diff --git a/src/executor/test/FetchEdgesTest.cpp b/src/executor/test/FetchEdgesTest.cpp
index 26f5c07e5750a5afa4de0eaad4c7f2cc15f540db..77f2074fdc6c87790821a49d4826c8846e06d74c 100644
--- a/src/executor/test/FetchEdgesTest.cpp
+++ b/src/executor/test/FetchEdgesTest.cpp
@@ -35,6 +35,12 @@ TEST_F(FetchEdgesTest, base) {
         auto query = folly::stringPrintf(fmt, player.vid(), team.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"serve.start_year"}, {"serve.end_year"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<int64_t, int64_t>> expected = {
             {std::get<1>(serve), std::get<2>(serve)},
         };
@@ -50,6 +56,12 @@ TEST_F(FetchEdgesTest, base) {
         auto query = folly::stringPrintf(fmt, player.vid(), team.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"(serve.start_year>2001)"}, {"serve.end_year"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<bool, int64_t>> expected = {
             {std::get<1>(serve) > 2001, std::get<2>(serve)},
         };
@@ -65,6 +77,12 @@ TEST_F(FetchEdgesTest, base) {
         auto query = folly::stringPrintf(fmt, player.vid(), team.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"serve.start_year"}, {"serve.end_year"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<int64_t, int64_t>> expected = {
             {std::get<1>(serve), std::get<2>(serve)},
         };
@@ -83,6 +101,12 @@ TEST_F(FetchEdgesTest, base) {
                 fmt, player.vid(), team0.vid(), player.vid(), team1.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"serve.start_year"}, {"serve.end_year"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<int64_t, int64_t>> expected = {
             {std::get<1>(serve0), std::get<2>(serve0)},
             {std::get<1>(serve1), std::get<2>(serve1)},
@@ -98,6 +122,12 @@ TEST_F(FetchEdgesTest, base) {
         auto query = folly::stringPrintf(fmt, player.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"serve.start_year"}, {"serve.end_year"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<int64_t, int64_t>> expected;
         for (auto &serve : player.serves()) {
             std::tuple<int64_t, int64_t> result(std::get<1>(serve), std::get<2>(serve));
@@ -115,6 +145,12 @@ TEST_F(FetchEdgesTest, base) {
         auto query = folly::stringPrintf(fmt, player.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"serve.start_year"}, {"serve.end_year"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<int64_t, int64_t>> expected;
         for (auto &serve : player.serves()) {
             std::tuple<int64_t, int64_t> result(std::get<1>(serve), std::get<2>(serve));
@@ -149,6 +185,12 @@ TEST_F(FetchEdgesTest, noYield) {
         auto query = folly::stringPrintf(fmt, player.vid(), team.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"serve.start_year"}, {"serve.end_year"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<int64_t, int64_t>> expected = {
             {std::get<1>(serve), std::get<2>(serve)},
         };
@@ -163,6 +205,12 @@ TEST_F(FetchEdgesTest, noYield) {
         auto query = folly::stringPrintf(fmt, player.vid(), team.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"serve.start_year"}, {"serve.end_year"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<int64_t, int64_t>> expected = {
             {std::get<1>(serve), std::get<2>(serve)},
         };
@@ -177,6 +225,12 @@ TEST_F(FetchEdgesTest, noYield) {
         auto query = folly::stringPrintf(fmt, player.name().c_str(), team.name().c_str());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"serve.start_year"}, {"serve.end_year"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<int64_t, int64_t>> expected = {
             {std::get<1>(serve), std::get<2>(serve)},
         };
@@ -196,6 +250,12 @@ TEST_F(FetchEdgesTest, distinct) {
                 fmt, player.vid(), team.vid(), player.vid(), team.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"serve.start_year"}, {"serve.end_year"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<int64_t, int64_t>> expected = {
             {std::get<1>(serve), std::get<2>(serve)},
         };
@@ -210,6 +270,12 @@ TEST_F(FetchEdgesTest, distinct) {
         auto query = folly::stringPrintf(fmt, player.vid(), player.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"serve.start_year"}, {"serve.end_year"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<int64_t, int64_t>> expected;
         for (auto &serve : player.serves()) {
             std::tuple<int64_t, int64_t> result(std::get<1>(serve), std::get<2>(serve));
@@ -227,6 +293,12 @@ TEST_F(FetchEdgesTest, distinct) {
         auto query = folly::stringPrintf(fmt, player.vid(), player.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"serve.start_year"}, {"serve.end_year"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<int64_t, int64_t>> expected;
         for (auto &serve : player.serves()) {
             std::tuple<int64_t, int64_t> result(std::get<1>(serve), std::get<2>(serve));
@@ -244,6 +316,12 @@ TEST_F(FetchEdgesTest, distinct) {
         auto query = folly::stringPrintf(fmt, tim.vid(), tony.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"serve._dst"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<int64_t>> expected = {
             {teams_["Spurs"].vid()},
             {teams_["Hornets"].vid()},
diff --git a/src/executor/test/FetchVerticesTest.cpp b/src/executor/test/FetchVerticesTest.cpp
index 33b017a0ab427732684f686b3da4e5215fb3e01c..3d57bf79a24886038444d17542894a5fb821a4d9 100644
--- a/src/executor/test/FetchVerticesTest.cpp
+++ b/src/executor/test/FetchVerticesTest.cpp
@@ -33,6 +33,12 @@ TEST_F(FetchVerticesTest, base) {
         auto query = folly::stringPrintf(fmt, player.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"player.name"}, {"player.age"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<std::string, int64_t>> expected = {
             {player.name(), player.age()},
         };
@@ -46,6 +52,12 @@ TEST_F(FetchVerticesTest, base) {
         auto query = folly::stringPrintf(fmt, player.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"player.name"}, {"player.age"}, {"(player.age>30)"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<std::string, int64_t, bool>> expected = {
             {player.name(), player.age(), player.age() > 30},
         };
@@ -59,6 +71,12 @@ TEST_F(FetchVerticesTest, base) {
         auto query = folly::stringPrintf(fmt, player.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"player.name"}, {"player.age"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<std::string, int64_t>> expected = {
             {"Tony Parker", players_["Tony Parker"].age()},
             {"Tim Duncan", players_["Tim Duncan"].age()},
@@ -73,6 +91,12 @@ TEST_F(FetchVerticesTest, base) {
         auto query = folly::stringPrintf(fmt, player.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"player.name"}, {"player.age"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<std::string, int64_t>> expected = {
             {"Tony Parker", players_["Tony Parker"].age()},
             {"Tim Duncan", players_["Tim Duncan"].age()},
@@ -88,6 +112,12 @@ TEST_F(FetchVerticesTest, base) {
         auto query = folly::stringPrintf(fmt, player.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"name"}, {"player.age"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<std::string, int64_t>> expected = {
             {"Tim Duncan", players_["Tim Duncan"].age()},
             {"Tony Parker", players_["Tony Parker"].age()},
@@ -102,6 +132,12 @@ TEST_F(FetchVerticesTest, base) {
         auto query = folly::stringPrintf(fmt, player.name().c_str());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"player.name"}, {"player.age"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<std::string, int64_t>> expected = {
             {player.name(), player.age()},
         };
@@ -117,6 +153,12 @@ TEST_F(FetchVerticesTest, noYield) {
         auto query = folly::stringPrintf(fmt, player.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"player.name"}, {"player.age"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<std::string, int64_t>> expected = {
             {player.name(), player.age()},
         };
@@ -129,6 +171,12 @@ TEST_F(FetchVerticesTest, noYield) {
         auto query = folly::stringPrintf(fmt, player.name().c_str());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"player.name"}, {"player.age"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<std::string, int64_t>> expected = {
             {player.name(), player.age()},
         };
@@ -145,6 +193,12 @@ TEST_F(FetchVerticesTest, distinct) {
         auto query = folly::stringPrintf(fmt, player.vid(), player.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"player.name"}, {"player.age"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<std::string, int64_t>> expected = {
             {player.name(), player.age()},
         };
@@ -159,6 +213,12 @@ TEST_F(FetchVerticesTest, distinct) {
         auto query = folly::stringPrintf(fmt, boris.vid(), tony.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"player.age"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<int64_t>> expected = {
             {boris.age()},
         };
diff --git a/src/executor/test/GoTest.cpp b/src/executor/test/GoTest.cpp
index e7a758f4376382a12ec54a915e388ae0d09e53cc..9f55a7e46d3ed0e574e49ee5fdb484725814622b 100644
--- a/src/executor/test/GoTest.cpp
+++ b/src/executor/test/GoTest.cpp
@@ -34,6 +34,12 @@ TEST_F(GoTest, OneStepOutBound) {
         auto query = folly::stringPrintf(fmt, players_["Tim Duncan"].vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"id"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<int64_t>> expected = {
             {teams_["Spurs"].vid()},
         };
@@ -47,6 +53,12 @@ TEST_F(GoTest, OneStepOutBound) {
         auto query = folly::stringPrintf(fmt, player.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"$^.player.name"}, {"serve.start_year"}, {"serve.end_year"}, {"$$.team.name"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<std::string, int64_t, int64_t, std::string>> expected = {
             {player.name(), 2003, 2005, "Hawks"},
             {player.name(), 2005, 2008, "Suns"},
@@ -65,6 +77,12 @@ TEST_F(GoTest, OneStepOutBound) {
         auto query = folly::stringPrintf(fmt, player.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"$^.player.name"}, {"serve.start_year"}, {"serve.end_year"}, {"$$.team.name"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<std::string, int64_t, int64_t, std::string>> expected = {
             {player.name(), 2014, 2015, "Mavericks"},
             {player.name(), 2015, 2016, "Kings"},
@@ -81,6 +99,12 @@ TEST_F(GoTest, OneStepOutBound) {
         auto query = folly::stringPrintf(fmt, player.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"id"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<int64_t>> expected = {
             {teams_["Spurs"].vid()},
             {teams_["Spurs"].vid()},
@@ -100,6 +124,12 @@ TEST_F(GoTest, OneStepOutBound) {
         auto query = folly::stringPrintf(fmt, player.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"id"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<int64_t>> expected = {
             {teams_["Spurs"].vid()},
             {teams_["Spurs"].vid()},
@@ -123,6 +153,12 @@ TEST_F(GoTest, AssignmentSimple) {
         auto query = folly::stringPrintf(fmt, player.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"id"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<uint64_t>> expected = {
             {players_["Tracy McGrady"].vid()},
             {players_["LaMarcus Aldridge"].vid()},
@@ -141,6 +177,12 @@ TEST_F(GoTest, AssignmentPipe) {
         auto query = folly::stringPrintf(fmt, player.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"id"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<uint64_t>> expected = {
             {players_["Kobe Bryant"].vid()},
             {players_["Grant Hill"].vid()},
@@ -237,6 +279,12 @@ TEST_F(GoTest, Distinct) {
         auto query = folly::stringPrintf(fmt, player.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"serve._dst"}, {"$$.team.name"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<int64_t, std::string>> expected = {
             {teams_["Spurs"].vid(), "Spurs"},
             {teams_["Hornets"].vid(), "Hornets"},
@@ -323,6 +371,12 @@ TEST_F(GoTest, ReferencePipeInYieldAndWhere) {
                             "YIELD $-.name, $^.player.name, $$.player.name";
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"$-.name"}, {"$^.player.name"}, {"$$.player.name"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<uniform_tuple_t<std::string, 3>> expected = {
             {"Tim Duncan", "Manu Ginobili", "Tim Duncan"},
             {"Tim Duncan", "Tony Parker", "LaMarcus Aldridge"},
@@ -347,6 +401,12 @@ TEST_F(GoTest, ReferencePipeInYieldAndWhere) {
                             "YIELD $-.name, $^.player.name, $$.player.name";
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"$-.name"}, {"$^.player.name"}, {"$$.player.name"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<uniform_tuple_t<std::string, 3>> expected = {
             {"Tim Duncan", "Tony Parker", "LaMarcus Aldridge"},
             {"Tim Duncan", "Tony Parker", "Manu Ginobili"},
@@ -370,6 +430,12 @@ TEST_F(GoTest, ReferenceVariableInYieldAndWhere) {
                             "YIELD $var.name, $^.player.name, $$.player.name";
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"$var.name"}, {"$^.player.name"}, {"$$.player.name"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<uniform_tuple_t<std::string, 3>> expected = {
             {"Tim Duncan", "Manu Ginobili", "Tim Duncan"},
             {"Tim Duncan", "Tony Parker", "LaMarcus Aldridge"},
@@ -394,6 +460,12 @@ TEST_F(GoTest, ReferenceVariableInYieldAndWhere) {
                             "YIELD $var.name, $^.player.name, $$.player.name";
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"$var.name"}, {"$^.player.name"}, {"$$.player.name"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<uniform_tuple_t<std::string, 3>> expected = {
             {"Tim Duncan", "Tony Parker", "LaMarcus Aldridge"},
             {"Tim Duncan", "Tony Parker", "Manu Ginobili"},
diff --git a/src/executor/test/OrderByTest.cpp b/src/executor/test/OrderByTest.cpp
index c0828bf57c93797a38c26e75f584b3edf443c71b..0b9a8954a7652e3505e8baeeb66553e9165ee565 100644
--- a/src/executor/test/OrderByTest.cpp
+++ b/src/executor/test/OrderByTest.cpp
@@ -100,6 +100,12 @@ TEST_F(OrderByTest, SingleFactor) {
         auto query = folly::stringPrintf(fmt.c_str(), player.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"name"}, {"start"}, {"team"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<std::string, int64_t, std::string>> expected = {
             {player.name(), 2003, "Hawks"},
             {player.name(), 2008, "Hornets"},
@@ -116,6 +122,12 @@ TEST_F(OrderByTest, SingleFactor) {
         auto query = folly::stringPrintf(fmt.c_str(), player.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"name"}, {"start"}, {"team"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<std::string, int64_t, std::string>> expected = {
             {player.name(), 2008, "Hornets"},
             {player.name(), 2003, "Hawks"},
@@ -132,6 +144,12 @@ TEST_F(OrderByTest, SingleFactor) {
         auto query = folly::stringPrintf(fmt.c_str(), player.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"name"}, {"start"}, {"team"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<std::string, int64_t, std::string>> expected = {
             {player.name(), 2003, "Hawks"},
             {player.name(), 2008, "Hornets"},
@@ -148,6 +166,12 @@ TEST_F(OrderByTest, SingleFactor) {
         auto query = folly::stringPrintf(fmt.c_str(), player.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"name"}, {"start"}, {"team"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<std::string, int64_t, std::string>> expected = {
             {player.name(), 2005, "Suns"},
             {player.name(), 2012, "Spurs"},
@@ -171,6 +195,12 @@ TEST_F(OrderByTest, MultiFactors) {
         auto query = folly::stringPrintf(fmt.c_str(), boris.vid(), aldridge.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"team"}, {"player"}, {"age"}, {"start"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<std::string, std::string, int64_t, int64_t>> expected = {
             {"Jazz", boris.name(), 36, 2016},
             {"Spurs", aldridge.name(), 33, 2015},
@@ -186,6 +216,12 @@ TEST_F(OrderByTest, MultiFactors) {
         auto query = folly::stringPrintf(fmt.c_str(), boris.vid(), aldridge.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"team"}, {"player"}, {"age"}, {"start"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<std::string, std::string, int64_t, int64_t>> expected = {
             {"Jazz", boris.name(), 36, 2016},
             {"Spurs", boris.name(), 36, 2012},
@@ -201,6 +237,12 @@ TEST_F(OrderByTest, MultiFactors) {
         auto query = folly::stringPrintf(fmt.c_str(), boris.vid(), aldridge.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"team"}, {"player"}, {"age"}, {"start"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<std::string, std::string, int64_t, int64_t>> expected = {
             {"Spurs", aldridge.name(), 33, 2015},
             {"Spurs", boris.name(), 36, 2012},
@@ -216,6 +258,12 @@ TEST_F(OrderByTest, MultiFactors) {
         auto query = folly::stringPrintf(fmt.c_str(), boris.vid(), aldridge.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"team"}, {"player"}, {"age"}, {"start"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<std::string, std::string, int64_t, int64_t>> expected = {
             {"Spurs", boris.name(), 36, 2012},
             {"Spurs", aldridge.name(), 33, 2015},
@@ -231,6 +279,12 @@ TEST_F(OrderByTest, MultiFactors) {
         auto query = folly::stringPrintf(fmt.c_str(), boris.vid(), aldridge.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"team"}, {"player"}, {"age"}, {"start"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<std::string, std::string, int64_t, int64_t>> expected = {
             {"Spurs", boris.name(), 36, 2012},
             {"Spurs", aldridge.name(), 33, 2015},
@@ -248,6 +302,12 @@ TEST_F(OrderByTest, InterimResult) {
         auto query = folly::stringPrintf(fmt, boris.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"id"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<int64_t>> expected = {
             teams_["Spurs"].vid(),
             teams_["Spurs"].vid(),
diff --git a/src/executor/test/SetTest.cpp b/src/executor/test/SetTest.cpp
index 88519907a66e3187de470a9869f38e3b6f027a1b..359a664abaf1bd6a669c0947471b5f95da4ff53e 100644
--- a/src/executor/test/SetTest.cpp
+++ b/src/executor/test/SetTest.cpp
@@ -37,6 +37,12 @@ TEST_F(SetTest, UnionAllTest) {
         auto query = folly::stringPrintf(fmt, tim.vid(), tony.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"$^.player.name"}, {"serve.start_year"}, {"$$.team.name"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<std::string, int64_t, std::string>> expected;
         for (auto &serve : tim.serves()) {
             std::tuple<std::string, int64_t, std::string> record(
@@ -62,6 +68,12 @@ TEST_F(SetTest, UnionAllTest) {
         auto &manu = players_["Manu Ginobili"];
         auto query = folly::stringPrintf(fmt, tim.vid(), tony.vid(), manu.vid());
         auto code = client_->execute(query, resp);
+
+        std::vector<std::string> expectedColNames{
+            {"$^.player.name"}, {"serve.start_year"}, {"$$.team.name"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
         std::vector<std::tuple<std::string, int64_t, std::string>> expected;
         for (auto &serve : tim.serves()) {
@@ -92,6 +104,12 @@ TEST_F(SetTest, UnionAllTest) {
         auto query = folly::stringPrintf(fmt, tim.vid(), tony.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"$^.player.name"}, {"serve.start_year"}, {"$$.team.name"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<std::string, int64_t, std::string>> expected;
         for (auto &like : tim.likes()) {
             auto &player = players_[std::get<0>(like)];
@@ -119,6 +137,12 @@ TEST_F(SetTest, UnionAllTest) {
         auto query = folly::stringPrintf(fmt, tim.vid(), tony.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"$^.player.name"}, {"serve.start_year"}, {"$$.team.name"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<std::string, int64_t, std::string>> expected;
         for (auto &like : tim.likes()) {
             auto &player = players_[std::get<0>(like)];
@@ -146,6 +170,12 @@ TEST_F(SetTest, UnionAllTest) {
         auto query = folly::stringPrintf(fmt, tony.vid(), tim.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"$^.player.name"}, {"serve.start_year"}, {"$$.team.name"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<std::string, int64_t, std::string>> expected;
         for (auto &like : tim.likes()) {
             auto &player = players_[std::get<0>(like)];
@@ -173,6 +203,12 @@ TEST_F(SetTest, UnionAllTest) {
         auto query = folly::stringPrintf(fmt, tony.vid(), tim.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"$^.player.name"}, {"serve.start_year"}, {"$$.team.name"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<std::string, int64_t, std::string>> expected;
         for (auto &like : tim.likes()) {
             auto &player = players_[std::get<0>(like)];
@@ -199,6 +235,12 @@ TEST_F(SetTest, UnionAllTest) {
         auto query = folly::stringPrintf(fmt, tony.vid(), tim.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"$^.player.name"}, {"serve.start_year"}, {"$$.team.name"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<std::string, int64_t, std::string>> expected;
         for (auto &like : tim.likes()) {
             auto &player = players_[std::get<0>(like)];
@@ -230,6 +272,12 @@ TEST_F(SetTest, UnionAllTest) {
         auto query = folly::stringPrintf(fmt, tim.vid(), tony.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"name"}, {"player"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<std::string, std::string>> expected;
         for (auto &serve : tim.serves()) {
             std::tuple<std::string, std::string> record(
@@ -260,6 +308,12 @@ TEST_F(SetTest, UnionDistinct) {
         auto query = folly::stringPrintf(fmt, tim.vid(), tony.vid(), manu.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"$^.player.name"}, {"serve.start_year"}, {"$$.team.name"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<std::string, int64_t, std::string>> expected;
         for (auto &like : tim.likes()) {
             auto &player = players_[std::get<0>(like)];
@@ -282,6 +336,12 @@ TEST_F(SetTest, UnionDistinct) {
         auto query = folly::stringPrintf(fmt, tim.vid(), tony.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"$^.player.name"}, {"serve.start_year"}, {"$$.team.name"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<std::string, int64_t, std::string>> expected;
         for (auto &like : tim.likes()) {
             auto &player = players_[std::get<0>(like)];
@@ -307,6 +367,12 @@ TEST_F(SetTest, Minus) {
         auto query = folly::stringPrintf(fmt, tim.vid(), tony.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"$^.player.name"}, {"serve.start_year"}, {"$$.team.name"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<std::string, int64_t, std::string>> expected;
         for (auto &like : tim.likes()) {
             auto &player = players_[std::get<0>(like)];
@@ -335,6 +401,12 @@ TEST_F(SetTest, Intersect) {
         auto query = folly::stringPrintf(fmt, tim.vid(), tony.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"$^.player.name"}, {"serve.start_year"}, {"$$.team.name"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<std::string, int64_t, std::string>> expected;
         for (auto &serve : tony.serves()) {
             std::tuple<std::string, int64_t, std::string> record(
@@ -362,6 +434,12 @@ TEST_F(SetTest, Mix) {
         auto query = folly::stringPrintf(fmt, tim.vid(), tony.vid(), tim.vid(), manu.vid());
         auto code = client_->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"$^.player.name"}, {"serve.start_year"}, {"$$.team.name"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<std::string, int64_t, std::string>> expected;
         for (auto &serve : manu.serves()) {
             std::tuple<std::string, int64_t, std::string> record(
diff --git a/src/executor/test/TestBase.h b/src/executor/test/TestBase.h
index 8974cd5b0b27504dbf66bebb9707a7a8175b3bb8..379e31a46dc363f2c3e08bafa74ab0126515a7f2 100644
--- a/src/executor/test/TestBase.h
+++ b/src/executor/test/TestBase.h
@@ -222,6 +222,39 @@ protected:
         return TestOK();
     }
 
+    AssertionResult verifyColNames(const cpp2::ExecutionResponse &resp,
+                                   std::vector<std::string> &expectedColNames) {
+        if (resp.get_error_code() != cpp2::ErrorCode::SUCCEEDED) {
+            auto *errmsg = resp.get_error_msg();
+            return TestError() << "Query failed with `"
+                               << static_cast<int32_t>(resp.get_error_code())
+                               << (errmsg == nullptr ? "'" : "': " + *errmsg);
+        }
+
+        if (resp.get_column_names() == nullptr && expectedColNames.empty()) {
+            return TestOK();
+        }
+
+        if (resp.get_column_names() != nullptr) {
+            auto colNames = *(resp.get_column_names());
+            if (colNames.size() != expectedColNames.size()) {
+                return TestError() << "Column size not match: "
+                                   << colNames.size() << " vs. " << expectedColNames.size();
+            }
+            for (decltype(colNames.size()) i = 0; i < colNames.size(); ++i) {
+                if (colNames[i] != expectedColNames[i]) {
+                    return TestError() << colNames[i] << " vs. " << expectedColNames[i]
+                                       << ", index: " << i;
+                }
+            }
+        } else {
+            return TestError() << "Response has no column names.";
+        }
+
+        return TestOK();
+    }
+
+
 protected:
 };
 
diff --git a/src/executor/test/YieldTest.cpp b/src/executor/test/YieldTest.cpp
index b6087eb9fa5c79c82c77b7e4312cfed21bee9e80..94788f057415011a79bbd099711c0215deb71f85 100644
--- a/src/executor/test/YieldTest.cpp
+++ b/src/executor/test/YieldTest.cpp
@@ -33,6 +33,12 @@ TEST_F(YieldTest, Basic) {
         std::string query = "YIELD 1";
         auto code = client->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+
+        std::vector<std::string> expectedColNames{
+            {"1"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
+
         std::vector<std::tuple<int64_t>> expected{
             {1}
         };
@@ -43,6 +49,10 @@ TEST_F(YieldTest, Basic) {
         std::string query = "YIELD 1+1, '1+1', (int)3.14, (string)(1+1), (string)true";
         auto code = client->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+        std::vector<std::string> expectedColNames{
+            {"(1+1)"}, {"\"1+1\""}, {"(int)3.140000"}, {"(string)(1+1)"}, {"(string)true"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
         std::vector<std::tuple<int64_t, std::string, int64_t, std::string, std::string>> expected{
             {2, "1+1", 3, "2", "true"}
         };
@@ -53,6 +63,10 @@ TEST_F(YieldTest, Basic) {
         std::string query = "YIELD \"Hello\", hash(\"Hello\")";
         auto code = client->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+        std::vector<std::string> expectedColNames{
+            {"\"Hello\""}, {"hash(\"Hello\")"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
         std::vector<std::tuple<std::string, int64_t>> expected{
             {"Hello", std::hash<std::string>()("Hello")}
         };
@@ -68,6 +82,10 @@ TEST_F(YieldTest, hashCall) {
         std::string query = "YIELD hash(\"Boris\")";
         auto code = client->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+        std::vector<std::string> expectedColNames{
+            {"hash(\"Boris\")"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
         std::vector<std::tuple<int64_t>> expected{
             std::hash<std::string>{}("Boris")
         };
@@ -77,6 +95,10 @@ TEST_F(YieldTest, hashCall) {
         cpp2::ExecutionResponse resp;
         std::string query = "YIELD hash(123)";
         auto code = client->execute(query, resp);
+        std::vector<std::string> expectedColNames{
+            {"hash(123)"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
         std::vector<std::tuple<int64_t>> expected{
             std::hash<int64_t>{}(123)
@@ -88,6 +110,10 @@ TEST_F(YieldTest, hashCall) {
         std::string query = "YIELD hash(123 + 456)";
         auto code = client->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+        std::vector<std::string> expectedColNames{
+            {"hash((123+456))"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
         std::vector<std::tuple<int64_t>> expected{
             std::hash<int64_t>{}(123 + 456)
         };
@@ -98,6 +124,10 @@ TEST_F(YieldTest, hashCall) {
         std::string query = "YIELD hash(123.0)";
         auto code = client->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+        std::vector<std::string> expectedColNames{
+            {"hash(123.000000)"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
         std::vector<std::tuple<int64_t>> expected{
             std::hash<double>{}(123.0)
         };
@@ -108,6 +138,10 @@ TEST_F(YieldTest, hashCall) {
         std::string query = "YIELD hash(!0)";
         auto code = client->execute(query, resp);
         ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
+        std::vector<std::string> expectedColNames{
+            {"hash(!(0))"}
+        };
+        ASSERT_TRUE(verifyColNames(resp, expectedColNames));
         std::vector<std::tuple<int64_t>> expected{
             std::hash<bool>{}(!0)
         };