diff --git a/src/context/test/CMakeLists.txt b/src/context/test/CMakeLists.txt
index 7d7aec6c5ca9716f0109ed6c8d8cf2d8a9b413f1..2924174f1a969eddbddb39f76fa467baede15569 100644
--- a/src/context/test/CMakeLists.txt
+++ b/src/context/test/CMakeLists.txt
@@ -53,8 +53,7 @@ nebula_add_test(
         ${THRIFT_LIBRARIES}
         gtest
         wangle
-        proxygenhttpserver
-        proxygenlib
+        ${PROXYGEN_LIBRARIES}
 )
 
 nebula_add_executable(
@@ -69,6 +68,5 @@ nebula_add_executable(
         boost_regex
         ${THRIFT_LIBRARIES}
         wangle
-        proxygenhttpserver
-        proxygenlib
+        ${PROXYGEN_LIBRARIES}
 )
diff --git a/src/daemons/CMakeLists.txt b/src/daemons/CMakeLists.txt
index bf9eeeda9661ca9cc6fdda49fe92627e0233e0bd..26066c57b970da1f1344e8b6b667980a212b6a37 100644
--- a/src/daemons/CMakeLists.txt
+++ b/src/daemons/CMakeLists.txt
@@ -62,8 +62,7 @@ nebula_add_executable(
         $<TARGET_OBJECTS:common_ft_es_graph_adapter_obj>
         $<TARGET_OBJECTS:common_version_obj>
     LIBRARIES
-        proxygenhttpserver
-        proxygenlib
+        ${PROXYGEN_LIBRARIES}
         ${THRIFT_LIBRARIES}
         wangle
 )
diff --git a/src/daemons/GraphDaemon.cpp b/src/daemons/GraphDaemon.cpp
index b71308c65388151cc8e29da89e39706478fd1ced..3b2add55f1eb3261ccc074f53cc8b9da14c1d667 100644
--- a/src/daemons/GraphDaemon.cpp
+++ b/src/daemons/GraphDaemon.cpp
@@ -151,7 +151,6 @@ int main(int argc, char *argv[]) {
     gServer->setIdleTimeout(std::chrono::seconds(FLAGS_client_idle_timeout_secs));
     gServer->setNumAcceptThreads(FLAGS_num_accept_threads);
     gServer->setListenBacklog(FLAGS_listen_backlog);
-    gServer->setThreadStackSizeMB(5);
     setupThreadManager();
 
     // Setup the signal handlers
diff --git a/src/executor/StorageAccessExecutor.cpp b/src/executor/StorageAccessExecutor.cpp
index 8d129b3b356c367a585087744decbc1edb7500c3..4939c4637c6cb380cd6952652cca93ce4fd33e67 100644
--- a/src/executor/StorageAccessExecutor.cpp
+++ b/src/executor/StorageAccessExecutor.cpp
@@ -46,7 +46,7 @@ DataSet buildRequestDataSet(const SpaceInfo &space,
     std::unordered_set<VidType> uniqueSet;
     uniqueSet.reserve(iter->size());
 
-    const auto &vidType = space.spaceDesc.vid_type;
+    const auto &vidType = *(space.spaceDesc.vid_type_ref());
 
     for (; iter->valid(); iter->next()) {
         auto vid = expr->eval(exprCtx(iter));
@@ -66,7 +66,7 @@ DataSet buildRequestDataSet(const SpaceInfo &space,
 }   // namespace internal
 
 bool StorageAccessExecutor::isIntVidType(const SpaceInfo &space) const {
-    return space.spaceDesc.vid_type.type == meta::cpp2::PropertyType::INT64;
+    return (*space.spaceDesc.vid_type_ref()).type == meta::cpp2::PropertyType::INT64;
 }
 
 DataSet StorageAccessExecutor::buildRequestDataSetByVidType(Iterator *iter,
diff --git a/src/executor/StorageAccessExecutor.h b/src/executor/StorageAccessExecutor.h
index f7eec220c1a8f6e4be2537736ae5fd175d1044ea..b23c6b798ce62d36c31bd9abc70c2b4b23a79679 100644
--- a/src/executor/StorageAccessExecutor.h
+++ b/src/executor/StorageAccessExecutor.h
@@ -7,6 +7,7 @@
 #ifndef EXECUTOR_STORAGEACCESSEXECUTOR_H_
 #define EXECUTOR_STORAGEACCESSEXECUTOR_H_
 
+#include <thrift/lib/cpp/util/EnumUtils.h>
 #include "common/clients/storage/StorageClientBase.h"
 #include "context/QueryContext.h"
 #include "executor/Executor.h"
@@ -40,7 +41,7 @@ protected:
             const auto &failedCodes = rpcResp.failedParts();
             for (auto it = failedCodes.begin(); it != failedCodes.end(); it++) {
                 LOG(ERROR) << name_ << " failed, error "
-                           << storage::cpp2::_ErrorCode_VALUES_TO_NAMES.at(it->second) << ", part "
+                           << apache::thrift::util::enumNameSafe(it->second) << ", part "
                            << it->first;
             }
             // cannot execute at all, or partial success is not accepted
@@ -114,7 +115,7 @@ protected:
             default:
                 auto status = Status::Error("Storage Error: part: %d, error: %s(%d).",
                                             partId,
-                                            storage::cpp2::_ErrorCode_VALUES_TO_NAMES.at(code),
+                                            apache::thrift::util::enumNameSafe(code).c_str(),
                                             static_cast<int32_t>(code));
                 LOG(ERROR) << status;
                 return status;
diff --git a/src/executor/admin/BalanceExecutor.cpp b/src/executor/admin/BalanceExecutor.cpp
index 4c5af86a4e3ce5e41080a9ab907afc5ab2f64605..5818e305cc0f337a3277472928c84b514da2936d 100644
--- a/src/executor/admin/BalanceExecutor.cpp
+++ b/src/executor/admin/BalanceExecutor.cpp
@@ -19,7 +19,7 @@ folly::Future<Status> BalanceExecutor::balance() {
     auto *bNode = asNode<Balance>(node());
     return qctx()->getMetaClient()->balance(bNode->deleteHosts(), false, false)
         .via(runner())
-        .then([this](StatusOr<int64_t> resp) {
+        .thenValue([this](StatusOr<int64_t> resp) {
             SCOPED_TIMER(&execTime_);
             if (!resp.ok()) {
                 LOG(ERROR) << resp.status();
diff --git a/src/executor/admin/BalanceLeadersExecutor.cpp b/src/executor/admin/BalanceLeadersExecutor.cpp
index 77837dc3618882ba185c45008dc21291af9ea1f3..55434a2be75043296cb1bf4ee82976224db73427 100644
--- a/src/executor/admin/BalanceLeadersExecutor.cpp
+++ b/src/executor/admin/BalanceLeadersExecutor.cpp
@@ -18,7 +18,7 @@ folly::Future<Status> BalanceLeadersExecutor::execute() {
 folly::Future<Status> BalanceLeadersExecutor::balanceLeaders() {
     return qctx()->getMetaClient()->balanceLeader()
         .via(runner())
-        .then([this](StatusOr<bool> resp) {
+        .thenValue([this](StatusOr<bool> resp) {
             SCOPED_TIMER(&execTime_);
             if (!resp.ok()) {
                 LOG(ERROR) << resp.status();
diff --git a/src/executor/admin/ChangePasswordExecutor.cpp b/src/executor/admin/ChangePasswordExecutor.cpp
index 7409b98518a79c9ba438c04777da29df0c5e6ccb..e69d133ffcd36802bb77b18e4806959bbebc5f47 100644
--- a/src/executor/admin/ChangePasswordExecutor.cpp
+++ b/src/executor/admin/ChangePasswordExecutor.cpp
@@ -26,7 +26,7 @@ folly::Future<Status> ChangePasswordExecutor::changePassword() {
                          encryption::MD5Utils::md5Encode(*cpNode->newPassword()),
                          encryption::MD5Utils::md5Encode(*cpNode->password()))
         .via(runner())
-        .then([this](StatusOr<bool> &&resp) {
+        .thenValue([this](StatusOr<bool> &&resp) {
             SCOPED_TIMER(&execTime_);
             NG_RETURN_IF_ERROR(resp);
             if (!resp.value()) {
diff --git a/src/executor/admin/ConfigExecutor.cpp b/src/executor/admin/ConfigExecutor.cpp
index 218ce8fa0fec07c9cb603a3993fd8f8228f954c1..0f743b663e3251b88ff97b05c067f78bbd908e12 100644
--- a/src/executor/admin/ConfigExecutor.cpp
+++ b/src/executor/admin/ConfigExecutor.cpp
@@ -4,6 +4,8 @@
 * attached with Common Clause Condition 1.0, found in the LICENSES directory.
 */
 
+#include <thrift/lib/cpp/util/EnumUtils.h>
+
 #include "common/conf/Configuration.h"
 #include "executor/admin/ConfigExecutor.h"
 #include "planner/Admin.h"
@@ -18,10 +20,10 @@ std::vector<Value> ConfigBaseExecutor::generateColumns(const meta::cpp2::ConfigI
     std::vector<Value> columns;
     columns.resize(5);
     auto value = item.get_value();
-    columns[0].setStr(meta::cpp2::_ConfigModule_VALUES_TO_NAMES.at(item.get_module()));
+    columns[0].setStr(apache::thrift::util::enumNameSafe(item.get_module()));
     columns[1].setStr(item.get_name());
     columns[2].setStr(value.typeName());
-    columns[3].setStr(meta::cpp2::_ConfigMode_VALUES_TO_NAMES.at(item.get_mode()));
+    columns[3].setStr(apache::thrift::util::enumNameSafe(item.get_mode()));
     columns[4] = std::move(value);
     return columns;
 }
@@ -42,13 +44,13 @@ folly::Future<Status> ShowConfigsExecutor::execute() {
     auto *scNode = asNode<ShowConfigs>(node());
     return qctx()->getMetaClient()->listConfigs(scNode->getModule())
             .via(runner())
-            .then([this, scNode](StatusOr<std::vector<meta::cpp2::ConfigItem>> resp) {
+            .thenValue([this, scNode](StatusOr<std::vector<meta::cpp2::ConfigItem>> resp) {
                 if (!resp.ok()) {
-                    auto module = meta::cpp2::_ConfigModule_VALUES_TO_NAMES.at(scNode->getModule());
+                    auto module = apache::thrift::util::enumNameSafe(scNode->getModule());
                     LOG(ERROR) << "Show configs `" << module
                                << "' failed: " << resp.status();
                     return Status::Error("Show config `%s' failed: %s",
-                                          module,
+                                          module.c_str(),
                                           resp.status().toString().c_str());
                 }
 
@@ -65,7 +67,7 @@ folly::Future<Status> SetConfigExecutor::execute() {
                                               scNode->getName(),
                                               scNode->getValue())
             .via(runner())
-            .then([scNode](StatusOr<bool> resp) {
+            .thenValue([scNode](StatusOr<bool> resp) {
                 if (!resp.ok()) {
                     LOG(ERROR) << "Set config `" << scNode->getName()
                                << "' failed: " << resp.status();
@@ -84,7 +86,7 @@ folly::Future<Status> GetConfigExecutor::execute() {
     return qctx()->getMetaClient()->getConfig(gcNode->getModule(),
                                               gcNode->getName())
             .via(runner())
-            .then([this, gcNode](StatusOr<std::vector<meta::cpp2::ConfigItem>> resp) {
+            .thenValue([this, gcNode](StatusOr<std::vector<meta::cpp2::ConfigItem>> resp) {
                 if (!resp.ok()) {
                     LOG(ERROR) << "Get config `" << gcNode->getName()
                                << "' failed: " << resp.status();
diff --git a/src/executor/admin/CreateUserExecutor.cpp b/src/executor/admin/CreateUserExecutor.cpp
index d9ecc22d98cbc77cfe97fbc0380d12895714a6f5..fc1b31f9d4d39539cb3049a39f8f0b06792fada9 100644
--- a/src/executor/admin/CreateUserExecutor.cpp
+++ b/src/executor/admin/CreateUserExecutor.cpp
@@ -26,7 +26,7 @@ folly::Future<Status> CreateUserExecutor::createUser() {
                      encryption::MD5Utils::md5Encode(*cuNode->password()),
                      cuNode->ifNotExist())
         .via(runner())
-        .then([this](StatusOr<bool> resp) {
+        .thenValue([this](StatusOr<bool> resp) {
             SCOPED_TIMER(&execTime_);
             NG_RETURN_IF_ERROR(resp);
             if (!resp.value()) {
diff --git a/src/executor/admin/DownloadExecutor.cpp b/src/executor/admin/DownloadExecutor.cpp
index f4611cf27ba891a1f532506e444aa18c3312781f..a7a63ece36338c139782f9ccc84e87ee4dc167d1 100644
--- a/src/executor/admin/DownloadExecutor.cpp
+++ b/src/executor/admin/DownloadExecutor.cpp
@@ -20,7 +20,7 @@ folly::Future<Status> DownloadExecutor::execute() {
                                              dNode->getHdfsPath(),
                                              spaceId)
         .via(runner())
-        .then([this](StatusOr<bool> resp) {
+        .thenValue([this](StatusOr<bool> resp) {
             SCOPED_TIMER(&execTime_);
             NG_RETURN_IF_ERROR(resp);
             if (!resp.value()) {
diff --git a/src/executor/admin/DropUserExecutor.cpp b/src/executor/admin/DropUserExecutor.cpp
index 9ab48beff561a897dfba04436c5f694ad5c78d9c..23529cc8db9a8d294566a95ae7745238a95385bb 100644
--- a/src/executor/admin/DropUserExecutor.cpp
+++ b/src/executor/admin/DropUserExecutor.cpp
@@ -20,7 +20,7 @@ folly::Future<Status> DropUserExecutor::dropUser() {
     auto *duNode = asNode<DropUser>(node());
     return qctx()->getMetaClient()->dropUser(*duNode->username(), duNode->ifExist())
         .via(runner())
-        .then([this](StatusOr<bool> resp) {
+        .thenValue([this](StatusOr<bool> resp) {
             SCOPED_TIMER(&execTime_);
             NG_RETURN_IF_ERROR(resp);
             if (!resp.value()) {
diff --git a/src/executor/admin/GrantRoleExecutor.cpp b/src/executor/admin/GrantRoleExecutor.cpp
index 51157c43667891a355cecb1828ee6a6d3660e004..207f18d2cdc70a4c3c7bb84f9c5f4e76a859f3a3 100644
--- a/src/executor/admin/GrantRoleExecutor.cpp
+++ b/src/executor/admin/GrantRoleExecutor.cpp
@@ -39,7 +39,7 @@ folly::Future<Status> GrantRoleExecutor::grantRole() {
         ->getMetaClient()
         ->grantToUser(std::move(item))
         .via(runner())
-        .then([this](StatusOr<bool> resp) {
+        .thenValue([this](StatusOr<bool> resp) {
             SCOPED_TIMER(&execTime_);
             NG_RETURN_IF_ERROR(resp);
             if (!resp.value()) {
diff --git a/src/executor/admin/GroupExecutor.cpp b/src/executor/admin/GroupExecutor.cpp
index 9e19b816aa6a315e882ce0efead03e74af2922cf..cf5f4c2afe86caa0efd433fbf7d4e31eb3dd87a4 100644
--- a/src/executor/admin/GroupExecutor.cpp
+++ b/src/executor/admin/GroupExecutor.cpp
@@ -16,7 +16,7 @@ folly::Future<Status> AddGroupExecutor::execute() {
     auto *agNode = asNode<AddGroup>(node());
     return qctx()->getMetaClient()->addGroup(agNode->groupName(), agNode->zoneNames())
             .via(runner())
-            .then([](StatusOr<bool> resp) {
+            .thenValue([](StatusOr<bool> resp) {
                 if (!resp.ok()) {
                     LOG(ERROR) << "Add Group Failed: " << resp.status();
                     return resp.status();
@@ -30,7 +30,7 @@ folly::Future<Status> DropGroupExecutor::execute() {
     auto *dgNode = asNode<DropGroup>(node());
     return qctx()->getMetaClient()->dropGroup(dgNode->groupName())
             .via(runner())
-            .then([](StatusOr<bool> resp) {
+            .thenValue([](StatusOr<bool> resp) {
                 if (!resp.ok()) {
                     LOG(ERROR) << "Drop Group Failed: " << resp.status();
                     return resp.status();
@@ -44,7 +44,7 @@ folly::Future<Status> DescribeGroupExecutor::execute() {
     auto *dgNode = asNode<DescribeGroup>(node());
     return qctx()->getMetaClient()->getGroup(dgNode->groupName())
             .via(runner())
-            .then([this](StatusOr<std::vector<std::string>> resp) {
+            .thenValue([this](StatusOr<std::vector<std::string>> resp) {
                 if (!resp.ok()) {
                     LOG(ERROR) << "Describe Group Failed: " << resp.status();
                     return resp.status();
@@ -68,7 +68,7 @@ folly::Future<Status> AddZoneIntoGroupExecutor::execute() {
     auto *azNode = asNode<AddZoneIntoGroup>(node());
     return qctx()->getMetaClient()->addZoneIntoGroup(azNode->zoneName(), azNode->groupName())
             .via(runner())
-            .then([](StatusOr<bool> resp) {
+            .thenValue([](StatusOr<bool> resp) {
                 if (!resp.ok()) {
                     LOG(ERROR) << "Add Zone Into Group Failed: " << resp.status();
                     return resp.status();
@@ -82,7 +82,7 @@ folly::Future<Status> DropZoneFromGroupExecutor::execute() {
     auto *dzNode = asNode<DropZoneFromGroup>(node());
     return qctx()->getMetaClient()->dropZoneFromGroup(dzNode->zoneName(), dzNode->groupName())
             .via(runner())
-            .then([](StatusOr<bool> resp) {
+            .thenValue([](StatusOr<bool> resp) {
                 if (!resp.ok()) {
                     LOG(ERROR) << "Drop Zone From Group Failed: " << resp.status();
                     return resp.status();
@@ -95,7 +95,7 @@ folly::Future<Status> ListGroupsExecutor::execute() {
     SCOPED_TIMER(&execTime_);
     return qctx()->getMetaClient()->listGroups()
             .via(runner())
-            .then([this](StatusOr<std::vector<meta::cpp2::Group>> resp) {
+            .thenValue([this](StatusOr<std::vector<meta::cpp2::Group>> resp) {
                 if (!resp.ok()) {
                     LOG(ERROR) << "List Groups Failed: " << resp.status();
                     return resp.status();
@@ -105,7 +105,7 @@ folly::Future<Status> ListGroupsExecutor::execute() {
                 DataSet dataSet({"Name", "Zone"});
                 for (auto &group : groups) {
                     for (auto &zone : group.get_zone_names()) {
-                        Row row({group.group_name, zone});
+                        Row row({*group.group_name_ref(), zone});
                         dataSet.rows.emplace_back(std::move(row));
                     }
                 }
diff --git a/src/executor/admin/IngestExecutor.cpp b/src/executor/admin/IngestExecutor.cpp
index 2455bdb27383051bf192bd8945c0bea6e4edbdbe..b246494113d178610720068a013ec7ec8e3184ea 100644
--- a/src/executor/admin/IngestExecutor.cpp
+++ b/src/executor/admin/IngestExecutor.cpp
@@ -15,7 +15,7 @@ folly::Future<Status> IngestExecutor::execute() {
     auto spaceId = qctx()->rctx()->session()->space().id;
     return qctx()->getMetaClient()->ingest(spaceId)
         .via(runner())
-        .then([this](StatusOr<bool> resp) {
+        .thenValue([this](StatusOr<bool> resp) {
             SCOPED_TIMER(&execTime_);
             NG_RETURN_IF_ERROR(resp);
             if (!resp.value()) {
diff --git a/src/executor/admin/ListRolesExecutor.cpp b/src/executor/admin/ListRolesExecutor.cpp
index 7cf0a1d502bd6df2e788836f96bb4a82a05fbec4..9c6d3e8cc3378098ee95a01986333955fc6c5b8f 100644
--- a/src/executor/admin/ListRolesExecutor.cpp
+++ b/src/executor/admin/ListRolesExecutor.cpp
@@ -4,6 +4,8 @@
  * attached with Common Clause Condition 1.0, found in the LICENSES directory.
  */
 
+#include <thrift/lib/cpp/util/EnumUtils.h>
+
 #include "executor/admin/ListRolesExecutor.h"
 #include "context/QueryContext.h"
 #include "planner/Admin.h"
@@ -23,7 +25,7 @@ folly::Future<Status> ListRolesExecutor::listRoles() {
         ->getMetaClient()
         ->listRoles(lrNode->space())
         .via(runner())
-        .then([this](StatusOr<std::vector<meta::cpp2::RoleItem>> &&resp) {
+        .thenValue([this](StatusOr<std::vector<meta::cpp2::RoleItem>> &&resp) {
             SCOPED_TIMER(&execTime_);
             if (!resp.ok()) {
                 return std::move(resp).status();
@@ -39,12 +41,12 @@ folly::Future<Status> ListRolesExecutor::listRoles() {
                 foundItem->get_role_type() != meta::cpp2::RoleType::ADMIN) {
                 v.emplace_back(
                     Row({foundItem->get_user_id(),
-                         meta::cpp2::_RoleType_VALUES_TO_NAMES.at(foundItem->get_role_type())}));
+                         apache::thrift::util::enumNameSafe(foundItem->get_role_type())}));
             } else {
                 for (const auto &item : items) {
                     v.emplace_back(nebula::Row(
                         {item.get_user_id(),
-                         meta::cpp2::_RoleType_VALUES_TO_NAMES.at(item.get_role_type())}));
+                         apache::thrift::util::enumNameSafe(item.get_role_type())}));
                 }
             }
             return finish(std::move(v));
diff --git a/src/executor/admin/ListUserRolesExecutor.cpp b/src/executor/admin/ListUserRolesExecutor.cpp
index 6f4fa93ed1f833deaa13a5e885223a87fd2b8416..60efca14cbfebf6d0a06969d06b9c3ea6708aced 100644
--- a/src/executor/admin/ListUserRolesExecutor.cpp
+++ b/src/executor/admin/ListUserRolesExecutor.cpp
@@ -4,6 +4,8 @@
  * attached with Common Clause Condition 1.0, found in the LICENSES directory.
  */
 
+#include <thrift/lib/cpp/util/EnumUtils.h>
+
 #include "executor/admin/ListUserRolesExecutor.h"
 #include "planner/Admin.h"
 #include "context/QueryContext.h"
@@ -20,7 +22,7 @@ folly::Future<Status> ListUserRolesExecutor::listUserRoles() {
     auto *lurNode = asNode<ListUserRoles>(node());
     return qctx()->getMetaClient()->getUserRoles(*lurNode->username())
         .via(runner())
-        .then([this](StatusOr<std::vector<meta::cpp2::RoleItem>> &&resp) {
+        .thenValue([this](StatusOr<std::vector<meta::cpp2::RoleItem>> &&resp) {
             SCOPED_TIMER(&execTime_);
             if (!resp.ok()) {
                 return std::move(resp).status();
@@ -31,7 +33,7 @@ folly::Future<Status> ListUserRolesExecutor::listUserRoles() {
                 v.emplace_back(nebula::Row(
                     {
                         item.get_user_id(),
-                        meta::cpp2::_RoleType_VALUES_TO_NAMES.at(item.get_role_type())
+                        apache::thrift::util::enumNameSafe(item.get_role_type())
                     }));
             }
             return finish(std::move(v));
diff --git a/src/executor/admin/ListUsersExecutor.cpp b/src/executor/admin/ListUsersExecutor.cpp
index d3b8d3b8aefe09e8a1c3dc26995aa7bf9b6f5b00..b7ff99819bf91c1a21c711012241d7bf3f146b9d 100644
--- a/src/executor/admin/ListUsersExecutor.cpp
+++ b/src/executor/admin/ListUsersExecutor.cpp
@@ -19,7 +19,7 @@ folly::Future<Status> ListUsersExecutor::execute() {
 folly::Future<Status> ListUsersExecutor::listUsers() {
     return qctx()->getMetaClient()->listUsers()
         .via(runner())
-        .then([this](StatusOr<std::unordered_map<std::string, std::string>> &&resp) {
+        .thenValue([this](StatusOr<std::unordered_map<std::string, std::string>> &&resp) {
             SCOPED_TIMER(&execTime_);
             if (!resp.ok()) {
                 return std::move(resp).status();
diff --git a/src/executor/admin/ListenerExecutor.cpp b/src/executor/admin/ListenerExecutor.cpp
index 67fc5afcd70c8babb695bed49a812f547f82c31e..b203ac29161d1a46f46c47b833585cb0f4dd565a 100644
--- a/src/executor/admin/ListenerExecutor.cpp
+++ b/src/executor/admin/ListenerExecutor.cpp
@@ -4,6 +4,8 @@
  * attached with Common Clause Condition 1.0, found in the LICENSES directory.
  */
 
+#include <thrift/lib/cpp/util/EnumUtils.h>
+
 #include "executor/admin/ListenerExecutor.h"
 #include "planner/Admin.h"
 
@@ -16,7 +18,7 @@ folly::Future<Status> AddListenerExecutor::execute() {
     auto spaceId = qctx()->rctx()->session()->space().id;
     return qctx()->getMetaClient()->addListener(spaceId, alNode->type(), alNode->hosts())
         .via(runner())
-        .then([this](StatusOr<bool> resp) {
+        .thenValue([this](StatusOr<bool> resp) {
             SCOPED_TIMER(&execTime_);
             if (!resp.ok()) {
                 LOG(ERROR) << resp.status();
@@ -32,7 +34,7 @@ folly::Future<Status> RemoveListenerExecutor::execute() {
     auto spaceId = qctx()->rctx()->session()->space().id;
     return qctx()->getMetaClient()->removeListener(spaceId, rlNode->type())
         .via(runner())
-        .then([this](StatusOr<bool> resp) {
+        .thenValue([this](StatusOr<bool> resp) {
             SCOPED_TIMER(&execTime_);
             if (!resp.ok()) {
                 LOG(ERROR) << resp.status();
@@ -47,7 +49,7 @@ folly::Future<Status> ShowListenerExecutor::execute() {
     auto spaceId = qctx()->rctx()->session()->space().id;
     return qctx()->getMetaClient()->listListener(spaceId)
         .via(runner())
-        .then([this](StatusOr<std::vector<meta::cpp2::ListenerInfo>> resp) {
+        .thenValue([this](StatusOr<std::vector<meta::cpp2::ListenerInfo>> resp) {
             SCOPED_TIMER(&execTime_);
             if (!resp.ok()) {
                 LOG(ERROR) << resp.status();
@@ -56,13 +58,13 @@ folly::Future<Status> ShowListenerExecutor::execute() {
 
             auto listenerInfos = std::move(resp).value();
             std::sort(listenerInfos.begin(), listenerInfos.end(), [](const auto& a, const auto& b) {
-                if (a.part_id != b.part_id) {
-                    return a.part_id < b.part_id;
+                if (a.part_id_ref() != b.part_id_ref()) {
+                    return a.part_id_ref() < b.part_id_ref();
                 }
-                if (a.type != b.type) {
-                    return a.type < b.type;
+                if (a.type_ref() != b.type_ref()) {
+                    return a.type_ref() < b.type_ref();
                 }
-                return a.host < b.host;
+                return a.host_ref() < b.host_ref();
             });
 
             DataSet result({"PartId", "Type", "Host", "Status"});
@@ -70,10 +72,10 @@ folly::Future<Status> ShowListenerExecutor::execute() {
                 Row row;
                 row.values.emplace_back(info.get_part_id());
                 row.values.emplace_back(
-                    meta::cpp2::_ListenerType_VALUES_TO_NAMES.at(info.get_type()));
-                row.values.emplace_back(info.host.toString());
+                    apache::thrift::util::enumNameSafe(info.get_type()));
+                row.values.emplace_back((*info.host_ref()).toString());
                 row.values.emplace_back(
-                    meta::cpp2::_HostStatus_VALUES_TO_NAMES.at(info.get_status()));
+                    apache::thrift::util::enumNameSafe(info.get_status()));
                 result.emplace_back(std::move(row));
             }
 
diff --git a/src/executor/admin/PartExecutor.cpp b/src/executor/admin/PartExecutor.cpp
index 537f8698bc7d1b23dc5386e0344fd57724a76438..d26afe204e4d1aa796a5721e121f17b064afe760 100644
--- a/src/executor/admin/PartExecutor.cpp
+++ b/src/executor/admin/PartExecutor.cpp
@@ -19,7 +19,7 @@ folly::Future<Status> ShowPartsExecutor::execute() {
     auto *spNode = asNode<ShowParts>(node());
     return qctx()->getMetaClient()->listParts(spNode->getSpaceId(), spNode->getPartIds())
             .via(runner())
-            .then([this](StatusOr<std::vector<meta::cpp2::PartItem>> resp) {
+            .thenValue([this](StatusOr<std::vector<meta::cpp2::PartItem>> resp) {
                 if (!resp.ok()) {
                     LOG(ERROR) << resp.status();
                     return resp.status();
@@ -37,8 +37,8 @@ folly::Future<Status> ShowPartsExecutor::execute() {
                     row.values.resize(4);
                     row.values[0].setInt(item.get_part_id());
 
-                    if (item.__isset.leader) {
-                        std::string leaderStr = NetworkUtils::toHostsStr({*item.get_leader()});
+                    if (item.leader_ref().has_value()) {
+                        std::string leaderStr = NetworkUtils::toHostsStr({*item.leader_ref()});
                         row.values[1].setStr(std::move(leaderStr));
                     } else {
                         row.values[1].setStr("");
diff --git a/src/executor/admin/ResetBalanceExecutor.cpp b/src/executor/admin/ResetBalanceExecutor.cpp
index a9551d7d4eb789e8d70b9e9f374f7717798204eb..e16b0b27f6b92e855ace63cfef230948f48f25a6 100644
--- a/src/executor/admin/ResetBalanceExecutor.cpp
+++ b/src/executor/admin/ResetBalanceExecutor.cpp
@@ -18,7 +18,7 @@ folly::Future<Status> ResetBalanceExecutor::execute() {
 folly::Future<Status> ResetBalanceExecutor::resetBalance() {
     return qctx()->getMetaClient()->balance({}, false, true)
         .via(runner())
-        .then([this](StatusOr<int64_t> resp) {
+        .thenValue([this](StatusOr<int64_t> resp) {
             SCOPED_TIMER(&execTime_);
             if (!resp.ok()) {
                 LOG(ERROR) << resp.status();
diff --git a/src/executor/admin/RevokeRoleExecutor.cpp b/src/executor/admin/RevokeRoleExecutor.cpp
index 3b9b0941afcbbcfb159b31a572ae1243c033edea..a593d287a448e9a9261208abe6fa9a7d57f1177b 100644
--- a/src/executor/admin/RevokeRoleExecutor.cpp
+++ b/src/executor/admin/RevokeRoleExecutor.cpp
@@ -41,7 +41,7 @@ folly::Future<Status> RevokeRoleExecutor::revokeRole() {
         ->getMetaClient()
         ->revokeFromUser(std::move(item))
         .via(runner())
-        .then([this](StatusOr<bool> resp) {
+        .thenValue([this](StatusOr<bool> resp) {
             SCOPED_TIMER(&execTime_);
             NG_RETURN_IF_ERROR(resp);
             if (!resp.value()) {
diff --git a/src/executor/admin/ShowBalanceExecutor.cpp b/src/executor/admin/ShowBalanceExecutor.cpp
index 8d53edfbbd484a17749706197ff61bfb8667868e..b20c7f058f8b6b65aa880dcf91e17352f5036715 100644
--- a/src/executor/admin/ShowBalanceExecutor.cpp
+++ b/src/executor/admin/ShowBalanceExecutor.cpp
@@ -4,6 +4,8 @@
  * attached with Common Clause Condition 1.0, found in the LICENSES directory.
  */
 
+#include <thrift/lib/cpp/util/EnumUtils.h>
+
 #include "executor/admin/ShowBalanceExecutor.h"
 #include "planner/Admin.h"
 
@@ -19,7 +21,7 @@ folly::Future<Status> ShowBalanceExecutor::showBalance() {
     auto *sbNode = asNode<ShowBalance>(node());
     return qctx()->getMetaClient()->showBalance(sbNode->jobId())
         .via(runner())
-        .then([this](StatusOr<std::vector<meta::cpp2::BalanceTask>> resp) {
+        .thenValue([this](StatusOr<std::vector<meta::cpp2::BalanceTask>> resp) {
             SCOPED_TIMER(&execTime_);
             if (!resp.ok()) {
                 LOG(ERROR) << resp.status();
@@ -47,7 +49,7 @@ folly::Future<Status> ShowBalanceExecutor::showBalance() {
                 }
                 v.emplace_back(Row({
                     std::move(task).get_id(),
-                    meta::cpp2::_TaskResult_VALUES_TO_NAMES.at(task.get_result())
+                    apache::thrift::util::enumNameSafe(task.get_result())
                 }));
             }
             double percentage = total == 0 ? 0 : static_cast<double>(succeeded) / total * 100;
diff --git a/src/executor/admin/ShowHostsExecutor.cpp b/src/executor/admin/ShowHostsExecutor.cpp
index 246653f14761f2b34f6d89a36bb82639676d9b0d..e9f0e85c3d0d1f3da74849be00921a306180c4f3 100644
--- a/src/executor/admin/ShowHostsExecutor.cpp
+++ b/src/executor/admin/ShowHostsExecutor.cpp
@@ -4,6 +4,8 @@
  * attached with Common Clause Condition 1.0, found in the LICENSES directory.
  */
 
+#include <thrift/lib/cpp/util/EnumUtils.h>
+
 #include "executor/admin/ShowHostsExecutor.h"
 #include "context/QueryContext.h"
 #include "planner/Admin.h"
@@ -37,7 +39,7 @@ folly::Future<Status> ShowHostsExecutor::showHosts() {
         for (const auto &host : hostVec) {
             nebula::Row r({host.get_hostAddr().host,
                            host.get_hostAddr().port,
-                           meta::cpp2::_HostStatus_VALUES_TO_NAMES.at(host.get_status())});
+                           apache::thrift::util::enumNameSafe(host.get_status())});
             int64_t leaderCount = 0;
             for (const auto &spaceEntry : host.get_leader_parts()) {
                 leaderCount += spaceEntry.second.size();
@@ -130,8 +132,8 @@ folly::Future<Status> ShowHostsExecutor::showHosts() {
         for (const auto &host : hostVec) {
             nebula::Row r({host.get_hostAddr().host,
                            host.get_hostAddr().port,
-                           meta::cpp2::_HostStatus_VALUES_TO_NAMES.at(host.get_status()),
-                           meta::cpp2::_HostRole_VALUES_TO_NAMES.at(host.get_role()),
+                           apache::thrift::util::enumNameSafe(host.get_status()),
+                           apache::thrift::util::enumNameSafe(host.get_role()),
                            host.get_git_info_sha()});
             v.emplace_back(std::move(r));
         }   // row loop
@@ -142,7 +144,7 @@ folly::Future<Status> ShowHostsExecutor::showHosts() {
         ->getMetaClient()
         ->listHosts(shNode->getType())
         .via(runner())
-        .then([=, type = shNode->getType()](auto &&resp) {
+        .thenValue([=, type = shNode->getType()](auto &&resp) {
             if (!resp.ok()) {
                 LOG(ERROR) << resp.status();
                 return resp.status();
diff --git a/src/executor/admin/ShowStatsExecutor.cpp b/src/executor/admin/ShowStatsExecutor.cpp
index 9e9638769dddbf998cb701aad9d00b0617f577fb..c9f8af2991ed2fbae1c54f09deeff9fad90b16d5 100644
--- a/src/executor/admin/ShowStatsExecutor.cpp
+++ b/src/executor/admin/ShowStatsExecutor.cpp
@@ -18,7 +18,7 @@ folly::Future<Status> ShowStatsExecutor::execute() {
     SCOPED_TIMER(&execTime_);
 
     auto spaceId = qctx()->rctx()->session()->space().id;
-    return qctx()->getMetaClient()->getStatis(spaceId).via(runner()).then(
+    return qctx()->getMetaClient()->getStatis(spaceId).via(runner()).thenValue(
         [this, spaceId](StatusOr<meta::cpp2::StatisItem> resp) {
             if (!resp.ok()) {
                 LOG(ERROR) << "SpaceId: " << spaceId
@@ -64,13 +64,13 @@ folly::Future<Status> ShowStatsExecutor::execute() {
             Row verticeRow;
             verticeRow.values.emplace_back("Space");
             verticeRow.values.emplace_back("vertices");
-            verticeRow.values.emplace_back(statisItem.space_vertices);
+            verticeRow.values.emplace_back(*statisItem.space_vertices_ref());
             dataSet.rows.emplace_back(std::move(verticeRow));
 
             Row edgeRow;
             edgeRow.values.emplace_back("Space");
             edgeRow.values.emplace_back("edges");
-            edgeRow.values.emplace_back(statisItem.space_edges);
+            edgeRow.values.emplace_back(*statisItem.space_edges_ref());
             dataSet.rows.emplace_back(std::move(edgeRow));
 
             return finish(ResultBuilder()
diff --git a/src/executor/admin/ShowTSClientsExecutor.cpp b/src/executor/admin/ShowTSClientsExecutor.cpp
index a0e273989d1f9becc151a39251034effafe8c531..ca5c0c0fa81e12368ff0c79c31e48bf1b2b8bcf4 100644
--- a/src/executor/admin/ShowTSClientsExecutor.cpp
+++ b/src/executor/admin/ShowTSClientsExecutor.cpp
@@ -24,7 +24,7 @@ return qctx()
         ->getMetaClient()
         ->listFTClients()
         .via(runner())
-        .then([this](auto &&resp) {
+        .thenValue([this](auto &&resp) {
             if (!resp.ok()) {
                 LOG(ERROR) << resp.status();
                 return resp.status();
diff --git a/src/executor/admin/SignInTSServiceExecutor.cpp b/src/executor/admin/SignInTSServiceExecutor.cpp
index 07ad13dbd70a190599f41fc5a1df76eb408c4d32..b681e3be3693b8ca205a74b3216be7d5f58774e8 100644
--- a/src/executor/admin/SignInTSServiceExecutor.cpp
+++ b/src/executor/admin/SignInTSServiceExecutor.cpp
@@ -19,7 +19,7 @@ folly::Future<Status> SignInTSServiceExecutor::signInTSService() {
     auto *siNode = asNode<SignInTSService>(node());
     return qctx()->getMetaClient()->signInFTService(siNode->type(), siNode->clients())
         .via(runner())
-        .then([this](StatusOr<bool> resp) {
+        .thenValue([this](StatusOr<bool> resp) {
             SCOPED_TIMER(&execTime_);
             NG_RETURN_IF_ERROR(resp);
             if (!resp.value()) {
diff --git a/src/executor/admin/SignOutTSServiceExecutor.cpp b/src/executor/admin/SignOutTSServiceExecutor.cpp
index 18cccaf2295f28f9f929dece0f5b5f594bac195c..281e83a64185b86696f43fdc5824defe0fe7ace8 100644
--- a/src/executor/admin/SignOutTSServiceExecutor.cpp
+++ b/src/executor/admin/SignOutTSServiceExecutor.cpp
@@ -18,7 +18,7 @@ folly::Future<Status> SignOutTSServiceExecutor::execute() {
 folly::Future<Status> SignOutTSServiceExecutor::signOutTSService() {
     return qctx()->getMetaClient()->signOutFTService()
         .via(runner())
-        .then([this](StatusOr<bool> resp) {
+        .thenValue([this](StatusOr<bool> resp) {
             SCOPED_TIMER(&execTime_);
             NG_RETURN_IF_ERROR(resp);
             if (!resp.value()) {
diff --git a/src/executor/admin/SnapshotExecutor.cpp b/src/executor/admin/SnapshotExecutor.cpp
index d13cc2536c2583b1a0dc51b6a0a27c1ce03b2f73..aa867f99d19804e5f0c45429e5d16a9e062b97dc 100644
--- a/src/executor/admin/SnapshotExecutor.cpp
+++ b/src/executor/admin/SnapshotExecutor.cpp
@@ -4,6 +4,8 @@
  * attached with Common Clause Condition 1.0, found in the LICENSES directory.
  */
 
+#include <thrift/lib/cpp/util/EnumUtils.h>
+
 #include "executor/admin/SnapshotExecutor.h"
 #include "planner/Admin.h"
 #include "context/QueryContext.h"
@@ -17,7 +19,7 @@ folly::Future<Status> CreateSnapshotExecutor::execute() {
 
     return qctx()->getMetaClient()->createSnapshot()
             .via(runner())
-            .then([](StatusOr<bool> resp) {
+            .thenValue([](StatusOr<bool> resp) {
                 if (!resp.ok()) {
                     LOG(ERROR) << resp.status();
                     return resp.status();
@@ -32,7 +34,7 @@ folly::Future<Status> DropSnapshotExecutor::execute() {
     auto *dsNode = asNode<DropSnapshot>(node());
     return qctx()->getMetaClient()->dropSnapshot(dsNode->getShapshotName())
             .via(runner())
-            .then([](StatusOr<bool> resp) {
+            .thenValue([](StatusOr<bool> resp) {
                 if (!resp.ok()) {
                     LOG(ERROR) << resp.status();
                     return resp.status();
@@ -46,7 +48,7 @@ folly::Future<Status> ShowSnapshotsExecutor::execute() {
 
     return qctx()->getMetaClient()->listSnapshots()
             .via(runner())
-            .then([this](StatusOr<std::vector<meta::cpp2::Snapshot>> resp) {
+            .thenValue([this](StatusOr<std::vector<meta::cpp2::Snapshot>> resp) {
                 if (!resp.ok()) {
                     LOG(ERROR) << resp.status();
                     return resp.status();
@@ -57,10 +59,10 @@ folly::Future<Status> ShowSnapshotsExecutor::execute() {
 
                 for (auto &snapshot : snapshots) {
                     Row row;
-                    row.values.emplace_back(snapshot.name);
+                    row.values.emplace_back(*snapshot.name_ref());
                     row.values.emplace_back(
-                            meta::cpp2::_SnapshotStatus_VALUES_TO_NAMES.at(snapshot.status));
-                    row.values.emplace_back(snapshot.hosts);
+                            apache::thrift::util::enumNameSafe(*snapshot.status_ref()));
+                    row.values.emplace_back(*snapshot.hosts_ref());
                     dataSet.rows.emplace_back(std::move(row));
                 }
                 return finish(ResultBuilder()
diff --git a/src/executor/admin/SpaceExecutor.cpp b/src/executor/admin/SpaceExecutor.cpp
index d1c0a5036f83d943cdcdbb621ebb85fda91cf525..816a6b266dff2e9b6ddb775d212554023429d2ed 100644
--- a/src/executor/admin/SpaceExecutor.cpp
+++ b/src/executor/admin/SpaceExecutor.cpp
@@ -19,7 +19,7 @@ folly::Future<Status> CreateSpaceExecutor::execute() {
     auto *csNode = asNode<CreateSpace>(node());
     return qctx()->getMetaClient()->createSpace(csNode->getSpaceDesc(), csNode->getIfNotExists())
             .via(runner())
-            .then([](StatusOr<bool> resp) {
+            .thenValue([](StatusOr<bool> resp) {
                 if (!resp.ok()) {
                     LOG(ERROR) << resp.status();
                     return resp.status();
@@ -35,7 +35,7 @@ folly::Future<Status> DescSpaceExecutor::execute() {
     auto *dsNode = asNode<DescSpace>(node());
     return qctx()->getMetaClient()->getSpace(dsNode->getSpaceName())
             .via(runner())
-            .then([this](StatusOr<meta::cpp2::SpaceItem> resp) {
+            .thenValue([this](StatusOr<meta::cpp2::SpaceItem> resp) {
                 if (!resp.ok()) {
                     LOG(ERROR) << resp.status();
                     return resp.status();
@@ -67,13 +67,13 @@ folly::Future<Status> DescSpaceExecutor::execute() {
                 row.values.emplace_back(properties.get_collate_name());
                 row.values.emplace_back(SchemaUtil::typeToString(properties.get_vid_type()));
                 std::string sAtomicEdge{"false"};
-                if (properties.__isset.isolation_level  &&
-                    (*properties.get_isolation_level() == meta::cpp2::IsolationLevel::TOSS)) {
+                if (properties.isolation_level_ref().has_value()  &&
+                    (*properties.isolation_level_ref() == meta::cpp2::IsolationLevel::TOSS)) {
                     sAtomicEdge = "true";
                 }
                 row.values.emplace_back(sAtomicEdge);
-                if (properties.__isset.group_name) {
-                    row.values.emplace_back(*properties.get_group_name());
+                if (properties.group_name_ref().has_value()) {
+                    row.values.emplace_back(*properties.group_name_ref());
                 } else {
                     row.values.emplace_back("default");
                 }
@@ -91,7 +91,7 @@ folly::Future<Status> DropSpaceExecutor::execute() {
     auto *dsNode = asNode<DropSpace>(node());
     return qctx()->getMetaClient()->dropSpace(dsNode->getSpaceName(), dsNode->getIfExists())
             .via(runner())
-            .then([this, dsNode](StatusOr<bool> resp) {
+            .thenValue([this, dsNode](StatusOr<bool> resp) {
                 if (!resp.ok()) {
                     LOG(ERROR) << "Drop space `" << dsNode->getSpaceName()
                                << "' failed: " << resp.status();
@@ -111,7 +111,7 @@ folly::Future<Status> DropSpaceExecutor::execute() {
 folly::Future<Status> ShowSpacesExecutor::execute() {
     SCOPED_TIMER(&execTime_);
 
-    return qctx()->getMetaClient()->listSpaces().via(runner()).then(
+    return qctx()->getMetaClient()->listSpaces().via(runner()).thenValue(
         [this](StatusOr<std::vector<meta::SpaceIdName>> resp) {
             if (!resp.ok()) {
                 LOG(ERROR) << "Show spaces failed: " << resp.status();
@@ -146,7 +146,7 @@ folly::Future<Status> ShowCreateSpaceExecutor::execute() {
     auto *scsNode = asNode<ShowCreateSpace>(node());
     return qctx()->getMetaClient()->getSpace(scsNode->getSpaceName())
             .via(runner())
-            .then([this, scsNode](StatusOr<meta::cpp2::SpaceItem> resp) {
+            .thenValue([this, scsNode](StatusOr<meta::cpp2::SpaceItem> resp) {
                 if (!resp.ok()) {
                     LOG(ERROR) << "Show create space `" << scsNode->getSpaceName()
                                << "' failed: " << resp.status();
@@ -157,8 +157,8 @@ folly::Future<Status> ShowCreateSpaceExecutor::execute() {
                 Row row;
                 row.values.emplace_back(properties.get_space_name());
                 std::string sAtomicEdge{"false"};
-                if (properties.__isset.isolation_level &&
-                    (*properties.get_isolation_level() == meta::cpp2::IsolationLevel::TOSS)) {
+                if (properties.isolation_level_ref().has_value() &&
+                    (*properties.isolation_level_ref() == meta::cpp2::IsolationLevel::TOSS)) {
                     sAtomicEdge = "true";
                 }
                 auto fmt = "CREATE SPACE `%s` (partition_num = %d, replica_factor = %d, "
@@ -172,8 +172,8 @@ folly::Future<Status> ShowCreateSpaceExecutor::execute() {
                     properties.get_collate_name().c_str(),
                     SchemaUtil::typeToString(properties.get_vid_type()).c_str(),
                     sAtomicEdge.c_str(),
-                    properties.__isset.group_name ? properties.get_group_name()->c_str()
-                                                  : "default"));
+                    properties.group_name_ref().has_value() ?
+                        (*properties.group_name_ref()).c_str() : "default"));
                 dataSet.rows.emplace_back(std::move(row));
                 return finish(ResultBuilder()
                                   .value(Value(std::move(dataSet)))
diff --git a/src/executor/admin/StopBalanceExecutor.cpp b/src/executor/admin/StopBalanceExecutor.cpp
index fdc58faae4c271a4cd56ffda7971341c5f40f9d6..dc6c4c6d6b096e4afc8cb0ce372ffc03679a5ac2 100644
--- a/src/executor/admin/StopBalanceExecutor.cpp
+++ b/src/executor/admin/StopBalanceExecutor.cpp
@@ -18,7 +18,7 @@ folly::Future<Status> StopBalanceExecutor::execute() {
 folly::Future<Status> StopBalanceExecutor::stopBalance() {
     return qctx()->getMetaClient()->balance({}, true, false)
         .via(runner())
-        .then([this](StatusOr<int64_t> resp) {
+        .thenValue([this](StatusOr<int64_t> resp) {
             SCOPED_TIMER(&execTime_);
             if (!resp.ok()) {
                 LOG(ERROR) << resp.status();
diff --git a/src/executor/admin/SubmitJobExecutor.cpp b/src/executor/admin/SubmitJobExecutor.cpp
index 81a53b3588174790a0af895d58b57bca462d4255..f5262ab638bb11d544ffc598442af9d6581d6b93 100644
--- a/src/executor/admin/SubmitJobExecutor.cpp
+++ b/src/executor/admin/SubmitJobExecutor.cpp
@@ -4,6 +4,8 @@
  * attached with Common Clause Condition 1.0, found in the LICENSES directory.
  */
 
+#include <thrift/lib/cpp/util/EnumUtils.h>
+
 #include "executor/admin/SubmitJobExecutor.h"
 
 #include "planner/Admin.h"
@@ -24,7 +26,7 @@ folly::Future<Status> SubmitJobExecutor::execute() {
 
     return qctx()->getMetaClient()->submitJob(jobOp, cmd, params)
         .via(runner())
-        .then([jobOp, this](StatusOr<meta::cpp2::AdminJobResult> &&resp) {
+        .thenValue([jobOp, this](StatusOr<meta::cpp2::AdminJobResult> &&resp) {
             SCOPED_TIMER(&execTime_);
 
             if (!resp.ok()) {
@@ -34,40 +36,40 @@ folly::Future<Status> SubmitJobExecutor::execute() {
             switch (jobOp) {
                 case meta::cpp2::AdminJobOp::ADD: {
                     nebula::DataSet v({"New Job Id"});
-                    DCHECK(resp.value().__isset.job_id);
-                    if (!resp.value().__isset.job_id) {
+                    DCHECK(resp.value().job_id_ref().has_value());
+                    if (!resp.value().job_id_ref().has_value()) {
                         return Status::Error("Response unexpected.");
                     }
-                    v.emplace_back(nebula::Row({*DCHECK_NOTNULL(resp.value().get_job_id())}));
+                    v.emplace_back(nebula::Row({*resp.value().job_id_ref()}));
                     return finish(std::move(v));
                 }
                 case meta::cpp2::AdminJobOp::RECOVER: {
                     nebula::DataSet v({"Recovered job num"});
-                    DCHECK(resp.value().__isset.recovered_job_num);
-                    if (!resp.value().__isset.recovered_job_num) {
+                    DCHECK(resp.value().recovered_job_num_ref().has_value());
+                    if (!resp.value().recovered_job_num_ref().has_value()) {
                         return Status::Error("Response unexpected.");
                     }
                     v.emplace_back(
-                        nebula::Row({*DCHECK_NOTNULL(resp.value().get_recovered_job_num())}));
+                        nebula::Row({*resp.value().recovered_job_num_ref()}));
                     return finish(std::move(v));
                 }
                 case meta::cpp2::AdminJobOp::SHOW: {
                     nebula::DataSet v(
                         {"Job Id(TaskId)", "Command(Dest)", "Status", "Start Time", "Stop Time"});
-                    DCHECK(resp.value().__isset.job_desc);
-                    if (!resp.value().__isset.job_desc) {
+                    DCHECK(resp.value().job_desc_ref().has_value());
+                    if (!resp.value().job_desc_ref().has_value()) {
                         return Status::Error("Response unexpected.");
                     }
-                    DCHECK(resp.value().__isset.task_desc);
-                    if (!resp.value().__isset.task_desc) {
+                    DCHECK(resp.value().task_desc_ref().has_value());
+                    if (!resp.value().task_desc_ref().has_value()) {
                         return Status::Error("Response unexpected");
                     }
-                    auto &jobDesc = *resp.value().get_job_desc();
+                    auto &jobDesc = *resp.value().job_desc_ref();
                     // job desc
                     v.emplace_back(nebula::Row({
                         jobDesc.front().get_id(),
-                        meta::cpp2::_AdminCmd_VALUES_TO_NAMES.at(jobDesc.front().get_cmd()),
-                        meta::cpp2::_JobStatus_VALUES_TO_NAMES.at(jobDesc.front().get_status()),
+                        apache::thrift::util::enumNameSafe(jobDesc.front().get_cmd()),
+                        apache::thrift::util::enumNameSafe(jobDesc.front().get_status()),
                         time::TimeUtils::unixSecondsToDateTime(jobDesc.front().get_start_time()),
                         time::TimeUtils::unixSecondsToDateTime(jobDesc.front().get_stop_time()),
                     }));
@@ -77,7 +79,7 @@ folly::Future<Status> SubmitJobExecutor::execute() {
                         v.emplace_back(nebula::Row({
                             taskDesc.get_task_id(),
                             taskDesc.get_host().host,
-                            meta::cpp2::_JobStatus_VALUES_TO_NAMES.at(taskDesc.get_status()),
+                            apache::thrift::util::enumNameSafe(taskDesc.get_status()),
                             time::TimeUtils::unixSecondsToDateTime(taskDesc.get_start_time()),
                             time::TimeUtils::unixSecondsToDateTime(taskDesc.get_stop_time()),
                         }));
@@ -86,16 +88,16 @@ folly::Future<Status> SubmitJobExecutor::execute() {
                 }
                 case meta::cpp2::AdminJobOp::SHOW_All: {
                     nebula::DataSet v({"Job Id", "Command", "Status", "Start Time", "Stop Time"});
-                    DCHECK(resp.value().__isset.job_desc);
-                    if (!resp.value().__isset.job_desc) {
+                    DCHECK(resp.value().job_desc_ref().has_value());
+                    if (!resp.value().job_desc_ref().has_value()) {
                         return Status::Error("Response unexpected");
                     }
-                    const auto &jobsDesc = *resp.value().get_job_desc();
+                    const auto &jobsDesc = *resp.value().job_desc_ref();
                     for (const auto &jobDesc : jobsDesc) {
                         v.emplace_back(nebula::Row({
                             jobDesc.get_id(),
-                            meta::cpp2::_AdminCmd_VALUES_TO_NAMES.at(jobDesc.get_cmd()),
-                            meta::cpp2::_JobStatus_VALUES_TO_NAMES.at(jobDesc.get_status()),
+                            apache::thrift::util::enumNameSafe(jobDesc.get_cmd()),
+                            apache::thrift::util::enumNameSafe(jobDesc.get_status()),
                             time::TimeUtils::unixSecondsToDateTime(jobDesc.get_start_time()),
                             time::TimeUtils::unixSecondsToDateTime(jobDesc.get_stop_time()),
                         }));
diff --git a/src/executor/admin/SwitchSpaceExecutor.cpp b/src/executor/admin/SwitchSpaceExecutor.cpp
index c597d2586dc85eb4f74a868f215be4f7b712beca..2d0569df7fb8cf76fb567d07df19e7d4634bcd85 100644
--- a/src/executor/admin/SwitchSpaceExecutor.cpp
+++ b/src/executor/admin/SwitchSpaceExecutor.cpp
@@ -24,7 +24,7 @@ folly::Future<Status> SwitchSpaceExecutor::execute() {
     auto spaceName = spaceToNode->getSpaceName();
     return qctx()->getMetaClient()->getSpace(spaceName)
             .via(runner())
-            .then([spaceName, this](StatusOr<meta::cpp2::SpaceItem> resp) {
+            .thenValue([spaceName, this](StatusOr<meta::cpp2::SpaceItem> resp) {
                 if (!resp.ok()) {
                     LOG(ERROR) << resp.status();
                     return resp.status();
diff --git a/src/executor/admin/UpdateUserExecutor.cpp b/src/executor/admin/UpdateUserExecutor.cpp
index 969d005729b6ca9816c535d20fc0ffb1941f4d90..97c8658e3038126dc71a70ffdd153b3dbde89b96 100644
--- a/src/executor/admin/UpdateUserExecutor.cpp
+++ b/src/executor/admin/UpdateUserExecutor.cpp
@@ -24,7 +24,7 @@ folly::Future<Status> UpdateUserExecutor::updateUser() {
         ->getMetaClient()
         ->alterUser(*uuNode->username(), encryption::MD5Utils::md5Encode(*uuNode->password()))
         .via(runner())
-        .then([this](StatusOr<bool> resp) {
+        .thenValue([this](StatusOr<bool> resp) {
             SCOPED_TIMER(&execTime_);
             NG_RETURN_IF_ERROR(resp);
             if (!resp.value()) {
diff --git a/src/executor/admin/ZoneExecutor.cpp b/src/executor/admin/ZoneExecutor.cpp
index 9ffdcb3ab963e61f8392eeacf057938879e80126..2e43cd000fd3eccce9daa820049cf1e188aac874 100644
--- a/src/executor/admin/ZoneExecutor.cpp
+++ b/src/executor/admin/ZoneExecutor.cpp
@@ -16,7 +16,7 @@ folly::Future<Status> AddZoneExecutor::execute() {
     auto *azNode = asNode<AddZone>(node());
     return qctx()->getMetaClient()->addZone(azNode->zoneName(), azNode->addresses())
             .via(runner())
-            .then([](StatusOr<bool> resp) {
+            .thenValue([](StatusOr<bool> resp) {
                 if (!resp.ok()) {
                     LOG(ERROR) << "Add Zone Failed :" << resp.status();
                     return resp.status();
@@ -30,7 +30,7 @@ folly::Future<Status> DropZoneExecutor::execute() {
     auto *dzNode = asNode<DropZone>(node());
     return qctx()->getMetaClient()->dropZone(dzNode->zoneName())
             .via(runner())
-            .then([](StatusOr<bool> resp) {
+            .thenValue([](StatusOr<bool> resp) {
                 if (!resp.ok()) {
                     LOG(ERROR) << "Drop Zone Failed :" << resp.status();
                     return resp.status();
@@ -44,7 +44,7 @@ folly::Future<Status> DescribeZoneExecutor::execute() {
     auto *dzNode = asNode<DescribeZone>(node());
     return qctx()->getMetaClient()->getZone(dzNode->zoneName())
             .via(runner())
-            .then([this](StatusOr<std::vector<HostAddr>> resp) {
+            .thenValue([this](StatusOr<std::vector<HostAddr>> resp) {
                 if (!resp.ok()) {
                     LOG(ERROR) << "Describe Zone Failed: " << resp.status();
                     return resp.status();
@@ -69,7 +69,7 @@ folly::Future<Status> AddHostIntoZoneExecutor::execute() {
     auto *ahNode = asNode<AddHostIntoZone>(node());
     return qctx()->getMetaClient()->addHostIntoZone(ahNode->address(), ahNode->zoneName())
             .via(runner())
-            .then([](StatusOr<bool> resp) {
+            .thenValue([](StatusOr<bool> resp) {
                 if (!resp.ok()) {
                     LOG(ERROR) << "Add Host Into Zone Failed: " << resp.status();
                     return resp.status();
@@ -83,7 +83,7 @@ folly::Future<Status> DropHostFromZoneExecutor::execute() {
     auto *dhNode = asNode<DropHostFromZone>(node());
     return qctx()->getMetaClient()->dropHostFromZone(dhNode->address(), dhNode->zoneName())
             .via(runner())
-            .then([](StatusOr<bool> resp) {
+            .thenValue([](StatusOr<bool> resp) {
                 if (!resp.ok()) {
                     LOG(ERROR) << "Drop Host From Zone Failed: " << resp.status();
                     return resp.status();
@@ -96,7 +96,7 @@ folly::Future<Status> ListZonesExecutor::execute() {
     SCOPED_TIMER(&execTime_);
     return qctx()->getMetaClient()->listZones()
             .via(runner())
-            .then([this](StatusOr<std::vector<meta::cpp2::Zone>> resp) {
+            .thenValue([this](StatusOr<std::vector<meta::cpp2::Zone>> resp) {
                 if (!resp.ok()) {
                     LOG(ERROR) << "List Zones Failed: " << resp.status();
                     return resp.status();
@@ -106,7 +106,7 @@ folly::Future<Status> ListZonesExecutor::execute() {
                 DataSet dataSet({"Name", "Host", "Port"});
                 for (auto &zone : zones) {
                     for (auto &host : zone.get_nodes()) {
-                        Row row({zone.zone_name, host.host, host.port});
+                        Row row({*zone.zone_name_ref(), host.host, host.port});
                         dataSet.rows.emplace_back(std::move(row));
                     }
                 }
diff --git a/src/executor/maintain/EdgeExecutor.cpp b/src/executor/maintain/EdgeExecutor.cpp
index b5d955e3dc226777f9cf4be42f88b8b14636e92c..fe722d13456a26cfe97f97773cd0af798a56664a 100644
--- a/src/executor/maintain/EdgeExecutor.cpp
+++ b/src/executor/maintain/EdgeExecutor.cpp
@@ -21,7 +21,7 @@ folly::Future<Status> CreateEdgeExecutor::execute() {
     return qctx()->getMetaClient()->createEdgeSchema(spaceId,
             ceNode->getName(), ceNode->getSchema(), ceNode->getIfNotExists())
             .via(runner())
-            .then([ceNode, spaceId](StatusOr<EdgeType> resp) {
+            .thenValue([ceNode, spaceId](StatusOr<EdgeType> resp) {
                 if (!resp.ok()) {
                     LOG(ERROR) << "SpaceId: " << spaceId
                                << ", Create edge `" << ceNode->getName()
@@ -40,7 +40,7 @@ folly::Future<Status> DescEdgeExecutor::execute() {
     auto spaceId = qctx()->rctx()->session()->space().id;
     return qctx()->getMetaClient()->getEdgeSchema(spaceId, deNode->getName())
             .via(runner())
-            .then([this, deNode, spaceId](StatusOr<meta::cpp2::Schema> resp) {
+            .thenValue([this, deNode, spaceId](StatusOr<meta::cpp2::Schema> resp) {
                 if (!resp.ok()) {
                     LOG(ERROR) << resp.status();
                     return resp.status();
@@ -69,7 +69,7 @@ folly::Future<Status> DropEdgeExecutor::execute() {
                                                    deNode->getName(),
                                                    deNode->getIfExists())
             .via(runner())
-            .then([deNode, spaceId](StatusOr<bool> resp) {
+            .thenValue([deNode, spaceId](StatusOr<bool> resp) {
                 if (!resp.ok()) {
                     LOG(ERROR) << "SpaceId: " << spaceId
                                << ", Drop edge `" << deNode->getName()
@@ -84,7 +84,7 @@ folly::Future<Status> ShowEdgesExecutor::execute() {
     SCOPED_TIMER(&execTime_);
 
     auto spaceId = qctx()->rctx()->session()->space().id;
-    return qctx()->getMetaClient()->listEdgeSchemas(spaceId).via(runner()).then(
+    return qctx()->getMetaClient()->listEdgeSchemas(spaceId).via(runner()).thenValue(
         [this, spaceId](StatusOr<std::vector<meta::cpp2::EdgeItem>> resp) {
             if (!resp.ok()) {
                 LOG(ERROR) << "SpaceId: " << spaceId
@@ -120,7 +120,7 @@ folly::Future<Status> ShowCreateEdgeExecutor::execute() {
         ->getMetaClient()
         ->getEdgeSchema(spaceId, sceNode->getName())
         .via(runner())
-        .then([this, sceNode, spaceId](StatusOr<meta::cpp2::Schema> resp) {
+        .thenValue([this, sceNode, spaceId](StatusOr<meta::cpp2::Schema> resp) {
             if (!resp.ok()) {
                 LOG(ERROR) << "SpaceId: " << spaceId
                            << ", ShowCreate edge `" << sceNode->getName()
@@ -148,7 +148,7 @@ folly::Future<Status> AlterEdgeExecutor::execute() {
                                                     aeNode->getSchemaItems(),
                                                     aeNode->getSchemaProp())
             .via(runner())
-            .then([this, aeNode](StatusOr<bool> resp) {
+            .thenValue([this, aeNode](StatusOr<bool> resp) {
                 if (!resp.ok()) {
                     LOG(ERROR) << "SpaceId: " << aeNode->space()
                                << ", Alter edge `" << aeNode->getName()
diff --git a/src/executor/maintain/EdgeIndexExecutor.cpp b/src/executor/maintain/EdgeIndexExecutor.cpp
index 7b003312026721fa38118ef93b533d1f1a18cc4f..e914be576be6bd4a7b1ed8d57c3c49512b8cc34f 100644
--- a/src/executor/maintain/EdgeIndexExecutor.cpp
+++ b/src/executor/maintain/EdgeIndexExecutor.cpp
@@ -24,7 +24,7 @@ folly::Future<Status> CreateEdgeIndexExecutor::execute() {
                           ceiNode->getFields(),
                           ceiNode->getIfNotExists())
         .via(runner())
-        .then([ceiNode, spaceId](StatusOr<IndexID> resp) {
+        .thenValue([ceiNode, spaceId](StatusOr<IndexID> resp) {
             if (!resp.ok()) {
                 LOG(ERROR) << "SpaceId: " << spaceId << ", Create index `"
                            << ceiNode->getIndexName() << "' at edge: `" << ceiNode->getSchemaName()
@@ -44,7 +44,7 @@ folly::Future<Status> DropEdgeIndexExecutor::execute() {
         ->getMetaClient()
         ->dropEdgeIndex(spaceId, deiNode->getIndexName(), deiNode->getIfExists())
         .via(runner())
-        .then([deiNode, spaceId](StatusOr<IndexID> resp) {
+        .thenValue([deiNode, spaceId](StatusOr<IndexID> resp) {
             if (!resp.ok()) {
                 LOG(ERROR) << "SpaceId: " << spaceId << ", Drop edge index`"
                            << deiNode->getIndexName() << "' failed: " << resp.status();
@@ -63,7 +63,7 @@ folly::Future<Status> DescEdgeIndexExecutor::execute() {
         ->getMetaClient()
         ->getEdgeIndex(spaceId, deiNode->getIndexName())
         .via(runner())
-        .then([this, deiNode, spaceId](StatusOr<meta::cpp2::IndexItem> resp) {
+        .thenValue([this, deiNode, spaceId](StatusOr<meta::cpp2::IndexItem> resp) {
             if (!resp.ok()) {
                 LOG(ERROR) << "SpaceId: " << spaceId << ", Desc edge index`"
                            << deiNode->getIndexName() << "' failed: " << resp.status();
@@ -91,7 +91,7 @@ folly::Future<Status> ShowCreateEdgeIndexExecutor::execute() {
         ->getMetaClient()
         ->getEdgeIndex(spaceId, sceiNode->getIndexName())
         .via(runner())
-        .then([this, sceiNode, spaceId](StatusOr<meta::cpp2::IndexItem> resp) {
+        .thenValue([this, sceiNode, spaceId](StatusOr<meta::cpp2::IndexItem> resp) {
             if (!resp.ok()) {
                 LOG(ERROR) << "SpaceId: " << spaceId << ", Show create edge index `"
                            << sceiNode->getIndexName() << "' failed: " << resp.status();
@@ -113,7 +113,7 @@ folly::Future<Status> ShowEdgeIndexesExecutor::execute() {
     SCOPED_TIMER(&execTime_);
 
     auto spaceId = qctx()->rctx()->session()->space().id;
-    return qctx()->getMetaClient()->listEdgeIndexes(spaceId).via(runner()).then(
+    return qctx()->getMetaClient()->listEdgeIndexes(spaceId).via(runner()).thenValue(
         [this, spaceId](StatusOr<std::vector<meta::cpp2::IndexItem>> resp) {
             if (!resp.ok()) {
                 LOG(ERROR) << "SpaceId: " << spaceId << ", Show edge indexes failed"
@@ -145,7 +145,7 @@ folly::Future<Status> ShowEdgeIndexStatusExecutor::execute() {
     SCOPED_TIMER(&execTime_);
 
     auto spaceId = qctx()->rctx()->session()->space().id;
-    return qctx()->getMetaClient()->listEdgeIndexStatus(spaceId).via(runner()).then(
+    return qctx()->getMetaClient()->listEdgeIndexStatus(spaceId).via(runner()).thenValue(
         [this, spaceId](StatusOr<std::vector<meta::cpp2::IndexStatus>> resp) {
             if (!resp.ok()) {
                 LOG(ERROR) << "SpaceId: " << spaceId << ", Show edge index status failed"
diff --git a/src/executor/maintain/TagExecutor.cpp b/src/executor/maintain/TagExecutor.cpp
index b043cf514326f3f3422ff8294ac5be8c3b9f0b5a..95ab26674bb11f4b099581bc5c9ecdb44abbb962 100644
--- a/src/executor/maintain/TagExecutor.cpp
+++ b/src/executor/maintain/TagExecutor.cpp
@@ -21,7 +21,7 @@ folly::Future<Status> CreateTagExecutor::execute() {
     return qctx()->getMetaClient()->createTagSchema(spaceId,
             ctNode->getName(), ctNode->getSchema(), ctNode->getIfNotExists())
             .via(runner())
-            .then([ctNode, spaceId](StatusOr<TagID> resp) {
+            .thenValue([ctNode, spaceId](StatusOr<TagID> resp) {
                 if (!resp.ok()) {
                     LOG(ERROR) << "SpaceId: " << spaceId
                                << ", Create tag `" << ctNode->getName()
@@ -41,7 +41,7 @@ folly::Future<Status> DescTagExecutor::execute() {
         ->getMetaClient()
         ->getTagSchema(spaceId, dtNode->getName())
         .via(runner())
-        .then([this, dtNode, spaceId](StatusOr<meta::cpp2::Schema> resp) {
+        .thenValue([this, dtNode, spaceId](StatusOr<meta::cpp2::Schema> resp) {
             if (!resp.ok()) {
                 LOG(ERROR) << "SpaceId: " << spaceId
                            << ", Desc tag `" << dtNode->getName()
@@ -69,7 +69,7 @@ folly::Future<Status> DropTagExecutor::execute() {
                                                   dtNode->getName(),
                                                   dtNode->getIfExists())
             .via(runner())
-            .then([dtNode, spaceId](StatusOr<bool> resp) {
+            .thenValue([dtNode, spaceId](StatusOr<bool> resp) {
                 if (!resp.ok()) {
                     LOG(ERROR) << "SpaceId: " << spaceId
                                << ", Drop tag `" << dtNode->getName()
@@ -84,7 +84,7 @@ folly::Future<Status> ShowTagsExecutor::execute() {
     SCOPED_TIMER(&execTime_);
 
     auto spaceId = qctx()->rctx()->session()->space().id;
-    return qctx()->getMetaClient()->listTagSchemas(spaceId).via(runner()).then(
+    return qctx()->getMetaClient()->listTagSchemas(spaceId).via(runner()).thenValue(
         [this, spaceId](StatusOr<std::vector<meta::cpp2::TagItem>> resp) {
             if (!resp.ok()) {
                 LOG(ERROR) << "SpaceId: " << spaceId
@@ -118,7 +118,7 @@ folly::Future<Status> ShowCreateTagExecutor::execute() {
     auto spaceId = qctx()->rctx()->session()->space().id;
     return qctx()->getMetaClient()->getTagSchema(spaceId, sctNode->getName())
             .via(runner())
-            .then([this, sctNode, spaceId](StatusOr<meta::cpp2::Schema> resp) {
+            .thenValue([this, sctNode, spaceId](StatusOr<meta::cpp2::Schema> resp) {
                 if (!resp.ok()) {
                     LOG(ERROR) << "SpaceId: " << spaceId
                                << ", Show create tag `" << sctNode->getName()
@@ -146,7 +146,7 @@ folly::Future<Status> AlterTagExecutor::execute() {
                                                    aeNode->getSchemaItems(),
                                                    aeNode->getSchemaProp())
             .via(runner())
-            .then([aeNode](StatusOr<bool> resp) {
+            .thenValue([aeNode](StatusOr<bool> resp) {
                 if (!resp.ok()) {
                     LOG(ERROR) << "SpaceId: " << aeNode->space()
                                << ", Alter tag `" << aeNode->getName()
diff --git a/src/executor/maintain/TagIndexExecutor.cpp b/src/executor/maintain/TagIndexExecutor.cpp
index d617f72edfaf85ad217d79d120a60c713b529822..5991b9477d8daf711027be416ead7cbd7d910f31 100644
--- a/src/executor/maintain/TagIndexExecutor.cpp
+++ b/src/executor/maintain/TagIndexExecutor.cpp
@@ -24,7 +24,7 @@ folly::Future<Status> CreateTagIndexExecutor::execute() {
                          ctiNode->getFields(),
                          ctiNode->getIfNotExists())
         .via(runner())
-        .then([ctiNode, spaceId](StatusOr<IndexID> resp) {
+        .thenValue([ctiNode, spaceId](StatusOr<IndexID> resp) {
             if (!resp.ok()) {
                 LOG(ERROR) << "SpaceId: " << spaceId << ", Create index `"
                            << ctiNode->getIndexName() << "' at tag: `" << ctiNode->getSchemaName()
@@ -44,7 +44,7 @@ folly::Future<Status> DropTagIndexExecutor::execute() {
         ->getMetaClient()
         ->dropTagIndex(spaceId, dtiNode->getIndexName(), dtiNode->getIfExists())
         .via(runner())
-        .then([dtiNode, spaceId](StatusOr<bool> resp) {
+        .thenValue([dtiNode, spaceId](StatusOr<bool> resp) {
             if (!resp.ok()) {
                 LOG(ERROR) << "SpaceId: " << spaceId << ", Drop tag index `"
                            << dtiNode->getIndexName() << "' failed: " << resp.status();
@@ -63,7 +63,7 @@ folly::Future<Status> DescTagIndexExecutor::execute() {
         ->getMetaClient()
         ->getTagIndex(spaceId, dtiNode->getIndexName())
         .via(runner())
-        .then([this, dtiNode, spaceId](StatusOr<meta::cpp2::IndexItem> resp) {
+        .thenValue([this, dtiNode, spaceId](StatusOr<meta::cpp2::IndexItem> resp) {
             if (!resp.ok()) {
                 LOG(ERROR) << "SpaceId: " << spaceId << ", Desc tag index `"
                            << dtiNode->getIndexName() << "' failed: " << resp.status();
@@ -91,7 +91,7 @@ folly::Future<Status> ShowCreateTagIndexExecutor::execute() {
         ->getMetaClient()
         ->getTagIndex(spaceId, sctiNode->getIndexName())
         .via(runner())
-        .then([this, sctiNode, spaceId](StatusOr<meta::cpp2::IndexItem> resp) {
+        .thenValue([this, sctiNode, spaceId](StatusOr<meta::cpp2::IndexItem> resp) {
             if (!resp.ok()) {
                 LOG(ERROR) << "SpaceId: " << spaceId << ", Show create tag index `"
                            << sctiNode->getIndexName() << "' failed: " << resp.status();
@@ -113,7 +113,7 @@ folly::Future<Status> ShowTagIndexesExecutor::execute() {
     SCOPED_TIMER(&execTime_);
 
     auto spaceId = qctx()->rctx()->session()->space().id;
-    return qctx()->getMetaClient()->listTagIndexes(spaceId).via(runner()).then(
+    return qctx()->getMetaClient()->listTagIndexes(spaceId).via(runner()).thenValue(
         [this, spaceId](StatusOr<std::vector<meta::cpp2::IndexItem>> resp) {
             if (!resp.ok()) {
                 LOG(ERROR) << "SpaceId: " << spaceId << ", Show tag indexes failed"
@@ -145,7 +145,7 @@ folly::Future<Status> ShowTagIndexStatusExecutor::execute() {
     SCOPED_TIMER(&execTime_);
 
     auto spaceId = qctx()->rctx()->session()->space().id;
-    return qctx()->getMetaClient()->listTagIndexStatus(spaceId).via(runner()).then(
+    return qctx()->getMetaClient()->listTagIndexStatus(spaceId).via(runner()).thenValue(
         [this, spaceId](StatusOr<std::vector<meta::cpp2::IndexStatus>> resp) {
             if (!resp.ok()) {
                 LOG(ERROR) << "SpaceId: " << spaceId << ", Show tag index status failed"
diff --git a/src/executor/mutate/DeleteExecutor.cpp b/src/executor/mutate/DeleteExecutor.cpp
index 5f22a89a00e6791fdf78ef5b11072f6ac119a8f6..547958fa9339daba2ccff95c294dc05e01419bdf 100644
--- a/src/executor/mutate/DeleteExecutor.cpp
+++ b/src/executor/mutate/DeleteExecutor.cpp
@@ -46,7 +46,7 @@ folly::Future<Status> DeleteVerticesExecutor::deleteVertices() {
                 VLOG(3) << "NULL or EMPTY vid";
                 continue;
             }
-            if (!SchemaUtil::isValidVid(val, spaceInfo.spaceDesc.vid_type)) {
+            if (!SchemaUtil::isValidVid(val, *spaceInfo.spaceDesc.vid_type_ref())) {
                 std::stringstream ss;
                 ss << "Wrong vid type `" << val.type() << "', value `" << val.toString() << "'";
                 return Status::Error(ss.str());
@@ -65,7 +65,7 @@ folly::Future<Status> DeleteVerticesExecutor::deleteVertices() {
         .ensure([deleteVertTime]() {
             VLOG(1) << "Delete vertices time: " << deleteVertTime.elapsedInUSec() << "us";
         })
-        .then([this](storage::StorageRpcResponse<storage::cpp2::ExecResponse> resp) {
+        .thenValue([this](storage::StorageRpcResponse<storage::cpp2::ExecResponse> resp) {
             SCOPED_TIMER(&execTime_);
             NG_RETURN_IF_ERROR(handleCompleteness(resp, false));
             return Status::OK();
@@ -98,14 +98,14 @@ folly::Future<Status> DeleteEdgesExecutor::deleteEdges() {
                     VLOG(3) << "NULL or EMPTY vid";
                     continue;
                 }
-                if (!SchemaUtil::isValidVid(srcId, spaceInfo.spaceDesc.vid_type)) {
+                if (!SchemaUtil::isValidVid(srcId, *spaceInfo.spaceDesc.vid_type_ref())) {
                     std::stringstream ss;
                     ss << "Wrong srcId type `" << srcId.type()
                        << "`, value `" << srcId.toString() << "'";
                     return Status::Error(ss.str());
                 }
                 auto dstId = Expression::eval(edgeKeyRef->dstid(), ctx(iter.get()));
-                if (!SchemaUtil::isValidVid(dstId, spaceInfo.spaceDesc.vid_type)) {
+                if (!SchemaUtil::isValidVid(dstId, *spaceInfo.spaceDesc.vid_type_ref())) {
                     std::stringstream ss;
                     ss << "Wrong dstId type `" << dstId.type()
                        << "', value `" << dstId.toString() << "'";
@@ -155,7 +155,7 @@ folly::Future<Status> DeleteEdgesExecutor::deleteEdges() {
             .ensure([deleteEdgeTime]() {
                 VLOG(1) << "Delete edge time: " << deleteEdgeTime.elapsedInUSec() << "us";
             })
-            .then([this](storage::StorageRpcResponse<storage::cpp2::ExecResponse> resp) {
+            .thenValue([this](storage::StorageRpcResponse<storage::cpp2::ExecResponse> resp) {
                 SCOPED_TIMER(&execTime_);
                 NG_RETURN_IF_ERROR(handleCompleteness(resp, false));
                 return Status::OK();
diff --git a/src/executor/mutate/InsertExecutor.cpp b/src/executor/mutate/InsertExecutor.cpp
index bad2ae4ba97a660537b2b0c7a17d1c9133a85bdd..ef625553f057df48d5cd0e5cc011cf60122c1427 100644
--- a/src/executor/mutate/InsertExecutor.cpp
+++ b/src/executor/mutate/InsertExecutor.cpp
@@ -30,7 +30,7 @@ folly::Future<Status> InsertVerticesExecutor::insertVertices() {
         .ensure([addVertTime]() {
             VLOG(1) << "Add vertices time: " << addVertTime.elapsedInUSec() << "us";
         })
-        .then([this](storage::StorageRpcResponse<storage::cpp2::ExecResponse> resp) {
+        .thenValue([this](storage::StorageRpcResponse<storage::cpp2::ExecResponse> resp) {
             SCOPED_TIMER(&execTime_);
             NG_RETURN_IF_ERROR(handleCompleteness(resp, false));
             return Status::OK();
@@ -56,7 +56,7 @@ folly::Future<Status> InsertEdgesExecutor::insertEdges() {
             .ensure([addEdgeTime]() {
                 VLOG(1) << "Add edge time: " << addEdgeTime.elapsedInUSec() << "us";
             })
-            .then([this](storage::StorageRpcResponse<storage::cpp2::ExecResponse> resp) {
+            .thenValue([this](storage::StorageRpcResponse<storage::cpp2::ExecResponse> resp) {
                 SCOPED_TIMER(&execTime_);
                 NG_RETURN_IF_ERROR(handleCompleteness(resp, false));
                 return Status::OK();
diff --git a/src/executor/mutate/UpdateExecutor.cpp b/src/executor/mutate/UpdateExecutor.cpp
index 8dde755062b97f3ad319327553b438dd5a97b080..a16813d4748cd80c9f21ec722d2b345b7336ef07 100644
--- a/src/executor/mutate/UpdateExecutor.cpp
+++ b/src/executor/mutate/UpdateExecutor.cpp
@@ -56,7 +56,7 @@ folly::Future<Status> UpdateVertexExecutor::execute() {
         .ensure([updateVertTime]() {
             VLOG(1) << "Update vertice time: " << updateVertTime.elapsedInUSec() << "us";
         })
-        .then([this](StatusOr<storage::cpp2::UpdateResponse> resp) {
+        .thenValue([this](StatusOr<storage::cpp2::UpdateResponse> resp) {
             SCOPED_TIMER(&execTime_);
             if (!resp.ok()) {
                 LOG(ERROR) << resp.status();
@@ -66,8 +66,8 @@ folly::Future<Status> UpdateVertexExecutor::execute() {
             for (auto& code : value.get_result().get_failed_parts()) {
                 NG_RETURN_IF_ERROR(handleErrorCode(code.get_code(), code.get_part_id()));
             }
-            if (value.__isset.props) {
-                auto status = handleResult(std::move(*value.get_props()));
+            if (value.props_ref().has_value()) {
+                auto status = handleResult(std::move(*value.props_ref()));
                 if (!status.ok()) {
                     return status.status();
                 }
@@ -101,7 +101,7 @@ folly::Future<Status> UpdateEdgeExecutor::execute() {
             .ensure([updateEdgeTime]() {
                 VLOG(1) << "Update edge time: " << updateEdgeTime.elapsedInUSec() << "us";
             })
-            .then([this](StatusOr<storage::cpp2::UpdateResponse> resp) {
+            .thenValue([this](StatusOr<storage::cpp2::UpdateResponse> resp) {
                 SCOPED_TIMER(&execTime_);
                 if (!resp.ok()) {
                     LOG(ERROR) << "Update edge failed: " << resp.status();
@@ -111,8 +111,8 @@ folly::Future<Status> UpdateEdgeExecutor::execute() {
                 for (auto& code : value.get_result().get_failed_parts()) {
                     NG_RETURN_IF_ERROR(handleErrorCode(code.get_code(), code.get_part_id()));
                 }
-                if (value.__isset.props) {
-                    auto status = handleResult(std::move(*value.get_props()));
+                if (value.props_ref().has_value()) {
+                    auto status = handleResult(std::move(*value.props_ref()));
                     if (!status.ok()) {
                         return status.status();
                     }
diff --git a/src/executor/query/GetEdgesExecutor.cpp b/src/executor/query/GetEdgesExecutor.cpp
index d9ea578567ecb26805dfbd4967b422779f1c2893..f119f417d57ee46c784d750f58aca485868d34c4 100644
--- a/src/executor/query/GetEdgesExecutor.cpp
+++ b/src/executor/query/GetEdgesExecutor.cpp
@@ -41,8 +41,8 @@ folly::Future<Status> GetEdgesExecutor::getEdges() {
             auto type = ge->type()->eval(expCtx(valueIter.get()));
             auto ranking = ge->ranking()->eval(expCtx(valueIter.get()));
             auto dst = ge->dst()->eval(expCtx(valueIter.get()));
-            if (!SchemaUtil::isValidVid(src, spaceInfo.spaceDesc.vid_type)
-                    || !SchemaUtil::isValidVid(dst, spaceInfo.spaceDesc.vid_type)
+            if (!SchemaUtil::isValidVid(src, *spaceInfo.spaceDesc.vid_type_ref())
+                    || !SchemaUtil::isValidVid(dst, *spaceInfo.spaceDesc.vid_type_ref())
                     || !type.isInt() || !ranking.isInt()) {
                 LOG(WARNING) << "Mismatched edge key type";
                 continue;
@@ -78,7 +78,7 @@ folly::Future<Status> GetEdgesExecutor::getEdges() {
             otherStats_.emplace("total_rpc",
                                 folly::stringPrintf("%lu(us)", getPropsTime.elapsedInUSec()));
         })
-        .then([this, ge](StorageRpcResponse<GetPropResponse> &&rpcResp) {
+        .thenValue([this, ge](StorageRpcResponse<GetPropResponse> &&rpcResp) {
             SCOPED_TIMER(&execTime_);
             addStats(rpcResp, otherStats_);
             return handleResp(std::move(rpcResp), ge->colNamesRef());
diff --git a/src/executor/query/GetNeighborsExecutor.cpp b/src/executor/query/GetNeighborsExecutor.cpp
index 750a9d4bce5c9d95244371c61f6bee2fcff89c01..aad5cda2ae8c4d9075899c418ce852c34740d538 100644
--- a/src/executor/query/GetNeighborsExecutor.cpp
+++ b/src/executor/query/GetNeighborsExecutor.cpp
@@ -63,17 +63,18 @@ folly::Future<Status> GetNeighborsExecutor::execute() {
             otherStats_.emplace("total_rpc_time",
                                 folly::stringPrintf("%lu(us)", getNbrTime.elapsedInUSec()));
         })
-        .then([this](StorageRpcResponse<GetNeighborsResponse>&& resp) {
+        .thenValue([this](StorageRpcResponse<GetNeighborsResponse>&& resp) {
             SCOPED_TIMER(&execTime_);
             auto& hostLatency = resp.hostLatency();
             for (size_t i = 0; i < hostLatency.size(); ++i) {
                 auto& info = hostLatency[i];
-                otherStats_.emplace(folly::stringPrintf("%s exec/total/vertices",
-                                                        std::get<0>(info).toString().c_str()),
-                                    folly::stringPrintf("%d(us)/%d(us)/%lu,",
-                                                        std::get<1>(info),
-                                                        std::get<2>(info),
-                                                        resp.responses()[i].vertices.size()));
+                otherStats_.emplace(
+                        folly::stringPrintf("%s exec/total/vertices",
+                                            std::get<0>(info).toString().c_str()),
+                        folly::stringPrintf("%d(us)/%d(us)/%lu,",
+                                            std::get<1>(info),
+                                            std::get<2>(info),
+                                            (*resp.responses()[i].vertices_ref()).size()));
             }
             return handleResponse(resp);
         });
diff --git a/src/executor/query/GetPropExecutor.h b/src/executor/query/GetPropExecutor.h
index ad97563914cc4cc7616dd47f26e032d8ee46c515..fb3650f4fa33ff35c7d7c7708ef5543900e0a4b7 100644
--- a/src/executor/query/GetPropExecutor.h
+++ b/src/executor/query/GetPropExecutor.h
@@ -27,8 +27,8 @@ protected:
         // Ok, merge DataSets to one
         nebula::DataSet v;
         for (auto &resp : rpcResp.responses()) {
-            if (resp.__isset.props) {
-                if (UNLIKELY(!v.append(std::move(*resp.get_props())))) {
+            if (resp.props_ref().has_value()) {
+                if (UNLIKELY(!v.append(std::move(*resp.props_ref())))) {
                     // it's impossible according to the interface
                     LOG(WARNING) << "Heterogeneous props dataset";
                     state = Result::State::kPartialSuccess;
diff --git a/src/executor/query/GetVerticesExecutor.cpp b/src/executor/query/GetVerticesExecutor.cpp
index e78c3f168d6b6833eb74f0aeb06fb47edc1f066e..72b1916df5d69bcf05d6b5ce6ebc93281c4e6cab 100644
--- a/src/executor/query/GetVerticesExecutor.cpp
+++ b/src/executor/query/GetVerticesExecutor.cpp
@@ -25,8 +25,8 @@ folly::Future<Status> GetVerticesExecutor::getVertices() {
 
     auto *gv = asNode<GetVertices>(node());
     GraphStorageClient *storageClient = qctx()->getStorageClient();
-    DataSet vertices = buildRequestDataSet(gv);
 
+    DataSet vertices = buildRequestDataSet(gv);
     VLOG(1) << "vertices: " << vertices;
     if (vertices.rows.empty()) {
         // TODO: add test for empty input.
@@ -53,7 +53,7 @@ folly::Future<Status> GetVerticesExecutor::getVertices() {
             otherStats_.emplace("total_rpc",
                                  folly::stringPrintf("%lu(us)", getPropsTime.elapsedInUSec()));
         })
-        .then([this, gv](StorageRpcResponse<GetPropResponse> &&rpcResp) {
+        .thenValue([this, gv](StorageRpcResponse<GetPropResponse> &&rpcResp) {
             SCOPED_TIMER(&execTime_);
             addStats(rpcResp, otherStats_);
             return handleResp(std::move(rpcResp), gv->colNamesRef());
diff --git a/src/executor/query/IndexScanExecutor.cpp b/src/executor/query/IndexScanExecutor.cpp
index 63f4398cfa28b2d4efd1767bd6c6c65e6d41f6c4..f0027814c7a2b521d08cf6ae188c863fcb18ef2d 100644
--- a/src/executor/query/IndexScanExecutor.cpp
+++ b/src/executor/query/IndexScanExecutor.cpp
@@ -34,7 +34,7 @@ folly::Future<Status> IndexScanExecutor::indexScan() {
                                       lookup->schemaId(),
                                      *lookup->returnColumns())
         .via(runner())
-        .then([this](StorageRpcResponse<LookupIndexResp> &&rpcResp) {
+        .thenValue([this](StorageRpcResponse<LookupIndexResp> &&rpcResp) {
             return handleResp(std::move(rpcResp));
         });
 }
@@ -49,13 +49,13 @@ Status IndexScanExecutor::handleResp(storage::StorageRpcResponse<Resp> &&rpcResp
     auto state = std::move(completeness).value();
     nebula::DataSet v;
     for (auto &resp : rpcResp.responses()) {
-        if (resp.__isset.data) {
-            nebula::DataSet* data = resp.get_data();
+        if (resp.data_ref().has_value()) {
+            nebula::DataSet& data = *resp.data_ref();
             // TODO : convert the column name to alias.
             if (v.colNames.empty()) {
-                v.colNames = data->colNames;
+                v.colNames = data.colNames;
             }
-            v.rows.insert(v.rows.end(), data->rows.begin(), data->rows.end());
+            v.rows.insert(v.rows.end(), data.rows.begin(), data.rows.end());
         } else {
             state = Result::State::kPartialSuccess;
         }
diff --git a/src/executor/test/CMakeLists.txt b/src/executor/test/CMakeLists.txt
index 6c9ff1010397d9d0c21c3af9af4a219553ab5bcf..d70fab62bf3892f93ba343aac0c60850a2e54eda 100644
--- a/src/executor/test/CMakeLists.txt
+++ b/src/executor/test/CMakeLists.txt
@@ -52,8 +52,7 @@ SET(EXEC_QUERY_TEST_LIBS
     ${THRIFT_LIBRARIES}
     gtest
     wangle
-    proxygenhttpserver
-    proxygenlib
+    ${PROXYGEN_LIBRARIES}
 )
 
 nebula_add_test(
diff --git a/src/executor/test/GetNeighborsTest.cpp b/src/executor/test/GetNeighborsTest.cpp
index 5cac1b96fd1ae6e6de47319bd363bdfd28c5f248..8042b456cc1f60ff5ad889040c1577cab452cd0c 100644
--- a/src/executor/test/GetNeighborsTest.cpp
+++ b/src/executor/test/GetNeighborsTest.cpp
@@ -35,7 +35,7 @@ protected:
         SpaceInfo spaceInfo;
         spaceInfo.name = "test_space";
         spaceInfo.id = 1;
-        spaceInfo.spaceDesc.space_name = "test_space";
+        spaceInfo.spaceDesc.set_space_name("test_space");
         session->setSpace(std::move(spaceInfo));
         auto rctx = std::make_unique<RequestContext<ExecutionResponse>>();
         rctx->setSession(std::move(session));
diff --git a/src/optimizer/OptimizerUtils.cpp b/src/optimizer/OptimizerUtils.cpp
index 42c6305d98983ecaadd0e23580ead60c06b075f2..2865d55f272acefbc565cb1f628bdc8128a73609 100644
--- a/src/optimizer/OptimizerUtils.cpp
+++ b/src/optimizer/OptimizerUtils.cpp
@@ -54,17 +54,16 @@ Value OptimizerUtils::boundValueWithGT(const meta::cpp2::ColumnDef& col, const V
             return v.getFloat() + kEpsilon;
         }
         case Value::Type::STRING : {
-            if (!col.type.__isset.type_length ||
-                col.get_type().get_type_length() == nullptr) {
+            if (!col.type.type_length_ref().has_value()) {
                 return Value::kNullBadType;
             }
             std::vector<unsigned char> bytes(v.getStr().begin(), v.getStr().end());
-            bytes.resize(*col.get_type().get_type_length());
+            bytes.resize(*col.get_type().type_length_ref());
             for (size_t i = bytes.size();; i--) {
                 if (i > 0) {
                     if (bytes[i-1]++ != 255) break;
                 } else {
-                    return Value(std::string(*col.get_type().get_type_length(), '\377'));
+                    return Value(std::string(*col.get_type().type_length_ref(), '\377'));
                 }
             }
             return Value(std::string(bytes.begin(), bytes.end()));
@@ -200,16 +199,16 @@ Value OptimizerUtils::boundValueWithLT(const meta::cpp2::ColumnDef& col, const V
             return v.getFloat() - kEpsilon;
         }
         case Value::Type::STRING : {
-            if (!col.type.__isset.type_length || col.get_type().get_type_length() == nullptr) {
+            if (!col.type.type_length_ref().has_value()) {
                 return Value::kNullBadType;
             }
             std::vector<unsigned char> bytes(v.getStr().begin(), v.getStr().end());
-            bytes.resize(*col.get_type().get_type_length());
+            bytes.resize(*col.get_type().type_length_ref());
             for (size_t i = bytes.size();; i--) {
                 if (i > 0) {
                     if (bytes[i-1]-- != 0) break;
                 } else {
-                    return Value(std::string(*col.get_type().get_type_length(), '\0'));
+                    return Value(std::string(*col.get_type().type_length_ref(), '\0'));
                 }
             }
             return Value(std::string(bytes.begin(), bytes.end()));
@@ -334,11 +333,10 @@ Value OptimizerUtils::boundValueWithMax(const meta::cpp2::ColumnDef& col) {
             return Value(std::numeric_limits<double>::max());
         }
         case Value::Type::STRING : {
-            if (!col.type.__isset.type_length ||
-                col.get_type().get_type_length() == nullptr) {
+            if (!col.type.type_length_ref().has_value()) {
                 return Value::kNullBadType;
             }
-            return Value(std::string(*col.get_type().get_type_length(), '\377'));
+            return Value(std::string(*col.get_type().type_length_ref(), '\377'));
         }
         case Value::Type::DATE : {
             Date d;
@@ -395,11 +393,10 @@ Value OptimizerUtils::boundValueWithMin(const meta::cpp2::ColumnDef& col) {
             return Value(-std::numeric_limits<double>::max());
         }
         case Value::Type::STRING : {
-            if (!col.type.__isset.type_length ||
-                col.get_type().get_type_length() == nullptr) {
+            if (!col.type.type_length_ref().has_value()) {
                 return Value::kNullBadType;
             }
-            return Value(std::string(*col.get_type().get_type_length(), '\0'));
+            return Value(std::string(*col.get_type().type_length_ref(), '\0'));
         }
         case Value::Type::DATE : {
             return Value(Date());
@@ -441,11 +438,10 @@ Value OptimizerUtils::normalizeValue(const meta::cpp2::ColumnDef& col, const Val
             return v;
         }
         case Value::Type::STRING : {
-            if (!col.type.__isset.type_length ||
-                col.get_type().get_type_length() == nullptr) {
+            if (!col.type.type_length_ref().has_value()) {
                 return Value::kNullBadType;
             }
-            auto len = static_cast<size_t>(*col.get_type().get_type_length());
+            auto len = static_cast<size_t>(*col.get_type().type_length_ref());
             if (v.getStr().size() > len) {
                 return Value(v.getStr().substr(0, len));
             } else {
diff --git a/src/optimizer/rule/IndexScanRule.cpp b/src/optimizer/rule/IndexScanRule.cpp
index a776c9c66638189d963a1f77c4aea68e6606f857..b5d074a3f048fe455ec2cf6c6e667454d2d820b7 100644
--- a/src/optimizer/rule/IndexScanRule.cpp
+++ b/src/optimizer/rule/IndexScanRule.cpp
@@ -129,7 +129,7 @@ Status IndexScanRule::appendIQCtx(const IndexItem& index,
     auto hc = hintCount(items);
     auto fields = index->get_fields();
     IndexQueryContext ctx;
-    decltype(ctx.column_hints) hints;
+    std::vector<nebula::storage::cpp2::IndexColumnHint> hints;
     for (const auto& field : fields) {
         bool found = false;
         FilterItems filterItems;
diff --git a/src/optimizer/test/CMakeLists.txt b/src/optimizer/test/CMakeLists.txt
index 9dbd228d5fde414b9fe96faf0b8f0999a9971b3b..aa635618bd631b685127ea892cb26a7e109002c9 100644
--- a/src/optimizer/test/CMakeLists.txt
+++ b/src/optimizer/test/CMakeLists.txt
@@ -52,10 +52,8 @@ nebula_add_test(
     OBJECTS
         ${OPTIMIZER_TEST_LIB}
     LIBRARIES
-        proxygenhttpserver
-        proxygenlib
+        ${PROXYGEN_LIBRARIES}
         ${THRIFT_LIBRARIES}
-        wangle
         gtest
         gtest_main
 )
@@ -68,10 +66,8 @@ nebula_add_test(
     OBJECTS
         ${OPTIMIZER_TEST_LIB}
     LIBRARIES
-        proxygenhttpserver
-        proxygenlib
-    ${THRIFT_LIBRARIES}
-        wangle
+        ${PROXYGEN_LIBRARIES}
+        ${THRIFT_LIBRARIES}
         gtest
         gtest_main
 )
diff --git a/src/optimizer/test/IndexScanRuleTest.cpp b/src/optimizer/test/IndexScanRuleTest.cpp
index b025072a6b5c861d7b088796944b7d589523b892..1ddc2b967a2b0caffd2fe73262e2bc9143bfb6db 100644
--- a/src/optimizer/test/IndexScanRuleTest.cpp
+++ b/src/optimizer/test/IndexScanRuleTest.cpp
@@ -261,10 +261,10 @@ TEST(IndexScanRuleTest, BoundValueRangeTest) {
             EXPECT_TRUE(status.ok());
             EXPECT_EQ(1, hints.size());
             const auto& hint = hints[0];
-            EXPECT_EQ("col_int", hint.column_name);
-            EXPECT_EQ(storage::cpp2::ScanType::RANGE, hint.scan_type);
-            EXPECT_EQ(std::numeric_limits<int64_t>::min(), hint.begin_value);
-            EXPECT_EQ(2, hint.end_value);
+            EXPECT_EQ("col_int", *hint.column_name_ref());
+            EXPECT_EQ(storage::cpp2::ScanType::RANGE, *hint.scan_type_ref());
+            EXPECT_EQ(std::numeric_limits<int64_t>::min(), *hint.begin_value_ref());
+            EXPECT_EQ(2, *hint.end_value_ref());
         }
         {
             std::vector<storage::cpp2::IndexColumnHint> hints;
@@ -275,10 +275,10 @@ TEST(IndexScanRuleTest, BoundValueRangeTest) {
             EXPECT_TRUE(status.ok());
             EXPECT_EQ(1, hints.size());
             const auto& hint = hints[0];
-            EXPECT_EQ("col_int", hint.column_name);
-            EXPECT_EQ(storage::cpp2::ScanType::RANGE, hint.scan_type);
-            EXPECT_EQ(std::numeric_limits<int64_t>::min(), hint.begin_value);
-            EXPECT_EQ(3, hint.end_value);
+            EXPECT_EQ("col_int", *hint.column_name_ref());
+            EXPECT_EQ(storage::cpp2::ScanType::RANGE, *hint.scan_type_ref());
+            EXPECT_EQ(std::numeric_limits<int64_t>::min(), *hint.begin_value_ref());
+            EXPECT_EQ(3, *hint.end_value_ref());
         }
         {
             std::vector<storage::cpp2::IndexColumnHint> hints;
@@ -289,10 +289,10 @@ TEST(IndexScanRuleTest, BoundValueRangeTest) {
             EXPECT_TRUE(status.ok());
             EXPECT_EQ(1, hints.size());
             const auto& hint = hints[0];
-            EXPECT_EQ("col_int", hint.column_name);
-            EXPECT_EQ(storage::cpp2::ScanType::RANGE, hint.scan_type);
-            EXPECT_EQ(3, hint.begin_value);
-            EXPECT_EQ(std::numeric_limits<int64_t>::max(), hint.end_value);
+            EXPECT_EQ("col_int", *hint.column_name_ref());
+            EXPECT_EQ(storage::cpp2::ScanType::RANGE, *hint.scan_type_ref());
+            EXPECT_EQ(3, *hint.begin_value_ref());
+            EXPECT_EQ(std::numeric_limits<int64_t>::max(), *hint.end_value_ref());
         }
         {
             std::vector<storage::cpp2::IndexColumnHint> hints;
@@ -303,10 +303,10 @@ TEST(IndexScanRuleTest, BoundValueRangeTest) {
             EXPECT_TRUE(status.ok());
             EXPECT_EQ(1, hints.size());
             const auto& hint = hints[0];
-            EXPECT_EQ("col_int", hint.column_name);
-            EXPECT_EQ(storage::cpp2::ScanType::RANGE, hint.scan_type);
-            EXPECT_EQ(2, hint.begin_value);
-            EXPECT_EQ(std::numeric_limits<int64_t>::max(), hint.end_value);
+            EXPECT_EQ("col_int", *hint.column_name_ref());
+            EXPECT_EQ(storage::cpp2::ScanType::RANGE, *hint.scan_type_ref());
+            EXPECT_EQ(2, *hint.begin_value_ref());
+            EXPECT_EQ(std::numeric_limits<int64_t>::max(), *hint.end_value_ref());
         }
         {
             std::vector<storage::cpp2::IndexColumnHint> hints;
@@ -318,10 +318,10 @@ TEST(IndexScanRuleTest, BoundValueRangeTest) {
             EXPECT_TRUE(status.ok());
             EXPECT_EQ(1, hints.size());
             const auto& hint = hints[0];
-            EXPECT_EQ("col_int", hint.column_name);
-            EXPECT_EQ(storage::cpp2::ScanType::RANGE, hint.scan_type);
-            EXPECT_EQ(3, hint.begin_value);
-            EXPECT_EQ(5, hint.end_value);
+            EXPECT_EQ("col_int", *hint.column_name_ref());
+            EXPECT_EQ(storage::cpp2::ScanType::RANGE, *hint.scan_type_ref());
+            EXPECT_EQ(3, *hint.begin_value_ref());
+            EXPECT_EQ(5, *hint.end_value_ref());
         }
         {
             std::vector<storage::cpp2::IndexColumnHint> hints;
@@ -333,10 +333,10 @@ TEST(IndexScanRuleTest, BoundValueRangeTest) {
             EXPECT_TRUE(status.ok());
             EXPECT_EQ(1, hints.size());
             const auto& hint = hints[0];
-            EXPECT_EQ("col_int", hint.column_name);
-            EXPECT_EQ(storage::cpp2::ScanType::RANGE, hint.scan_type);
-            EXPECT_EQ(2, hint.begin_value);
-            EXPECT_EQ(6, hint.end_value);
+            EXPECT_EQ("col_int", *hint.column_name_ref());
+            EXPECT_EQ(storage::cpp2::ScanType::RANGE, *hint.scan_type_ref());
+            EXPECT_EQ(2, *hint.begin_value_ref());
+            EXPECT_EQ(6, *hint.end_value_ref());
         }
     }
     {
@@ -373,10 +373,10 @@ TEST(IndexScanRuleTest, BoundValueRangeTest) {
             EXPECT_TRUE(status.ok());
             EXPECT_EQ(1, hints.size());
             const auto& hint = hints[0];
-            EXPECT_EQ("col_double", hint.column_name);
-            EXPECT_EQ(storage::cpp2::ScanType::RANGE, hint.scan_type);
-            EXPECT_EQ(-std::numeric_limits<double>::max(), hint.begin_value);
-            EXPECT_EQ(1, hint.end_value);
+            EXPECT_EQ("col_double", *hint.column_name_ref());
+            EXPECT_EQ(storage::cpp2::ScanType::RANGE, *hint.scan_type_ref());
+            EXPECT_EQ(-std::numeric_limits<double>::max(), *hint.begin_value_ref());
+            EXPECT_EQ(1, *hint.end_value_ref());
         }
         {
             std::vector<storage::cpp2::IndexColumnHint> hints;
@@ -387,10 +387,10 @@ TEST(IndexScanRuleTest, BoundValueRangeTest) {
             EXPECT_TRUE(status.ok());
             EXPECT_EQ(1, hints.size());
             const auto& hint = hints[0];
-            EXPECT_EQ("col_double", hint.column_name);
-            EXPECT_EQ(storage::cpp2::ScanType::RANGE, hint.scan_type);
-            EXPECT_EQ(1, hint.begin_value);
-            EXPECT_EQ(std::numeric_limits<double>::max(), hint.end_value);
+            EXPECT_EQ("col_double", *hint.column_name_ref());
+            EXPECT_EQ(storage::cpp2::ScanType::RANGE, *hint.scan_type_ref());
+            EXPECT_EQ(1, *hint.begin_value_ref());
+            EXPECT_EQ(std::numeric_limits<double>::max(), *hint.end_value_ref());
         }
         {
             std::vector<storage::cpp2::IndexColumnHint> hints;
@@ -402,10 +402,10 @@ TEST(IndexScanRuleTest, BoundValueRangeTest) {
             EXPECT_TRUE(status.ok());
             EXPECT_EQ(1, hints.size());
             const auto& hint = hints[0];
-            EXPECT_EQ("col_double", hint.column_name);
-            EXPECT_EQ(storage::cpp2::ScanType::RANGE, hint.scan_type);
-            EXPECT_EQ(1 + OptimizerUtils::kEpsilon, hint.begin_value);
-            EXPECT_EQ(5 - OptimizerUtils::kEpsilon, hint.end_value);
+            EXPECT_EQ("col_double", *hint.column_name_ref());
+            EXPECT_EQ(storage::cpp2::ScanType::RANGE, *hint.scan_type_ref());
+            EXPECT_EQ(1 + OptimizerUtils::kEpsilon, *hint.begin_value_ref());
+            EXPECT_EQ(5 - OptimizerUtils::kEpsilon, *hint.end_value_ref());
         }
     }
     {
@@ -423,10 +423,10 @@ TEST(IndexScanRuleTest, BoundValueRangeTest) {
             EXPECT_TRUE(status.ok());
             EXPECT_EQ(1, hints.size());
             const auto& hint = hints[0];
-            EXPECT_EQ("col_str", hint.column_name);
-            EXPECT_EQ(storage::cpp2::ScanType::RANGE, hint.scan_type);
-            EXPECT_EQ(std::string(len, '\0'), hint.begin_value);
-            EXPECT_EQ("ccc", hint.end_value);
+            EXPECT_EQ("col_str", *hint.column_name_ref());
+            EXPECT_EQ(storage::cpp2::ScanType::RANGE, *hint.scan_type_ref());
+            EXPECT_EQ(std::string(len, '\0'), *hint.begin_value_ref());
+            EXPECT_EQ("ccc", *hint.end_value_ref());
         }
         {
             std::vector<storage::cpp2::IndexColumnHint> hints;
@@ -437,12 +437,12 @@ TEST(IndexScanRuleTest, BoundValueRangeTest) {
             EXPECT_TRUE(status.ok());
             EXPECT_EQ(1, hints.size());
             const auto& hint = hints[0];
-            EXPECT_EQ("col_str", hint.column_name);
-            EXPECT_EQ(storage::cpp2::ScanType::RANGE, hint.scan_type);
+            EXPECT_EQ("col_str", *hint.column_name_ref());
+            EXPECT_EQ(storage::cpp2::ScanType::RANGE, *hint.scan_type_ref());
             std::string begin = std::string(3, 'c').append(6, 0x00).append(1, 0x01);
             std::string end = std::string(len, static_cast<char>(0xFF));
-            EXPECT_EQ(begin, hint.begin_value);
-            EXPECT_EQ(end, hint.end_value);
+            EXPECT_EQ(begin, *hint.begin_value_ref());
+            EXPECT_EQ(end, *hint.end_value_ref());
         }
         {
             std::vector<storage::cpp2::IndexColumnHint> hints;
@@ -454,12 +454,12 @@ TEST(IndexScanRuleTest, BoundValueRangeTest) {
             EXPECT_TRUE(status.ok());
             EXPECT_EQ(1, hints.size());
             const auto& hint = hints[0];
-            EXPECT_EQ("col_str", hint.column_name);
-            EXPECT_EQ(storage::cpp2::ScanType::RANGE, hint.scan_type);
+            EXPECT_EQ("col_str", *hint.column_name_ref());
+            EXPECT_EQ(storage::cpp2::ScanType::RANGE, *hint.scan_type_ref());
             std::string begin = std::string(3, 'a').append(6, 0x00).append(1, 0x01);
             std::string end = "ccc";
-            EXPECT_EQ(begin, hint.begin_value);
-            EXPECT_EQ(end, hint.end_value);
+            EXPECT_EQ(begin, *hint.begin_value_ref());
+            EXPECT_EQ(end, *hint.end_value_ref());
         }
         {
             std::vector<storage::cpp2::IndexColumnHint> hints;
@@ -471,12 +471,12 @@ TEST(IndexScanRuleTest, BoundValueRangeTest) {
             EXPECT_TRUE(status.ok());
             EXPECT_EQ(1, hints.size());
             const auto& hint = hints[0];
-            EXPECT_EQ("col_str", hint.column_name);
-            EXPECT_EQ(storage::cpp2::ScanType::RANGE, hint.scan_type);
+            EXPECT_EQ("col_str", *hint.column_name_ref());
+            EXPECT_EQ(storage::cpp2::ScanType::RANGE, *hint.scan_type_ref());
             std::string begin = "aaa";
             std::string end = std::string(3, 'c').append(6, 0x00).append(1, 0x01);
-            EXPECT_EQ(begin, hint.begin_value);
-            EXPECT_EQ(end, hint.end_value);
+            EXPECT_EQ(begin, *hint.begin_value_ref());
+            EXPECT_EQ(end, *hint.end_value_ref());
         }
         {
             std::vector<storage::cpp2::IndexColumnHint> hints;
@@ -488,10 +488,10 @@ TEST(IndexScanRuleTest, BoundValueRangeTest) {
             EXPECT_TRUE(status.ok());
             EXPECT_EQ(1, hints.size());
             const auto& hint = hints[0];
-            EXPECT_EQ("col_str", hint.column_name);
-            EXPECT_EQ(storage::cpp2::ScanType::RANGE, hint.scan_type);
-            EXPECT_EQ("aaa", hint.begin_value);
-            EXPECT_EQ("ccc", hint.end_value);
+            EXPECT_EQ("col_str", *hint.column_name_ref());
+            EXPECT_EQ(storage::cpp2::ScanType::RANGE, *hint.scan_type_ref());
+            EXPECT_EQ("aaa", *hint.begin_value_ref());
+            EXPECT_EQ("ccc", *hint.end_value_ref());
         }
     }
 }
diff --git a/src/parser/AdminSentences.cpp b/src/parser/AdminSentences.cpp
index 0fd5071e7c1c6be417d9019dab593b1530136518..d29c2902506419eb42ebb669e70a6ebc9361ed6a 100644
--- a/src/parser/AdminSentences.cpp
+++ b/src/parser/AdminSentences.cpp
@@ -7,6 +7,7 @@
 #include "parser/AdminSentences.h"
 #include <sstream>
 #include "util/SchemaUtil.h"
+#include <thrift/lib/cpp/util/EnumUtils.h>
 
 namespace nebula {
 
@@ -123,7 +124,7 @@ std::string ConfigRowItem::toString() const {
     std::string buf;
     buf.reserve(128);
     if (module_ != meta::cpp2::ConfigModule::ALL) {
-        buf += meta::cpp2::_ConfigModule_VALUES_TO_NAMES.at(module_);
+        buf += apache::thrift::util::enumNameSafe(module_);
         buf += ":";
     }
     if (name_ != nullptr) {
@@ -276,7 +277,7 @@ std::string AdminJobSentence::toString() const {
                 case meta::cpp2::AdminCmd::DATA_BALANCE:
                 case meta::cpp2::AdminCmd::UNKNOWN:
                     return folly::stringPrintf("Unsupported AdminCmd: %s",
-                            meta::cpp2::_AdminCmd_VALUES_TO_NAMES.at(cmd_));
+                            apache::thrift::util::enumNameSafe(cmd_).c_str());
             }
         }
         case meta::cpp2::AdminJobOp::SHOW_All:
@@ -333,12 +334,12 @@ std::string SignInTextServiceSentence::toString() const {
         buf += client.get_host().host;
         buf += ":";
         buf += std::to_string(client.get_host().port);
-        if (client.__isset.user && !client.get_user()->empty()) {
+        if (client.user_ref().has_value() && !(*client.user_ref()).empty()) {
             buf += ", \"";
             buf += *client.get_user();
             buf += "\"";
         }
-        if (client.__isset.pwd && !client.get_pwd()->empty()) {
+        if (client.pwd_ref().has_value() && !(*client.pwd_ref()).empty()) {
             buf += ", \"";
             buf += *client.get_pwd();
             buf += "\"";
diff --git a/src/parser/MaintainSentences.cpp b/src/parser/MaintainSentences.cpp
index 749e0189a1371c8ffd947283c0258cc9543b9910..7a9ca07b6998e6bba6d95c1f61bf8cc406e37058 100644
--- a/src/parser/MaintainSentences.cpp
+++ b/src/parser/MaintainSentences.cpp
@@ -5,13 +5,14 @@
  */
 
 #include <string>
+#include <thrift/lib/cpp/util/EnumUtils.h>
 #include "common/base/Base.h"
 #include "parser/MaintainSentences.h"
 
 namespace nebula {
 
 std::ostream& operator<<(std::ostream& os, meta::cpp2::PropertyType type) {
-    os << meta::cpp2::_PropertyType_VALUES_TO_NAMES.at(type);
+    os << apache::thrift::util::enumNameSafe(type);
     return os;
 }
 
@@ -55,7 +56,7 @@ std::string ColumnSpecification::toString() const {
         buf += std::to_string(typeLen_);
         buf += ")";
     } else {
-        buf += meta::cpp2::_PropertyType_VALUES_TO_NAMES.at(type_);
+        buf += apache::thrift::util::enumNameSafe(type_);
     }
     if (isNull_) {
         buf += " NULL";
@@ -242,8 +243,8 @@ std::string CreateTagIndexSentence::toString() const {
     std::vector<std::string> fieldDefs;
     for (const auto& field : this->fields()) {
         std::string f = field.get_name();
-        if (field.__isset.type_length) {
-            f += "(" + std::to_string(*field.get_type_length()) + ")";
+        if (field.type_length_ref().has_value()) {
+            f += "(" + std::to_string(*field.type_length_ref()) + ")";
         }
         fieldDefs.emplace_back(std::move(f));
     }
@@ -269,8 +270,8 @@ std::string CreateEdgeIndexSentence::toString() const {
     std::vector<std::string> fieldDefs;
     for (const auto& field : this->fields()) {
         std::string f = field.get_name();
-        if (field.__isset.type_length) {
-            f += "(" + std::to_string(*field.get_type_length()) + ")";
+        if (field.type_length_ref().has_value()) {
+            f += "(" + std::to_string(*field.type_length_ref()) + ")";
         }
         fieldDefs.emplace_back(std::move(f));
     }
diff --git a/src/parser/parser.yy b/src/parser/parser.yy
index 0381b02e7223b365aac2e7e19b7c05fbe0ef40d2..f8892122af9925baba51d81a1052bd031414ca43 100644
--- a/src/parser/parser.yy
+++ b/src/parser/parser.yy
@@ -2092,35 +2092,35 @@ column_spec_list
 
 column_spec
     : name_label type_spec {
-        $$ = new ColumnSpecification($1, $2->type, true, nullptr, $2->type_length);
+        $$ = new ColumnSpecification($1, $2->type, true, nullptr, $2->type_length_ref().value_or(0));
         delete $2;
     }
     | name_label type_spec KW_DEFAULT expression {
-        $$ = new ColumnSpecification($1, $2->type, true, $4, $2->type_length);
+        $$ = new ColumnSpecification($1, $2->type, true, $4, $2->type_length_ref().value_or(0));
         delete $2;
     }
     | name_label type_spec KW_NOT KW_NULL {
-        $$ = new ColumnSpecification($1, $2->type, false, nullptr, $2->type_length);
+        $$ = new ColumnSpecification($1, $2->type, false, nullptr, $2->type_length_ref().value_or(0));
         delete $2;
     }
     | name_label type_spec KW_NULL {
-        $$ = new ColumnSpecification($1, $2->type, true, nullptr, $2->type_length);
+        $$ = new ColumnSpecification($1, $2->type, true, nullptr, $2->type_length_ref().value_or(0));
         delete $2;
     }
     | name_label type_spec KW_NOT KW_NULL KW_DEFAULT expression {
-        $$ = new ColumnSpecification($1, $2->type, false, $6, $2->type_length);
+        $$ = new ColumnSpecification($1, $2->type, false, $6, $2->type_length_ref().value_or(0));
         delete $2;
     }
     | name_label type_spec KW_DEFAULT expression KW_NOT KW_NULL {
-        $$ = new ColumnSpecification($1, $2->type, false, $4, $2->type_length);
+        $$ = new ColumnSpecification($1, $2->type, false, $4, $2->type_length_ref().value_or(0));
         delete $2;
     }
     | name_label type_spec KW_NULL KW_DEFAULT expression {
-        $$ = new ColumnSpecification($1, $2->type, true, $5 , $2->type_length);
+        $$ = new ColumnSpecification($1, $2->type, true, $5 , $2->type_length_ref().value_or(0));
         delete $2;
     }
     | name_label type_spec KW_DEFAULT expression KW_NULL {
-        $$ = new ColumnSpecification($1, $2->type, true, $4 , $2->type_length);
+        $$ = new ColumnSpecification($1, $2->type, true, $4 , $2->type_length_ref().value_or(0));
         delete $2;
     }
     ;
diff --git a/src/parser/test/CMakeLists.txt b/src/parser/test/CMakeLists.txt
index 626b0a84a5977b378bee642e984714be6184df57..4914cd70f0c9658f4d3a83d8784f4e2cf2f74a9e 100644
--- a/src/parser/test/CMakeLists.txt
+++ b/src/parser/test/CMakeLists.txt
@@ -47,28 +47,28 @@ nebula_add_test(
     NAME parser_test
     SOURCES ParserTest.cpp
     OBJECTS ${PARSER_TEST_LIBS}
-    LIBRARIES gtest gtest_main ${THRIFT_LIBRARIES} proxygenlib
+    LIBRARIES gtest gtest_main ${THRIFT_LIBRARIES} ${PROXYGEN_LIBRARIES}
 )
 
 nebula_add_test(
     NAME scanner_test
     SOURCES ScannerTest.cpp
     OBJECTS ${PARSER_TEST_LIBS}
-    LIBRARIES gtest gtest_main ${THRIFT_LIBRARIES} proxygenlib
+    LIBRARIES gtest gtest_main ${THRIFT_LIBRARIES} ${PROXYGEN_LIBRARIES}
 )
 
 nebula_add_executable(
     NAME parser_bm
     SOURCES ParserBenchmark.cpp
     OBJECTS ${PARSER_TEST_LIBS}
-    LIBRARIES follybenchmark boost_regex ${THRIFT_LIBRARIES} proxygenlib
+    LIBRARIES follybenchmark boost_regex ${THRIFT_LIBRARIES} ${PROXYGEN_LIBRARIES}
 )
 
 nebula_add_test(
     NAME expression_parsing_test
     SOURCES ExpressionParsingTest.cpp
     OBJECTS ${PARSER_TEST_LIBS}
-    LIBRARIES gtest gtest_main ${THRIFT_LIBRARIES} proxygenlib
+    LIBRARIES gtest gtest_main ${THRIFT_LIBRARIES} ${PROXYGEN_LIBRARIES}
 )
 
 if(ENABLE_FUZZ_TEST)
diff --git a/src/planner/Admin.cpp b/src/planner/Admin.cpp
index c128e501f6cd46d1148450a5c664608e95ac47df..e109aae0c27fe8b91239f7346530efc48fc76ac2 100644
--- a/src/planner/Admin.cpp
+++ b/src/planner/Admin.cpp
@@ -8,6 +8,7 @@
 #include "planner/Admin.h"
 
 #include "util/ToJson.h"
+#include <thrift/lib/cpp/util/EnumUtils.h>
 
 namespace nebula {
 namespace graph {
@@ -53,13 +54,13 @@ std::unique_ptr<PlanNodeDescription> ShowParts::explain() const {
 
 std::unique_ptr<PlanNodeDescription> ShowConfigs::explain() const {
     auto desc = SingleDependencyNode::explain();
-    addDescription("module", meta::cpp2::_ConfigModule_VALUES_TO_NAMES.at(module_), desc.get());
+    addDescription("module", apache::thrift::util::enumNameSafe(module_), desc.get());
     return desc;
 }
 
 std::unique_ptr<PlanNodeDescription> SetConfig::explain() const {
     auto desc = SingleDependencyNode::explain();
-    addDescription("module", meta::cpp2::_ConfigModule_VALUES_TO_NAMES.at(module_), desc.get());
+    addDescription("module", apache::thrift::util::enumNameSafe(module_), desc.get());
     addDescription("name", name_, desc.get());
     addDescription("value", value_.toString(), desc.get());
     return desc;
@@ -67,7 +68,7 @@ std::unique_ptr<PlanNodeDescription> SetConfig::explain() const {
 
 std::unique_ptr<PlanNodeDescription> GetConfig::explain() const {
     auto desc = SingleDependencyNode::explain();
-    addDescription("module", meta::cpp2::_ConfigModule_VALUES_TO_NAMES.at(module_), desc.get());
+    addDescription("module", apache::thrift::util::enumNameSafe(module_), desc.get());
     addDescription("name", name_, desc.get());
     return desc;
 }
@@ -108,7 +109,7 @@ std::unique_ptr<PlanNodeDescription> GrantRole::explain() const {
     auto desc = SingleDependencyNode::explain();
     addDescription("username", *username_, desc.get());
     addDescription("spaceName", *spaceName_, desc.get());
-    addDescription("role", meta::cpp2::_RoleType_VALUES_TO_NAMES.at(role_), desc.get());
+    addDescription("role", apache::thrift::util::enumNameSafe(role_), desc.get());
     return desc;
 }
 
@@ -116,7 +117,7 @@ std::unique_ptr<PlanNodeDescription> RevokeRole::explain() const {
     auto desc = SingleDependencyNode::explain();
     addDescription("username", *username_, desc.get());
     addDescription("spaceName", *spaceName_, desc.get());
-    addDescription("role", meta::cpp2::_RoleType_VALUES_TO_NAMES.at(role_), desc.get());
+    addDescription("role", apache::thrift::util::enumNameSafe(role_), desc.get());
     return desc;
 }
 
@@ -142,8 +143,8 @@ std::unique_ptr<PlanNodeDescription> ListRoles::explain() const {
 
 std::unique_ptr<PlanNodeDescription> SubmitJob::explain() const {
     auto desc = SingleDependencyNode::explain();
-    addDescription("operation", meta::cpp2::_AdminJobOp_VALUES_TO_NAMES.at(op_), desc.get());
-    addDescription("command", meta::cpp2::_AdminCmd_VALUES_TO_NAMES.at(cmd_), desc.get());
+    addDescription("operation", apache::thrift::util::enumNameSafe(op_), desc.get());
+    addDescription("command", apache::thrift::util::enumNameSafe(cmd_), desc.get());
     addDescription("parameters", folly::toJson(util::toJson(params_)), desc.get());
     return desc;
 }
diff --git a/src/planner/Query.cpp b/src/planner/Query.cpp
index 4b785dc4d716ae2c23be0311760bbbff82c40c15..94f203d6481a72e57f90e13cd1406ef0e0361857 100644
--- a/src/planner/Query.cpp
+++ b/src/planner/Query.cpp
@@ -9,6 +9,7 @@
 #include <folly/String.h>
 #include <folly/dynamic.h>
 #include <folly/json.h>
+#include <thrift/lib/cpp/util/EnumUtils.h>
 
 #include "util/ToJson.h"
 
@@ -39,7 +40,7 @@ std::unique_ptr<PlanNodeDescription> GetNeighbors::explain() const {
     addDescription("src", src_ ? src_->toString() : "", desc.get());
     addDescription("edgeTypes", folly::toJson(util::toJson(edgeTypes_)), desc.get());
     addDescription("edgeDirection",
-                   storage::cpp2::_EdgeDirection_VALUES_TO_NAMES.at(edgeDirection_),
+                   apache::thrift::util::enumNameSafe(edgeDirection_),
                    desc.get());
     addDescription(
         "vertexProps", vertexProps_ ? folly::toJson(util::toJson(*vertexProps_)) : "", desc.get());
diff --git a/src/planner/test/CMakeLists.txt b/src/planner/test/CMakeLists.txt
index be8798d5d7ca59104b3ebdf4c2a7fdbd308097e4..df54a3458579a2aa60eaeed988e8edde0d4e3d46 100644
--- a/src/planner/test/CMakeLists.txt
+++ b/src/planner/test/CMakeLists.txt
@@ -50,8 +50,6 @@ nebula_add_test(
         $<TARGET_OBJECTS:context_obj>
     LIBRARIES
         gtest
-        proxygenhttpserver
-        proxygenlib
+        ${PROXYGEN_LIBRARIES}
         ${THRIFT_LIBRARIES}
-        wangle
 )
diff --git a/src/planner/test/ExecutionPlanTest.cpp b/src/planner/test/ExecutionPlanTest.cpp
index 9f4cf673d2c5b453e7fc2195e15025989e6eceef..955d3389b8126d12b28f55c7759ce162f62d8778 100644
--- a/src/planner/test/ExecutionPlanTest.cpp
+++ b/src/planner/test/ExecutionPlanTest.cpp
@@ -35,9 +35,13 @@ public:
 
         watch_.reset();
         scheduler_->schedule()
-            .then([](Status s) { ASSERT_TRUE(s.ok()) << s.toString(); })
-            .onError([](const ExecutionError& e) { LOG(ERROR) << e.what(); })
-            .onError([](const std::exception& e) { LOG(ERROR) << "exception: " << e.what(); })
+            .thenValue([](Status s) { ASSERT_TRUE(s.ok()) << s.toString(); })
+            .onError(folly::tag_t<ExecutionError>{}, [](const ExecutionError& e) {
+                        LOG(ERROR) << e.what();
+                    })
+            .onError(folly::tag_t<std::exception>{}, [](const std::exception& e) {
+                        LOG(ERROR) << "exception: " << e.what();
+                    })
             .ensure([this]() {
                 auto us = duration_cast<microseconds>(watch_.elapsed());
                 LOG(INFO) << "elapsed time: " << us.count() << "us";
diff --git a/src/scheduler/Scheduler.cpp b/src/scheduler/Scheduler.cpp
index 35594663105bcaa7dff5f47663459f5d21c81231..3960e79309647db64308201a348feb9d0b29a732 100644
--- a/src/scheduler/Scheduler.cpp
+++ b/src/scheduler/Scheduler.cpp
@@ -67,12 +67,12 @@ folly::Future<Status> Scheduler::doSchedule(Executor *executor) {
         case PlanNode::Kind::kSelect: {
             auto sel = static_cast<SelectExecutor *>(executor);
             return doScheduleParallel(sel->depends())
-                .then(task(sel,
+                .thenValue(task(sel,
                            [sel, this](Status status) {
                                if (!status.ok()) return sel->error(std::move(status));
                                return execute(sel);
                            }))
-                .then(task(sel, [sel, this](Status status) {
+                .thenValue(task(sel, [sel, this](Status status) {
                     if (!status.ok()) return sel->error(std::move(status));
 
                     auto val = qctx_->ectx()->getValue(sel->node()->outputVar());
@@ -82,9 +82,10 @@ folly::Future<Status> Scheduler::doSchedule(Executor *executor) {
         }
         case PlanNode::Kind::kLoop: {
             auto loop = static_cast<LoopExecutor *>(executor);
-            return doScheduleParallel(loop->depends()).then(task(loop, [loop, this](Status status) {
-                if (!status.ok()) return loop->error(std::move(status));
-                return iterate(loop);
+            return doScheduleParallel(loop->depends())
+                .thenValue(task(loop, [loop, this](Status status) {
+                    if (!status.ok()) return loop->error(std::move(status));
+                    return iterate(loop);
             }));
         }
         case PlanNode::Kind::kPassThrough: {
@@ -107,7 +108,7 @@ folly::Future<Status> Scheduler::doSchedule(Executor *executor) {
             }
 
             return doScheduleParallel(mout->depends())
-                .then(task(mout, [&data, mout, this](Status status) {
+                .thenValue(task(mout, [&data, mout, this](Status status) {
                     // Notify and wake up all waited tasks
                     data.promise->setValue(status);
 
@@ -121,9 +122,10 @@ folly::Future<Status> Scheduler::doSchedule(Executor *executor) {
                 return execute(executor);
             }
 
-            return doScheduleParallel(deps).then(task(executor, [executor, this](Status stats) {
-                if (!stats.ok()) return executor->error(std::move(stats));
-                return execute(executor);
+            return doScheduleParallel(deps)
+                .thenValue(task(executor, [executor, this](Status stats) {
+                    if (!stats.ok()) return executor->error(std::move(stats));
+                    return execute(executor);
             }));
         }
     }
@@ -136,7 +138,8 @@ folly::Future<Status> Scheduler::doScheduleParallel(const std::set<Executor *> &
     for (auto dep : dependents) {
         futures.emplace_back(doSchedule(dep));
     }
-    return folly::collect(futures).then([](std::vector<Status> stats) {
+    auto *runner = qctx_->rctx()->runner();
+    return folly::collect(futures).via(runner).thenValue([](std::vector<Status> stats) {
         for (auto &s : stats) {
             if (!s.ok()) return s;
         }
@@ -145,7 +148,7 @@ folly::Future<Status> Scheduler::doScheduleParallel(const std::set<Executor *> &
 }
 
 folly::Future<Status> Scheduler::iterate(LoopExecutor *loop) {
-    return execute(loop).then(task(loop, [loop, this](Status status) {
+    return execute(loop).thenValue(task(loop, [loop, this](Status status) {
         if (!status.ok()) return loop->error(std::move(status));
 
         auto val = qctx_->ectx()->getValue(loop->node()->outputVar());
@@ -156,7 +159,7 @@ folly::Future<Status> Scheduler::iterate(LoopExecutor *loop) {
         }
         auto cond = val.moveBool();
         if (!cond) return folly::makeFuture(Status::OK());
-        return doSchedule(loop->loopBody()).then(task(loop, [loop, this](Status s) {
+        return doSchedule(loop->loopBody()).thenValue(task(loop, [loop, this](Status s) {
             if (!s.ok()) return loop->error(std::move(s));
             return iterate(loop);
         }));
@@ -168,7 +171,7 @@ folly::Future<Status> Scheduler::execute(Executor *executor) {
     if (!status.ok()) {
         return executor->error(std::move(status));
     }
-    return executor->execute().then([executor](Status s) {
+    return executor->execute().thenValue([executor](Status s) {
         NG_RETURN_IF_ERROR(s);
         return executor->close();
     });
diff --git a/src/service/GraphService.cpp b/src/service/GraphService.cpp
index f1259de9bc8de8b5bcac6238fe48897f98575d8c..4d64d9a9bdfdef1ef9369b00f10408bdc3ff366f 100644
--- a/src/service/GraphService.cpp
+++ b/src/service/GraphService.cpp
@@ -29,7 +29,7 @@ Status GraphService::init(std::shared_ptr<folly::IOThreadPoolExecutor> ioExecuto
 folly::Future<AuthResponse> GraphService::future_authenticate(
         const std::string& username,
         const std::string& password) {
-    auto *peer = getConnectionContext()->getPeerAddress();
+    auto *peer = getRequestContext()->getPeerAddress();
     LOG(INFO) << "Authenticating user " << username << " from " <<  peer->describe();
 
     RequestContext<AuthResponse> ctx;
diff --git a/src/service/PermissionManager.cpp b/src/service/PermissionManager.cpp
index bd92e03d94b45672dead25a7ab05b51a08805ada..b2de3c30bc1c97f67d25a9f0b0b0b34cf9791124 100644
--- a/src/service/PermissionManager.cpp
+++ b/src/service/PermissionManager.cpp
@@ -4,6 +4,7 @@
  * attached with Common Clause Condition 1.0, found in the LICENSES directory.
  */
 
+#include <thrift/lib/cpp/util/EnumUtils.h>
 #include "service/PermissionManager.h"
 
 namespace nebula {
@@ -161,7 +162,7 @@ Status PermissionManager::canWriteRole(Session *session,
         return Status::OK();
     }
     return Status::PermissionError("No permission to grant/revoke `%s' to `%s'.",
-                                   meta::cpp2::_RoleType_VALUES_TO_NAMES.at(role),
+                                   apache::thrift::util::enumNameSafe(role).c_str(),
                                    targetUser.c_str());
 }
 
diff --git a/src/service/QueryInstance.cpp b/src/service/QueryInstance.cpp
index d95eb9f6aad94a5109ffea6cdfdce64a2bae9a24..a08b8bb11e5c3fb4c38d387c58327ca0261186cc 100644
--- a/src/service/QueryInstance.cpp
+++ b/src/service/QueryInstance.cpp
@@ -45,15 +45,19 @@ void QueryInstance::execute() {
     }
 
     scheduler_->schedule()
-        .then([this](Status s) {
+        .thenValue([this](Status s) {
             if (s.ok()) {
                 this->onFinish();
             } else {
                 this->onError(std::move(s));
             }
         })
-        .onError([this](const ExecutionError &e) { onError(e.status()); })
-        .onError([this](const std::exception &e) { onError(Status::Error("%s", e.what())); });
+        .thenError(folly::tag_t<ExecutionError>{}, [this](const ExecutionError &e) {
+            onError(e.status());
+        })
+        .thenError(folly::tag_t<std::exception>{}, [this](const std::exception &e) {
+            onError(Status::Error("%s", e.what()));
+        });
 }
 
 Status QueryInstance::validateAndOptimize() {
diff --git a/src/util/IndexUtil.cpp b/src/util/IndexUtil.cpp
index 562496c29e31544dfc9e45f61b8c7405452a101d..9fe00ace84b4596622c62e6d8782a03f3cc1ef9e 100644
--- a/src/util/IndexUtil.cpp
+++ b/src/util/IndexUtil.cpp
@@ -52,12 +52,12 @@ StatusOr<DataSet> IndexUtil::toShowCreateIndex(bool isTagIndex,
     for (auto &col : indexItem.get_fields()) {
         createStr += " `" + col.get_name();
         const auto &type = col.get_type();
-        if (type.__isset.type_length) {
-            createStr += "(" + std::to_string(*type.get_type_length()) + ")";
+        if (type.type_length_ref().has_value()) {
+            createStr += "(" + std::to_string(*type.type_length_ref()) + ")";
         }
         createStr += "`,\n";
     }
-    if (!indexItem.fields.empty()) {
+    if (!(*indexItem.fields_ref()).empty()) {
         createStr.resize(createStr.size() -2);
         createStr += "\n";
     }
diff --git a/src/util/SchemaUtil.cpp b/src/util/SchemaUtil.cpp
index 7db3d95c02e0066642c08f7f3083554c1e8bfd1b..e3e75498d9f4c6cd4f4e574f63a458eb79e1b772 100644
--- a/src/util/SchemaUtil.cpp
+++ b/src/util/SchemaUtil.cpp
@@ -4,6 +4,8 @@
 * attached with Common Clause Condition 1.0, found in the LICENSES directory.
 */
 
+#include <thrift/lib/cpp/util/EnumUtils.h>
+
 #include "common/base/Base.h"
 #include "util/SchemaUtil.h"
 #include "context/QueryExpressionContext.h"
@@ -33,11 +35,12 @@ Status SchemaUtil::validateProps(const std::vector<SchemaPropItem*> &schemaProps
             }
         }
 
-        if (schema.schema_prop.get_ttl_duration() &&
-            (*schema.schema_prop.get_ttl_duration() != 0)) {
+        auto &prop = *schema.schema_prop_ref();
+        if (prop.get_ttl_duration() &&
+            (*prop.get_ttl_duration() != 0)) {
             // Disable implicit TTL mode
-            if (!schema.schema_prop.get_ttl_col() ||
-                (schema.schema_prop.get_ttl_col() && schema.schema_prop.get_ttl_col()->empty())) {
+            if (!prop.get_ttl_col() ||
+                (prop.get_ttl_col() && prop.get_ttl_col()->empty())) {
                 return Status::Error("Implicit ttl_col not support");
             }
         }
@@ -51,15 +54,15 @@ std::shared_ptr<const meta::NebulaSchemaProvider>
 SchemaUtil::generateSchemaProvider(const SchemaVer ver, const meta::cpp2::Schema &schema) {
     auto schemaPtr = std::make_shared<meta::NebulaSchemaProvider>(ver);
     for (auto col : schema.get_columns()) {
-        bool hasDef = col.__isset.default_value;
+        bool hasDef = col.default_value_ref().has_value();
         std::unique_ptr<Expression> defaultValueExpr;
         if (hasDef) {
-            defaultValueExpr = Expression::decode(*col.get_default_value());
+            defaultValueExpr = Expression::decode(*col.default_value_ref());
         }
         schemaPtr->addField(col.get_name(),
                             col.get_type().get_type(),
-                            col.type.__isset.type_length ? *col.get_type().get_type_length() : 0,
-                            col.__isset.nullable ? *col.get_nullable() : false,
+                            col.type.type_length_ref().value_or(0),
+                            col.nullable_ref().value_or(false),
                             hasDef ? defaultValueExpr.release() : nullptr);
     }
     return schemaPtr;
@@ -73,7 +76,7 @@ Status SchemaUtil::setTTLDuration(SchemaPropItem* schemaProp, meta::cpp2::Schema
     }
 
     auto ttlDuration = ret.value();
-    schema.schema_prop.set_ttl_duration(ttlDuration);
+    schema.schema_prop_ref().value().set_ttl_duration(ttlDuration);
     return Status::OK();
 }
 
@@ -87,11 +90,11 @@ Status SchemaUtil::setTTLCol(SchemaPropItem* schemaProp, meta::cpp2::Schema& sch
 
     auto  ttlColName = ret.value();
     if (ttlColName.empty()) {
-        schema.schema_prop.set_ttl_col("");
+        schema.schema_prop_ref().value().set_ttl_col("");
         return Status::OK();
     }
     // Check the legality of the ttl column name
-    for (auto& col : schema.columns) {
+    for (auto& col : *schema.columns_ref()) {
         if (col.name == ttlColName) {
             // Only integer columns and timestamp columns can be used as ttl_col
             // TODO(YT) Ttl_duration supports datetime type
@@ -99,7 +102,7 @@ Status SchemaUtil::setTTLCol(SchemaPropItem* schemaProp, meta::cpp2::Schema& sch
                 col.type.type != meta::cpp2::PropertyType::TIMESTAMP) {
                 return Status::Error("Ttl column type illegal");
             }
-            schema.schema_prop.set_ttl_col(ttlColName);
+            schema.schema_prop_ref().value().set_ttl_col(ttlColName);
             return Status::OK();
         }
     }
@@ -140,11 +143,11 @@ StatusOr<DataSet> SchemaUtil::toDescSchema(const meta::cpp2::Schema &schema) {
         Row row;
         row.values.emplace_back(Value(col.get_name()));
         row.values.emplace_back(typeToString(col));
-        auto nullable = col.__isset.nullable ? *col.get_nullable() : false;
+        auto nullable = col.nullable_ref().has_value() ? *col.nullable_ref() : false;
         row.values.emplace_back(nullable ? "YES" : "NO");
         auto defaultValue = Value::kEmpty;
-        if (col.__isset.default_value) {
-            auto expr = Expression::decode(*col.get_default_value());
+        if (col.default_value_ref().has_value()) {
+            auto expr = Expression::decode(*col.default_value_ref());
             if (expr == nullptr) {
                 LOG(ERROR) << "Internal error: Wrong default value expression.";
                 defaultValue = Value();
@@ -181,15 +184,15 @@ StatusOr<DataSet> SchemaUtil::toShowCreateSchema(bool isTag,
     for (auto &col : schema.get_columns()) {
         createStr += " `" + col.get_name() + "`";
         createStr += " " + typeToString(col);
-        auto nullable = col.__isset.nullable ? *col.get_nullable() : false;
+        auto nullable = col.nullable_ref().has_value() ? *col.nullable_ref() : false;
         if (!nullable) {
             createStr += " NOT NULL";
         } else {
             createStr += " NULL";
         }
 
-        if (col.__isset.default_value) {
-            auto encodeStr = *col.get_default_value();
+        if (col.default_value_ref().has_value()) {
+            auto encodeStr = *col.default_value_ref();
             auto expr = Expression::decode(encodeStr);
             if (expr == nullptr) {
                 LOG(ERROR) << "Internal error: the default value is wrong expression.";
@@ -199,21 +202,21 @@ StatusOr<DataSet> SchemaUtil::toShowCreateSchema(bool isTag,
         }
         createStr += ",\n";
     }
-    if (!schema.columns.empty()) {
+    if (!(*schema.columns_ref()).empty()) {
         createStr.resize(createStr.size() -2);
         createStr += "\n";
     }
     createStr += ")";
     auto prop = schema.get_schema_prop();
     createStr += " ttl_duration = ";
-    if (prop.__isset.ttl_duration) {
-        createStr += folly::to<std::string>(*prop.get_ttl_duration());
+    if (prop.ttl_duration_ref().has_value()) {
+        createStr += folly::to<std::string>(*prop.ttl_duration_ref());
     } else {
         createStr += "0";
     }
     createStr += ", ttl_col = ";
-    if (prop.__isset.ttl_col && !(prop.get_ttl_col()->empty())) {
-        createStr += "\"" + *prop.get_ttl_col() + "\"";
+    if (prop.ttl_col_ref().has_value() && !(*prop.ttl_col_ref()).empty()) {
+        createStr += "\"" + *prop.ttl_col_ref() + "\"";
     } else {
         createStr += "\"\"";
     }
@@ -223,9 +226,9 @@ StatusOr<DataSet> SchemaUtil::toShowCreateSchema(bool isTag,
 }
 
 std::string SchemaUtil::typeToString(const meta::cpp2::ColumnTypeDef &col) {
-    auto type = meta::cpp2::_PropertyType_VALUES_TO_NAMES.at(col.get_type());
+    auto type = apache::thrift::util::enumNameSafe(col.get_type());
     if (col.get_type() == meta::cpp2::PropertyType::FIXED_STRING) {
-        return folly::stringPrintf("%s(%d)", type, *col.get_type_length());
+        return folly::stringPrintf("%s(%d)", type.c_str(), *col.get_type_length());
     }
     return type;
 }
diff --git a/src/util/ToJson.cpp b/src/util/ToJson.cpp
index f7ee060ab1cdb03b307825e31abf1a8d8dbbdea7..f3ea4c0b204e388b2672f59d0f642ac2f761524b 100644
--- a/src/util/ToJson.cpp
+++ b/src/util/ToJson.cpp
@@ -9,6 +9,7 @@
 #include <folly/String.h>
 #include <folly/dynamic.h>
 #include <string>
+#include <thrift/lib/cpp/util/EnumUtils.h>
 
 #include "common/clients/meta/MetaClient.h"
 #include "common/datatypes/Value.h"
@@ -67,11 +68,11 @@ std::string toJson(const Expression *expr) {
 
 folly::dynamic toJson(const meta::cpp2::SpaceDesc &desc) {
     folly::dynamic obj = folly::dynamic::object();
-    obj.insert("name", desc.space_name);
-    obj.insert("partNum", desc.partition_num);
-    obj.insert("replicaFactor", desc.replica_factor);
-    obj.insert("charset", desc.charset_name);
-    obj.insert("collate", desc.collate_name);
+    obj.insert("name", *desc.space_name_ref());
+    obj.insert("partNum", *desc.partition_num_ref());
+    obj.insert("replicaFactor", *desc.replica_factor_ref());
+    obj.insert("charset", *desc.charset_name_ref());
+    obj.insert("collate", *desc.collate_name_ref());
     obj.insert("vidType", graph::SchemaUtil::typeToString(desc.get_vid_type()));
     return obj;
 }
@@ -79,16 +80,16 @@ folly::dynamic toJson(const meta::cpp2::SpaceDesc &desc) {
 folly::dynamic toJson(const meta::cpp2::ColumnDef &column) {
     folly::dynamic obj = folly::dynamic::object();
     obj.insert("name", column.get_name());
-    obj.insert("type", meta::cpp2::_PropertyType_VALUES_TO_NAMES.at(column.get_type().get_type()));
-    if (column.type.__isset.type_length) {
-        obj.insert("typeLength", folly::to<std::string>(*column.get_type().get_type_length()));
+    obj.insert("type", apache::thrift::util::enumNameSafe(column.get_type().get_type()));
+    if (column.type.type_length_ref().has_value()) {
+        obj.insert("typeLength", folly::to<std::string>(*column.get_type().type_length_ref()));
     }
-    if (column.__isset.nullable) {
-        obj.insert("nullable", folly::to<std::string>(*column.get_nullable()));
+    if (column.nullable_ref().has_value()) {
+        obj.insert("nullable", folly::to<std::string>(*column.nullable_ref()));
     }
-    if (column.__isset.default_value) {
+    if (column.default_value_ref().has_value()) {
         graph::QueryExpressionContext ctx;
-        auto value = Expression::decode(*column.get_default_value());
+        auto value = Expression::decode(*column.default_value_ref());
         obj.insert("defaultValue", value->toString());
     }
     return obj;
@@ -96,83 +97,83 @@ folly::dynamic toJson(const meta::cpp2::ColumnDef &column) {
 
 folly::dynamic toJson(const meta::cpp2::Schema &schema) {
     folly::dynamic json = folly::dynamic::object();
-    if (schema.__isset.columns) {
-        json.insert("columns", toJson(schema.get_columns()));
+    if (schema.columns_ref().is_set()) {
+        json.insert("columns", toJson(*schema.columns_ref()));
     }
-    if (schema.__isset.schema_prop) {
-        json.insert("prop", toJson(schema.get_schema_prop()));
+    if (schema.schema_prop_ref().is_set()) {
+        json.insert("prop", toJson(*schema.schema_prop_ref()));
     }
     return json;
 }
 
 folly::dynamic toJson(const meta::cpp2::SchemaProp &prop) {
     folly::dynamic object = folly::dynamic::object();
-    if (prop.__isset.ttl_col) {
-        object.insert("ttlCol", *prop.get_ttl_col());
+    if (prop.ttl_col_ref().has_value()) {
+        object.insert("ttlCol", *prop.ttl_col_ref());
     }
-    if (prop.__isset.ttl_duration) {
-        object.insert("ttlDuration", *prop.get_ttl_duration());
+    if (prop.ttl_duration_ref()) {
+        object.insert("ttlDuration", *prop.ttl_duration_ref());
     }
     return object;
 }
 
 folly::dynamic toJson(const meta::cpp2::AlterSchemaItem &item) {
     folly::dynamic json = folly::dynamic::object();
-    if (item.__isset.schema) {
-        json.insert("schema", toJson(item.get_schema()));
+    if (item.schema_ref().is_set()) {
+        json.insert("schema", toJson(*item.schema_ref()));
     }
-    if (item.__isset.op) {
-        json.insert("op", meta::cpp2::_AlterSchemaOp_VALUES_TO_NAMES.at(item.get_op()));
+    if (item.op_ref().is_set()) {
+        json.insert("op", apache::thrift::util::enumNameSafe(*item.op_ref()));
     }
     return json;
 }
 
 folly::dynamic toJson(const storage::cpp2::EdgeKey &edgeKey) {
     folly::dynamic edgeKeyObj = folly::dynamic::object();
-    if (edgeKey.__isset.src) {
-        edgeKeyObj.insert("src", toJson(edgeKey.get_src()));
+    if (edgeKey.src_ref().is_set()) {
+        edgeKeyObj.insert("src", toJson(*edgeKey.src_ref()));
     }
-    if (edgeKey.__isset.dst) {
-        edgeKeyObj.insert("dst", toJson(edgeKey.get_dst()));
+    if (edgeKey.dst_ref().is_set()) {
+        edgeKeyObj.insert("dst", toJson(*edgeKey.dst_ref()));
     }
-    if (edgeKey.__isset.edge_type) {
-        edgeKeyObj.insert("edgeType", edgeKey.get_edge_type());
+    if (edgeKey.edge_type_ref().is_set()) {
+        edgeKeyObj.insert("edgeType", *edgeKey.edge_type_ref());
     }
-    if (edgeKey.__isset.ranking) {
-        edgeKeyObj.insert("ranking", edgeKey.get_ranking());
+    if (edgeKey.ranking_ref().is_set()) {
+        edgeKeyObj.insert("ranking", *edgeKey.ranking_ref());
     }
     return edgeKeyObj;
 }
 
 folly::dynamic toJson(const storage::cpp2::NewTag &tag) {
     folly::dynamic tagObj = folly::dynamic::object();
-    if (tag.__isset.tag_id) {
-        tagObj.insert("tagId", tag.get_tag_id());
+    if (tag.tag_id_ref().is_set()) {
+        tagObj.insert("tagId", *tag.tag_id_ref());
     }
-    if (tag.__isset.props) {
-        tagObj.insert("props", toJson(tag.get_props()));
+    if (tag.props_ref().is_set()) {
+        tagObj.insert("props", toJson(*tag.props_ref()));
     }
     return tagObj;
 }
 
 folly::dynamic toJson(const storage::cpp2::NewVertex &vert) {
     folly::dynamic vertObj = folly::dynamic::object();
-    if (vert.__isset.id) {
-        vertObj.insert("id", toJson(vert.get_id()));
+    if (vert.id_ref().is_set()) {
+        vertObj.insert("id", toJson(*vert.id_ref()));
     }
-    if (vert.__isset.tags) {
-        vertObj.insert("tags", util::toJson(vert.get_tags()));
+    if (vert.tags_ref().is_set()) {
+        vertObj.insert("tags", util::toJson(*vert.tags_ref()));
     }
     return vertObj;
 }
 
 folly::dynamic toJson(const storage::cpp2::NewEdge &edge) {
     folly::dynamic edgeObj = folly::dynamic::object();
-    if (edge.__isset.key) {
-        edgeObj.insert("key", toJson(edge.get_key()));
+    if (edge.key_ref().is_set()) {
+        edgeObj.insert("key", toJson(*edge.key_ref()));
     }
-    if (edge.__isset.props) {
-        edgeObj.insert("props", toJson(edge.get_props()));
+    if (edge.props_ref().is_set()) {
+        edgeObj.insert("props", toJson(*edge.props_ref()));
     }
     return edgeObj;
 }
@@ -183,60 +184,60 @@ folly::dynamic toJson(const storage::cpp2::UpdatedProp &prop) {
 
 folly::dynamic toJson(const storage::cpp2::OrderBy &orderBy) {
     folly::dynamic obj = folly::dynamic::object();
-    if (orderBy.__isset.direction) {
-        auto dir = orderBy.get_direction();
-        obj.insert("direction", storage::cpp2::_OrderDirection_VALUES_TO_NAMES.at(dir));
+    if (orderBy.direction_ref().is_set()) {
+        auto dir = *orderBy.direction_ref();
+        obj.insert("direction", apache::thrift::util::enumNameSafe(dir));
     }
-    if (orderBy.__isset.prop) {
-        obj.insert("prop", orderBy.get_prop());
+    if (orderBy.prop_ref().is_set()) {
+        obj.insert("prop", *orderBy.prop_ref());
     }
     return obj;
 }
 
 folly::dynamic toJson(const storage::cpp2::VertexProp &prop) {
     folly::dynamic obj = folly::dynamic::object();
-    if (prop.__isset.tag) {
-        auto tag = prop.get_tag();
+    if (prop.tag_ref().is_set()) {
+        auto tag = *prop.tag_ref();
         obj.insert("tagId", tag);
     }
-    if (prop.__isset.props) {
-        obj.insert("props", toJson(prop.get_props()));
+    if (prop.props_ref().is_set()) {
+        obj.insert("props", toJson(*prop.props_ref()));
     }
     return obj;
 }
 
 folly::dynamic toJson(const storage::cpp2::EdgeProp &prop) {
     folly::dynamic obj = folly::dynamic::object();
-    if (prop.__isset.type) {
-        obj.insert("type", toJson(prop.get_type()));
+    if (prop.type_ref().is_set()) {
+        obj.insert("type", toJson(*prop.type_ref()));
     }
-    if (prop.__isset.props) {
-        obj.insert("props", toJson(prop.get_props()));
+    if (prop.props_ref().is_set()) {
+        obj.insert("props", toJson(*prop.props_ref()));
     }
     return obj;
 }
 
 folly::dynamic toJson(const storage::cpp2::StatProp &prop) {
     folly::dynamic obj = folly::dynamic::object();
-    if (prop.__isset.alias) {
-        obj.insert("alias", prop.get_alias());
+    if (prop.alias_ref().is_set()) {
+        obj.insert("alias", *prop.alias_ref());
     }
-    if (prop.__isset.prop) {
-        obj.insert("prop", prop.get_prop());
+    if (prop.prop_ref().is_set()) {
+        obj.insert("prop", *prop.prop_ref());
     }
-    if (prop.__isset.stat) {
-        obj.insert("stat", storage::cpp2::_StatType_VALUES_TO_NAMES.at(prop.get_stat()));
+    if (prop.stat_ref().is_set()) {
+        obj.insert("stat", apache::thrift::util::enumNameSafe(*prop.stat_ref()));
     }
     return obj;
 }
 
 folly::dynamic toJson(const storage::cpp2::Expr &expr) {
     folly::dynamic obj = folly::dynamic::object();
-    if (expr.__isset.alias) {
-        obj.insert("alias", expr.get_alias());
+    if (expr.alias_ref().is_set()) {
+        obj.insert("alias", *expr.alias_ref());
     }
-    if (expr.__isset.expr) {
-        obj.insert("expr", expr.get_expr());
+    if (expr.expr_ref().is_set()) {
+        obj.insert("expr", *expr.expr_ref());
     }
     return obj;
 }
@@ -253,7 +254,7 @@ folly::dynamic toJson(const storage::cpp2::IndexQueryContext &iqc) {
 folly::dynamic toJson(const storage::cpp2::IndexColumnHint &hints) {
     folly::dynamic obj = folly::dynamic::object();
     obj.insert("column", hints.get_column_name());
-    auto scanType = storage::cpp2::_ScanType_VALUES_TO_NAMES.at(hints.get_scan_type());
+    auto scanType = apache::thrift::util::enumNameSafe(hints.get_scan_type());
     obj.insert("scanType", scanType);
     auto rtrim = [](const std::string &str) { return std::string(str.c_str()); };
     auto begin = toJson(hints.get_begin_value());
diff --git a/src/util/test/CMakeLists.txt b/src/util/test/CMakeLists.txt
index aeabd61504c70d49ebcc490c39d538a83f742368..441240a12811a3340470ab3aa856cd88e33ab8af 100644
--- a/src/util/test/CMakeLists.txt
+++ b/src/util/test/CMakeLists.txt
@@ -45,5 +45,5 @@ nebula_add_test(
         gtest
         gtest_main
         ${THRIFT_LIBRARIES}
-        proxygenlib
+        ${PROXYGEN_LIBRARIES}
 )
diff --git a/src/validator/AdminValidator.cpp b/src/validator/AdminValidator.cpp
index fcad805a06f8051370e286e49ab2097c6238e232..5251699f24f402bbc4beecc8d061f604e0620dbc 100644
--- a/src/validator/AdminValidator.cpp
+++ b/src/validator/AdminValidator.cpp
@@ -4,6 +4,8 @@
 * attached with Common Clause Condition 1.0, found in the LICENSES directory.
 */
 
+#include <thrift/lib/cpp/util/EnumUtils.h>
+
 #include "validator/AdminValidator.h"
 
 #include "common/base/Base.h"
@@ -21,22 +23,22 @@ Status CreateSpaceValidator::validateImpl() {
     auto sentence = static_cast<CreateSpaceSentence*>(sentence_);
     ifNotExist_ = sentence->isIfNotExist();
     auto status = Status::OK();
-    spaceDesc_.space_name = std::move(*(sentence->spaceName()));
+    spaceDesc_.set_space_name(std::move(*(sentence->spaceName())));
     StatusOr<std::string> retStatusOr;
     std::string result;
     auto* charsetInfo = qctx_->getCharsetInfo();
     for (auto &item : sentence->getOpts()) {
         switch (item->getOptType()) {
             case SpaceOptItem::PARTITION_NUM: {
-                spaceDesc_.partition_num = item->getPartitionNum();
-                if (spaceDesc_.partition_num <= 0) {
+                spaceDesc_.set_partition_num(item->getPartitionNum());
+                if (*spaceDesc_.partition_num_ref() <= 0) {
                     return Status::SemanticError("Partition_num value should be greater than zero");
                 }
                 break;
             }
             case SpaceOptItem::REPLICA_FACTOR: {
-                spaceDesc_.replica_factor = item->getReplicaFactor();
-                if (spaceDesc_.replica_factor <= 0) {
+                spaceDesc_.set_replica_factor(item->getReplicaFactor());
+                if (*spaceDesc_.replica_factor_ref() <= 0) {
                     return Status::SemanticError(
                         "Replica_factor value should be greater than zero");
                 }
@@ -48,23 +50,23 @@ Status CreateSpaceValidator::validateImpl() {
                     typeDef.type != meta::cpp2::PropertyType::FIXED_STRING) {
                     std::stringstream ss;
                     ss << "Only support FIXED_STRING or INT64 vid type, but was given "
-                       << meta::cpp2::_PropertyType_VALUES_TO_NAMES.at(typeDef.type);
+                       << apache::thrift::util::enumNameSafe(typeDef.type);
                     return Status::SemanticError(ss.str());
                 }
-                spaceDesc_.vid_type.set_type(typeDef.type);
+                spaceDesc_.vid_type_ref().value().set_type(typeDef.type);
 
                 if (typeDef.type == meta::cpp2::PropertyType::INT64) {
-                    spaceDesc_.vid_type.set_type_length(8);
+                    spaceDesc_.vid_type_ref().value().set_type_length(8);
                 } else {
-                    if (!typeDef.__isset.type_length) {
+                    if (!typeDef.type_length_ref().has_value()) {
                         return Status::SemanticError(
                             "type length is not set for fixed string type");
                     }
-                    if (*typeDef.get_type_length() <= 0) {
+                    if (*typeDef.type_length_ref() <= 0) {
                         return Status::SemanticError("Vid size should be a positive number: %d",
-                                                     *typeDef.get_type_length());
+                                                     *typeDef.type_length_ref());
                     }
-                    spaceDesc_.vid_type.set_type_length(*typeDef.get_type_length());
+                    spaceDesc_.vid_type_ref().value().set_type_length(*typeDef.type_length_ref());
                 }
                 break;
             }
@@ -72,14 +74,14 @@ Status CreateSpaceValidator::validateImpl() {
                 result = item->getCharset();
                 folly::toLowerAscii(result);
                 NG_RETURN_IF_ERROR(charsetInfo->isSupportCharset(result));
-                spaceDesc_.charset_name = std::move(result);
+                spaceDesc_.set_charset_name(std::move(result));
                 break;
             }
             case SpaceOptItem::COLLATE: {
                 result = item->getCollate();
                 folly::toLowerAscii(result);
                 NG_RETURN_IF_ERROR(charsetInfo->isSupportCollate(result));
-                spaceDesc_.collate_name = std::move(result);
+                spaceDesc_.set_collate_name(std::move(result));
                 break;
             }
             case SpaceOptItem::ATOMIC_EDGE: {
@@ -98,24 +100,24 @@ Status CreateSpaceValidator::validateImpl() {
     }
 
     // if charset and collate are not specified, set default value
-    if (!spaceDesc_.charset_name.empty() && !spaceDesc_.collate_name.empty()) {
-        NG_RETURN_IF_ERROR(charsetInfo->charsetAndCollateMatch(spaceDesc_.charset_name,
-                    spaceDesc_.collate_name));
-    } else if (!spaceDesc_.charset_name.empty()) {
-        retStatusOr = charsetInfo->getDefaultCollationbyCharset(spaceDesc_.charset_name);
+    if (!(*spaceDesc_.charset_name_ref()).empty() && !(*spaceDesc_.collate_name_ref()).empty()) {
+        NG_RETURN_IF_ERROR(charsetInfo->charsetAndCollateMatch(*spaceDesc_.charset_name_ref(),
+                    *spaceDesc_.collate_name_ref()));
+    } else if (!(*spaceDesc_.charset_name_ref()).empty()) {
+        retStatusOr = charsetInfo->getDefaultCollationbyCharset(*spaceDesc_.charset_name_ref());
         if (!retStatusOr.ok()) {
             return retStatusOr.status();
         }
-        spaceDesc_.collate_name = std::move(retStatusOr.value());
-    } else if (!spaceDesc_.collate_name.empty()) {
-        retStatusOr = charsetInfo->getCharsetbyCollation(spaceDesc_.collate_name);
+        spaceDesc_.set_collate_name(std::move(retStatusOr.value()));
+    } else if (!(*spaceDesc_.collate_name_ref()).empty()) {
+        retStatusOr = charsetInfo->getCharsetbyCollation(*spaceDesc_.collate_name_ref());
         if (!retStatusOr.ok()) {
             return retStatusOr.status();
         }
-        spaceDesc_.charset_name = std::move(retStatusOr.value());
+        spaceDesc_.set_charset_name(std::move(retStatusOr.value()));
     }
 
-    if (spaceDesc_.charset_name.empty() && spaceDesc_.collate_name.empty()) {
+    if ((*spaceDesc_.charset_name_ref()).empty() && (*spaceDesc_.collate_name_ref()).empty()) {
         std::string charsetName = FLAGS_default_charset;
         folly::toLowerAscii(charsetName);
         NG_RETURN_IF_ERROR(charsetInfo->isSupportCharset(charsetName));
@@ -124,15 +126,15 @@ Status CreateSpaceValidator::validateImpl() {
         folly::toLowerAscii(collateName);
         NG_RETURN_IF_ERROR(charsetInfo->isSupportCollate(collateName));
 
-        spaceDesc_.charset_name = std::move(charsetName);
-        spaceDesc_.collate_name = std::move(collateName);
+        spaceDesc_.set_charset_name(std::move(charsetName));
+        spaceDesc_.set_collate_name(std::move(collateName));
 
-        NG_RETURN_IF_ERROR(charsetInfo->charsetAndCollateMatch(spaceDesc_.charset_name,
-                    spaceDesc_.collate_name));
+        NG_RETURN_IF_ERROR(charsetInfo->charsetAndCollateMatch(*spaceDesc_.charset_name_ref(),
+                    *spaceDesc_.collate_name_ref()));
     }
 
     // add to validate context
-    vctx_->addSpace(spaceDesc_.space_name);
+    vctx_->addSpace(*spaceDesc_.space_name_ref());
     return status;
 }
 
diff --git a/src/validator/GoValidator.cpp b/src/validator/GoValidator.cpp
index bfaf3b83d1dcf1d24b31aa042cf13e7fc405af9f..8dae770af698eeca2ce1c4a4d1c4d9d842903ac6 100644
--- a/src/validator/GoValidator.cpp
+++ b/src/validator/GoValidator.cpp
@@ -613,9 +613,9 @@ GetNeighbors::VertexProps GoValidator::buildSrcVertexProps() {
                        vertexProps->begin(),
                        [](auto& tag) {
                            storage::cpp2::VertexProp vp;
-                           vp.tag = tag.first;
+                           vp.set_tag(tag.first);
                            std::vector<std::string> props(tag.second.begin(), tag.second.end());
-                           vp.props = std::move(props);
+                           vp.set_props(std::move(props));
                            return vp;
                        });
     }
@@ -630,9 +630,9 @@ std::vector<storage::cpp2::VertexProp> GoValidator::buildDstVertexProps() {
                        vertexProps.begin(),
                        [](auto& tag) {
                            storage::cpp2::VertexProp vp;
-                           vp.tag = tag.first;
+                           vp.set_tag(tag.first);
                            std::vector<std::string> props(tag.second.begin(), tag.second.end());
-                           vp.props = std::move(props);
+                           vp.set_props(std::move(props));
                            return vp;
                        });
     }
@@ -676,7 +676,7 @@ void GoValidator::buildEdgeProps(GetNeighbors::EdgeProps& edgeProps, bool isInEd
 
         const auto& propsFound = exprProps_.edgeProps().find(e);
         if (propsFound == exprProps_.edgeProps().end()) {
-            ep.props = {kDst};
+            ep.set_props({kDst});
         } else {
             std::vector<std::string> props(propsFound->second.begin(), propsFound->second.end());
             if (needJoin && propsFound->second.find(kDst) == propsFound->second.end()) {
diff --git a/src/validator/LookupValidator.cpp b/src/validator/LookupValidator.cpp
index 1d08ff850d6b2873f13caeb1d0801f8791239603..5404c2540c88f459107a77175ac4efc5912b850d 100644
--- a/src/validator/LookupValidator.cpp
+++ b/src/validator/LookupValidator.cpp
@@ -233,7 +233,7 @@ StatusOr<std::vector<std::string>> LookupValidator::textSearch(TextSearchExpress
     if (*expr->arg()->from() != from_) {
         return Status::SemanticError("Schema name error : %s", expr->arg()->from()->c_str());
     }
-    auto index = nebula::plugin::IndexTraits::indexName(space_.spaceDesc.space_name, isEdge_);
+    auto index = plugin::IndexTraits::indexName(*space_.spaceDesc.space_name_ref(), isEdge_);
     nebula::plugin::DocItem doc(index, *expr->arg()->prop(), schemaId_, *expr->arg()->val());
     nebula::plugin::LimitItem limit(expr->arg()->timeout(), expr->arg()->limit());
     std::vector<std::string> result;
@@ -442,9 +442,9 @@ Status LookupValidator::checkTSService() {
     for (const auto& c : tcs.value()) {
         nebula::plugin::HttpClient hc;
         hc.host = c.host;
-        if (c.__isset.user && c.__isset.pwd) {
-            hc.user = c.user;
-            hc.password = c.pwd;
+        if (c.user_ref().has_value() && c.pwd_ref().has_value()) {
+            hc.user = *c.user_ref();
+            hc.password = *c.pwd_ref();
         }
         esClients_.emplace_back(std::move(hc));
     }
diff --git a/src/validator/MaintainValidator.cpp b/src/validator/MaintainValidator.cpp
index 0b45038d68d457f788ddb4889352531b645ed9ce..f9c597c8e2a545c4711f07146f07e3546a4114c3 100644
--- a/src/validator/MaintainValidator.cpp
+++ b/src/validator/MaintainValidator.cpp
@@ -52,7 +52,7 @@ Status SchemaValidator::validateColumns(const std::vector<ColumnSpecification *>
             // some expression is evaluable but not pure so only fold instead of eval here
             column.set_default_value(ExpressionUtils::foldConstantExpr(defaultValueExpr)->encode());
         }
-        schema.columns.emplace_back(std::move(column));
+        schema.columns_ref().value().emplace_back(std::move(column));
     }
 
     return Status::OK();
@@ -152,7 +152,7 @@ Status AlterValidator::alterSchema(const std::vector<AlterSchemaOptItem *> &sche
             for (auto &colName : colNames) {
                 meta::cpp2::ColumnDef column;
                 column.name = *colName;
-                schema.columns.emplace_back(std::move(column));
+                schema.columns_ref().value().emplace_back(std::move(column));
             }
         } else {
             const auto &specs = schemaOpt->columnSpecs();
diff --git a/src/validator/MutateValidator.cpp b/src/validator/MutateValidator.cpp
index 3a0b3f32c369c73dc06bc150c58469240ba48b85..f67003ba7108485a513c5a58eae382af85d72f8e 100644
--- a/src/validator/MutateValidator.cpp
+++ b/src/validator/MutateValidator.cpp
@@ -147,7 +147,9 @@ Status InsertEdgesValidator::validateImpl() {
 }
 
 Status InsertEdgesValidator::toPlan() {
-    auto useChainInsert = space_.spaceDesc.isolation_level == meta::cpp2::IsolationLevel::TOSS;
+    using IsoLevel = meta::cpp2::IsolationLevel;
+    auto isoLevel = space_.spaceDesc.isolation_level_ref().value_or(IsoLevel::DEFAULT);
+    auto useChainInsert = isoLevel == IsoLevel::TOSS;
     auto doNode = InsertEdges::make(qctx_,
                                     nullptr,
                                     spaceId_,
@@ -188,7 +190,9 @@ Status InsertEdgesValidator::check() {
 }
 
 Status InsertEdgesValidator::prepareEdges() {
-    auto useToss = space_.spaceDesc.isolation_level == meta::cpp2::IsolationLevel::TOSS;
+    using IsoLevel = meta::cpp2::IsolationLevel;
+    auto isoLevel = space_.spaceDesc.isolation_level_ref().value_or(IsoLevel::DEFAULT);
+    auto useToss = isoLevel == IsoLevel::TOSS;
     auto size = useToss ? rows_.size() : rows_.size() * 2;
     edges_.reserve(size);
     for (auto i = 0u; i < rows_.size(); i++) {
@@ -229,22 +233,22 @@ Status InsertEdgesValidator::prepareEdges() {
         auto valsRet = SchemaUtil::toValueVec(row->values());
         NG_RETURN_IF_ERROR(valsRet);
         auto props = std::move(valsRet).value();
-        // outbound
         storage::cpp2::NewEdge edge;
-        edge.key.set_src(srcId);
-        edge.key.set_dst(dstId);
-        edge.key.set_ranking(rank);
-        edge.key.set_edge_type(edgeType_);
+        storage::cpp2::EdgeKey key;
+
+        key.set_src(srcId);
+        key.set_dst(dstId);
+        key.set_edge_type(edgeType_);
+        key.set_ranking(rank);
+        edge.set_key(key);
         edge.set_props(std::move(props));
-        edge.__isset.key = true;
-        edge.__isset.props = true;
         edges_.emplace_back(edge);
-
         if (!useToss) {
             // inbound
-            edge.key.set_src(dstId);
-            edge.key.set_dst(srcId);
-            edge.key.set_edge_type(-edgeType_);
+            key.set_src(dstId);
+            key.set_dst(srcId);
+            key.set_edge_type(-edgeType_);
+            edge.set_key(key);
             edges_.emplace_back(std::move(edge));
         }
     }
@@ -330,10 +334,10 @@ Status DeleteVerticesValidator::toPlan() {
 
         storage::cpp2::EdgeProp edgeProp;
         edgeProp.set_type(edgeTypes_[index]);
-        edgeProp.props.emplace_back(kSrc);
-        edgeProp.props.emplace_back(kDst);
-        edgeProp.props.emplace_back(kType);
-        edgeProp.props.emplace_back(kRank);
+        edgeProp.props_ref().value().emplace_back(kSrc);
+        edgeProp.props_ref().value().emplace_back(kDst);
+        edgeProp.props_ref().value().emplace_back(kType);
+        edgeProp.props_ref().value().emplace_back(kRank);
         edgeProps.emplace_back(edgeProp);
 
         edgeProp.set_type(-edgeTypes_[index]);
@@ -683,7 +687,9 @@ Status UpdateEdgeValidator::toPlan() {
                                      {},
                                      condition_,
                                      {});
-    auto useToss = space_.spaceDesc.isolation_level == meta::cpp2::IsolationLevel::TOSS;
+    using IsoLevel = meta::cpp2::IsolationLevel;
+    auto isoLevel = space_.spaceDesc.isolation_level_ref().value_or(IsoLevel::DEFAULT);
+    auto useToss = isoLevel == IsoLevel::TOSS;
     if (useToss) {
         root_ = outNode;
         tail_ = root_;
diff --git a/src/validator/TraversalValidator.cpp b/src/validator/TraversalValidator.cpp
index 95a27aec88137ad75d99a54ea7927fcd749f02ab..7ed5be3f46154550590d0c8c1d4239034ad21a8e 100644
--- a/src/validator/TraversalValidator.cpp
+++ b/src/validator/TraversalValidator.cpp
@@ -4,6 +4,7 @@
  * attached with Common Clause Condition 1.0, found in the LICENSES directory.
  */
 
+#include <thrift/lib/cpp/util/EnumUtils.h>
 #include "validator/TraversalValidator.h"
 #include "common/expression/VariableExpression.h"
 #include "util/SchemaUtil.h"
@@ -28,11 +29,11 @@ Status TraversalValidator::validateStarts(const VerticesClause* clause, Starts&
         if (!type.ok()) {
             return type.status();
         }
-        auto vidType = space_.spaceDesc.vid_type.get_type();
+        auto vidType = space_.spaceDesc.vid_type_ref().value().get_type();
         if (type.value() != SchemaUtil::propTypeToValueType(vidType)) {
             std::stringstream ss;
             ss << "`" << src->toString() << "', the srcs should be type of "
-                << meta::cpp2::_PropertyType_VALUES_TO_NAMES.at(vidType) << ", but was`"
+                << apache::thrift::util::enumNameSafe(vidType) << ", but was`"
                 << type.value() << "'";
             return Status::SemanticError(ss.str());
         }
@@ -52,10 +53,10 @@ Status TraversalValidator::validateStarts(const VerticesClause* clause, Starts&
                         expr->toString().c_str());
             }
             auto vid = expr->eval(ctx(nullptr));
-            auto vidType = space_.spaceDesc.vid_type.get_type();
+            auto vidType = space_.spaceDesc.vid_type_ref().value().get_type();
             if (!SchemaUtil::isValidVid(vid, vidType)) {
                 std::stringstream ss;
-                ss << "Vid should be a " << meta::cpp2::_PropertyType_VALUES_TO_NAMES.at(vidType);
+                ss << "Vid should be a " << apache::thrift::util::enumNameSafe(vidType);
                 return Status::SemanticError(ss.str());
             }
             starts.vids.emplace_back(std::move(vid));
diff --git a/src/validator/Validator.cpp b/src/validator/Validator.cpp
index 818b6b670001a2f07625c9f7c64948c8041f5384..c734805d442c870c4b28bf0fb00f059659ddca78 100644
--- a/src/validator/Validator.cpp
+++ b/src/validator/Validator.cpp
@@ -307,10 +307,11 @@ Status Validator::validate() {
 
     if (!noSpaceRequired_) {
         space_ = vctx_->whichSpace();
-        VLOG(1) << "Space chosen, name: " << space_.spaceDesc.space_name << " id: " << space_.id;
+        VLOG(1) << "Space chosen, name: " << space_.spaceDesc.space_name_ref().value()
+                << " id: " << space_.id;
     }
 
-    auto vidType = space_.spaceDesc.vid_type.get_type();
+    auto vidType = space_.spaceDesc.vid_type_ref().value().type_ref().value();
     vidType_ = SchemaUtil::propTypeToValueType(vidType);
 
     NG_RETURN_IF_ERROR(validateImpl());
diff --git a/src/validator/test/CMakeLists.txt b/src/validator/test/CMakeLists.txt
index 0934d88689f8745fdbbbfb08f63519e3e230348f..d6f06b766a5fbac72683dfeb9cb6feeec4272d5c 100644
--- a/src/validator/test/CMakeLists.txt
+++ b/src/validator/test/CMakeLists.txt
@@ -78,7 +78,5 @@ nebula_add_test(
     LIBRARIES
         gtest
         ${THRIFT_LIBRARIES}
-        wangle
-        proxygenhttpserver
-        proxygenlib
+        ${PROXYGEN_LIBRARIES}
 )
diff --git a/src/validator/test/MockIndexManager.cpp b/src/validator/test/MockIndexManager.cpp
index 2991589ef87c68ad1e759be970812de221c320b7..2064e31a07fe9fa69d0458158e925d50d19e69bd 100644
--- a/src/validator/test/MockIndexManager.cpp
+++ b/src/validator/test/MockIndexManager.cpp
@@ -39,7 +39,7 @@ void MockIndexManager::init() {
     type.set_type_length(32);
     field.set_type(std::move(type));
     book_name_index.set_fields({});
-    book_name_index.fields.emplace_back(std::move(field));
+    book_name_index.fields_ref().value().emplace_back(std::move(field));
 
     tagIndexes_.emplace(1, std::vector<std::shared_ptr<meta::cpp2::IndexItem>>{});
     tagIndexes_[1].emplace_back(
diff --git a/src/validator/test/ValidatorTestBase.h b/src/validator/test/ValidatorTestBase.h
index 7c4c1a47acd89a5f6456cc2cb4b729818ce2f2b4..08a40e41701a41c05b98b67519b48d11e4e7a727 100644
--- a/src/validator/test/ValidatorTestBase.h
+++ b/src/validator/test/ValidatorTestBase.h
@@ -34,7 +34,7 @@ protected:
         SpaceInfo spaceInfo;
         spaceInfo.name = "test_space";
         spaceInfo.id = 1;
-        spaceInfo.spaceDesc.space_name = "test_space";
+        spaceInfo.spaceDesc.set_space_name("test_space");
         session_->setSpace(std::move(spaceInfo));
         schemaMng_ = CHECK_NOTNULL(MockSchemaManager::makeUnique());
         indexMng_ = CHECK_NOTNULL(MockIndexManager::makeUnique());
diff --git a/src/visitor/DeduceTypeVisitor.cpp b/src/visitor/DeduceTypeVisitor.cpp
index e1ddd573d74b39bab4436695fbb8da52ad128add..3a3f2ffcb3978b2acdc1c6a0a4215d0245b04794 100644
--- a/src/visitor/DeduceTypeVisitor.cpp
+++ b/src/visitor/DeduceTypeVisitor.cpp
@@ -105,7 +105,7 @@ DeduceTypeVisitor::DeduceTypeVisitor(QueryContext *qctx,
     if (!vctx->spaceChosen()) {
         vidType_ = Value::Type::__EMPTY__;
     } else {
-        auto vidType = vctx_->whichSpace().spaceDesc.vid_type.get_type();
+        auto vidType = vctx_->whichSpace().spaceDesc.vid_type_ref().value().get_type();
         vidType_ = SchemaUtil::propTypeToValueType(vidType);
     }
 }
diff --git a/src/visitor/test/CMakeLists.txt b/src/visitor/test/CMakeLists.txt
index fb9a87f14b923f95c266d9536cf71ac75386181c..d8aa20abcadaffd26687d8d7fec93e29fee0e2e2 100644
--- a/src/visitor/test/CMakeLists.txt
+++ b/src/visitor/test/CMakeLists.txt
@@ -54,7 +54,5 @@ nebula_add_test(
     LIBRARIES
         gtest
         ${THRIFT_LIBRARIES}
-        wangle
-        proxygenhttpserver
-        proxygenlib
+        ${PROXYGEN_LIBRARIES}
 )