diff --git a/ci/test.sh b/ci/test.sh
index 1de5e9b1dafe1f72fa28d205748a88d4e57beae0..25bc6cbd07f120052860bfb3983aded5c7e4d894 100755
--- a/ci/test.sh
+++ b/ci/test.sh
@@ -79,6 +79,7 @@ function run_test() {
     # CI
     cd $BUILD_DIR/tests
     ./ntr -h
+    #./ntr $PROJ_DIR/tests/admin/* $PROJ_DIR/tests/maintain/* $PROJ_DIR/tests/query/stateless/test_schema.py
 }
 
 case "$1" in
diff --git a/tests/admin/test_space.py b/tests/admin/test_space.py
new file mode 100644
index 0000000000000000000000000000000000000000..9bf47ef6f72766c40b8dc027a89989f51a88daa0
--- /dev/null
+++ b/tests/admin/test_space.py
@@ -0,0 +1,199 @@
+# --coding:utf-8--
+#
+# Copyright (c) 2020 vesoft inc. All rights reserved.
+#
+# This source code is licensed under Apache 2.0 License,
+# attached with Common Clause Condition 1.0, found in the LICENSES directory.
+
+import time
+import re
+
+from nebula_test_common.nebula_test_suite import NebulaTestSuite
+
+
+class TestSpace(NebulaTestSuite):
+
+    @classmethod
+    def prepare(self):
+        pass
+
+    @classmethod
+    def cleanup(self):
+        pass
+
+    def test_space(self):
+        # not exist
+        resp = self.client.execute('USE not_exist_space')
+        self.check_resp_failed(resp)
+
+        # with default options
+        resp = self.client.execute('CREATE SPACE space_with_default_options')
+        self.check_resp_succeeded(resp)
+
+        # check result
+        resp = self.client.execute_query('DESC SPACE space_with_default_options')
+        expect_result = [['space_with_default_options', 100, 1, 8, 'utf8', 'utf8_bin']]
+        self.check_result(resp, expect_result, {0})
+
+        # drop space
+        resp = self.client.execute('DROP SPACE space_with_default_options')
+        self.check_resp_succeeded(resp)
+
+        # create space succeeded
+        resp = self.client.execute('CREATE SPACE default_space(partition_num=9, replica_factor=1)')
+        self.check_resp_succeeded(resp)
+
+        # show spaces
+        resp = self.client.execute_query('SHOW SPACES')
+        self.check_resp_succeeded(resp)
+        self.search_result(resp, [['default_space']])
+
+        # desc space
+        resp = self.client.execute_query('DESC SPACE default_space')
+        self.check_resp_succeeded(resp)
+        expect_result = [['default_space', 9, 1, 8, 'utf8', 'utf8_bin']]
+        self.check_result(resp, expect_result, {0})
+
+        # show create space
+        resp = self.client.execute_query('SHOW CREATE SPACE default_space')
+        self.check_resp_succeeded(resp)
+
+        create_space_str = 'CREATE SPACE `default_space` ('\
+                           'partition_num = 9, '\
+                           'replica_factor = 1, '\
+                           'vid_size = 8, '\
+                           'charset = utf8, '\
+                           'collate = utf8_bin)';
+
+        expect_result = [['default_space', create_space_str]]
+        self.check_result(resp, expect_result)
+
+        # check result from show create
+        resp = self.client.execute('DROP SPACE default_space')
+        self.check_resp_succeeded(resp)
+
+
+        resp = self.client.execute(create_space_str)
+        self.check_resp_succeeded(resp)
+
+        resp = self.client.execute_query('SHOW SPACES')
+        self.check_resp_succeeded(resp)
+
+        # 2.0 when use space, the validator get from cache
+        time.sleep(self.delay)
+        resp = self.client.execute("USE default_space")
+        self.check_resp_succeeded(resp)
+
+    def test_charset_collate(self):
+        resp = self.client.execute('CREATE SPACE space_charset_collate (partition_num=9, '
+                                   'replica_factor=1, charset=utf8, collate=utf8_bin)')
+        self.check_resp_succeeded(resp)
+
+        resp = self.client.execute_query('DESC SPACE space_charset_collate')
+        self.check_resp_succeeded(resp)
+        expect_result = [['space_charset_collate', 9, 1, 8, 'utf8', 'utf8_bin']]
+        self.check_result(resp, expect_result, {0})
+
+        # drop space
+        resp = self.client.execute('DROP SPACE space_charset_collate')
+        self.check_resp_succeeded(resp)
+
+        resp = self.client.execute('CREATE SPACE space_charset (partition_num=9, '
+                                   'replica_factor=1, charset=utf8)')
+        self.check_resp_succeeded(resp)
+
+        resp = self.client.execute_query('DESC SPACE space_charset')
+        self.check_resp_succeeded(resp)
+        expect_result = [['space_charset', 9, 1, 8, 'utf8', 'utf8_bin']]
+        self.check_result(resp, expect_result, {0})
+
+        # drop space
+        resp = self.client.execute('DROP SPACE space_charset')
+        self.check_resp_succeeded(resp)
+
+        resp = self.client.execute('CREATE SPACE space_collate (partition_num=9, '
+                                   'replica_factor=1, collate=utf8_bin)')
+        self.check_resp_succeeded(resp)
+
+        resp = self.client.execute_query('DESC SPACE space_collate')
+        self.check_resp_succeeded(resp)
+        expect_result = [['space_collate', 9, 1, 8, 'utf8', 'utf8_bin']]
+        self.check_result(resp, expect_result, {0})
+
+        # drop space
+        resp = self.client.execute('DROP SPACE space_collate')
+        self.check_resp_succeeded(resp)
+
+        # not supported collate
+        resp = self.client.execute('CREATE SPACE space_charset_collate_nomatch (partition_num=9, '
+                                   'replica_factor=1, charset = utf8, collate=gbk_bin)')
+        self.check_resp_failed(resp)
+
+        # not supported charset
+        resp = self.client.execute_query('CREATE SPACE space_charset_collate_nomatch (partition_num=9, '
+                                         'replica_factor=1, charset = gbk, collate=utf8_bin)')
+        self.check_resp_failed(resp)
+
+        # not supported charset
+        resp = self.client.execute_query('CREATE SPACE space_illegal_charset (partition_num=9, '
+                                         'replica_factor=1, charset = gbk)')
+        self.check_resp_failed(resp)
+
+        # not supported collate
+        resp = self.client.execute_query('CREATE SPACE space_illegal_collate (partition_num=9, '
+                                         'replica_factor=1, collate = gbk_bin)')
+        self.check_resp_failed(resp)
+
+        resp = self.client.execute('CREATE SPACE space_illegal_collate (partition_num=9, '
+                                   'replica_factor=1, collate = gbk_bin)')
+        self.check_resp_failed(resp)
+
+        resp = self.client.execute('CREATE SPACE space_capital (partition_num=9, '
+                                   'replica_factor=1, charset=UTF8, collate=UTF8_bin)')
+        self.check_resp_succeeded(resp)
+
+        resp = self.client.execute_query('DESC SPACE space_capital')
+        self.check_resp_succeeded(resp)
+        expect_result = [['space_capital', 9, 1, 8, 'utf8', 'utf8_bin']]
+        self.check_result(resp, expect_result, {0})
+
+        # drop space
+        resp = self.client.execute('DROP SPACE space_capital')
+        self.check_resp_succeeded(resp)
+
+    def test_if_not_exists_and_if_exist(self):
+        # exist then failed
+        resp = self.client.execute('CREATE SPACE default_space')
+        self.check_resp_failed(resp)
+
+        # exist but success
+        resp = self.client.execute('CREATE SPACE IF NOT EXISTS default_space')
+        self.check_resp_succeeded(resp)
+
+        # not exist but success
+        resp = self.client.execute('DROP SPACE IF EXISTS not_exist_space')
+        self.check_resp_succeeded(resp)
+
+        # not exist then failed
+        resp = self.client.execute('DROP SPACE not_exist_space')
+        self.check_resp_failed(resp)
+
+        resp = self.client.execute('CREATE SPACE exist_space')
+        self.check_resp_succeeded(resp)
+
+        resp = self.client.execute('DROP SPACE IF EXISTS exist_space')
+        self.check_resp_succeeded(resp)
+
+    def test_drop_space(self):
+        resp = self.client.execute_query('SHOW SPACES')
+        self.check_resp_succeeded(resp)
+        expect_result = [['default_space']]
+        self.search_result(resp, expect_result)
+
+        resp = self.client.execute('DROP SPACE default_space')
+        self.check_resp_succeeded(resp)
+
+        resp = self.client.execute_query('SHOW SPACES')
+        self.check_resp_succeeded(resp)
+        expect_result = []
+        self.check_result(resp, expect_result)
diff --git a/tests/maintain/test_comments.py b/tests/maintain/test_comments.py
new file mode 100644
index 0000000000000000000000000000000000000000..4d3d6ac0b2469aba5aef67f66eab9e66e3b805d8
--- /dev/null
+++ b/tests/maintain/test_comments.py
@@ -0,0 +1,28 @@
+# --coding:utf-8--
+#
+# Copyright (c) 2020 vesoft inc. All rights reserved.
+#
+# This source code is licensed under Apache 2.0 License,
+# attached with Common Clause Condition 1.0, found in the LICENSES directory.
+
+from nebula_test_common.nebula_test_suite import NebulaTestSuite
+
+
+class TestComment(NebulaTestSuite):
+
+    @classmethod
+    def prepare(self):
+        pass
+
+    @classmethod
+    def cleanup(self):
+        pass
+
+    def test_comment(self):
+        # Test command is comment
+        resp = self.client.execute('# CREATE TAG TAG1')
+        self.check_resp_succeeded(resp)
+
+        # Test command is comment
+        resp = self.client.execute('SHOW SPACES # show all spaces')
+        self.check_resp_succeeded(resp)
diff --git a/tests/maintain/test_tag_edge.py b/tests/maintain/test_tag_edge.py
new file mode 100644
index 0000000000000000000000000000000000000000..242ee74e8aad38460e5ccb8755f05e7aaf435cae
--- /dev/null
+++ b/tests/maintain/test_tag_edge.py
@@ -0,0 +1,555 @@
+# --coding:utf-8--
+#
+# Copyright (c) 2020 vesoft inc. All rights reserved.
+#
+# This source code is licensed under Apache 2.0 License,
+# attached with Common Clause Condition 1.0, found in the LICENSES directory.
+
+import time
+
+from nebula_test_common.nebula_test_suite import NebulaTestSuite
+
+
+class TestSchema(NebulaTestSuite):
+
+    @classmethod
+    def prepare(self):
+        resp = self.client.execute('CREATE SPACE tag_space(partition_num=9)')
+        self.check_resp_succeeded(resp)
+
+        time.sleep(self.delay)
+        resp = self.client.execute('USE tag_space')
+        self.check_resp_succeeded(resp)
+
+    @classmethod
+    def cleanup(self):
+        resp = self.execute('DROP SPACE tag_space;DROP SPACE my_space')
+        self.check_resp_succeeded(resp)
+
+    def test_tag(self):
+        # empty prop
+        resp = self.client.execute('CREATE TAG tag1()')
+        self.check_resp_succeeded(resp)
+
+        # if not exists
+        resp = self.client.execute('CREATE TAG IF NOT EXISTS tag1()')
+        self.check_resp_succeeded(resp)
+
+        # check result
+        resp = self.client.execute_query('DESCRIBE TAG tag1')
+        self.check_resp_succeeded(resp)
+        expect_result = []
+        self.check_result(resp, expect_result)
+
+        # alter
+        resp = self.client.execute('ALTER TAG tag1 ADD (id int, name string)')
+        self.check_resp_succeeded(resp)
+
+        # check result, 2.0 add null and DEFAULT
+        resp = self.client.execute_query('DESCRIBE TAG tag1')
+        self.check_resp_succeeded(resp)
+        expect_result = [['id', 'int64', 'YES', 'EMPTY'], ['name', 'string', 'YES', 'EMPTY']]
+        self.check_result(resp, expect_result)
+
+        # create tag succeed
+        resp = self.client.execute('CREATE TAG person(name string, email string DEFAULT "NULL", '
+                                   'age int, gender string, row_timestamp timestamp DEFAULT 2020)')
+        self.check_resp_succeeded(resp)
+
+        # Create Tag with duplicate field, failed
+        resp = self.client.execute('CREATE TAG duplicate_tag(name string, name int)')
+        self.check_resp_failed(resp)
+
+        # Create Tag with duplicate field, failed
+        resp = self.client.execute('CREATE TAG duplicate_tag(name string, name string)')
+        self.check_resp_failed(resp)
+
+        # Create Tag with DEFAULT value
+        resp = self.client.execute('CREATE TAG person_with_default(name string, age int DEFAULT 18)')
+        self.check_resp_succeeded(resp)
+
+        # Create Tag with wrong type DEFAULT value, failed
+        resp = self.client.execute('CREATE TAG person_type_mismatch'
+                                   '(name string, age int DEFAULT "hello")')
+        self.check_resp_failed(resp)
+
+        # test DESCRIBE
+        resp = self.client.execute_query('DESCRIBE TAG person')
+        self.check_resp_succeeded(resp)
+        expect_result = [['name', 'string', 'YES', 'EMPTY'],
+                         ['email', 'string', 'YES', 'NULL'],
+                         ['age', 'int64', 'YES', 'EMPTY'],
+                         ['gender', 'string', 'YES', 'EMPTY'],
+                         ['row_timestamp', 'timestamp', 'YES', 2020]]
+        # timestamp has not support
+        # self.check_result(resp, expect_result)
+
+        # test DESC
+        resp = self.client.execute_query('DESCRIBE TAG person')
+        self.check_resp_succeeded(resp)
+        expect_result = [['name', 'string', 'YES', 'EMPTY'],
+                         ['email', 'string', 'YES', 'NULL'],
+                         ['age', 'int64', 'YES', 'EMPTY'],
+                         ['gender', 'string', 'YES', 'EMPTY'],
+                         ['row_timestamp', 'timestamp', 'YES', 2020]]
+        # timestamp has not support
+        # self.check_result(resp, expect_result)
+
+        # test show create tag
+        resp = self.client.execute_query('SHOW CREATE TAG person')
+        self.check_resp_succeeded(resp)
+        create_tag_str = 'CREATE TAG `person` (\n' \
+                         '  `name` string NULL,\n' \
+                         '  `email` string NULL DEFAULT "NULL",\n' \
+                         '  `age` int64 NULL,\n' \
+                         '  `gender` string NULL,\n' \
+                         '  `row_timestamp` timestamp NULL DEFAULT 2020\n' \
+                         ') ttl_duration = 0, ttl_col = ""'
+        # timestamp has not support
+        expect_result = [['person', create_tag_str]]
+        # self.check_result(resp, expect_result)
+
+        # check result
+        resp = self.client.execute('DROP TAG person')
+        self.check_resp_succeeded(resp)
+
+        resp = self.client.execute(create_tag_str)
+        self.check_resp_succeeded(resp)
+
+        # describe tag not exist
+        resp = self.client.execute_query('DESCRIBE TAG not_exist')
+        self.check_resp_failed(resp)
+
+        # unreserved keyword
+        resp = self.client.execute('CREATE TAG upper(name string, ACCOUNT string, '
+                                         'age int, gender string, row_timestamp timestamp DEFAULT 100)')
+        self.check_resp_succeeded(resp)
+
+        # check result
+        resp = self.client.execute_query('DESCRIBE TAG upper')
+        self.check_resp_succeeded(resp)
+        expect_result = [['name', 'string', 'YES', 'EMPTY'],
+                         ['account', 'string', 'YES', 'EMPTY'],
+                         ['age', 'int64', 'YES', 'EMPTY'],
+                         ['gender', 'string', 'YES', 'EMPTY'],
+                         ['row_timestamp', 'timestamp', 'YES', 100]]
+        # timestamp has not support
+        # self.check_result(resp, expect_result)
+
+        # existent tag
+        resp = self.client.execute('CREATE TAG person(id int)')
+        self.check_resp_failed(resp)
+
+        # nonexistent tag
+        resp = self.client.execute_query('DESCRIBE TAG not_exist')
+        self.check_resp_failed(resp)
+
+        # alter tag
+        resp = self.client.execute('ALTER TAG person '
+                                   'ADD (col1 int, col2 string), '
+                                   'CHANGE (age string), '
+                                   'DROP (gender)')
+        self.check_resp_succeeded(resp)
+        
+        # drop not exist prop
+        resp = self.client.execute('ALTER TAG person DROP (gender)')
+        self.check_resp_failed(resp)
+
+        # check result
+        resp = self.client.execute_query('DESCRIBE TAG person')
+        self.check_resp_succeeded(resp)
+        expect_result = [['name', 'string', 'YES', 'EMPTY'],
+                         ['email', 'string', 'YES', 'EMPTY'],
+                         ['age', 'int64', 'YES', 'EMPTY'],
+                         ['row_timestamp', 'timestamp', 'YES', 2010],
+                         ['col1', 'int', 'YES', 'EMPTY'],
+                         ['col2', 'string', 'YES', 'EMPTY']]
+        # timestamp has not support
+        # self.check_result(resp, expect_result)
+
+        # check result
+        resp = self.client.execute_query('SHOW CREATE TAG person')
+        self.check_resp_succeeded(resp)
+        create_tag_str = 'CREATE TAG `person` (\n' \
+                         '  `name` string NULL,\n' \
+                         '  `email` string NULL DEFAULT "NULL",\n' \
+                         '  `age` string NULL,\n' \
+                         '  `row_timestamp` timestamp NULL DEFAULT 2020,\n' \
+                         '  `col1` int NULL,\n' \
+                         '  `col2` string NULL\n' \
+                         ') ttl_duration = 0, ttl_col = ""';
+        # timestamp has not support
+        expect_result = [['person', create_tag_str]]
+        #self.check_result(resp, expect_result)
+
+        # show tags
+        resp = self.client.execute_query('SHOW TAGS')
+        self.check_resp_succeeded(resp)
+        expect_result = [['tag1'], ['person'], ['person_with_default'], ['upper']]
+        self.check_out_of_order_result(resp, expect_result)
+
+        # with negative DEFAULT value
+        resp = self.client.execute('CREATE TAG default_tag_neg(id int DEFAULT -10, '
+                                   'height double DEFAULT -176.0)')
+        self.check_resp_succeeded(resp)
+
+        # Tag with expression DEFAULT value
+        resp = self.client.execute('CREATE TAG default_tag_expr'
+                                   '(id int DEFAULT 3/2*4-5, '
+                                   'male bool DEFAULT 3 > 2, '
+                                   'height double DEFAULT abs(-176.0), '
+                                   'adult bool DEFAULT true && false)')
+        self.check_resp_succeeded(resp)
+
+    def test_drop_tag(self):
+        resp = self.client.execute('DROP TAG person')
+        self.check_resp_succeeded(resp)
+
+        # drop not exist
+        resp = self.client.execute('DROP TAG not_exist_tag')
+        self.check_resp_failed(resp)
+
+        # drop if exists
+        resp = self.client.execute('DROP TAG IF EXISTS not_exist_tag')
+        self.check_resp_succeeded(resp)
+
+        # drop if exists
+        resp = self.client.execute('CREATE TAG exist_tag(id int)')
+        self.check_resp_succeeded(resp)
+        resp = self.client.execute('DROP TAG IF EXISTS exist_tag')
+        self.check_resp_succeeded(resp)
+
+    def test_edge(self):
+        # empty edge prop
+        resp = self.client.execute('CREATE EDGE edge1()')
+        self.check_resp_succeeded(resp)
+
+        # IF NOT EXISTS
+        resp = self.client.execute('CREATE EDGE IF NOT EXISTS edge1()')
+        self.check_resp_succeeded(resp)
+
+        # desc edge
+        resp = self.client.execute_query('DESCRIBE EDGE edge1')
+        self.check_resp_succeeded(resp)
+
+        # alter edge
+        resp = self.client.execute('ALTER EDGE edge1 ADD (id int, name string)')
+        self.check_resp_succeeded(resp)
+
+        # desc edge
+        resp = self.client.execute_query('DESCRIBE EDGE edge1')
+        self.check_resp_succeeded(resp)
+
+        # 1.0 expect ['id', 'int', 'YES', 'EMPTY'], 2.0 has int8, int16, int32 and int64
+        expect_result = [['id', 'int64', 'YES', 'EMPTY'],
+                         ['name', 'string', 'YES', 'EMPTY']]
+        self.check_out_of_order_result(resp, expect_result)
+
+        # create edge succeeded
+        resp = self.client.execute('CREATE EDGE buy(id int, time string)')
+        self.check_resp_succeeded(resp)
+
+        # create Edge with duplicate field
+        resp = self.client.execute('CREATE EDGE duplicate_buy(time int, time string)')
+        self.check_resp_failed(resp)
+
+        # create Edge with duplicate field
+        resp = self.client.execute('CREATE EDGE duplicate_buy(time int, time int)')
+        self.check_resp_failed(resp)
+
+        # create Edge with DEFAULT
+        resp = self.client.execute('CREATE EDGE buy_with_default(id int, name string DEFAULT "NULL",'
+                                   'time timestamp DEFAULT 2020)')
+        self.check_resp_succeeded(resp)
+
+        # DEFAULT value not match type
+        resp = self.client.execute('CREATE EDGE buy_type_mismatch(id int, time string DEFAULT 0)')
+        self.check_resp_failed(resp)
+
+        # existent edge
+        resp = self.client.execute('CREATE EDGE buy(id int, time string)')
+        self.check_resp_failed(resp)
+
+        # DESCRIBE edge
+        resp = self.client.execute_query('DESCRIBE EDGE buy')
+        self.check_resp_succeeded(resp)
+        expect_result = [['id', 'int64', 'YES', 'EMPTY'],
+                         ['time', 'string', 'YES', 'EMPTY']]
+        self.check_out_of_order_result(resp, expect_result)
+
+        # desc nonexistent edge
+        resp = self.client.execute('DESCRIBE EDGE not_exist')
+        self.check_resp_failed(resp)
+
+        # DESC edge
+        resp = self.client.execute_query('DESC EDGE buy')
+        self.check_resp_succeeded(resp)
+        expect_result = [['id', 'int64', 'YES', 'EMPTY'],
+                         ['time', 'string', 'YES', 'EMPTY']]
+        self.check_out_of_order_result(resp, expect_result)
+
+        # show create edge
+        resp = self.client.execute_query('SHOW CREATE EDGE buy_with_default')
+        self.check_resp_succeeded(resp)
+        create_edge_str = 'CREATE EDGE `buy_with_default` (\n' \
+                          '  `id` int NULL,\n' \
+                          '  `name` string NULL DEFAULT "NULL",\n' \
+                          '  `time` timestamp NULL DEFAULT 2020\n' \
+                          ') ttl_duration = 0, ttl_col = "\"'
+        expect_result = [['buy_with_default', create_edge_str]]
+        # self.check_result(resp, expect_result)
+
+        # create edge succeed
+        resp = self.client.execute('CREATE EDGE education(id int, time timestamp, school string)')
+        self.check_resp_succeeded(resp)
+
+        # DESC edge
+        resp = self.client.execute_query('DESC EDGE education')
+        self.check_resp_succeeded(resp)
+        expect_result = [['id', 'int64', 'YES', 'EMPTY'],
+                         ['time', 'timestamp', 'YES', 'EMPTY'],
+                         ['school', 'string', 'YES', 'EMPTY']]
+        self.check_out_of_order_result(resp, expect_result)
+
+        # show edges
+        resp = self.client.execute_query('SHOW EDGES')
+        self.check_resp_succeeded(resp)
+        expect_result = [['edge1'], ['buy'], ['buy_with_default'], ['education']]
+        self.check_out_of_order_result(resp, expect_result)
+
+        # alter edge
+        resp = self.client.execute('ALTER EDGE education '
+                                   'ADD (col1 int, col2 string), '
+                                   'CHANGE (school int), '
+                                   'DROP (id, time)')
+        self.check_resp_succeeded(resp)
+
+        # drop not exist prop, failed
+        resp = self.client.execute('ALTER EDGE education DROP (id, time)')
+        self.check_resp_failed(resp)
+
+        # check result
+        resp = self.client.execute_query('DESC EDGE education')
+        self.check_resp_succeeded(resp)
+        expect_result = [['school', 'int64', 'YES', 'EMPTY'],
+                         ['col1', 'int64', 'YES', 'EMPTY'],
+                         ['col2', 'string', 'YES', 'EMPTY'],]
+        self.check_out_of_order_result(resp, expect_result)
+
+        # show create edge
+        resp = self.client.execute_query('SHOW CREATE EDGE education')
+        self.check_resp_succeeded(resp)
+        create_edge_str = 'CREATE EDGE `education` (\n' \
+                          ' `school` int64 NULL,\n' \
+                          ' `col1` int64 NULL,\n' \
+                          ' `col2` string NULL\n' \
+                          ') ttl_duration = 0, ttl_col = "\"'
+        expect_result = [['education', create_edge_str]]
+        self.check_result(resp, expect_result)
+
+        # check result from show create
+        resp = self.client.execute('DROP EDGE education')
+        self.check_resp_succeeded(resp)
+        resp = self.client.execute(create_edge_str)
+        self.check_resp_succeeded(resp)
+
+        # with negative DEFAULT value
+        resp = self.client.execute('CREATE EDGE default_edge_neg(id int DEFAULT -10, '
+                                   'height double DEFAULT -176.0)')
+        self.check_resp_succeeded(resp)
+
+        # Tag with expression DEFAULT value
+        resp = self.client.execute('CREATE EDGE default_edge_expr'
+                                   '(id int DEFAULT 3/2*4-5, '
+                                   'male bool DEFAULT 3 > 2, '
+                                   'height double DEFAULT abs(-176.0), '
+                                   'adult bool DEFAULT true && false)')
+        self.check_resp_succeeded(resp)
+
+    def test_drop_edge(self):
+        resp = self.client.execute('DROP EDGE buy')
+        self.check_resp_succeeded(resp)
+
+        # drop not exist edge
+        resp = self.client.execute('DROP EDGE not_exist_edge')
+        self.check_resp_failed(resp)
+
+        # drop if exists
+        resp = self.client.execute('DROP EDGE IF EXISTS not_exist_edge')
+        self.check_resp_succeeded(resp)
+
+        # drop if exists
+        resp = self.client.execute('CREATE EDGE exist_edge(id int)')
+        self.check_resp_succeeded(resp)
+        resp = self.client.execute('DROP EDGE IF EXISTS exist_edge')
+        self.check_resp_succeeded(resp)
+
+    def test_multi(self):
+        # multi sentences
+        cmd = ''
+        for i in range(0, 1000):
+            cmd += 'CREATE TAG tag10' + str(i) + '(name string);'
+        resp = self.client.execute(cmd)
+        self.check_resp_succeeded(resp)
+
+        # check result
+        for i in range(0, 1000):
+            resp = self.client.execute_query('DESC TAG tag10' + str(i))
+            self.check_resp_succeeded(resp)
+            expect_result = [['name', 'string', 'YES', 'EMPTY']]
+            self.check_result(resp, expect_result)
+
+    def test_same_tag_in_different_space(self):
+        resp = self.client.execute('CREATE SPACE my_space(partition_num=9, replica_factor=1)')
+        self.check_resp_succeeded(resp)
+
+        # 2.0 use space get from cache
+        time.sleep(self.delay)
+
+        resp = self.client.execute('USE my_space')
+        self.check_resp_succeeded(resp)
+
+        resp = self.client.execute('CREATE TAG animal(name string, kind string)')
+        self.check_resp_succeeded(resp)
+
+        resp = self.client.execute_query('DESCRIBE TAG animal')
+        self.check_resp_succeeded(resp)
+        expect_result = [['name', 'string', 'YES', 'EMPTY'],
+                         ['kind', 'string', 'YES', 'EMPTY']]
+        self.check_out_of_order_result(resp, expect_result)
+
+        resp = self.client.execute('CREATE TAG person(name string, interest string)')
+        self.check_resp_succeeded(resp)
+
+        resp = self.client.execute_query('SHOW TAGS')
+        self.check_resp_succeeded(resp)
+        expect_result = [['animal'],['person']]
+        self.check_out_of_order_result(resp, expect_result)
+
+        resp = self.client.execute('CREATE SPACE test_multi')
+        self.check_resp_succeeded(resp)
+
+        # 2.0 use space get from cache
+        time.sleep(self.delay)
+
+        resp = self.client.execute_query('USE test_multi; CREATE Tag test_tag(); SHOW TAGS;')
+        self.check_resp_succeeded(resp)
+        expect_result = [['test_tag']]
+        self.check_result(resp, expect_result)
+
+        resp = self.client.execute_query('USE test_multi; CREATE TAG test_tag1(); USE my_space; SHOW TAGS;')
+        self.check_resp_succeeded(resp)
+        expect_result = [['animal'], ['person']]
+        self.check_out_of_order_result(resp, expect_result)
+
+        resp = self.client.execute('DROP SPACE test_multi')
+        self.check_resp_succeeded(resp)
+
+    def test_reserved_keyword(self):
+        resp = self.client.execute('USE my_space; CREATE TAG `tag` (`edge` string)')
+        self.check_resp_succeeded(resp)
+
+        resp = self.client.execute_query('DESCRIBE TAG `tag`')
+        self.check_resp_succeeded(resp)
+        expect_result = [['edge', 'string', 'YES', 'EMPTY']]
+        self.check_result(resp, expect_result)
+
+    def drop_space(self):
+        resp = self.client.execute_query('SHOW SPACES')
+        self.check_resp_succeeded(resp)
+
+        resp = self.client.execute('DROP SPACE my_space')
+        self.check_resp_succeeded(resp)
+
+        resp = self.client.execute('DROP SPACE default_space')
+        self.check_resp_succeeded(resp)
+
+    def alter_tag_with_default(self):
+        resp = self.client.execute('CREATE TAG t(name string DEFAULT "N/A", age int DEFAULT -1)')
+        self.check_resp_succeeded(resp)
+
+        # alter add
+        resp = self.client.execute('ALTER TAG t ADD (description string DEFAULT "none")')
+        self.check_resp_succeeded(resp)
+
+        # insert
+        resp = self.client.execute('INSERT VERTEX t() VALUES "1":()')
+        self.check_resp_succeeded(resp)
+
+        # fetch
+        resp = self.client.execute('FETCH PROP ON t 1')
+        self.check_resp_succeeded(resp)
+        expect_result = [['N/A'], [-1], ['NONE']]
+        self.check_out_of_order_result(resp, expect_result)
+
+        # alter drop
+        resp = self.client.execute('ALTER TAG t CHANGE (description string)')
+        self.check_resp_succeeded(resp)
+
+        # insert wrong tyoe
+        resp = self.client.execute('INSERT VERTEX t(description) VALUES "1":("some one")')
+        self.check_resp_succeeded(resp)
+
+        # fetch
+        resp = self.client.execute('FETCH PROP ON t "1"')
+        self.check_resp_succeeded(resp)
+        expect_result = [['N/A'], [-1], ['some one']]
+        self.check_out_of_order_result(resp, expect_result)
+
+        # insert without default prop, failed
+        resp = self.client.execute('INSERT VERTEX t() VALUES "1":()')
+        self.check_resp_failed(resp)
+
+    def alter_edge_with_default(self):
+        resp = self.client.execute('CREATE EDGE e(name string DEFAULT "N/A", age int DEFAULT -1)')
+        self.check_resp_succeeded(resp)
+
+        # alter add
+        resp = self.client.execute('ALTER EDGE e ADD (description string DEFAULT "none")')
+        self.check_resp_succeeded(resp)
+
+        # insert
+        resp = self.client.execute('INSERT EDGE e() VALUES "1"->"2":()')
+        self.check_resp_succeeded(resp)
+
+        # fetch
+        resp = self.client.execute('FETCH PROP ON e "1"->"2"')
+        self.check_resp_succeeded(resp)
+        expect_result = [['N/A'], [-1], ['NONE']]
+        self.check_out_of_order_result(resp, expect_result)
+
+        # alter drop
+        resp = self.client.execute('ALTER EDGE e CHANGE (description string)')
+        self.check_resp_succeeded(resp)
+
+        # sleep to get schema in cache
+        time.sleep(self.delay)
+
+        # insert successed
+        resp = self.client.execute('INSERT EDGE e(description) VALUES "1"->"2":("some one")')
+        self.check_resp_succeeded(resp)
+
+        # fetch
+        resp = self.client.execute('FETCH PROP ON e "1"->"2"')
+        self.check_resp_succeeded(resp)
+        expect_result = [['N/A'], [-1], ['some one']]
+        self.check_out_of_order_result(resp, expect_result)
+
+        # insert without default prop, failed
+        resp = self.client.execute('INSERT EDGE e() VALUES "1"->"2":()')
+        self.check_resp_failed(resp)
+
+    def alter_edge_with_default(self):
+        resp = self.client.execute('CREATE SPACE issue2009; USE issue2009')
+        self.check_resp_succeeded(resp)
+
+        resp = self.client.execute('CREATE EDGE IF NOT EXISTS relation'
+                                   '(intimacy int DEFAULT 0, '
+                                   'isReversible bool DEFAULT false, '
+                                   'name string DEFAULT \"N/A\", '
+                                   'startTime timestamp DEFAULT 0)')
+        self.check_resp_succeeded(resp)
+
+        resp = self.client.execute('INSERT EDGE relation (intimacy) VALUES '
+                                   '"person.Tom" -> "person.Marry"@0:(3)')
+        self.check_resp_succeeded(resp)
diff --git a/tests/nebula-test-run.py b/tests/nebula-test-run.py
index ac7c44ca56a4758bc2330e1021b023b06ad5cf74..7d0be6f8125c752b15f0d4218d65683f6c1c9271 100755
--- a/tests/nebula-test-run.py
+++ b/tests/nebula-test-run.py
@@ -195,7 +195,7 @@ def startNebula(nebula_test_dir):
             print("error: " + p.communicate()[0])
 
     #wait nebula start
-    time.sleep(5)
+    time.sleep(8)
     for pf in glob.glob(nebula_test_dir+'/pids/*.pid'):
         with open(pf) as f:
             pid = int(f.readline())
diff --git a/tests/nebula_test_common/nebula_test_suite.py b/tests/nebula_test_common/nebula_test_suite.py
index e06974841a235d75e89123e4608c0a09591b33fb..cbac969e1284e6e68e688975d56760bcf9844cab 100644
--- a/tests/nebula_test_common/nebula_test_suite.py
+++ b/tests/nebula_test_common/nebula_test_suite.py
@@ -11,7 +11,7 @@ from typing import Pattern, Set
 import pytest
 import time
 from pathlib import Path
-
+from nebula2.common import ttypes as CommonTtypes
 from nebula2.graph import ttypes
 from nebula2.ConnectionPool import ConnectionPool
 from nebula2.Client import AuthException, ExecutionException, GraphClient
@@ -24,14 +24,14 @@ class NebulaTestSuite(object):
         #     'get configs GRAPH:heartbeat_interval_secs')
         # self.check_resp_succeeded(resp)
         # assert len(resp.rows) == 1, "invalid row size: {}".format(resp.rows)
-        # self.graph_delay = int(resp.rows[0].columns[4].get_str()) + 1
+        # self.graph_delay = int(resp.rows[0].columns[4].get_sVal()) + 1
         self.graph_delay = 3
 
         # resp = self.client.execute_query(
         #     'get configs STORAGE:heartbeat_interval_secs')
         # self.check_resp_succeeded(resp)
         # assert len(resp.rows) == 1, "invalid row size: {}".format(resp.rows)
-        # self.storage_delay = int(resp.rows[0].columns[4].get_str()) + 1
+        # self.storage_delay = int(resp.rows[0].columns[4].get_sVal()) + 1
         self.storage_delay = 3
         self.delay = max(self.graph_delay, self.storage_delay) * 2
 
@@ -49,7 +49,6 @@ class NebulaTestSuite(object):
         self.prepare()
         self.check_format_str = 'result: {}, expect: {}'
         self.data_dir = pytest.cmdline.data_dir
-        self.load_data()
 
     @classmethod
     def load_data(self):
@@ -130,7 +129,8 @@ class NebulaTestSuite(object):
 
     @classmethod
     def check_resp_succeeded(self, resp):
-        assert resp.error_code == 0, resp.error_msg
+        assert resp.error_code == ttypes.ErrorCode.SUCCEEDED \
+               or resp.error_code == ttypes.ErrorCode.E_STATEMENT_EMTPY, resp.error_msg
 
     @classmethod
     def check_resp_failed(self, resp, error_code: ttypes.ErrorCode = ttypes.ErrorCode.SUCCEEDED):
@@ -147,12 +147,18 @@ class NebulaTestSuite(object):
 
     @classmethod
     def check_value(self, col, expect):
-        if col.getType() == ttypes.ColumnValue.__EMPTY__:
+        if col.getType() == CommonTtypes.Value.__EMPTY__:
             msg = 'ERROR: type is empty'
-            return False, msg
+            if isinstance(expect, Pattern):
+                if not expect.match(str('EMPTY')):
+                    return False, msg
+            else:
+                if 'EMPTY' != expect:
+                    return False, msg
+            return True, ''
 
-        if col.getType() == ttypes.ColumnValue.BOOL_VAL:
-            msg = self.check_format_str.format(col.get_bool_val(), expect)
+        if col.getType() == CommonTtypes.Value.BVAL:
+            msg = self.check_format_str.format(col.get_bVal(), expect)
             if isinstance(expect, Pattern):
                 if not expect.match(str(col.get_bool_val())):
                     return False, msg
@@ -161,55 +167,55 @@ class NebulaTestSuite(object):
                     return False, msg
             return True, ''
 
-        if col.getType() == ttypes.ColumnValue.INTEGER:
-            msg = self.check_format_str.format(col.get_integer(), expect)
+        if col.getType() == CommonTtypes.Value.IVAL:
+            msg = self.check_format_str.format(col.get_iVal(), expect)
             if isinstance(expect, Pattern):
-                if not expect.match(str(col.get_integer())):
+                if not expect.match(str(col.get_iVal())):
                     return False, msg
             else:
-                if col.get_integer() != expect:
+                if col.get_iVal() != expect:
                     return False, msg
             return True, ''
 
-        if col.getType() == ttypes.ColumnValue.ID:
-            msg = self.check_format_str.format(col.get_id(), expect)
+        if col.getType() == CommonTtypes.Value.SVAL:
+            msg = self.check_format_str.format(col.get_sVal().decode('utf-8'),
+                                               expect)
             if isinstance(expect, Pattern):
-                if not expect.match(str(col.get_id())):
+                if not expect.match(col.get_sVal().decode('utf-8')):
                     return False, msg
             else:
-                if col.get_id() != expect:
+                if col.get_sVal().decode('utf-8') != expect:
                     return False, msg
             return True, ''
 
-        if col.getType() == ttypes.ColumnValue.STR:
-            msg = self.check_format_str.format(col.get_str().decode('utf-8'),
+        if col.getType() == CommonTtypes.Value.FVAL:
+            msg = self.check_format_str.format(col.get_fVal(),
                                                expect)
             if isinstance(expect, Pattern):
-                if not expect.match(col.get_str().decode('utf-8')):
+                if not expect.match(str(col.get_fVal())):
                     return False, msg
             else:
-                if col.get_str().decode('utf-8') != expect:
+                if not math.isclose(col.get_fVal(), expect):
                     return False, msg
             return True, ''
 
-        if col.getType() == ttypes.ColumnValue.DOUBLE_PRECISION:
-            msg = self.check_format_str.format(col.get_double_precision(),
-                                               expect)
+        if col.getType() == CommonTtypes.Value.DVAL:
+            msg = self.check_format_str.format(col.get_dVal(), expect)
             if isinstance(expect, Pattern):
-                if not expect.match(str(col.get_double_precision())):
+                if not expect.match(str(col.get_dVal())):
                     return False, msg
             else:
-                if not math.isclose(col.get_double_precision(), expect):
+                if col.get_dVal() != expect:
                     return False, msg
             return True, ''
 
-        if col.getType() == ttypes.ColumnValue.TIMESTAMP:
-            msg = self.check_format_str.format(col.get_timestamp(), expect)
+        if col.getType() == CommonTtypes.Value.TVAL:
+            msg = self.check_format_str.format(col.get_tVal(), expect)
             if isinstance(expect, Pattern):
-                if not expect.match(str(col.get_timestamp())):
+                if not expect.match(str(col.get_tVal())):
                     return False, msg
             else:
-                if col.get_timestamp() != expect:
+                if col.get_tVal() != expect:
                     return False, msg
             return True, ''
 
@@ -219,25 +225,33 @@ class NebulaTestSuite(object):
     def row_to_string(self, row):
         value_list = []
         for col in row.columns:
-            if col.getType() == ttypes.ColumnValue.__EMPTY__:
-                print('ERROR: type is empty')
-                return
-            elif col.getType() == ttypes.ColumnValue.BOOL_VAL:
-                value_list.append(col.get_bool_val())
-            elif col.getType() == ttypes.ColumnValue.INTEGER:
-                value_list.append(col.get_integer())
-            elif col.getType() == ttypes.ColumnValue.ID:
+            if col.getType() == CommonTtypes.Value.__EMPTY__:
+                value_list.append('EMPTY')
+            elif col.getType() == CommonTtypes.Value.NVAL:
+                value_list.append('NULL')
+            elif col.getType() == CommonTtypes.Value.BVAL:
+                value_list.append(col.get_bVal())
+            elif col.getType() == CommonTtypes.Value.IVAL:
+                value_list.append(col.get_iVal())
+            elif col.getType() == CommonTtypes.Value.FVAL:
                 value_list.append(col.get_id())
-            elif col.getType() == ttypes.ColumnValue.STR:
-                value_list.append(col.get_str().decode('utf-8'))
-            elif col.getType() == ttypes.ColumnValue.DOUBLE_PRECISION:
-                value_list.append(col.get_double_precision())
-            elif col.getType() == ttypes.ColumnValue.TIMESTAMP:
-                value_list.append(col.get_timestamp())
+            elif col.getType() == CommonTtypes.Value.SVAL:
+                value_list.append(col.get_sVal().decode('utf-8'))
+            elif col.getType() == CommonTtypes.Type.DVAL:
+                value_list.append(col.get_dVal().decode('utf-8'))
+            elif col.getType() == CommonTtypes.Type.DATETIME:
+                value_list.append(col.get_datetime())
         return str(value_list)
 
     @classmethod
-    def search_result(self, rows, expect):
+    def search_result(self, resp, expect):
+        if resp.data is None and len(expect) == 0:
+            return
+
+        if resp.data is None:
+            assert False, 'resp.data is None'
+        rows = resp.data.rows
+
         msg = 'len(rows)[%d] != len(expect)[%d]' % (len(rows), len(expect))
         assert len(rows) == len(expect), msg
         for row in rows:
@@ -255,10 +269,14 @@ class NebulaTestSuite(object):
             expect.remove(exp)
 
     @classmethod
-    def check_result(self, rows, expect, ignore_col: Set[int] = set()):
-        if rows is None and len(expect) == 0:
+    def check_result(self, resp, expect, ignore_col: Set[int] = set()):
+        if resp.data is None and len(expect) == 0:
             return
 
+        if resp.data is None:
+            assert False, 'resp.data is None'
+        rows = resp.data.rows
+
         msg = 'len(rows)[%d] != len(expect)[%d]' % (len(rows), len(expect))
         assert len(rows) == len(expect), msg
         for row, i in zip(rows, range(0, len(expect))):
@@ -275,21 +293,25 @@ class NebulaTestSuite(object):
                     self.row_to_string(row), expect[i], msg)
 
     @classmethod
-    def check_out_of_order_result(self, rows, expect):
-        if rows is None and len(expect) == 0:
+    def check_out_of_order_result(self, resp, expect, ignore_col: Set[int] = set()):
+        if resp.data is None and len(expect) == 0:
             return
 
+        if resp.data is None:
+            assert False, 'resp.data is None'
+        rows = resp.data.rows
         sorted_rows = sorted(rows, key=str)
+        resp.data.rows = sorted_rows
         sorted_expect = sorted(expect)
-        self.check_result(sorted_rows, sorted_expect)
+        self.check_result(resp, sorted_expect, ignore_col)
 
     @classmethod
-    def check_empty_result(self, rows):
-        msg = 'the row was not empty {}'.format(rows)
+    def check_empty_result(self, resp):
+        msg = 'the row was not empty {}'.format(resp)
         empty = False
-        if rows is None:
+        if resp.data is None:
             empty = True
-        elif len(rows) == 0:
+        elif len(resp.data.rows) == 0:
             empty = True
         assert empty, msg
 
@@ -321,9 +343,9 @@ class NebulaTestSuite(object):
                 assert len(
                     row.columns
                 ) == 1, "invalid columns size in rows: {}".format(row)
-                assert row.columns[0].getType(
-                ) == ttypes.ColumnValue.PATH, "invalid column path type: {}".format(
-                    row.columns[0].getType())
+                assert row.columns[0].getType()(
+                ) == ttypes.Value.PATH, "invalid column path type: {}".format(
+                    row.columns[0].getType()())
                 if row.columns[0].get_path() == path:
                     find = True
                     break
diff --git a/tests/query/stateless/test_schema.py b/tests/query/stateless/test_schema.py
index b49368a467b6e728042a1d8c856d1412314b4fa3..bb29bd960fb3fb3373d29e8d68b0cbed79c48059 100644
--- a/tests/query/stateless/test_schema.py
+++ b/tests/query/stateless/test_schema.py
@@ -9,8 +9,6 @@ import re
 import sys
 import time
 
-from graph import ttypes
-
 from nebula_test_common.nebula_test_suite import NebulaTestSuite
 
 
@@ -32,7 +30,7 @@ class TestSchema(NebulaTestSuite):
         self.check_resp_succeeded(resp)
         resp = self.execute_query('DESC TAG TAG_empty')
         self.check_resp_succeeded(resp)
-        self.check_empty_result(resp.rows)
+        self.check_empty_result(resp)
 
         # create tag with all type
         resp = self.execute_query('CREATE TAG TAG_all_type(name string, age int, '
@@ -41,9 +39,12 @@ class TestSchema(NebulaTestSuite):
 
         resp = self.execute_query('DESC TAG TAG_all_type')
         self.check_resp_succeeded(resp)
-        expect = [['name', 'string'], ['age', 'int'], ['is_man', 'bool'],
-                  ['account', 'double'], ['birthday', 'timestamp']]
-        self.check_result(resp.rows, expect)
+        expect = [['name', 'string', 'YES', 'EMPTY'],
+                  ['age', 'int64', 'YES', 'EMPTY'],
+                  ['is_man', 'bool', 'YES', 'EMPTY'],
+                  ['account', 'double', 'YES', 'EMPTY'],
+                  ['birthday', 'timestamp', 'YES', 'EMPTY']]
+        self.check_result(resp, expect)
 
         # create tag with default value
         resp = self.execute('CREATE TAG TAG_default(name string, age int, gender string DEFAULT "male")')
@@ -51,9 +52,9 @@ class TestSchema(NebulaTestSuite):
 
         resp = self.execute_query('SHOW CREATE TAG TAG_default')
         self.check_resp_succeeded(resp)
-        expect = [['TAG_default', 'CREATE TAG TAG_default (\n  name string,\n  age int,\n  '
-                                  'gender string default male\n) ttl_duration = 0, ttl_col = ""']]
-        self.check_result(resp.rows, expect)
+        expect = [['TAG_default', 'CREATE TAG `TAG_default` (\n `name` string NULL,\n `age` int64 NULL,\n '
+                                  '`gender` string NULL DEFAULT "male"\n) ttl_duration = 0, ttl_col = ""']]
+        self.check_result(resp, expect)
 
         # create tag with ttl
         resp = self.execute('CREATE TAG person(name string, email string, '
@@ -63,15 +64,17 @@ class TestSchema(NebulaTestSuite):
 
         resp = self.execute_query('DESC TAG person')
         self.check_resp_succeeded(resp)
-        expect = [['name', 'string'], ['email', 'string'], ['age', 'int'],
-                  ['gender', 'string'], ['birthday', 'timestamp']]
-        self.check_result(resp.rows, expect)
+        expect = [['name', 'string', 'YES', 'EMPTY'],
+                  ['email', 'string', 'YES', 'EMPTY'],
+                  ['age', 'int64', 'YES', 'EMPTY'],
+                  ['gender', 'string', 'YES', 'EMPTY'],
+                  ['birthday', 'timestamp', 'YES', 'EMPTY']]
+        self.check_result(resp, expect)
 
         # show all tags
         resp = self.execute_query('SHOW TAGS')
         self.check_resp_succeeded(resp)
-        self.check_result(resp.rows, [[re.compile(r'\d+'), 'TAG_empty'], [re.compile(r'\d+'), 'TAG_all_type'],
-                                      [re.compile(r'\d+'), 'TAG_default'], [re.compile(r'\d+'), 'person']])
+        self.check_out_of_order_result(resp, [['TAG_empty'], ['TAG_all_type'], ['TAG_default'], ['person']])
 
     def test_create_tag_failed(self):
         # create tag without prop
@@ -119,8 +122,10 @@ class TestSchema(NebulaTestSuite):
 
         resp = self.execute_query('DESC TAG student')
         self.check_resp_succeeded(resp)
-        expect = [['name', 'string'], ['email', 'string'], ['birthday', 'timestamp']]
-        self.check_result(resp.rows, expect)
+        expect = [['name', 'string', 'YES', 'EMPTY'],
+                  ['email', 'string', 'YES', 'EMPTY'],
+                  ['birthday', 'timestamp', 'YES', 'EMPTY']]
+        self.check_result(resp, expect)
 
         # alter add
         resp = self.execute('ALTER TAG student add (age string)')
@@ -128,8 +133,11 @@ class TestSchema(NebulaTestSuite):
 
         resp = self.execute_query('DESC TAG student')
         self.check_resp_succeeded(resp)
-        expect = [['name', 'string'], ['email', 'string'], ['birthday', 'timestamp'], ['age', 'string']]
-        self.check_result(resp.rows, expect)
+        expect = [['name', 'string', 'YES', 'EMPTY'],
+                  ['email', 'string', 'YES', 'EMPTY'],
+                  ['birthday', 'timestamp', 'YES', 'EMPTY'],
+                  ['age', 'string', 'YES', 'EMPTY']]
+        self.check_result(resp, expect)
 
         # alter change
         resp = self.execute('ALTER TAG student change (age int)')
@@ -137,8 +145,11 @@ class TestSchema(NebulaTestSuite):
 
         resp = self.execute_query('DESC TAG student')
         self.check_resp_succeeded(resp)
-        expect = [['name', 'string'], ['email', 'string'], ['birthday', 'timestamp'], ['age', 'int']]
-        self.check_result(resp.rows, expect)
+        expect = [['name', 'string', 'YES', 'EMPTY'],
+                  ['email', 'string', 'YES', 'EMPTY'],
+                  ['birthday', 'timestamp', 'YES', 'EMPTY'],
+                  ['age', 'int64', 'YES', 'EMPTY']]
+        self.check_result(resp, expect)
 
         # alter all
         resp = self.execute('ALTER TAG student drop (name),'
@@ -148,8 +159,11 @@ class TestSchema(NebulaTestSuite):
 
         resp = self.execute_query('DESC TAG student')
         self.check_resp_succeeded(resp)
-        expect = [['email', 'string'], ['birthday', 'timestamp'], ['age', 'int'], ['gender', 'int']]
-        self.check_result(resp.rows, expect)
+        expect = [['email', 'string', 'YES', 'EMPTY'],
+                  ['birthday', 'timestamp', 'YES', 'EMPTY'],
+                  ['age', 'int64', 'YES', 'EMPTY'],
+                  ['gender', 'int64', 'YES', 'EMPTY']]
+        self.check_result(resp, expect)
 
     def test_alter_tag_failed(self):
         # alter ttl_col on wrong type
@@ -179,7 +193,7 @@ class TestSchema(NebulaTestSuite):
         self.check_resp_succeeded(resp)
         resp = self.execute_query('DESC EDGE EDGE_empty')
         self.check_resp_succeeded(resp)
-        self.check_empty_result(resp.rows)
+        self.check_empty_result(resp)
 
         # create tag with all type
         resp = self.execute_query('CREATE EDGE EDGE_all_type(name string, age int, '
@@ -188,9 +202,12 @@ class TestSchema(NebulaTestSuite):
 
         resp = self.execute_query('DESC EDGE EDGE_all_type')
         self.check_resp_succeeded(resp)
-        expect = [['name', 'string'], ['age', 'int'], ['is_man', 'bool'],
-                  ['account', 'double'], ['birthday', 'timestamp']]
-        self.check_result(resp.rows, expect)
+        expect = [['name', 'string', 'YES', 'EMPTY'],
+                  ['age', 'int64', 'YES', 'EMPTY'],
+                  ['is_man', 'bool', 'YES', 'EMPTY'],
+                  ['account', 'double', 'YES', 'EMPTY'],
+                  ['birthday', 'timestamp', 'YES', 'EMPTY']]
+        self.check_result(resp, expect)
 
         # create tag with default value
         resp = self.execute('CREATE EDGE EDGE_default(name string, age int, gender string DEFAULT "male")')
@@ -198,9 +215,9 @@ class TestSchema(NebulaTestSuite):
 
         resp = self.execute_query('SHOW CREATE EDGE EDGE_default')
         self.check_resp_succeeded(resp)
-        expect = [['EDGE_default', 'CREATE EDGE EDGE_default (\n  name string,\n  age int,\n  '
-                                   'gender string default male\n) ttl_duration = 0, ttl_col = ""']]
-        self.check_result(resp.rows, expect)
+        expect = [['EDGE_default', 'CREATE EDGE `EDGE_default` (\n `name` string NULL,\n `age` int64 NULL,\n '
+                                   '`gender` string NULL DEFAULT "male"\n) ttl_duration = 0, ttl_col = ""']]
+        self.check_result(resp, expect)
 
         # create tag with ttl
         resp = self.execute('CREATE EDGE human(name string, email string, '
@@ -210,15 +227,17 @@ class TestSchema(NebulaTestSuite):
 
         resp = self.execute_query('DESC EDGE human')
         self.check_resp_succeeded(resp)
-        expect = [['name', 'string'], ['email', 'string'], ['age', 'int'],
-                  ['gender', 'string'], ['birthday', 'timestamp']]
-        self.check_result(resp.rows, expect)
+        expect = [['name', 'string', 'YES', 'EMPTY'],
+                  ['email', 'string', 'YES', 'EMPTY'],
+                  ['age', 'int64', 'YES', 'EMPTY'],
+                  ['gender', 'string', 'YES', 'EMPTY'],
+                  ['birthday', 'timestamp', 'YES', 'EMPTY']]
+        self.check_result(resp, expect)
 
         # show all tags
         resp = self.execute_query('SHOW EDGES')
         self.check_resp_succeeded(resp)
-        self.check_result(resp.rows, [[re.compile(r'\d+'), 'EDGE_empty'], [re.compile(r'\d+'), 'EDGE_all_type'],
-                                      [re.compile(r'\d+'), 'EDGE_default'], [re.compile(r'\d+'), 'human']])
+        self.check_out_of_order_result(resp, [['EDGE_empty'], ['EDGE_all_type'], ['EDGE_default'], ['human']])
 
     def test_create_edge_failed(self):
         # create edge without prop
@@ -263,8 +282,8 @@ class TestSchema(NebulaTestSuite):
 
         resp = self.execute_query('DESC EDGE relationship')
         self.check_resp_succeeded(resp)
-        expect = [['name', 'string'], ['email', 'string']]
-        self.check_result(resp.rows, expect)
+        expect = [['name', 'string', 'YES', 'EMPTY'], ['email', 'string', 'YES', 'EMPTY']]
+        self.check_result(resp, expect)
 
         # alter add
         resp = self.execute('ALTER EDGE relationship ADD (start_year string)')
@@ -272,8 +291,10 @@ class TestSchema(NebulaTestSuite):
 
         resp = self.execute_query('DESC EDGE relationship')
         self.check_resp_succeeded(resp)
-        expect = [['name', 'string'], ['email', 'string'], ['start_year', 'string']]
-        self.check_result(resp.rows, expect)
+        expect = [['name', 'string', 'YES', 'EMPTY'],
+                  ['email', 'string', 'YES', 'EMPTY'],
+                  ['start_year', 'string', 'YES', 'EMPTY']]
+        self.check_result(resp, expect)
 
         # alter change
         resp = self.execute('ALTER EDGE relationship change (start_year int)')
@@ -281,8 +302,10 @@ class TestSchema(NebulaTestSuite):
 
         resp = self.execute_query('DESC EDGE relationship')
         self.check_resp_succeeded(resp)
-        expect = [['name', 'string'], ['email', 'string'], ['start_year', 'int']]
-        self.check_result(resp.rows, expect)
+        expect = [['name', 'string', 'YES', 'EMPTY'],
+                  ['email', 'string', 'YES', 'EMPTY'],
+                  ['start_year', 'int64', 'YES', 'EMPTY']]
+        self.check_result(resp, expect)
 
         # alter all
         resp = self.execute('ALTER EDGE relationship drop (name),'
@@ -292,8 +315,10 @@ class TestSchema(NebulaTestSuite):
 
         resp = self.execute_query('DESC EDGE relationship')
         self.check_resp_succeeded(resp)
-        expect = [['email', 'string'], ['start_year', 'int'], ['end_year', 'int']]
-        self.check_result(resp.rows, expect)
+        expect = [['email', 'string', 'YES', 'EMPTY'],
+                  ['start_year', 'int64', 'YES', 'EMPTY'],
+                  ['end_year', 'int64', 'YES', 'EMPTY']]
+        self.check_result(resp, expect)
 
     def test_alter_edge_failed(self):
         # alter ttl_col on wrong type
diff --git a/tests/requirements.txt b/tests/requirements.txt
index 035fc8f6b51e7826cdf06366bf86eb99d007dd5e..27f79490922a592993eac55fe4b24792c453faec 100644
--- a/tests/requirements.txt
+++ b/tests/requirements.txt
@@ -3,6 +3,6 @@ pytest-html==2.0.1
 pytest-metadata==1.8.0
 pytest-reportlog==0.1.0
 pytest-xdist==1.31.0
-nebula2_python==0.0.1.post2
+nebula2_python
 pytest-benchmark==v3.2.3
 pytest-metadata==1.8.0