diff --git a/src/daemons/CMakeLists.txt b/src/daemons/CMakeLists.txt
index fac9554ad419dc940c45293742a251faab1d68be..7059e007453ad19a55ce674d70beaf050117f3d6 100644
--- a/src/daemons/CMakeLists.txt
+++ b/src/daemons/CMakeLists.txt
@@ -4,27 +4,19 @@ nebula_add_executable(
     SOURCES
         GraphDaemon.cpp
     OBJECTS
-        $<TARGET_OBJECTS:meta_client>
+        $<TARGET_OBJECTS:filter_obj>
         $<TARGET_OBJECTS:graph_http_handler>
-        $<TARGET_OBJECTS:meta_thrift_obj>
         $<TARGET_OBJECTS:graph_obj>
-        $<TARGET_OBJECTS:base_obj>
-        $<TARGET_OBJECTS:graph_thrift_obj>
-        $<TARGET_OBJECTS:storage_thrift_obj>
-        $<TARGET_OBJECTS:common_thrift_obj>
-        $<TARGET_OBJECTS:meta_client>
-        $<TARGET_OBJECTS:meta_thrift_obj>
-        $<TARGET_OBJECTS:storage_client>
-        $<TARGET_OBJECTS:meta_thrift_obj>
-        $<TARGET_OBJECTS:time_obj>
-        $<TARGET_OBJECTS:fs_obj>
         $<TARGET_OBJECTS:http_client_obj>
-        $<TARGET_OBJECTS:stats_obj>
-        $<TARGET_OBJECTS:thread_obj>
         $<TARGET_OBJECTS:parser_obj>
-        $<TARGET_OBJECTS:filter_obj>
         $<TARGET_OBJECTS:network_obj>
         $<TARGET_OBJECTS:process_obj>
+        $<TARGET_OBJECTS:graph_thrift_obj>
+        $<TARGET_OBJECTS:storage_client>
+        $<TARGET_OBJECTS:storage_thrift_obj>
+        $<TARGET_OBJECTS:meta_client>
+        $<TARGET_OBJECTS:meta_thrift_obj>
+        $<TARGET_OBJECTS:common_thrift_obj>
         $<TARGET_OBJECTS:thrift_obj>
         $<TARGET_OBJECTS:schema_obj>
         $<TARGET_OBJECTS:ws_obj>
@@ -32,6 +24,11 @@ nebula_add_executable(
         $<TARGET_OBJECTS:dataman_obj>
         $<TARGET_OBJECTS:meta_gflags_man_obj>
         $<TARGET_OBJECTS:gflags_man_obj>
+        $<TARGET_OBJECTS:stats_obj>
+        $<TARGET_OBJECTS:thread_obj>
+        $<TARGET_OBJECTS:time_obj>
+        $<TARGET_OBJECTS:fs_obj>
+        $<TARGET_OBJECTS:base_obj>
     LIBRARIES
         proxygenhttpserver
         proxygenlib
@@ -46,34 +43,35 @@ nebula_add_executable(
     SOURCES
         StorageDaemon.cpp
     OBJECTS
+        $<TARGET_OBJECTS:filter_obj>
         $<TARGET_OBJECTS:storage_server>
         $<TARGET_OBJECTS:storage_service_handler>
         $<TARGET_OBJECTS:storage_http_handler>
-        $<TARGET_OBJECTS:storage_thrift_obj>
         $<TARGET_OBJECTS:kvstore_obj>
-        $<TARGET_OBJECTS:meta_client>
-        $<TARGET_OBJECTS:meta_thrift_obj>
-        $<TARGET_OBJECTS:common_thrift_obj>
         $<TARGET_OBJECTS:raftex_obj>
         $<TARGET_OBJECTS:raftex_thrift_obj>
         $<TARGET_OBJECTS:wal_obj>
         $<TARGET_OBJECTS:dataman_obj>
         $<TARGET_OBJECTS:schema_obj>
         $<TARGET_OBJECTS:hdfs_helper_obj>
+        $<TARGET_OBJECTS:storage_thrift_obj>
         $<TARGET_OBJECTS:http_client_obj>
-        $<TARGET_OBJECTS:filter_obj>
-        $<TARGET_OBJECTS:base_obj>
+        $<TARGET_OBJECTS:storage_client>
+        $<TARGET_OBJECTS:meta_client>
+        $<TARGET_OBJECTS:meta_thrift_obj>
+        $<TARGET_OBJECTS:common_thrift_obj>
         $<TARGET_OBJECTS:thrift_obj>
-        $<TARGET_OBJECTS:thread_obj>
-        $<TARGET_OBJECTS:time_obj>
-        $<TARGET_OBJECTS:fs_obj>
-        $<TARGET_OBJECTS:stats_obj>
+        $<TARGET_OBJECTS:meta_gflags_man_obj>
+        $<TARGET_OBJECTS:gflags_man_obj>
         $<TARGET_OBJECTS:network_obj>
         $<TARGET_OBJECTS:process_obj>
         $<TARGET_OBJECTS:ws_obj>
         $<TARGET_OBJECTS:ws_common_obj>
-        $<TARGET_OBJECTS:meta_gflags_man_obj>
-        $<TARGET_OBJECTS:gflags_man_obj>
+        $<TARGET_OBJECTS:thread_obj>
+        $<TARGET_OBJECTS:time_obj>
+        $<TARGET_OBJECTS:fs_obj>
+        $<TARGET_OBJECTS:stats_obj>
+        $<TARGET_OBJECTS:base_obj>
     LIBRARIES
         proxygenhttpserver
         proxygenlib
@@ -93,27 +91,28 @@ nebula_add_executable(
         $<TARGET_OBJECTS:meta_http_handler>
         $<TARGET_OBJECTS:kvstore_obj>
         $<TARGET_OBJECTS:schema_obj>
+        $<TARGET_OBJECTS:wal_obj>
+        $<TARGET_OBJECTS:hdfs_helper_obj>
+        $<TARGET_OBJECTS:http_client_obj>
+        $<TARGET_OBJECTS:storage_client>
+        $<TARGET_OBJECTS:storage_thrift_obj>
         $<TARGET_OBJECTS:meta_client>
         $<TARGET_OBJECTS:meta_thrift_obj>
-        $<TARGET_OBJECTS:common_thrift_obj>
-        $<TARGET_OBJECTS:storage_thrift_obj>
         $<TARGET_OBJECTS:raftex_obj>
         $<TARGET_OBJECTS:raftex_thrift_obj>
-        $<TARGET_OBJECTS:wal_obj>
-        $<TARGET_OBJECTS:hdfs_helper_obj>
-        $<TARGET_OBJECTS:http_client_obj>
-        $<TARGET_OBJECTS:base_obj>
+        $<TARGET_OBJECTS:common_thrift_obj>
         $<TARGET_OBJECTS:thrift_obj>
-        $<TARGET_OBJECTS:network_obj>
-        $<TARGET_OBJECTS:thread_obj>
-        $<TARGET_OBJECTS:time_obj>
-        $<TARGET_OBJECTS:fs_obj>
-        $<TARGET_OBJECTS:stats_obj>
         $<TARGET_OBJECTS:process_obj>
         $<TARGET_OBJECTS:ws_obj>
         $<TARGET_OBJECTS:ws_common_obj>
         $<TARGET_OBJECTS:kv_gflags_man_obj>
         $<TARGET_OBJECTS:gflags_man_obj>
+        $<TARGET_OBJECTS:network_obj>
+        $<TARGET_OBJECTS:thread_obj>
+        $<TARGET_OBJECTS:stats_obj>
+        $<TARGET_OBJECTS:time_obj>
+        $<TARGET_OBJECTS:fs_obj>
+        $<TARGET_OBJECTS:base_obj>
     LIBRARIES
         proxygenhttpserver
         proxygenlib
diff --git a/src/executor/DeleteVertexExecutor.cpp b/src/executor/DeleteVertexExecutor.cpp
index f778d0143d6b50f59b216dbbafff8d805bfa7749..92e4552fe34ba6e7f40f84c18867a6b5028a8a95 100644
--- a/src/executor/DeleteVertexExecutor.cpp
+++ b/src/executor/DeleteVertexExecutor.cpp
@@ -28,7 +28,7 @@ Status DeleteVertexExecutor::prepare() {
 void DeleteVertexExecutor::execute() {
     GraphSpaceID space = ectx()->rctx()->session()->space();
     // TODO(zlcook) Get edgeKes of a vertex by Go
-    auto future = ectx()->storage()->getEdgeKeys(space, vid_);
+    auto future = ectx()->getStorageClient()->getEdgeKeys(space, vid_);
     auto *runner = ectx()->rctx()->runner();
     auto cb = [this] (auto &&resp) {
         if (!resp.ok()) {
@@ -62,7 +62,7 @@ void DeleteVertexExecutor::execute() {
 
 void DeleteVertexExecutor::deleteEdges(std::vector<storage::cpp2::EdgeKey>* edges) {
     GraphSpaceID space = ectx()->rctx()->session()->space();
-    auto future = ectx()->storage()->deleteEdges(space, *edges);
+    auto future = ectx()->getStorageClient()->deleteEdges(space, *edges);
     auto *runner = ectx()->rctx()->runner();
     auto cb = [this] (auto &&resp) {
         auto completeness = resp.completeness();
@@ -86,7 +86,7 @@ void DeleteVertexExecutor::deleteEdges(std::vector<storage::cpp2::EdgeKey>* edge
 
 void DeleteVertexExecutor::deleteVertex() {
     GraphSpaceID space = ectx()->rctx()->session()->space();
-    auto future = ectx()->storage()->deleteVertex(space, vid_);
+    auto future = ectx()->getStorageClient()->deleteVertex(space, vid_);
     auto *runner = ectx()->rctx()->runner();
     auto cb = [this] (auto &&resp) {
         if (!resp.ok()) {
diff --git a/src/executor/ExecutionContext.cpp b/src/executor/ExecutionContext.cpp
index 2a56abd1c610f22596388c07af15bb960bcd34ed..03b0aaa4d7ed58feb0f0753bb0a6500cdba651d3 100644
--- a/src/executor/ExecutionContext.cpp
+++ b/src/executor/ExecutionContext.cpp
@@ -19,8 +19,8 @@ ExecutionContext::~ExecutionContext() {
         gflagsManager_ = nullptr;
     }
 
-    if (nullptr != storage_) {
-        storage_ = nullptr;
+    if (nullptr != storageClient_) {
+        storageClient_ = nullptr;
     }
 
     if (nullptr != metaClient_) {
diff --git a/src/executor/ExecutionContext.h b/src/executor/ExecutionContext.h
index d0200d864877254cda9d977b7f77e13b7fe989ab..56c5e19fea952e50e1f47225b9b2320d85506449 100644
--- a/src/executor/ExecutionContext.h
+++ b/src/executor/ExecutionContext.h
@@ -37,7 +37,7 @@ public:
         rctx_ = std::move(rctx);
         sm_ = sm;
         gflagsManager_ = gflagsManager;
-        storage_ = storage;
+        storageClient_ = storage;
         metaClient_ = metaClient;
         variableHolder_ = std::make_unique<VariableHolder>();
     }
@@ -56,8 +56,8 @@ public:
         return gflagsManager_;
     }
 
-    storage::StorageClient* storage() const {
-        return storage_;
+    storage::StorageClient* getStorageClient() const {
+        return storageClient_;
     }
 
     VariableHolder* variableHolder() const {
@@ -72,7 +72,7 @@ private:
     RequestContextPtr                           rctx_;
     meta::SchemaManager                        *sm_{nullptr};
     meta::ClientBasedGflagsManager             *gflagsManager_{nullptr};
-    storage::StorageClient                     *storage_{nullptr};
+    storage::StorageClient                     *storageClient_{nullptr};
     meta::MetaClient                           *metaClient_{nullptr};
     std::unique_ptr<VariableHolder>             variableHolder_;
 };
diff --git a/src/executor/FetchEdgesExecutor.cpp b/src/executor/FetchEdgesExecutor.cpp
index bc4d32d473f08a2c74608a30ed3f7d8f74939a27..23725fd95fb3c767f8e6c0e9cd39de28043aafaf 100644
--- a/src/executor/FetchEdgesExecutor.cpp
+++ b/src/executor/FetchEdgesExecutor.cpp
@@ -28,6 +28,7 @@ Status FetchEdgesExecutor::prepareClauses() {
             break;
         }
         expCtx_ = std::make_unique<ExpressionContext>();
+        expCtx_->setStorageClient(ectx()->getStorageClient());
         spaceId_ = ectx()->rctx()->session()->space();
         yieldClause_ = sentence_->yieldClause();
         labelName_ = sentence_->edge();
@@ -196,12 +197,18 @@ Status FetchEdgesExecutor::setupEdgeKeysFromExpr() {
     if (distinct_) {
         uniq = std::make_unique<EdgeKeyHashSet>(256, hash_);
     }
+
     auto edgeKeyExprs = sentence_->keys()->keys();
+    expCtx_->setSpace(spaceId_);
+
     for (auto *keyExpr : edgeKeyExprs) {
         auto *srcExpr = keyExpr->srcid();
+        srcExpr->setContext(expCtx_.get());
+
         auto *dstExpr = keyExpr->dstid();
-        auto rank = keyExpr->rank();
+        dstExpr->setContext(expCtx_.get());
 
+        auto rank = keyExpr->rank();
         status = srcExpr->prepare();
         if (!status.ok()) {
             break;
@@ -258,7 +265,7 @@ void FetchEdgesExecutor::fetchEdges() {
         return;
     }
 
-    auto future = ectx()->storage()->getEdgeProps(spaceId_, edgeKeys_, std::move(props));
+    auto future = ectx()->getStorageClient()->getEdgeProps(spaceId_, edgeKeys_, std::move(props));
     auto *runner = ectx()->rctx()->runner();
     auto cb = [this] (RpcResponse &&result) mutable {
         auto completeness = result.completeness();
@@ -361,5 +368,6 @@ void FetchEdgesExecutor::processResult(RpcResponse &&result) {
 
     finishExecution(std::move(rsWriter));
 }
+
 }  // namespace graph
 }  // namespace nebula
diff --git a/src/executor/FetchEdgesExecutor.h b/src/executor/FetchEdgesExecutor.h
index 82fee2e3b07c7a6c8ef36b4689f86f9bbabf1ba6..43b23bfd06a9689f02153eb99d43afe9eb5cc209 100644
--- a/src/executor/FetchEdgesExecutor.h
+++ b/src/executor/FetchEdgesExecutor.h
@@ -45,7 +45,6 @@ private:
     using RpcResponse = storage::StorageRpcResponse<storage::cpp2::EdgePropResponse>;
     void processResult(RpcResponse &&result);
 
-
     using EdgeKeyHashSet = std::unordered_set<
             storage::cpp2::EdgeKey,
             std::function<size_t(const storage::cpp2::EdgeKey& key)>>;
diff --git a/src/executor/FetchVerticesExecutor.cpp b/src/executor/FetchVerticesExecutor.cpp
index 7e8a912118fc6020bf2fe19fe8bf5141de56de49..e1463a3f8af115c5efbe93406aa8366ab1c3dbb0 100644
--- a/src/executor/FetchVerticesExecutor.cpp
+++ b/src/executor/FetchVerticesExecutor.cpp
@@ -31,6 +31,8 @@ Status FetchVerticesExecutor::prepareClauses() {
         }
 
         expCtx_ = std::make_unique<ExpressionContext>();
+        expCtx_->setStorageClient(ectx()->getStorageClient());
+
         spaceId_ = ectx()->rctx()->session()->space();
         yieldClause_ = sentence_->yieldClause();
         labelName_ = sentence_->tag();
@@ -117,7 +119,7 @@ void FetchVerticesExecutor::fetchVertices() {
         return;
     }
 
-    auto future = ectx()->storage()->getVertexProps(spaceId_, vids_, std::move(props));
+    auto future = ectx()->getStorageClient()->getVertexProps(spaceId_, vids_, std::move(props));
     auto *runner = ectx()->rctx()->runner();
     auto cb = [this] (RpcResponse &&result) mutable {
         auto completeness = result.completeness();
@@ -247,8 +249,11 @@ Status FetchVerticesExecutor::setupVidsFromExpr() {
     if (distinct_) {
         uniqID = std::make_unique<std::unordered_set<VertexID>>();
     }
+
+    expCtx_->setSpace(spaceId_);
     auto vidList = sentence_->vidList();
     for (auto *expr : vidList) {
+        expr->setContext(expCtx_.get());
         status = expr->prepare();
         if (!status.ok()) {
             break;
@@ -304,6 +309,5 @@ Status FetchVerticesExecutor::setupVidsFromRef() {
     return Status::OK();
 }
 
-
 }  // namespace graph
 }  // namespace nebula
diff --git a/src/executor/GoExecutor.cpp b/src/executor/GoExecutor.cpp
index ba76d2a7dbe8e206241ae1a4c9f3176b3e9d0ce2..5ca5ffe00ee6ec77da8406070132619764800e97 100644
--- a/src/executor/GoExecutor.cpp
+++ b/src/executor/GoExecutor.cpp
@@ -33,6 +33,8 @@ Status GoExecutor::prepareClauses() {
     DCHECK(sentence_ != nullptr);
     Status status;
     expCtx_ = std::make_unique<ExpressionContext>();
+    expCtx_->setStorageClient(ectx()->getStorageClient());
+
     do {
         status = checkIfGraphSpaceChosen();
         if (!status.ok()) {
@@ -156,8 +158,12 @@ Status GoExecutor::prepareFrom() {
             break;
         }
 
+        auto space = ectx()->rctx()->session()->space();
+        expCtx_->setSpace(space);
         auto vidList = clause->vidList();
         for (auto *expr : vidList) {
+            expr->setContext(expCtx_.get());
+
             status = expr->prepare();
             if (!status.ok()) {
                 break;
@@ -388,11 +394,11 @@ void GoExecutor::stepOut() {
         return;
     }
     auto returns = status.value();
-    auto future  = ectx()->storage()->getNeighbors(spaceId,
-                                                   starts_,
-                                                   edgeTypes_,
-                                                   "",
-                                                   std::move(returns));
+    auto future  = ectx()->getStorageClient()->getNeighbors(spaceId,
+                                                            starts_,
+                                                            edgeTypes_,
+                                                            "",
+                                                            std::move(returns));
     auto *runner = ectx()->rctx()->runner();
     auto cb = [this] (auto &&result) {
         auto completeness = result.completeness();
@@ -630,7 +636,7 @@ void GoExecutor::fetchVertexProps(std::vector<VertexID> ids, RpcResponse &&rpcRe
         return;
     }
     auto returns = status.value();
-    auto future = ectx()->storage()->getVertexProps(spaceId, ids, returns);
+    auto future = ectx()->getStorageClient()->getVertexProps(spaceId, ids, returns);
     auto *runner = ectx()->rctx()->runner();
     auto cb = [this, stepOutResp = std::move(rpcResp)] (auto &&result) mutable {
         auto completeness = result.completeness();
@@ -903,6 +909,7 @@ bool GoExecutor::processFinalResult(RpcResponse &rpcResp, Callback cb) const {
                         }
                         return getPropFromInterim(vdata.get_vertex_id(), prop);
                     };
+
                     // Evaluate filter
                     if (filter_ != nullptr) {
                         auto value = filter_->eval();
@@ -1040,6 +1047,5 @@ SupportedType GoExecutor::getPropTypeFromInterim(const std::string &prop) const
     return index_->getColumnType(prop);
 }
 
-
 }   // namespace graph
 }   // namespace nebula
diff --git a/src/executor/InsertEdgeExecutor.cpp b/src/executor/InsertEdgeExecutor.cpp
index 883cc15dab2a9316a4c66c9a5a4826c7df451a74..7b3cbc5b8f01993d646d4f1d2588a98250ae88ed 100644
--- a/src/executor/InsertEdgeExecutor.cpp
+++ b/src/executor/InsertEdgeExecutor.cpp
@@ -18,6 +18,8 @@ InsertEdgeExecutor::InsertEdgeExecutor(Sentence *sentence,
 
 
 Status InsertEdgeExecutor::prepare() {
+    expCtx_ = std::make_unique<ExpressionContext>();
+    expCtx_->setStorageClient(ectx()->getStorageClient());
     return Status::OK();
 }
 
@@ -41,6 +43,8 @@ Status InsertEdgeExecutor::check() {
         auto props = sentence_->properties();
         rows_ = sentence_->rows();
 
+        expCtx_->setStorageClient(ectx()->getStorageClient());
+
         schema_ = ectx()->schemaManager()->getEdgeSchema(spaceId, edgeType_);
         if (schema_ == nullptr) {
             status = Status::Error("No schema found for `%s'", sentence_->edge()->c_str());
@@ -68,11 +72,18 @@ Status InsertEdgeExecutor::check() {
 
 
 StatusOr<std::vector<storage::cpp2::Edge>> InsertEdgeExecutor::prepareEdges() {
+    expCtx_ = std::make_unique<ExpressionContext>();
+    expCtx_->setStorageClient(ectx()->getStorageClient());
+
+    auto space = ectx()->rctx()->session()->space();
+    expCtx_->setSpace(space);
+
     std::vector<storage::cpp2::Edge> edges(rows_.size() * 2);   // inbound and outbound
     auto index = 0;
     for (auto i = 0u; i < rows_.size(); i++) {
         auto *row = rows_[i];
         auto sid = row->srcid();
+        sid->setContext(expCtx_.get());
         auto status = sid->prepare();
         if (!status.ok()) {
             return status;
@@ -89,6 +100,7 @@ StatusOr<std::vector<storage::cpp2::Edge>> InsertEdgeExecutor::prepareEdges() {
         auto src = Expression::asInt(v);
 
         auto did = row->dstid();
+        did->setContext(expCtx_.get());
         status = did->prepare();
         if (!status.ok()) {
             return status;
@@ -195,7 +207,9 @@ void InsertEdgeExecutor::execute() {
         return;
     }
     auto space = ectx()->rctx()->session()->space();
-    auto future = ectx()->storage()->addEdges(space, std::move(result).value(), overwritable_);
+    auto future = ectx()->getStorageClient()->addEdges(space,
+                                                       std::move(result).value(),
+                                                       overwritable_);
     auto *runner = ectx()->rctx()->runner();
 
     auto cb = [this] (auto &&resp) {
diff --git a/src/executor/InsertEdgeExecutor.h b/src/executor/InsertEdgeExecutor.h
index 026c226a2e663c2b80512410761fa9cfa1fe4b93..e3e332ad3c9d53ae58170fa5ec94c8801c328f65 100644
--- a/src/executor/InsertEdgeExecutor.h
+++ b/src/executor/InsertEdgeExecutor.h
@@ -32,6 +32,7 @@ private:
 private:
     using EdgeSchema = std::shared_ptr<const meta::SchemaProviderIf>;
     InsertEdgeSentence                         *sentence_{nullptr};
+    std::unique_ptr<ExpressionContext>          expCtx_;
     bool                                        overwritable_{true};
     EdgeType                                    edgeType_{0};
     EdgeSchema                                  schema_;
diff --git a/src/executor/InsertVertexExecutor.cpp b/src/executor/InsertVertexExecutor.cpp
index 4507c69f57e301ac311c52cbd4dcdc415395d978..9788e461de3db97021667f9c6d04a9970aacf6d2 100644
--- a/src/executor/InsertVertexExecutor.cpp
+++ b/src/executor/InsertVertexExecutor.cpp
@@ -18,6 +18,8 @@ InsertVertexExecutor::InsertVertexExecutor(Sentence *sentence,
 
 
 Status InsertVertexExecutor::prepare() {
+    expCtx_ = std::make_unique<ExpressionContext>();
+    expCtx_->setStorageClient(ectx()->getStorageClient());
     return Status::OK();
 }
 
@@ -75,12 +77,16 @@ Status InsertVertexExecutor::check() {
     return Status::OK();
 }
 
-
 StatusOr<std::vector<storage::cpp2::Vertex>> InsertVertexExecutor::prepareVertices() {
+    expCtx_->setStorageClient(ectx()->getStorageClient());
+    expCtx_->setSpace(spaceId_);
+
     std::vector<storage::cpp2::Vertex> vertices(rows_.size());
     for (auto i = 0u; i < rows_.size(); i++) {
         auto *row = rows_[i];
         auto rid = row->id();
+        rid->setContext(expCtx_.get());
+
         auto status = rid->prepare();
         if (!status.ok()) {
             return status;
@@ -182,9 +188,9 @@ void InsertVertexExecutor::execute() {
         onError_(std::move(result).status());
         return;
     }
-    auto future = ectx()->storage()->addVertices(spaceId_,
-                                                 std::move(result).value(),
-                                                 overwritable_);
+    auto future = ectx()->getStorageClient()->addVertices(spaceId_,
+                                                          std::move(result).value(),
+                                                          overwritable_);
     auto *runner = ectx()->rctx()->runner();
 
     auto cb = [this] (auto &&resp) {
diff --git a/src/executor/InsertVertexExecutor.h b/src/executor/InsertVertexExecutor.h
index 79b180ea4b12f6f5d8369fd3e121fd7712e876c5..ec1be0a6a2428ed2b1c0b1cb1442b53294515589 100644
--- a/src/executor/InsertVertexExecutor.h
+++ b/src/executor/InsertVertexExecutor.h
@@ -32,6 +32,7 @@ private:
 private:
     using TagSchema = std::shared_ptr<const meta::SchemaProviderIf>;
     InsertVertexSentence                       *sentence_{nullptr};
+    std::unique_ptr<ExpressionContext>          expCtx_;
     bool                                        overwritable_{true};
     std::vector<VertexRowItem*>                 rows_;
     std::vector<TagID>                          tagIds_;
diff --git a/src/executor/UpdateEdgeExecutor.cpp b/src/executor/UpdateEdgeExecutor.cpp
index 658e2b6debf565ba05f161c59922b3827e4afbd4..bf3ee975d92c4dab1709352c62e934288d9dc6e9 100644
--- a/src/executor/UpdateEdgeExecutor.cpp
+++ b/src/executor/UpdateEdgeExecutor.cpp
@@ -201,7 +201,7 @@ void UpdateEdgeExecutor::insertReverselyEdge(storage::cpp2::UpdateResponse &&rpc
     reverselyEdge.props = "";
     edges.emplace_back(reverselyEdge);
     auto space = ectx()->rctx()->session()->space();
-    auto future = ectx()->storage()->addEdges(space, std::move(edges), false);
+    auto future = ectx()->getStorageClient()->addEdges(space, std::move(edges), false);
     auto *runner = ectx()->rctx()->runner();
     auto cb = [this, updateResp = std::move(rpcResp)] (auto &&resp) mutable {
         auto completeness = resp.completeness();
@@ -228,12 +228,12 @@ void UpdateEdgeExecutor::execute() {
     auto space = ectx()->rctx()->session()->space();
     std::string filterStr = filter_ ? Expression::encode(filter_) : "";
     auto returns = getReturnColumns();
-    auto future = ectx()->storage()->updateEdge(space,
-                                                edge_,
-                                                filterStr,
-                                                std::move(updateItems_),
-                                                std::move(returns),
-                                                insertable_);
+    auto future = ectx()->getStorageClient()->updateEdge(space,
+                                                         edge_,
+                                                         filterStr,
+                                                         std::move(updateItems_),
+                                                         std::move(returns),
+                                                         insertable_);
     auto *runner = ectx()->rctx()->runner();
     auto cb = [this] (auto &&resp) {
         if (!resp.ok()) {
diff --git a/src/executor/UpdateVertexExecutor.cpp b/src/executor/UpdateVertexExecutor.cpp
index 402f280dcfff3eecdae4624e85ce84300096d1ad..44f9a3ed33f883a75d8d729018a9e3957d0784f1 100644
--- a/src/executor/UpdateVertexExecutor.cpp
+++ b/src/executor/UpdateVertexExecutor.cpp
@@ -179,12 +179,12 @@ void UpdateVertexExecutor::execute() {
     auto spaceId = ectx()->rctx()->session()->space();
     std::string filterStr = filter_ ? Expression::encode(filter_) : "";
     auto returns = getReturnColumns();
-    auto future = ectx()->storage()->updateVertex(spaceId,
-                                                  vertex_,
-                                                  filterStr,
-                                                  std::move(updateItems_),
-                                                  std::move(returns),
-                                                  insertable_);
+    auto future = ectx()->getStorageClient()->updateVertex(spaceId,
+                                                           vertex_,
+                                                           filterStr,
+                                                           std::move(updateItems_),
+                                                           std::move(returns),
+                                                           insertable_);
     auto *runner = ectx()->rctx()->runner();
     auto cb = [this] (auto &&resp) {
         if (!resp.ok()) {
diff --git a/src/executor/test/CMakeLists.txt b/src/executor/test/CMakeLists.txt
index 92b872a5853745b140d6ab382abbe02ff92d8a20..5a586e464b46c37ad3c77a5ff08c69a2b25a204e 100644
--- a/src/executor/test/CMakeLists.txt
+++ b/src/executor/test/CMakeLists.txt
@@ -2,6 +2,7 @@ set(GRAPH_TEST_LIBS
     $<TARGET_OBJECTS:graph_obj>
     $<TARGET_OBJECTS:graph_thrift_obj>
     $<TARGET_OBJECTS:storage_service_handler>
+    $<TARGET_OBJECTS:storage_client>
     $<TARGET_OBJECTS:storage_thrift_obj>
     $<TARGET_OBJECTS:common_thrift_obj>
     $<TARGET_OBJECTS:parser_obj>
diff --git a/src/executor/test/DataTest.cpp b/src/executor/test/DataTest.cpp
index bc38c9732ecac5e3548d575091c1fe27469d022b..b307ac4e1f9cdfe335c60a41585232bf2ac3156d 100644
--- a/src/executor/test/DataTest.cpp
+++ b/src/executor/test/DataTest.cpp
@@ -179,6 +179,12 @@ TEST_F(DataTest, InsertVertex) {
         auto code = client_->execute(cmd, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
     }
+    {
+        cpp2::ExecutionResponse resp;
+        std::string cmd = "INSERT VERTEX person(name, age) VALUES uuid(\"Tom\"):(\"Tom\", 22)";
+        auto code = client_->execute(cmd, resp);
+        ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+    }
     // One vertex multi tags
     {
         cpp2::ExecutionResponse resp;
@@ -187,6 +193,13 @@ TEST_F(DataTest, InsertVertex) {
         auto code = client_->execute(cmd, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
     }
+    {
+        cpp2::ExecutionResponse resp;
+        std::string cmd = "INSERT VERTEX person(name, age),student(grade, number) "
+                          "VALUES uuid(\"Lucy\"):(\"Lucy\", 8, \"three\", 20190901001)";
+        auto code = client_->execute(cmd, resp);
+        ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+    }
     // Multi vertices multi tags
     {
         cpp2::ExecutionResponse resp;
@@ -196,6 +209,14 @@ TEST_F(DataTest, InsertVertex) {
         auto code = client_->execute(cmd, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
     }
+    {
+        cpp2::ExecutionResponse resp;
+        std::string cmd = "INSERT VERTEX person(name, age),student(grade, number) "
+                          "VALUES uuid(\"Laura\"):(\"Laura\", 8, \"three\", 20190901008),"
+                          "uuid(\"Amber\"):(\"Amber\", 9, \"four\", 20180901003)";
+        auto code = client_->execute(cmd, resp);
+        ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+    }
     // Multi vertices one tag
     {
         cpp2::ExecutionResponse resp;
@@ -204,6 +225,13 @@ TEST_F(DataTest, InsertVertex) {
         auto code = client_->execute(cmd, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
     }
+    {
+        cpp2::ExecutionResponse resp;
+        std::string cmd = "INSERT VERTEX person(name, age) "
+                          "VALUES uuid(\"Kitty\"):(\"Kitty\", 8), uuid(\"Peter\"):(\"Peter\", 9)";
+        auto code = client_->execute(cmd, resp);
+        ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+    }
     {
         cpp2::ExecutionResponse resp;
         std::string cmd = "INSERT EDGE schoolmate(likeness) VALUES "
@@ -211,6 +239,13 @@ TEST_F(DataTest, InsertVertex) {
         auto code = client_->execute(cmd, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
     }
+    {
+        cpp2::ExecutionResponse resp;
+        std::string cmd = "INSERT EDGE schoolmate(likeness) VALUES "
+                          "uuid(\"Tom\")->uuid(\"Lucy\"):(85)";
+        auto code = client_->execute(cmd, resp);
+        ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+    }
     // Insert multi edges
     {
         cpp2::ExecutionResponse resp;
@@ -220,6 +255,14 @@ TEST_F(DataTest, InsertVertex) {
         auto code = client_->execute(cmd, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
     }
+    {
+        cpp2::ExecutionResponse resp;
+        std::string cmd = "INSERT EDGE schoolmate(likeness) VALUES "
+                          "uuid(\"Tom\")->uuid(\"Kitty\"):(81),"
+                          "uuid(\"Tom\")->uuid(\"Peter\"):(83)";
+        auto code = client_->execute(cmd, resp);
+        ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+    }
     // Get result
     {
         cpp2::ExecutionResponse resp;
@@ -234,6 +277,19 @@ TEST_F(DataTest, InsertVertex) {
         };
         ASSERT_TRUE(verifyResult(resp, expected));
     }
+    {
+        cpp2::ExecutionResponse resp;
+        std::string cmd = "GO FROM uuid(\"Tom\") OVER schoolmate YIELD $^.person.name,"
+                          "schoolmate.likeness, $$.person.name";
+        auto code = client_->execute(cmd, resp);
+        ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+        std::vector<std::tuple<std::string, int64_t, std::string>> expected = {
+            {"Tom", 85, "Lucy"},
+            {"Tom", 81, "Kitty"},
+            {"Tom", 83, "Peter"},
+        };
+        ASSERT_TRUE(verifyResult(resp, expected));
+    }
     // Get multi tags
     {
         cpp2::ExecutionResponse resp;
@@ -243,6 +299,14 @@ TEST_F(DataTest, InsertVertex) {
         auto code = client_->execute(cmd, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
     }
+    {
+        cpp2::ExecutionResponse resp;
+        std::string cmd = "INSERT EDGE schoolmate(likeness) VALUES "
+                          "uuid(\"Lucy\")->uuid(\"Laura\"):(90),"
+                          "uuid(\"Lucy\")->uuid(\"Amber\"):(95)";
+        auto code = client_->execute(cmd, resp);
+        ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+    }
     {
         cpp2::ExecutionResponse resp;
         std::string cmd = "GO FROM hash(\"Lucy\") OVER schoolmate YIELD "
@@ -257,6 +321,20 @@ TEST_F(DataTest, InsertVertex) {
         };
         ASSERT_TRUE(verifyResult(resp, expected));
     }
+    {
+        cpp2::ExecutionResponse resp;
+        std::string cmd = "GO FROM uuid(\"Lucy\") OVER schoolmate YIELD "
+                          "schoolmate.likeness, $$.person.name,"
+                          "$$.student.grade, $$.student.number";
+        auto code = client_->execute(cmd, resp);
+        ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+        using valueType = std::tuple<int64_t, std::string, std::string, int64_t>;
+        std::vector<valueType> expected = {
+            {90, "Laura", "three", 20190901008},
+            {95, "Amber", "four", 20180901003},
+        };
+        ASSERT_TRUE(verifyResult(resp, expected));
+    }
     // Multi sentences to insert multi tags
     {
         cpp2::ExecutionResponse resp;
@@ -267,6 +345,15 @@ TEST_F(DataTest, InsertVertex) {
         auto code = client_->execute(cmd, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
     }
+    {
+        cpp2::ExecutionResponse resp;
+        std::string cmd = "INSERT VERTEX person(name, age)"
+                          "VALUES uuid(\"Aero\"):(\"Aero\", 8);"
+                          "INSERT VERTEX student(grade, number) "
+                          "VALUES uuid(\"Aero\"):(\"four\", 20190901003)";
+        auto code = client_->execute(cmd, resp);
+        ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+    }
     {
         cpp2::ExecutionResponse resp;
         std::string cmd = "INSERT EDGE schoolmate(likeness) VALUES "
@@ -274,6 +361,13 @@ TEST_F(DataTest, InsertVertex) {
         auto code = client_->execute(cmd, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
     }
+    {
+        cpp2::ExecutionResponse resp;
+        std::string cmd = "INSERT EDGE schoolmate(likeness) VALUES "
+                          "uuid(\"Laura\")->uuid(\"Aero\"):(90)";
+        auto code = client_->execute(cmd, resp);
+        ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+    }
     // Get result
     {
         cpp2::ExecutionResponse resp;
@@ -287,6 +381,18 @@ TEST_F(DataTest, InsertVertex) {
         };
         ASSERT_TRUE(verifyResult(resp, expected));
     }
+    {
+        cpp2::ExecutionResponse resp;
+        std::string cmd = "GO FROM uuid(\"Laura\") OVER schoolmate "
+                          "YIELD $$.student.number, $$.person.name";
+        auto code = client_->execute(cmd, resp);
+        ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+        using valueType = std::tuple<int64_t, std::string>;
+        std::vector<valueType> expected{
+            {20190901003, "Aero"},
+        };
+        ASSERT_TRUE(verifyResult(resp, expected));
+    }
     // Test same prop name diff type in diff tags
     {
         cpp2::ExecutionResponse resp;
@@ -296,6 +402,14 @@ TEST_F(DataTest, InsertVertex) {
         auto code = client_->execute(cmd, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
     }
+    {
+        cpp2::ExecutionResponse resp;
+        std::string cmd = "INSERT VERTEX person(name, age),employee(name) "
+                          "VALUES uuid(\"Joy\"):(\"Joy\", 18, 123),"
+                          "uuid(\"Petter\"):(\"Petter\", 19, 456)";
+        auto code = client_->execute(cmd, resp);
+        ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+    }
     {
         cpp2::ExecutionResponse resp;
         std::string cmd = "INSERT EDGE schoolmate(likeness) VALUES "
@@ -303,6 +417,13 @@ TEST_F(DataTest, InsertVertex) {
         auto code = client_->execute(cmd, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
     }
+    {
+        cpp2::ExecutionResponse resp;
+        std::string cmd = "INSERT EDGE schoolmate(likeness) VALUES "
+                          "uuid(\"Joy\")->uuid(\"Petter\"):(90)";
+        auto code = client_->execute(cmd, resp);
+        ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+    }
     {
         cpp2::ExecutionResponse resp;
         std::string cmd = "GO FROM hash(\"Joy\") OVER schoolmate YIELD $^.person.name,"
@@ -314,6 +435,17 @@ TEST_F(DataTest, InsertVertex) {
         };
         ASSERT_TRUE(verifyResult(resp, expected));
     }
+    {
+        cpp2::ExecutionResponse resp;
+        std::string cmd = "GO FROM uuid(\"Joy\") OVER schoolmate YIELD $^.person.name,"
+                          "schoolmate.likeness, $$.person.name, $$.person.age,$$.employee.name";
+        auto code = client_->execute(cmd, resp);
+        ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+        std::vector<std::tuple<std::string, int64_t, std::string, int64_t, int64_t>> expected = {
+            {"Joy", 90, "Petter", 19, 456},
+        };
+        ASSERT_TRUE(verifyResult(resp, expected));
+    }
     // Test same prop name same type in diff tags
     {
         cpp2::ExecutionResponse resp;
@@ -322,6 +454,13 @@ TEST_F(DataTest, InsertVertex) {
         auto code = client_->execute(cmd, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
     }
+    {
+        cpp2::ExecutionResponse resp;
+        std::string cmd = "INSERT VERTEX person(name, age),interest(name) "
+                          "VALUES uuid(\"Bob\"):(\"Bob\", 19, \"basketball\")";
+        auto code = client_->execute(cmd, resp);
+        ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+    }
     {
         cpp2::ExecutionResponse resp;
         std::string cmd = "INSERT EDGE schoolmate(likeness) VALUES "
@@ -329,6 +468,13 @@ TEST_F(DataTest, InsertVertex) {
         auto code = client_->execute(cmd, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
     }
+    {
+        cpp2::ExecutionResponse resp;
+        std::string cmd = "INSERT EDGE schoolmate(likeness) VALUES "
+                          "uuid(\"Petter\")->uuid(\"Bob\"):(90)";
+        auto code = client_->execute(cmd, resp);
+        ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+    }
     {
         cpp2::ExecutionResponse resp;
         std::string cmd = "GO FROM hash(\"Petter\") OVER schoolmate "
@@ -343,6 +489,20 @@ TEST_F(DataTest, InsertVertex) {
         };
         ASSERT_TRUE(verifyResult(resp, expected));
     }
+    {
+        cpp2::ExecutionResponse resp;
+        std::string cmd = "GO FROM uuid(\"Petter\") OVER schoolmate "
+                          "YIELD $^.person.name, $^.employee.name, "
+                          "schoolmate.likeness, $$.person.name,"
+                          "$$.interest.name, $$.person.age";
+        auto code = client_->execute(cmd, resp);
+        ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+        using type = std::tuple<std::string, int64_t, int64_t, std::string, std::string, int64_t>;
+        std::vector<type> expected = {
+            {"Petter", 456, 90, "Bob", "basketball", 19},
+        };
+        ASSERT_TRUE(verifyResult(resp, expected));
+    }
     // Insert wrong type
     {
         cpp2::ExecutionResponse resp;
@@ -392,6 +552,13 @@ TEST_F(DataTest, InsertVertex) {
         auto code = client_->execute(cmd, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
     }
+    {
+        cpp2::ExecutionResponse resp;
+        std::string cmd = "INSERT VERTEX school(name, create_time) VALUES "
+                          "uuid(\"sun_school\"):(\"sun_school\", \"2010-01-01 10:00:00\")";
+        auto code = client_->execute(cmd, resp);
+        ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+    }
     {
         cpp2::ExecutionResponse resp;
         std::string cmd = "INSERT EDGE study(start_time, end_time) "
@@ -400,6 +567,14 @@ TEST_F(DataTest, InsertVertex) {
         auto code = client_->execute(cmd, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
     }
+    {
+        cpp2::ExecutionResponse resp;
+        std::string cmd = "INSERT EDGE study(start_time, end_time) "
+                          "VALUES uuid(\"Laura\")->uuid(\"sun_school\"):"
+                          "(\"2019-01-01 10:00:00\", now()+3600*24*365*3)";
+        auto code = client_->execute(cmd, resp);
+        ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+    }
     {
         cpp2::ExecutionResponse resp;
         std::string cmd = "GO FROM hash(\"Laura\") OVER study "
@@ -412,6 +587,18 @@ TEST_F(DataTest, InsertVertex) {
         };
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
     }
+    {
+        cpp2::ExecutionResponse resp;
+        std::string cmd = "GO FROM uuid(\"Laura\") OVER study "
+                          "YIELD $$.school.name, study._dst, "
+                          "$$.school.create_time, (string)study.start_time";
+        auto code = client_->execute(cmd, resp);
+        ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+        std::vector<std::tuple<std::string, int64_t, int64_t, std::string>> expected = {
+            {"sun_school", std::hash<std::string>()("sun_school"),  1262311200, "1535760000"},
+        };
+        ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+    }
     {
         cpp2::ExecutionResponse resp;
         std::string cmd = "FETCH PROP ON school hash(\"sun_school\") ";;
@@ -422,6 +609,16 @@ TEST_F(DataTest, InsertVertex) {
         };
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
     }
+    {
+        cpp2::ExecutionResponse resp;
+        std::string cmd = "FETCH PROP ON school uuid(\"sun_school\") ";;
+        auto code = client_->execute(cmd, resp);
+        ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+        std::vector<std::tuple<std::string, int64_t>> expected = {
+                {"sun_school", 1262311200},
+        };
+        ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+    }
     // TODO: Test insert multi tags, and delete one of them then check other existent
 }
 
@@ -487,6 +684,68 @@ TEST_F(DataTest, InsertMultiVersionTest) {
     }
 }
 
+TEST_F(DataTest, InsertMultiVersionWithUUIDTest) {
+    // Insert multi version vertex
+    {
+        cpp2::ExecutionResponse resp;
+        std::string cmd = "INSERT VERTEX person(name, age) VALUES "
+                          "uuid(\"Tony\"):(\"Tony\", 18), "
+                          "uuid(\"Mack\"):(\"Mack\", 19)";
+        auto code = client_->execute(cmd, resp);
+        ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+    }
+    {
+        cpp2::ExecutionResponse resp;
+        std::string cmd = "INSERT VERTEX person(name, age) VALUES "
+                          "uuid(\"Mack\"):(\"Mack\", 20)";
+        auto code = client_->execute(cmd, resp);
+        ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+    }
+    {
+        cpp2::ExecutionResponse resp;
+        std::string cmd = "INSERT VERTEX person(name, age) VALUES "
+                          "uuid(\"Mack\"):(\"Mack\", 21)";
+        auto code = client_->execute(cmd, resp);
+        ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+    }
+    // Insert multi version edge
+    {
+        cpp2::ExecutionResponse resp;
+        std::string cmd = "INSERT EDGE schoolmate(likeness) VALUES "
+                          "uuid(\"Tony\")->uuid(\"Mack\")@1:(1)";
+        auto code = client_->execute(cmd, resp);
+        ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+    }
+    {
+        cpp2::ExecutionResponse resp;
+        std::string cmd = "INSERT EDGE schoolmate(likeness) VALUES "
+                          "uuid(\"Tony\")->uuid(\"Mack\")@1:(2)";
+        auto code = client_->execute(cmd, resp);
+        ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+    }
+    {
+        cpp2::ExecutionResponse resp;
+        std::string cmd = "INSERT EDGE schoolmate(likeness) VALUES "
+                          "uuid(\"Tony\")->uuid(\"Mack\")@1:(3)";
+        auto code = client_->execute(cmd, resp);
+        ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+    }
+    // Get result
+    {
+        cpp2::ExecutionResponse resp;
+        std::string cmd = "GO FROM uuid(\"Tony\") OVER schoolmate "
+                          "YIELD $$.person.name, $$.person.age, schoolmate.likeness";
+        auto code = client_->execute(cmd, resp);
+        ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+        using valueType = std::tuple<std::string, int64_t, int64_t>;
+        // Get the latest result
+        std::vector<valueType> expected{
+            {"Mack", 21, 3},
+        };
+        ASSERT_TRUE(verifyResult(resp, expected));
+    }
+}
+
 TEST_F(DataTest, FindTest) {
     {
         cpp2::ExecutionResponse resp;
diff --git a/src/executor/test/FetchEdgesTest.cpp b/src/executor/test/FetchEdgesTest.cpp
index efc4239d0b64be3e832f4907b3f8ef7ea77cac21..bb382890c386d901d730d3d95f1092ca567165b2 100644
--- a/src/executor/test/FetchEdgesTest.cpp
+++ b/src/executor/test/FetchEdgesTest.cpp
@@ -163,8 +163,23 @@ TEST_F(FetchEdgesTest, base) {
         auto &player = players_["Boris Diaw"];
         auto &serve = player.serves()[0];
         auto &team = teams_[std::get<0>(serve)];
-        auto *fmt = "FETCH PROP ON serve hash(\"%s\")->hash(\"%s\")"
-                    " YIELD serve.start_year, serve.end_year";
+        auto *fmt = "FETCH PROP ON serve hash(\"%s\")->hash(\"%s\") "
+                    "YIELD serve.start_year, serve.end_year";
+        auto query = folly::stringPrintf(fmt, player.name().c_str(), team.name().c_str());
+        auto code = client_->execute(query, resp);
+        ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+        std::vector<std::tuple<int64_t, int64_t>> expected = {
+            {std::get<1>(serve), std::get<2>(serve)},
+        };
+        ASSERT_TRUE(verifyResult(resp, expected));
+    }
+    {
+        cpp2::ExecutionResponse resp;
+        auto &player = players_["Boris Diaw"];
+        auto &serve = player.serves()[0];
+        auto &team = teams_[std::get<0>(serve)];
+        auto *fmt = "FETCH PROP ON serve uuid(\"%s\")->hash(\"%s\") "
+                    "YIELD serve.start_year, serve.end_year";
         auto query = folly::stringPrintf(fmt, player.name().c_str(), team.name().c_str());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
@@ -236,6 +251,20 @@ TEST_F(FetchEdgesTest, noYield) {
         };
         ASSERT_TRUE(verifyResult(resp, expected));
     }
+    {
+        cpp2::ExecutionResponse resp;
+        auto &player = players_["Boris Diaw"];
+        auto &serve = player.serves()[0];
+        auto &team = teams_[std::get<0>(serve)];
+        auto *fmt = "FETCH PROP ON serve uuid(\"%s\")->hash(\"%s\")";
+        auto query = folly::stringPrintf(fmt, player.name().c_str(), team.name().c_str());
+        auto code = client_->execute(query, resp);
+        ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+        std::vector<std::tuple<int64_t, int64_t>> expected = {
+            {std::get<1>(serve), std::get<2>(serve)},
+        };
+        ASSERT_TRUE(verifyResult(resp, expected));
+    }
 }
 
 TEST_F(FetchEdgesTest, distinct) {
@@ -347,22 +376,22 @@ TEST_F(FetchEdgesTest, noInput) {
 TEST_F(FetchEdgesTest, syntaxError) {
     {
         cpp2::ExecutionResponse resp;
-        auto query = "FETCH PROP ON serve hash(\"Boris Diaw\")->hash(\"Spurs\")"
-                     " YIELD $^.serve.start_year";
+        auto query = "FETCH PROP ON serve hash(\"Boris Diaw\")->hash(\"Spurs\") "
+                     "YIELD $^.serve.start_year";
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::E_SYNTAX_ERROR, code);
     }
     {
         cpp2::ExecutionResponse resp;
-        auto query = "FETCH PROP ON serve hash(\"Boris Diaw\")->hash(\"Spurs\")"
-                     " YIELD $$.serve.start_year";
+        auto query = "FETCH PROP ON serve hash(\"Boris Diaw\")->hash(\"Spurs\") "
+                     "YIELD $$.serve.start_year";
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::E_SYNTAX_ERROR, code);
     }
     {
         cpp2::ExecutionResponse resp;
-        auto query = "FETCH PROP ON serve hash(\"Boris Diaw\")->hash(\"Spurs\")"
-                     " YIELD abc.start_year";
+        auto query = "FETCH PROP ON serve hash(\"Boris Diaw\")->hash(\"Spurs\") "
+                     "YIELD abc.start_year";
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::E_SYNTAX_ERROR, code);
     }
@@ -371,8 +400,16 @@ TEST_F(FetchEdgesTest, syntaxError) {
 TEST_F(FetchEdgesTest, nonExistEdge) {
     {
         cpp2::ExecutionResponse resp;
-        auto query = "FETCH PROP ON serve hash(\"Zion Williamson\")->hash(\"Spurs\")"
-                     " YIELD serve.start_year";
+        auto query = "FETCH PROP ON serve hash(\"Zion Williamson\")->hash(\"Spurs\") "
+                     "YIELD serve.start_year";
+        auto code = client_->execute(query, resp);
+        ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+        ASSERT_EQ(nullptr, resp.get_rows());
+    }
+    {
+        cpp2::ExecutionResponse resp;
+        auto query = "FETCH PROP ON serve uuid(\"Zion Williamson\")->hash(\"Spurs\") "
+                     "YIELD serve.start_year";
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
         ASSERT_EQ(nullptr, resp.get_rows());
diff --git a/src/executor/test/FetchVerticesTest.cpp b/src/executor/test/FetchVerticesTest.cpp
index 61f8220692b5a571fe342ec96cd5c8d3bdf9a1f2..713a2926bd2e7d7714f2ca521f2c322ce002c8bf 100644
--- a/src/executor/test/FetchVerticesTest.cpp
+++ b/src/executor/test/FetchVerticesTest.cpp
@@ -127,8 +127,8 @@ TEST_F(FetchVerticesTest, base) {
     {
         cpp2::ExecutionResponse resp;
         auto &player = players_["Boris Diaw"];
-        auto *fmt = "FETCH PROP ON player hash(\"%s\")"
-                    " YIELD player.name, player.age";
+        auto *fmt = "FETCH PROP ON player hash(\"%s\") "
+                    "YIELD player.name, player.age";
         auto query = folly::stringPrintf(fmt, player.name().c_str());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
@@ -143,6 +143,19 @@ TEST_F(FetchVerticesTest, base) {
         };
         ASSERT_TRUE(verifyResult(resp, expected));
     }
+    {
+        cpp2::ExecutionResponse resp;
+        auto &player = players_["Boris Diaw"];
+        auto *fmt = "FETCH PROP ON player uuid(\"%s\") "
+                    "YIELD player.name, player.age";
+        auto query = folly::stringPrintf(fmt, player.name().c_str());
+        auto code = client_->execute(query, resp);
+        ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+        std::vector<std::tuple<std::string, int64_t>> expected = {
+            {player.name(), player.age()},
+        };
+        ASSERT_TRUE(verifyResult(resp, expected));
+    }
 }
 
 TEST_F(FetchVerticesTest, noYield) {
@@ -182,6 +195,18 @@ TEST_F(FetchVerticesTest, noYield) {
         };
         ASSERT_TRUE(verifyResult(resp, expected));
     }
+    {
+        cpp2::ExecutionResponse resp;
+        auto &player = players_["Boris Diaw"];
+        auto *fmt = "FETCH PROP ON player uuid(\"%s\")";
+        auto query = folly::stringPrintf(fmt, player.name().c_str());
+        auto code = client_->execute(query, resp);
+        ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+        std::vector<std::tuple<std::string, int64_t>> expected = {
+            {player.name(), player.age()},
+        };
+        ASSERT_TRUE(verifyResult(resp, expected));
+    }
 }
 
 TEST_F(FetchVerticesTest, distinct) {
diff --git a/src/executor/test/TraverseTestBase.h b/src/executor/test/TraverseTestBase.h
index 4bc53d6914d55ad633d5a7a30b53ba6939d26ab7..94d75b2797eef176cd9236ea22f7f95e5f725586 100644
--- a/src/executor/test/TraverseTestBase.h
+++ b/src/executor/test/TraverseTestBase.h
@@ -675,6 +675,31 @@ AssertionResult TraverseTestBase::prepareData() {
                                << static_cast<int32_t>(code);
         }
     }
+    {
+        // Insert vertices `player' with uuid
+        cpp2::ExecutionResponse resp;
+        std::string query;
+        query.reserve(1024);
+        query += "INSERT VERTEX player(name, age) VALUES ";
+        for (auto &player : players_) {
+            query += "uuid(\"";
+            query += player.name();
+            query += "\"): ";
+            query += "(";
+            query += "\"";
+            query += player.name();
+            query += "\"";
+            query += ",";
+            query += std::to_string(player.age());
+            query += "),\n\t";
+        }
+        query.resize(query.size() - 3);
+        auto code = client_->execute(query, resp);
+        if (code != cpp2::ErrorCode::SUCCEEDED) {
+            return TestError() << "Insert `players' failed: "
+                               << static_cast<int32_t>(code);
+        }
+    }
     {
         // Insert vertices `team'
         cpp2::ExecutionResponse resp;
@@ -702,7 +727,7 @@ AssertionResult TraverseTestBase::prepareData() {
         cpp2::ExecutionResponse resp;
         std::string query;
         query.reserve(1024);
-        query += "INSERT EDGE serve(start_year, end_year) VALUES";
+        query += "INSERT EDGE serve(start_year, end_year) VALUES ";
         for (auto &player : players_) {
             for (auto &serve : player.serves()) {
                 auto &team = std::get<0>(serve);
@@ -726,6 +751,36 @@ AssertionResult TraverseTestBase::prepareData() {
                                << static_cast<int32_t>(code);
         }
     }
+    {
+        // Insert edges `serve' with uuid
+        cpp2::ExecutionResponse resp;
+        std::string query;
+        query.reserve(1024);
+        query += "INSERT EDGE serve(start_year, end_year) VALUES ";
+        for (auto &player : players_) {
+            for (auto &serve : player.serves()) {
+                auto &team = std::get<0>(serve);
+                auto startYear = std::get<1>(serve);
+                auto endYear = std::get<2>(serve);
+                query += "uuid(\"";
+                query += player.name();
+                query += "\") -> ";
+                query += std::to_string(teams_[team].vid());
+                query += ": ";
+                query += "(";
+                query += std::to_string(startYear);
+                query += ", ";
+                query += std::to_string(endYear);
+                query += "),\n\t";
+            }
+        }
+        query.resize(query.size() - 3);
+        auto code = client_->execute(query, resp);
+        if (code != cpp2::ErrorCode::SUCCEEDED) {
+            return TestError() << "Insert `serve' failed: "
+                               << static_cast<int32_t>(code);
+        }
+    }
     {
         // Insert edges `like'
         cpp2::ExecutionResponse resp;
@@ -752,6 +807,33 @@ AssertionResult TraverseTestBase::prepareData() {
                                << static_cast<int32_t>(code);
         }
     }
+    {
+        // Insert edges `like' with uuid
+        cpp2::ExecutionResponse resp;
+        std::string query;
+        query.reserve(1024);
+        query += "INSERT EDGE like(likeness) VALUES ";
+        for (auto &player : players_) {
+            for (auto &like : player.likes()) {
+                auto &other = std::get<0>(like);
+                auto likeness = std::get<1>(like);
+                query += "uuid(\"";
+                query += player.name();
+                query += "\") -> uuid(\"";
+                query += players_[other].name();
+                query += "\"): ";
+                query += "(";
+                query += std::to_string(likeness);
+                query += "),\n\t";
+            }
+        }
+        query.resize(query.size() - 3);
+        auto code = client_->execute(query, resp);
+        if (code != cpp2::ErrorCode::SUCCEEDED) {
+            return TestError() << "Insert `like' failed: "
+                               << static_cast<int32_t>(code);
+        }
+    }
     return TestOK();
 }
 
diff --git a/src/parser/parser.yy b/src/parser/parser.yy
index 47e90f650bfd3d8f61047fe62d0e1a5212bc06df..8499b549df6c582c2810df6541cd8eb1e9a754a4 100644
--- a/src/parser/parser.yy
+++ b/src/parser/parser.yy
@@ -98,7 +98,7 @@ class GraphScanner;
 %token KW_EDGE KW_EDGES KW_STEPS KW_OVER KW_UPTO KW_REVERSELY KW_SPACE KW_DELETE KW_FIND
 %token KW_INT KW_BIGINT KW_DOUBLE KW_STRING KW_BOOL KW_TAG KW_TAGS KW_UNION KW_INTERSECT KW_MINUS
 %token KW_NO KW_OVERWRITE KW_IN KW_DESCRIBE KW_DESC KW_SHOW KW_HOSTS KW_TIMESTAMP KW_ADD
-%token KW_PARTITION_NUM KW_REPLICA_FACTOR KW_DROP KW_REMOVE KW_SPACES KW_INGEST
+%token KW_PARTITION_NUM KW_REPLICA_FACTOR KW_DROP KW_REMOVE KW_SPACES KW_INGEST KW_UUID
 %token KW_IF KW_NOT KW_EXISTS KW_WITH KW_FIRSTNAME KW_LASTNAME KW_EMAIL KW_PHONE KW_USER KW_USERS
 %token KW_PASSWORD KW_CHANGE KW_ROLE KW_GOD KW_ADMIN KW_GUEST KW_GRANT KW_REVOKE KW_ON
 %token KW_ROLES KW_BY KW_DOWNLOAD KW_HDFS
@@ -133,6 +133,7 @@ class GraphScanner;
 %type <expr> vid_ref_expression
 %type <expr> vid
 %type <expr> function_call_expression
+%type <expr> uuid_expression
 %type <argument_list> argument_list
 %type <type> type_spec
 %type <step_clause> step_clause
@@ -331,6 +332,12 @@ function_call_expression
     }
     ;
 
+uuid_expression
+    : KW_UUID L_PAREN STRING R_PAREN {
+        $$ = new UUIDExpression($3);
+    }
+    ;
+
 argument_list
     : %empty {
         $$ = nullptr;
@@ -518,6 +525,9 @@ vid
     | function_call_expression {
         $$ = $1;
     }
+    | uuid_expression {
+        $$ = $1;
+    }
     ;
 
 unary_integer
diff --git a/src/parser/scanner.lex b/src/parser/scanner.lex
index d80d9c4e4395b0f68d4c4a4ee4f4ef968f4d2894..b6755139462e3b88d578c8323306e12c88dc5987 100644
--- a/src/parser/scanner.lex
+++ b/src/parser/scanner.lex
@@ -119,6 +119,7 @@ PROP                        ([Pp][Rr][Oo][Pp])
 ALL                         ([Aa][Ll][Ll])
 BALANCE                     ([Bb][Aa][Ll][Aa][Nn][Cc][Ee])
 LEADER                      ([Ll][Ee][Aa][Dd][Ee][Rr])
+UUID                        ([Uu][Uu][Ii][Dd])
 OF                          ([Oo][Ff])
 DATA                        ([Dd][Aa][Tt][Aa])
 
@@ -230,6 +231,7 @@ IP_OCTET                    ([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])
 {ALL}                       { return TokenType::KW_ALL; }
 {BALANCE}                   { return TokenType::KW_BALANCE; }
 {LEADER}                    { return TokenType::KW_LEADER; }
+{UUID}                      { return TokenType::KW_UUID; }
 {DATA}                      { return TokenType::KW_DATA; }
 
 "."                         { return TokenType::DOT; }
diff --git a/src/parser/test/CMakeLists.txt b/src/parser/test/CMakeLists.txt
index 7783b23e8c6ac77d728815ccb8698e8a41760198..7a381d4f38afefed7348bd15d7580721dced826f 100644
--- a/src/parser/test/CMakeLists.txt
+++ b/src/parser/test/CMakeLists.txt
@@ -1,29 +1,38 @@
 set(PARSER_TEST_LIBS
     $<TARGET_OBJECTS:parser_obj>
     $<TARGET_OBJECTS:filter_obj>
-    $<TARGET_OBJECTS:base_obj>
     $<TARGET_OBJECTS:network_obj>
     $<TARGET_OBJECTS:fs_obj>
     $<TARGET_OBJECTS:time_obj>
+    $<TARGET_OBJECTS:gflags_man_obj>
+    $<TARGET_OBJECTS:schema_obj>
+    $<TARGET_OBJECTS:meta_client>
+    $<TARGET_OBJECTS:meta_thrift_obj>
+    $<TARGET_OBJECTS:storage_client>
+    $<TARGET_OBJECTS:storage_thrift_obj>
+    $<TARGET_OBJECTS:common_thrift_obj>
+    $<TARGET_OBJECTS:thrift_obj>
+    $<TARGET_OBJECTS:thread_obj>
+    $<TARGET_OBJECTS:base_obj>
 )
 
 nebula_add_test(
     NAME parser_test
     SOURCES ParserTest.cpp
     OBJECTS ${PARSER_TEST_LIBS}
-    LIBRARIES gtest gtest_main
+    LIBRARIES gtest gtest_main ${THRIFT_LIBRARIES} wangle
 )
 
 nebula_add_test(
     NAME scanner_test
     SOURCES ScannerTest.cpp
     OBJECTS ${PARSER_TEST_LIBS}
-    LIBRARIES gtest gtest_main
+    LIBRARIES gtest gtest_main ${THRIFT_LIBRARIES} wangle
 )
 
 nebula_add_executable(
     NAME parser_benchmark
     SOURCES ParserBenchmark.cpp
     OBJECTS ${PARSER_TEST_LIBS}
-    LIBRARIES follybenchmark boost_regex
+    LIBRARIES follybenchmark boost_regex ${THRIFT_LIBRARIES} wangle
 )
diff --git a/src/parser/test/ParserTest.cpp b/src/parser/test/ParserTest.cpp
index 6b57bb700df5de771b201e86cb7a06a32b1d24d1..c22acc47e7cd75968ee24f71d41f6c450d4ea6f1 100644
--- a/src/parser/test/ParserTest.cpp
+++ b/src/parser/test/ParserTest.cpp
@@ -503,6 +503,20 @@ TEST(Parser, InsertVertex) {
         auto result = parser.parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
+    {
+        GQLParser parser;
+        std::string query = "INSERT VERTEX person(name,age,married,salary,create_time) "
+                            "VALUES hash(\"dutor\"):(\"dutor\", 30, true, 3.14, 1551331900)";
+        auto result = parser.parse(query);
+        ASSERT_TRUE(result.ok()) << result.status();
+    }
+    {
+        GQLParser parser;
+        std::string query = "INSERT VERTEX person(name,age,married,salary,create_time) "
+                            "VALUES uuid(\"dutor\"):(\"dutor\", 30, true, 3.14, 1551331900)";
+        auto result = parser.parse(query);
+        ASSERT_TRUE(result.ok()) << result.status();
+    }
     // Test insert empty value
     {
         GQLParser parser;
@@ -527,6 +541,20 @@ TEST(Parser, InsertVertex) {
         auto result = parser.parse(query);
         ASSERT_TRUE(result.status().isSyntaxError());
     }
+    {
+        GQLParser parser;
+        std::string query = "INSERT VERTEX person(name, age) "
+                            "VALUES hash(\"dutor\"):(\'dutor, 30)";
+        auto result = parser.parse(query);
+        ASSERT_TRUE(result.status().isSyntaxError());
+    }
+    {
+        GQLParser parser;
+        std::string query = "INSERT VERTEX person(name, age) "
+                            "VALUES uuid(\"dutor\"):(\'dutor, 30)";
+        auto result = parser.parse(query);
+        ASSERT_TRUE(result.status().isSyntaxError());
+    }
 }
 
 TEST(Parser, UpdateVertex) {
@@ -588,6 +616,20 @@ TEST(Parser, InsertEdge) {
         auto result = parser.parse(query);
         ASSERT_TRUE(result.ok()) << result.status();
     }
+    {
+        GQLParser parser;
+        std::string query = "INSERT EDGE transfer(amount, time) "
+                            "VALUES hash(\"from\")->hash(\"to\"):(3.75, 1537408527)";
+        auto result = parser.parse(query);
+        ASSERT_TRUE(result.ok()) << result.status();
+    }
+    {
+        GQLParser parser;
+        std::string query = "INSERT EDGE transfer(amount, time) "
+                            "VALUES uuid(\"from\")->uuid(\"to\"):(3.75, 1537408527)";
+        auto result = parser.parse(query);
+        ASSERT_TRUE(result.ok()) << result.status();
+    }
     // multi edge
     {
         GQLParser parser;
@@ -1040,6 +1082,12 @@ TEST(Parser, UnreservedKeywords) {
         auto result = parser.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);
+        ASSERT_TRUE(result.ok()) << result.status();
+    }
     {
         GQLParser parser;
         std::string query = "GO FROM 123 OVER like YIELD $$.tag1.EMAIL, like.users,"
@@ -1048,12 +1096,26 @@ TEST(Parser, UnreservedKeywords) {
         auto result = parser.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);
+        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);
         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);
+        ASSERT_TRUE(result.ok()) << result.status();
+    }
 }
 
 TEST(Parser, Annotation) {
diff --git a/src/parser/test/ScannerTest.cpp b/src/parser/test/ScannerTest.cpp
index cc35e2b07a744d3357a5fdb0b601462dd4ceb1ed..aad3e44c2d9bda527224b70cd98eca3b74f225be 100644
--- a/src/parser/test/ScannerTest.cpp
+++ b/src/parser/test/ScannerTest.cpp
@@ -379,6 +379,12 @@ TEST(Scanner, Basic) {
         CHECK_SEMANTIC_TYPE("LEADER", TokenType::KW_LEADER),
         CHECK_SEMANTIC_TYPE("Leader", TokenType::KW_LEADER),
         CHECK_SEMANTIC_TYPE("leader", TokenType::KW_LEADER),
+        CHECK_SEMANTIC_TYPE("FETCH", TokenType::KW_FETCH),
+        CHECK_SEMANTIC_TYPE("Fetch", TokenType::KW_FETCH),
+        CHECK_SEMANTIC_TYPE("fetch", TokenType::KW_FETCH),
+        CHECK_SEMANTIC_TYPE("UUID", TokenType::KW_UUID),
+        CHECK_SEMANTIC_TYPE("Uuid", TokenType::KW_UUID),
+        CHECK_SEMANTIC_TYPE("uuid", TokenType::KW_UUID),
         CHECK_SEMANTIC_TYPE("OF", TokenType::KW_OF),
         CHECK_SEMANTIC_TYPE("Of", TokenType::KW_OF),
         CHECK_SEMANTIC_TYPE("of", TokenType::KW_OF),