diff --git a/src/parser/AdminSentences.cpp b/src/parser/AdminSentences.cpp
index b138d57f9bc53c73667caee1cc1e0b26da667480..1cc52a7cd357daf5ffcd3f9596e6bb106fd2180a 100644
--- a/src/parser/AdminSentences.cpp
+++ b/src/parser/AdminSentences.cpp
@@ -5,6 +5,7 @@
  */
 
 #include "parser/AdminSentences.h"
+#include <sstream>
 #include "util/SchemaUtil.h"
 
 namespace nebula {
@@ -68,9 +69,12 @@ std::string SpaceOptItem::toString() const {
             return folly::stringPrintf("charset = %s", boost::get<std::string>(optValue_).c_str());
         case COLLATE:
             return folly::stringPrintf("collate = %s", boost::get<std::string>(optValue_).c_str());
-        default:
-            FLOG_FATAL("Space parameter illegal");
+        case ATOMIC_EDGE:
+            return folly::stringPrintf("atomic_edge = %s", getAtomicEdge() ? "true" : "false");
+        case GROUP_NAME:
+            return "";
     }
+    DLOG(FATAL) << "Space parameter illegal";
     return "Unknown";
 }
 
@@ -98,6 +102,10 @@ std::string CreateSpaceSentence::toString() const {
         buf += spaceOpts_->toString();
         buf += ")";
     }
+    if (groupName_ != nullptr) {
+        buf += " ON ";
+        buf += *groupName_;
+    }
     return buf;
 }
 
@@ -112,15 +120,39 @@ std::string DescribeSpaceSentence::toString() const {
 }
 
 std::string ConfigRowItem::toString() const {
-    return "";
+    std::string buf;
+    buf.reserve(128);
+    if (module_ != meta::cpp2::ConfigModule::ALL) {
+        buf += meta::cpp2::_ConfigModule_VALUES_TO_NAMES.at(module_);
+        buf += ":";
+    }
+    if (name_ != nullptr) {
+        buf += *name_;
+    }
+    if (value_ != nullptr) {
+        buf += " = ";
+        buf += value_->toString();
+    }
+    if (updateItems_ != nullptr) {
+        buf += " = ";
+        buf += "{";
+        buf += updateItems_->toString();
+        buf += "}";
+    }
+    return buf;
 }
 
 std::string ShowConfigsSentence::toString() const {
-    return std::string("SHOW CONFIGS ") + configItem_->toString();
+    std::string buf;
+    buf += "SHOW CONFIGS ";
+    if (configItem_ != nullptr) {
+        configItem_->toString();
+    }
+    return buf;
 }
 
 std::string SetConfigSentence::toString() const {
-    return std::string("SET CONFIGS ") + configItem_->toString();
+    return std::string("UPDATE CONFIGS ") + configItem_->toString();
 }
 
 std::string GetConfigSentence::toString() const {
@@ -129,11 +161,31 @@ std::string GetConfigSentence::toString() const {
 
 std::string BalanceSentence::toString() const {
     switch (subType_) {
+        case SubType::kUnknown:
+            return "Unknown";
         case SubType::kLeader:
-            return std::string("BALANCE LEADER");
-        default:
-            FLOG_FATAL("Type illegal");
+            return "BALANCE LEADER";
+        case SubType::kData: {
+            if (hostDel_ == nullptr) {
+                return "BALANCE DATA";
+            } else {
+                std::stringstream ss;
+                ss << "BALANCE DATA REMOVE ";
+                ss << hostDel_->toString();
+                return ss.str();
+            }
+        }
+        case SubType::kDataStop:
+            return "BALANCE DATA STOP";
+        case SubType::kDataReset:
+            return "BALANCE DATA RESET PLAN";
+        case SubType::kShowBalancePlan: {
+            std::stringstream ss;
+            ss << "BALANCE DATA " << balanceId_;
+            return ss.str();
+        }
     }
+    DLOG(FATAL) << "Type illegal";
     return "Unknown";
 }
 
@@ -141,7 +193,9 @@ std::string HostList::toString() const {
     std::string buf;
     buf.reserve(256);
     for (auto &host : hosts_) {
+        buf += "\"";
         buf += host->host;
+        buf += "\"";
         buf += ":";
         buf += std::to_string(host->port);
         buf += ",";
@@ -161,11 +215,34 @@ std::string DropSnapshotSentence::toString() const {
 }
 
 std::string AddListenerSentence::toString() const {
-    return "ADD LISTENER";
+    std::string buf;
+    buf.reserve(64);
+    buf += "ADD LISTENER ";
+    switch (type_) {
+        case meta::cpp2::ListenerType::ELASTICSEARCH:
+            buf += "ELASTICSEARCH ";
+            break;
+        case meta::cpp2::ListenerType::UNKNOWN:
+            LOG(FATAL) << "Unknown listener type.";
+            break;
+    }
+    buf += listeners_->toString();
+    return buf;
 }
 
 std::string RemoveListenerSentence::toString() const {
-    return "REMOVE LISTENER";
+    std::string buf;
+    buf.reserve(64);
+    buf += "REMOVE LISTENER ";
+    switch (type_) {
+        case meta::cpp2::ListenerType::ELASTICSEARCH:
+            buf += "ELASTICSEARCH ";
+            break;
+        case meta::cpp2::ListenerType::UNKNOWN:
+            DLOG(FATAL) << "Unknown listener type.";
+            break;
+    }
+    return buf;
 }
 
 std::string ShowListenerSentence::toString() const {
diff --git a/src/parser/AdminSentences.h b/src/parser/AdminSentences.h
index 376631eb984a4a9f30c01cc3362c72c5aaf9341c..f6af20d7698c4ca761d49949107bd5ef1dd55efd 100644
--- a/src/parser/AdminSentences.h
+++ b/src/parser/AdminSentences.h
@@ -6,6 +6,7 @@
 #ifndef PARSER_ADMINSENTENCES_H_
 #define PARSER_ADMINSENTENCES_H_
 
+#include <memory>
 #include "parser/Clauses.h"
 #include "parser/Sentence.h"
 #include "parser/MutateSentences.h"
@@ -262,7 +263,7 @@ public:
         return optType_;
     }
 
-    int64_t getAtomicEdge() const {
+    bool getAtomicEdge() const {
         if (isInt()) {
             return asInt();
         } else {
@@ -315,9 +316,8 @@ public:
         spaceOpts_.reset(spaceOpts);
     }
 
-    void setGroupName(std::string& name) {
-        auto *item = new SpaceOptItem(SpaceOptItem::OptionType::GROUP_NAME, name);
-        spaceOpts_->addOpt(std::move(item));
+    void setGroupName(std::string* name) {
+        groupName_.reset(name);
     }
 
     std::vector<SpaceOptItem*> getOpts() {
@@ -331,6 +331,7 @@ public:
 
 private:
     std::unique_ptr<std::string>     spaceName_;
+    std::unique_ptr<std::string>     groupName_;
     std::unique_ptr<SpaceOptList>    spaceOpts_;
 };
 
diff --git a/src/parser/Clauses.cpp b/src/parser/Clauses.cpp
index 16afdd547fab6df466db1a50b76dd7ff69b69a60..442f93e13c4d84103f16d9b6b6130c35cd342e83 100644
--- a/src/parser/Clauses.cpp
+++ b/src/parser/Clauses.cpp
@@ -97,7 +97,11 @@ std::string OverClause::toString() const {
     std::string buf;
     buf.reserve(256);
     buf += "OVER ";
-    buf += overEdges_->toString();
+    if (isOverAll_) {
+        buf += "*";
+    } else {
+        buf += overEdges_->toString();
+    }
 
     if (direction_ == storage::cpp2::EdgeDirection::IN_EDGE) {
         buf += " REVERSELY";
@@ -116,6 +120,14 @@ std::string WhereClause::toString() const {
     return buf;
 }
 
+std::string WhenClause::toString() const {
+    std::string buf;
+    buf.reserve(256);
+    buf += "WHEN ";
+    buf += filter()->toString();
+    return buf;
+}
+
 std::string YieldColumn::toString() const {
     std::string buf;
     buf.reserve(256);
@@ -164,6 +176,9 @@ bool operator==(const YieldColumn &l, const YieldColumn &r) {
 
 std::string YieldClause::toString() const {
     std::string buf;
+    if (yieldColumns_->empty()) {
+        return buf;
+    }
     buf.reserve(256);
     buf += "YIELD ";
     if (distinct_) {
diff --git a/src/parser/Clauses.h b/src/parser/Clauses.h
index 2ccc548aa038be54165a1602f8bc973aa80b206b..94849a38527751dfe43acb24a35109ad76e60820 100644
--- a/src/parser/Clauses.h
+++ b/src/parser/Clauses.h
@@ -191,7 +191,7 @@ private:
     bool                                          isOverAll_{false};
 };
 
-class WhereClause final {
+class WhereClause {
 public:
     explicit WhereClause(Expression *filter) {
         filter_.reset(filter);
@@ -215,7 +215,12 @@ private:
     std::unique_ptr<Expression>                 filter_;
 };
 
-using WhenClause = WhereClause;
+class WhenClause : public WhereClause {
+public:
+    explicit WhenClause(Expression *filter) : WhereClause(filter) {}
+
+    std::string toString() const;
+};
 
 class YieldColumn final {
 public:
diff --git a/src/parser/GraphScanner.h b/src/parser/GraphScanner.h
index 429c46f5f3e358ce1187a8fb1a35528ae41a8c74..604ca976e9e98dc5dc9f7c3a6ed58e985129c6e8 100644
--- a/src/parser/GraphScanner.h
+++ b/src/parser/GraphScanner.h
@@ -99,6 +99,7 @@ protected:
             if (val == MAX_ABS_INTEGER && !hasUnaryMinus()) {
                 throw GraphParser::syntax_error(*yylloc, "Out of range:");
             }
+            // TODO for min of int64_t will overflow
             yylval->intval = val;
         } catch (...) {
             throw GraphParser::syntax_error(*yylloc, "Out of range:");
@@ -134,6 +135,7 @@ protected:
         if (val == MAX_ABS_INTEGER && !hasUnaryMinus()) {
             throw GraphParser::syntax_error(*yylloc, "Out of range:");
         }
+        // TODO for min of int64_t will overflow
         yylval->intval = static_cast<int64_t>(val);
         return TokenType::INTEGER;
     }
@@ -157,6 +159,7 @@ protected:
         if (val == MAX_ABS_INTEGER && !hasUnaryMinus()) {
             throw GraphParser::syntax_error(*yylloc, "Out of range:");
         }
+        // TODO for min of int64_t will overflow
         yylval->intval = static_cast<int64_t>(val);
         return TokenType::INTEGER;
     }
diff --git a/src/parser/MaintainSentences.cpp b/src/parser/MaintainSentences.cpp
index e6aaa0cad98704771bcea415bb37c3266461a036..0a05e4f9751688e5738b19462da6bc90ab22538b 100644
--- a/src/parser/MaintainSentences.cpp
+++ b/src/parser/MaintainSentences.cpp
@@ -4,6 +4,7 @@
  * attached with Common Clause Condition 1.0, found in the LICENSES directory.
  */
 
+#include <string>
 #include "common/base/Base.h"
 #include "parser/MaintainSentences.h"
 
@@ -20,7 +21,7 @@ std::string SchemaPropItem::toString() const {
             return folly::stringPrintf("ttl_duration = %ld",
                                        boost::get<int64_t>(propValue_));
         case TTL_COL:
-            return folly::stringPrintf("ttl_col = %s",
+            return folly::stringPrintf("ttl_col = \"%s\"",
                                        boost::get<std::string>(propValue_).c_str());
         default:
             FLOG_FATAL("Schema property type illegal");
@@ -43,25 +44,53 @@ std::string SchemaPropItem::toString() const {
     return buf;
 }
 
-
-std::string CreateTagSentence::toString() const {
+std::string ColumnSpecification::toString() const {
     std::string buf;
-    buf.reserve(256);
-    buf += "CREATE TAG ";
+    buf.reserve(128);
+    buf += "`";
     buf += *name_;
-    buf += " (";
-    auto colSpecs = columns_->columnSpecs();
-    for (auto *col : colSpecs) {
-        buf += *col->name();
-        buf += " ";
-        std::stringstream ss;
-        ss << col->type();
-        buf += ss.str();
+    buf += "` ";
+    if (meta::cpp2::PropertyType::FIXED_STRING == type_) {
+        buf += "FIXED_STRING(";
+        buf += std::to_string(typeLen_);
+        buf += ")";
+    } else {
+        buf += meta::cpp2::_PropertyType_VALUES_TO_NAMES.at(type_);
+    }
+    if (isNull_) {
+        buf += " NULL";
+    } else {
+        buf += " NOT NULL";
+    }
+    if (defaultValue_ != nullptr) {
+        buf += " DEFAULT ";
+        buf += defaultValue_->toString();
+    }
+    return buf;
+}
+
+std::string ColumnSpecificationList::toString() const {
+    std::string buf;
+    buf.reserve(128);
+    const auto &colSpecs = columnSpecs();
+    for (auto &col : colSpecs) {
+        buf += col->toString();
         buf += ",";
     }
     if (!colSpecs.empty()) {
         buf.resize(buf.size() - 1);
     }
+    return buf;
+}
+
+std::string CreateTagSentence::toString() const {
+    std::string buf;
+    buf.reserve(256);
+    buf += "CREATE TAG ";
+    buf += "`";
+    buf += *name_;
+    buf += "` (";
+    buf += columns_->toString();
     buf += ")";
     if (schemaProps_ != nullptr) {
         buf +=  schemaProps_->toString();
@@ -74,20 +103,10 @@ std::string CreateEdgeSentence::toString() const {
     std::string buf;
     buf.reserve(256);
     buf += "CREATE EDGE ";
+    buf += "`";
     buf += *name_;
-    buf += " (";
-    auto colSpecs = columns_->columnSpecs();
-    for (auto &col : colSpecs) {
-        buf += *col->name();
-        buf += " ";
-        std::stringstream ss;
-        ss << col->type();
-        buf += ss.str();
-        buf += ",";
-    }
-    if (!colSpecs.empty()) {
-        buf.resize(buf.size() - 1);
-    }
+    buf += "` (";
+    buf += columns_->toString();
     buf += ")";
     if (schemaProps_ != nullptr) {
         buf +=  schemaProps_->toString();
@@ -101,30 +120,29 @@ std::string AlterSchemaOptItem::toString() const {
     switch (optType_) {
         case ADD:
             buf += "ADD";
+            buf += " (";
+            if (columns_ != nullptr) {
+                buf += columns_->toString();
+            }
+            buf += ")";
             break;
         case CHANGE:
             buf += "CHANGE";
+            buf += " (";
+            if (columns_ != nullptr) {
+                buf += columns_->toString();
+            }
+            buf += ")";
             break;
         case DROP:
             buf += "DROP";
+            buf += " (";
+            if (colNames_ != nullptr) {
+                buf += colNames_->toString();
+            }
+            buf += ")";
             break;
     }
-    buf += " (";
-    if (columns_ != nullptr) {
-        auto colSpecs = columns_->columnSpecs();
-        for (auto &col : colSpecs) {
-            buf += *col->name();
-            buf += " ";
-            std::stringstream ss;
-            ss << col->type();
-            buf += ss.str();
-            buf += ",";
-        }
-        if (!colSpecs.empty()) {
-            buf.resize(buf.size() - 1);
-        }
-    }
-    buf += ")";
     return buf;
 }
 
@@ -152,7 +170,7 @@ std::string AlterSchemaOptList::toString() const {
         buf += ",";
     }
     if (!buf.empty()) {
-        buf.resize(buf.size() - 1);
+        buf.pop_back();
     }
     return buf;
 }
@@ -164,10 +182,8 @@ std::string AlterTagSentence::toString() const {
     buf += "ALTER TAG ";
     buf += *name_;
     if (opts_ != nullptr) {
-        for (auto &schemaOpt : opts_->alterSchemaItems()) {
-            buf += " ";
-            buf += schemaOpt->toString();
-        }
+        buf += " ";
+        buf += opts_->toString();
     }
     if (schemaProps_ != nullptr) {
         buf +=  schemaProps_->toString();
@@ -182,10 +198,8 @@ std::string AlterEdgeSentence::toString() const {
     buf += "ALTER EDGE ";
     buf += *name_;
     if (opts_ != nullptr) {
-        for (auto &schemaOpt : opts_->alterSchemaItems()) {
-            buf += " ";
-            buf += schemaOpt->toString();
-        }
+        buf += " ";
+        buf += opts_->toString();
     }
     if (schemaProps_ != nullptr) {
         buf +=  schemaProps_->toString();
@@ -319,11 +333,22 @@ std::string ShowCreateEdgeIndexSentence::toString() const {
 }
 
 std::string AddGroupSentence::toString() const {
-    return folly::stringPrintf("ADD GROUP %s", groupName_.get()->c_str());
+    std::string buf;
+    buf.reserve(64);
+    buf += "ADD GROUP ";
+    buf += *groupName_;
+    buf += " ";
+    buf += zoneNames_->toString();
+    return buf;
 }
 
 std::string AddZoneSentence::toString() const {
-    return folly::stringPrintf("ADD ZONE %s", zoneName_.get()->c_str());
+    std::string buf;
+    buf.reserve(128);
+    buf += "ADD ZONE ";
+    buf += *zoneName_;
+    buf += hosts_->toString();
+    return buf;
 }
 
 std::string DropGroupSentence::toString() const {
@@ -357,7 +382,13 @@ std::string AddZoneIntoGroupSentence::toString() const {
 }
 
 std::string AddHostIntoZoneSentence::toString() const {
-    return folly::stringPrintf("Add Host Into Zone %s", zoneName_.get()->c_str());
+    std::string buf;
+    buf.reserve(64);
+    buf += "ADD HOST ";
+    buf += address_->toString();
+    buf += " INTO ZONE ";
+    buf += *zoneName_;
+    return buf;
 }
 
 std::string DropZoneFromGroupSentence::toString() const {
@@ -367,7 +398,13 @@ std::string DropZoneFromGroupSentence::toString() const {
 }
 
 std::string DropHostFromZoneSentence::toString() const {
-    return folly::stringPrintf("Drop Host From Zone %s", zoneName_.get()->c_str());
+    std::string buf;
+    buf.reserve(64);
+    buf += "DROP HOST ";
+    buf += address_->toString();
+    buf += " FROM ZONE ";
+    buf += *zoneName_;
+    return buf;
 }
 
 }   // namespace nebula
diff --git a/src/parser/MaintainSentences.h b/src/parser/MaintainSentences.h
index 27d6aa446871900f3910a2ce350c7625506ffe90..a84af7ebbbeff139812f597b5b4b95f0469fef9c 100644
--- a/src/parser/MaintainSentences.h
+++ b/src/parser/MaintainSentences.h
@@ -56,6 +56,8 @@ public:
         return defaultValue_.get();
     }
 
+    std::string toString() const;
+
 private:
     meta::cpp2::PropertyType                    type_;
     std::unique_ptr<std::string>                name_;
@@ -80,6 +82,8 @@ public:
         return result;
     }
 
+    std::string toString() const;
+
 private:
     std::vector<std::unique_ptr<ColumnSpecification>> columns_;
 };
@@ -101,6 +105,20 @@ public:
         return result;
     }
 
+    std::string toString() const {
+        std::string buf;
+        buf.reserve(128);
+        for (const auto &col : columns_) {
+            buf += *col;
+            buf += ", ";
+        }
+        if (!columns_.empty()) {
+            buf.pop_back();
+            buf.pop_back();
+        }
+        return buf;
+    }
+
 private:
     std::vector<std::unique_ptr<std::string>> columns_;
 };
@@ -800,6 +818,18 @@ public:
         return result;
     }
 
+    std::string toString() const {
+        std::string buf;
+        for (const auto &zone : zones_) {
+            buf += *zone;
+            buf += ",";
+        }
+        if (!zones_.empty()) {
+            buf.pop_back();
+        }
+        return buf;
+    }
+
 private:
     std::vector<std::unique_ptr<std::string>> zones_;
 };
diff --git a/src/parser/MatchSentence.cpp b/src/parser/MatchSentence.cpp
index 750b5a3bef4bd53482736b0850260bae3bc430ba..6e5d4d237b6cccf0a357d24682743f7acb37dca3 100644
--- a/src/parser/MatchSentence.cpp
+++ b/src/parser/MatchSentence.cpp
@@ -59,11 +59,13 @@ std::string WithClause::toString() const {
 
     if (skip_ != nullptr) {
         buf += " ";
+        buf += "SKIP ";
         buf += skip_->toString();
     }
 
     if (limit_ != nullptr) {
         buf += " ";
+        buf += "LIMIT ";
         buf += limit_->toString();
     }
 
@@ -189,17 +191,19 @@ std::string MatchReturn::toString() const {
 
     if (orderFactors_ != nullptr) {
         buf += " ";
-        buf += "ORDER BY";
+        buf += "ORDER BY ";
         buf += orderFactors_->toString();
     }
 
     if (skip_ != nullptr) {
         buf += " ";
+        buf += "SKIP ";
         buf += skip_->toString();
     }
 
     if (limit_ != nullptr) {
         buf += " ";
+        buf += "LIMIT ";
         buf += limit_->toString();
     }
 
diff --git a/src/parser/MutateSentences.cpp b/src/parser/MutateSentences.cpp
index 8401bffc859e439f53ea87684560a454ea59a78a..af1c34db4554b848abd0fc31ec3d4f123e2a7161 100644
--- a/src/parser/MutateSentences.cpp
+++ b/src/parser/MutateSentences.cpp
@@ -27,11 +27,11 @@ std::string VertexTagItem::toString() const {
     buf.reserve(256);
 
     buf += *tagName_;
+    buf += "(";
     if (properties_ != nullptr) {
-        buf += "(";
         buf += properties_->toString();
-        buf += ")";
     }
+    buf += ")";
 
     return buf;
 }
@@ -147,7 +147,7 @@ std::string InsertEdgesSentence::toString() const {
     buf += *edge_;
     buf += "(";
     buf += properties_->toString();
-    buf += ") VALUES";
+    buf += ") VALUES ";
     buf += rows_->toString();
     return buf;
 }
@@ -210,7 +210,9 @@ std::string UpdateVertexSentence::toString() const {
         buf += "UPDATE ";
     }
     buf += "VERTEX ";
-    buf += "ON " + *name_ + " ";
+    if (name_ != nullptr) {
+        buf += "ON " + *name_ + " ";
+    }
     buf += vid_->toString();
     buf += " SET ";
     buf += updateList_->toString();
@@ -239,7 +241,7 @@ std::string UpdateEdgeSentence::toString() const {
     buf += srcId_->toString();
     buf += "->";
     buf += dstId_->toString();
-    buf += " AT" + std::to_string(rank_);
+    buf += "@" + std::to_string(rank_);
     buf += " OF " + *name_;
     buf += " SET ";
     buf += updateList_->toString();
@@ -269,12 +271,16 @@ std::string DeleteEdgesSentence::toString() const {
     buf += "DELETE EDGE ";
     buf += *edge_;
     buf += " ";
-    buf += edgeKeys_->toString();
+    if (edgeKeyRef_ != nullptr) {
+        buf += edgeKeyRef_->toString();
+    } else {
+        buf += edgeKeys_->toString();
+    }
     return buf;
 }
 
 std::string DownloadSentence::toString() const {
-    return folly::stringPrintf("DOWNLOAD HDFS \"%s:%d/%s\"", host_.get()->c_str(),
+    return folly::stringPrintf("DOWNLOAD HDFS \"hdfs://%s:%d%s\"", host_.get()->c_str(),
                                port_, path_.get()->c_str());
 }
 
diff --git a/src/parser/TraverseSentences.cpp b/src/parser/TraverseSentences.cpp
index 23a6ed72fa1ca3a3c695c1db101cb6663b1937e1..eefba70cd46da5a20a2791e843f7f0f38673587f 100644
--- a/src/parser/TraverseSentences.cpp
+++ b/src/parser/TraverseSentences.cpp
@@ -128,8 +128,13 @@ std::string OrderBySentence::toString() const {
 std::string FetchVerticesSentence::toString() const {
     std::string buf;
     buf.reserve(256);
-    buf += "FETCH PROP ON ";
-    buf += tags_->toString();
+    buf += "FETCH PROP ON";
+    buf += " ";
+    if (tags_->empty()) {
+        buf += "*";
+    } else {
+        buf += tags_->toString();
+    }
     buf += " ";
     buf += vertices_->toString();
     if (yieldClause_ != nullptr) {
@@ -193,6 +198,7 @@ std::string FindPathSentence::toString() const {
         buf += " ";
     }
     if (step_ != nullptr) {
+        buf += "UPTO ";
         buf += step_->toString();
         buf += " ";
     }
diff --git a/src/parser/parser.yy b/src/parser/parser.yy
index e5e36da4eb562523d4b823825d87eaacfe31d3f5..67b557067e6f8a8d2b5ff22de9cc06aca0d09e62 100644
--- a/src/parser/parser.yy
+++ b/src/parser/parser.yy
@@ -227,6 +227,7 @@ static constexpr size_t MAX_ABS_INTEGER = 9223372036854775808ULL;
 %type <expr> compound_expression
 %type <expr> aggregate_expression
 %type <expr> text_search_expression
+%type <expr> constant_expression
 %type <argument_list> argument_list opt_argument_list
 %type <type> type_spec
 %type <step_clause> step_clause
@@ -524,18 +525,8 @@ agg_function
     ;
 
 expression
-    : DOUBLE {
-        $$ = new ConstantExpression($1);
-    }
-    | STRING {
-        $$ = new ConstantExpression(*$1);
-        delete $1;
-    }
-    | BOOL {
-        $$ = new ConstantExpression($1);
-    }
-    | KW_NULL {
-        $$ = new ConstantExpression(NullType::__NULL__);
+    : constant_expression {
+        $$ = $1;
     }
     | name_label {
         $$ = new LabelExpression($1);
@@ -543,9 +534,6 @@ expression
     | VARIABLE {
         $$ = new VariableExpression($1);
     }
-    | INTEGER {
-        $$ = new ConstantExpression($1);
-    }
     | compound_expression {
         $$ = $1;
     }
@@ -654,6 +642,25 @@ expression
     }
     ;
 
+constant_expression
+    : DOUBLE {
+        $$ = new ConstantExpression($1);
+    }
+    | STRING {
+        $$ = new ConstantExpression(*$1);
+        delete $1;
+    }
+    | BOOL {
+        $$ = new ConstantExpression($1);
+    }
+    | KW_NULL {
+        $$ = new ConstantExpression(NullType::__NULL__);
+    }
+    | INTEGER {
+        $$ = new ConstantExpression($1);
+    }
+    ;
+
 compound_expression
     : L_PAREN expression R_PAREN {
         $$ = $2;
@@ -1769,20 +1776,23 @@ edge_keys
     }
     ;
 
-edge_key_ref:
-    input_prop_expression R_ARROW input_prop_expression AT input_prop_expression {
+edge_key_ref
+    : input_prop_expression R_ARROW input_prop_expression AT input_prop_expression {
         $$ = new EdgeKeyRef($1, $3, $5);
     }
-    |
-    var_prop_expression R_ARROW var_prop_expression AT var_prop_expression {
+    | input_prop_expression R_ARROW input_prop_expression AT constant_expression {
+        $$ = new EdgeKeyRef($1, $3, $5);
+    }
+    | var_prop_expression R_ARROW var_prop_expression AT var_prop_expression {
+        $$ = new EdgeKeyRef($1, $3, $5, false);
+    }
+    | var_prop_expression R_ARROW var_prop_expression AT constant_expression {
         $$ = new EdgeKeyRef($1, $3, $5, false);
     }
-    |
-    input_prop_expression R_ARROW input_prop_expression {
+    | input_prop_expression R_ARROW input_prop_expression {
         $$ = new EdgeKeyRef($1, $3, new ConstantExpression(0));
     }
-    |
-    var_prop_expression R_ARROW var_prop_expression {
+    | var_prop_expression R_ARROW var_prop_expression {
         $$ = new EdgeKeyRef($1, $3, new ConstantExpression(0), false);
     }
     ;
@@ -2829,10 +2839,8 @@ create_space_sentence
     }
     | KW_CREATE KW_SPACE opt_if_not_exists name_label KW_ON name_label {
         auto sentence = new CreateSpaceSentence($4, $3);
-        sentence->setOpts(new SpaceOptList());
-        sentence->setGroupName(*$6);
+        sentence->setGroupName($6);
         $$ = sentence;
-        delete $6;
     }
     | KW_CREATE KW_SPACE opt_if_not_exists name_label L_PAREN space_opt_list R_PAREN {
         auto sentence = new CreateSpaceSentence($4, $3);
@@ -2841,10 +2849,9 @@ create_space_sentence
     }
     | KW_CREATE KW_SPACE opt_if_not_exists name_label L_PAREN space_opt_list R_PAREN KW_ON name_label {
         auto sentence = new CreateSpaceSentence($4, $3);
+        sentence->setGroupName($9);
         sentence->setOpts($6);
-        sentence->setGroupName(*$9);
         $$ = sentence;
-        delete $9;
     }
     ;
 
diff --git a/src/parser/test/ParserTest.cpp b/src/parser/test/ParserTest.cpp
index 63f2d8d2c3bfe0e027405854544789eb21428ac2..a0495c6230d55abfc2cb94acd7c3f95afd7ef46d 100644
--- a/src/parser/test/ParserTest.cpp
+++ b/src/parser/test/ParserTest.cpp
@@ -7,1647 +7,1450 @@
 #include <gtest/gtest.h>
 #include "common/base/Base.h"
 #include "parser/GQLParser.h"
+#include "util/AstUtils.h"
 
 namespace nebula {
 
+static StatusOr<std::unique_ptr<Sentence>> parse(const std::string &query) {
+    GQLParser parser;
+    auto result = parser.parse(query);
+    NG_RETURN_IF_ERROR(result);
+    NG_RETURN_IF_ERROR(graph::AstUtils::reprAstCheck(*result.value()));
+    return result;
+}
+
 TEST(Parser, TestSchemaCreation) {
     // All type
     {
-        GQLParser parser;
         std::string query = "CREATE TAG person(name STRING, age INT8, count INT16, "
                             "friends INT32, books INT64, citys INT, property DOUBLE, "
                             "liabilities FLOAT, profession FIXED_STRING(20), "
                             "start TIMESTAMP, study DATE, birthday DATETIME)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
 
     {
-        GQLParser parser;
         std::string query = "CREATE TAG person(name STRING NULL, age INT8 NOT NULL, "
                             "count INT16 DEFAULT 10, friends INT32 NULL DEFAULT 10, "
                             "profession FIXED_STRING(20) NOT NULL DEFAULT \"student\");";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     // Error FIXED_STRING
     {
-        GQLParser parser;
         std::string query = "CREATE TAG person(profession FIXED_STRING)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "CREATE TAG person(profession FIXED_STRING(400000))";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok()) << result.status();
     }
     // Default value is NULL
     {
-        GQLParser parser;
         std::string query = "CREATE TAG person(profession string DEFAULT NULL)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     // Default value AND NOT NULL
     {
-        GQLParser parser;
         std::string query = "CREATE TAG person(profession string DEFAULT \"HELLO\" NOT NULL)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "CREATE TAG person(profession string NOT NULL DEFAULT \"HELLO\")";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     // Default value AND NULL
     {
-        GQLParser parser;
         std::string query = "CREATE TAG person(profession string DEFAULT \"HELLO\" NULL)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "CREATE TAG person(profession string NULL DEFAULT \"HELLO\")";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
 }
 
 TEST(Parser, Go) {
     {
-        GQLParser parser;
         std::string query = "GO FROM \"1\" OVER friend";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "GO FROM \"1\" OVER friend;";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "GO 2 STEPS FROM \"1\" OVER friend";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "GO FROM \"1\" OVER friend";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "GO FROM \"1\" OVER friend REVERSELY";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "GO FROM \"1\" OVER friend YIELD person.name";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "GO FROM \"1\" OVER friend "
                             "YIELD $^.manager.name,$^.manager.age";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "GO FROM \"1\" OVER friend "
                             "YIELD $$.manager.name,$$.manager.age";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     // Test wrong syntax
     {
-        GQLParser parser;
         std::string query = "GO FROM \"1\" OVER friend "
                             "YIELD $^[manager].name,$^[manager].age";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "GO FROM \"1\",\"2\",\"3\" OVER friend";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "GO FROM $-.id OVER friend";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "GO FROM $-.col1 OVER friend";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "GO FROM $-.id OVER friend";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "GO FROM \"1\",\"2\",\"3\" OVER friend WHERE person.name == \"Tom\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
 }
 
 TEST(Parser, SpaceOperation) {
     {
-        GQLParser parser;
         std::string query = "CREATE SPACE default_space(partition_num=9, replica_factor=3)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
+        ASSERT_TRUE(result.ok()) << result.status();
+    }
+    {
+        std::string query = "USE default_space";
+        auto result = parse(query);
+        ASSERT_TRUE(result.ok()) << result.status();
+    }
+    {
+        std::string query = "DESC SPACE default_space";
+        auto result = parse(query);
+        ASSERT_TRUE(result.ok()) << result.status();
+    }
+    {
+        std::string query = "DESCRIBE SPACE default_space";
+        auto result = parse(query);
+        ASSERT_TRUE(result.ok()) << result.status();
+    }
+    {
+        std::string query = "SHOW CREATE SPACE default_space";
+        auto result = parse(query);
+        ASSERT_TRUE(result.ok()) << result.status();
+    }
+    {
+        std::string query = "DROP SPACE default_space";
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "CREATE SPACE default_space(partition_num=9, replica_factor=3) "
                             "ON group_0";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "CREATE SPACE default_space ON group_0";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "CREATE SPACE default_space";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "CREATE SPACE default_space(partition_num=9, replica_factor=3,"
                             "charset=utf8, collate=utf8_bin)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "CREATE SPACE default_space(partition_num=9, replica_factor=3,"
                             "charset=utf8)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "CREATE SPACE default_space(partition_num=9, replica_factor=3,"
                             "collate=utf8_bin)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "CREATE SPACE default_space(partition_num=9, replica_factor=3,"
                             "atomic_edge=true)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         EXPECT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "CREATE SPACE default_space(partition_num=9, replica_factor=3,"
                             "atomic_edge=FALSE)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         EXPECT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "USE default_space";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "DESC SPACE default_space";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "DESCRIBE SPACE default_space";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "SHOW CREATE SPACE default_space";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "DROP SPACE default_space";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
 }
 
 TEST(Parser, TagOperation) {
     {
-        GQLParser parser;
         std::string query = "CREATE TAG person(name string, age int, "
                             "married bool, salary double)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     // Test empty prop
     {
-        GQLParser parser;
         std::string query = "CREATE TAG person()";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "CREATE TAG man(name string, age int, "
                             "married bool, salary double)"
                             "ttl_duration = 100";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "CREATE TAG woman(name string, age int, "
                             "married bool, salary double)"
                             "ttl_duration = 100, ttl_col = \"create_time\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "CREATE TAG woman(name string, age int default 22, "
                             "married bool default false, salary double default 1000.0)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "CREATE TAG woman(name string default \"\", age int default 22, "
                             "married bool default false, salary double default 1000.0)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "ALTER TAG person ADD (col1 int, col2 string), "
                             "CHANGE (married int, salary int), "
                             "DROP (age, create_time)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "ALTER TAG man ttl_duration = 200";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "ALTER TAG man ttl_col = \"\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "ALTER TAG woman ttl_duration = 50, ttl_col = \"age\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "ALTER TAG woman ADD (col6 int) ttl_duration = 200";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "DESCRIBE TAG person";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "DESC TAG person";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "SHOW CREATE TAG person";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "DROP TAG person";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
 }
 
 TEST(Parser, EdgeOperation) {
     {
-        GQLParser parser;
         std::string query = "CREATE EDGE e1(name string, age int, "
                             "married bool, salary double)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     // Test empty prop
     {
-        GQLParser parser;
         std::string query = "CREATE EDGE e1()";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "CREATE EDGE man(name string, age int, "
                             "married bool, salary double)"
                             "ttl_duration = 100";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "CREATE EDGE man(name string default \"\", age int default 18, "
                             "married bool default false, salary double default 1000.0)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "CREATE EDGE woman(name string, age int, "
                             "married bool, salary double)"
                             "ttl_duration = 100, ttl_col = \"create_time\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "ALTER EDGE e1 ADD (col1 int, col2 string), "
                             "CHANGE (married int, salary int), "
                             "DROP (age, create_time)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "ALTER EDGE man ttl_duration = 200";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "ALTER EDGE man ttl_col = \"\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "ALTER EDGE woman ttl_duration = 50, ttl_col = \"age\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "ALTER EDGE woman ADD (col6 int)  ttl_duration = 200";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "DESCRIBE EDGE e1";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "DESC EDGE e1";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "SHOW CREATE EDGE e1";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "DROP EDGE e1";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
 }
 // Column space format test, expected SyntaxError
 TEST(Parser, ColumnSpacesTest) {
     {
-        GQLParser parser;
         std::string query = "CREATE TAG person(name, age, married bool)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
     }
     {
-        GQLParser parser;
         std::string query = "CREATE TAG person(name, age, married)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
     }
     {
-        GQLParser parser;
         std::string query = "CREATE TAG man(name string, age)"
                             "ttl_duration = 100";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
     }
     {
-        GQLParser parser;
         std::string query = "ALTER TAG person ADD (col1 int, col2 string), "
                             "CHANGE (married int, salary int), "
                             "DROP (age int)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
     }
     {
-        GQLParser parser;
         std::string query = "ALTER TAG person ADD (col1, col2), "
                             "CHANGE (married int, salary int), "
                             "DROP (age, create_time)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
     }
     {
-        GQLParser parser;
         std::string query = "ALTER TAG person ADD (col1 int, col2 string), "
                             "CHANGE (married, salary), "
                             "DROP (age, create_time)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
     }
     {
-        GQLParser parser;
         std::string query = "CREATE EDGE man(name, age, married bool) "
                             "ttl_duration = 100";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
     }
     {
-        GQLParser parser;
         std::string query = "ALTER EDGE woman ADD (col6)  ttl_duration = 200";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
     }
     {
-        GQLParser parser;
         std::string query = "ALTER EDGE woman CHANGE (col6)  ttl_duration = 200";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
     }
     {
-        GQLParser parser;
         std::string query = "ALTER EDGE woman DROP (col6 int)  ttl_duration = 200";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
     }
 }
 
 TEST(Parser, IndexOperation) {
     {
-        GQLParser parser;
         std::string query = "CREATE TAG INDEX empty_field_index ON person()";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "CREATE TAG INDEX name_index ON person(name)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "CREATE TAG INDEX IF NOT EXISTS name_index ON person(name)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "CREATE TAG INDEX IF NOT EXISTS name_index ON person(name, age)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "CREATE EDGE INDEX IF NOT EXISTS empty_field_index ON service()";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "CREATE EDGE INDEX IF NOT EXISTS like_index ON service(like)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "CREATE EDGE INDEX IF NOT EXISTS like_index ON service(like, score)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "CREATE EDGE INDEX IF NOT EXISTS std_index ON t1(c1(10), c2(20))";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "CREATE EDGE INDEX IF NOT EXISTS std_index ON t1(c1, c2(20))";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "CREATE EDGE INDEX IF NOT EXISTS std_index ON t1(c1(10), c2)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "CREATE TAG INDEX IF NOT EXISTS std_index ON t1(c1(10), c2(20))";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "CREATE TAG INDEX IF NOT EXISTS std_index ON t1(c1, c2(20))";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "CREATE TAG INDEX IF NOT EXISTS std_index ON t1(c1(10), c2)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "DROP TAG INDEX name_index";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "DROP EDGE INDEX like_index";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "DESCRIBE TAG INDEX name_index";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "DESCRIBE EDGE INDEX like_index";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "REBUILD TAG INDEX name_index";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "REBUILD EDGE INDEX like_index";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
 }
 
 TEST(Parser, Set) {
     {
-        GQLParser parser;
         std::string query = "GO FROM \"1\" OVER friend INTERSECT "
                             "GO FROM \"2\" OVER friend";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "GO FROM \"1\" OVER friend UNION "
                             "GO FROM \"2\" OVER friend";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "GO FROM \"1\" OVER friend MINUS "
                             "GO FROM \"2\" OVER friend";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "GO FROM \"1\" OVER friend MINUS "
                             "GO FROM \"2\" OVER friend UNION "
                             "GO FROM \"2\" OVER friend INTERSECT "
                             "GO FROM \"3\" OVER friend";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "(GO FROM \"1\" OVER friend | "
                             "GO FROM \"2\" OVER friend) UNION "
                             "GO FROM \"3\" OVER friend";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         // pipe have priority over set
         std::string query = "GO FROM \"1\" OVER friend | "
                             "GO FROM \"2\" OVER friend UNION "
                             "GO FROM \"3\" OVER friend";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "(GO FROM \"1\" OVER friend YIELD friend._dst AS id UNION "
                             "GO FROM \"2\" OVER friend YIELD friend._dst AS id) | "
                             "GO FROM $-.id OVER friend";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
 }
 
 TEST(Parser, Pipe) {
     {
-        GQLParser parser;
         std::string query = "GO FROM \"1\" OVER friend | "
                             "GO FROM \"2\" OVER friend | "
                             "GO FROM \"3\" OVER friend";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "GO FROM \"1\" OVER friend MINUS "
                             "GO FROM \"2\" OVER friend | "
                             "GO FROM \"3\" OVER friend";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
 }
 
 TEST(Parser, InsertVertex) {
     {
-        GQLParser parser;
         std::string query = "INSERT VERTEX person(name,age,married,salary,create_time) "
                             "VALUES \"Tom\":(\"Tom\", 30, true, 3.14, 1551331900)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     // Test one vertex multi tags
     {
-        GQLParser parser;
         std::string query = "INSERT VERTEX person(name, age, id), student(name, number, id) "
                             "VALUES \"zhangsan\":(\"zhangsan\", 18, 1111, "
                             "\"zhangsan\", 20190527, 1111)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     // Test multi vertex multi tags
     {
-        GQLParser parser;
         std::string query = "INSERT VERTEX person(name, age, id), student(name, number, id) "
                             "VALUES \"zhangsan\":(\"zhangsan\", 18, 1111, "
                             "\"zhangsan\", 20190527, 1111),"
                             "\"12346\":(\"lisi\", 20, 1112, \"lisi\", 20190413, 1112)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     // Test wrong syntax
     {
-        GQLParser parser;
         std::string query = "INSERT VERTEX person(name, age, id), student(name, number) "
                             "VALUES \"zhangsan\":(\"zhangsan\", 18, 1111), "
                             "( \"zhangsan\", 20190527),"
                             "\"12346\":(\"lisi\", 20, 1112), (\"lisi\", 20190413)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "INSERT VERTEX person(name,age,married,salary,create_time) "
                             "VALUES \"Tom\":(\"Tom\", 30, true, 3.14, 1551331900)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "INSERT VERTEX person(name,age,married,salary,create_time) "
                             "VALUES \"Tom\":(\"Tom\", 30, true, 3.14, 1551331900)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "INSERT VERTEX person(name,age,married,salary,create_time) "
                             "VALUES \"Tom\":(\"Tom\", 30, true, 3.14, 1551331900)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     // Test insert empty value
     {
-        GQLParser parser;
         std::string query = "INSERT VERTEX person() "
                             "VALUES \"12345\":()";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     // Test insert prop unterminated ""
     {
-        GQLParser parser;
         std::string query = "INSERT VERTEX person(name, age) "
                             "VALUES \"Tom\":(\"Tom, 30)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.status().isSyntaxError());
     }
     // Test insert prop unterminated ''
     {
-        GQLParser parser;
         std::string query = "INSERT VERTEX person(name, age) "
                             "VALUES \"Tom\":(\'Tom, 30)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.status().isSyntaxError());
     }
     {
-        GQLParser parser;
         std::string query = "INSERT VERTEX person(name, age) "
                             "VALUES \"Tom\":(\'Tom, 30)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.status().isSyntaxError());
     }
     {
-        GQLParser parser;
         std::string query = "INSERT VERTEX person(name, age) "
                             "VALUES \"Tom\":(\'Tom, 30)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.status().isSyntaxError());
     }
 }
 
 TEST(Parser, UpdateVertex) {
     {
-        GQLParser parser;
         std::string query = "UPDATE VERTEX \"12345\" "
                             "SET person.name=\"Tome\", person.age=30, "
                             "job.salary=10000, person.create_time=1551331999";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "UPDATE VERTEX ON person \"12345\" "
                             "SET name=\"Tome\", age=30";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "UPDATE VERTEX \"12345\" "
                             "SET person.name=\"Tom\", person.age=$^.person.age + 1, "
                             "person.married=true "
                             "WHEN $^.job.salary > 10000 AND $^.person.age > 30";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "UPDATE VERTEX \"12345\" "
                             "SET name=\"Tom\", age=age + 1, "
                             "married=true "
                             "WHEN salary > 10000 AND age > 30";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "UPDATE VERTEX \"12345\" "
                             "SET person.name=\"Tom\", person.age=31, person.married=true, "
                             "job.salary=1.1 * $^.person.create_time / 31536000 "
                             "YIELD $^.person.name AS Name, job.name AS Title, "
                             "$^.job.salary AS Salary";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "UPDATE VERTEX ON person \"12345\" "
                             "SET name=\"Tom\", age=31, married=true "
                             "YIELD name AS Name";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "UPDATE VERTEX \"12345\" "
                             "SET person.name=\"Tom\", person.age=30, person.married=true "
                             "WHEN $^.job.salary > 10000 AND $^.job.name == \"CTO\" OR "
                             "$^.person.age < 30"
                             "YIELD $^.person.name AS Name, $^.job.salary AS Salary, "
                             "$^.person.create_time AS Time_";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "UPDATE VERTEX ON person \"12345\" "
                             "SET name=\"Tom\", age=30, married=true "
                             "WHEN salary > 10000 AND name == \"CTO\" OR age < 30"
                             "YIELD name AS Name, salary AS Salary, create_time AS Time_";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "UPSERT VERTEX \"12345\" "
                             "SET person.name=\"Tom\", person.age = 30, job.name =\"CTO\" "
                             "WHEN $^.job.salary > 10000 "
                             "YIELD $^.person.name AS Name, $^.job.salary AS Salary, "
                             "$^.person.create_time AS Time_";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "UPSERT VERTEX ON person \"12345\" "
                             "SET name=\"Tom\", age = 30, name =\"CTO\" "
                             "WHEN salary > 10000 "
                             "YIELD name AS Name, salary AS Salary, create_time AS Time_";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
 }
 
 TEST(Parser, InsertEdge) {
     {
-        GQLParser parser;
         std::string query = "INSERT EDGE transfer(amount, time_) "
                             "VALUES \"12345\"->\"54321\":(3.75, 1537408527)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "INSERT EDGE transfer(amount, time_) "
                             "VALUES \"from\"->\"to\":(3.75, 1537408527)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "INSERT EDGE transfer(amount, time_) "
                             "VALUES \"from\"->\"to\":(3.75, 1537408527)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     // multi edge
     {
-        GQLParser parser;
         std::string query = "INSERT EDGE transfer(amount, time_) "
                             "VALUES \"12345\"->\"54321@1537408527\":(3.75, 1537408527),"
                             "\"56789\"->\"98765@1537408527\":(3.5, 1537408527)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     // Test insert empty value
     {
-        GQLParser parser;
         std::string query = "INSERT EDGE transfer() "
                             "VALUES \"12345\"->\"54321@1537408527\":()";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "INSERT EDGE NO OVERWRITE transfer(amount, time_) "
                             "VALUES \"-12345\"->\"54321\":(3.75, 1537408527)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "INSERT EDGE transfer(amount, time_) "
                             "VALUES \"12345\"->\"54321\"@1537408527:(3.75, 1537408527)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "INSERT EDGE NO OVERWRITE transfer(amount, time_) "
                             "VALUES \"12345\"->\"54321@1537408527\":(3.75, 1537408527)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     // Test insert empty value
     {
-        GQLParser parser;
         std::string query = "INSERT EDGE NO OVERWRITE transfer() "
                             "VALUES \"12345\"->\"54321@1537408527\":()";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
 }
 
 TEST(Parser, UpdateEdge) {
     {
-        GQLParser parser;
         std::string query = "UPDATE EDGE \"12345\" -> \"54321\" OF transfer "
                             "SET amount=3.14, time_=1537408527";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "UPDATE EDGE ON transfer \"12345\" -> \"54321\" "
                             "SET amount=3.14, time_=1537408527";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "UPDATE EDGE \"12345\" -> \"54321\"@789 OF transfer "
                             "SET amount=3.14,time_=1537408527 "
                             "WHEN transfer.amount > 3.14 AND $^.person.name == \"Tom\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "UPDATE EDGE ON transfer \"12345\" -> \"54321\"@789 "
                             "SET amount=3.14,time_=1537408527 "
                             "WHEN amount > 3.14";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "UPDATE EDGE \"12345\" -> \"54321\" OF transfer "
                             "SET amount = 3.14 + $^.job.salary, time_ = 1537408527 "
                             "WHEN transfer.amount > 3.14 OR $^.job.salary >= 10000 "
                             "YIELD transfer.amount, transfer.time_ AS Time_, "
                             "$^.person.name AS PayFrom";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "UPDATE EDGE ON transfer \"12345\" -> \"54321\" "
                             "SET amount = 3.14 + amount, time_ = 1537408527 "
                             "WHEN amount > 3.14 "
                             "YIELD amount, time_ AS Time_";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "UPSERT EDGE \"12345\" -> \"54321\" @789 OF transfer "
                             "SET amount=$^.job.salary + 3.14, time_=1537408527 "
                             "WHEN transfer.amount > 3.14 AND $^.job.salary >= 10000 "
                             "YIELD transfer.amount,transfer.time_, $^.person.name AS Name";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "UPSERT EDGE ON transfer \"12345\" -> \"54321\" @789 "
                             "SET amount=$^.job.salary + 3.14, time_=1537408527 "
                             "WHEN amount > 3.14 AND salary >= 10000 "
                             "YIELD amount, time_, name AS Name";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
 }
 
 TEST(Parser, DeleteVertex) {
     {
-        GQLParser parser;
         std::string query = "DELETE VERTEX \"12345\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "DELETE VERTEX \"12345\",\"23456\",\"34567\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "DELETE VERTEX \"Tom\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "DELETE VERTEX \"Tom\", \"Jerry\", \"Mickey\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "DELETE VERTEX \"Tom\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "DELETE VERTEX \"Tom\", \"Jerry\", \"Mickey\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "GO FROM \"Ann\" OVER schoolmate YIELD $$.person.name as name"
                             "| DELETE VERTEX $-.id";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
 }
 
 TEST(Parser, DeleteEdge) {
     {
-        GQLParser parser;
         std::string query = "DELETE EDGE transfer \"12345\" -> \"5432\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "DELETE EDGE transfer \"123\" -> \"321\", "
                             "\"456\" -> \"654\"@11, \"789\" -> \"987\"@12";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "DELETE EDGE transfer \"jack\" -> \"rose\","
                             "\"mr\" -> \"miss\"@13";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "GO FROM \"Ann\" OVER schoolmate "
                             "YIELD schoolmate._src as src, schoolmate._dst as dst, "
                             "schoolmate._rank as rank"
                             "| DELETE EDGE transfer $-.src -> $-.dst @ $-.rank";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
 }
 
 TEST(Parser, FetchVertex) {
     {
-        GQLParser parser;
         std::string query = "FETCH PROP ON person \"1\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "FETCH PROP ON person \"1\", \"2\", \"3\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "FETCH PROP ON person \"Tom\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "FETCH PROP ON person \"Tom\", \"darion\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "FETCH PROP ON person \"Tom\" "
                             "YIELD person.name, person.age";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "FETCH PROP ON person \"Tom\", \"darion\" "
                             "YIELD person.name, person.age";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "GO FROM \"1\" over edu YIELD edu._dst AS id | "
                             "FETCH PROP ON person $-.id YIELD person.name, person.age";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "$var = GO FROM \"1\" over e1; "
                             "FETCH PROP ON person $var.id YIELD person.name, person.age";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "FETCH PROP ON person \"1\", \"2\", \"3\" "
                             "YIELD DISTINCT person.name, person.age";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "FETCH PROP ON person uuid(\"Tom\")";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "FETCH PROP ON person \"Tom\", \"darion\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "FETCH PROP ON person \"Tom\" "
                             "YIELD person.name, person.age";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "FETCH PROP ON person \"Tom\", \"darion\" "
                             "YIELD person.name, person.age";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "FETCH PROP ON * \"1\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "FETCH PROP ON * \"1\", \"2\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "FETCH PROP ON * $-.id";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "yield \"1\" as id | FETCH PROP ON * $-.id";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "yield \"1\" as id | FETCH PROP ON * $-.id yield friend.id, person.id";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
 }
 
 TEST(Parser, FetchEdge) {
     {
-        GQLParser parser;
         std::string query = "FETCH PROP ON transfer \"12345\" -> \"54321\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "FETCH PROP ON transfer \"12345\" -> \"54321\" "
                             "YIELD transfer.time_";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "GO FROM \"12345\" OVER transfer "
                             "YIELD transfer.time_";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "GO FROM \"12345\" OVER transfer "
                             "YIELD transfer._src AS s, serve._dst AS d | "
                             "FETCH PROP ON transfer $-.s -> $-.d YIELD transfer.amount";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "$var = GO FROM \"12345\" OVER transfer "
                             "YIELD transfer._src AS s, edu._dst AS d; "
                             "FETCH PROP ON service $var.s -> $var.d YIELD service.amount";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     // this will be denied in Semantic Analysis
     {
-        GQLParser parser;
         std::string query = "FETCH PROP ON transfer, another \"12345\" -> \"-54321\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
 }
 
 TEST(Parser, Lookup) {
     {
-        GQLParser parser;
         std::string query = "LOOKUP ON person";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "LOOKUP ON salary, age";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
     }
     {
-        GQLParser parser;
         std::string query = "LOOKUP ON person WHERE person.gender == \"man\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "LOOKUP ON transfer WHERE transfer.amount > 1000 YIELD transfer.amount";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "LOOKUP ON transfer WHERE transfer.amount > 1000 YIELD transfer.amount,"
                             " transfer.test";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
 }
 
 TEST(Parser, subgraph) {
     {
-        GQLParser parser;
         std::string query = "GET SUBGRAPH FROM \"TOM\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "GET SUBGRAPH FROM \"TOM\" BOTH like";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "GET SUBGRAPH FROM \"TOM\" IN like";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "GET SUBGRAPH FROM \"TOM\" OUT like";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "GET SUBGRAPH FROM \"TOM\" IN like OUT serve";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "GET SUBGRAPH 1 STEPS FROM \"TOM\" IN like OUT serve";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "GET SUBGRAPH 2 STEPS FROM \"TOM\" BOTH like";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "GET SUBGRAPH 2 STEPS FROM \"TOM\" IN like";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "GET SUBGRAPH 4 STEPS FROM \"TOM\" IN like OUT serve BOTH owner";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "GET SUBGRAPH 4 STEPS FROM \"TOM\" IN like OUT serve";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
 }
 
 TEST(Parser, AdminOperation) {
     {
-        GQLParser parser;
         std::string query = "SHOW HOSTS";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "SHOW HOSTS graph";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "SHOW HOSTS meta";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "SHOW HOSTS storage";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "SHOW SPACES";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "SHOW PARTS";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "SHOW PARTS 666";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "SHOW TAGS";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "SHOW EDGES";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "SHOW TAG INDEXES";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "SHOW EDGE INDEXES";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "SHOW CREATE SPACE default_space";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "SHOW CREATE TAG person";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "SHOW CREATE EDGE like";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "SHOW CREATE TAG INDEX person_index";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "SHOW CREATE EDGE INDEX like_index";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "SHOW TAG INDEX STATUS";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "SHOW EDGE INDEX STATUS";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "SHOW CHARSET";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "SHOW COLLATION";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "SHOW STATS";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
 }
 
 TEST(Parser, UserOperation) {
     {
-        GQLParser parser;
         std::string query = "CREATE USER user1";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "CREATE USER user1 WITH PASSWORD aaa";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
     }
     {
-        GQLParser parser;
         std::string query = "CREATE USER user1 WITH PASSWORD \"aaa\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
         auto& sentence = result.value();
         EXPECT_EQ(query, sentence->toString());
     }
     {
-        GQLParser parser;
         std::string query = "CREATE USER IF NOT EXISTS user1 WITH PASSWORD \"aaa\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
         auto& sentence = result.value();
         EXPECT_EQ(query, sentence->toString());
     }
     {
-        GQLParser parser;
         std::string query = "ALTER USER user1 WITH PASSWORD \"a\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
         auto& sentence = result.value();
         EXPECT_EQ(query, sentence->toString());
     }
     {
-        GQLParser parser;
         std::string query = "ALTER USER user1 WITH PASSWORD \"a\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
         auto& sentence = result.value();
         EXPECT_EQ(query, sentence->toString());
     }
     {
-        GQLParser parser;
         std::string query = "DROP USER user1";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
         auto& sentence = result.value();
         EXPECT_EQ(query, sentence->toString());
     }
     {
-        GQLParser parser;
         std::string query = "DROP USER IF EXISTS user1";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
         auto& sentence = result.value();
         EXPECT_EQ(query, sentence->toString());
     }
     {
-        GQLParser parser;
         std::string query = "CHANGE PASSWORD \"new password\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
     }
     {
-        GQLParser parser;
         std::string query = "CHANGE PASSWORD account TO \"new password\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
     }
     {
-        GQLParser parser;
         std::string query = "CHANGE PASSWORD account FROM \"old password\" TO \"new password\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
         auto& sentence = result.value();
         EXPECT_EQ(query, sentence->toString());
     }
     {
-        GQLParser parser;
         std::string query = "GRANT ROLE ADMIN ON spacename TO account";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
         auto& sentence = result.value();
         EXPECT_EQ(query, sentence->toString());
     }
     {
-        GQLParser parser;
         std::string query = "GRANT ROLE DBA ON spacename TO account";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
         auto& sentence = result.value();
         EXPECT_EQ(query, sentence->toString());
     }
     {
-        GQLParser parser;
         std::string query = "GRANT ROLE SYSTEM ON spacename TO account";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
     }
     {
-        GQLParser parser;
         std::string query = "REVOKE ROLE ADMIN ON spacename FROM account";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
         auto& sentence = result.value();
         EXPECT_EQ(query, sentence->toString());
     }
     {
-        GQLParser parser;
         std::string query = "SHOW ROLES IN spacename";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
         auto& sentence = result.value();
         EXPECT_EQ(query, sentence->toString());
     }
     {
-        GQLParser parser;
         std::string query = "SHOW USERS";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
         auto& sentence = result.value();
         EXPECT_EQ(query, sentence->toString());
@@ -1656,421 +1459,363 @@ TEST(Parser, UserOperation) {
 
 TEST(Parser, UnreservedKeywords) {
     {
-        GQLParser parser;
         std::string query = "CREATE TAG tag1(space string, spaces string, "
                             "email string, password string, roles string, uuid int, "
                             "path string, variables string, leader string, data string)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "CREATE EDGE edge1(space string, spaces string, "
                             "email string, password string, roles string)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "GO FROM \"123\" OVER guest WHERE $-.EMAIL";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "GO FROM UUID(\"tom\") OVER guest WHERE $-.EMAIL";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "GO FROM \"123\" OVER like YIELD $$.tag1.EMAIL, like.users,"
                             "like._src, like._dst, like.type, $^.tag2.SPACE "
                             "| ORDER BY $-.SPACE";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "GO FROM UUID(\"tom\") OVER like YIELD $$.tag1.EMAIL, like.users,"
                             "like._src, like._dst, like.type, $^.tag2.SPACE "
                             "| ORDER BY $-.SPACE";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "$var = GO FROM \"123\" OVER like;GO FROM $var.SPACE OVER like";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "$var = GO FROM UUID(\"tom\") OVER like;GO FROM $var.SPACE OVER like";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "CREATE TAG status(part int, parts int, job string, jobs string,"
                             " rebuild bool, submit bool, compact bool, "
                             " bidirect bool, force bool, configs string)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
     }
 }
 
 TEST(Parser, Annotation) {
     {
-        GQLParser parser;
         std::string query = "show spaces /* test comment....";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.status().isSyntaxError());
     }
     {
-        GQLParser parser;
         std::string query = "// test comment....";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.status().isStatementEmpty());
     }
     {
-        GQLParser parser;
         std::string query = "# test comment....";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.status().isStatementEmpty());
     }
     {
-        GQLParser parser;
         std::string query = "/* test comment....*/";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.status().isStatementEmpty());
     }
     {
-        GQLParser parser;
         std::string query = "CREATE TAG TAG1(space string) // test....";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "CREATE TAG TAG1(space string) # test....";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "CREATE TAG TAG1/* tag name */(space string)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "CREATE TAG TAG1/* tag name */(space string) // test....";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
 }
 
 TEST(Parser, DownloadAndIngest) {
     {
-        GQLParser parser;
         std::string query = "DOWNLOAD HDFS \"hdfs://127.0.0.1:9090/data\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "INGEST";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
 }
 
 TEST(Parser, Agg) {
     {
-        GQLParser parser;
         std::string query = "ORDER BY $-.id";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "GO FROM \"1\" OVER friend "
                             "YIELD friend.name as name | "
                             "ORDER BY name";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "GO FROM \"1\" OVER friend "
                             "YIELD friend.name as name | "
                             "ORDER BY $-.name";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "GO FROM \"1\" OVER friend "
                             "YIELD friend.name as name | "
                             "ORDER BY $-.name ASC";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "GO FROM \"1\" OVER friend "
                             "YIELD friend.name as name | "
                             "ORDER BY $-.name DESC";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "GO FROM \"1\" OVER friend "
                             "YIELD friend.name as name, friend.age as age | "
                             "ORDER BY $-.name ASC, $-.age DESC";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "GO FROM \"1\" OVER friend "
                             "YIELD friend.name as name, friend.age as age | "
                             "ORDER BY name ASC, age DESC";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
 }
 
 TEST(Parser, ReentrantRecoveryFromFailure) {
-    GQLParser parser;
     {
         std::string query = "USE dumy tag_name";
-        ASSERT_FALSE(parser.parse(query).ok());
+        ASSERT_FALSE(parse(query).ok());
     }
     {
         std::string query = "USE space_name";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
 }
 
 TEST(Parser, IllegalCharacter) {
-    GQLParser parser;
     {
         std::string query = "USE space锛�";
-        ASSERT_FALSE(parser.parse(query).ok());
+        ASSERT_FALSE(parse(query).ok());
     }
     {
         std::string query = "USE space_name锛沀SE space";
-        ASSERT_FALSE(parser.parse(query).ok());
+        ASSERT_FALSE(parse(query).ok());
     }
 }
 
 TEST(Parser, Distinct) {
     {
-        GQLParser parser;
         std::string query = "GO FROM \"1\" OVER friend "
                             "YIELD DISTINCT friend.name as name, friend.age as age";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         // syntax error
         std::string query = "GO FROM \"1\" OVER friend "
                             "YIELD friend.name as name, DISTINCT friend.age as age";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(!result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "GO FROM \"1\" OVER like "
                             "| GO FROM $-.id OVER like | GO FROM $-.id OVER serve "
                             "YIELD DISTINCT serve._dst, $$.team.name";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
 }
 
 TEST(Parser, ConfigOperation) {
     {
-        GQLParser parser;
         std::string query = "SHOW CONFIGS";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "SHOW CONFIGS GRAPH";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "UPDATE CONFIGS storage:name=\"value\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "GET CONFIGS Meta:name";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "UPDATE CONFIGS load_data_interval_secs=120";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "GET CONFIGS load_data_interval_secs";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "UPDATE CONFIGS storage:rocksdb_db_options = "
                             "{ stats_dump_period_sec = 200 }";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "UPDATE CONFIGS rocksdb_db_options={disable_auto_compaction=false}";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "UPDATE CONFIGS storage:rocksdb_db_options = "
                             "{stats_dump_period_sec = 200, disable_auto_compaction = false}";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "UPDATE CONFIGS rocksdb_column_family_options={"
                             "write_buffer_size = 1 * 1024 * 1024}";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "UPDATE CONFIGS storage:rocksdb_db_options = {}";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
     }
 }
 
 TEST(Parser, BalanceOperation) {
     {
-        GQLParser parser;
         std::string query = "BALANCE LEADER";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "BALANCE DATA";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "BALANCE DATA 1234567890";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "BALANCE DATA STOP";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "BALANCE DATA REMOVE 192.168.0.1:50000,192.168.0.1:50001";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "BALANCE DATA REMOVE 192.168.0.1:50000,\"localhost\":50001";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "BALANCE DATA RESET PLAN";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
 }
 
 TEST(Parser, CrashByFuzzer) {
     {
-        GQLParser parser;
         std::string query = ";YIELD\nI41( ,1)GEGE.INGEST";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok()) << result.status();
     }
 }
 
 TEST(Parser, FindPath) {
     {
-        GQLParser parser;
         std::string query = "FIND SHORTEST PATH FROM \"1\" TO \"2\" OVER like";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "FIND ALL PATH FROM \"1\" TO \"2\" OVER like";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "FIND SHORTEST PATH WITH PROP FROM \"1\" TO \"2\" OVER like";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "FIND ALL PATH WITH PROP FROM \"1\" TO \"2\" OVER like";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
 }
 
 TEST(Parser, Limit) {
     {
-        GQLParser parser;
         std::string query = "GO FROM \"1\" OVER work | LIMIT 1";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "GO FROM \"1\" OVER work | LIMIT 1,2";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "GO FROM \"1\" OVER work | LIMIT 1 OFFSET 2";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     // ERROR
     {
-        GQLParser parser;
         std::string query = "GO FROM \"1\" OVER work | LIMIT \"1\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
     }
 }
@@ -2078,7 +1823,6 @@ TEST(Parser, Limit) {
 TEST(Parser, GroupBy) {
     // All fun succeed
     {
-        GQLParser parser;
         std::string query = "GO FROM \"1\" OVER work "
                             "YIELD $$.company.name, $^.person.name AS name "
                             "| GROUP BY $$.company.name , abs($$.company.age+1)"
@@ -2110,11 +1854,10 @@ TEST(Parser, GroupBy) {
                             "F_BIT_OR($^.person.name ), "
                             "F_BIT_XOR($^.person.name )";
 
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "GO FROM \"1\" OVER work "
                             "YIELD $$.company.name, $^.person.name AS name "
                             "| YIELD $$.company.name AS name, "
@@ -2146,206 +1889,183 @@ TEST(Parser, GroupBy) {
                             "F_BIT_OR($^.person.name ), "
                             "F_BIT_XOR($^.person.name )";
 
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     // Error syntax
     {
-        GQLParser parser;
         std::string query = "YIELD rand32() as id, sum(1) as sum, avg(2) as avg GROUP BY id";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
     }
     // All fun error, empty group name
     {
-        GQLParser parser;
         std::string query = "GO FROM \"1\" OVER work "
                             "YIELD $$.company.name, $^.person.name "
                             "| GROUP BY "
                             "YIELD $$.company.name as name, "
                             "COUNT($^.person.name )";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
     }
 }
 
 TEST(Parser, Return) {
     {
-        GQLParser parser;
         std::string query = "RETURN $A IF $A IS NOT NULL";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
 }
 
 TEST(Parser, ErrorMsg) {
     {
-        GQLParser parser;
         std::string query = "CREATE SPACE " + std::string(4097, 'A');
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
         auto error = "SyntaxError: Out of range of the LABEL length, "
                      "the  max length of LABEL is 4096: near `" + std::string(80, 'A') + "'";
         ASSERT_EQ(error, result.status().toString());
     }
     {
-        GQLParser parser;
         std::string query = "INSERT VERTEX person(id) VALUES \"100\":(9223372036854775809) ";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
         auto error = "SyntaxError: Out of range: near `9223372036854775809'";
         ASSERT_EQ(error, result.status().toString());
     }
     // min integer bound checking
+    // TODO(shylock) out of range int64_t
+    // {
+        // std::string query = "INSERT VERTEX person(id) VALUES \"100\":(-9223372036854775808) ";
+        // auto result = parse(query);
+        // ASSERT_TRUE(result.ok()) << result.status();
+    // }
     {
-        GQLParser parser;
-        std::string query = "INSERT VERTEX person(id) VALUES \"100\":(-9223372036854775808) ";
-        auto result = parser.parse(query);
-        ASSERT_TRUE(result.ok());
-    }
-    {
-        GQLParser parser;
         std::string query = "INSERT VERTEX person(id) VALUES \"100\":(-(1+9223372036854775808)) ";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
     }
     {
-        GQLParser parser;
         std::string query = "INSERT VERTEX person(id) VALUES \"100\":(-9223372036854775809) ";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
         auto error = "SyntaxError: Out of range: near `9223372036854775809'";
         ASSERT_EQ(error, result.status().toString());
     }
     // max integer bound checking
     {
-        GQLParser parser;
         std::string query = "INSERT VERTEX person(id) VALUES \"100\":(9223372036854775807) ";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok());
     }
     {
-        GQLParser parser;
         std::string query = "INSERT VERTEX person(id) VALUES \"100\":(+9223372036854775807) ";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok());
     }
     {
-        GQLParser parser;
         std::string query = "INSERT VERTEX person(id) VALUES \"100\":(9223372036854775808) ";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
         auto error = "SyntaxError: Out of range: near `9223372036854775808'";
         ASSERT_EQ(error, result.status().toString());
     }
     {
-        GQLParser parser;
         std::string query = "INSERT VERTEX person(id) VALUES \"100\":(+9223372036854775808) ";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
         auto error = "SyntaxError: Out of range: near `9223372036854775808'";
         ASSERT_EQ(error, result.status().toString());
     }
     {
-        GQLParser parser;
         std::string query = "INSERT VERTEX person(id) VALUES \"100\":(0xFFFFFFFFFFFFFFFFF) ";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
         auto error = "SyntaxError: Out of range: near `0xFFFFFFFFFFFFFFFFF'";
         ASSERT_EQ(error, result.status().toString());
     }
     // min hex integer bound
+    // TODO(shylock) out of range int64_t
+    // {
+        // std::string query = "INSERT VERTEX person(id) VALUES \"100\":(-0x8000000000000000) ";
+        // auto result = parse(query);
+        // ASSERT_TRUE(result.ok()) << result.status();
+    // }
     {
-        GQLParser parser;
-        std::string query = "INSERT VERTEX person(id) VALUES \"100\":(-0x8000000000000000) ";
-        auto result = parser.parse(query);
-        ASSERT_TRUE(result.ok());
-    }
-    {
-        GQLParser parser;
         std::string query = "INSERT VERTEX person(id) VALUES \"100\":(-0x8000000000000001) ";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
         auto error = "SyntaxError: Out of range: near `0x8000000000000001'";
         ASSERT_EQ(error, result.status().toString());
     }
     // max hex integer bound
     {
-        GQLParser parser;
         std::string query = "INSERT VERTEX person(id) VALUES \"100\":(0x7FFFFFFFFFFFFFFF) ";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok());
     }
     {
-        GQLParser parser;
         std::string query = "INSERT VERTEX person(id) VALUES \"100\":(+0x7FFFFFFFFFFFFFFF) ";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok());
     }
     {
-        GQLParser parser;
         std::string query = "INSERT VERTEX person(id) VALUES \"100\":(0x8000000000000000) ";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
         auto error = "SyntaxError: Out of range: near `0x8000000000000000'";
         ASSERT_EQ(error, result.status().toString());
     }
     {
-        GQLParser parser;
         std::string query = "INSERT VERTEX person(id) VALUES \"100\":(+0x8000000000000000) ";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
         auto error = "SyntaxError: Out of range: near `0x8000000000000000'";
         ASSERT_EQ(error, result.status().toString());
     }
     {
-        GQLParser parser;
         std::string query = "INSERT VERTEX person(id) VALUES \"100\":(002777777777777777777777) ";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
         auto error = "SyntaxError: Out of range: near `002777777777777777777777'";
         ASSERT_EQ(error, result.status().toString());
     }
     // min oct integer bound
+    // TODO(shylock) out of range int64_t
+    // {
+        // std::string query = "INSERT VERTEX person(id) VALUES \"100\":(-01000000000000000000000)";
+        // auto result = parse(query);
+        // ASSERT_TRUE(result.ok()) << result.status().toString();
+    // }
     {
-        GQLParser parser;
-        std::string query = "INSERT VERTEX person(id) VALUES \"100\":(-01000000000000000000000) ";
-        auto result = parser.parse(query);
-        ASSERT_TRUE(result.ok()) << result.status().toString();
-    }
-    {
-        GQLParser parser;
         std::string query = "INSERT VERTEX person(id) VALUES \"100\":(-01000000000000000000001) ";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
         auto error = "SyntaxError: Out of range: near `01000000000000000000001'";
         ASSERT_EQ(error, result.status().toString());
     }
     // max oct integer bound
     {
-        GQLParser parser;
         std::string query = "INSERT VERTEX person(id) VALUES \"100\":(0777777777777777777777) ";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status().toString();
     }
     {
-        GQLParser parser;
         std::string query = "INSERT VERTEX person(id) VALUES \"100\":(+0777777777777777777777) ";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status().toString();
     }
     {
-        GQLParser parser;
         std::string query = "INSERT VERTEX person(id) VALUES \"100\":(01000000000000000000000) ";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
         auto error = "SyntaxError: Out of range: near `01000000000000000000000'";
         ASSERT_EQ(error, result.status().toString());
     }
     {
-        GQLParser parser;
         std::string query = "INSERT VERTEX person(id) VALUES \"100\":(+01000000000000000000000) ";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
         auto error = "SyntaxError: Out of range: near `01000000000000000000000'";
         ASSERT_EQ(error, result.status().toString());
@@ -2354,766 +2074,644 @@ TEST(Parser, ErrorMsg) {
 
 TEST(Parser, UseReservedKeyword) {
     {
-        GQLParser parser;
         std::string query = "CREATE TAG tag()";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
 
         query = "CREATE TAG `tag`()";
-        result = parser.parse(query);
-        ASSERT_TRUE(result.ok());
+        result = parse(query);
+        ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "CREATE EDGE edge()";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
 
         query = "CREATE EDGE `edge`()";
-        result = parser.parse(query);
+        result = parse(query);
         ASSERT_TRUE(result.ok());
     }
     {
-        GQLParser parser;
         std::string query = "CREATE TAG `person`(`tag` string)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok());
     }
     {
-        GQLParser parser;
         std::string query = "CREATE TAG `time`(`time` string)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok());
     }
 }
 
 TEST(Parser, TypeCast) {
     {
-        GQLParser parser;
         std::string query = "YIELD (INT)\"123\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok());
     }
     {
-        GQLParser parser;
         std::string query = "YIELD (INT)  \"123\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok());
     }
     {
-        GQLParser parser;
         std::string query = "YIELD (INT)\".123\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok());
     }
     {
-        GQLParser parser;
         std::string query = "YIELD (INT8)\".123\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok());
     }
     {
-        GQLParser parser;
         std::string query = "YIELD (INT16)\".123\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok());
     }
     {
-        GQLParser parser;
         std::string query = "YIELD (INT32)\".123\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok());
     }
     {
-        GQLParser parser;
         std::string query = "YIELD (INT64)\"1.23\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok());
     }
     {
-        GQLParser parser;
         std::string query = "YIELD (INT65)\"1.23\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
     }
     {
-        GQLParser parser;
         std::string query = "YIELD (DOUBLE)\"123abc\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok());
     }
     {
-        GQLParser parser;
         std::string query = "YIELD (INT)\"abc123\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok());
     }
     {
-        GQLParser parser;
         std::string query = "YIELD (FLOAT)\"123\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok());
     }
     {
-        GQLParser parser;
         std::string query = "YIELD (FLOAT)\"1.23\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok());
     }
     {
-        GQLParser parser;
         std::string query = "YIELD (FLOAT)\".123\"";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok());
     }
     {
-        GQLParser parser;
         std::string query = "YIELD (STRING)123";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok());
     }
     {
-        GQLParser parser;
         std::string query = "YIELD (STRING)1.23";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok());
     }
     {
-        GQLParser parser;
         std::string query = "YIELD (MAP)123";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
     }
     {
-        GQLParser parser;
         std::string query = "YIELD (INT)true";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok());
     }
 }
 
 TEST(Parser, Match) {
     {
-        GQLParser parser;
         std::string query = "MATCH () -- () RETURN *";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "MATCH () <-- () RETURN *";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "MATCH () --> () RETURN *";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "MATCH () <--> () RETURN *";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "MATCH (a) --> (b) RETURN *";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "MATCH (a:person) --> (b) RETURN *";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "MATCH (:person {name: 'Tom'}) --> (:person {name: 'Jerry'}) RETURN *";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "MATCH (a) -[]- (b) RETURN *";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "MATCH (a) -[]-> (b) RETURN *";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "MATCH (a) <-[]- (b) RETURN *";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "MATCH (a) -[m]- (b) RETURN *";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "MATCH (a) <-[m:like]-> (b) RETURN *";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "MATCH (a) <-[m:like{likeness: 99}]-> (b) RETURN *";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "MATCH (a) -[m]- (b) WHERE a.name == 'Tom' RETURN a";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "MATCH (a) -[m]- (b) RETURN a as Person";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "MATCH (a) -[m:like|serve]- (b) RETURN a as Person";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "MATCH (a) -[m:like|:serve]- (b) RETURN a as Person";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "MATCH (a) -[m:like*]- (b) RETURN a as Person";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "MATCH (a) -[m:like*2]- (b) RETURN a as Person";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "MATCH (a) -[m:like*2..]- (b) RETURN a as Person";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "MATCH (a) -[m:like*..2]- (b) RETURN a as Person";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "MATCH (a) -[m:like*2..4]- (b) RETURN a as Person";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "MATCH (a) -[m:like*..2]- (b) RETURN a as Person";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "MATCH p = (a) -[m:like*..2]- (b) RETURN p as Path";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "OPTIONAL MATCH (a) -[m]- (b) RETURN a as Person";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "MATCH (a) -[m]- (b) RETURN DISTINCT a as Person";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "MATCH (a) -[m]- (b) RETURN a as Person ORDER BY Person";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "MATCH (a) -[m]- (b) RETURN a as Person ORDER BY Person SKIP 1";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "MATCH (a) -[m]- (b) RETURN a as Person ORDER BY Person SKIP 1 LIMIT 2";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "MATCH (a) -[m]- (b) RETURN a as Person SKIP 1 LIMIT 2";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "MATCH (a) -[m]- (b) RETURN a as Person SKIP 1";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "MATCH (a) -[m]- (b) RETURN a as Person LIMIT 1";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "WITH a AS b RETURN b";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "WITH DISTINCT a as b RETURN b";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "WITH a as b ORDER BY b RETURN b";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "WITH a as b ORDER BY b SKIP 1 LIMIT 1 RETURN b";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "WITH a as b SKIP 1 LIMIT 1 RETURN b";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "WITH a as b LIMIT 1 RETURN b";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "WITH a as b SKIP 1 RETURN b";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "WITH a as b SKIP 1 WHERE b > 0 RETURN b";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "UNWIND a as b RETURN b";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "MATCH (a) MATCH (b) -[m]- (c) RETURN a,b,c";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "UNWIND a AS b MATCH (c) -[m]- (d) RETURN b,c,d";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "UNWIND a AS b MATCH (c) MATCH (d) WITH e MATCH (f) RETURN b,c,d";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
 }
 
 TEST(Parser, MatchMultipleTags) {
     {
-        GQLParser parser;
         std::string query = "MATCH (a:person:player) --> (b) RETURN *";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query =
             "MATCH (:person {name: 'Tom'}:player {id: 233}) --> (:person {name: 'Jerry'}) RETURN *";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query =
             "MATCH (:person:player {id: 233}) --> (:person {name: 'Jerry'}) RETURN *";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "MATCH () --> (:person {name: 'Jerry'}:player {id: 233}) RETURN *";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "MATCH () --> (:person {name: 'Jerry'}:player) RETURN *";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
 }
 
 TEST(Parser, Zone) {
     {
-        GQLParser parser;
         std::string query = "SHOW GROUPS";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "SHOW ZONES";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "ADD ZONE zone_0 127.0.0.1:8989,127.0.0.1:8988,127.0.0.1:8987";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "ADD HOST 127.0.0.1:8989 INTO ZONE zone_0";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "DROP HOST 127.0.0.1:8989 FROM ZONE zone_0";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "DESC ZONE zone_0";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "DESCRIBE ZONE zone_0";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "DROP ZONE zone_0";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "ADD GROUP group_0 zone_0,zone_1,zone_2";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "ADD ZONE zone_3 INTO GROUP group_0";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "DROP ZONE zone_3 FROM GROUP group_0";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "DESC GROUP group_0";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "DESCRIBE GROUP group_0";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "DROP GROUP group_0";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
 }
 
 TEST(Parser, FullText) {
     {
-        GQLParser parser;
         std::string query = "LOOKUP ON t1 WHERE PREFIX(t1.c1, \"a\")";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "LOOKUP ON t1 WHERE WILDCARD(t1.c1, \"a\")";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "LOOKUP ON t1 WHERE REGEXP(t1.c1, \"a\")";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "LOOKUP ON t1 WHERE FUZZY(t1.c1, \"a\")";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "LOOKUP ON t1 WHERE PREFIX(t1.c1, \"a\", 1)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "LOOKUP ON t1 WHERE WILDCARD(t1.c1, \"a\", 1)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "LOOKUP ON t1 WHERE REGEXP(t1.c1, \"a\", 1)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "LOOKUP ON t1 WHERE FUZZY(t1.c1, \"a\", 1)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "LOOKUP ON t1 WHERE PREFIX(t1.c1, \"a\", 1, 2)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "LOOKUP ON t1 WHERE WILDCARD(t1.c1, \"a\", 1, 2)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "LOOKUP ON t1 WHERE REGEXP(t1.c1, \"a\", 1, 2)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "LOOKUP ON t1 WHERE FUZZY(t1.c1, \"a\", 1, 2)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "LOOKUP ON t1 WHERE FUZZY(t1.c1, \"a\", AUTO, AND)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "LOOKUP ON t1 WHERE FUZZY(t1.c1, \"a\", AUTO, OR)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "LOOKUP ON t1 WHERE FUZZY(t1.c1, \"a\", 0, AND)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "LOOKUP ON t1 WHERE FUZZY(t1.c1, \"a\", 0, OR)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "LOOKUP ON t1 WHERE FUZZY(t1.c1, \"a\", 0, OR, 1)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "LOOKUP ON t1 WHERE FUZZY(t1.c1, \"a\", 0, OR, 1, 1)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "LOOKUP ON t1 WHERE FUZZY(t1.c1, \"a\", 0, OR, -1, 1)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
     }
     {
-        GQLParser parser;
         std::string query = "LOOKUP ON t1 WHERE FUZZY(t1.c1, \"a\", 0, OR, 1, -1)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
     }
     {
-        GQLParser parser;
         std::string query = "LOOKUP ON t1 WHERE FUZZY(t1.c1, \"a\", -1, OR, 1, 1)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
     }
     {
-        GQLParser parser;
         std::string query = "LOOKUP ON t1 WHERE FUZZY(t1.c1, \"a\", 4, OR, 1, 1)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
     }
     {
-        GQLParser parser;
         std::string query = "LOOKUP ON t1 WHERE PREFIX(t1.c1, \"a\", -1, 2)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
     }
     {
-        GQLParser parser;
         std::string query = "LOOKUP ON t1 WHERE PREFIX(t1.c1, \"a\", 1, -2)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
     }
     {
-        GQLParser parser;
         std::string query = "LOOKUP ON t1 WHERE PREFIX(t1.c1, \"a\", AUTO, AND)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
     }
     {
-        GQLParser parser;
         std::string query = "LOOKUP ON t1 WHERE WILDCARD(t1.c1, \"a\", AUTO, AND)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
     }
     {
-        GQLParser parser;
         std::string query = "LOOKUP ON t1 WHERE REGEXP(t1.c1, \"a\", AUTO, AND)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
     }
 }
 
 TEST(Parser, FullTextServiceTest) {
     {
-        GQLParser parser;
         std::string query = "ADD LISTENER ELASTICSEARCH 127.0.0.1:12000";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "ADD LISTENER ELASTICSEARCH 127.0.0.1:12000, 127.0.0.1:12001";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "REMOVE LISTENER ELASTICSEARCH";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "SHOW LISTENER";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "SIGN IN TEXT SERVICE (127.0.0.1:9200)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "SIGN IN TEXT SERVICE (127.0.0.1:9200), (127.0.0.1:9300)";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "SIGN IN TEXT SERVICE (127.0.0.1:9200, \"user\", \"password\")";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "SIGN IN TEXT SERVICE (127.0.0.1:9200, \"user\", \"password\"), "
                             "(127.0.0.1:9200, \"user\", \"password\")";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "SIGN OUT TEXT SERVICE";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
     {
-        GQLParser parser;
         std::string query = "SIGN IN TEXT SERVICE (127.0.0.1:9200, \"user\")";
-        auto result = parser.parse(query);
+        auto result = parse(query);
         ASSERT_FALSE(result.ok());
     }
 }
 
 TEST(Parser, JobTest) {
-    GQLParser parser;
-    auto checkTest = [&parser] (const std::string& query, const std::string expectedStr) {
-        auto result = parser.parse(query);
+    auto checkTest = [] (const std::string& query, const std::string expectedStr) {
+        auto result = parse(query);
         ASSERT_TRUE(result.ok()) << query << ":" << result.status();
         ASSERT_EQ(result.value()->toString(), expectedStr);
     };
diff --git a/src/service/QueryInstance.cpp b/src/service/QueryInstance.cpp
index 231b07d45ee66aad1084c270f1e23af7bf35c406..98f0ceab94a8f423e8576ad85696569d29fb89b1 100644
--- a/src/service/QueryInstance.cpp
+++ b/src/service/QueryInstance.cpp
@@ -15,6 +15,7 @@
 #include "planner/PlanNode.h"
 #include "scheduler/Scheduler.h"
 #include "validator/Validator.h"
+#include "util/AstUtils.h"
 #include "stats/StatsDef.h"
 
 using nebula::opt::Optimizer;
diff --git a/src/util/AstUtils.h b/src/util/AstUtils.h
new file mode 100644
index 0000000000000000000000000000000000000000..31caec4a5d582e79f5b075cd6af4d6cc648fea33
--- /dev/null
+++ b/src/util/AstUtils.h
@@ -0,0 +1,39 @@
+/* Copyright (c) 2020 vesoft inc. All rights reserved.
+ *
+ * This source code is licensed under Apache 2.0 License,
+ * attached with Common Clause Condition 1.0, found in the LICENSES directory.
+ */
+
+#ifndef UTIL_ASTUTIL_H_
+#define UTIL_ASTUTIL_H_
+
+#include "parser/GQLParser.h"
+
+namespace nebula {
+namespace graph {
+
+class AstUtils final {
+public:
+    explicit AstUtils(...) = delete;
+
+    static Status reprAstCheck(const Sentence& origin) {
+        auto toString = origin.toString();
+        auto copyResult = GQLParser().parse(toString);
+        if (!copyResult.ok()) {
+            return Status::Error("The repr sentence `%s' can't be parsed, error: `%s'.",
+                                 toString.c_str(),
+                                 copyResult.status().toString().c_str());
+        }
+        auto copyToString = copyResult.value()->toString();
+        if (toString != copyToString) {
+            return Status::Error("The reparsed ast `%s' is different from origin `%s'.",
+                                 copyToString.c_str(),
+                                 toString.c_str());
+        }
+        return Status::OK();
+    }
+};
+
+}   // namespace graph
+}   // namespace nebula
+#endif   // UTIL_ASTUTIL_H_
diff --git a/src/util/SchemaUtil.cpp b/src/util/SchemaUtil.cpp
index 3c73d9b23d4697ac163492ba108cc9b75c54604a..7db3d95c02e0066642c08f7f3083554c1e8bfd1b 100644
--- a/src/util/SchemaUtil.cpp
+++ b/src/util/SchemaUtil.cpp
@@ -195,18 +195,7 @@ StatusOr<DataSet> SchemaUtil::toShowCreateSchema(bool isTag,
                 LOG(ERROR) << "Internal error: the default value is wrong expression.";
                 continue;
             }
-            if (expr->kind() == Expression::Kind::kConstant) {
-                QueryExpressionContext ctx;
-                auto& value = expr->eval(ctx(nullptr));
-                auto toStr = value.toString();
-                if (value.isNumeric() || value.isBool()) {
-                    createStr += " DEFAULT " + toStr;
-                } else {
-                    createStr += " DEFAULT \"" + toStr + "\"";
-                }
-            } else {
-                createStr += " DEFAULT " + expr->toString();
-            }
+            createStr += " DEFAULT " + expr->toString();
         }
         createStr += ",\n";
     }
diff --git a/src/util/test/ExpressionUtilsTest.cpp b/src/util/test/ExpressionUtilsTest.cpp
index 658493960fe5d6efff19f694b6c22a8f46697926..75b202db10012d5426d06feac83a21811f387859 100644
--- a/src/util/test/ExpressionUtilsTest.cpp
+++ b/src/util/test/ExpressionUtilsTest.cpp
@@ -374,11 +374,11 @@ TEST_F(ExpressionUtilsTest, pushOrs) {
         rels.emplace_back(std::move(r));
     }
     auto t = ExpressionUtils::pushOrs(rels);
-    auto expected = std::string("(((((tag0.col0==val0) OR "
-                                "(tag1.col1==val1)) OR "
-                                "(tag2.col2==val2)) OR "
-                                "(tag3.col3==val3)) OR "
-                                "(tag4.col4==val4))");
+    auto expected = std::string("(((((tag0.col0==\"val0\") OR "
+                                "(tag1.col1==\"val1\")) OR "
+                                "(tag2.col2==\"val2\")) OR "
+                                "(tag3.col3==\"val3\")) OR "
+                                "(tag4.col4==\"val4\"))");
     ASSERT_EQ(expected, t->toString());
 }
 
@@ -393,11 +393,11 @@ TEST_F(ExpressionUtilsTest, pushAnds) {
         rels.emplace_back(std::move(r));
     }
     auto t = ExpressionUtils::pushAnds(rels);
-    auto expected = std::string("(((((tag0.col0==val0) AND "
-                                "(tag1.col1==val1)) AND "
-                                "(tag2.col2==val2)) AND "
-                                "(tag3.col3==val3)) AND "
-                                "(tag4.col4==val4))");
+    auto expected = std::string("(((((tag0.col0==\"val0\") AND "
+                                "(tag1.col1==\"val1\")) AND "
+                                "(tag2.col2==\"val2\")) AND "
+                                "(tag3.col3==\"val3\")) AND "
+                                "(tag4.col4==\"val4\"))");
     ASSERT_EQ(expected, t->toString());
 }
 
diff --git a/src/validator/GroupByValidator.cpp b/src/validator/GroupByValidator.cpp
index f49117cabf1283d0ad013186ce8775e60f6a1ca6..475398acc8c81c092edc280dc779d030c2051aaa 100644
--- a/src/validator/GroupByValidator.cpp
+++ b/src/validator/GroupByValidator.cpp
@@ -216,7 +216,7 @@ Status GroupByValidator::checkAggExpr(AggregateExpression* aggExpr) {
     }
 
     if (iter->second != AggregateExpression::Function::kCount) {
-        if (aggArg->toString() == "*") {
+        if (aggArg->toString() == "\"*\"") {
             return Status::SemanticError("Could not apply aggregation function `%s' on `*`",
                                          aggExpr->toString().c_str());
         }
diff --git a/src/validator/test/FetchVerticesTest.cpp b/src/validator/test/FetchVerticesTest.cpp
index 186a02b61e1c709d6a7a75c8febcf8bc3772df27..0129b510867fe8bab0e32e771a8b51c5555c262b 100644
--- a/src/validator/test/FetchVerticesTest.cpp
+++ b/src/validator/test/FetchVerticesTest.cpp
@@ -16,9 +16,9 @@ namespace graph {
 class FetchVerticesValidatorTest : public ValidatorTestBase {
 protected:
     QueryContext *getQCtx(const std::string &query) {
-        auto status = validate(query);
-        EXPECT_TRUE(status.ok());
-        return std::move(status).value();
+        auto result = validate(query);
+        EXPECT_TRUE(result.ok()) << result.status();
+        return std::move(result).value();
     }
 };
 
diff --git a/src/validator/test/ValidatorTestBase.h b/src/validator/test/ValidatorTestBase.h
index 34966b529bd04858738e4373703482b5dda7d9a4..7c4c1a47acd89a5f6456cc2cb4b729818ce2f2b4 100644
--- a/src/validator/test/ValidatorTestBase.h
+++ b/src/validator/test/ValidatorTestBase.h
@@ -22,6 +22,7 @@
 #include "validator/Validator.h"
 #include "validator/test/MockSchemaManager.h"
 #include "validator/test/MockIndexManager.h"
+#include "util/AstUtils.h"
 
 namespace nebula {
 namespace graph {
@@ -47,6 +48,7 @@ protected:
         if (!result.ok()) {
             return std::move(result).status();
         }
+        NG_RETURN_IF_ERROR(AstUtils::reprAstCheck(*result.value()));
         auto sentences = pool_->add(std::move(result).value().release());
         auto qctx = buildContext();
         NG_RETURN_IF_ERROR(Validator::validate(sentences, qctx));
diff --git a/src/validator/test/YieldValidatorTest.cpp b/src/validator/test/YieldValidatorTest.cpp
index 2d6ec01abd99a3f7c14cb5fd26f4031a7dfce6cf..bcd6503180aa51c0889803334439e59f33be35b1 100644
--- a/src/validator/test/YieldValidatorTest.cpp
+++ b/src/validator/test/YieldValidatorTest.cpp
@@ -119,7 +119,8 @@ TEST_F(YieldValidatorTest, FuncitonCall) {
         std::string query = "YIELD abs(\"test\")";
         auto result = checkResult(query);
         EXPECT_EQ(std::string(result.message()),
-                  "SemanticError: `abs(test)' is not a valid expression : Parameter's type error");
+                  "SemanticError: `abs(\"test\")' is not a valid expression : "
+                  "Parameter's type error");
     }
     {
         std::string query = "YIELD noexist(12)";
@@ -164,13 +165,13 @@ TEST_F(YieldValidatorTest, TypeCastTest) {
         std::string query = "YIELD (int)\"123abc\"";
         auto result = checkResult(query);
         EXPECT_EQ(std::string(result.message()),
-                  "SemanticError: `(INT)123abc' is not a valid expression ");
+                  "SemanticError: `(INT)\"123abc\"' is not a valid expression ");
     }
     {
         std::string query = "YIELD (int)\"abc123\"";
         auto result = checkResult(query);
         EXPECT_EQ(std::string(result.message()),
-                  "SemanticError: `(INT)abc123' is not a valid expression ");
+                  "SemanticError: `(INT)\"abc123\"' is not a valid expression ");
     }
     {
         std::string query = "YIELD (doublE)\"123\"";
@@ -184,7 +185,7 @@ TEST_F(YieldValidatorTest, TypeCastTest) {
         std::string query = "YIELD (doublE)\".a123\"";
         auto result = checkResult(query);
         EXPECT_EQ(std::string(result.message()),
-                  "SemanticError: `(FLOAT).a123' is not a valid expression ");
+                  "SemanticError: `(FLOAT)\".a123\"' is not a valid expression ");
     }
     {
         std::string query = "YIELD (STRING)1.23";
diff --git a/tests/tck/features/expression/EndsWith.feature b/tests/tck/features/expression/EndsWith.feature
index c371d8c97f9d2d54401772eae9b073f80709b6f4..fe67f9fc0cf405ac00001509b00211f15b161c6a 100644
--- a/tests/tck/features/expression/EndsWith.feature
+++ b/tests/tck/features/expression/EndsWith.feature
@@ -13,50 +13,50 @@ Feature: Ends With Expression
       YIELD 'apple' ENDS WITH 'le'
       """
     Then the result should be, in any order:
-      | (apple ENDS WITH le) |
-      | true                 |
+      | ("apple" ENDS WITH "le") |
+      | true                     |
     When executing query:
       """
       YIELD 'apple' ENDS WITH 'app'
       """
     Then the result should be, in any order:
-      | (apple ENDS WITH app) |
-      | false                 |
+      | ("apple" ENDS WITH "app") |
+      | false                     |
     When executing query:
       """
       YIELD 'apple' ENDS WITH 'a'
       """
     Then the result should be, in any order:
-      | (apple ENDS WITH a) |
-      | false               |
+      | ("apple" ENDS WITH "a") |
+      | false                   |
     When executing query:
       """
       YIELD 'apple' ENDS WITH 'e'
       """
     Then the result should be, in any order:
-      | (apple ENDS WITH e) |
-      | true                |
+      | ("apple" ENDS WITH "e") |
+      | true                    |
     When executing query:
       """
       YIELD 'apple' ENDS WITH 'E'
       """
     Then the result should be, in any order:
-      | (apple ENDS WITH E) |
-      | false               |
+      | ("apple" ENDS WITH "E") |
+      | false                   |
     When executing query:
       """
       YIELD 'apple' ENDS WITH 'b'
       """
     Then the result should be, in any order:
-      | (apple ENDS WITH b) |
-      | false               |
+      | ("apple" ENDS WITH "b") |
+      | false                   |
     When executing query:
       """
       YIELD '123' ENDS WITH '3'
       """
     Then the result should be, in any order:
-      | (123 ENDS WITH 3) |
-      | true              |
+      | ("123" ENDS WITH "3") |
+      | true                  |
     When executing query:
       """
       YIELD 123 ENDS WITH 3
@@ -71,50 +71,50 @@ Feature: Ends With Expression
       YIELD 'apple' NOT ENDS WITH 'le'
       """
     Then the result should be, in any order:
-      | (apple NOT ENDS WITH le) |
-      | false                    |
+      | ("apple" NOT ENDS WITH "le") |
+      | false                        |
     When executing query:
       """
       YIELD 'apple' NOT ENDS WITH 'app'
       """
     Then the result should be, in any order:
-      | (apple NOT ENDS WITH app) |
-      | true                      |
+      | ("apple" NOT ENDS WITH "app") |
+      | true                          |
     When executing query:
       """
       YIELD 'apple' NOT ENDS WITH 'a'
       """
     Then the result should be, in any order:
-      | (apple NOT ENDS WITH a) |
-      | true                    |
+      | ("apple" NOT ENDS WITH "a") |
+      | true                        |
     When executing query:
       """
       YIELD 'apple' NOT ENDS WITH 'e'
       """
     Then the result should be, in any order:
-      | (apple NOT ENDS WITH e) |
-      | false                   |
+      | ("apple" NOT ENDS WITH "e") |
+      | false                       |
     When executing query:
       """
       YIELD 'apple' NOT ENDS WITH 'E'
       """
     Then the result should be, in any order:
-      | (apple NOT ENDS WITH E) |
-      | true                    |
+      | ("apple" NOT ENDS WITH "E") |
+      | true                        |
     When executing query:
       """
       YIELD 'apple' NOT ENDS WITH 'b'
       """
     Then the result should be, in any order:
-      | (apple NOT ENDS WITH b) |
-      | true                    |
+      | ("apple" NOT ENDS WITH "b") |
+      | true                        |
     When executing query:
       """
       YIELD '123' NOT ENDS WITH '3'
       """
     Then the result should be, in any order:
-      | (123 NOT ENDS WITH 3) |
-      | false                 |
+      | ("123" NOT ENDS WITH "3") |
+      | false                     |
     When executing query:
       """
       YIELD 123 NOT ENDS WITH 3
diff --git a/tests/tck/features/expression/Predicate.feature b/tests/tck/features/expression/Predicate.feature
index 44e8d3d9b9a0e7e903f1e2fd1ebd15d8284ce54a..79e7d5858f0160b07fb2a3977a420b6c99e2406c 100644
--- a/tests/tck/features/expression/Predicate.feature
+++ b/tests/tck/features/expression/Predicate.feature
@@ -88,7 +88,7 @@ Feature: Predicate
       """
       YIELD single(n IN "Tom" WHERE n == 3) AS r
       """
-    Then a SemanticError should be raised at runtime: `single(n IN Tom WHERE (n==3))': Invalid colletion type, expected type of LIST, but was: STRING
+    Then a SemanticError should be raised at runtime: `single(n IN "Tom" WHERE (n==3))': Invalid colletion type, expected type of LIST, but was: STRING
     When executing query:
       """
       YIELD single(n IN NULL WHERE n == 3) AS r
diff --git a/tests/tck/features/expression/Reduce.feature b/tests/tck/features/expression/Reduce.feature
index 09f2a1638f2a73ced31180cf1db755c87ee48d0f..25ad1710b85501bb40b7126a1db5ec362dd7b27c 100644
--- a/tests/tck/features/expression/Reduce.feature
+++ b/tests/tck/features/expression/Reduce.feature
@@ -86,7 +86,7 @@ Feature: Reduce
       """
       YIELD reduce(totalNum = 10, n IN "jerry" | totalNum + n) AS r
       """
-    Then a SemanticError should be raised at runtime: `reduce(totalNum = 10, n IN jerry | (totalNum+n))': Invalid colletion type, expected type of LIST, but was: STRING
+    Then a SemanticError should be raised at runtime: `reduce(totalNum = 10, n IN "jerry" | (totalNum+n))': Invalid colletion type, expected type of LIST, but was: STRING
     When executing query:
       """
       YIELD reduce(totalNum = 10, n IN NULL | totalNum + n) AS r
diff --git a/tests/tck/features/expression/StartsWith.feature b/tests/tck/features/expression/StartsWith.feature
index 5350857f9520ccb792faa67e3b8fdd40da0a64b1..9b7c650c4374ce45ea2b0e5ebc7861470df56524 100644
--- a/tests/tck/features/expression/StartsWith.feature
+++ b/tests/tck/features/expression/StartsWith.feature
@@ -13,36 +13,36 @@ Feature: Starts With Expression
       YIELD 'apple' STARTS WITH 'app'
       """
     Then the result should be, in any order:
-      | (apple STARTS WITH app) |
-      | true                    |
+      | ("apple" STARTS WITH "app") |
+      | true                        |
     When executing query:
       """
       YIELD 'apple' STARTS WITH 'a'
       """
     Then the result should be, in any order:
-      | (apple STARTS WITH a) |
-      | true                  |
+      | ("apple" STARTS WITH "a") |
+      | true                      |
     When executing query:
       """
       YIELD 'apple' STARTS WITH 'A'
       """
     Then the result should be, in any order:
-      | (apple STARTS WITH A) |
-      | false                 |
+      | ("apple" STARTS WITH "A") |
+      | false                     |
     When executing query:
       """
       YIELD 'apple' STARTS WITH 'b'
       """
     Then the result should be, in any order:
-      | (apple STARTS WITH b) |
-      | false                 |
+      | ("apple" STARTS WITH "b") |
+      | false                     |
     When executing query:
       """
       YIELD '123' STARTS WITH '1'
       """
     Then the result should be, in any order:
-      | (123 STARTS WITH 1) |
-      | true                |
+      | ("123" STARTS WITH "1") |
+      | true                    |
     When executing query:
       """
       YIELD 123 STARTS WITH 1
@@ -57,36 +57,36 @@ Feature: Starts With Expression
       YIELD 'apple' NOT STARTS WITH 'app'
       """
     Then the result should be, in any order:
-      | (apple NOT STARTS WITH app) |
-      | false                       |
+      | ("apple" NOT STARTS WITH "app") |
+      | false                           |
     When executing query:
       """
       YIELD 'apple' NOT STARTS WITH 'a'
       """
     Then the result should be, in any order:
-      | (apple NOT STARTS WITH a) |
-      | false                     |
+      | ("apple" NOT STARTS WITH "a") |
+      | false                         |
     When executing query:
       """
       YIELD 'apple' NOT STARTS WITH 'A'
       """
     Then the result should be, in any order:
-      | (apple NOT STARTS WITH A) |
-      | true                      |
+      | ("apple" NOT STARTS WITH "A") |
+      | true                          |
     When executing query:
       """
       YIELD 'apple' NOT STARTS WITH 'b'
       """
     Then the result should be, in any order:
-      | (apple NOT STARTS WITH b) |
-      | true                      |
+      | ("apple" NOT STARTS WITH "b") |
+      | true                          |
     When executing query:
       """
       YIELD '123' NOT STARTS WITH '1'
       """
     Then the result should be, in any order:
-      | (123 NOT STARTS WITH 1) |
-      | false                   |
+      | ("123" NOT STARTS WITH "1") |
+      | false                       |
     When executing query:
       """
       YIELD 123 NOT STARTS WITH 1
diff --git a/tests/tck/features/match/Base.IntVid.feature b/tests/tck/features/match/Base.IntVid.feature
index 4e4a945b17798e0325f0506eb32dd8232fd7edf5..be10473b7cb266366afe058f25b731cdf19aab53 100644
--- a/tests/tck/features/match/Base.IntVid.feature
+++ b/tests/tck/features/match/Base.IntVid.feature
@@ -372,7 +372,7 @@ Feature: Basic match
       """
       MATCH (v{name: "Tim Duncan"}) return v
       """
-    Then a ExecutionError should be raised at runtime: Can't solve the start vids from the sentence: MATCH (v{name:Tim Duncan}) RETURN v
+    Then a ExecutionError should be raised at runtime: Can't solve the start vids from the sentence: MATCH (v{name:"Tim Duncan"}) RETURN v
     When executing query:
       """
       MATCH (v:player:bachelor) RETURN v
diff --git a/tests/tck/features/match/Base.feature b/tests/tck/features/match/Base.feature
index c3a84b86300145ef7837b757cc96a590e2af3f5b..2536d43697898ffd3a8934a4a4aebba6e9354e3b 100644
--- a/tests/tck/features/match/Base.feature
+++ b/tests/tck/features/match/Base.feature
@@ -377,7 +377,7 @@ Feature: Basic match
       """
       MATCH (v{name: "Tim Duncan"}) return v
       """
-    Then a ExecutionError should be raised at runtime: Can't solve the start vids from the sentence: MATCH (v{name:Tim Duncan}) RETURN v
+    Then a ExecutionError should be raised at runtime: Can't solve the start vids from the sentence: MATCH (v{name:"Tim Duncan"}) RETURN v
     When executing query:
       """
       MATCH (v:player:bachelor) RETURN v
diff --git a/tests/tck/features/update/Update.IntVid.feature b/tests/tck/features/update/Update.IntVid.feature
index dc8541afbd27e8d8a4d59b94fa39c22c33684eca..4edbf97bf85f58c6aae91e4f6f6a091424967e73 100644
--- a/tests/tck/features/update/Update.IntVid.feature
+++ b/tests/tck/features/update/Update.IntVid.feature
@@ -387,7 +387,7 @@ Feature: Update int vid of vertex and edge
       WHEN $^.student.age > 15 AND $^.student.gender == "male"
       YIELD select.grade AS Grade, select.year AS Year
       """
-    Then a SemanticError should be raised at runtime: Has wrong expr in `(($^.student.age>15) AND ($^.student.gender==male))'
+    Then a SemanticError should be raised at runtime: Has wrong expr in `(($^.student.age>15) AND ($^.student.gender=="male"))'
     When executing query:
       """
       UPSERT EDGE ON select 201 -> 101@0
diff --git a/tests/tck/features/update/Update.feature b/tests/tck/features/update/Update.feature
index c1dbc72730950e3edce007a8c7974bef58f46025..dd75755e5c3d0f327fc722631ee3e89f609989f5 100644
--- a/tests/tck/features/update/Update.feature
+++ b/tests/tck/features/update/Update.feature
@@ -257,7 +257,7 @@ Feature: Update string vid of vertex and edge
       WHEN "xyz"
       YIELD $^.course.name AS Name, $^.course.credits AS Credits
       """
-    Then a SemanticError should be raised at runtime: `xyz', expected Boolean, but was `STRING'
+    Then a SemanticError should be raised at runtime: `"xyz"', expected Boolean, but was `STRING'
     When executing query:
       """
       UPDATE VERTEX ON course "101"
@@ -273,7 +273,7 @@ Feature: Update string vid of vertex and edge
       WHEN "xyz"
       YIELD $^.course.name AS Name, $^.course.credits AS Credits
       """
-    Then a SemanticError should be raised at runtime: `xyz', expected Boolean, but was `STRING'
+    Then a SemanticError should be raised at runtime: `"xyz"', expected Boolean, but was `STRING'
     # make sure TagName and PropertyName must exist in all clauses
     When executing query:
       """
@@ -432,7 +432,7 @@ Feature: Update string vid of vertex and edge
       WHEN $^.student.age > 15 AND $^.student.gender == "male"
       YIELD select.grade AS Grade, select.year AS Year
       """
-    Then a SemanticError should be raised at runtime: Has wrong expr in `(($^.student.age>15) AND ($^.student.gender==male))'
+    Then a SemanticError should be raised at runtime: Has wrong expr in `(($^.student.age>15) AND ($^.student.gender=="male"))'
     When executing query:
       """
       UPSERT EDGE "201" -> "101"@0 OF select
diff --git a/tests/tck/features/yield/NoSpaceChosen.feature b/tests/tck/features/yield/NoSpaceChosen.feature
index 4822d8e7a22a079053c75a486b0300bad59eac29..352c09115f41bd6611173d4020803d3725bcad39 100644
--- a/tests/tck/features/yield/NoSpaceChosen.feature
+++ b/tests/tck/features/yield/NoSpaceChosen.feature
@@ -16,7 +16,7 @@ Feature: Yield
       YIELD 1+1, '1+1', (int)3.14, (string)(1+1), (string)true
       """
     Then the result should be, in any order:
-      | (1+1) | 1+1   | (INT)3.14 | (STRING)(1+1) | (STRING)true |
+      | (1+1) | "1+1" | (INT)3.14 | (STRING)(1+1) | (STRING)true |
       | 2     | "1+1" | 3         | "2"           | "true"       |
 
   Scenario: hash call
@@ -25,7 +25,7 @@ Feature: Yield
       YIELD hash("Boris")
       """
     Then the result should be, in any order:
-      | hash(Boris)         |
+      | hash("Boris")       |
       | 9126854228122744212 |
     When executing query:
       """
diff --git a/tests/tck/features/yield/return.feature b/tests/tck/features/yield/return.feature
index 11235ea042853a16f0ffbf1bdabe129a2cf138e7..d72d3d1b77a209bba432a966968a971148b4d893 100644
--- a/tests/tck/features/yield/return.feature
+++ b/tests/tck/features/yield/return.feature
@@ -20,7 +20,7 @@ Feature: Return
       RETURN DISTINCT 1+1, '1+1', (int)3.14, (string)(1+1), (string)true
       """
     Then the result should be, in any order:
-      | (1+1) | 1+1   | (INT)3.14 | (STRING)(1+1) | (STRING)true |
+      | (1+1) | "1+1" | (INT)3.14 | (STRING)(1+1) | (STRING)true |
       | 2     | "1+1" | 3         | "2"           | "true"       |
 
   Scenario: hash call
@@ -29,7 +29,7 @@ Feature: Return
       RETURN hash("Boris")
       """
     Then the result should be, in any order:
-      | hash(Boris)         |
+      | hash("Boris")       |
       | 9126854228122744212 |
     When executing query:
       """
diff --git a/tests/tck/features/yield/yield.IntVid.feature b/tests/tck/features/yield/yield.IntVid.feature
index 556f91b067ffcfefaa222865e6c0a3d92cf79a4e..348b3d46a41bc1255a0aa00a3123618f7ae5fac3 100644
--- a/tests/tck/features/yield/yield.IntVid.feature
+++ b/tests/tck/features/yield/yield.IntVid.feature
@@ -16,14 +16,14 @@ Feature: Yield Sentence
       YIELD 1+1, (int)3.14, (string)(1+1), (string)true,"1+1"
       """
     Then the result should be, in any order:
-      | (1+1) | (INT)3.14 | (STRING)(1+1) | (STRING)true | 1+1   |
+      | (1+1) | (INT)3.14 | (STRING)(1+1) | (STRING)true | "1+1" |
       | 2     | 3         | "2"           | "true"       | "1+1" |
     When executing query:
       """
       YIELD "Hello", hash("Hello")
       """
     Then the result should be, in any order:
-      | Hello   | hash(Hello)         |
+      | "Hello" | hash("Hello")       |
       | "Hello" | 2275118702903107253 |
 
   Scenario: HashCall
@@ -32,7 +32,7 @@ Feature: Yield Sentence
       YIELD hash("Boris")
       """
     Then the result should be, in any order:
-      | hash(Boris)         |
+      | hash("Boris")       |
       | 9126854228122744212 |
     When executing query:
       """
diff --git a/tests/tck/features/yield/yield.feature b/tests/tck/features/yield/yield.feature
index 702719dd06bf5ff6af268e656e88f3240b74a93d..82a68b5ce372a969c5a28ef4be42edba5b3ad436 100644
--- a/tests/tck/features/yield/yield.feature
+++ b/tests/tck/features/yield/yield.feature
@@ -16,14 +16,14 @@ Feature: Yield Sentence
       YIELD 1+1, (int)3.14, (string)(1+1), (string)true,"1+1"
       """
     Then the result should be, in any order, with relax comparison:
-      | (1+1) | (INT)3.14 | (STRING)(1+1) | (STRING)true | 1+1   |
+      | (1+1) | (INT)3.14 | (STRING)(1+1) | (STRING)true | "1+1" |
       | 2     | 3         | "2"           | "true"       | "1+1" |
     When executing query:
       """
       YIELD "Hello", hash("Hello")
       """
     Then the result should be, in any order, with relax comparison:
-      | Hello   | hash(Hello)         |
+      | "Hello" | hash("Hello")       |
       | "Hello" | 2275118702903107253 |
 
   Scenario: HashCall
@@ -32,7 +32,7 @@ Feature: Yield Sentence
       YIELD hash("Boris")
       """
     Then the result should be, in any order, with relax comparison:
-      | hash(Boris)         |
+      | hash("Boris")       |
       | 9126854228122744212 |
     When executing query:
       """