diff --git a/README-CN.md b/README-CN.md index 189b7a059a..12ac7b9ee7 100644 --- a/README-CN.md +++ b/README-CN.md @@ -352,4 +352,4 @@ TDengine 提供了丰富的应用程序开发接口,其中包括 C/C++、Java # 加入技术交流群 -TDengine 官方社群「物联网大数据群」对外开放,欢迎您加入讨论。搜索微信号 "tdengine",加小 T 为好友,即可入群。 +TDengine 官方社群「物联网大数据群」对外开放,欢迎您加入讨论。搜索微信号 "tdengine1",加小 T 为好友,即可入群。 diff --git a/cmake/cmake.version b/cmake/cmake.version index 232e86d891..3166a0695c 100644 --- a/cmake/cmake.version +++ b/cmake/cmake.version @@ -2,7 +2,7 @@ IF (DEFINED VERNUMBER) SET(TD_VER_NUMBER ${VERNUMBER}) ELSE () - SET(TD_VER_NUMBER "3.0.4.0") + SET(TD_VER_NUMBER "3.0.4.1") ENDIF () IF (DEFINED VERCOMPATIBLE) diff --git a/cmake/taosadapter_CMakeLists.txt.in b/cmake/taosadapter_CMakeLists.txt.in index ba937b40c1..4a8f4864b3 100644 --- a/cmake/taosadapter_CMakeLists.txt.in +++ b/cmake/taosadapter_CMakeLists.txt.in @@ -2,7 +2,7 @@ # taosadapter ExternalProject_Add(taosadapter GIT_REPOSITORY https://github.com/taosdata/taosadapter.git - GIT_TAG e02ddb2 + GIT_TAG ae8d51c SOURCE_DIR "${TD_SOURCE_DIR}/tools/taosadapter" BINARY_DIR "" #BUILD_IN_SOURCE TRUE diff --git a/cmake/taostools_CMakeLists.txt.in b/cmake/taostools_CMakeLists.txt.in index d8bf3a09b4..d9d2f12069 100644 --- a/cmake/taostools_CMakeLists.txt.in +++ b/cmake/taostools_CMakeLists.txt.in @@ -2,7 +2,7 @@ # taos-tools ExternalProject_Add(taos-tools GIT_REPOSITORY https://github.com/taosdata/taos-tools.git - GIT_TAG 0681d8b + GIT_TAG 4378702 SOURCE_DIR "${TD_SOURCE_DIR}/tools/taos-tools" BINARY_DIR "" #BUILD_IN_SOURCE TRUE diff --git a/docs/en/12-taos-sql/24-show.md b/docs/en/12-taos-sql/24-show.md index e2aff7a878..1f340cab30 100644 --- a/docs/en/12-taos-sql/24-show.md +++ b/docs/en/12-taos-sql/24-show.md @@ -189,7 +189,7 @@ show table distributed d0\G; Show Example

 *************************** 1.row ***************************
-_block_dist: Total_Blocks=[5] Total_Size=[93.65 Kb] Average_size=[18.73 Kb] Compression_Ratio=[23.98 %]
+_block_dist: Total_Blocks=[5] Total_Size=[93.65 KB] Average_size=[18.73 KB] Compression_Ratio=[23.98 %]
 
 Total_Blocks :  Table `d0` contains total 5 blocks
 
diff --git a/docs/examples/rust/nativeexample/examples/subscribe_demo.rs b/docs/examples/rust/nativeexample/examples/subscribe_demo.rs
index 7551ad46b1..d54bb60e93 100644
--- a/docs/examples/rust/nativeexample/examples/subscribe_demo.rs
+++ b/docs/examples/rust/nativeexample/examples/subscribe_demo.rs
@@ -45,7 +45,7 @@ async fn main() -> anyhow::Result<()> {
     taos.exec_many([
         format!("DROP TOPIC IF EXISTS tmq_meters"),
         format!("DROP DATABASE IF EXISTS `{db}`"),
-        format!("CREATE DATABASE `{db}`"),
+        format!("CREATE DATABASE `{db}` WAL_RETENTION_PERIOD 3600"),
         format!("USE `{db}`"),
         // create super table
         format!("CREATE TABLE `meters` (`ts` TIMESTAMP, `current` FLOAT, `voltage` INT, `phase` FLOAT) TAGS (`groupid` INT, `location` BINARY(24))"),
diff --git a/docs/zh/12-taos-sql/24-show.md b/docs/zh/12-taos-sql/24-show.md
index c85efa2376..ab29a1ee50 100644
--- a/docs/zh/12-taos-sql/24-show.md
+++ b/docs/zh/12-taos-sql/24-show.md
@@ -189,7 +189,7 @@ SHOW TABLE DISTRIBUTED table_name;
 
 *************************** 1.row ***************************
 
-_block_dist: Total_Blocks=[5] Total_Size=[93.65 Kb] Average_size=[18.73 Kb] Compression_Ratio=[23.98 %]
+_block_dist: Total_Blocks=[5] Total_Size=[93.65 KB] Average_size=[18.73 KB] Compression_Ratio=[23.98 %]
 
 Total_Blocks:  表 d0 占用的 block 个数为 5 个
 
diff --git a/include/common/systable.h b/include/common/systable.h
index 558a1ca297..ea18338e9e 100644
--- a/include/common/systable.h
+++ b/include/common/systable.h
@@ -12,7 +12,7 @@
  * You should have received a copy of the GNU Affero General Public License
  * along with this program. If not, see .
  */
- 
+
 #ifndef TDENGINE_SYSTABLE_H
 #define TDENGINE_SYSTABLE_H
 
diff --git a/include/common/tcommon.h b/include/common/tcommon.h
index c9eaae74cd..2bc67e439f 100644
--- a/include/common/tcommon.h
+++ b/include/common/tcommon.h
@@ -212,14 +212,6 @@ enum {
   FETCH_TYPE__NONE,
 };
 
-typedef struct {
-  int8_t       fetchType;
-  union {
-    SSDataBlock data;
-    void*       meta;
-  };
-} SFetchRet;
-
 typedef struct SVarColAttr {
   int32_t* offset;    // start position for each entry in the list
   uint32_t length;    // used buffer size that contain the valid data
@@ -341,6 +333,8 @@ typedef struct {
     float       f;
   };
   size_t length;
+  bool keyEscaped;
+  bool valueEscaped;
 } SSmlKv;
 
 #define QUERY_ASC_FORWARD_STEP  1
diff --git a/include/common/tmsg.h b/include/common/tmsg.h
index da482c9ebc..9b01532839 100644
--- a/include/common/tmsg.h
+++ b/include/common/tmsg.h
@@ -415,7 +415,7 @@ static FORCE_INLINE SSchemaWrapper* tCloneSSchemaWrapper(const SSchemaWrapper* p
   return pSW;
 }
 
-static FORCE_INLINE void tDeleteSSchemaWrapper(SSchemaWrapper* pSchemaWrapper) {
+static FORCE_INLINE void tDeleteSchemaWrapper(SSchemaWrapper* pSchemaWrapper) {
   if (pSchemaWrapper) {
     taosMemoryFree(pSchemaWrapper->pSchema);
     taosMemoryFree(pSchemaWrapper);
@@ -689,6 +689,7 @@ typedef struct {
 
 int32_t tSerializeSAlterUserReq(void* buf, int32_t bufLen, SAlterUserReq* pReq);
 int32_t tDeserializeSAlterUserReq(void* buf, int32_t bufLen, SAlterUserReq* pReq);
+void    tFreeSAlterUserReq(SAlterUserReq* pReq);
 
 typedef struct {
   char user[TSDB_USER_LEN];
@@ -3433,10 +3434,10 @@ typedef struct {
   char     data[];  // SSubmitReq2
 } SSubmitReq2Msg;
 
-int32_t tEncodeSSubmitReq2(SEncoder* pCoder, const SSubmitReq2* pReq);
-int32_t tDecodeSSubmitReq2(SDecoder* pCoder, SSubmitReq2* pReq);
-void    tDestroySSubmitTbData(SSubmitTbData* pTbData, int32_t flag);
-void    tDestroySSubmitReq2(SSubmitReq2* pReq, int32_t flag);
+int32_t tEncodeSubmitReq(SEncoder* pCoder, const SSubmitReq2* pReq);
+int32_t tDecodeSubmitReq(SDecoder* pCoder, SSubmitReq2* pReq);
+void    tDestroySubmitTbData(SSubmitTbData* pTbData, int32_t flag);
+void    tDestroySubmitReq(SSubmitReq2* pReq, int32_t flag);
 
 typedef struct {
   int32_t affectedRows;
diff --git a/include/common/ttokendef.h b/include/common/ttokendef.h
index 641cbbb588..10b5328e6d 100644
--- a/include/common/ttokendef.h
+++ b/include/common/ttokendef.h
@@ -16,335 +16,336 @@
 #ifndef _TD_COMMON_TOKEN_H_
 #define _TD_COMMON_TOKEN_H_
 
-#define TK_OR                   1
-#define TK_AND                  2
-#define TK_UNION                3
-#define TK_ALL                  4
-#define TK_MINUS                5
-#define TK_EXCEPT               6
-#define TK_INTERSECT            7
-#define TK_NK_BITAND            8
-#define TK_NK_BITOR             9
-#define TK_NK_LSHIFT            10
-#define TK_NK_RSHIFT            11
-#define TK_NK_PLUS              12
-#define TK_NK_MINUS             13
-#define TK_NK_STAR              14
-#define TK_NK_SLASH             15
-#define TK_NK_REM               16
-#define TK_NK_CONCAT            17
-#define TK_CREATE               18
-#define TK_ACCOUNT              19
-#define TK_NK_ID                20
-#define TK_PASS                 21
-#define TK_NK_STRING            22
-#define TK_ALTER                23
-#define TK_PPS                  24
-#define TK_TSERIES              25
-#define TK_STORAGE              26
-#define TK_STREAMS              27
-#define TK_QTIME                28
-#define TK_DBS                  29
-#define TK_USERS                30
-#define TK_CONNS                31
-#define TK_STATE                32
-#define TK_USER                 33
-#define TK_ENABLE               34
-#define TK_NK_INTEGER           35
-#define TK_SYSINFO              36
-#define TK_DROP                 37
-#define TK_GRANT                38
-#define TK_ON                   39
-#define TK_TO                   40
-#define TK_REVOKE               41
-#define TK_FROM                 42
-#define TK_SUBSCRIBE            43
-#define TK_NK_COMMA             44
-#define TK_READ                 45
-#define TK_WRITE                46
-#define TK_NK_DOT               47
-#define TK_WITH                 48
-#define TK_DNODE                49
-#define TK_PORT                 50
-#define TK_DNODES               51
-#define TK_NK_IPTOKEN           52
-#define TK_FORCE                53
-#define TK_LOCAL                54
-#define TK_QNODE                55
-#define TK_BNODE                56
-#define TK_SNODE                57
-#define TK_MNODE                58
-#define TK_DATABASE             59
-#define TK_USE                  60
-#define TK_FLUSH                61
-#define TK_TRIM                 62
-#define TK_COMPACT              63
-#define TK_IF                   64
-#define TK_NOT                  65
-#define TK_EXISTS               66
-#define TK_BUFFER               67
-#define TK_CACHEMODEL           68
-#define TK_CACHESIZE            69
-#define TK_COMP                 70
-#define TK_DURATION             71
-#define TK_NK_VARIABLE          72
-#define TK_MAXROWS              73
-#define TK_MINROWS              74
-#define TK_KEEP                 75
-#define TK_PAGES                76
-#define TK_PAGESIZE             77
-#define TK_TSDB_PAGESIZE        78
-#define TK_PRECISION            79
-#define TK_REPLICA              80
-#define TK_VGROUPS              81
-#define TK_SINGLE_STABLE        82
-#define TK_RETENTIONS           83
-#define TK_SCHEMALESS           84
-#define TK_WAL_LEVEL            85
-#define TK_WAL_FSYNC_PERIOD     86
-#define TK_WAL_RETENTION_PERIOD 87
-#define TK_WAL_RETENTION_SIZE   88
-#define TK_WAL_ROLL_PERIOD      89
-#define TK_WAL_SEGMENT_SIZE     90
-#define TK_STT_TRIGGER          91
-#define TK_TABLE_PREFIX         92
-#define TK_TABLE_SUFFIX         93
-#define TK_NK_COLON             94
-#define TK_MAX_SPEED            95
-#define TK_START                96
-#define TK_TIMESTAMP            97
-#define TK_END                  98
-#define TK_TABLE                99
-#define TK_NK_LP                100
-#define TK_NK_RP                101
-#define TK_STABLE               102
-#define TK_ADD                  103
-#define TK_COLUMN               104
-#define TK_MODIFY               105
-#define TK_RENAME               106
-#define TK_TAG                  107
-#define TK_SET                  108
-#define TK_NK_EQ                109
-#define TK_USING                110
-#define TK_TAGS                 111
-#define TK_BOOL                 112
-#define TK_TINYINT              113
-#define TK_SMALLINT             114
-#define TK_INT                  115
-#define TK_INTEGER              116
-#define TK_BIGINT               117
-#define TK_FLOAT                118
-#define TK_DOUBLE               119
-#define TK_BINARY               120
-#define TK_NCHAR                121
-#define TK_UNSIGNED             122
-#define TK_JSON                 123
-#define TK_VARCHAR              124
-#define TK_MEDIUMBLOB           125
-#define TK_BLOB                 126
-#define TK_VARBINARY            127
-#define TK_DECIMAL              128
-#define TK_COMMENT              129
-#define TK_MAX_DELAY            130
-#define TK_WATERMARK            131
-#define TK_ROLLUP               132
-#define TK_TTL                  133
-#define TK_SMA                  134
-#define TK_DELETE_MARK          135
-#define TK_FIRST                136
-#define TK_LAST                 137
-#define TK_SHOW                 138
-#define TK_PRIVILEGES           139
-#define TK_DATABASES            140
-#define TK_TABLES               141
-#define TK_STABLES              142
-#define TK_MNODES               143
-#define TK_QNODES               144
-#define TK_FUNCTIONS            145
-#define TK_INDEXES              146
-#define TK_ACCOUNTS             147
-#define TK_APPS                 148
-#define TK_CONNECTIONS          149
-#define TK_LICENCES             150
-#define TK_GRANTS               151
-#define TK_QUERIES              152
-#define TK_SCORES               153
-#define TK_TOPICS               154
-#define TK_VARIABLES            155
-#define TK_CLUSTER              156
-#define TK_BNODES               157
-#define TK_SNODES               158
-#define TK_TRANSACTIONS         159
-#define TK_DISTRIBUTED          160
-#define TK_CONSUMERS            161
-#define TK_SUBSCRIPTIONS        162
-#define TK_VNODES               163
-#define TK_ALIVE                164
-#define TK_LIKE                 165
-#define TK_TBNAME               166
-#define TK_QTAGS                167
-#define TK_AS                   168
-#define TK_INDEX                169
-#define TK_FUNCTION             170
-#define TK_INTERVAL             171
-#define TK_COUNT                172
-#define TK_LAST_ROW             173
-#define TK_TOPIC                174
-#define TK_META                 175
-#define TK_CONSUMER             176
-#define TK_GROUP                177
-#define TK_DESC                 178
-#define TK_DESCRIBE             179
-#define TK_RESET                180
-#define TK_QUERY                181
-#define TK_CACHE                182
-#define TK_EXPLAIN              183
-#define TK_ANALYZE              184
-#define TK_VERBOSE              185
-#define TK_NK_BOOL              186
-#define TK_RATIO                187
-#define TK_NK_FLOAT             188
-#define TK_OUTPUTTYPE           189
-#define TK_AGGREGATE            190
-#define TK_BUFSIZE              191
-#define TK_LANGUAGE             192
-#define TK_REPLACE              193
-#define TK_STREAM               194
-#define TK_INTO                 195
-#define TK_TRIGGER              196
-#define TK_AT_ONCE              197
-#define TK_WINDOW_CLOSE         198
-#define TK_IGNORE               199
-#define TK_EXPIRED              200
-#define TK_FILL_HISTORY         201
-#define TK_UPDATE               202
-#define TK_SUBTABLE             203
-#define TK_KILL                 204
-#define TK_CONNECTION           205
-#define TK_TRANSACTION          206
-#define TK_BALANCE              207
-#define TK_VGROUP               208
-#define TK_LEADER               209
-#define TK_MERGE                210
-#define TK_REDISTRIBUTE         211
-#define TK_SPLIT                212
-#define TK_DELETE               213
-#define TK_INSERT               214
-#define TK_NULL                 215
-#define TK_NK_QUESTION          216
-#define TK_NK_ARROW             217
-#define TK_ROWTS                218
-#define TK_QSTART               219
-#define TK_QEND                 220
-#define TK_QDURATION            221
-#define TK_WSTART               222
-#define TK_WEND                 223
-#define TK_WDURATION            224
-#define TK_IROWTS               225
-#define TK_ISFILLED             226
-#define TK_CAST                 227
-#define TK_NOW                  228
-#define TK_TODAY                229
-#define TK_TIMEZONE             230
-#define TK_CLIENT_VERSION       231
-#define TK_SERVER_VERSION       232
-#define TK_SERVER_STATUS        233
-#define TK_CURRENT_USER         234
-#define TK_CASE                 235
-#define TK_WHEN                 236
-#define TK_THEN                 237
-#define TK_ELSE                 238
-#define TK_BETWEEN              239
-#define TK_IS                   240
-#define TK_NK_LT                241
-#define TK_NK_GT                242
-#define TK_NK_LE                243
-#define TK_NK_GE                244
-#define TK_NK_NE                245
-#define TK_MATCH                246
-#define TK_NMATCH               247
-#define TK_CONTAINS             248
-#define TK_IN                   249
-#define TK_JOIN                 250
-#define TK_INNER                251
-#define TK_SELECT               252
-#define TK_DISTINCT             253
-#define TK_WHERE                254
-#define TK_PARTITION            255
-#define TK_BY                   256
-#define TK_SESSION              257
-#define TK_STATE_WINDOW         258
-#define TK_EVENT_WINDOW         259
-#define TK_SLIDING              260
-#define TK_FILL                 261
-#define TK_VALUE                262
-#define TK_VALUE_F              263
-#define TK_NONE                 264
-#define TK_PREV                 265
-#define TK_NULL_F               266
-#define TK_LINEAR               267
-#define TK_NEXT                 268
-#define TK_HAVING               269
-#define TK_RANGE                270
-#define TK_EVERY                271
-#define TK_ORDER                272
-#define TK_SLIMIT               273
-#define TK_SOFFSET              274
-#define TK_LIMIT                275
-#define TK_OFFSET               276
-#define TK_ASC                  277
-#define TK_NULLS                278
-#define TK_ABORT                279
-#define TK_AFTER                280
-#define TK_ATTACH               281
-#define TK_BEFORE               282
-#define TK_BEGIN                283
-#define TK_BITAND               284
-#define TK_BITNOT               285
-#define TK_BITOR                286
-#define TK_BLOCKS               287
-#define TK_CHANGE               288
-#define TK_COMMA                289
-#define TK_CONCAT               290
-#define TK_CONFLICT             291
-#define TK_COPY                 292
-#define TK_DEFERRED             293
-#define TK_DELIMITERS           294
-#define TK_DETACH               295
-#define TK_DIVIDE               296
-#define TK_DOT                  297
-#define TK_EACH                 298
-#define TK_FAIL                 299
-#define TK_FILE                 300
-#define TK_FOR                  301
-#define TK_GLOB                 302
-#define TK_ID                   303
-#define TK_IMMEDIATE            304
-#define TK_IMPORT               305
-#define TK_INITIALLY            306
-#define TK_INSTEAD              307
-#define TK_ISNULL               308
-#define TK_KEY                  309
-#define TK_MODULES              310
-#define TK_NK_BITNOT            311
-#define TK_NK_SEMI              312
-#define TK_NOTNULL              313
-#define TK_OF                   314
-#define TK_PLUS                 315
-#define TK_PRIVILEGE            316
-#define TK_RAISE                317
-#define TK_RESTRICT             318
-#define TK_ROW                  319
-#define TK_SEMI                 320
-#define TK_STAR                 321
-#define TK_STATEMENT            322
-#define TK_STRICT               323
-#define TK_STRING               324
-#define TK_TIMES                325
-#define TK_VALUES               326
-#define TK_VARIABLE             327
-#define TK_VIEW                 328
-#define TK_WAL                  329
+#define TK_OR                               1
+#define TK_AND                              2
+#define TK_UNION                            3
+#define TK_ALL                              4
+#define TK_MINUS                            5
+#define TK_EXCEPT                           6
+#define TK_INTERSECT                        7
+#define TK_NK_BITAND                        8
+#define TK_NK_BITOR                         9
+#define TK_NK_LSHIFT                       10
+#define TK_NK_RSHIFT                       11
+#define TK_NK_PLUS                         12
+#define TK_NK_MINUS                        13
+#define TK_NK_STAR                         14
+#define TK_NK_SLASH                        15
+#define TK_NK_REM                          16
+#define TK_NK_CONCAT                       17
+#define TK_CREATE                          18
+#define TK_ACCOUNT                         19
+#define TK_NK_ID                           20
+#define TK_PASS                            21
+#define TK_NK_STRING                       22
+#define TK_ALTER                           23
+#define TK_PPS                             24
+#define TK_TSERIES                         25
+#define TK_STORAGE                         26
+#define TK_STREAMS                         27
+#define TK_QTIME                           28
+#define TK_DBS                             29
+#define TK_USERS                           30
+#define TK_CONNS                           31
+#define TK_STATE                           32
+#define TK_USER                            33
+#define TK_ENABLE                          34
+#define TK_NK_INTEGER                      35
+#define TK_SYSINFO                         36
+#define TK_DROP                            37
+#define TK_GRANT                           38
+#define TK_ON                              39
+#define TK_TO                              40
+#define TK_REVOKE                          41
+#define TK_FROM                            42
+#define TK_SUBSCRIBE                       43
+#define TK_NK_COMMA                        44
+#define TK_READ                            45
+#define TK_WRITE                           46
+#define TK_NK_DOT                          47
+#define TK_WITH                            48
+#define TK_DNODE                           49
+#define TK_PORT                            50
+#define TK_DNODES                          51
+#define TK_NK_IPTOKEN                      52
+#define TK_FORCE                           53
+#define TK_LOCAL                           54
+#define TK_QNODE                           55
+#define TK_BNODE                           56
+#define TK_SNODE                           57
+#define TK_MNODE                           58
+#define TK_DATABASE                        59
+#define TK_USE                             60
+#define TK_FLUSH                           61
+#define TK_TRIM                            62
+#define TK_COMPACT                         63
+#define TK_IF                              64
+#define TK_NOT                             65
+#define TK_EXISTS                          66
+#define TK_BUFFER                          67
+#define TK_CACHEMODEL                      68
+#define TK_CACHESIZE                       69
+#define TK_COMP                            70
+#define TK_DURATION                        71
+#define TK_NK_VARIABLE                     72
+#define TK_MAXROWS                         73
+#define TK_MINROWS                         74
+#define TK_KEEP                            75
+#define TK_PAGES                           76
+#define TK_PAGESIZE                        77
+#define TK_TSDB_PAGESIZE                   78
+#define TK_PRECISION                       79
+#define TK_REPLICA                         80
+#define TK_VGROUPS                         81
+#define TK_SINGLE_STABLE                   82
+#define TK_RETENTIONS                      83
+#define TK_SCHEMALESS                      84
+#define TK_WAL_LEVEL                       85
+#define TK_WAL_FSYNC_PERIOD                86
+#define TK_WAL_RETENTION_PERIOD            87
+#define TK_WAL_RETENTION_SIZE              88
+#define TK_WAL_ROLL_PERIOD                 89
+#define TK_WAL_SEGMENT_SIZE                90
+#define TK_STT_TRIGGER                     91
+#define TK_TABLE_PREFIX                    92
+#define TK_TABLE_SUFFIX                    93
+#define TK_NK_COLON                        94
+#define TK_MAX_SPEED                       95
+#define TK_START                           96
+#define TK_TIMESTAMP                       97
+#define TK_END                             98
+#define TK_TABLE                           99
+#define TK_NK_LP                          100
+#define TK_NK_RP                          101
+#define TK_STABLE                         102
+#define TK_ADD                            103
+#define TK_COLUMN                         104
+#define TK_MODIFY                         105
+#define TK_RENAME                         106
+#define TK_TAG                            107
+#define TK_SET                            108
+#define TK_NK_EQ                          109
+#define TK_USING                          110
+#define TK_TAGS                           111
+#define TK_BOOL                           112
+#define TK_TINYINT                        113
+#define TK_SMALLINT                       114
+#define TK_INT                            115
+#define TK_INTEGER                        116
+#define TK_BIGINT                         117
+#define TK_FLOAT                          118
+#define TK_DOUBLE                         119
+#define TK_BINARY                         120
+#define TK_NCHAR                          121
+#define TK_UNSIGNED                       122
+#define TK_JSON                           123
+#define TK_VARCHAR                        124
+#define TK_MEDIUMBLOB                     125
+#define TK_BLOB                           126
+#define TK_VARBINARY                      127
+#define TK_DECIMAL                        128
+#define TK_COMMENT                        129
+#define TK_MAX_DELAY                      130
+#define TK_WATERMARK                      131
+#define TK_ROLLUP                         132
+#define TK_TTL                            133
+#define TK_SMA                            134
+#define TK_DELETE_MARK                    135
+#define TK_FIRST                          136
+#define TK_LAST                           137
+#define TK_SHOW                           138
+#define TK_PRIVILEGES                     139
+#define TK_DATABASES                      140
+#define TK_TABLES                         141
+#define TK_STABLES                        142
+#define TK_MNODES                         143
+#define TK_QNODES                         144
+#define TK_FUNCTIONS                      145
+#define TK_INDEXES                        146
+#define TK_ACCOUNTS                       147
+#define TK_APPS                           148
+#define TK_CONNECTIONS                    149
+#define TK_LICENCES                       150
+#define TK_GRANTS                         151
+#define TK_QUERIES                        152
+#define TK_SCORES                         153
+#define TK_TOPICS                         154
+#define TK_VARIABLES                      155
+#define TK_CLUSTER                        156
+#define TK_BNODES                         157
+#define TK_SNODES                         158
+#define TK_TRANSACTIONS                   159
+#define TK_DISTRIBUTED                    160
+#define TK_CONSUMERS                      161
+#define TK_SUBSCRIPTIONS                  162
+#define TK_VNODES                         163
+#define TK_ALIVE                          164
+#define TK_LIKE                           165
+#define TK_TBNAME                         166
+#define TK_QTAGS                          167
+#define TK_AS                             168
+#define TK_INDEX                          169
+#define TK_FUNCTION                       170
+#define TK_INTERVAL                       171
+#define TK_COUNT                          172
+#define TK_LAST_ROW                       173
+#define TK_TOPIC                          174
+#define TK_META                           175
+#define TK_CONSUMER                       176
+#define TK_GROUP                          177
+#define TK_DESC                           178
+#define TK_DESCRIBE                       179
+#define TK_RESET                          180
+#define TK_QUERY                          181
+#define TK_CACHE                          182
+#define TK_EXPLAIN                        183
+#define TK_ANALYZE                        184
+#define TK_VERBOSE                        185
+#define TK_NK_BOOL                        186
+#define TK_RATIO                          187
+#define TK_NK_FLOAT                       188
+#define TK_OUTPUTTYPE                     189
+#define TK_AGGREGATE                      190
+#define TK_BUFSIZE                        191
+#define TK_LANGUAGE                       192
+#define TK_REPLACE                        193
+#define TK_STREAM                         194
+#define TK_INTO                           195
+#define TK_TRIGGER                        196
+#define TK_AT_ONCE                        197
+#define TK_WINDOW_CLOSE                   198
+#define TK_IGNORE                         199
+#define TK_EXPIRED                        200
+#define TK_FILL_HISTORY                   201
+#define TK_UPDATE                         202
+#define TK_SUBTABLE                       203
+#define TK_KILL                           204
+#define TK_CONNECTION                     205
+#define TK_TRANSACTION                    206
+#define TK_BALANCE                        207
+#define TK_VGROUP                         208
+#define TK_LEADER                         209
+#define TK_MERGE                          210
+#define TK_REDISTRIBUTE                   211
+#define TK_SPLIT                          212
+#define TK_DELETE                         213
+#define TK_INSERT                         214
+#define TK_NULL                           215
+#define TK_NK_QUESTION                    216
+#define TK_NK_ARROW                       217
+#define TK_ROWTS                          218
+#define TK_QSTART                         219
+#define TK_QEND                           220
+#define TK_QDURATION                      221
+#define TK_WSTART                         222
+#define TK_WEND                           223
+#define TK_WDURATION                      224
+#define TK_IROWTS                         225
+#define TK_ISFILLED                       226
+#define TK_CAST                           227
+#define TK_NOW                            228
+#define TK_TODAY                          229
+#define TK_TIMEZONE                       230
+#define TK_CLIENT_VERSION                 231
+#define TK_SERVER_VERSION                 232
+#define TK_SERVER_STATUS                  233
+#define TK_CURRENT_USER                   234
+#define TK_CASE                           235
+#define TK_WHEN                           236
+#define TK_THEN                           237
+#define TK_ELSE                           238
+#define TK_BETWEEN                        239
+#define TK_IS                             240
+#define TK_NK_LT                          241
+#define TK_NK_GT                          242
+#define TK_NK_LE                          243
+#define TK_NK_GE                          244
+#define TK_NK_NE                          245
+#define TK_MATCH                          246
+#define TK_NMATCH                         247
+#define TK_CONTAINS                       248
+#define TK_IN                             249
+#define TK_JOIN                           250
+#define TK_INNER                          251
+#define TK_SELECT                         252
+#define TK_DISTINCT                       253
+#define TK_WHERE                          254
+#define TK_PARTITION                      255
+#define TK_BY                             256
+#define TK_SESSION                        257
+#define TK_STATE_WINDOW                   258
+#define TK_EVENT_WINDOW                   259
+#define TK_SLIDING                        260
+#define TK_FILL                           261
+#define TK_VALUE                          262
+#define TK_VALUE_F                        263
+#define TK_NONE                           264
+#define TK_PREV                           265
+#define TK_NULL_F                         266
+#define TK_LINEAR                         267
+#define TK_NEXT                           268
+#define TK_HAVING                         269
+#define TK_RANGE                          270
+#define TK_EVERY                          271
+#define TK_ORDER                          272
+#define TK_SLIMIT                         273
+#define TK_SOFFSET                        274
+#define TK_LIMIT                          275
+#define TK_OFFSET                         276
+#define TK_ASC                            277
+#define TK_NULLS                          278
+#define TK_ABORT                          279
+#define TK_AFTER                          280
+#define TK_ATTACH                         281
+#define TK_BEFORE                         282
+#define TK_BEGIN                          283
+#define TK_BITAND                         284
+#define TK_BITNOT                         285
+#define TK_BITOR                          286
+#define TK_BLOCKS                         287
+#define TK_CHANGE                         288
+#define TK_COMMA                          289
+#define TK_CONCAT                         290
+#define TK_CONFLICT                       291
+#define TK_COPY                           292
+#define TK_DEFERRED                       293
+#define TK_DELIMITERS                     294
+#define TK_DETACH                         295
+#define TK_DIVIDE                         296
+#define TK_DOT                            297
+#define TK_EACH                           298
+#define TK_FAIL                           299
+#define TK_FILE                           300
+#define TK_FOR                            301
+#define TK_GLOB                           302
+#define TK_ID                             303
+#define TK_IMMEDIATE                      304
+#define TK_IMPORT                         305
+#define TK_INITIALLY                      306
+#define TK_INSTEAD                        307
+#define TK_ISNULL                         308
+#define TK_KEY                            309
+#define TK_MODULES                        310
+#define TK_NK_BITNOT                      311
+#define TK_NK_SEMI                        312
+#define TK_NOTNULL                        313
+#define TK_OF                             314
+#define TK_PLUS                           315
+#define TK_PRIVILEGE                      316
+#define TK_RAISE                          317
+#define TK_RESTRICT                       318
+#define TK_ROW                            319
+#define TK_SEMI                           320
+#define TK_STAR                           321
+#define TK_STATEMENT                      322
+#define TK_STRICT                         323
+#define TK_STRING                         324
+#define TK_TIMES                          325
+#define TK_VALUES                         326
+#define TK_VARIABLE                       327
+#define TK_VIEW                           328
+#define TK_WAL                            329
+
 
 #define TK_NK_SPACE   600
 #define TK_NK_COMMENT 601
diff --git a/include/libs/catalog/catalog.h b/include/libs/catalog/catalog.h
index 48b312967a..9250bda592 100644
--- a/include/libs/catalog/catalog.h
+++ b/include/libs/catalog/catalog.h
@@ -82,6 +82,7 @@ typedef struct SCatalogReq {
   SArray* pUser;          // element is SUserAuthInfo
   SArray* pTableIndex;    // element is SNAME
   SArray* pTableCfg;      // element is SNAME
+  SArray* pTableTag;      // element is SNAME
   bool    qNodeRequired;  // valid qnode
   bool    dNodeRequired;  // valid dnode
   bool    svrVerRequired;
@@ -105,6 +106,7 @@ typedef struct SMetaData {
   SArray*   pUser;        // pRes = SUserAuthRes*
   SArray*   pQnodeList;   // pRes = SArray*
   SArray*   pTableCfg;    // pRes = STableCfg*
+  SArray*   pTableTag;    // pRes = SArray*
   SArray*   pDnodeList;   // pRes = SArray*
   SMetaRes* pSvrVer;      // pRes = char*
 } SMetaData;
@@ -122,8 +124,8 @@ typedef struct SSTableVersion {
   char     stbName[TSDB_TABLE_NAME_LEN];
   uint64_t dbId;
   uint64_t suid;
-  int16_t  sversion;
-  int16_t  tversion;
+  int32_t  sversion;
+  int32_t  tversion;
   int32_t  smaVer;
 } SSTableVersion;
 
@@ -314,6 +316,8 @@ int32_t catalogGetIndexMeta(SCatalog* pCtg, SRequestConnInfo* pConn, const char*
 
 int32_t catalogGetTableIndex(SCatalog* pCtg, SRequestConnInfo* pConn, const SName* pTableName, SArray** pRes);
 
+int32_t catalogGetTableTag(SCatalog* pCtg, SRequestConnInfo* pConn, const SName* pTableName, SArray** pRes);
+
 int32_t catalogRefreshGetTableCfg(SCatalog* pCtg, SRequestConnInfo* pConn, const SName* pTableName, STableCfg** pCfg);
 
 int32_t catalogUpdateTableIndex(SCatalog* pCtg, STableIndexRsp* pRsp);
diff --git a/include/libs/executor/executor.h b/include/libs/executor/executor.h
index 34372dc2ff..b7e6c42e3b 100644
--- a/include/libs/executor/executor.h
+++ b/include/libs/executor/executor.h
@@ -190,9 +190,9 @@ STimeWindow getAlignQueryTimeWindow(SInterval* pInterval, int32_t precision, int
 
 SArray* qGetQueriedTableListInfo(qTaskInfo_t tinfo);
 
-int32_t qStreamPrepareScan(qTaskInfo_t tinfo, STqOffsetVal* pOffset, int8_t subType);
+void verifyOffset(void *pWalReader, STqOffsetVal* pOffset);
 
-int32_t qStreamSetScanMemData(qTaskInfo_t tinfo, SPackedData submit);
+int32_t qStreamPrepareScan(qTaskInfo_t tinfo, STqOffsetVal* pOffset, int8_t subType);
 
 void qStreamSetOpen(qTaskInfo_t tinfo);
 
@@ -208,8 +208,6 @@ void* qExtractReaderFromStreamScanner(void* scanner);
 
 int32_t qExtractStreamScanner(qTaskInfo_t tinfo, void** scanner);
 
-int32_t qStreamInput(qTaskInfo_t tinfo, void* pItem);
-
 int32_t qStreamSetParamForRecover(qTaskInfo_t tinfo);
 int32_t qStreamSourceRecoverStep1(qTaskInfo_t tinfo, int64_t ver);
 int32_t qStreamSourceRecoverStep2(qTaskInfo_t tinfo, int64_t ver);
diff --git a/include/libs/nodes/querynodes.h b/include/libs/nodes/querynodes.h
index 480912a8cf..9569cfe055 100644
--- a/include/libs/nodes/querynodes.h
+++ b/include/libs/nodes/querynodes.h
@@ -379,6 +379,8 @@ typedef struct SVnodeModifyOpStmt {
   SName                 usingTableName;
   const char*           pBoundCols;
   struct STableMeta*    pTableMeta;
+  SNode*                pTagCond;
+  SArray*               pTableTag;
   SHashObj*             pVgroupsHashObj;
   SHashObj*             pTableBlockHashObj;  // SHashObj
   SHashObj*             pSubTableHashObj;
diff --git a/include/libs/qcom/query.h b/include/libs/qcom/query.h
index afbc1b06a7..69aa315ec2 100644
--- a/include/libs/qcom/query.h
+++ b/include/libs/qcom/query.h
@@ -116,8 +116,8 @@ typedef struct STableMeta {
 
   // if the table is TSDB_CHILD_TABLE, the following information is acquired from the corresponding super table meta
   // info
-  int16_t       sversion;
-  int16_t       tversion;
+  int32_t       sversion;
+  int32_t       tversion;
   STableComInfo tableInfo;
   SSchema       schema[];
 } STableMeta;
diff --git a/include/libs/stream/tstream.h b/include/libs/stream/tstream.h
index 78fd9bed5d..5fd9a8b12b 100644
--- a/include/libs/stream/tstream.h
+++ b/include/libs/stream/tstream.h
@@ -50,7 +50,6 @@ enum {
   TASK_STATUS__RECOVER_PREPARE,
   TASK_STATUS__RECOVER1,
   TASK_STATUS__RECOVER2,
-  TASK_STATUS__RESTORE,  // only available for source task to replay WAL from the checkpoint
 };
 
 enum {
@@ -341,12 +340,13 @@ typedef struct SStreamMeta {
   TTB*         pTaskDb;
   TTB*         pCheckpointDb;
   SHashObj*    pTasks;
+  SArray*      pTaskList;   // SArray
   void*        ahandle;
   TXN*         txn;
   FTaskExpand* expandFunc;
   int32_t      vgId;
   SRWLatch     lock;
-  int32_t      walScan;
+  int32_t      walScanCounter;
 } SStreamMeta;
 
 int32_t tEncodeStreamEpInfo(SEncoder* pEncoder, const SStreamChildEpInfo* pInfo);
@@ -545,8 +545,9 @@ int32_t streamScanExec(SStreamTask* pTask, int32_t batchSz);
 // recover and fill history
 int32_t streamTaskCheckDownstream(SStreamTask* pTask, int64_t version);
 int32_t streamTaskLaunchRecover(SStreamTask* pTask, int64_t version);
-int32_t streamProcessTaskCheckReq(SStreamTask* pTask, const SStreamTaskCheckReq* pReq);
+int32_t streamTaskCheckStatus(SStreamTask* pTask);
 int32_t streamProcessTaskCheckRsp(SStreamTask* pTask, const SStreamTaskCheckRsp* pRsp, int64_t version);
+
 // common
 int32_t streamSetParamForRecover(SStreamTask* pTask);
 int32_t streamRestoreParam(SStreamTask* pTask);
diff --git a/include/libs/wal/wal.h b/include/libs/wal/wal.h
index b51289de5e..46dc179295 100644
--- a/include/libs/wal/wal.h
+++ b/include/libs/wal/wal.h
@@ -132,7 +132,7 @@ typedef struct {
 } SWalRef;
 
 typedef struct {
-  int8_t scanUncommited;
+//  int8_t scanUncommited;
   int8_t scanNotApplied;
   int8_t scanMeta;
   int8_t enableRef;
@@ -147,8 +147,6 @@ typedef struct SWalReader {
   int64_t        curFileFirstVer;
   int64_t        curVersion;
   int64_t        capacity;
-//  int8_t         curInvalid;
-//  int8_t         curStopped;
   TdThreadMutex  mutex;
   SWalFilterCond cond;
   // TODO remove it
diff --git a/include/util/taoserror.h b/include/util/taoserror.h
index ab89466a19..80630c1358 100644
--- a/include/util/taoserror.h
+++ b/include/util/taoserror.h
@@ -146,7 +146,7 @@ int32_t* taosGetErrno();
 #define TSDB_CODE_TSC_CONN_KILLED               TAOS_DEF_ERROR_CODE(0, 0x0215)
 #define TSDB_CODE_TSC_SQL_SYNTAX_ERROR          TAOS_DEF_ERROR_CODE(0, 0x0216)
 #define TSDB_CODE_TSC_DB_NOT_SELECTED           TAOS_DEF_ERROR_CODE(0, 0x0217)
-#define TSDB_CODE_TSC_INVALID_TABLE_NAME        TAOS_DEF_ERROR_CODE(0, 0x0218)
+//#define TSDB_CODE_TSC_INVALID_TABLE_NAME        TAOS_DEF_ERROR_CODE(0, 0x0218)
 #define TSDB_CODE_TSC_EXCEED_SQL_LIMIT          TAOS_DEF_ERROR_CODE(0, 0x0219)
 #define TSDB_CODE_TSC_FILE_EMPTY                TAOS_DEF_ERROR_CODE(0, 0x021A)
 #define TSDB_CODE_TSC_LINE_SYNTAX_ERROR         TAOS_DEF_ERROR_CODE(0, 0x021B)
@@ -261,6 +261,7 @@ int32_t* taosGetErrno();
 // #define TSDB_CODE_MND_INVALID_STABLE_NAME    TAOS_DEF_ERROR_CODE(0, 0x036D) // 2.x
 #define TSDB_CODE_MND_INVALID_STB_OPTION        TAOS_DEF_ERROR_CODE(0, 0x036E)
 #define TSDB_CODE_MND_INVALID_ROW_BYTES         TAOS_DEF_ERROR_CODE(0, 0x036F)
+#define TSDB_CODE_MND_FIELD_VALUE_OVERFLOW           TAOS_DEF_ERROR_CODE(0, 0x0370)
 
 
 // mnode-func
diff --git a/include/util/tdef.h b/include/util/tdef.h
index 2f86395dad..680620a094 100644
--- a/include/util/tdef.h
+++ b/include/util/tdef.h
@@ -368,11 +368,11 @@ typedef enum ELogicConditionType {
 #define TSDB_MIN_STT_TRIGGER            1
 #define TSDB_MAX_STT_TRIGGER            16
 #define TSDB_DEFAULT_SST_TRIGGER        1
-#define TSDB_MIN_HASH_PREFIX            0
-#define TSDB_MAX_HASH_PREFIX            128
+#define TSDB_MIN_HASH_PREFIX            (2 - TSDB_TABLE_NAME_LEN)
+#define TSDB_MAX_HASH_PREFIX            (TSDB_TABLE_NAME_LEN - 2)
 #define TSDB_DEFAULT_HASH_PREFIX        0
-#define TSDB_MIN_HASH_SUFFIX            0
-#define TSDB_MAX_HASH_SUFFIX            128
+#define TSDB_MIN_HASH_SUFFIX            (2 - TSDB_TABLE_NAME_LEN)
+#define TSDB_MAX_HASH_SUFFIX            (TSDB_TABLE_NAME_LEN - 2)
 #define TSDB_DEFAULT_HASH_SUFFIX        0
 
 #define TSDB_DB_MIN_WAL_RETENTION_PERIOD -1
diff --git a/include/util/tutil.h b/include/util/tutil.h
index e0801e5295..7a59aa170a 100644
--- a/include/util/tutil.h
+++ b/include/util/tutil.h
@@ -81,14 +81,22 @@ static FORCE_INLINE void taosEncryptPass_c(uint8_t *inBuf, size_t len, char *tar
 
 static FORCE_INLINE int32_t taosGetTbHashVal(const char *tbname, int32_t tblen, int32_t method, int32_t prefix,
                                              int32_t suffix) {
-  if (prefix == 0 && suffix == 0) {
+  if ((prefix == 0 && suffix == 0) || (tblen <= (prefix + suffix)) || (tblen <= -1 * (prefix + suffix)) || prefix * suffix < 0) {
     return MurmurHash3_32(tbname, tblen);
+  } else if (prefix > 0 || suffix > 0) {
+    return MurmurHash3_32(tbname + prefix, tblen - prefix - suffix);
   } else {
-    if (tblen <= (prefix + suffix)) {
-      return MurmurHash3_32(tbname, tblen);
-    } else {
-      return MurmurHash3_32(tbname + prefix, tblen - prefix - suffix);
+    char tbName[TSDB_TABLE_FNAME_LEN];
+    int32_t offset = 0;
+    if (prefix < 0) {
+      offset = -1 * prefix;
+      strncpy(tbName, tbname, offset);
     }
+    if (suffix < 0) {
+      strncpy(tbName + offset, tbname + tblen + suffix, -1 * suffix);
+      offset += -1 *suffix;
+    }
+    return MurmurHash3_32(tbName, offset);
   }
 }
 
@@ -98,6 +106,8 @@ static FORCE_INLINE int32_t taosGetTbHashVal(const char *tbname, int32_t tblen,
     goto LABEL;                            \
   }
 
+#define VND_CHECK_CODE(CODE, LINO, LABEL) TSDB_CHECK_CODE(CODE, LINO, LABEL)
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/packaging/deb/DEBIAN/preinst b/packaging/deb/DEBIAN/preinst
index 8a1a7d4d81..904a946e20 100644
--- a/packaging/deb/DEBIAN/preinst
+++ b/packaging/deb/DEBIAN/preinst
@@ -26,6 +26,38 @@ if pidof taosd &> /dev/null; then
     sleep 1
 fi
 
+# Stop adapter service if running
+if pidof taosadapter &> /dev/null; then
+    if pidof systemd &> /dev/null; then
+        ${csudo}systemctl stop taosadapter || :
+    elif $(which service  &> /dev/null); then
+        ${csudo}service taosadapter stop || :
+    else
+        pid=$(ps -ef | grep "taosadapter" | grep -v "grep" | awk '{print $2}')
+        if [ -n "$pid" ]; then
+           ${csudo}kill -9 $pid   || :
+        fi
+    fi
+    echo "Stop taosadapter service success!"
+    sleep 1
+fi
+
+# Stop keeper service if running
+if pidof taoskeeper &> /dev/null; then
+    if pidof systemd &> /dev/null; then
+        ${csudo}systemctl stop taoskeeper || :
+    elif $(which service  &> /dev/null); then
+        ${csudo}service taoskeeper stop || :
+    else
+        pid=$(ps -ef | grep "taoskeeper" | grep -v "grep" | awk '{print $2}')
+        if [ -n "$pid" ]; then
+           ${csudo}kill -9 $pid   || :
+        fi
+    fi
+    echo "Stop taoskeeper service success!"
+    sleep 1
+fi
+
 # if taos.cfg already softlink, remove it
 cfg_install_dir="/etc/taos"
 install_main_dir="/usr/local/taos"
@@ -41,6 +73,11 @@ if [ -f "${install_main_dir}/taosadapter.service" ]; then
     ${csudo}rm -f ${install_main_dir}/cfg/taosadapter.service || :
 fi
 
+if [ -f "${install_main_dir}/taoskeeper.toml" ]; then
+    ${csudo}rm -f ${install_main_dir}/cfg/taoskeeper.toml     || :
+fi
+
+
 # there can not libtaos.so*, otherwise ln -s  error
 ${csudo}rm -f ${install_main_dir}/driver/libtaos.*   || :
 [ -f ${install_main_dir}/driver/libtaosws.so ] && ${csudo}rm -f ${install_main_dir}/driver/libtaosws.so   || :
diff --git a/packaging/deb/DEBIAN/prerm b/packaging/deb/DEBIAN/prerm
index 65f261db2c..0d63115a04 100644
--- a/packaging/deb/DEBIAN/prerm
+++ b/packaging/deb/DEBIAN/prerm
@@ -32,6 +32,7 @@ else
     ${csudo}rm -f ${bin_link_dir}/udfd       || :
     ${csudo}rm -f ${bin_link_dir}/taosadapter       || :
     ${csudo}rm -f ${bin_link_dir}/taosdemo   || :
+    ${csudo}rm -f ${bin_link_dir}/taoskeeper   || :
     ${csudo}rm -f ${cfg_link_dir}/*          || :
     ${csudo}rm -f ${inc_link_dir}/taos.h     || :
     ${csudo}rm -f ${inc_link_dir}/taosdef.h     || :
diff --git a/packaging/deb/makedeb.sh b/packaging/deb/makedeb.sh
index 94a24a4148..9f49cf345a 100755
--- a/packaging/deb/makedeb.sh
+++ b/packaging/deb/makedeb.sh
@@ -44,8 +44,31 @@ mkdir -p ${pkg_dir}${install_home_path}/include
 #mkdir -p ${pkg_dir}${install_home_path}/init.d
 mkdir -p ${pkg_dir}${install_home_path}/script
 
+# download taoskeeper and build
+if [ "$cpuType" = "x64" ] || [ "$cpuType" = "x86_64" ] || [ "$cpuType" = "amd64" ]; then
+  arch=amd64
+elif [ "$cpuType" = "x32" ] || [ "$cpuType" = "i386" ] || [ "$cpuType" = "i686" ]; then
+  arch=386
+elif [ "$cpuType" = "arm" ] || [ "$cpuType" = "aarch32" ]; then
+  arch=arm
+elif [ "$cpuType" = "arm64" ] || [ "$cpuType" = "aarch64" ]; then
+  arch=arm64
+else
+  arch=$cpuType
+fi
+
+echo "${top_dir}/../enterprise/packaging/build_taoskeeper.sh -r ${arch} -e taoskeeper"
+echo "$top_dir=${top_dir}"
+taoskeeper_binary=`${top_dir}/../enterprise/packaging/build_taoskeeper.sh -r $arch -e taoskeeper`
+echo "taoskeeper_binary: ${taoskeeper_binary}"
+
+# copy config files
+cp $(dirname ${taoskeeper_binary})/config/taoskeeper.toml ${pkg_dir}${install_home_path}/cfg
+cp $(dirname ${taoskeeper_binary})/taoskeeper.service ${pkg_dir}${install_home_path}/cfg
+
 cp ${compile_dir}/../packaging/cfg/taos.cfg         ${pkg_dir}${install_home_path}/cfg
 cp ${compile_dir}/../packaging/cfg/taosd.service    ${pkg_dir}${install_home_path}/cfg
+
 if [ -f "${compile_dir}/test/cfg/taosadapter.toml" ]; then
     cp ${compile_dir}/test/cfg/taosadapter.toml		${pkg_dir}${install_home_path}/cfg || :
 fi
@@ -53,6 +76,7 @@ if [ -f "${compile_dir}/test/cfg/taosadapter.service" ]; then
     cp ${compile_dir}/test/cfg/taosadapter.service	${pkg_dir}${install_home_path}/cfg || :
 fi
 
+cp ${taoskeeper_binary}                      ${pkg_dir}${install_home_path}/bin
 #cp ${compile_dir}/../packaging/deb/taosd            ${pkg_dir}${install_home_path}/init.d
 cp ${compile_dir}/../packaging/tools/post.sh        ${pkg_dir}${install_home_path}/script
 cp ${compile_dir}/../packaging/tools/preun.sh       ${pkg_dir}${install_home_path}/script
@@ -143,6 +167,7 @@ else
   exit 1
 fi
 
+rm -rf ${pkg_dir}/build-taoskeeper
 # make deb package
 dpkg -b ${pkg_dir} $debname
 echo "make deb package success!"
@@ -150,4 +175,5 @@ echo "make deb package success!"
 cp ${pkg_dir}/*.deb ${output_dir}
 
 # clean temp dir
+
 rm -rf ${pkg_dir}
diff --git a/packaging/docker/bin/entrypoint.sh b/packaging/docker/bin/entrypoint.sh
index f2811de7bd..a60254d7ef 100755
--- a/packaging/docker/bin/entrypoint.sh
+++ b/packaging/docker/bin/entrypoint.sh
@@ -55,7 +55,7 @@ else
         exit $?
     fi
     while true; do
-        es=$(taos -h $FIRST_EP_HOST -P $FIRST_EP_PORT --check)
+        es=$(taos -h $FIRST_EP_HOST -P $FIRST_EP_PORT --check | grep "^[0-9]*:")
         echo ${es}
         if [ "${es%%:*}" -eq 2 ]; then
             echo "execute create dnode"
diff --git a/packaging/docker/bin/taos-check b/packaging/docker/bin/taos-check
index 5dc06b6018..349187da9b 100755
--- a/packaging/docker/bin/taos-check
+++ b/packaging/docker/bin/taos-check
@@ -1,5 +1,5 @@
 #!/bin/sh
-es=$(taos --check)
+es=$(taos --check | grep "^[0-9]*:")
 code=${es%%:*}
 if [ "$code" -ne "0" ] && [ "$code" -ne "4" ]; then
     exit 0
diff --git a/packaging/rpm/makerpm.sh b/packaging/rpm/makerpm.sh
index 4ac67ec754..9cf00364aa 100755
--- a/packaging/rpm/makerpm.sh
+++ b/packaging/rpm/makerpm.sh
@@ -35,14 +35,16 @@ function cp_rpm_package() {
     local cur_dir
     cd $1
     cur_dir=$(pwd)
-
+    echo "cp_rpm_package cd: ${cur_dir}"
     for dirlist in "$(ls ${cur_dir})"; do
         if test -d ${dirlist}; then
             cd ${dirlist}
+            echo 'cp_rpm_package ${cur_dir}/${dirlist}'
             cp_rpm_package ${cur_dir}/${dirlist}
             cd ..
         fi
         if test -e ${dirlist}; then
+            echo "${cur_dir}/${dirlist} ${output_dir}/TDengine-${tdengine_ver}.rpm"
             cp ${cur_dir}/${dirlist} ${output_dir}/TDengine-${tdengine_ver}.rpm
         fi
     done
@@ -54,6 +56,25 @@ fi
 ${csudo}mkdir -p ${pkg_dir}
 cd ${pkg_dir}
 
+# download taoskeeper and build
+if [ "$cpuType" = "x64" ] || [ "$cpuType" = "x86_64" ] || [ "$cpuType" = "amd64" ]; then
+  arch=amd64
+elif [ "$cpuType" = "x32" ] || [ "$cpuType" = "i386" ] || [ "$cpuType" = "i686" ]; then
+  arch=386
+elif [ "$cpuType" = "arm" ] || [ "$cpuType" = "aarch32" ]; then
+  arch=arm
+elif [ "$cpuType" = "arm64" ] || [ "$cpuType" = "aarch64" ]; then
+  arch=arm64
+else
+  arch=$cpuType
+fi
+
+cd ${top_dir}
+echo "${top_dir}/../enterprise/packaging/build_taoskeeper.sh -r ${arch} -e taoskeeper"
+taoskeeper_binary=`${top_dir}/../enterprise/packaging/build_taoskeeper.sh -r $arch -e taoskeeper`
+echo "taoskeeper_binary: ${taoskeeper_binary}"
+cd ${package_dir}
+
 ${csudo}mkdir -p BUILD BUILDROOT RPMS SOURCES SPECS SRPMS
 
 ${csudo}rpmbuild --define="_version ${tdengine_ver}" --define="_topdir ${pkg_dir}" --define="_compiledir ${compile_dir}" -bb ${spec_file}
@@ -85,3 +106,4 @@ mv ${output_dir}/TDengine-${tdengine_ver}.rpm ${output_dir}/${rpmname}
 
 cd ..
 ${csudo}rm -rf ${pkg_dir}
+rm -rf ${top_dir}/build-taoskeeper
\ No newline at end of file
diff --git a/packaging/rpm/tdengine.spec b/packaging/rpm/tdengine.spec
index c21063e6a4..52d5335003 100644
--- a/packaging/rpm/tdengine.spec
+++ b/packaging/rpm/tdengine.spec
@@ -3,6 +3,7 @@
 %define cfg_install_dir  /etc/taos
 %define __strip /bin/true
 %global __python /usr/bin/python3
+%global _build_id_links none
 
 Name:		tdengine
 Version:	%{_version}
@@ -62,6 +63,15 @@ fi
 if [ -f %{_compiledir}/test/cfg/taosadapter.service ]; then
     cp %{_compiledir}/test/cfg/taosadapter.service %{buildroot}%{homepath}/cfg
 fi
+
+if [ -f %{_compiledir}/../build-taoskeeper/config/taoskeeper.toml ]; then
+    cp %{_compiledir}/../build-taoskeeper/config/taoskeeper.toml %{buildroot}%{homepath}/cfg ||:
+fi
+
+if [ -f %{_compiledir}/../build-taoskeeper/taoskeeper.service ]; then
+    cp %{_compiledir}/../build-taoskeeper/taoskeeper.service %{buildroot}%{homepath}/cfg ||:
+fi
+
 #cp %{_compiledir}/../packaging/rpm/taosd            %{buildroot}%{homepath}/init.d
 cp %{_compiledir}/../packaging/tools/post.sh        %{buildroot}%{homepath}/script
 cp %{_compiledir}/../packaging/tools/preun.sh       %{buildroot}%{homepath}/script
@@ -73,8 +83,12 @@ cp %{_compiledir}/build/bin/taosd                   %{buildroot}%{homepath}/bin
 cp %{_compiledir}/build/bin/udfd                    %{buildroot}%{homepath}/bin
 cp %{_compiledir}/build/bin/taosBenchmark           %{buildroot}%{homepath}/bin
 
+if [ -f %{_compiledir}/../build-taoskeeper/taoskeeper ]; then
+    cp %{_compiledir}/../build-taoskeeper/taoskeeper %{buildroot}%{homepath}/bin
+fi
+
 if [ -f %{_compiledir}/build/bin/taosadapter ]; then
-    cp %{_compiledir}/build/bin/taosadapter                    %{buildroot}%{homepath}/bin ||:
+    cp %{_compiledir}/build/bin/taosadapter                    %{buildroot}%{homepath}/bin
 fi
 cp %{_compiledir}/build/lib/${libfile}              %{buildroot}%{homepath}/driver
 [ -f %{_compiledir}/build/lib/${wslibfile} ] && cp %{_compiledir}/build/lib/${wslibfile}            %{buildroot}%{homepath}/driver ||:
@@ -119,7 +133,9 @@ if [ -f %{_compiledir}/build/bin/jemalloc-config ]; then
         cp %{_compiledir}/build/lib/pkgconfig/jemalloc.pc %{buildroot}%{homepath}/jemalloc/lib/pkgconfig
     fi
 fi
-
+ls -al %{buildroot}%{homepath}/bin
+tree -L 5
+echo "==============================copying files done"
 #Scripts executed before installation
 %pre
 if [ -f /var/lib/taos/dnode/dnodeCfg.json ]; then
@@ -196,6 +212,7 @@ if [ $1 -eq 0 ];then
     ${csudo}rm -f ${bin_link_dir}/taosd      || :
     ${csudo}rm -f ${bin_link_dir}/udfd       || :
     ${csudo}rm -f ${bin_link_dir}/taosadapter       || :
+    ${csudo}rm -f ${bin_link_dir}/taoskeeper       || :
     ${csudo}rm -f ${cfg_link_dir}/*          || :
     ${csudo}rm -f ${inc_link_dir}/taos.h     || :
     ${csudo}rm -f ${inc_link_dir}/taosdef.h     || :
diff --git a/packaging/tools/makepkg.sh b/packaging/tools/makepkg.sh
index a590835257..3da005c405 100755
--- a/packaging/tools/makepkg.sh
+++ b/packaging/tools/makepkg.sh
@@ -341,7 +341,7 @@ if [ "$verMode" == "cluster" ] || [ "$verMode" == "cloud" ]; then
         tmp_pwd=`pwd`
     	  cd ${install_dir}/connector
     	  if [ ! -d taos-connector-jdbc ];then
-          	git clone -b main --depth=1 https://github.com/taosdata/taos-connector-jdbc.git ||:
+          	git clone -b 3.1.0 --depth=1 https://github.com/taosdata/taos-connector-jdbc.git ||:
     	  fi
     	  cd taos-connector-jdbc
     	  mvn clean package -Dmaven.test.skip=true
diff --git a/packaging/tools/post.sh b/packaging/tools/post.sh
index 3a013ade2c..fc392c9684 100755
--- a/packaging/tools/post.sh
+++ b/packaging/tools/post.sh
@@ -436,7 +436,7 @@ function local_fqdn_check() {
 
 function install_taosadapter_config() {
     if [ ! -f "${cfg_install_dir}/taosadapter.toml" ]; then
-        [ ! -d %{cfg_install_dir} ] &&
+        [ ! -d ${cfg_install_dir} ] &&
             ${csudo}${csudo}mkdir -p ${cfg_install_dir}
         [ -f ${cfg_dir}/taosadapter.toml ] && ${csudo}cp ${cfg_dir}/taosadapter.toml ${cfg_install_dir}
         [ -f ${cfg_install_dir}/taosadapter.toml ] &&
@@ -451,19 +451,26 @@ function install_taosadapter_config() {
 }
 
 function install_taoskeeper_config() {
-    if [ ! -f "${cfg_install_dir}/keeper.toml" ]; then
-        [ ! -d %{cfg_install_dir} ] &&
-            ${csudo}${csudo}mkdir -p ${cfg_install_dir}
-        [ -f ${cfg_dir}/keeper.toml ] && ${csudo}cp ${cfg_dir}/keeper.toml ${cfg_install_dir}
-        [ -f ${cfg_install_dir}/keeper.toml ] &&
-            ${csudo}chmod 644 ${cfg_install_dir}/keeper.toml
+    # if new environment without taoskeeper
+    if [[ ! -f "${cfg_install_dir}/keeper.toml" ]] && [[ ! -f "${cfg_install_dir}/taoskeeper.toml" ]]; then
+        [ ! -d ${cfg_install_dir} ] && ${csudo}${csudo}mkdir -p ${cfg_install_dir}
+        [ -f ${cfg_dir}/taoskeeper.toml ] && ${csudo}cp ${cfg_dir}/taoskeeper.toml ${cfg_install_dir}
+        [ -f ${cfg_install_dir}/taoskeeper.toml ] &&
+            ${csudo}chmod 644 ${cfg_install_dir}/taoskeeper.toml
+    fi
+    # if old machine with taoskeeper.toml file
+    if [ -f ${cfg_install_dir}/taoskeeper.toml ]; then
+        ${csudo}mv ${cfg_dir}/taoskeeper.toml ${cfg_dir}/taoskeeper.toml.new
     fi
 
-    [ -f ${cfg_dir}/keeper.toml ] &&
-        ${csudo}mv ${cfg_dir}/keeper.toml ${cfg_dir}/keeper.toml.new
+    if [ -f ${cfg_install_dir}/keeper.toml ]; then
+        echo "The file keeper.toml will be renamed to taoskeeper.toml"
+        ${csudo}mv ${cfg_install_dir}/keeper.toml ${cfg_install_dir}/taoskeeper.toml
+        ${csudo}mv ${cfg_dir}/taoskeeper.toml ${cfg_dir}/taoskeeper.toml.new
+    fi
 
-    [ -f ${cfg_install_dir}/keeper.toml ] &&
-        ${csudo}ln -s ${cfg_install_dir}/keeper.toml ${cfg_dir}
+    [ -f ${cfg_install_dir}/taoskeeper.toml ] &&
+        ${csudo}ln -s ${cfg_install_dir}/taoskeeper.toml ${cfg_dir}
 }
 
 function install_config() {
@@ -655,6 +662,15 @@ function install_taosadapter_service() {
     fi
 }
 
+function install_taoskeeper_service() {
+    if ((${service_mod}==0)); then
+        [ -f ${script_dir}/../cfg/taoskeeper.service ] &&\
+            ${csudo}cp ${script_dir}/../cfg/taoskeeper.service \
+            ${service_config_dir}/ || :
+        ${csudo}systemctl daemon-reload
+    fi
+}
+
 function install_service() {
   log_print "start install service"
   if [ "$osType" != "Darwin" ]; then
@@ -732,6 +748,7 @@ function install_TDengine() {
     install_taosadapter_config
     install_taoskeeper_config
     install_taosadapter_service
+    install_taoskeeper_service
     install_service
     install_app
 
diff --git a/packaging/tools/preun.sh b/packaging/tools/preun.sh
index 0e96c71d5d..68f6b53c45 100755
--- a/packaging/tools/preun.sh
+++ b/packaging/tools/preun.sh
@@ -17,7 +17,7 @@ cfg_link_dir="/usr/local/taos/cfg"
 
 service_config_dir="/etc/systemd/system"
 taos_service_name="taosd"
-
+taoskeeper_service_name="taoskeeper"
 csudo=""
 if command -v sudo > /dev/null; then
     csudo="sudo "
@@ -57,6 +57,13 @@ function kill_taosd() {
   fi
 }
 
+function kill_taoskeeper() {
+  pid=$(ps -ef | grep "taoskeeper" | grep -v "grep" | awk '{print $2}')
+  if [ -n "$pid" ]; then
+    ${csudo}kill -9 $pid   || :
+  fi
+}
+
 function clean_service_on_systemd() {
     taosadapter_service_config="${service_config_dir}/taosadapter.service"
     if systemctl is-active --quiet taosadapter; then
@@ -76,6 +83,12 @@ function clean_service_on_systemd() {
 
     [ -f ${taosadapter_service_config} ] && ${csudo}rm -f ${taosadapter_service_config}
 
+    taoskeeper_service_config="${service_config_dir}/${taoskeeper_service_name}.service"
+    if systemctl is-active --quiet ${taoskeeper_service_name}; then
+        echo "TDengine taoskeeper is running, stopping it..."
+        ${csudo}systemctl stop ${taoskeeper_service_name} &> /dev/null || echo &> /dev/null
+    fi
+    [ -f ${taoskeeper_service_config} ] && ${csudo}rm -f ${taoskeeper_service_config}
 }
 
 function clean_service_on_sysvinit() {
@@ -111,6 +124,7 @@ function clean_service() {
         # must manual stop taosd
         kill_taosadapter
         kill_taosd
+        kill_taoskeeper
     fi
 }
 
@@ -124,6 +138,7 @@ ${csudo}rm -f ${bin_link_dir}/taosadapter       || :
 ${csudo}rm -f ${bin_link_dir}/taosBenchmark || :
 ${csudo}rm -f ${bin_link_dir}/taosdemo   || :
 ${csudo}rm -f ${bin_link_dir}/set_core   || :
+${csudo}rm -f ${bin_link_dir}/taoskeeper  || :
 ${csudo}rm -f ${cfg_link_dir}/*.new      || :
 ${csudo}rm -f ${inc_link_dir}/taos.h     || :
 ${csudo}rm -f ${inc_link_dir}/taosdef.h  || :
diff --git a/source/client/inc/clientSml.h b/source/client/inc/clientSml.h
index 43a7e8ba45..b20fc6f57a 100644
--- a/source/client/inc/clientSml.h
+++ b/source/client/inc/clientSml.h
@@ -107,6 +107,7 @@ typedef struct {
   int32_t colsLen;
   int32_t timestampLen;
 
+  bool    measureEscaped;
   SArray *colArray;
 } SSmlLineInfo;
 
@@ -168,6 +169,7 @@ typedef struct {
   int32_t         uid; // used for automatic create child table
 
   SHashObj *childTables;
+  SHashObj *tableUids;
   SHashObj *superTables;
   SHashObj *pVgHash;
 
@@ -206,6 +208,19 @@ typedef struct {
 
 #define IS_SAME_KEY (maxKV->keyLen == kv.keyLen && memcmp(maxKV->key, kv.key, kv.keyLen) == 0)
 
+#define IS_SLASH_LETTER_IN_MEASUREMENT(sql)                                                           \
+  (*((sql)-1) == SLASH && (*(sql) == COMMA || *(sql) == SPACE))
+
+#define MOVE_FORWARD_ONE(sql, len) (memmove((void *)((sql)-1), (sql), len))
+
+#define PROCESS_SLASH_IN_MEASUREMENT(key, keyLen)           \
+  for (int i = 1; i < keyLen; ++i) {         \
+    if (IS_SLASH_LETTER_IN_MEASUREMENT(key + i)) {          \
+      MOVE_FORWARD_ONE(key + i, keyLen - i); \
+      keyLen--;                              \
+    }                                        \
+  }
+
 extern int64_t smlFactorNS[3];
 extern int64_t smlFactorS[3];
 
@@ -228,6 +243,7 @@ int8_t        smlGetTsTypeByLen(int32_t len);
 SSmlTableInfo*    smlBuildTableInfo(int numRows, const char* measure, int32_t measureLen);
 SSmlSTableMeta*   smlBuildSTableMeta(bool isDataFormat);
 int32_t           smlSetCTableName(SSmlTableInfo *oneTable);
+void              getTableUid(SSmlHandle *info, SSmlLineInfo *currElement, SSmlTableInfo *tinfo);
 STableMeta*       smlGetMeta(SSmlHandle *info, const void* measure, int32_t measureLen);
 int32_t           is_same_child_table_telnet(const void *a, const void *b);
 int64_t           smlParseOpenTsdbTime(SSmlHandle *info, const char *data, int32_t len);
@@ -237,6 +253,7 @@ uint8_t           smlGetTimestampLen(int64_t num);
 void              clearColValArray(SArray* pCols);
 void              smlDestroyTableInfo(SSmlHandle *info, SSmlTableInfo *tag);
 
+void freeSSmlKv(void* data);
 int32_t smlParseInfluxString(SSmlHandle *info, char *sql, char *sqlEnd, SSmlLineInfo *elements);
 int32_t smlParseTelnetString(SSmlHandle *info, char *sql, char *sqlEnd, SSmlLineInfo *elements);
 int32_t smlParseJSON(SSmlHandle *info, char *payload);
diff --git a/source/client/src/clientMain.c b/source/client/src/clientMain.c
index 44f50e11c6..b43f1e79e0 100644
--- a/source/client/src/clientMain.c
+++ b/source/client/src/clientMain.c
@@ -108,7 +108,7 @@ TAOS *taos_connect(const char *ip, const char *user, const char *pass, const cha
   if (pass == NULL) {
     pass = TSDB_DEFAULT_PASS;
   }
-  
+
   STscObj *pObj = taos_connect_internal(ip, user, pass, NULL, db, port, CONN_TYPE__QUERY);
   if (pObj) {
     int64_t *rid = taosMemoryCalloc(1, sizeof(int64_t));
@@ -191,7 +191,7 @@ void taos_free_result(TAOS_RES *res) {
     taosArrayDestroyP(pRsp->rsp.blockData, taosMemoryFree);
     taosArrayDestroy(pRsp->rsp.blockDataLen);
     taosArrayDestroyP(pRsp->rsp.blockTbName, taosMemoryFree);
-    taosArrayDestroyP(pRsp->rsp.blockSchema, (FDelete)tDeleteSSchemaWrapper);
+    taosArrayDestroyP(pRsp->rsp.blockSchema, (FDelete)tDeleteSchemaWrapper);
     // taosx
     taosArrayDestroy(pRsp->rsp.createTableLen);
     taosArrayDestroyP(pRsp->rsp.createTableReq, taosMemoryFree);
@@ -204,7 +204,7 @@ void taos_free_result(TAOS_RES *res) {
     taosArrayDestroyP(pRsp->rsp.blockData, taosMemoryFree);
     taosArrayDestroy(pRsp->rsp.blockDataLen);
     taosArrayDestroyP(pRsp->rsp.blockTbName, taosMemoryFree);
-    taosArrayDestroyP(pRsp->rsp.blockSchema, (FDelete)tDeleteSSchemaWrapper);
+    taosArrayDestroyP(pRsp->rsp.blockSchema, (FDelete)tDeleteSchemaWrapper);
     pRsp->resInfo.pRspMsg = NULL;
     doFreeReqResultInfo(&pRsp->resInfo);
     taosMemoryFree(pRsp);
@@ -359,11 +359,11 @@ int taos_print_row(char *str, TAOS_ROW row, TAOS_FIELD *fields, int num_fields)
       case TSDB_DATA_TYPE_NCHAR: {
         int32_t charLen = varDataLen((char *)row[i] - VARSTR_HEADER_SIZE);
         if (fields[i].type == TSDB_DATA_TYPE_BINARY) {
-          if(ASSERT(charLen <= fields[i].bytes && charLen >= 0)){
+          if (ASSERT(charLen <= fields[i].bytes && charLen >= 0)) {
             tscError("taos_print_row error binary. charLen:%d, fields[i].bytes:%d", charLen, fields[i].bytes);
           }
         } else {
-          if(ASSERT(charLen <= fields[i].bytes * TSDB_NCHAR_SIZE && charLen >= 0)){
+          if (ASSERT(charLen <= fields[i].bytes * TSDB_NCHAR_SIZE && charLen >= 0)) {
             tscError("taos_print_row error. charLen:%d, fields[i].bytes:%d", charLen, fields[i].bytes);
           }
         }
@@ -705,16 +705,16 @@ int taos_get_current_db(TAOS *taos, char *database, int len, int *required) {
 
   int code = TSDB_CODE_SUCCESS;
   taosThreadMutexLock(&pTscObj->mutex);
-  if(database == NULL || len <= 0){
-    if(required != NULL) *required = strlen(pTscObj->db) + 1;
+  if (database == NULL || len <= 0) {
+    if (required != NULL) *required = strlen(pTscObj->db) + 1;
     terrno = TSDB_CODE_INVALID_PARA;
     code = -1;
-  }else if(len < strlen(pTscObj->db) + 1){
+  } else if (len < strlen(pTscObj->db) + 1) {
     tstrncpy(database, pTscObj->db, len);
-    if(required) *required = strlen(pTscObj->db) + 1;
+    if (required) *required = strlen(pTscObj->db) + 1;
     terrno = TSDB_CODE_INVALID_PARA;
     code = -1;
-  }else{
+  } else {
     strcpy(database, pTscObj->db);
     code = 0;
   }
@@ -741,6 +741,7 @@ static void destoryCatalogReq(SCatalogReq *pCatalogReq) {
   taosArrayDestroy(pCatalogReq->pUser);
   taosArrayDestroy(pCatalogReq->pTableIndex);
   taosArrayDestroy(pCatalogReq->pTableCfg);
+  taosArrayDestroy(pCatalogReq->pTableTag);
   taosMemoryFree(pCatalogReq);
 }
 
@@ -975,8 +976,10 @@ void doAsyncQuery(SRequestObj *pRequest, bool updateMetaForce) {
 
   if (TSDB_CODE_SUCCESS == code) {
     pRequest->stmtType = pRequest->pQuery->pRoot->type;
-    phaseAsyncQuery(pWrapper);
-  } else {
+    code = phaseAsyncQuery(pWrapper);
+  }
+
+  if (TSDB_CODE_SUCCESS != code) {
     tscError("0x%" PRIx64 " error happens, code:%d - %s, reqId:0x%" PRIx64, pRequest->self, code, tstrerror(code),
              pRequest->requestId);
     destorySqlCallbackWrapper(pWrapper);
@@ -1042,11 +1045,11 @@ static void fetchCallback(void *pResult, void *param, int32_t code) {
 }
 
 void taos_fetch_rows_a(TAOS_RES *res, __taos_async_fn_t fp, void *param) {
-  if(ASSERT(res != NULL && fp != NULL)){
+  if (ASSERT(res != NULL && fp != NULL)) {
     tscError("taos_fetch_rows_a invalid paras");
     return;
   }
-  if(ASSERT(TD_RES_QUERY(res))){
+  if (ASSERT(TD_RES_QUERY(res))) {
     tscError("taos_fetch_rows_a res is NULL");
     return;
   }
@@ -1092,11 +1095,11 @@ void taos_fetch_rows_a(TAOS_RES *res, __taos_async_fn_t fp, void *param) {
 }
 
 void taos_fetch_raw_block_a(TAOS_RES *res, __taos_async_fn_t fp, void *param) {
-  if(ASSERT(res != NULL && fp != NULL)){
+  if (ASSERT(res != NULL && fp != NULL)) {
     tscError("taos_fetch_rows_a invalid paras");
     return;
   }
-  if(ASSERT(TD_RES_QUERY(res))){
+  if (ASSERT(TD_RES_QUERY(res))) {
     tscError("taos_fetch_rows_a res is NULL");
     return;
   }
@@ -1111,11 +1114,11 @@ void taos_fetch_raw_block_a(TAOS_RES *res, __taos_async_fn_t fp, void *param) {
 }
 
 const void *taos_get_raw_block(TAOS_RES *res) {
-  if(ASSERT(res != NULL)){
+  if (ASSERT(res != NULL)) {
     tscError("taos_fetch_rows_a invalid paras");
     return NULL;
   }
-  if(ASSERT(TD_RES_QUERY(res))){
+  if (ASSERT(TD_RES_QUERY(res))) {
     tscError("taos_fetch_rows_a res is NULL");
     return NULL;
   }
@@ -1273,7 +1276,6 @@ _return:
   return code;
 }
 
-
 int taos_load_table_info(TAOS *taos, const char *tableNameList) {
   if (NULL == taos) {
     terrno = TSDB_CODE_TSC_DISCONNECTED;
diff --git a/source/client/src/clientMsgHandler.c b/source/client/src/clientMsgHandler.c
index a0146cfa39..032517cafc 100644
--- a/source/client/src/clientMsgHandler.c
+++ b/source/client/src/clientMsgHandler.c
@@ -92,7 +92,6 @@ int32_t processConnectRsp(void* param, SDataBuf* pMsg, int32_t code) {
     goto End;
   }
 
-  /*assert(connectRsp.epSet.numOfEps > 0);*/
   if (connectRsp.epSet.numOfEps == 0) {
     setErrno(pRequest, TSDB_CODE_APP_ERROR);
     tsem_post(&pRequest->body.rspSem);
diff --git a/source/client/src/clientSml.c b/source/client/src/clientSml.c
index 763d4b6915..30c0008f3d 100644
--- a/source/client/src/clientSml.c
+++ b/source/client/src/clientSml.c
@@ -195,6 +195,20 @@ int32_t smlSetCTableName(SSmlTableInfo *oneTable) {
   return TSDB_CODE_SUCCESS;
 }
 
+void getTableUid(SSmlHandle *info, SSmlLineInfo *currElement, SSmlTableInfo *tinfo){
+  char key[TSDB_TABLE_NAME_LEN * 2 + 1] = {0};
+  size_t nLen = strlen(tinfo->childTableName);
+  memcpy(key, currElement->measure, currElement->measureLen);
+  memcpy(key + currElement->measureLen + 1, tinfo->childTableName, nLen);
+  void *uid = taosHashGet(info->tableUids, key, currElement->measureLen + 1 + nLen);    // use \0 as separator for stable name and child table name
+  if (uid == NULL) {
+    tinfo->uid = info->uid++;
+    taosHashPut(info->tableUids, key, currElement->measureLen + 1 + nLen, &tinfo->uid, sizeof(uint64_t));
+  }else{
+    tinfo->uid = *(uint64_t*)uid;
+  }
+}
+
 SSmlSTableMeta *smlBuildSTableMeta(bool isDataFormat) {
   SSmlSTableMeta *meta = (SSmlSTableMeta *)taosMemoryCalloc(sizeof(SSmlSTableMeta), 1);
   if (!meta) {
@@ -534,7 +548,7 @@ static int32_t smlGenerateSchemaAction(SSchema *colField, SHashObj *colHash, SSm
   uint16_t *index = colHash ? (uint16_t *)taosHashGet(colHash, kv->key, kv->keyLen) : NULL;
   if (index) {
     if (colField[*index].type != kv->type) {
-      uError("SML:0x%" PRIx64 " point type and db type mismatch. point type: %d, db type: %d, key: %s", info->id, colField[*index].type, kv->type, kv->key);
+      uError("SML:0x%" PRIx64 " point type and db type mismatch. db type: %d, point type: %d, key: %s", info->id, colField[*index].type, kv->type, kv->key);
       return TSDB_CODE_SML_INVALID_DATA;
     }
 
@@ -558,10 +572,15 @@ static int32_t smlGenerateSchemaAction(SSchema *colField, SHashObj *colHash, SSm
   return 0;
 }
 
+#define BOUNDARY 1024
 static int32_t smlFindNearestPowerOf2(int32_t length, uint8_t type) {
   int32_t result = 1;
-  while (result <= length) {
-    result *= 2;
+  if (length >= BOUNDARY){
+    result = length;
+  }else{
+    while (result <= length) {
+      result *= 2;
+    }
   }
   if (type == TSDB_DATA_TYPE_BINARY && result > TSDB_MAX_BINARY_LEN - VARSTR_HEADER_SIZE) {
     result = TSDB_MAX_BINARY_LEN - VARSTR_HEADER_SIZE;
@@ -649,6 +668,17 @@ static int32_t smlBuildFieldsList(SSmlHandle *info, SSchema *schemaField, SHashO
       field->bytes = getBytes(kv->type, kv->length);
     }
   }
+
+  int32_t maxLen = isTag ? TSDB_MAX_TAGS_LEN : TSDB_MAX_BYTES_PER_ROW;
+  int32_t len = 0;
+  for (int j = 0; j < taosArrayGetSize(results); ++j) {
+    SField *field = taosArrayGet(results, j);
+    len += field->bytes;
+  }
+  if(len > maxLen){
+    return isTag ? TSDB_CODE_PAR_INVALID_TAGS_LENGTH : TSDB_CODE_PAR_INVALID_ROW_LENGTH;
+  }
+
   return TSDB_CODE_SUCCESS;
 }
 
@@ -765,8 +795,12 @@ static int32_t smlModifyDBSchemas(SSmlHandle *info) {
 
     size_t superTableLen = 0;
     void  *superTable = taosHashGetKey(tmp, &superTableLen);
+    char* measure = taosMemoryMalloc(superTableLen);
+    memcpy(measure, superTable, superTableLen);
+    PROCESS_SLASH_IN_MEASUREMENT(measure, superTableLen);
     memset(pName.tname, 0, TSDB_TABLE_NAME_LEN);
-    memcpy(pName.tname, superTable, superTableLen);
+    memcpy(pName.tname, measure, superTableLen);
+    taosMemoryFree(measure);
 
     code = catalogGetSTableMeta(info->pCatalog, &conn, &pName, &pTableMeta);
 
@@ -777,11 +811,15 @@ static int32_t smlModifyDBSchemas(SSmlHandle *info) {
       code = smlBuildFieldsList(info, NULL, NULL, sTableData->tags, pTags, 0, true);
       if (code != TSDB_CODE_SUCCESS) {
         uError("SML:0x%" PRIx64 " smlBuildFieldsList tag1 failed. %s", info->id, pName.tname);
+        taosArrayDestroy(pColumns);
+        taosArrayDestroy(pTags);
         goto end;
       }
       code = smlBuildFieldsList(info, NULL, NULL, sTableData->cols, pColumns, 0, false);
       if (code != TSDB_CODE_SUCCESS) {
         uError("SML:0x%" PRIx64 " smlBuildFieldsList col1 failed. %s", info->id, pName.tname);
+        taosArrayDestroy(pColumns);
+        taosArrayDestroy(pTags);
         goto end;
       }
       code = smlSendMetaMsg(info, &pName, pColumns, pTags, NULL, SCHEMA_ACTION_CREATE_STABLE);
@@ -833,6 +871,23 @@ static int32_t smlModifyDBSchemas(SSmlHandle *info) {
                                   pTableMeta->tableInfo.numOfColumns, true);
         if (code != TSDB_CODE_SUCCESS) {
           uError("SML:0x%" PRIx64 " smlBuildFieldsList tag2 failed. %s", info->id, pName.tname);
+          taosArrayDestroy(pColumns);
+          taosArrayDestroy(pTags);
+          goto end;
+        }
+
+        if (taosArrayGetSize(pTags) + pTableMeta->tableInfo.numOfColumns > TSDB_MAX_COLUMNS) {
+          uError("SML:0x%" PRIx64 " too many columns than 4096", info->id);
+          code = TSDB_CODE_PAR_TOO_MANY_COLUMNS;
+          taosArrayDestroy(pColumns);
+          taosArrayDestroy(pTags);
+          goto end;
+        }
+        if (taosArrayGetSize(pTags) > TSDB_MAX_TAGS) {
+          uError("SML:0x%" PRIx64 " too many tags than 128", info->id);
+          code = TSDB_CODE_PAR_INVALID_TAGS_NUM;
+          taosArrayDestroy(pColumns);
+          taosArrayDestroy(pTags);
           goto end;
         }
 
@@ -887,6 +942,16 @@ static int32_t smlModifyDBSchemas(SSmlHandle *info) {
                                   pTableMeta->tableInfo.numOfColumns, false);
         if (code != TSDB_CODE_SUCCESS) {
           uError("SML:0x%" PRIx64 " smlBuildFieldsList col2 failed. %s", info->id, pName.tname);
+          taosArrayDestroy(pColumns);
+          taosArrayDestroy(pTags);
+          goto end;
+        }
+
+        if (taosArrayGetSize(pColumns) + pTableMeta->tableInfo.numOfTags > TSDB_MAX_COLUMNS) {
+          uError("SML:0x%" PRIx64 " too many columns than 4096", info->id);
+          code = TSDB_CODE_PAR_TOO_MANY_COLUMNS;
+          taosArrayDestroy(pColumns);
+          taosArrayDestroy(pTags);
           goto end;
         }
 
@@ -1049,7 +1114,7 @@ void smlDestroyTableInfo(SSmlHandle *info, SSmlTableInfo *tag) {
   //  }
   //  taosMemoryFree(tag->key);
   taosArrayDestroy(tag->cols);
-  taosArrayDestroy(tag->tags);
+  taosArrayDestroyEx(tag->tags, freeSSmlKv);
   taosMemoryFree(tag);
 }
 
@@ -1063,6 +1128,12 @@ void clearColValArray(SArray *pCols) {
   }
 }
 
+void freeSSmlKv(void* data){
+  SSmlKv *kv = (SSmlKv*)data;
+  if(kv->keyEscaped) taosMemoryFree((void*)(kv->key));
+  if(kv->valueEscaped) taosMemoryFree((void*)(kv->value));
+}
+
 void smlDestroyInfo(SSmlHandle *info) {
   if (!info) return;
   qDestroyQuery(info->pQuery);
@@ -1085,6 +1156,7 @@ void smlDestroyInfo(SSmlHandle *info) {
   taosHashCleanup(info->pVgHash);
   taosHashCleanup(info->childTables);
   taosHashCleanup(info->superTables);
+  taosHashCleanup(info->tableUids);
 
   for (int i = 0; i < taosArrayGetSize(info->tagJsonArray); i++) {
     cJSON *tags = (cJSON *)taosArrayGetP(info->tagJsonArray, i);
@@ -1098,11 +1170,11 @@ void smlDestroyInfo(SSmlHandle *info) {
   }
   taosArrayDestroy(info->valueJsonArray);
 
-  taosArrayDestroy(info->preLineTagKV);
+  taosArrayDestroyEx(info->preLineTagKV, freeSSmlKv);
 
   if (!info->dataFormat) {
     for (int i = 0; i < info->lineNum; i++) {
-      taosArrayDestroy(info->lines[i].colArray);
+      taosArrayDestroyEx(info->lines[i].colArray, freeSSmlKv);
       if (info->parseJsonByLib) {
         taosMemoryFree(info->lines[i].tags);
       }
@@ -1135,6 +1207,7 @@ SSmlHandle *smlBuildSmlInfo(TAOS *taos) {
 
   info->pVgHash = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_NO_LOCK);
   info->childTables = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK);
+  info->tableUids = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK);
   info->superTables = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK);
 
   info->id = smlGenId();
@@ -1145,7 +1218,7 @@ SSmlHandle *smlBuildSmlInfo(TAOS *taos) {
   info->valueJsonArray = taosArrayInit(8, POINTER_BYTES);
   info->preLineTagKV = taosArrayInit(8, sizeof(SSmlKv));
 
-  if (NULL == info->pVgHash || NULL == info->childTables || NULL == info->superTables) {
+  if (NULL == info->pVgHash || NULL == info->childTables || NULL == info->superTables || NULL == info->tableUids) {
     uError("create SSmlHandle failed");
     goto cleanup;
   }
@@ -1165,8 +1238,10 @@ static int32_t smlPushCols(SArray *colsArray, SArray *cols) {
   }
   for (size_t i = 0; i < taosArrayGetSize(cols); i++) {
     SSmlKv *kv = (SSmlKv *)taosArrayGet(cols, i);
+    terrno = 0;
     taosHashPut(kvHash, kv->key, kv->keyLen, &kv, POINTER_BYTES);
     if (terrno == TSDB_CODE_DUP_KEY) {
+      taosHashCleanup(kvHash);
       return terrno;
     }
   }
@@ -1240,12 +1315,13 @@ static int32_t smlParseLineBottom(SSmlHandle *info) {
       uDebug("SML:0x%" PRIx64 " smlParseLineBottom add meta, format:%d, linenum:%d", info->id, info->dataFormat,
              info->lineNum);
       SSmlSTableMeta *meta = smlBuildSTableMeta(info->dataFormat);
+      taosHashPut(info->superTables, elements->measure, elements->measureLen, &meta, POINTER_BYTES);
+      terrno = 0;
       smlInsertMeta(meta->tagHash, meta->tags, tinfo->tags);
       if (terrno == TSDB_CODE_DUP_KEY) {
         return terrno;
       }
       smlInsertMeta(meta->colHash, meta->cols, elements->colArray);
-      taosHashPut(info->superTables, elements->measure, elements->measureLen, &meta, POINTER_BYTES);
     }
   }
   uDebug("SML:0x%" PRIx64 " smlParseLineBottom end, format:%d, linenum:%d", info->id, info->dataFormat, info->lineNum);
@@ -1260,23 +1336,23 @@ static int32_t smlInsertData(SSmlHandle *info) {
   if (info->pRequest->dbList == NULL) {
     info->pRequest->dbList = taosArrayInit(1, TSDB_DB_FNAME_LEN);
   }
-  void *data = taosArrayReserve(info->pRequest->dbList, 1);
-  memcpy(data, info->pRequest->pDb,
-         TSDB_DB_FNAME_LEN > strlen(info->pRequest->pDb) ? strlen(info->pRequest->pDb) : TSDB_DB_FNAME_LEN);
+  char *data = (char*)taosArrayReserve(info->pRequest->dbList, 1);
+  SName pName = {TSDB_TABLE_NAME_T, info->taos->acctId, {0}, {0}};
+  tstrncpy(pName.dbname, info->pRequest->pDb, sizeof(pName.dbname));
+  tNameGetFullDbName(&pName, data);
 
   SSmlTableInfo **oneTable = (SSmlTableInfo **)taosHashIterate(info->childTables, NULL);
   while (oneTable) {
     SSmlTableInfo *tableData = *oneTable;
-
-    SName pName = {TSDB_TABLE_NAME_T, info->taos->acctId, {0}, {0}};
-    tstrncpy(pName.dbname, info->pRequest->pDb, sizeof(pName.dbname));
-    memcpy(pName.tname, tableData->childTableName, strlen(tableData->childTableName));
+    tstrncpy(pName.tname, tableData->sTableName, tableData->sTableNameLen + 1);
 
     if (info->pRequest->tableList == NULL) {
       info->pRequest->tableList = taosArrayInit(1, sizeof(SName));
     }
     taosArrayPush(info->pRequest->tableList, &pName);
 
+    strcpy(pName.tname, tableData->childTableName);
+
     SRequestConnInfo conn = {0};
     conn.pTrans = info->taos->pAppInfo->pTransporter;
     conn.requestId = info->pRequest->requestId;
@@ -1304,9 +1380,15 @@ static int32_t smlInsertData(SSmlHandle *info) {
     uDebug("SML:0x%" PRIx64 " smlInsertData table:%s, uid:%" PRIu64 ", format:%d", info->id, pName.tname,
            tableData->uid, info->dataFormat);
 
+    int   measureLen = tableData->sTableNameLen;
+    char* measure = (char*)taosMemoryMalloc(tableData->sTableNameLen);
+    memcpy(measure, tableData->sTableName, tableData->sTableNameLen);
+    PROCESS_SLASH_IN_MEASUREMENT(measure, measureLen);
+
     code = smlBindData(info->pQuery, info->dataFormat, tableData->tags, (*pMeta)->cols, tableData->cols,
-                       (*pMeta)->tableMeta, tableData->childTableName, tableData->sTableName, tableData->sTableNameLen,
+                       (*pMeta)->tableMeta, tableData->childTableName, measure, measureLen,
                        info->ttl, info->msgBuf.buf, info->msgBuf.len);
+    taosMemoryFree(measure);
     if (code != TSDB_CODE_SUCCESS) {
       uError("SML:0x%" PRIx64 " smlBindData failed", info->id);
       return code;
@@ -1362,6 +1444,7 @@ int32_t smlClearForRerun(SSmlHandle *info) {
 
   taosHashClear(info->childTables);
   taosHashClear(info->superTables);
+  taosHashClear(info->tableUids);
 
   if (!info->dataFormat) {
     if (unlikely(info->lines != NULL)) {
@@ -1420,14 +1503,14 @@ static int32_t smlParseLine(SSmlHandle *info, char *lines[], char *rawLine, char
 
     char cTmp = 0;  // for print tmp if is raw
     if (info->isRawLine) {
-      cTmp = tmp[len - 1];
-      tmp[len - 1] = '\0';
+      cTmp = tmp[len];
+      tmp[len] = '\0';
     }
 
     uDebug("SML:0x%" PRIx64 " smlParseLine israw:%d, numLines:%d, protocol:%d, len:%d, sql:%s", info->id,
            info->isRawLine, numLines, info->protocol, len, tmp);
     if (info->isRawLine) {
-      tmp[len - 1] = cTmp;
+      tmp[len] = cTmp;
     }
 
     if (info->protocol == TSDB_SML_LINE_PROTOCOL) {
@@ -1449,6 +1532,7 @@ static int32_t smlParseLine(SSmlHandle *info, char *lines[], char *rawLine, char
       code = TSDB_CODE_SML_INVALID_PROTOCOL_TYPE;
     }
     if (code != TSDB_CODE_SUCCESS) {
+      tmp[len] = '\0';
       uError("SML:0x%" PRIx64 " smlParseLine failed. line %d : %s", info->id, i, tmp);
       return code;
     }
@@ -1494,7 +1578,11 @@ static int smlProcess(SSmlHandle *info, char *lines[], char *rawLine, char *rawL
 
   do {
     code = smlModifyDBSchemas(info);
-    if (code == 0 || code == TSDB_CODE_SML_INVALID_DATA) break;
+    if (code == 0 || code == TSDB_CODE_SML_INVALID_DATA || code == TSDB_CODE_PAR_TOO_MANY_COLUMNS
+        || code == TSDB_CODE_PAR_INVALID_TAGS_NUM || code == TSDB_CODE_PAR_INVALID_TAGS_LENGTH
+        || code == TSDB_CODE_PAR_INVALID_ROW_LENGTH || code == TSDB_CODE_MND_FIELD_VALUE_OVERFLOW) {
+      break;
+    }
     taosMsleep(100);
     uInfo("SML:0x%" PRIx64 " smlModifyDBSchemas retry code:%s, times:%d", info->id, tstrerror(code), retryNum);
   } while (retryNum++ < taosHashGetSize(info->superTables) * MAX_RETRY_TIMES);
@@ -1579,7 +1667,8 @@ TAOS_RES *taos_schemaless_insert_inner(TAOS *taos, char *lines[], char *rawLine,
     info->cost.endTime = taosGetTimestampUs();
     info->cost.code = code;
     if (code == TSDB_CODE_TDB_INVALID_TABLE_SCHEMA_VER || code == TSDB_CODE_SDB_OBJ_CREATING ||
-        code == TSDB_CODE_PAR_VALUE_TOO_LONG || code == TSDB_CODE_MND_TRANS_CONFLICT) {
+        code == TSDB_CODE_PAR_VALUE_TOO_LONG || code == TSDB_CODE_MND_TRANS_CONFLICT ||
+        code == TSDB_CODE_PAR_TABLE_NOT_EXIST) {
       if (cnt++ >= 10) {
         uInfo("SML:%" PRIx64 " retry:%d/10 end code:%d, msg:%s", info->id, cnt, code, tstrerror(code));
         break;
diff --git a/source/client/src/clientSmlJson.c b/source/client/src/clientSmlJson.c
index 9fd98e33b7..7ccf930964 100644
--- a/source/client/src/clientSmlJson.c
+++ b/source/client/src/clientSmlJson.c
@@ -575,7 +575,7 @@ static int32_t smlConvertJSONString(SSmlKv *pVal, char *typeStr, cJSON *value) {
     uError("OTD:invalid type(%s) for JSON String", typeStr);
     return TSDB_CODE_TSC_INVALID_JSON_TYPE;
   }
-  pVal->length = (int16_t)strlen(value->valuestring);
+  pVal->length = strlen(value->valuestring);
 
   if (pVal->type == TSDB_DATA_TYPE_BINARY && pVal->length > TSDB_MAX_BINARY_LEN - VARSTR_HEADER_SIZE) {
     return TSDB_CODE_PAR_INVALID_VAR_COLUMN_LEN;
@@ -778,7 +778,7 @@ static int32_t smlParseTagsFromJSON(SSmlHandle *info, cJSON *tags, SSmlLineInfo
     tinfo->tags = taosArrayDup(preLineKV, NULL);
 
     smlSetCTableName(tinfo);
-    tinfo->uid = info->uid++;
+    getTableUid(info, elements, tinfo);
     if (info->dataFormat) {
       info->currSTableMeta->uid = tinfo->uid;
       tinfo->tableDataCtx = smlInitTableDataCtx(info->pQuery, info->currSTableMeta);
diff --git a/source/client/src/clientSmlLine.c b/source/client/src/clientSmlLine.c
index 335e3a1dc7..2f7e8a0f97 100644
--- a/source/client/src/clientSmlLine.c
+++ b/source/client/src/clientSmlLine.c
@@ -21,32 +21,33 @@
 #include "clientSml.h"
 
 // comma ,
-// #define IS_SLASH_COMMA(sql) (*(sql) == COMMA && *((sql)-1) == SLASH)
 #define IS_COMMA(sql) (*(sql) == COMMA && *((sql)-1) != SLASH)
 // space
-// #define IS_SLASH_SPACE(sql) (*(sql) == SPACE && *((sql)-1) == SLASH)
 #define IS_SPACE(sql) (*(sql) == SPACE && *((sql)-1) != SLASH)
 // equal =
-// #define IS_SLASH_EQUAL(sql) (*(sql) == EQUAL && *((sql)-1) == SLASH)
 #define IS_EQUAL(sql) (*(sql) == EQUAL && *((sql)-1) != SLASH)
 // quote "
-// #define IS_SLASH_QUOTE(sql) (*(sql) == QUOTE && *((sql)-1) == SLASH)
-#define IS_QUOTE(sql) (*(sql) == QUOTE && *((sql)-1) != SLASH)
+//#define IS_QUOTE(sql) (*(sql) == QUOTE && *((sql)-1) != SLASH)
 // SLASH
-// #define IS_SLASH_SLASH(sql) (*(sql) == SLASH && *((sql)-1) == SLASH)
 
-#define IS_SLASH_LETTER(sql)                                                                           \
-  (*((sql)-1) == SLASH && (*(sql) == COMMA || *(sql) == SPACE || *(sql) == EQUAL || *(sql) == QUOTE || \
-                           *(sql) == SLASH))  //  (IS_SLASH_COMMA(sql) || IS_SLASH_SPACE(sql) || IS_SLASH_EQUAL(sql) ||
-                                              //  IS_SLASH_QUOTE(sql) || IS_SLASH_SLASH(sql))
+#define IS_SLASH_LETTER_IN_FIELD_VALUE(sql)                                                           \
+  (*((sql)-1) == SLASH && (*(sql) == QUOTE || *(sql) == SLASH))
 
-#define MOVE_FORWARD_ONE(sql, len) (memmove((void *)((sql)-1), (sql), len))
+#define IS_SLASH_LETTER_IN_TAG_FIELD_KEY(sql)                                                         \
+  (*((sql)-1) == SLASH && (*(sql) == COMMA || *(sql) == SPACE || *(sql) == EQUAL))
 
-#define PROCESS_SLASH(key, keyLen)           \
-  for (int i = 1; i < keyLen; ++i) {         \
-    if (IS_SLASH_LETTER(key + i)) {          \
+#define PROCESS_SLASH_IN_FIELD_VALUE(key, keyLen)           \
+  for (int i = 1; i < keyLen; ++i) {                        \
+    if (IS_SLASH_LETTER_IN_FIELD_VALUE(key + i)) {          \
+      MOVE_FORWARD_ONE(key + i, keyLen - i); \
+      keyLen--;                              \
+    }                                        \
+  }
+
+#define PROCESS_SLASH_IN_TAG_FIELD_KEY(key, keyLen)           \
+  for (int i = 1; i < keyLen; ++i) {         \
+    if (IS_SLASH_LETTER_IN_TAG_FIELD_KEY(key + i)) {          \
       MOVE_FORWARD_ONE(key + i, keyLen - i); \
-      i--;                                   \
       keyLen--;                              \
     }                                        \
   }
@@ -151,7 +152,17 @@ static int32_t smlParseTagKv(SSmlHandle *info, char **sql, char *sqlEnd, SSmlLin
 
       SSmlSTableMeta *sMeta = NULL;
       if (unlikely(tmp == NULL)) {
-        STableMeta *pTableMeta = smlGetMeta(info, currElement->measure, currElement->measureLen);
+        char* measure = currElement->measure;
+        int   measureLen = currElement->measureLen;
+        if(currElement->measureEscaped){
+          measure = (char*)taosMemoryMalloc(currElement->measureLen);
+          memcpy(measure, currElement->measure, currElement->measureLen);
+          PROCESS_SLASH_IN_MEASUREMENT(measure, measureLen);
+        }
+        STableMeta *pTableMeta = smlGetMeta(info, measure, measureLen);
+        if(currElement->measureEscaped){
+          taosMemoryFree(measure);
+        }
         if (pTableMeta == NULL) {
           info->dataFormat = false;
           info->reRun = true;
@@ -171,17 +182,18 @@ static int32_t smlParseTagKv(SSmlHandle *info, char **sql, char *sqlEnd, SSmlLin
       info->maxTagKVs = (*tmp)->tags;
     }
   }
-  taosArrayClear(preLineKV);
+  taosArrayClearEx(preLineKV, freeSSmlKv);
 
   while (*sql < sqlEnd) {
     if (unlikely(IS_SPACE(*sql))) {
       break;
     }
 
-    bool hasSlash = false;
     // parse key
     const char *key = *sql;
     size_t      keyLen = 0;
+    bool        keyEscaped = false;
+    size_t      keyLenEscaped = 0;
     while (*sql < sqlEnd) {
       if (unlikely(IS_COMMA(*sql))) {
         smlBuildInvalidDataMsg(&info->msgBuf, "invalid data", *sql);
@@ -192,16 +204,14 @@ static int32_t smlParseTagKv(SSmlHandle *info, char **sql, char *sqlEnd, SSmlLin
         (*sql)++;
         break;
       }
-      if (!hasSlash) {
-        hasSlash = (*(*sql) == SLASH);
+      if (IS_SLASH_LETTER_IN_TAG_FIELD_KEY(*sql)) {
+        keyLenEscaped++;
+        keyEscaped = true;
       }
       (*sql)++;
     }
-    if (unlikely(hasSlash)) {
-      PROCESS_SLASH(key, keyLen)
-    }
 
-    if (unlikely(IS_INVALID_COL_LEN(keyLen))) {
+    if (unlikely(IS_INVALID_COL_LEN(keyLen - keyLenEscaped))) {
       smlBuildInvalidDataMsg(&info->msgBuf, "invalid key or key is too long than 64", key);
       return TSDB_CODE_TSC_INVALID_COLUMN_LENGTH;
     }
@@ -209,7 +219,8 @@ static int32_t smlParseTagKv(SSmlHandle *info, char **sql, char *sqlEnd, SSmlLin
     // parse value
     const char *value = *sql;
     size_t      valueLen = 0;
-    hasSlash = false;
+    bool        valueEscaped = false;
+    size_t      valueLenEscaped = 0;
     while (*sql < sqlEnd) {
       // parse value
       if (unlikely(IS_SPACE(*sql) || IS_COMMA(*sql))) {
@@ -219,8 +230,9 @@ static int32_t smlParseTagKv(SSmlHandle *info, char **sql, char *sqlEnd, SSmlLin
         return TSDB_CODE_SML_INVALID_DATA;
       }
 
-      if (!hasSlash) {
-        hasSlash = (*(*sql) == SLASH);
+      if (IS_SLASH_LETTER_IN_TAG_FIELD_KEY(*sql)) {
+        valueLenEscaped++;
+        valueEscaped = true;
       }
 
       (*sql)++;
@@ -232,15 +244,24 @@ static int32_t smlParseTagKv(SSmlHandle *info, char **sql, char *sqlEnd, SSmlLin
       return TSDB_CODE_SML_INVALID_DATA;
     }
 
-    if (unlikely(hasSlash)) {
-      PROCESS_SLASH(value, valueLen)
-    }
-
-    if (unlikely(valueLen > (TSDB_MAX_NCHAR_LEN - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE)) {
+    if (unlikely(valueLen - valueLenEscaped > (TSDB_MAX_NCHAR_LEN - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE)) {
       return TSDB_CODE_PAR_INVALID_VAR_COLUMN_LEN;
     }
 
-    SSmlKv kv = {.key = key, .keyLen = keyLen, .type = TSDB_DATA_TYPE_NCHAR, .value = value, .length = valueLen};
+    if (keyEscaped){
+      char *tmp = (char*)taosMemoryMalloc(keyLen);
+      memcpy(tmp, key, keyLen);
+      PROCESS_SLASH_IN_TAG_FIELD_KEY(tmp, keyLen);
+      key = tmp;
+    }
+    if (valueEscaped){
+      char *tmp = (char*)taosMemoryMalloc(valueLen);
+      memcpy(tmp, value, valueLen);
+      PROCESS_SLASH_IN_TAG_FIELD_KEY(tmp, valueLen);
+      value = tmp;
+    }
+    SSmlKv kv = {.key = key, .keyLen = keyLen, .type = TSDB_DATA_TYPE_NCHAR, .value = value, .length = valueLen, .keyEscaped = keyEscaped, .valueEscaped = valueEscaped};
+    taosArrayPush(preLineKV, &kv);
     if (info->dataFormat) {
       if (unlikely(cnt + 1 > info->currSTableMeta->tableInfo.numOfTags)) {
         info->dataFormat = false;
@@ -266,7 +287,6 @@ static int32_t smlParseTagKv(SSmlHandle *info, char **sql, char *sqlEnd, SSmlLin
         info->needModifySchema = true;
       }
     }
-    taosArrayPush(preLineKV, &kv);
 
     cnt++;
     if (IS_SPACE(*sql)) {
@@ -285,9 +305,14 @@ static int32_t smlParseTagKv(SSmlHandle *info, char **sql, char *sqlEnd, SSmlLin
     return TSDB_CODE_OUT_OF_MEMORY;
   }
   tinfo->tags = taosArrayDup(preLineKV, NULL);
+  for(size_t i = 0; i < taosArrayGetSize(preLineKV); i++){
+    SSmlKv *kv = (SSmlKv *)taosArrayGet(preLineKV, i);
+    if(kv->keyEscaped)kv->key = NULL;
+    if(kv->valueEscaped)kv->value = NULL;
+  }
 
   smlSetCTableName(tinfo);
-  tinfo->uid = info->uid++;
+  getTableUid(info, currElement, tinfo);
   if (info->dataFormat) {
     info->currSTableMeta->uid = tinfo->uid;
     tinfo->tableDataCtx = smlInitTableDataCtx(info->pQuery, info->currSTableMeta);
@@ -321,7 +346,17 @@ static int32_t smlParseColKv(SSmlHandle *info, char **sql, char *sqlEnd, SSmlLin
       SSmlSTableMeta **tmp =
           (SSmlSTableMeta **)taosHashGet(info->superTables, currElement->measure, currElement->measureLen);
       if (unlikely(tmp == NULL)) {
-        STableMeta *pTableMeta = smlGetMeta(info, currElement->measure, currElement->measureLen);
+        char* measure = currElement->measure;
+        int   measureLen = currElement->measureLen;
+        if(currElement->measureEscaped){
+          measure = (char*)taosMemoryMalloc(currElement->measureLen);
+          memcpy(measure, currElement->measure, currElement->measureLen);
+          PROCESS_SLASH_IN_MEASUREMENT(measure, measureLen);
+        }
+        STableMeta *pTableMeta = smlGetMeta(info, measure, measureLen);
+        if(currElement->measureEscaped){
+          taosMemoryFree(measure);
+        }
         if (pTableMeta == NULL) {
           info->dataFormat = false;
           info->reRun = true;
@@ -352,10 +387,11 @@ static int32_t smlParseColKv(SSmlHandle *info, char **sql, char *sqlEnd, SSmlLin
       break;
     }
 
-    bool hasSlash = false;
     // parse key
     const char *key = *sql;
     size_t      keyLen = 0;
+    bool        keyEscaped = false;
+    size_t      keyLenEscaped = 0;
     while (*sql < sqlEnd) {
       if (unlikely(IS_COMMA(*sql))) {
         smlBuildInvalidDataMsg(&info->msgBuf, "invalid data", *sql);
@@ -366,16 +402,14 @@ static int32_t smlParseColKv(SSmlHandle *info, char **sql, char *sqlEnd, SSmlLin
         (*sql)++;
         break;
       }
-      if (!hasSlash) {
-        hasSlash = (*(*sql) == SLASH);
+      if (IS_SLASH_LETTER_IN_TAG_FIELD_KEY(*sql)) {
+        keyLenEscaped++;
+        keyEscaped = true;
       }
       (*sql)++;
     }
-    if (unlikely(hasSlash)) {
-      PROCESS_SLASH(key, keyLen)
-    }
 
-    if (unlikely(IS_INVALID_COL_LEN(keyLen))) {
+    if (unlikely(IS_INVALID_COL_LEN(keyLen - keyLenEscaped))) {
       smlBuildInvalidDataMsg(&info->msgBuf, "invalid key or key is too long than 64", key);
       return TSDB_CODE_TSC_INVALID_COLUMN_LENGTH;
     }
@@ -383,11 +417,13 @@ static int32_t smlParseColKv(SSmlHandle *info, char **sql, char *sqlEnd, SSmlLin
     // parse value
     const char *value = *sql;
     size_t      valueLen = 0;
-    hasSlash = false;
-    bool isInQuote = false;
+    bool        valueEscaped = false;
+    size_t      valueLenEscaped = 0;
+    bool        isInQuote = false;
+    const char *escapeChar = NULL;
     while (*sql < sqlEnd) {
       // parse value
-      if (unlikely(IS_QUOTE(*sql))) {
+      if (unlikely(*(*sql) == QUOTE && (*(*sql - 1) != SLASH || (*sql - 1) == escapeChar))) {
         isInQuote = !isInQuote;
         (*sql)++;
         continue;
@@ -395,13 +431,12 @@ static int32_t smlParseColKv(SSmlHandle *info, char **sql, char *sqlEnd, SSmlLin
       if (!isInQuote) {
         if (unlikely(IS_SPACE(*sql) || IS_COMMA(*sql))) {
           break;
-        } else if (unlikely(IS_EQUAL(*sql))) {
-          smlBuildInvalidDataMsg(&info->msgBuf, "invalid data", *sql);
-          return TSDB_CODE_SML_INVALID_DATA;
         }
       }
-      if (!hasSlash) {
-        hasSlash = (*(*sql) == SLASH);
+      if (IS_SLASH_LETTER_IN_FIELD_VALUE(*sql) && (*sql - 1) != escapeChar) {
+        escapeChar = *sql;
+        valueEscaped = true;
+        valueLenEscaped++;
       }
 
       (*sql)++;
@@ -416,9 +451,6 @@ static int32_t smlParseColKv(SSmlHandle *info, char **sql, char *sqlEnd, SSmlLin
       smlBuildInvalidDataMsg(&info->msgBuf, "invalid value", value);
       return TSDB_CODE_SML_INVALID_DATA;
     }
-    if (unlikely(hasSlash)) {
-      PROCESS_SLASH(value, valueLen)
-    }
 
     SSmlKv  kv = {.key = key, .keyLen = keyLen, .value = value, .length = valueLen};
     int32_t ret = smlParseValue(&kv, &info->msgBuf);
@@ -427,11 +459,28 @@ static int32_t smlParseColKv(SSmlHandle *info, char **sql, char *sqlEnd, SSmlLin
       return ret;
     }
 
+    if (keyEscaped){
+      char *tmp = (char*)taosMemoryMalloc(kv.keyLen);
+      memcpy(tmp, key, kv.keyLen);
+      PROCESS_SLASH_IN_TAG_FIELD_KEY(tmp, kv.keyLen);
+      kv.key = tmp;
+      kv.keyEscaped = keyEscaped;
+    }
+
+    if (valueEscaped){
+      char *tmp = (char*)taosMemoryMalloc(kv.length);
+      memcpy(tmp, kv.value, kv.length);
+      PROCESS_SLASH_IN_FIELD_VALUE(tmp, kv.length);
+      kv.value = tmp;
+      kv.valueEscaped = valueEscaped;
+    }
+
     if (info->dataFormat) {
       // cnt begin 0, add ts so + 2
       if (unlikely(cnt + 2 > info->currSTableMeta->tableInfo.numOfColumns)) {
         info->dataFormat = false;
         info->reRun = true;
+        freeSSmlKv(&kv);
         return TSDB_CODE_SUCCESS;
       }
       // bind data
@@ -440,22 +489,26 @@ static int32_t smlParseColKv(SSmlHandle *info, char **sql, char *sqlEnd, SSmlLin
         uDebug("smlBuildCol error, retry");
         info->dataFormat = false;
         info->reRun = true;
+        freeSSmlKv(&kv);
         return TSDB_CODE_SUCCESS;
       }
       if (cnt >= taosArrayGetSize(info->masColKVs)) {
         info->dataFormat = false;
         info->reRun = true;
+        freeSSmlKv(&kv);
         return TSDB_CODE_SUCCESS;
       }
       SSmlKv *maxKV = (SSmlKv *)taosArrayGet(info->masColKVs, cnt);
       if (kv.type != maxKV->type) {
         info->dataFormat = false;
         info->reRun = true;
+        freeSSmlKv(&kv);
         return TSDB_CODE_SUCCESS;
       }
       if (unlikely(!IS_SAME_KEY)) {
         info->dataFormat = false;
         info->reRun = true;
+        freeSSmlKv(&kv);
         return TSDB_CODE_SUCCESS;
       }
 
@@ -463,6 +516,7 @@ static int32_t smlParseColKv(SSmlHandle *info, char **sql, char *sqlEnd, SSmlLin
         maxKV->length = kv.length;
         info->needModifySchema = true;
       }
+      freeSSmlKv(&kv);
     } else {
       if (currElement->colArray == NULL) {
         currElement->colArray = taosArrayInit_s(sizeof(SSmlKv), 1);
@@ -487,10 +541,12 @@ int32_t smlParseInfluxString(SSmlHandle *info, char *sql, char *sqlEnd, SSmlLine
   elements->measure = sql;
 
   // parse measure
+  size_t measureLenEscaped = 0;
   while (sql < sqlEnd) {
-    if (unlikely((sql != elements->measure) && IS_SLASH_LETTER(sql))) {
-      MOVE_FORWARD_ONE(sql, sqlEnd - sql);
-      sqlEnd--;
+    if (unlikely((sql != elements->measure) && IS_SLASH_LETTER_IN_MEASUREMENT(sql))) {
+      elements->measureEscaped = true;
+      measureLenEscaped++;
+      sql++;
       continue;
     }
     if (unlikely(IS_COMMA(sql))) {
@@ -503,7 +559,7 @@ int32_t smlParseInfluxString(SSmlHandle *info, char *sql, char *sqlEnd, SSmlLine
     sql++;
   }
   elements->measureLen = sql - elements->measure;
-  if (unlikely(IS_INVALID_TABLE_LEN(elements->measureLen))) {
+  if (unlikely(IS_INVALID_TABLE_LEN(elements->measureLen - measureLenEscaped))) {
     smlBuildInvalidDataMsg(&info->msgBuf, "measure is empty or too large than 192", NULL);
     return TSDB_CODE_TSC_INVALID_TABLE_ID_LENGTH;
   }
@@ -581,7 +637,9 @@ int32_t smlParseInfluxString(SSmlHandle *info, char *sql, char *sqlEnd, SSmlLine
                .keyLen = TS_LEN,
                .type = TSDB_DATA_TYPE_TIMESTAMP,
                .i = ts,
-               .length = (size_t)tDataTypes[TSDB_DATA_TYPE_TIMESTAMP].bytes};
+               .length = (size_t)tDataTypes[TSDB_DATA_TYPE_TIMESTAMP].bytes,
+               .keyEscaped = false,
+               .valueEscaped = false};
   if (info->dataFormat) {
     uDebug("SML:0x%" PRIx64 " smlParseInfluxString format true, ts:%" PRId64, info->id, ts);
     ret = smlBuildCol(info->currTableDataCtx, info->currSTableMeta->schema, &kv, 0);
diff --git a/source/client/src/clientSmlTelnet.c b/source/client/src/clientSmlTelnet.c
index 036442573d..c5dd20ba7b 100644
--- a/source/client/src/clientSmlTelnet.c
+++ b/source/client/src/clientSmlTelnet.c
@@ -206,7 +206,7 @@ static int32_t smlParseTelnetTags(SSmlHandle *info, char *data, char *sqlEnd, SS
     tinfo->tags = taosArrayDup(preLineKV, NULL);
 
     smlSetCTableName(tinfo);
-    tinfo->uid = info->uid++;
+    getTableUid(info, elements, tinfo);
     if (info->dataFormat) {
       info->currSTableMeta->uid = tinfo->uid;
       tinfo->tableDataCtx = smlInitTableDataCtx(info->pQuery, info->currSTableMeta);
diff --git a/source/client/src/clientStmt.c b/source/client/src/clientStmt.c
index 6e529f1a0b..975b304bf4 100644
--- a/source/client/src/clientStmt.c
+++ b/source/client/src/clientStmt.c
@@ -325,7 +325,7 @@ int32_t stmtCleanExecInfo(STscStmt* pStmt, bool keepTable, bool deepClean) {
   taosHashCleanup(pStmt->exec.pBlockHash);
   pStmt->exec.pBlockHash = NULL;
 
-  tDestroySSubmitTbData(pStmt->exec.pCurrTbData, TSDB_MSG_FLG_ENCODE);
+  tDestroySubmitTbData(pStmt->exec.pCurrTbData, TSDB_MSG_FLG_ENCODE);
   taosMemoryFreeClear(pStmt->exec.pCurrTbData);
 
   STMT_ERR_RET(stmtCleanBindInfo(pStmt));
@@ -895,7 +895,7 @@ int stmtExec(TAOS_STMT* stmt) {
   if (STMT_TYPE_QUERY == pStmt->sql.type) {
     launchQueryImpl(pStmt->exec.pRequest, pStmt->sql.pQuery, true, NULL);
   } else {
-    tDestroySSubmitTbData(pStmt->exec.pCurrTbData, TSDB_MSG_FLG_ENCODE);
+    tDestroySubmitTbData(pStmt->exec.pCurrTbData, TSDB_MSG_FLG_ENCODE);
     taosMemoryFreeClear(pStmt->exec.pCurrTbData);
 
     STMT_ERR_RET(qCloneCurrentTbData(pStmt->exec.pCurrBlock, &pStmt->exec.pCurrTbData));
diff --git a/source/client/src/clientTmq.c b/source/client/src/clientTmq.c
index ceca06e309..b488af9ba1 100644
--- a/source/client/src/clientTmq.c
+++ b/source/client/src/clientTmq.c
@@ -373,9 +373,6 @@ int32_t tmq_list_append(tmq_list_t* list, const char* src) {
   SArray* container = &list->container;
   if (src == NULL || src[0] == 0) return -1;
   char* topic = taosStrdup(src);
-  if (topic[0] != '`') {
-    strtolower(topic, src);
-  }
   if (taosArrayPush(container, &topic) == NULL) return -1;
   return 0;
 }
@@ -867,7 +864,7 @@ static void* tmqFreeRspWrapper(SMqRspWrapper* rspWrapper) {
     taosArrayDestroyP(pRsp->dataRsp.blockData, taosMemoryFree);
     taosArrayDestroy(pRsp->dataRsp.blockDataLen);
     taosArrayDestroyP(pRsp->dataRsp.blockTbName, taosMemoryFree);
-    taosArrayDestroyP(pRsp->dataRsp.blockSchema, (FDelete)tDeleteSSchemaWrapper);
+    taosArrayDestroyP(pRsp->dataRsp.blockSchema, (FDelete)tDeleteSchemaWrapper);
   } else if (rspWrapper->tmqRspType == TMQ_MSG_TYPE__POLL_META_RSP) {
     SMqPollRspWrapper* pRsp = (SMqPollRspWrapper*)rspWrapper;
     taosMemoryFreeClear(pRsp->pEpset);
@@ -880,7 +877,7 @@ static void* tmqFreeRspWrapper(SMqRspWrapper* rspWrapper) {
     taosArrayDestroyP(pRsp->taosxRsp.blockData, taosMemoryFree);
     taosArrayDestroy(pRsp->taosxRsp.blockDataLen);
     taosArrayDestroyP(pRsp->taosxRsp.blockTbName, taosMemoryFree);
-    taosArrayDestroyP(pRsp->taosxRsp.blockSchema, (FDelete)tDeleteSSchemaWrapper);
+    taosArrayDestroyP(pRsp->taosxRsp.blockSchema, (FDelete)tDeleteSchemaWrapper);
     // taosx
     taosArrayDestroy(pRsp->taosxRsp.createTableLen);
     taosArrayDestroyP(pRsp->taosxRsp.createTableReq, taosMemoryFree);
@@ -1243,9 +1240,6 @@ int32_t tmqPollCb(void* param, SDataBuf* pMsg, int32_t code) {
   taosMemoryFree(pParam);
 
   if (code != 0) {
-    tscWarn("consumer:0x%" PRIx64 " msg from vgId:%d discarded, epoch %d, since %s, reqId:0x%" PRIx64, tmq->consumerId,
-            vgId, epoch, tstrerror(code), requestId);
-
     if (pMsg->pData) taosMemoryFree(pMsg->pData);
     if (pMsg->pEpSet) taosMemoryFree(pMsg->pEpSet);
 
@@ -1267,6 +1261,9 @@ int32_t tmqPollCb(void* param, SDataBuf* pMsg, int32_t code) {
       taosWriteQitem(tmq->mqueue, pRspWrapper);
     } else if (code == TSDB_CODE_WAL_LOG_NOT_EXIST) {  // poll data while insert
       taosMsleep(500);
+    } else{
+      tscError("consumer:0x%" PRIx64 " msg from vgId:%d discarded, epoch %d, since %s, reqId:0x%" PRIx64, tmq->consumerId,
+               vgId, epoch, tstrerror(code), requestId);
     }
 
     goto CREATE_MSG_FAIL;
@@ -1380,7 +1377,7 @@ static void initClientTopicFromRsp(SMqClientTopic* pTopic, SMqSubTopicEp* pTopic
   tstrncpy(pTopic->topicName, pTopicEp->topic, TSDB_TOPIC_FNAME_LEN);
   tstrncpy(pTopic->db, pTopicEp->db, TSDB_DB_FNAME_LEN);
 
-  tscDebug("consumer:0x%" PRIx64 ", update topic:%s, numOfVgs:%d", tmq->consumerId, pTopic->topicName, vgNumGet);
+  tscDebug("consumer:0x%" PRIx64 ", update topic:%s, new numOfVgs:%d", tmq->consumerId, pTopic->topicName, vgNumGet);
   pTopic->vgs = taosArrayInit(vgNumGet, sizeof(SMqClientVg));
 
   for (int32_t j = 0; j < vgNumGet; j++) {
@@ -1450,14 +1447,14 @@ static bool doUpdateLocalEp(tmq_t* tmq, int32_t epoch, const SMqAskEpRsp* pRsp)
     SMqClientTopic* pTopicCur = taosArrayGet(tmq->clientTopics, i);
     if (pTopicCur->vgs) {
       int32_t vgNumCur = taosArrayGetSize(pTopicCur->vgs);
-      tscDebug("consumer:0x%" PRIx64 ", new vg num: %d", tmq->consumerId, vgNumCur);
+      tscDebug("consumer:0x%" PRIx64 ", current vg num: %d", tmq->consumerId, vgNumCur);
       for (int32_t j = 0; j < vgNumCur; j++) {
         SMqClientVg* pVgCur = taosArrayGet(pTopicCur->vgs, j);
         makeTopicVgroupKey(vgKey, pTopicCur->topicName, pVgCur->vgId);
 
         char buf[80];
         tFormatOffset(buf, 80, &pVgCur->currentOffset);
-        tscDebug("consumer:0x%" PRIx64 ", epoch:%d vgId:%d vgKey:%s, offset:%s", tmq->consumerId, epoch, pVgCur->vgId,
+        tscDebug("consumer:0x%" PRIx64 ", doUpdateLocalEp current vg, epoch:%d vgId:%d vgKey:%s, offset:%s", tmq->consumerId, tmq->epoch, pVgCur->vgId,
                  vgKey, buf);
 
         SVgroupSaveInfo info = {.offset = pVgCur->currentOffset, .numOfRows = pVgCur->numOfRows};
@@ -1667,11 +1664,7 @@ static int32_t doTmqPollImpl(tmq_t* pTmq, SMqClientTopic* pTopic, SMqClientVg* p
     return handleErrorBeforePoll(pVg, pTmq);
   }
 
-  sendInfo->msgInfo = (SDataBuf){
-      .pData = msg,
-      .len = msgSize,
-      .handle = NULL,
-  };
+  sendInfo->msgInfo = (SDataBuf){ .pData = msg, .len = msgSize, .handle = NULL };
 
   sendInfo->requestId = req.reqId;
   sendInfo->requestObjRefId = 0;
@@ -1797,8 +1790,9 @@ static void* tmqHandleAllRsp(tmq_t* tmq, int64_t timeout, bool pollIfReset) {
           pVg->epSet = *pollRspWrapper->pEpset;
         }
 
-        // update the local offset value only for the returned values.
-        pVg->currentOffset = pDataRsp->rspOffset;
+        if(pDataRsp->rspOffset.type != 0){    // if offset is validate
+          pVg->currentOffset = pDataRsp->rspOffset;          // update the local offset value only for the returned values.
+        }
         atomic_store_32(&pVg->vgStatus, TMQ_VG_STATUS__IDLE);
 
         char buf[80];
@@ -1808,12 +1802,13 @@ static void* tmqHandleAllRsp(tmq_t* tmq, int64_t timeout, bool pollIfReset) {
                    " total:%" PRId64 " reqId:0x%" PRIx64,
                    tmq->consumerId, pVg->vgId, buf, pVg->numOfRows, tmq->totalRows, pollRspWrapper->reqId);
           pRspWrapper = tmqFreeRspWrapper(pRspWrapper);
+          pVg->emptyBlockReceiveTs = taosGetTimestampMs();
           taosFreeQitem(pollRspWrapper);
         } else {  // build rsp
           int64_t    numOfRows = 0;
           SMqRspObj* pRsp = tmqBuildRspFromWrapper(pollRspWrapper, pVg, &numOfRows);
           tmq->totalRows += numOfRows;
-
+          pVg->emptyBlockReceiveTs = 0;
           tscDebug("consumer:0x%" PRIx64 " process poll rsp, vgId:%d, offset:%s, blocks:%d, rows:%" PRId64
                    " vg total:%" PRId64 " total:%" PRId64 ", reqId:0x%" PRIx64,
                    tmq->consumerId, pVg->vgId, buf, pDataRsp->blockNum, numOfRows, pVg->numOfRows, tmq->totalRows,
@@ -1835,7 +1830,9 @@ static void* tmqHandleAllRsp(tmq_t* tmq, int64_t timeout, bool pollIfReset) {
 
       if (pollRspWrapper->metaRsp.head.epoch == consumerEpoch) {
         SMqClientVg* pVg = pollRspWrapper->vgHandle;
-        pVg->currentOffset = pollRspWrapper->metaRsp.rspOffset;
+        if(pollRspWrapper->metaRsp.rspOffset.type != 0){    // if offset is validate
+          pVg->currentOffset = pollRspWrapper->metaRsp.rspOffset;
+        }
         atomic_store_32(&pVg->vgStatus, TMQ_VG_STATUS__IDLE);
         // build rsp
         SMqMetaRspObj* pRsp = tmqBuildMetaRspFromWrapper(pollRspWrapper);
@@ -1853,7 +1850,9 @@ static void* tmqHandleAllRsp(tmq_t* tmq, int64_t timeout, bool pollIfReset) {
 
       if (pollRspWrapper->taosxRsp.head.epoch == consumerEpoch) {
         SMqClientVg* pVg = pollRspWrapper->vgHandle;
-        pVg->currentOffset = pollRspWrapper->taosxRsp.rspOffset;
+        if(pollRspWrapper->taosxRsp.rspOffset.type != 0){    // if offset is validate
+          pVg->currentOffset = pollRspWrapper->taosxRsp.rspOffset;
+        }
         atomic_store_32(&pVg->vgStatus, TMQ_VG_STATUS__IDLE);
 
         if (pollRspWrapper->taosxRsp.blockNum == 0) {
diff --git a/source/client/test/clientTests.cpp b/source/client/test/clientTests.cpp
index 055ac450dc..56f68e5972 100644
--- a/source/client/test/clientTests.cpp
+++ b/source/client/test/clientTests.cpp
@@ -165,7 +165,7 @@ void* queryThread(void* arg) {
 int32_t numOfThreads = 1;
 
 void tmq_commit_cb_print(tmq_t* pTmq, int32_t code, void* param) {
-  printf("auto commit success, code:%d\n\n\n\n", code);
+//  printf("auto commit success, code:%d\n", code);
 }
 
 void* doConsumeData(void* param) {
@@ -1059,13 +1059,18 @@ TEST(clientCase, sub_tb_test) {
   ASSERT_NE(pConn, nullptr);
 
   tmq_conf_t* conf = tmq_conf_new();
+
+  int32_t ts = taosGetTimestampMs()%INT32_MAX;
+  char consumerGroupid[128] = {0};
+  sprintf(consumerGroupid, "group_id_%d", ts);
+
   tmq_conf_set(conf, "enable.auto.commit", "true");
-  tmq_conf_set(conf, "auto.commit.interval.ms", "1000");
-  tmq_conf_set(conf, "group.id", "cgrpName45");
+  tmq_conf_set(conf, "auto.commit.interval.ms", "2000");
+  tmq_conf_set(conf, "group.id", consumerGroupid);
   tmq_conf_set(conf, "td.connect.user", "root");
   tmq_conf_set(conf, "td.connect.pass", "taosdata");
   tmq_conf_set(conf, "auto.offset.reset", "earliest");
-  tmq_conf_set(conf, "experimental.snapshot.enable", "true");
+  tmq_conf_set(conf, "experimental.snapshot.enable", "false");
   tmq_conf_set(conf, "msg.with.table.name", "true");
   tmq_conf_set_auto_commit_cb(conf, tmq_commit_cb_print, NULL);
 
@@ -1074,7 +1079,7 @@ TEST(clientCase, sub_tb_test) {
 
   // 创建订阅 topics 列表
   tmq_list_t* topicList = tmq_list_new();
-  tmq_list_append(topicList, "topic_t2");
+  tmq_list_append(topicList, "topic_t1");
 
   // 启动订阅
   tmq_subscribe(tmq, topicList);
@@ -1086,22 +1091,22 @@ TEST(clientCase, sub_tb_test) {
   int32_t     precision = 0;
   int32_t     totalRows = 0;
   int32_t     msgCnt = 0;
-  int32_t     timeout = 25000;
+  int32_t     timeout = 2500000;
 
   int32_t count = 0;
 
   while (1) {
     TAOS_RES* pRes = tmq_consumer_poll(tmq, timeout);
     if (pRes) {
-      char buf[1024];
+      char buf[128];
 
       const char* topicName = tmq_get_topic_name(pRes);
-      const char* dbName = tmq_get_db_name(pRes);
-      int32_t     vgroupId = tmq_get_vgroup_id(pRes);
-
-      printf("topic: %s\n", topicName);
-      printf("db: %s\n", dbName);
-      printf("vgroup id: %d\n", vgroupId);
+//      const char* dbName = tmq_get_db_name(pRes);
+//      int32_t     vgroupId = tmq_get_vgroup_id(pRes);
+//
+//      printf("topic: %s\n", topicName);
+//      printf("db: %s\n", dbName);
+//      printf("vgroup id: %d\n", vgroupId);
 
       while (1) {
         TAOS_ROW row = taos_fetch_row(pRes);
@@ -1111,16 +1116,14 @@ TEST(clientCase, sub_tb_test) {
 
         fields = taos_fetch_fields(pRes);
         numOfFields = taos_field_count(pRes);
-        precision = taos_result_precision(pRes);
-        taos_print_row(buf, row, fields, numOfFields);
         totalRows += 1;
-        printf("precision: %d, row content: %s\n", precision, buf);
+//        if (totalRows % 100000 == 0) {
+          taos_print_row(buf, row, fields, numOfFields);
+          printf("row content: %s\n", buf);
+//        }
       }
 
       taos_free_result(pRes);
-      //      if ((++count) > 1) {
-      //        break;
-      //      }
     } else {
       break;
     }
diff --git a/source/client/test/smlTest.cpp b/source/client/test/smlTest.cpp
index 76911e229a..1578b8b607 100644
--- a/source/client/test/smlTest.cpp
+++ b/source/client/test/smlTest.cpp
@@ -50,8 +50,9 @@ TEST(testCase, smlParseInfluxString_Test) {
   int ret = smlParseInfluxString(info, sql, sql + strlen(sql), &elements);
   ASSERT_EQ(ret, 0);
   ASSERT_EQ(elements.measure, sql);
-  ASSERT_EQ(elements.measureLen, strlen(",st"));
-  ASSERT_EQ(elements.measureTagsLen, strlen(",st,t1=3,t2=4,t3=t3"));
+  ASSERT_EQ(elements.measureLen, strlen("\\,st"));
+  ASSERT_EQ(elements.measureEscaped, true);
+  ASSERT_EQ(elements.measureTagsLen, strlen("\\,st,t1=3,t2=4,t3=t3"));
 
   ASSERT_EQ(elements.tags, sql + elements.measureLen + 1);
   ASSERT_EQ(elements.tagsLen, strlen("t1=3,t2=4,t3=t3"));
@@ -204,7 +205,26 @@ TEST(testCase, smlParseCols_Error_Test) {
                         "st,t=1 c=-3.402823466e+39u64 1626006833639000000",
                         "st,t=1 c=-339u64 1626006833639000000",
                         "st,t=1 c=18446744073709551616u64 1626006833639000000",
-                        "st,t=1 c=1=2 1626006833639000000"};
+                        "st,t=1 c=1=2 1626006833639000000,",
+                        // escape error test
+                        // measure comma,space
+                        "s,t,t=1 c=1 1626006833639000000,",
+                        "s t,t=1 c=1 1626006833639000000,",
+                        //tag key comma,equal,space
+                        "st,t,t=1 c=2 1626006833639000000,",
+                        "st,t=t=1 c=2 1626006833639000000,",
+                        "st,t t=1 c=2 1626006833639000000,",
+                        //tag value comma,equal,space
+                        "st,tt=a,a c=2 1626006833639000000,",
+                        "st,t=t=a a c=2 1626006833639000000,",
+                        "st,t t=a=a c=2 1626006833639000000,",
+                        //field key comma,equal,space
+                        "st,tt=aa c,1=2 1626006833639000000,",
+                        "st,tt=aa c=1=2 1626006833639000000,",
+                        "st,tt=aa c 1=2 1626006833639000000,",
+                        //field value    double quote,slash
+                        "st,tt=aa c=\"a\"a\" 1626006833639000000,",
+  };
 
   SSmlHandle *info = smlBuildSmlInfo(NULL);
   info->protocol = TSDB_SML_LINE_PROTOCOL;
@@ -256,16 +276,18 @@ TEST(testCase, smlParseCols_Test) {
   ASSERT_EQ(strncasecmp(kv->key, "cb=in", 5), 0);
   ASSERT_EQ(kv->keyLen, 5);
   ASSERT_EQ(kv->type, TSDB_DATA_TYPE_BINARY);
-  ASSERT_EQ(kv->length, 17);
-  ASSERT_EQ(strncasecmp(kv->value, "pass,it ", 8), 0);
+  ASSERT_EQ(kv->length, 18);
+  ASSERT_EQ(kv->keyEscaped, true);
+  ASSERT_EQ(kv->valueEscaped, false);
+  ASSERT_EQ(strncasecmp(kv->value, "pass\\,it ", 9), 0);
 
   // nchar
   kv = (SSmlKv *)taosArrayGet(elements.colArray, 2);
   ASSERT_EQ(strncasecmp(kv->key, "cnch", 4), 0);
   ASSERT_EQ(kv->keyLen, 4);
   ASSERT_EQ(kv->type, TSDB_DATA_TYPE_NCHAR);
-  ASSERT_EQ(kv->length, 8);
-  ASSERT_EQ(strncasecmp(kv->value, "ii=sd", 5), 0);
+  ASSERT_EQ(kv->length, 9);
+  ASSERT_EQ(strncasecmp(kv->value, "ii\\=sd", 5), 0);
 
   // bool
   kv = (SSmlKv *)taosArrayGet(elements.colArray, 3);
diff --git a/source/common/src/tdatablock.c b/source/common/src/tdatablock.c
index f4d2ed01b0..5f7e43668a 100644
--- a/source/common/src/tdatablock.c
+++ b/source/common/src/tdatablock.c
@@ -120,6 +120,7 @@ int32_t colDataSetVal(SColumnInfoData* pColumnInfoData, uint32_t rowIndex, const
     pColumnInfoData->varmeta.length += dataLen;
   } else {
     memcpy(pColumnInfoData->pData + pColumnInfoData->info.bytes * rowIndex, pData, pColumnInfoData->info.bytes);
+    colDataClearNull_f(pColumnInfoData->nullbitmap, rowIndex);
   }
 
   return 0;
@@ -1949,12 +1950,11 @@ void blockDebugShowDataBlocks(const SArray* dataBlocks, const char* flag) {
     }
   }
 }
-
 #endif
 
 // for debug
 char* dumpBlockData(SSDataBlock* pDataBlock, const char* flag, char** pDataBuf) {
-  int32_t size = 2048;
+  int32_t size = 2048*1024;
   *pDataBuf = taosMemoryCalloc(size, 1);
   char*   dumpBuf = *pDataBuf;
   char    pBuf[128] = {0};
@@ -1970,7 +1970,7 @@ char* dumpBlockData(SSDataBlock* pDataBlock, const char* flag, char** pDataBuf)
   if (len >= size - 1) return dumpBuf;
 
   for (int32_t j = 0; j < rows; j++) {
-    len += snprintf(dumpBuf + len, size - len, "%s |", flag);
+    len += snprintf(dumpBuf + len, size - len, "%s %d|", flag, j);
     if (len >= size - 1) return dumpBuf;
 
     for (int32_t k = 0; k < colNum; k++) {
@@ -2374,7 +2374,7 @@ int32_t buildSubmitReqFromDataBlock(SSubmitReq2** ppReq, const SSDataBlock* pDat
       }
       SRow* pRow = NULL;
       if ((terrno = tRowBuild(pVals, pTSchema, &pRow)) < 0) {
-        tDestroySSubmitTbData(&tbData, TSDB_MSG_FLG_ENCODE);
+        tDestroySubmitTbData(&tbData, TSDB_MSG_FLG_ENCODE);
         goto _end;
       }
       ASSERT(pRow);
@@ -2388,7 +2388,7 @@ _end:
   if (terrno != 0) {
     *ppReq = NULL;
     if (pReq) {
-      tDestroySSubmitReq2(pReq, TSDB_MSG_FLG_ENCODE);
+      tDestroySubmitReq(pReq, TSDB_MSG_FLG_ENCODE);
       taosMemoryFreeClear(pReq);
     }
 
diff --git a/source/common/src/tdataformat.c b/source/common/src/tdataformat.c
index f379084cf5..b18bd882ae 100644
--- a/source/common/src/tdataformat.c
+++ b/source/common/src/tdataformat.c
@@ -1509,7 +1509,9 @@ void tTagSetCid(const STag *pTag, int16_t iTag, int16_t cid) {
 // STSchema ========================================
 STSchema *tBuildTSchema(SSchema *aSchema, int32_t numOfCols, int32_t version) {
   STSchema *pTSchema = taosMemoryCalloc(1, sizeof(STSchema) + sizeof(STColumn) * numOfCols);
-  if (pTSchema == NULL) return NULL;
+  if (pTSchema == NULL) {
+    return NULL;
+  }
 
   pTSchema->numOfCols = numOfCols;
   pTSchema->version = version;
diff --git a/source/common/src/tglobal.c b/source/common/src/tglobal.c
index da4a912238..b85dfa80b0 100644
--- a/source/common/src/tglobal.c
+++ b/source/common/src/tglobal.c
@@ -84,7 +84,7 @@ bool     tsMonitorComp = false;
 // telem
 bool     tsEnableTelem = true;
 int32_t  tsTelemInterval = 43200;
-char     tsTelemServer[TSDB_FQDN_LEN] = "telemetry.taosdata.com";
+char     tsTelemServer[TSDB_FQDN_LEN] = "telemetry.tdengine.com";
 uint16_t tsTelemPort = 80;
 char    *tsTelemUri = "/report";
 
@@ -198,7 +198,7 @@ int32_t tsTransPullupInterval = 2;
 int32_t tsMqRebalanceInterval = 2;
 int32_t tsStreamCheckpointTickInterval = 1;
 int32_t tsTtlUnit = 86400;
-int32_t tsTtlPushInterval = 86400;
+int32_t tsTtlPushInterval = 3600;
 int32_t tsGrantHBInterval = 60;
 int32_t tsUptimeInterval = 300;    // seconds
 char    tsUdfdResFuncs[512] = "";  // udfd resident funcs that teardown when udfd exits
diff --git a/source/common/src/tmsg.c b/source/common/src/tmsg.c
index f594831bad..fde3a89081 100644
--- a/source/common/src/tmsg.c
+++ b/source/common/src/tmsg.c
@@ -1409,6 +1409,8 @@ int32_t tDeserializeSAlterUserReq(void *buf, int32_t bufLen, SAlterUserReq *pReq
   return 0;
 }
 
+void tFreeSAlterUserReq(SAlterUserReq *pReq) { taosMemoryFreeClear(pReq->tagCond); }
+
 int32_t tSerializeSGetUserAuthReq(void *buf, int32_t bufLen, SGetUserAuthReq *pReq) {
   SEncoder encoder = {0};
   tEncoderInit(&encoder, buf, bufLen);
@@ -1635,6 +1637,7 @@ int32_t tDeserializeSGetUserAuthRspImpl(SDecoder *pDecoder, SGetUserAuthRsp *pRs
       int32_t ref = 0;
       if (tDecodeI32(pDecoder, &ref) < 0) return -1;
       taosHashPut(pRsp->useDbs, key, strlen(key), &ref, sizeof(ref));
+      taosMemoryFree(key);
     }
   }
 
@@ -1831,7 +1834,6 @@ int32_t tSerializeSCreateFuncReq(void *buf, int32_t bufLen, SCreateFuncReq *pReq
     if (tEncodeCStr(&encoder, pReq->pComment) < 0) return -1;
   }
 
-
   if (tEncodeI8(&encoder, pReq->orReplace) < 0) return -1;
 
   tEndEncode(&encoder);
@@ -1876,7 +1878,6 @@ int32_t tDeserializeSCreateFuncReq(void *buf, int32_t bufLen, SCreateFuncReq *pR
     if (tDecodeCStrTo(&decoder, pReq->pComment) < 0) return -1;
   }
 
-
   if (!tDecodeIsEnd(&decoder)) {
     if (tDecodeI8(&decoder, &pReq->orReplace) < 0) return -1;
   } else {
@@ -2053,12 +2054,12 @@ int32_t tDeserializeSRetrieveFuncRsp(void *buf, int32_t bufLen, SRetrieveFuncRsp
   if (pRsp->pFuncExtraInfos == NULL) return -1;
   if (tDecodeIsEnd(&decoder)) {
     for (int32_t i = 0; i < pRsp->numOfFuncs; ++i) {
-      SFuncExtraInfo  extraInfo  = { 0 };
+      SFuncExtraInfo extraInfo = {0};
       taosArrayPush(pRsp->pFuncExtraInfos, &extraInfo);
     }
   } else {
     for (int32_t i = 0; i < pRsp->numOfFuncs; ++i) {
-      SFuncExtraInfo extraInfo = { 0 };
+      SFuncExtraInfo extraInfo = {0};
       if (tDecodeI32(&decoder, &extraInfo.funcVersion) < 0) return -1;
       if (tDecodeI64(&decoder, &extraInfo.funcCreatedTime) < 0) return -1;
       taosArrayPush(pRsp->pFuncExtraInfos, &extraInfo);
@@ -5407,9 +5408,9 @@ int32_t tSerializeSMqPollReq(void *buf, int32_t bufLen, SMqPollReq *pReq) {
 int32_t tDeserializeSMqPollReq(void *buf, int32_t bufLen, SMqPollReq *pReq) {
   int32_t headLen = sizeof(SMsgHead);
 
-  SMsgHead *pHead = buf;
-  pHead->vgId = pReq->head.vgId;
-  pHead->contLen = pReq->head.contLen;
+//  SMsgHead *pHead = buf;
+//  pHead->vgId = pReq->head.vgId;
+//  pHead->contLen = pReq->head.contLen;
 
   SDecoder decoder = {0};
   tDecoderInit(&decoder, (char *)buf + headLen, bufLen - headLen);
@@ -6917,10 +6918,8 @@ int32_t tEncodeSTqOffsetVal(SEncoder *pEncoder, const STqOffsetVal *pOffsetVal)
     if (tEncodeI64(pEncoder, pOffsetVal->ts) < 0) return -1;
   } else if (pOffsetVal->type == TMQ_OFFSET__LOG) {
     if (tEncodeI64(pEncoder, pOffsetVal->version) < 0) return -1;
-  } else if (pOffsetVal->type < 0) {
-    // do nothing
   } else {
-    ASSERT(0);
+    // do nothing
   }
   return 0;
 }
@@ -6932,10 +6931,8 @@ int32_t tDecodeSTqOffsetVal(SDecoder *pDecoder, STqOffsetVal *pOffsetVal) {
     if (tDecodeI64(pDecoder, &pOffsetVal->ts) < 0) return -1;
   } else if (pOffsetVal->type == TMQ_OFFSET__LOG) {
     if (tDecodeI64(pDecoder, &pOffsetVal->version) < 0) return -1;
-  } else if (pOffsetVal->type < 0) {
-    // do nothing
   } else {
-    ASSERT(0);
+    // do nothing
   }
   return 0;
 }
@@ -7140,7 +7137,7 @@ void tDeleteSMqDataRsp(SMqDataRsp *pRsp) {
   pRsp->blockDataLen = taosArrayDestroy(pRsp->blockDataLen);
   taosArrayDestroyP(pRsp->blockData, (FDelete)taosMemoryFree);
   pRsp->blockData = NULL;
-  taosArrayDestroyP(pRsp->blockSchema, (FDelete)tDeleteSSchemaWrapper);
+  taosArrayDestroyP(pRsp->blockSchema, (FDelete)tDeleteSchemaWrapper);
   pRsp->blockSchema = NULL;
   taosArrayDestroyP(pRsp->blockTbName, (FDelete)taosMemoryFree);
   pRsp->blockTbName = NULL;
@@ -7241,7 +7238,7 @@ void tDeleteSTaosxRsp(STaosxRsp *pRsp) {
   pRsp->blockDataLen = NULL;
   taosArrayDestroyP(pRsp->blockData, (FDelete)taosMemoryFree);
   pRsp->blockData = NULL;
-  taosArrayDestroyP(pRsp->blockSchema, (FDelete)tDeleteSSchemaWrapper);
+  taosArrayDestroyP(pRsp->blockSchema, (FDelete)tDeleteSchemaWrapper);
   pRsp->blockSchema = NULL;
   taosArrayDestroyP(pRsp->blockTbName, (FDelete)taosMemoryFree);
   pRsp->blockTbName = NULL;
@@ -7414,7 +7411,7 @@ _exit:
   return 0;
 }
 
-int32_t tEncodeSSubmitReq2(SEncoder *pCoder, const SSubmitReq2 *pReq) {
+int32_t tEncodeSubmitReq(SEncoder *pCoder, const SSubmitReq2 *pReq) {
   if (tStartEncode(pCoder) < 0) return -1;
 
   if (tEncodeU64v(pCoder, taosArrayGetSize(pReq->aSubmitTbData)) < 0) return -1;
@@ -7426,7 +7423,7 @@ int32_t tEncodeSSubmitReq2(SEncoder *pCoder, const SSubmitReq2 *pReq) {
   return 0;
 }
 
-int32_t tDecodeSSubmitReq2(SDecoder *pCoder, SSubmitReq2 *pReq) {
+int32_t tDecodeSubmitReq(SDecoder *pCoder, SSubmitReq2 *pReq) {
   int32_t code = 0;
 
   memset(pReq, 0, sizeof(*pReq));
@@ -7469,7 +7466,7 @@ _exit:
   return code;
 }
 
-void tDestroySSubmitTbData(SSubmitTbData *pTbData, int32_t flag) {
+void tDestroySubmitTbData(SSubmitTbData *pTbData, int32_t flag) {
   if (NULL == pTbData) {
     return;
   }
@@ -7515,14 +7512,14 @@ void tDestroySSubmitTbData(SSubmitTbData *pTbData, int32_t flag) {
   }
 }
 
-void tDestroySSubmitReq2(SSubmitReq2 *pReq, int32_t flag) {
+void tDestroySubmitReq(SSubmitReq2 *pReq, int32_t flag) {
   if (pReq->aSubmitTbData == NULL) return;
 
   int32_t        nSubmitTbData = TARRAY_SIZE(pReq->aSubmitTbData);
   SSubmitTbData *aSubmitTbData = (SSubmitTbData *)TARRAY_DATA(pReq->aSubmitTbData);
 
   for (int32_t i = 0; i < nSubmitTbData; i++) {
-    tDestroySSubmitTbData(&aSubmitTbData[i], flag);
+    tDestroySubmitTbData(&aSubmitTbData[i], flag);
   }
   taosArrayDestroy(pReq->aSubmitTbData);
   pReq->aSubmitTbData = NULL;
diff --git a/source/common/src/tname.c b/source/common/src/tname.c
index e5ed7a3728..c6210ca8c9 100644
--- a/source/common/src/tname.c
+++ b/source/common/src/tname.c
@@ -122,10 +122,8 @@ int32_t tNameLen(const SName* name) {
   int32_t len2 = (int32_t)strlen(name->tname);
 
   if (name->type == TSDB_DB_NAME_T) {
-    ASSERT(len2 == 0);
     return len + len1 + TSDB_NAME_DELIMITER_LEN;
   } else {
-    ASSERT(len2 > 0);
     return len + len1 + len2 + TSDB_NAME_DELIMITER_LEN * 2;
   }
 }
diff --git a/source/common/src/ttszip.c b/source/common/src/ttszip.c
index 0faa6eb4c8..f415bd20cd 100644
--- a/source/common/src/ttszip.c
+++ b/source/common/src/ttszip.c
@@ -982,7 +982,6 @@ void tsBufSetCursor(STSBuf* pTSBuf, STSCursor* pCur) {
     return;
   }
 
-  //  assert(pCur->vgroupIndex != -1 && pCur->tsIndex >= 0 && pCur->blockIndex >= 0);
   if (pCur->vgroupIndex != -1) {
     tsBufGetBlock(pTSBuf, pCur->vgroupIndex, pCur->blockIndex);
   }
diff --git a/source/dnode/mgmt/exe/dmMain.c b/source/dnode/mgmt/exe/dmMain.c
index f0e020edfe..989bff3984 100644
--- a/source/dnode/mgmt/exe/dmMain.c
+++ b/source/dnode/mgmt/exe/dmMain.c
@@ -87,18 +87,6 @@ static void dmStopDnode(int signum, void *sigInfo, void *context) {
 }
 
 void dmLogCrash(int signum, void *sigInfo, void *context) {
-  taosIgnSignal(SIGTERM);
-  taosIgnSignal(SIGHUP);
-  taosIgnSignal(SIGINT);
-  taosIgnSignal(SIGBREAK);
-
-#ifndef WINDOWS
-  taosIgnSignal(SIGBUS);
-#endif
-  taosIgnSignal(SIGABRT);
-  taosIgnSignal(SIGFPE);
-  taosIgnSignal(SIGSEGV);
-
   char       *pMsg = NULL;
   const char *flags = "UTL FATAL ";
   ELogLevel   level = DEBUG_FATAL;
diff --git a/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c b/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c
index d61eb3ec03..fc724f2b45 100644
--- a/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c
+++ b/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c
@@ -519,7 +519,7 @@ SArray *vmGetMsgHandles() {
   if (dmSetMgmtHandle(pArray, TDMT_VND_TMQ_COMMIT_OFFSET, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
   if (dmSetMgmtHandle(pArray, TDMT_VND_TMQ_ADD_CHECKINFO, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
   if (dmSetMgmtHandle(pArray, TDMT_VND_TMQ_DEL_CHECKINFO, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
-  if (dmSetMgmtHandle(pArray, TDMT_VND_TMQ_CONSUME, vmPutMsgToFetchQueue, 0) == NULL) goto _OVER;
+  if (dmSetMgmtHandle(pArray, TDMT_VND_TMQ_CONSUME, vmPutMsgToQueryQueue, 0) == NULL) goto _OVER;
   if (dmSetMgmtHandle(pArray, TDMT_VND_DELETE, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
   if (dmSetMgmtHandle(pArray, TDMT_VND_BATCH_DEL, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
   if (dmSetMgmtHandle(pArray, TDMT_VND_COMMIT, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
diff --git a/source/dnode/mgmt/mgmt_vnode/src/vmWorker.c b/source/dnode/mgmt/mgmt_vnode/src/vmWorker.c
index da08bd01ac..a318b9886e 100644
--- a/source/dnode/mgmt/mgmt_vnode/src/vmWorker.c
+++ b/source/dnode/mgmt/mgmt_vnode/src/vmWorker.c
@@ -113,8 +113,16 @@ static void vmProcessFetchQueue(SQueueInfo *pInfo, STaosQall *qall, int32_t numO
 
     int32_t code = vnodeProcessFetchMsg(pVnode->pImpl, pMsg, pInfo);
     if (code != 0) {
-      if (terrno != 0) code = terrno;
-      dGError("vnodeProcessFetchMsg vgId:%d, msg:%p failed to fetch since %s", pVnode->vgId, pMsg, terrstr());
+      if (terrno != 0) {
+        code = terrno;
+      }
+
+      if (code == TSDB_CODE_WAL_LOG_NOT_EXIST) {
+        dGDebug("vnodeProcessFetchMsg vgId:%d, msg:%p failed to fetch since %s", pVnode->vgId, pMsg, terrstr());
+      } else {
+        dGError("vnodeProcessFetchMsg vgId:%d, msg:%p failed to fetch since %s", pVnode->vgId, pMsg, terrstr());
+      }
+
       vmSendRsp(pMsg, code);
     }
 
diff --git a/source/dnode/mgmt/node_mgmt/src/dmNodes.c b/source/dnode/mgmt/node_mgmt/src/dmNodes.c
index 16931ab6df..19d5e06c5b 100644
--- a/source/dnode/mgmt/node_mgmt/src/dmNodes.c
+++ b/source/dnode/mgmt/node_mgmt/src/dmNodes.c
@@ -132,11 +132,15 @@ int32_t dmRunDnode(SDnode *pDnode) {
   int32_t count = 0;
   if (dmOpenNodes(pDnode) != 0) {
     dError("failed to open nodes since %s", terrstr());
+    dmCloseNodes(pDnode);
     return -1;
   }
 
   if (dmStartNodes(pDnode) != 0) {
     dError("failed to start nodes since %s", terrstr());
+    dmSetStatus(pDnode, DND_STAT_STOPPED);
+    dmStopNodes(pDnode);
+    dmCloseNodes(pDnode);
     return -1;
   }
 
diff --git a/source/dnode/mnode/impl/inc/mndConsumer.h b/source/dnode/mnode/impl/inc/mndConsumer.h
index aa38b94fd7..96401511d2 100644
--- a/source/dnode/mnode/impl/inc/mndConsumer.h
+++ b/source/dnode/mnode/impl/inc/mndConsumer.h
@@ -23,13 +23,12 @@ extern "C" {
 #endif
 
 enum {
-  MQ_CONSUMER_STATUS__MODIFY = 1,
+  MQ_CONSUMER_STATUS_REBALANCE = 1,
 //  MQ_CONSUMER_STATUS__MODIFY_IN_REB,     // this value is not used anymore
   MQ_CONSUMER_STATUS__READY,
   MQ_CONSUMER_STATUS__LOST,
 //  MQ_CONSUMER_STATUS__LOST_IN_REB,       // this value is not used anymore
   MQ_CONSUMER_STATUS__LOST_REBD,
-  MQ_CONSUMER_STATUS__REMOVED,
 };
 
 int32_t mndInitConsumer(SMnode *pMnode);
diff --git a/source/dnode/mnode/impl/inc/mndDef.h b/source/dnode/mnode/impl/inc/mndDef.h
index fcd314d2ae..2579ff5231 100644
--- a/source/dnode/mnode/impl/inc/mndDef.h
+++ b/source/dnode/mnode/impl/inc/mndDef.h
@@ -142,7 +142,7 @@ typedef enum {
   CONSUMER_UPDATE__REMOVE,
   CONSUMER_UPDATE__LOST,
   CONSUMER_UPDATE__RECOVER,
-  CONSUMER_UPDATE__MODIFY,      // subscribe req need change consume topic
+  CONSUMER_UPDATE__REBALANCE,      // subscribe req need change consume topic
 } ECsmUpdateType;
 
 typedef struct {
diff --git a/source/dnode/mnode/impl/inc/mndVgroup.h b/source/dnode/mnode/impl/inc/mndVgroup.h
index 0229735952..94c4eae83f 100644
--- a/source/dnode/mnode/impl/inc/mndVgroup.h
+++ b/source/dnode/mnode/impl/inc/mndVgroup.h
@@ -50,6 +50,8 @@ void *mndBuildCreateVnodeReq(SMnode *, SDnodeObj *pDnode, SDbObj *pDb, SVgObj *p
 void *mndBuildDropVnodeReq(SMnode *, SDnodeObj *pDnode, SDbObj *pDb, SVgObj *pVgroup, int32_t *pContLen);
 bool  mndVgroupInDb(SVgObj *pVgroup, int64_t dbUid);
 
+int32_t mndSplitVgroup(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SVgObj *pVgroup);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/source/dnode/mnode/impl/src/mndConsumer.c b/source/dnode/mnode/impl/src/mndConsumer.c
index 65a2fa72a2..d144747e81 100644
--- a/source/dnode/mnode/impl/src/mndConsumer.c
+++ b/source/dnode/mnode/impl/src/mndConsumer.c
@@ -192,15 +192,18 @@ FAIL:
   return -1;
 }
 
+// todo check the clear process
 static int32_t mndProcessConsumerClearMsg(SRpcMsg *pMsg) {
   SMnode              *pMnode = pMsg->info.node;
   SMqConsumerClearMsg *pClearMsg = pMsg->pCont;
-  SMqConsumerObj      *pConsumer = mndAcquireConsumer(pMnode, pClearMsg->consumerId);
+
+  SMqConsumerObj *pConsumer = mndAcquireConsumer(pMnode, pClearMsg->consumerId);
   if (pConsumer == NULL) {
+    mError("consumer:0x%"PRIx64" failed to be found to clear it", pClearMsg->consumerId);
     return 0;
   }
 
-  mInfo("receive consumer clear msg, consumer id %" PRId64 ", status %s", pClearMsg->consumerId,
+  mInfo("consumer:0x%" PRIx64 " needs to be cleared, status %s", pClearMsg->consumerId,
         mndConsumerStatusName(pConsumer->status));
 
   if (pConsumer->status != MQ_CONSUMER_STATUS__LOST_REBD) {
@@ -215,6 +218,8 @@ static int32_t mndProcessConsumerClearMsg(SRpcMsg *pMsg) {
 
   STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pMsg, "clear-csm");
   if (pTrans == NULL) goto FAIL;
+
+  // this is the drop action, not the update action
   if (mndSetConsumerDropLogs(pMnode, pTrans, pConsumerNew) != 0) goto FAIL;
   if (mndTransPrepare(pMnode, pTrans) != 0) goto FAIL;
 
@@ -299,28 +304,36 @@ static int32_t mndProcessMqTimerMsg(SRpcMsg *pMsg) {
     if (status == MQ_CONSUMER_STATUS__READY) {
       if (hbStatus > MND_CONSUMER_LOST_HB_CNT) {
         SMqConsumerLostMsg *pLostMsg = rpcMallocCont(sizeof(SMqConsumerLostMsg));
+        if (pLostMsg == NULL) {
+          mError("consumer:0x%"PRIx64" failed to transfer consumer status to lost due to out of memory. alloc size:%d",
+              pConsumer->consumerId, (int32_t)sizeof(SMqConsumerLostMsg));
+          continue;
+        }
 
         pLostMsg->consumerId = pConsumer->consumerId;
         SRpcMsg rpcMsg = {
-            .msgType = TDMT_MND_TMQ_CONSUMER_LOST,
-            .pCont = pLostMsg,
-            .contLen = sizeof(SMqConsumerLostMsg),
-        };
+            .msgType = TDMT_MND_TMQ_CONSUMER_LOST, .pCont = pLostMsg, .contLen = sizeof(SMqConsumerLostMsg)};
 
+        mDebug("consumer:0x%"PRIx64" hb not received beyond threshold %d, set to lost", pConsumer->consumerId,
+            MND_CONSUMER_LOST_HB_CNT);
         tmsgPutToQueue(&pMnode->msgCb, WRITE_QUEUE, &rpcMsg);
       }
     } else if (status == MQ_CONSUMER_STATUS__LOST_REBD) {
       // if the client is lost longer than one day, clear it. Otherwise, do nothing about the lost consumers.
       if (hbStatus > MND_CONSUMER_LOST_CLEAR_THRESHOLD) {
         SMqConsumerClearMsg *pClearMsg = rpcMallocCont(sizeof(SMqConsumerClearMsg));
+        if (pClearMsg == NULL) {
+          mError("consumer:0x%"PRIx64" failed to clear consumer due to out of memory. alloc size:%d",
+                 pConsumer->consumerId, (int32_t)sizeof(SMqConsumerClearMsg));
+          continue;
+        }
 
         pClearMsg->consumerId = pConsumer->consumerId;
         SRpcMsg rpcMsg = {
-            .msgType = TDMT_MND_TMQ_LOST_CONSUMER_CLEAR,
-            .pCont = pClearMsg,
-            .contLen = sizeof(SMqConsumerClearMsg),
-        };
+            .msgType = TDMT_MND_TMQ_LOST_CONSUMER_CLEAR, .pCont = pClearMsg, .contLen = sizeof(SMqConsumerClearMsg)};
 
+        mDebug("consumer:0x%" PRIx64 " lost beyond threshold %d, clear it", pConsumer->consumerId,
+               MND_CONSUMER_LOST_CLEAR_THRESHOLD);
         tmsgPutToQueue(&pMnode->msgCb, WRITE_QUEUE, &rpcMsg);
       }
     } else if (status == MQ_CONSUMER_STATUS__LOST) {
@@ -334,7 +347,7 @@ static int32_t mndProcessMqTimerMsg(SRpcMsg *pMsg) {
         taosArrayPush(pRebSub->removedConsumers, &pConsumer->consumerId);
       }
       taosRUnLockLatch(&pConsumer->lock);
-    } else {
+    } else {  // MQ_CONSUMER_STATUS_REBALANCE
       taosRLockLatch(&pConsumer->lock);
 
       int32_t newTopicNum = taosArrayGetSize(pConsumer->rebNewTopics);
@@ -449,7 +462,6 @@ static int32_t mndProcessAskEpReq(SRpcMsg *pMsg) {
   // 1. check consumer status
   int32_t status = atomic_load_32(&pConsumer->status);
 
-#if 1
   if (status == MQ_CONSUMER_STATUS__LOST_REBD) {
     mInfo("try to recover consumer:0x%" PRIx64, consumerId);
     SMqConsumerRecoverMsg *pRecoverMsg = rpcMallocCont(sizeof(SMqConsumerRecoverMsg));
@@ -463,7 +475,6 @@ static int32_t mndProcessAskEpReq(SRpcMsg *pMsg) {
 
     tmsgPutToQueue(&pMnode->msgCb, WRITE_QUEUE, &pRpcMsg);
   }
-#endif
 
   if (status != MQ_CONSUMER_STATUS__READY) {
     mInfo("consumer:0x%" PRIx64 " not ready, status: %s", consumerId, mndConsumerStatusName(status));
@@ -660,7 +671,7 @@ int32_t mndProcessSubscribeReq(SRpcMsg *pMsg) {
     tstrncpy(pConsumerNew->clientId, subscribe.clientId, tListLen(pConsumerNew->clientId));
 
     // set the update type
-    pConsumerNew->updateType = CONSUMER_UPDATE__MODIFY;
+    pConsumerNew->updateType = CONSUMER_UPDATE__REBALANCE;
     taosArrayDestroy(pConsumerNew->assignedTopics);
     pConsumerNew->assignedTopics = taosArrayDup(pTopicList, topicNameDup);
 
@@ -673,7 +684,6 @@ int32_t mndProcessSubscribeReq(SRpcMsg *pMsg) {
     if (mndTransPrepare(pMnode, pTrans) != 0) goto _over;
 
   } else {
-    /*taosRLockLatch(&pExistedConsumer->lock);*/
     int32_t status = atomic_load_32(&pExistedConsumer->status);
 
     mInfo("receive subscribe request from existed consumer:0x%" PRIx64
@@ -691,7 +701,7 @@ int32_t mndProcessSubscribeReq(SRpcMsg *pMsg) {
     }
 
     // set the update type
-    pConsumerNew->updateType = CONSUMER_UPDATE__MODIFY;
+    pConsumerNew->updateType = CONSUMER_UPDATE__REBALANCE;
     taosArrayDestroy(pConsumerNew->assignedTopics);
     pConsumerNew->assignedTopics = taosArrayDup(pTopicList, topicNameDup);
 
@@ -870,9 +880,10 @@ static void updateConsumerStatus(SMqConsumerObj *pConsumer) {
   int32_t status = pConsumer->status;
 
   if (taosArrayGetSize(pConsumer->rebNewTopics) == 0 && taosArrayGetSize(pConsumer->rebRemovedTopics) == 0) {
-    if (status == MQ_CONSUMER_STATUS__MODIFY) {
+    if (status == MQ_CONSUMER_STATUS_REBALANCE) {
       pConsumer->status = MQ_CONSUMER_STATUS__READY;
     } else if (status == MQ_CONSUMER_STATUS__LOST) {
+      ASSERT(taosArrayGetSize(pConsumer->currentTopics) == 0);
       pConsumer->status = MQ_CONSUMER_STATUS__LOST_REBD;
     }
   }
@@ -881,7 +892,7 @@ static void updateConsumerStatus(SMqConsumerObj *pConsumer) {
 // remove from new topic
 static void removeFromNewTopicList(SMqConsumerObj *pConsumer, const char *pTopic) {
   int32_t size = taosArrayGetSize(pConsumer->rebNewTopics);
-  for (int32_t i = 0; i < taosArrayGetSize(pConsumer->rebNewTopics); i++) {
+  for (int32_t i = 0; i < size; i++) {
     char *p = taosArrayGetP(pConsumer->rebNewTopics, i);
     if (strcmp(pTopic, p) == 0) {
       taosArrayRemove(pConsumer->rebNewTopics, i);
@@ -902,32 +913,57 @@ static void removeFromRemoveTopicList(SMqConsumerObj *pConsumer, const char *pTo
     if (strcmp(pTopic, p) == 0) {
       taosArrayRemove(pConsumer->rebRemovedTopics, i);
       taosMemoryFree(p);
+
+      mDebug("consumer:0x%" PRIx64 " remove topic:%s in the removed topic list, remain removedTopics:%d",
+             pConsumer->consumerId, pTopic, (int)taosArrayGetSize(pConsumer->rebRemovedTopics));
       break;
     }
   }
 }
 
+static void removeFromCurrentTopicList(SMqConsumerObj *pConsumer, const char *pTopic) {
+  int32_t sz = taosArrayGetSize(pConsumer->currentTopics);
+  for (int32_t i = 0; i < sz; i++) {
+    char *topic = taosArrayGetP(pConsumer->currentTopics, i);
+    if (strcmp(pTopic, topic) == 0) {
+      taosArrayRemove(pConsumer->currentTopics, i);
+      taosMemoryFree(topic);
+
+      mDebug("consumer:0x%" PRIx64 " remove topic:%s in the current topic list, remain currentTopics:%d",
+             pConsumer->consumerId, pTopic, (int)taosArrayGetSize(pConsumer->currentTopics));
+      break;
+    }
+  }
+}
+
+static bool existInCurrentTopicList(const SMqConsumerObj* pConsumer, const char* pTopic) {
+  bool    existing = false;
+  int32_t size = taosArrayGetSize(pConsumer->currentTopics);
+  for (int32_t i = 0; i < size; i++) {
+    char *topic = taosArrayGetP(pConsumer->currentTopics, i);
+
+    if (strcmp(topic, pTopic) == 0) {
+      existing = true;
+      break;
+    }
+  }
+
+  return existing;
+}
+
 static int32_t mndConsumerActionUpdate(SSdb *pSdb, SMqConsumerObj *pOldConsumer, SMqConsumerObj *pNewConsumer) {
   mDebug("consumer:0x%" PRIx64 " perform update action, update type:%d, subscribe-time:%" PRId64 ", uptime:%" PRId64,
          pOldConsumer->consumerId, pNewConsumer->updateType, pOldConsumer->subscribeTime, pOldConsumer->upTime);
 
   taosWLockLatch(&pOldConsumer->lock);
 
-  if (pNewConsumer->updateType == CONSUMER_UPDATE__MODIFY) {
-    SArray *tmp = pOldConsumer->rebNewTopics;
-    pOldConsumer->rebNewTopics = pNewConsumer->rebNewTopics;
-    pNewConsumer->rebNewTopics = tmp;
-
-    tmp = pOldConsumer->rebRemovedTopics;
-    pOldConsumer->rebRemovedTopics = pNewConsumer->rebRemovedTopics;
-    pNewConsumer->rebRemovedTopics = tmp;
-
-    tmp = pOldConsumer->assignedTopics;
-    pOldConsumer->assignedTopics = pNewConsumer->assignedTopics;
-    pNewConsumer->assignedTopics = tmp;
+  if (pNewConsumer->updateType == CONSUMER_UPDATE__REBALANCE) {
+    TSWAP(pOldConsumer->rebNewTopics, pNewConsumer->rebNewTopics);
+    TSWAP(pOldConsumer->rebRemovedTopics, pNewConsumer->rebRemovedTopics);
+    TSWAP(pOldConsumer->assignedTopics, pNewConsumer->assignedTopics);
 
     pOldConsumer->subscribeTime = pNewConsumer->upTime;
-    pOldConsumer->status = MQ_CONSUMER_STATUS__MODIFY;
+    pOldConsumer->status = MQ_CONSUMER_STATUS_REBALANCE;
   } else if (pNewConsumer->updateType == CONSUMER_UPDATE__LOST) {
     int32_t sz = taosArrayGetSize(pOldConsumer->currentTopics);
     for (int32_t i = 0; i < sz; i++) {
@@ -937,10 +973,10 @@ static int32_t mndConsumerActionUpdate(SSdb *pSdb, SMqConsumerObj *pOldConsumer,
 
     pOldConsumer->rebalanceTime = pNewConsumer->upTime;
 
-    int32_t status = pOldConsumer->status;
+    int32_t prevStatus = pOldConsumer->status;
     pOldConsumer->status = MQ_CONSUMER_STATUS__LOST;
     mDebug("consumer:0x%" PRIx64 " state %s -> %s, reb-time:%" PRId64 ", reb-removed-topics:%d",
-           pOldConsumer->consumerId, mndConsumerStatusName(status), mndConsumerStatusName(pOldConsumer->status),
+           pOldConsumer->consumerId, mndConsumerStatusName(prevStatus), mndConsumerStatusName(pOldConsumer->status),
            pOldConsumer->rebalanceTime, (int)taosArrayGetSize(pOldConsumer->rebRemovedTopics));
   } else if (pNewConsumer->updateType == CONSUMER_UPDATE__RECOVER) {
     int32_t sz = taosArrayGetSize(pOldConsumer->assignedTopics);
@@ -950,8 +986,7 @@ static int32_t mndConsumerActionUpdate(SSdb *pSdb, SMqConsumerObj *pOldConsumer,
     }
 
     pOldConsumer->rebalanceTime = pNewConsumer->upTime;
-
-    pOldConsumer->status = MQ_CONSUMER_STATUS__MODIFY;
+    pOldConsumer->status = MQ_CONSUMER_STATUS_REBALANCE;
   } else if (pNewConsumer->updateType == CONSUMER_UPDATE__TOUCH) {
     atomic_add_fetch_32(&pOldConsumer->epoch, 1);
 
@@ -960,24 +995,16 @@ static int32_t mndConsumerActionUpdate(SSdb *pSdb, SMqConsumerObj *pOldConsumer,
   } else if (pNewConsumer->updateType == CONSUMER_UPDATE__ADD) {
     char *pNewTopic = taosStrdup(taosArrayGetP(pNewConsumer->rebNewTopics, 0));
 
-    // not exist in current topic
-    bool    existing = false;
-    int32_t numOfExistedTopics = taosArrayGetSize(pOldConsumer->currentTopics);
-    for (int32_t i = 0; i < numOfExistedTopics; i++) {
-      char *topic = taosArrayGetP(pOldConsumer->currentTopics, i);
-      if (strcmp(topic, pNewTopic) == 0) {
-        existing = true;
-      }
-    }
-
+    // check if exist in current topic
     removeFromNewTopicList(pOldConsumer, pNewTopic);
 
     // add to current topic
-    if (!existing) {
+    bool existing = existInCurrentTopicList(pOldConsumer, pNewTopic);
+    if (existing) {
+      taosMemoryFree(pNewTopic);
+    } else {  // added into current topic list
       taosArrayPush(pOldConsumer->currentTopics, &pNewTopic);
       taosArraySort(pOldConsumer->currentTopics, taosArrayCompareString);
-    } else {
-      taosMemoryFree(pNewTopic);
     }
 
     // set status
@@ -1002,16 +1029,7 @@ static int32_t mndConsumerActionUpdate(SSdb *pSdb, SMqConsumerObj *pOldConsumer,
     removeFromRemoveTopicList(pOldConsumer, removedTopic);
 
     // remove from current topic
-    int32_t i = 0;
-    int32_t sz = taosArrayGetSize(pOldConsumer->currentTopics);
-    for (i = 0; i < sz; i++) {
-      char *topic = taosArrayGetP(pOldConsumer->currentTopics, i);
-      if (strcmp(removedTopic, topic) == 0) {
-        taosArrayRemove(pOldConsumer->currentTopics, i);
-        taosMemoryFree(topic);
-        break;
-      }
-    }
+    removeFromCurrentTopicList(pOldConsumer, removedTopic);
 
     // set status
     int32_t status = pOldConsumer->status;
@@ -1160,7 +1178,7 @@ static const char *mndConsumerStatusName(int status) {
     case MQ_CONSUMER_STATUS__LOST:
     case MQ_CONSUMER_STATUS__LOST_REBD:
       return "lost";
-    case MQ_CONSUMER_STATUS__MODIFY:
+    case MQ_CONSUMER_STATUS_REBALANCE:
       return "rebalancing";
     default:
       return "unknown";
diff --git a/source/dnode/mnode/impl/src/mndDb.c b/source/dnode/mnode/impl/src/mndDb.c
index da617bb0ab..e93b06fdea 100644
--- a/source/dnode/mnode/impl/src/mndDb.c
+++ b/source/dnode/mnode/impl/src/mndDb.c
@@ -373,6 +373,8 @@ static int32_t mndCheckDbCfg(SMnode *pMnode, SDbCfg *pCfg) {
   if (pCfg->sstTrigger < TSDB_MIN_STT_TRIGGER || pCfg->sstTrigger > TSDB_MAX_STT_TRIGGER) return -1;
   if (pCfg->hashPrefix < TSDB_MIN_HASH_PREFIX || pCfg->hashPrefix > TSDB_MAX_HASH_PREFIX) return -1;
   if (pCfg->hashSuffix < TSDB_MIN_HASH_SUFFIX || pCfg->hashSuffix > TSDB_MAX_HASH_SUFFIX) return -1;
+  if ((pCfg->hashSuffix * pCfg->hashPrefix) < 0) return -1;
+  if ((pCfg->hashPrefix + pCfg->hashSuffix) >= (TSDB_TABLE_NAME_LEN - 1)) return -1;
   if (pCfg->tsdbPageSize < TSDB_MIN_TSDB_PAGESIZE || pCfg->tsdbPageSize > TSDB_MAX_TSDB_PAGESIZE) return -1;
   if (taosArrayGetSize(pCfg->pRetensions) != pCfg->numOfRetensions) return -1;
 
@@ -409,8 +411,6 @@ static void mndSetDefaultDbCfg(SDbCfg *pCfg) {
   if (pCfg->walRollPeriod < 0) pCfg->walRollPeriod = TSDB_REPS_DEF_DB_WAL_ROLL_PERIOD;
   if (pCfg->walSegmentSize < 0) pCfg->walSegmentSize = TSDB_DEFAULT_DB_WAL_SEGMENT_SIZE;
   if (pCfg->sstTrigger <= 0) pCfg->sstTrigger = TSDB_DEFAULT_SST_TRIGGER;
-  if (pCfg->hashPrefix < 0) pCfg->hashPrefix = TSDB_DEFAULT_HASH_PREFIX;
-  if (pCfg->hashSuffix < 0) pCfg->hashSuffix = TSDB_DEFAULT_HASH_SUFFIX;
   if (pCfg->tsdbPageSize <= 0) pCfg->tsdbPageSize = TSDB_DEFAULT_TSDB_PAGESIZE;
 }
 
@@ -553,6 +553,10 @@ static int32_t mndCreateDb(SMnode *pMnode, SRpcMsg *pReq, SCreateDbReq *pCreate,
     int32_t dbLen = strlen(dbObj.name) + 1;
     mInfo("db:%s, hashPrefix adjust from %d to %d", dbObj.name, dbObj.cfg.hashPrefix, dbObj.cfg.hashPrefix + dbLen);
     dbObj.cfg.hashPrefix += dbLen;
+  } else if (dbObj.cfg.hashPrefix < 0) {
+    int32_t dbLen = strlen(dbObj.name) + 1;
+    mInfo("db:%s, hashPrefix adjust from %d to %d", dbObj.name, dbObj.cfg.hashPrefix, dbObj.cfg.hashPrefix - dbLen);
+    dbObj.cfg.hashPrefix -= dbLen;
   }
 
   SVgObj *pVgroups = NULL;
@@ -1814,6 +1818,8 @@ static void mndDumpDbInfoData(SMnode *pMnode, SSDataBlock *pBlock, SDbObj *pDb,
     int16_t hashPrefix = pDb->cfg.hashPrefix;
     if (hashPrefix > 0) {
       hashPrefix = pDb->cfg.hashPrefix - strlen(pDb->name) - 1;
+    } else if (hashPrefix < 0) {
+      hashPrefix = pDb->cfg.hashPrefix + strlen(pDb->name) + 1;
     }
     colDataSetVal(pColInfo, rows, (const char *)&hashPrefix, false);
 
diff --git a/source/dnode/mnode/impl/src/mndDef.c b/source/dnode/mnode/impl/src/mndDef.c
index c69f08eb6b..6dab018236 100644
--- a/source/dnode/mnode/impl/src/mndDef.c
+++ b/source/dnode/mnode/impl/src/mndDef.c
@@ -225,7 +225,7 @@ SMqConsumerObj *tNewSMqConsumerObj(int64_t consumerId, char cgroup[TSDB_CGROUP_L
   memcpy(pConsumer->cgroup, cgroup, TSDB_CGROUP_LEN);
 
   pConsumer->epoch = 0;
-  pConsumer->status = MQ_CONSUMER_STATUS__MODIFY;
+  pConsumer->status = MQ_CONSUMER_STATUS_REBALANCE;
   pConsumer->hbStatus = 0;
 
   taosInitRWLatch(&pConsumer->lock);
diff --git a/source/dnode/mnode/impl/src/mndMain.c b/source/dnode/mnode/impl/src/mndMain.c
index 5c20887cf5..92ff550895 100644
--- a/source/dnode/mnode/impl/src/mndMain.c
+++ b/source/dnode/mnode/impl/src/mndMain.c
@@ -124,11 +124,7 @@ static void mndCalMqRebalance(SMnode *pMnode) {
   int32_t contLen = 0;
   void   *pReq = mndBuildTimerMsg(&contLen);
   if (pReq != NULL) {
-    SRpcMsg rpcMsg = {
-        .msgType = TDMT_MND_TMQ_TIMER,
-        .pCont = pReq,
-        .contLen = contLen,
-    };
+    SRpcMsg rpcMsg = { .msgType = TDMT_MND_TMQ_TIMER, .pCont = pReq, .contLen = contLen };
     tmsgPutToQueue(&pMnode->msgCb, READ_QUEUE, &rpcMsg);
   }
 }
diff --git a/source/dnode/mnode/impl/src/mndProfile.c b/source/dnode/mnode/impl/src/mndProfile.c
index ec013681bb..fbd845d448 100644
--- a/source/dnode/mnode/impl/src/mndProfile.c
+++ b/source/dnode/mnode/impl/src/mndProfile.c
@@ -256,10 +256,13 @@ static int32_t mndProcessConnectReq(SRpcMsg *pReq) {
     snprintf(db, TSDB_DB_FNAME_LEN, "%d%s%s", pUser->acctId, TS_PATH_DELIMITER, connReq.db);
     pDb = mndAcquireDb(pMnode, db);
     if (pDb == NULL) {
-      terrno = TSDB_CODE_MND_INVALID_DB;
-      mGError("user:%s, failed to login from %s while use db:%s since %s", pReq->info.conn.user, ip, connReq.db,
-              terrstr());
-      goto _OVER;
+      if (0 != strcmp(connReq.db, TSDB_INFORMATION_SCHEMA_DB) &&
+          (0 != strcmp(connReq.db, TSDB_PERFORMANCE_SCHEMA_DB))) {
+        terrno = TSDB_CODE_MND_INVALID_DB;
+        mGError("user:%s, failed to login from %s while use db:%s since %s", pReq->info.conn.user, ip, connReq.db,
+                terrstr());
+        goto _OVER;
+      }
     }
 
     if (mndCheckDbPrivilege(pMnode, pReq->info.conn.user, MND_OPER_READ_OR_WRITE_DB, pDb) != 0) {
diff --git a/source/dnode/mnode/impl/src/mndStb.c b/source/dnode/mnode/impl/src/mndStb.c
index 63bcef2a5b..8b708c3e0f 100644
--- a/source/dnode/mnode/impl/src/mndStb.c
+++ b/source/dnode/mnode/impl/src/mndStb.c
@@ -797,6 +797,11 @@ int32_t mndBuildStbFromReq(SMnode *pMnode, SStbObj *pDst, SMCreateStbReq *pCreat
     return -1;
   }
 
+  if(pDst->nextColId < 0 || pDst->nextColId >= 0x7fff - pDst->numOfColumns - pDst->numOfTags){
+    terrno = TSDB_CODE_MND_FIELD_VALUE_OVERFLOW;
+    return -1;
+  }
+
   for (int32_t i = 0; i < pDst->numOfColumns; ++i) {
     SField  *pField = taosArrayGet(pCreate->pColumns, i);
     SSchema *pSchema = &pDst->pColumns[i];
@@ -927,6 +932,11 @@ static int32_t mndBuildStbFromAlter(SStbObj *pStb, SStbObj *pDst, SMCreateStbReq
     return -1;
   }
 
+  if(pDst->nextColId < 0 || pDst->nextColId >= 0x7fff - pDst->numOfColumns - pDst->numOfTags){
+    terrno = TSDB_CODE_MND_FIELD_VALUE_OVERFLOW;
+    return -1;
+  }
+
   for (int32_t i = 0; i < pDst->numOfColumns; ++i) {
     SField  *pField = taosArrayGet(createReq->pColumns, i);
     SSchema *pSchema = &pDst->pColumns[i];
@@ -1153,6 +1163,11 @@ static int32_t mndAddSuperTableTag(const SStbObj *pOld, SStbObj *pNew, SArray *p
   if (mndAllocStbSchemas(pOld, pNew) != 0) {
     return -1;
   }
+ 
+  if(pNew->nextColId < 0 || pNew->nextColId >= 0x7fff - ntags){
+    terrno = TSDB_CODE_MND_FIELD_VALUE_OVERFLOW;
+    return -1;
+  }
 
   for (int32_t i = 0; i < ntags; i++) {
     SField *pField = taosArrayGet(pFields, i);
@@ -1461,6 +1476,11 @@ static int32_t mndAddSuperTableColumn(const SStbObj *pOld, SStbObj *pNew, SArray
     return -1;
   }
 
+  if(pNew->nextColId < 0 || pNew->nextColId >= 0x7fff - ncols){
+    terrno = TSDB_CODE_MND_FIELD_VALUE_OVERFLOW;
+    return -1;
+  }
+
   for (int32_t i = 0; i < ncols; i++) {
     SField *pField = taosArrayGet(pFields, i);
     if (mndFindSuperTableColumnIndex(pOld, pField->name) >= 0) {
@@ -2524,6 +2544,9 @@ int32_t mndValidateStbInfo(SMnode *pMnode, SSTableVersion *pStbVersions, int32_t
     if (mndBuildStbSchema(pMnode, pStbVersion->dbFName, pStbVersion->stbName, &metaRsp, &smaVer) != 0) {
       metaRsp.numOfColumns = -1;
       metaRsp.suid = pStbVersion->suid;
+      tstrncpy(metaRsp.dbFName, pStbVersion->dbFName, sizeof(metaRsp.dbFName));
+      tstrncpy(metaRsp.tbName, pStbVersion->stbName, sizeof(metaRsp.tbName));
+      tstrncpy(metaRsp.stbName, pStbVersion->stbName, sizeof(metaRsp.stbName));
       taosArrayPush(hbRsp.pMetaRsp, &metaRsp);
       continue;
     }
diff --git a/source/dnode/mnode/impl/src/mndSubscribe.c b/source/dnode/mnode/impl/src/mndSubscribe.c
index 015c497de1..e62102fa77 100644
--- a/source/dnode/mnode/impl/src/mndSubscribe.c
+++ b/source/dnode/mnode/impl/src/mndSubscribe.c
@@ -133,10 +133,10 @@ static int32_t mndBuildSubChangeReq(void **pBuf, int32_t *pLen, const SMqSubscri
 
 static int32_t mndPersistSubChangeVgReq(SMnode *pMnode, STrans *pTrans, const SMqSubscribeObj *pSub,
                                         const SMqRebOutputVg *pRebVg) {
-  if (pRebVg->oldConsumerId == pRebVg->newConsumerId) {
-    terrno = TSDB_CODE_MND_INVALID_SUB_OPTION;
-    return -1;
-  }
+//  if (pRebVg->oldConsumerId == pRebVg->newConsumerId) {
+//    terrno = TSDB_CODE_MND_INVALID_SUB_OPTION;
+//    return -1;
+//  }
 
   void   *buf;
   int32_t tlen;
@@ -197,7 +197,7 @@ static SMqRebInfo *mndGetOrCreateRebSub(SHashObj *pHash, const char *key) {
   return pRebSub;
 }
 
-static void doRemoveExistedConsumers(SMqRebOutputObj *pOutput, SHashObj *pHash, const SMqRebInputObj *pInput) {
+static void doRemoveLostConsumers(SMqRebOutputObj *pOutput, SHashObj *pHash, const SMqRebInputObj *pInput) {
   int32_t     numOfRemoved = taosArrayGetSize(pInput->pRebInfo->removedConsumers);
   const char *pSubKey = pOutput->pSub->key;
 
@@ -213,13 +213,9 @@ static void doRemoveExistedConsumers(SMqRebOutputObj *pOutput, SHashObj *pHash,
 
       int32_t consumerVgNum = taosArrayGetSize(pConsumerEp->vgs);
       for (int32_t j = 0; j < consumerVgNum; j++) {
-        SMqVgEp       *pVgEp = taosArrayGetP(pConsumerEp->vgs, j);
-        SMqRebOutputVg outputVg = {
-            .oldConsumerId = consumerId,
-            .newConsumerId = -1,
-            .pVgEp = pVgEp,
-        };
+        SMqVgEp *pVgEp = taosArrayGetP(pConsumerEp->vgs, j);
 
+        SMqRebOutputVg outputVg = {.oldConsumerId = consumerId, .newConsumerId = -1, .pVgEp = pVgEp};
         taosHashPut(pHash, &pVgEp->vgId, sizeof(int32_t), &outputVg, sizeof(SMqRebOutputVg));
         mInfo("sub:%s mq re-balance remove vgId:%d from consumer:%" PRIx64, pSubKey, pVgEp->vgId, consumerId);
       }
@@ -273,6 +269,18 @@ static void addUnassignedVgroups(SMqRebOutputObj *pOutput, SHashObj *pHash) {
   }
 }
 
+static void putNoTransferToOutput(SMqRebOutputObj *pOutput, SMqConsumerEp *pConsumerEp){
+  for(int i = 0; i < taosArrayGetSize(pConsumerEp->vgs); i++){
+    SMqVgEp       *pVgEp = (SMqVgEp *)taosArrayGetP(pConsumerEp->vgs, i);
+    SMqRebOutputVg outputVg = {
+        .oldConsumerId = pConsumerEp->consumerId,
+        .newConsumerId = pConsumerEp->consumerId,
+        .pVgEp = pVgEp,
+    };
+    taosArrayPush(pOutput->rebVgs, &outputVg);
+  }
+}
+
 static void transferVgroupsForConsumers(SMqRebOutputObj *pOutput, SHashObj *pHash, int32_t minVgCnt,
                                         int32_t imbConsumerNum) {
   const char *pSubKey = pOutput->pSub->key;
@@ -294,24 +302,19 @@ static void transferVgroupsForConsumers(SMqRebOutputObj *pOutput, SHashObj *pHas
     taosArrayPush(pOutput->modifyConsumers, &pConsumerEp->consumerId);
     if (consumerVgNum > minVgCnt) {
       if (imbCnt < imbConsumerNum) {
-        if (consumerVgNum == minVgCnt + 1) {
-          imbCnt++;
-          continue;
-        } else {
-          // pop until equal minVg + 1
-          while (taosArrayGetSize(pConsumerEp->vgs) > minVgCnt + 1) {
-            SMqVgEp       *pVgEp = *(SMqVgEp **)taosArrayPop(pConsumerEp->vgs);
-            SMqRebOutputVg outputVg = {
-                .oldConsumerId = pConsumerEp->consumerId,
-                .newConsumerId = -1,
-                .pVgEp = pVgEp,
-            };
-            taosHashPut(pHash, &pVgEp->vgId, sizeof(int32_t), &outputVg, sizeof(SMqRebOutputVg));
-            mInfo("sub:%s mq rebalance remove vgId:%d from consumer:0x%" PRIx64 ",(first scan)", pSubKey, pVgEp->vgId,
-                  pConsumerEp->consumerId);
-          }
-          imbCnt++;
+        // pop until equal minVg + 1
+        while (taosArrayGetSize(pConsumerEp->vgs) > minVgCnt + 1) {
+          SMqVgEp       *pVgEp = *(SMqVgEp **)taosArrayPop(pConsumerEp->vgs);
+          SMqRebOutputVg outputVg = {
+              .oldConsumerId = pConsumerEp->consumerId,
+              .newConsumerId = -1,
+              .pVgEp = pVgEp,
+          };
+          taosHashPut(pHash, &pVgEp->vgId, sizeof(int32_t), &outputVg, sizeof(SMqRebOutputVg));
+          mInfo("sub:%s mq rebalance remove vgId:%d from consumer:0x%" PRIx64 ",(first scan)", pSubKey, pVgEp->vgId,
+                pConsumerEp->consumerId);
         }
+        imbCnt++;
       } else {
         // all the remain consumers should only have the number of vgroups, which is equalled to the value of minVg
         while (taosArrayGetSize(pConsumerEp->vgs) > minVgCnt) {
@@ -327,6 +330,7 @@ static void transferVgroupsForConsumers(SMqRebOutputObj *pOutput, SHashObj *pHas
         }
       }
     }
+    putNoTransferToOutput(pOutput, pConsumerEp);
   }
 }
 
@@ -343,7 +347,7 @@ static int32_t mndDoRebalance(SMnode *pMnode, const SMqRebInputObj *pInput, SMqR
   SHashObj *pHash = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_NO_LOCK);
 
   // 2. check and get actual removed consumers, put their vg into pHash
-  doRemoveExistedConsumers(pOutput, pHash, pInput);
+  doRemoveLostConsumers(pOutput, pHash, pInput);
 
   // 3. if previously no consumer, there are vgs not assigned, put these vg into pHash
   addUnassignedVgroups(pOutput, pHash);
@@ -484,14 +488,16 @@ static int32_t mndPersistRebResult(SMnode *pMnode, SRpcMsg *pMsg, const SMqRebOu
   for (int32_t i = 0; i < vgNum; i++) {
     SMqRebOutputVg *pRebVg = taosArrayGet(rebVgs, i);
     if (mndPersistSubChangeVgReq(pMnode, pTrans, pOutput->pSub, pRebVg) < 0) {
-      goto REB_FAIL;
+      mndTransDrop(pTrans);
+      return -1;
     }
   }
 
   // 2. redo log: subscribe and vg assignment
   // subscribe
   if (mndSetSubCommitLogs(pMnode, pTrans, pOutput->pSub) != 0) {
-    goto REB_FAIL;
+    mndTransDrop(pTrans);
+    return -1;
   }
 
   // 3. commit log: consumer to update status and epoch
@@ -506,11 +512,15 @@ static int32_t mndPersistRebResult(SMnode *pMnode, SRpcMsg *pMsg, const SMqRebOu
     if (mndSetConsumerCommitLogs(pMnode, pTrans, pConsumerNew) != 0) {
       tDeleteSMqConsumerObj(pConsumerNew);
       taosMemoryFree(pConsumerNew);
-      goto REB_FAIL;
+
+      mndTransDrop(pTrans);
+      return -1;
     }
+
     tDeleteSMqConsumerObj(pConsumerNew);
     taosMemoryFree(pConsumerNew);
   }
+
   // 3.2 set new consumer
   consumerNum = taosArrayGetSize(pOutput->newConsumers);
   for (int32_t i = 0; i < consumerNum; i++) {
@@ -527,8 +537,11 @@ static int32_t mndPersistRebResult(SMnode *pMnode, SRpcMsg *pMsg, const SMqRebOu
     if (mndSetConsumerCommitLogs(pMnode, pTrans, pConsumerNew) != 0) {
       tDeleteSMqConsumerObj(pConsumerNew);
       taosMemoryFree(pConsumerNew);
-      goto REB_FAIL;
+
+      mndTransDrop(pTrans);
+      return -1;
     }
+
     tDeleteSMqConsumerObj(pConsumerNew);
     taosMemoryFree(pConsumerNew);
   }
@@ -549,8 +562,11 @@ static int32_t mndPersistRebResult(SMnode *pMnode, SRpcMsg *pMsg, const SMqRebOu
     if (mndSetConsumerCommitLogs(pMnode, pTrans, pConsumerNew) != 0) {
       tDeleteSMqConsumerObj(pConsumerNew);
       taosMemoryFree(pConsumerNew);
-      goto REB_FAIL;
+
+      mndTransDrop(pTrans);
+      return -1;
     }
+
     tDeleteSMqConsumerObj(pConsumerNew);
     taosMemoryFree(pConsumerNew);
   }
@@ -563,15 +579,12 @@ static int32_t mndPersistRebResult(SMnode *pMnode, SRpcMsg *pMsg, const SMqRebOu
   // 6. execution
   if (mndTransPrepare(pMnode, pTrans) != 0) {
     mError("failed to prepare trans rebalance since %s", terrstr());
-    goto REB_FAIL;
+    mndTransDrop(pTrans);
+    return -1;
   }
 
   mndTransDrop(pTrans);
   return 0;
-
-REB_FAIL:
-  mndTransDrop(pTrans);
-  return -1;
 }
 
 static int32_t mndProcessRebalanceReq(SRpcMsg *pMsg) {
@@ -584,16 +597,11 @@ static int32_t mndProcessRebalanceReq(SRpcMsg *pMsg) {
 
   // here we only handle one topic rebalance requirement to ensure the atomic execution of this transaction.
   while (1) {
-//    if (rebalanceOnce) {
-//      break;
-//    }
-
     pIter = taosHashIterate(pReq->rebSubHash, pIter);
     if (pIter == NULL) {
       break;
     }
 
-    // todo handle the malloc failure
     SMqRebInputObj  rebInput = {0};
     SMqRebOutputObj rebOutput = {0};
     rebOutput.newConsumers = taosArrayInit(0, sizeof(int64_t));
@@ -601,6 +609,20 @@ static int32_t mndProcessRebalanceReq(SRpcMsg *pMsg) {
     rebOutput.modifyConsumers = taosArrayInit(0, sizeof(int64_t));
     rebOutput.rebVgs = taosArrayInit(0, sizeof(SMqRebOutputVg));
 
+    if (rebOutput.newConsumers == NULL || rebOutput.removedConsumers == NULL || rebOutput.modifyConsumers == NULL ||
+        rebOutput.rebVgs == NULL) {
+      taosArrayDestroy(rebOutput.newConsumers);
+      taosArrayDestroy(rebOutput.removedConsumers);
+      taosArrayDestroy(rebOutput.modifyConsumers);
+      taosArrayDestroy(rebOutput.rebVgs);
+
+      terrno = TSDB_CODE_OUT_OF_MEMORY;
+      mInfo("mq re-balance failed, due to out of memory");
+      taosHashCleanup(pReq->rebSubHash);
+      mndRebEnd();
+      return -1;
+    }
+
     SMqRebInfo      *pRebInfo = (SMqRebInfo *)pIter;
     SMqSubscribeObj *pSub = mndAcquireSubscribeByKey(pMnode, pRebInfo->key);
 
@@ -640,6 +662,7 @@ static int32_t mndProcessRebalanceReq(SRpcMsg *pMsg) {
       rebInput.oldConsumerNum = taosHashGetSize(pSub->consumerHash);
       rebOutput.pSub = tCloneSubscribeObj(pSub);
       taosRUnLockLatch(&pSub->lock);
+
       mInfo("sub topic:%s has %d consumers sub till now", pRebInfo->key, rebInput.oldConsumerNum);
       mndReleaseSubscribe(pMnode, pSub);
     }
@@ -661,9 +684,6 @@ static int32_t mndProcessRebalanceReq(SRpcMsg *pMsg) {
     taosArrayDestroy(rebOutput.rebVgs);
     tDeleteSubscribeObj(rebOutput.pSub);
     taosMemoryFree(rebOutput.pSub);
-
-//    taosSsleep(100);
-//    rebalanceOnce = true;
   }
 
   // reset flag
diff --git a/source/dnode/mnode/impl/src/mndUser.c b/source/dnode/mnode/impl/src/mndUser.c
index d08227927a..2a0d753722 100644
--- a/source/dnode/mnode/impl/src/mndUser.c
+++ b/source/dnode/mnode/impl/src/mndUser.c
@@ -236,7 +236,7 @@ SSdbRaw *mndUserActionEncode(SUserObj *pUser) {
     SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
 
     SDB_SET_INT32(pRaw, dataPos, *useDb, _OVER)
-    useDb = taosHashIterate(pUser->writeTbs, useDb);
+    useDb = taosHashIterate(pUser->useDbs, useDb);
   }
 
   SDB_SET_RESERVE(pRaw, dataPos, USER_RESERVE_SIZE, _OVER)
@@ -390,6 +390,7 @@ static SSdbRow *mndUserActionDecode(SSdbRaw *pRaw) {
       SDB_GET_INT32(pRaw, dataPos, &ref, _OVER);
 
       taosHashPut(pUser->useDbs, key, keyLen, &ref, sizeof(ref));
+      taosMemoryFree(key);
     }
   }
 
@@ -956,6 +957,7 @@ _OVER:
     mError("user:%s, failed to alter since %s", alterReq.user, terrstr());
   }
 
+  tFreeSAlterUserReq(&alterReq);
   mndReleaseUser(pMnode, pOperUser);
   mndReleaseUser(pMnode, pUser);
   mndUserFreeObj(&newUser);
diff --git a/source/dnode/mnode/impl/src/mndVgroup.c b/source/dnode/mnode/impl/src/mndVgroup.c
index ed1fddb63f..0003d07fd6 100644
--- a/source/dnode/mnode/impl/src/mndVgroup.c
+++ b/source/dnode/mnode/impl/src/mndVgroup.c
@@ -2006,7 +2006,7 @@ static int32_t mndAddAdjustVnodeHashRangeAction(SMnode *pMnode, STrans *pTrans,
   return 0;
 }
 
-static int32_t mndSplitVgroup(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SVgObj *pVgroup) {
+int32_t mndSplitVgroup(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SVgObj *pVgroup) {
   int32_t  code = -1;
   STrans  *pTrans = NULL;
   SSdbRaw *pRaw = NULL;
diff --git a/source/dnode/snode/src/snode.c b/source/dnode/snode/src/snode.c
index cefc4fa63e..7352bbc0fe 100644
--- a/source/dnode/snode/src/snode.c
+++ b/source/dnode/snode/src/snode.c
@@ -153,11 +153,15 @@ int32_t sndProcessTaskDeployReq(SSnode *pSnode, char *msg, int32_t msgLen) {
   ASSERT(pTask->taskLevel == TASK_LEVEL__AGG);
 
   // 2.save task
+  taosWLockLatch(&pSnode->pMeta->lock);
   code = streamMetaAddDeployedTask(pSnode->pMeta, -1, pTask);
   if (code < 0) {
+    taosWUnLockLatch(&pSnode->pMeta->lock);
     return -1;
   }
 
+  taosWUnLockLatch(&pSnode->pMeta->lock);
+
   // 3.go through recover steps to fill history
   if (pTask->fillHistory) {
     streamSetParamForRecover(pTask);
diff --git a/source/dnode/vnode/inc/vnode.h b/source/dnode/vnode/inc/vnode.h
index a8b2a74019..542d584a24 100644
--- a/source/dnode/vnode/inc/vnode.h
+++ b/source/dnode/vnode/inc/vnode.h
@@ -167,7 +167,6 @@ int32_t     metaTbCursorPrev(SMTbCursor *pTbCur, ETableType jumpTableType);
 #endif
 
 // tsdb
-// typedef struct STsdb STsdb;
 typedef struct STsdbReader STsdbReader;
 
 #define TSDB_DEFAULT_STT_FILE  8
@@ -181,11 +180,8 @@ typedef struct STsdbReader STsdbReader;
 #define CACHESCAN_RETRIEVE_LAST_ROW    0x4
 #define CACHESCAN_RETRIEVE_LAST        0x8
 
-int32_t tsdbSetTableList(STsdbReader *pReader, const void *pTableList, int32_t num);
-int32_t tsdbReaderOpen(SVnode *pVnode, SQueryTableDataCond *pCond, void *pTableList, int32_t numOfTables,
-                       SSDataBlock *pResBlock, STsdbReader **ppReader, const char *idstr, bool countOnly, SHashObj** pIgnoreTables);
-
-void         tsdbReaderSetId(STsdbReader* pReader, const char* idstr);
+int32_t      tsdbReaderOpen(SVnode *pVnode, SQueryTableDataCond *pCond, void *pTableList, int32_t numOfTables,
+                            SSDataBlock *pResBlock, STsdbReader **ppReader, const char *idstr, bool countOnly, SHashObj** pIgnoreTables);
 void         tsdbReaderClose(STsdbReader *pReader);
 int32_t      tsdbNextDataBlock(STsdbReader *pReader, bool *hasNext);
 int32_t      tsdbRetrieveDatablockSMA(STsdbReader *pReader, SSDataBlock *pDataBlock, bool *allHave);
@@ -196,7 +192,10 @@ int32_t      tsdbGetFileBlocksDistInfo(STsdbReader *pReader, STableBlockDistInfo
 int64_t      tsdbGetNumOfRowsInMemTable(STsdbReader *pHandle);
 void        *tsdbGetIdx(SMeta *pMeta);
 void        *tsdbGetIvtIdx(SMeta *pMeta);
-uint64_t     getReaderMaxVersion(STsdbReader *pReader);
+uint64_t     tsdbGetReaderMaxVersion(STsdbReader *pReader);
+int32_t      tsdbSetTableList(STsdbReader *pReader, const void *pTableList, int32_t num);
+void         tsdbReaderSetId(STsdbReader *pReader, const char *idstr);
+void         tsdbReaderSetCloseFlag(STsdbReader *pReader);
 
 int32_t tsdbReuseCacherowsReader(void* pReader, void* pTableIdList, int32_t numOfTables);
 int32_t tsdbCacherowsReaderOpen(void *pVnode, int32_t type, void *pTableIdList, int32_t numOfTables, int32_t numOfCols,
@@ -238,26 +237,22 @@ typedef struct SSnapContext {
 } SSnapContext;
 
 typedef struct STqReader {
-  SPackedData msg2;
-
-  SSubmitReq2 submit;
-  int32_t     nextBlk;
-
-  int64_t lastBlkUid;
-
-  SWalReader *pWalReader;
-
-  SMeta    *pVnodeMeta;
-  SHashObj *tbIdHash;
-  SArray   *pColIdList;  // SArray
-
+  SPackedData     msg;
+  SSubmitReq2     submit;
+  int32_t         nextBlk;
+  int64_t         lastBlkUid;
+  SWalReader     *pWalReader;
+  SMeta          *pVnodeMeta;
+  SHashObj       *tbIdHash;
+  SArray         *pColIdList;  // SArray
   int32_t         cachedSchemaVer;
   int64_t         cachedSchemaSuid;
+  int64_t         cachedSchemaUid;
   SSchemaWrapper *pSchemaWrapper;
-  STSchema       *pSchema;
+  SSDataBlock    *pResBlock;
 } STqReader;
 
-STqReader *tqOpenReader(SVnode *pVnode);
+STqReader *tqReaderOpen(SVnode *pVnode);
 void       tqCloseReader(STqReader *);
 
 void    tqReaderSetColIdList(STqReader *pReader, SArray *pColIdList);
@@ -266,17 +261,14 @@ int32_t tqReaderAddTbUidList(STqReader *pReader, const SArray *pTableUidList);
 int32_t tqReaderRemoveTbUidList(STqReader *pReader, const SArray *tbUidList);
 
 int32_t tqSeekVer(STqReader *pReader, int64_t ver, const char *id);
-void    tqNextBlock(STqReader *pReader, SFetchRet *ret);
-int32_t extractSubmitMsgFromWal(SWalReader *pReader, SPackedData *pPackedData);
+int32_t tqNextBlockInWal(STqReader* pReader);
+bool    tqNextBlockImpl(STqReader *pReader);
 
+int32_t extractSubmitMsgFromWal(SWalReader *pReader, SPackedData *pPackedData);
 int32_t tqReaderSetSubmitMsg(STqReader *pReader, void *msgStr, int32_t msgLen, int64_t ver);
-// int32_t tqReaderSetDataMsg(STqReader *pReader, const SSubmitReq *pMsg, int64_t ver);
-bool    tqNextDataBlock(STqReader *pReader);
-bool    tqNextDataBlockFilterOut2(STqReader *pReader, SHashObj *filterOutUids);
-int32_t tqRetrieveDataBlock2(SSDataBlock *pBlock, STqReader *pReader, SSubmitTbData **pSubmitTbDataRet);
-int32_t tqRetrieveTaosxBlock2(STqReader *pReader, SArray *blocks, SArray *schemas, SSubmitTbData **pSubmitTbDataRet);
-// int32_t tqRetrieveDataBlock(SSDataBlock *pBlock, STqReader *pReader);
-// int32_t tqRetrieveTaosxBlock(STqReader *pReader, SArray *blocks, SArray *schemas);
+bool    tqNextDataBlockFilterOut(STqReader *pReader, SHashObj *filterOutUids);
+int32_t tqRetrieveDataBlock(STqReader *pReader, SSubmitTbData **pSubmitTbDataRet);
+int32_t tqRetrieveTaosxBlock(STqReader *pReader, SArray *blocks, SArray *schemas, SSubmitTbData **pSubmitTbDataRet);
 
 int32_t vnodeEnqueueStreamMsg(SVnode *pVnode, SRpcMsg *pMsg);
 
diff --git a/source/dnode/vnode/src/inc/tq.h b/source/dnode/vnode/src/inc/tq.h
index acc0d29382..e431ca4a01 100644
--- a/source/dnode/vnode/src/inc/tq.h
+++ b/source/dnode/vnode/src/inc/tq.h
@@ -100,6 +100,8 @@ typedef struct {
   SWalRef*      pRef;
   STqPushHandle pushHandle;    // push
   STqExecHandle execHandle;    // exec
+  SRpcMsg*      msg;
+  int32_t       noDataPollCnt;
 } STqHandle;
 
 typedef struct {
@@ -113,7 +115,7 @@ struct STQ {
   char*           path;
   int64_t         walLogLastVer;
   SRWLatch        lock;
-  SHashObj*       pPushMgr;    // consumerId -> STqPushEntry
+  SHashObj*       pPushMgr;    // subKey -> STqHandle
   SHashObj*       pHandle;     // subKey -> STqHandle
   SHashObj*       pCheckInfo;  // topic -> SAlterCheckInfo
   STqOffsetStore* pOffsetStore;
@@ -146,7 +148,7 @@ int32_t tqFetchLog(STQ* pTq, STqHandle* pHandle, int64_t* fetchOffset, SWalCkHea
 int32_t tqTaosxScanLog(STQ* pTq, STqHandle* pHandle, SPackedData submit, STaosxRsp* pRsp, int32_t* totalRows);
 int32_t tqAddBlockDataToRsp(const SSDataBlock* pBlock, SMqDataRsp* pRsp, int32_t numOfCols, int8_t precision);
 int32_t tqSendDataRsp(STQ* pTq, const SRpcMsg* pMsg, const SMqPollReq* pReq, const SMqDataRsp* pRsp, int32_t type);
-int32_t tqPushDataRsp(STQ* pTq, STqPushEntry* pPushEntry);
+int32_t tqPushDataRsp(STQ* pTq, STqHandle* pHandle);
 
 // tqMeta
 int32_t tqMetaOpen(STQ* pTq);
diff --git a/source/dnode/vnode/src/inc/tsdb.h b/source/dnode/vnode/src/inc/tsdb.h
index 2a85b191a4..6102487400 100644
--- a/source/dnode/vnode/src/inc/tsdb.h
+++ b/source/dnode/vnode/src/inc/tsdb.h
@@ -16,6 +16,7 @@
 #ifndef _TD_VNODE_TSDB_H_
 #define _TD_VNODE_TSDB_H_
 
+#include "tsimplehash.h"
 #include "vnodeInt.h"
 
 #ifdef __cplusplus
@@ -122,14 +123,14 @@ int32_t tsdbRowCmprFn(const void *p1, const void *p2);
 int32_t  tsdbRowIterOpen(STSDBRowIter *pIter, TSDBROW *pRow, STSchema *pTSchema);
 void     tsdbRowClose(STSDBRowIter *pIter);
 SColVal *tsdbRowIterNext(STSDBRowIter *pIter);
-// SRowMerger
-int32_t tsdbRowMergerInit(SRowMerger *pMerger, STSchema *pResTSchema, TSDBROW *pRow, STSchema *pTSchema);
-int32_t tsdbRowMergerAdd(SRowMerger *pMerger, TSDBROW *pRow, STSchema *pTSchema);
 
-// int32_t tsdbRowMergerInit(SRowMerger *pMerger, TSDBROW *pRow, STSchema *pTSchema);
-void tsdbRowMergerClear(SRowMerger *pMerger);
-// int32_t tsdbRowMerge(SRowMerger *pMerger, TSDBROW *pRow);
+// SRowMerger
+int32_t tsdbRowMergerInit(SRowMerger *pMerger, STSchema *pSchema);
+int32_t tsdbRowMergerAdd(SRowMerger *pMerger, TSDBROW *pRow, STSchema *pTSchema);
 int32_t tsdbRowMergerGetRow(SRowMerger *pMerger, SRow **ppRow);
+void    tsdbRowMergerClear(SRowMerger *pMerger);
+void    tsdbRowMergerCleanup(SRowMerger *pMerger);
+
 // TABLEID
 int32_t tTABLEIDCmprFn(const void *p1, const void *p2);
 // TSDBKEY
@@ -224,7 +225,7 @@ int32_t tsdbTbDataIterCreate(STbData *pTbData, TSDBKEY *pFrom, int8_t backward,
 void   *tsdbTbDataIterDestroy(STbDataIter *pIter);
 void    tsdbTbDataIterOpen(STbData *pTbData, TSDBKEY *pFrom, int8_t backward, STbDataIter *pIter);
 bool    tsdbTbDataIterNext(STbDataIter *pIter);
-void    tsdbMemTableCountRows(SMemTable *pMemTable, SHashObj *pTableMap, int64_t *rowsNum);
+void    tsdbMemTableCountRows(SMemTable *pMemTable, SSHashObj *pTableMap, int64_t *rowsNum);
 
 // STbData
 int32_t tsdbGetNRowsInTbData(STbData *pTbData);
@@ -322,8 +323,9 @@ int32_t tGnrtDiskData(SDiskDataBuilder *pBuilder, const SDiskData **ppDiskData,
 #define TSDB_STT_FILE_DATA_ITER  2
 #define TSDB_TOMB_FILE_DATA_ITER 3
 
-#define TSDB_FILTER_FLAG_BY_VERSION 0x1
-#define TSDB_FILTER_FLAG_BY_TABLEID 0x2
+#define TSDB_FILTER_FLAG_BY_VERSION           0x1
+#define TSDB_FILTER_FLAG_BY_TABLEID           0x2
+#define TSDB_FILTER_FLAG_IGNORE_DROPPED_TABLE 0x4
 
 #define TSDB_RBTN_TO_DATA_ITER(pNode) ((STsdbDataIter2 *)(((char *)pNode) - offsetof(STsdbDataIter2, rbtn)))
 /* open */
@@ -705,7 +707,6 @@ typedef struct SSttBlockLoadInfo {
 typedef struct SMergeTree {
   int8_t             backward;
   SRBTree            rbt;
-  SArray            *pIterList;
   SLDataIter        *pIter;
   bool               destroyLoadInfo;
   SSttBlockLoadInfo *pLoadInfo;
@@ -751,13 +752,29 @@ struct SDiskDataBuilder {
   SBlkInfo     bi;
 };
 
+typedef struct SLDataIter {
+  SRBTreeNode        node;
+  SSttBlk           *pSttBlk;
+  SDataFReader      *pReader;
+  int32_t            iStt;
+  int8_t             backward;
+  int32_t            iSttBlk;
+  int32_t            iRow;
+  SRowInfo           rInfo;
+  uint64_t           uid;
+  STimeWindow        timeWindow;
+  SVersionRange      verRange;
+  SSttBlockLoadInfo *pBlockLoadInfo;
+  bool               ignoreEarlierTs;
+} SLDataIter;
+
+#define tMergeTreeGetRow(_t) (&((_t)->pIter->rInfo.row))
 int32_t tMergeTreeOpen(SMergeTree *pMTree, int8_t backward, SDataFReader *pFReader, uint64_t suid, uint64_t uid,
                        STimeWindow *pTimeWindow, SVersionRange *pVerRange, SSttBlockLoadInfo *pBlockLoadInfo,
-                       bool destroyLoadInfo, const char *idStr, bool strictTimeRange);
+                       bool destroyLoadInfo, const char *idStr, bool strictTimeRange, SLDataIter* pLDataIter);
 void    tMergeTreeAddIter(SMergeTree *pMTree, SLDataIter *pIter);
 bool    tMergeTreeNext(SMergeTree *pMTree);
 bool    tMergeTreeIgnoreEarlierTs(SMergeTree *pMTree);
-TSDBROW tMergeTreeGetRow(SMergeTree *pMTree);
 void    tMergeTreeClose(SMergeTree *pMTree);
 
 SSttBlockLoadInfo *tCreateLastBlockLoadInfo(STSchema *pSchema, int16_t *colList, int32_t numOfCols, int32_t numOfStt);
@@ -782,6 +799,7 @@ typedef struct SCacheRowsReader {
   STableKeyInfo     *pTableList;  // table id list
   int32_t            numOfTables;
   SSttBlockLoadInfo *pLoadInfo;
+  SLDataIter        *pDataIter;
   STsdbReadSnap     *pReadSnap;
   SDataFReader      *pDataFReader;
   SDataFReader      *pDataFReaderLast;
diff --git a/source/dnode/vnode/src/inc/vnodeInt.h b/source/dnode/vnode/src/inc/vnodeInt.h
index 416bc6cdc7..1aea479511 100644
--- a/source/dnode/vnode/src/inc/vnodeInt.h
+++ b/source/dnode/vnode/src/inc/vnodeInt.h
@@ -193,9 +193,8 @@ STQ* tqOpen(const char* path, SVnode* pVnode);
 void tqNotifyClose(STQ*);
 void tqClose(STQ*);
 int  tqPushMsg(STQ*, void* msg, int32_t msgLen, tmsg_t msgType, int64_t ver);
-int  tqRegisterPushHandle(STQ* pTq, void* pHandle, const SMqPollReq* pRequest, SRpcMsg* pRpcMsg, SMqDataRsp* pDataRsp,
-                         int32_t type);
-int  tqUnregisterPushHandle(STQ* pTq, const char* pKey, int32_t keyLen, uint64_t consumerId, bool rspConsumer);
+int  tqRegisterPushHandle(STQ* pTq, void* handle, SRpcMsg* pMsg);
+int  tqUnregisterPushHandle(STQ* pTq, void* pHandle);
 int  tqStartStreamTasks(STQ* pTq);    // restore all stream tasks after vnode launching completed.
 
 int     tqCommit(STQ*);
@@ -213,7 +212,7 @@ int32_t tqProcessTaskDeployReq(STQ* pTq, int64_t version, char* msg, int32_t msg
 int32_t tqProcessTaskDropReq(STQ* pTq, int64_t version, char* msg, int32_t msgLen);
 int32_t tqProcessStreamTaskCheckReq(STQ* pTq, SRpcMsg* pMsg);
 int32_t tqProcessStreamTaskCheckRsp(STQ* pTq, int64_t version, char* msg, int32_t msgLen);
-int32_t tqProcessSubmitReq(STQ* pTq, SPackedData submit);
+int32_t tqProcessSubmitReqForSubscribe(STQ* pTq);
 int32_t tqProcessDelReq(STQ* pTq, void* pReq, int32_t len, int64_t ver);
 int32_t tqProcessTaskRunReq(STQ* pTq, SRpcMsg* pMsg);
 int32_t tqProcessTaskDispatchReq(STQ* pTq, SRpcMsg* pMsg, bool exec);
diff --git a/source/dnode/vnode/src/meta/metaQuery.c b/source/dnode/vnode/src/meta/metaQuery.c
index 2359a165b7..d464f64de3 100644
--- a/source/dnode/vnode/src/meta/metaQuery.c
+++ b/source/dnode/vnode/src/meta/metaQuery.c
@@ -639,7 +639,6 @@ tb_uid_t metaStbCursorNext(SMStbCursor *pStbCur) {
 STSchema *metaGetTbTSchema(SMeta *pMeta, tb_uid_t uid, int32_t sver, int lock) {
   STSchema       *pTSchema = NULL;
   SSchemaWrapper *pSW = NULL;
-  SSchema        *pSchema = NULL;
 
   pSW = metaGetTableSchema(pMeta, uid, sver, lock);
   if (!pSW) return NULL;
diff --git a/source/dnode/vnode/src/meta/metaSnapshot.c b/source/dnode/vnode/src/meta/metaSnapshot.c
index 0126d29cc9..707dd66e30 100644
--- a/source/dnode/vnode/src/meta/metaSnapshot.c
+++ b/source/dnode/vnode/src/meta/metaSnapshot.c
@@ -187,23 +187,24 @@ _err:
 
 int32_t metaSnapWrite(SMetaSnapWriter* pWriter, uint8_t* pData, uint32_t nData) {
   int32_t    code = 0;
+  int32_t    line = 0;
   SMeta*     pMeta = pWriter->pMeta;
   SMetaEntry metaEntry = {0};
   SDecoder*  pDecoder = &(SDecoder){0};
 
   tDecoderInit(pDecoder, pData + sizeof(SSnapDataHdr), nData - sizeof(SSnapDataHdr));
   code = metaDecodeEntry(pDecoder, &metaEntry);
-  if (code) goto _err;
+  VND_CHECK_CODE(code, line, _err);
 
   code = metaHandleEntry(pMeta, &metaEntry);
-  if (code) goto _err;
+  VND_CHECK_CODE(code, line, _err);
 
   tDecoderClear(pDecoder);
   return code;
 
 _err:
   tDecoderClear(pDecoder);
-  metaError("vgId:%d, vnode snapshot meta write failed since %s", TD_VID(pMeta->pVnode), tstrerror(code));
+  metaError("vgId:%d, vnode snapshot meta write failed since %s at line:%d", TD_VID(pMeta->pVnode), terrstr(), line);
   return code;
 }
 
@@ -216,8 +217,8 @@ typedef struct STableInfoForChildTable {
 static void destroySTableInfoForChildTable(void* data) {
   STableInfoForChildTable* pData = (STableInfoForChildTable*)data;
   taosMemoryFree(pData->tableName);
-  tDeleteSSchemaWrapper(pData->schemaRow);
-  tDeleteSSchemaWrapper(pData->tagRow);
+  tDeleteSchemaWrapper(pData->schemaRow);
+  tDeleteSchemaWrapper(pData->tagRow);
 }
 
 static void MoveToSnapShotVersion(SSnapContext* ctx) {
diff --git a/source/dnode/vnode/src/meta/metaTable.c b/source/dnode/vnode/src/meta/metaTable.c
index b2d553055d..0164a82c69 100644
--- a/source/dnode/vnode/src/meta/metaTable.c
+++ b/source/dnode/vnode/src/meta/metaTable.c
@@ -673,8 +673,8 @@ int metaDropIndexFromSTable(SMeta *pMeta, int64_t version, SDropIndexReq *pReq)
   metaUpdateUidIdx(pMeta, &nStbEntry);
   metaULock(pMeta);
 
-  tDeleteSSchemaWrapper(tag);
-  tDeleteSSchemaWrapper(row);
+  tDeleteSchemaWrapper(tag);
+  tDeleteSchemaWrapper(row);
 
   if (oStbEntry.pBuf) taosMemoryFree(oStbEntry.pBuf);
   tDecoderClear(&dc);
@@ -937,8 +937,7 @@ static int metaDropTableByUid(SMeta *pMeta, tb_uid_t uid, int *type) {
     int   tLen = 0;
 
     if (tdbTbGet(pMeta->pUidIdx, &e.ctbEntry.suid, sizeof(tb_uid_t), &tData, &tLen) == 0) {
-      version = ((SUidIdxVal *)tData)[0].version;
-      STbDbKey tbDbKey = {.uid = e.ctbEntry.suid, .version = version};
+      STbDbKey tbDbKey = {.uid = e.ctbEntry.suid, .version = ((SUidIdxVal *)tData)[0].version};
       if (tdbTbGet(pMeta->pTbDb, &tbDbKey, sizeof(tbDbKey), &tData, &tLen) == 0) {
         SDecoder   tdc = {0};
         SMetaEntry stbEntry = {0};
@@ -1032,7 +1031,7 @@ int metaUpdateCtimeIdx(SMeta *pMeta, const SMetaEntry *pME) {
   metaTrace("vgId:%d, start to save version:%" PRId64 " uid:%" PRId64 " ctime:%" PRId64, TD_VID(pMeta->pVnode),
             pME->version, pME->uid, ctimeKey.ctime);
 
-  return tdbTbInsert(pMeta->pCtimeIdx, &ctimeKey, sizeof(ctimeKey), NULL, 0, pMeta->txn);
+  return tdbTbUpsert(pMeta->pCtimeIdx, &ctimeKey, sizeof(ctimeKey), NULL, 0, pMeta->txn);
 }
 
 int metaDeleteCtimeIdx(SMeta *pMeta, const SMetaEntry *pME) {
@@ -1047,7 +1046,7 @@ int metaUpdateNcolIdx(SMeta *pMeta, const SMetaEntry *pME) {
   if (metaBuildNColIdxKey(&ncolKey, pME) < 0) {
     return 0;
   }
-  return tdbTbInsert(pMeta->pNcolIdx, &ncolKey, sizeof(ncolKey), NULL, 0, pMeta->txn);
+  return tdbTbUpsert(pMeta->pNcolIdx, &ncolKey, sizeof(ncolKey), NULL, 0, pMeta->txn);
 }
 
 int metaDeleteNcolIdx(SMeta *pMeta, const SMetaEntry *pME) {
@@ -1882,24 +1881,24 @@ static int metaUpdateUidIdx(SMeta *pMeta, const SMetaEntry *pME) {
 }
 
 static int metaUpdateSuidIdx(SMeta *pMeta, const SMetaEntry *pME) {
-  return tdbTbInsert(pMeta->pSuidIdx, &pME->uid, sizeof(tb_uid_t), NULL, 0, pMeta->txn);
+  return tdbTbUpsert(pMeta->pSuidIdx, &pME->uid, sizeof(tb_uid_t), NULL, 0, pMeta->txn);
 }
 
 static int metaUpdateNameIdx(SMeta *pMeta, const SMetaEntry *pME) {
-  return tdbTbInsert(pMeta->pNameIdx, pME->name, strlen(pME->name) + 1, &pME->uid, sizeof(tb_uid_t), pMeta->txn);
+  return tdbTbUpsert(pMeta->pNameIdx, pME->name, strlen(pME->name) + 1, &pME->uid, sizeof(tb_uid_t), pMeta->txn);
 }
 
 static int metaUpdateTtlIdx(SMeta *pMeta, const SMetaEntry *pME) {
   STtlIdxKey ttlKey = {0};
   metaBuildTtlIdxKey(&ttlKey, pME);
   if (ttlKey.dtime == 0) return 0;
-  return tdbTbInsert(pMeta->pTtlIdx, &ttlKey, sizeof(ttlKey), NULL, 0, pMeta->txn);
+  return tdbTbUpsert(pMeta->pTtlIdx, &ttlKey, sizeof(ttlKey), NULL, 0, pMeta->txn);
 }
 
 static int metaUpdateCtbIdx(SMeta *pMeta, const SMetaEntry *pME) {
   SCtbIdxKey ctbIdxKey = {.suid = pME->ctbEntry.suid, .uid = pME->uid};
 
-  return tdbTbInsert(pMeta->pCtbIdx, &ctbIdxKey, sizeof(ctbIdxKey), pME->ctbEntry.pTags,
+  return tdbTbUpsert(pMeta->pCtbIdx, &ctbIdxKey, sizeof(ctbIdxKey), pME->ctbEntry.pTags,
                      ((STag *)(pME->ctbEntry.pTags))->len, pMeta->txn);
 }
 
@@ -2069,49 +2068,66 @@ _exit:
 }
 
 int metaHandleEntry(SMeta *pMeta, const SMetaEntry *pME) {
+  int32_t code = 0;
+  int32_t line = 0;
   metaWLock(pMeta);
 
   // save to table.db
-  if (metaSaveToTbDb(pMeta, pME) < 0) goto _err;
+  code = metaSaveToTbDb(pMeta, pME);
+  VND_CHECK_CODE(code, line, _err);
 
   // update uid.idx
-  if (metaUpdateUidIdx(pMeta, pME) < 0) goto _err;
+  code = metaUpdateUidIdx(pMeta, pME);
+  VND_CHECK_CODE(code, line, _err);
 
   // update name.idx
-  if (metaUpdateNameIdx(pMeta, pME) < 0) goto _err;
+  code = metaUpdateNameIdx(pMeta, pME);
+  VND_CHECK_CODE(code, line, _err);
 
   if (pME->type == TSDB_CHILD_TABLE) {
     // update ctb.idx
-    if (metaUpdateCtbIdx(pMeta, pME) < 0) goto _err;
+    code = metaUpdateCtbIdx(pMeta, pME);
+    VND_CHECK_CODE(code, line, _err);
 
     // update tag.idx
-    if (metaUpdateTagIdx(pMeta, pME) < 0) goto _err;
+    code = metaUpdateTagIdx(pMeta, pME);
+    VND_CHECK_CODE(code, line, _err);
   } else {
     // update schema.db
-    if (metaSaveToSkmDb(pMeta, pME) < 0) goto _err;
+    code = metaSaveToSkmDb(pMeta, pME);
+    VND_CHECK_CODE(code, line, _err);
 
     if (pME->type == TSDB_SUPER_TABLE) {
-      if (metaUpdateSuidIdx(pMeta, pME) < 0) goto _err;
+      code = metaUpdateSuidIdx(pMeta, pME);
+      VND_CHECK_CODE(code, line, _err);
     }
   }
 
-  if (metaUpdateCtimeIdx(pMeta, pME) < 0) goto _err;
+  code = metaUpdateCtimeIdx(pMeta, pME);
+  VND_CHECK_CODE(code, line, _err);
 
   if (pME->type == TSDB_NORMAL_TABLE) {
-    if (metaUpdateNcolIdx(pMeta, pME) < 0) goto _err;
+    code = metaUpdateNcolIdx(pMeta, pME);
+    VND_CHECK_CODE(code, line, _err);
   }
 
   if (pME->type != TSDB_SUPER_TABLE) {
-    if (metaUpdateTtlIdx(pMeta, pME) < 0) goto _err;
+    code = metaUpdateTtlIdx(pMeta, pME);
+    VND_CHECK_CODE(code, line, _err);
   }
 
   metaULock(pMeta);
+  metaDebug("vgId:%d, handle meta entry, ver:%" PRId64 ", uid:%" PRId64 ", name:%s", TD_VID(pMeta->pVnode),
+            pME->version, pME->uid, pME->name);
   return 0;
 
 _err:
   metaULock(pMeta);
+  metaError("vgId:%d, failed to handle meta entry since %s at line:%d, ver:%" PRId64 ", uid:%" PRId64 ", name:%s",
+            TD_VID(pMeta->pVnode), terrstr(), line, pME->version, pME->uid, pME->name);
   return -1;
 }
+
 // refactor later
 void *metaGetIdx(SMeta *pMeta) { return pMeta->pTagIdx; }
 void *metaGetIvtIdx(SMeta *pMeta) { return pMeta->pTagIvtIdx; }
diff --git a/source/dnode/vnode/src/sma/smaRollup.c b/source/dnode/vnode/src/sma/smaRollup.c
index ce987ca88e..20e04f122b 100644
--- a/source/dnode/vnode/src/sma/smaRollup.c
+++ b/source/dnode/vnode/src/sma/smaRollup.c
@@ -684,7 +684,7 @@ static int32_t tdRSmaExecAndSubmitResult(SSma *pSma, qTaskInfo_t taskInfo, SRSma
       }
 
       if (pReq && tdProcessSubmitReq(sinkTsdb, output->info.version, pReq) < 0) {
-        tDestroySSubmitReq2(pReq, TSDB_MSG_FLG_ENCODE);
+        tDestroySubmitReq(pReq, TSDB_MSG_FLG_ENCODE);
         taosMemoryFree(pReq);
         smaError("vgId:%d, process submit req for rsma suid:%" PRIu64 ", uid:%" PRIu64 " level %" PRIi8
                  " failed since %s",
@@ -696,7 +696,7 @@ static int32_t tdRSmaExecAndSubmitResult(SSma *pSma, qTaskInfo_t taskInfo, SRSma
                SMA_VID(pSma), suid, output->info.id.groupId, pItem->level, output->info.version);
 
       if (pReq) {
-        tDestroySSubmitReq2(pReq, TSDB_MSG_FLG_ENCODE);
+        tDestroySubmitReq(pReq, TSDB_MSG_FLG_ENCODE);
         taosMemoryFree(pReq);
       }
     }
diff --git a/source/dnode/vnode/src/sma/smaTimeRange.c b/source/dnode/vnode/src/sma/smaTimeRange.c
index 5058a7fc76..6a4bddc991 100644
--- a/source/dnode/vnode/src/sma/smaTimeRange.c
+++ b/source/dnode/vnode/src/sma/smaTimeRange.c
@@ -299,7 +299,7 @@ int32_t smaBlockToSubmit(SVnode *pVnode, const SArray *pBlocks, const STSchema *
       }
       SRow *pRow = NULL;
       if ((terrno = tRowBuild(pVals, (STSchema *)pTSchema, &pRow)) < 0) {
-        tDestroySSubmitTbData(&tbData, TSDB_MSG_FLG_ENCODE);
+        tDestroySubmitTbData(&tbData, TSDB_MSG_FLG_ENCODE);
         goto _end;
       }
       taosArrayPush(tbData.aRowP, &pRow);
@@ -309,7 +309,7 @@ int32_t smaBlockToSubmit(SVnode *pVnode, const SArray *pBlocks, const STSchema *
   }
 
   // encode
-  tEncodeSize(tEncodeSSubmitReq2, pReq, len, terrno);
+  tEncodeSize(tEncodeSubmitReq, pReq, len, terrno);
   if (TSDB_CODE_SUCCESS == terrno) {
     SEncoder encoder;
     len += sizeof(SSubmitReq2Msg);
@@ -321,7 +321,7 @@ int32_t smaBlockToSubmit(SVnode *pVnode, const SArray *pBlocks, const STSchema *
     ((SSubmitReq2Msg *)pBuf)->header.contLen = htonl(len);
     ((SSubmitReq2Msg *)pBuf)->version = htobe64(1);
     tEncoderInit(&encoder, POINTER_SHIFT(pBuf, sizeof(SSubmitReq2Msg)), len - sizeof(SSubmitReq2Msg));
-    if (tEncodeSSubmitReq2(&encoder, pReq) < 0) {
+    if (tEncodeSubmitReq(&encoder, pReq) < 0) {
       terrno = TSDB_CODE_OUT_OF_MEMORY;
       /*vError("failed to encode submit req since %s", terrstr());*/
     }
@@ -332,7 +332,7 @@ _end:
   taosArrayDestroy(tagArray);
   taosArrayDestroy(pVals);
   if (pReq) {
-    tDestroySSubmitReq2(pReq, TSDB_MSG_FLG_ENCODE);
+    tDestroySubmitReq(pReq, TSDB_MSG_FLG_ENCODE);
     taosMemoryFree(pReq);
   }
 
diff --git a/source/dnode/vnode/src/tq/tq.c b/source/dnode/vnode/src/tq/tq.c
index ae52db163f..311d637be8 100644
--- a/source/dnode/vnode/src/tq/tq.c
+++ b/source/dnode/vnode/src/tq/tq.c
@@ -71,18 +71,11 @@ static void destroyTqHandle(void* data) {
     walCloseReader(pData->pWalReader);
     tqCloseReader(pData->execHandle.pTqReader);
   }
-}
-
-static void tqPushEntryFree(void* data) {
-  STqPushEntry* p = *(void**)data;
-  if (p->pDataRsp->head.mqMsgType == TMQ_MSG_TYPE__POLL_RSP) {
-    tDeleteSMqDataRsp(p->pDataRsp);
-  } else if (p->pDataRsp->head.mqMsgType == TMQ_MSG_TYPE__TAOSX_RSP) {
-    tDeleteSTaosxRsp((STaosxRsp*)p->pDataRsp);
+  if(pData->msg != NULL) {
+    rpcFreeCont(pData->msg->pCont);
+    taosMemoryFree(pData->msg);
+    pData->msg = NULL;
   }
-
-  taosMemoryFree(p->pDataRsp);
-  taosMemoryFree(p);
 }
 
 static bool tqOffsetLessOrEqual(const STqOffset* pLeft, const STqOffset* pRight) {
@@ -105,14 +98,18 @@ STQ* tqOpen(const char* path, SVnode* pVnode) {
   taosHashSetFreeFp(pTq->pHandle, destroyTqHandle);
 
   taosInitRWLatch(&pTq->lock);
-  pTq->pPushMgr = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, HASH_NO_LOCK);
-  taosHashSetFreeFp(pTq->pPushMgr, tqPushEntryFree);
+  pTq->pPushMgr = taosHashInit(64, MurmurHash3_32, false, HASH_NO_LOCK);
 
   pTq->pCheckInfo = taosHashInit(64, MurmurHash3_32, true, HASH_ENTRY_LOCK);
   taosHashSetFreeFp(pTq->pCheckInfo, (FDelete)tDeleteSTqCheckInfo);
 
-  tqInitialize(pTq);
-  return pTq;
+  int32_t code = tqInitialize(pTq);
+  if (code != TSDB_CODE_SUCCESS) {
+    tqClose(pTq);
+    return NULL;
+  } else {
+    return pTq;
+  }
 }
 
 int32_t tqInitialize(STQ* pTq) {
@@ -228,17 +225,19 @@ static int32_t doSendDataRsp(const SRpcHandleInfo* pRpcHandleInfo, const SMqData
   return 0;
 }
 
-int32_t tqPushDataRsp(STQ* pTq, STqPushEntry* pPushEntry) {
-  SMqDataRsp* pRsp = pPushEntry->pDataRsp;
-  SMqRspHead* pHeader = &pPushEntry->pDataRsp->head;
-  doSendDataRsp(&pPushEntry->info, pRsp, pHeader->epoch, pHeader->consumerId, pHeader->mqMsgType);
+int32_t tqPushDataRsp(STQ* pTq, STqHandle* pHandle) {
+  SMqDataRsp dataRsp = {0};
+  dataRsp.head.consumerId = pHandle->consumerId;
+  dataRsp.head.epoch = pHandle->epoch;
+  dataRsp.head.mqMsgType = TMQ_MSG_TYPE__POLL_RSP;
+  doSendDataRsp(&pHandle->msg->info, &dataRsp, pHandle->epoch, pHandle->consumerId, TMQ_MSG_TYPE__POLL_RSP);
 
   char buf1[80] = {0};
   char buf2[80] = {0};
-  tFormatOffset(buf1, tListLen(buf1), &pRsp->reqOffset);
-  tFormatOffset(buf2, tListLen(buf2), &pRsp->rspOffset);
+  tFormatOffset(buf1, tListLen(buf1), &dataRsp.reqOffset);
+  tFormatOffset(buf2, tListLen(buf2), &dataRsp.rspOffset);
   tqDebug("vgId:%d, from consumer:0x%" PRIx64 " (epoch %d) push rsp, block num: %d, req:%s, rsp:%s",
-          TD_VID(pTq->pVnode), pRsp->head.consumerId, pRsp->head.epoch, pRsp->blockNum, buf1, buf2);
+          TD_VID(pTq->pVnode), dataRsp.head.consumerId, dataRsp.head.epoch, dataRsp.blockNum, buf1, buf2);
   return 0;
 }
 
@@ -382,13 +381,13 @@ int32_t tqProcessDeleteSubReq(STQ* pTq, int64_t sversion, char* msg, int32_t msg
   SMqVDeleteReq* pReq = (SMqVDeleteReq*)msg;
 
   tqDebug("vgId:%d, tq process delete sub req %s", pTq->pVnode->config.vgId, pReq->subKey);
-
-  taosWLockLatch(&pTq->lock);
-  int32_t code = taosHashRemove(pTq->pPushMgr, pReq->subKey, strlen(pReq->subKey));
-  if (code != 0) {
-    tqDebug("vgId:%d, tq remove push handle %s", pTq->pVnode->config.vgId, pReq->subKey);
-  }
-  taosWUnLockLatch(&pTq->lock);
+  int32_t code = 0;
+//  taosWLockLatch(&pTq->lock);
+//  int32_t code = taosHashRemove(pTq->pPushMgr, pReq->subKey, strlen(pReq->subKey));
+//  if (code != 0) {
+//    tqDebug("vgId:%d, tq remove push handle %s", pTq->pVnode->config.vgId, pReq->subKey);
+//  }
+//  taosWUnLockLatch(&pTq->lock);
 
   STqHandle* pHandle = taosHashGet(pTq->pHandle, pReq->subKey, strlen(pReq->subKey));
   if (pHandle) {
@@ -446,6 +445,7 @@ int32_t tqProcessDelCheckInfoReq(STQ* pTq, int64_t sversion, char* msg, int32_t
 }
 
 int32_t tqProcessSubscribeReq(STQ* pTq, int64_t sversion, char* msg, int32_t msgLen) {
+  int ret = 0;
   SMqRebVgReq req = {0};
   tDecodeSMqRebVgReq(msg, &req);
 
@@ -464,8 +464,7 @@ int32_t tqProcessSubscribeReq(STQ* pTq, int64_t sversion, char* msg, int32_t msg
 
     if (req.newConsumerId == -1) {
       tqError("vgId:%d, tq invalid re-balance request, new consumerId %" PRId64 "", req.vgId, req.newConsumerId);
-      taosMemoryFree(req.qmsg);
-      return 0;
+      goto end;
     }
 
     STqHandle tqHandle = {0};
@@ -482,8 +481,8 @@ int32_t tqProcessSubscribeReq(STQ* pTq, int64_t sversion, char* msg, int32_t msg
     // TODO version should be assigned and refed during preprocess
     SWalRef* pRef = walRefCommittedVer(pVnode->pWal);
     if (pRef == NULL) {
-      taosMemoryFree(req.qmsg);
-      return -1;
+      ret = -1;
+      goto end;
     }
 
     int64_t ver = pRef->refVer;
@@ -504,7 +503,7 @@ int32_t tqProcessSubscribeReq(STQ* pTq, int64_t sversion, char* msg, int32_t msg
       pHandle->execHandle.pTqReader = qExtractReaderFromStreamScanner(scanner);
     } else if (pHandle->execHandle.subType == TOPIC_SUB_TYPE__DB) {
       pHandle->pWalReader = walOpenReader(pVnode->pWal, NULL);
-      pHandle->execHandle.pTqReader = tqOpenReader(pVnode);
+      pHandle->execHandle.pTqReader = tqReaderOpen(pVnode);
 
       pHandle->execHandle.execDb.pFilterOutTbUid =
           taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK);
@@ -523,7 +522,7 @@ int32_t tqProcessSubscribeReq(STQ* pTq, int64_t sversion, char* msg, int32_t msg
         int64_t tbUid = *(int64_t*)taosArrayGet(tbUidList, i);
         tqDebug("vgId:%d, idx %d, uid:%" PRId64, vgId, i, tbUid);
       }
-      pHandle->execHandle.pTqReader = tqOpenReader(pVnode);
+      pHandle->execHandle.pTqReader = tqReaderOpen(pVnode);
       tqReaderSetTbUidList(pHandle->execHandle.pTqReader, tbUidList);
       taosArrayDestroy(tbUidList);
 
@@ -535,50 +534,42 @@ int32_t tqProcessSubscribeReq(STQ* pTq, int64_t sversion, char* msg, int32_t msg
     taosHashPut(pTq->pHandle, req.subKey, strlen(req.subKey), pHandle, sizeof(STqHandle));
     tqDebug("try to persist handle %s consumer:0x%" PRIx64 " , old consumer:0x%" PRIx64, req.subKey,
             pHandle->consumerId, oldConsumerId);
-    if (tqMetaSaveHandle(pTq, req.subKey, pHandle) < 0) {
-      taosMemoryFree(req.qmsg);
-      return -1;
-    }
+    ret = tqMetaSaveHandle(pTq, req.subKey, pHandle);
+    goto end;
   } else {
     if (pHandle->consumerId == req.newConsumerId) {  // do nothing
       tqInfo("vgId:%d consumer:0x%" PRIx64 " remains, no switch occurs", req.vgId, req.newConsumerId);
-      atomic_store_32(&pHandle->epoch, -1);
       atomic_add_fetch_32(&pHandle->epoch, 1);
-      taosMemoryFree(req.qmsg);
-      return tqMetaSaveHandle(pTq, req.subKey, pHandle);
+
     } else {
       tqInfo("vgId:%d switch consumer from Id:0x%" PRIx64 " to Id:0x%" PRIx64, req.vgId, pHandle->consumerId,
              req.newConsumerId);
-
-      // kill executing task
-      qTaskInfo_t pTaskInfo = pHandle->execHandle.task;
-      if (pTaskInfo != NULL) {
-        qKillTask(pTaskInfo, TSDB_CODE_SUCCESS);
-      }
-
-      taosWLockLatch(&pTq->lock);
-      atomic_store_32(&pHandle->epoch, -1);
-
-      // remove if it has been register in the push manager, and return one empty block to consumer
-      tqUnregisterPushHandle(pTq, req.subKey, (int32_t)strlen(req.subKey), pHandle->consumerId, true);
-
       atomic_store_64(&pHandle->consumerId, req.newConsumerId);
-      atomic_add_fetch_32(&pHandle->epoch, 1);
-
-      if (pHandle->execHandle.subType == TOPIC_SUB_TYPE__COLUMN) {
-        qStreamCloseTsdbReader(pTaskInfo);
-      }
-
-      taosWUnLockLatch(&pTq->lock);
-      if (tqMetaSaveHandle(pTq, req.subKey, pHandle) < 0) {
-        taosMemoryFree(req.qmsg);
-        return -1;
-      }
+      atomic_store_32(&pHandle->epoch, 0);
     }
+    // kill executing task
+    qTaskInfo_t pTaskInfo = pHandle->execHandle.task;
+    if (pTaskInfo != NULL) {
+      qKillTask(pTaskInfo, TSDB_CODE_SUCCESS);
+    }
+
+    taosWLockLatch(&pTq->lock);
+    // remove if it has been register in the push manager, and return one empty block to consumer
+    tqUnregisterPushHandle(pTq, pHandle);
+
+
+    if (pHandle->execHandle.subType == TOPIC_SUB_TYPE__COLUMN) {
+      qStreamCloseTsdbReader(pTaskInfo);
+    }
+
+    taosWUnLockLatch(&pTq->lock);
+    ret = tqMetaSaveHandle(pTq, req.subKey, pHandle);
+    goto end;
   }
 
+end:
   taosMemoryFree(req.qmsg);
-  return 0;
+  return ret;
 }
 
 int32_t tqExpandTask(STQ* pTq, SStreamTask* pTask, int64_t ver) {
@@ -601,11 +592,7 @@ int32_t tqExpandTask(STQ* pTq, SStreamTask* pTask, int64_t ver) {
   pTask->chkInfo.currentVer = ver;
 
   // expand executor
-  if (pTask->fillHistory) {
-    pTask->status.taskStatus = TASK_STATUS__WAIT_DOWNSTREAM;
-  } else {
-    pTask->status.taskStatus = TASK_STATUS__RESTORE;
-  }
+  pTask->status.taskStatus = (pTask->fillHistory)? TASK_STATUS__WAIT_DOWNSTREAM:TASK_STATUS__NORMAL;
 
   if (pTask->taskLevel == TASK_LEVEL__SOURCE) {
     pTask->pState = streamStateOpen(pTq->pStreamMeta->path, pTask, false, -1, -1);
@@ -664,6 +651,7 @@ int32_t tqExpandTask(STQ* pTq, SStreamTask* pTask, int64_t ver) {
   }
 
   streamSetupTrigger(pTask);
+
   tqInfo("vgId:%d expand stream task, s-task:%s, checkpoint ver:%" PRId64 " child id:%d, level:%d", vgId, pTask->id.idStr,
          pTask->chkInfo.version, pTask->selfChildId, pTask->taskLevel);
 
@@ -693,8 +681,9 @@ int32_t tqProcessStreamTaskCheckReq(STQ* pTq, SRpcMsg* pMsg) {
   };
 
   SStreamTask* pTask = streamMetaAcquireTask(pTq->pStreamMeta, taskId);
+
   if (pTask) {
-    rsp.status = (atomic_load_8(&pTask->status.taskStatus) == TASK_STATUS__NORMAL) ? 1 : 0;
+    rsp.status = streamTaskCheckStatus(pTask);
     streamMetaReleaseTask(pTq->pStreamMeta, pTask);
 
     tqDebug("tq recv task check req(reqId:0x%" PRIx64
@@ -785,13 +774,17 @@ int32_t tqProcessTaskDeployReq(STQ* pTq, int64_t sversion, char* msg, int32_t ms
   tDecoderClear(&decoder);
 
   // 2.save task, use the newest commit version as the initial start version of stream task.
+  taosWLockLatch(&pTq->pStreamMeta->lock);
   code = streamMetaAddDeployedTask(pTq->pStreamMeta, sversion, pTask);
   if (code < 0) {
     tqError("vgId:%d failed to add s-task:%s, total:%d", TD_VID(pTq->pVnode), pTask->id.idStr,
             streamMetaGetNumOfTasks(pTq->pStreamMeta));
+    taosWUnLockLatch(&pTq->pStreamMeta->lock);
     return -1;
   }
 
+  taosWUnLockLatch(&pTq->pStreamMeta->lock);
+
   // 3.go through recover steps to fill history
   if (pTask->fillHistory) {
     streamTaskCheckDownstream(pTask, sversion);
@@ -821,13 +814,18 @@ int32_t tqProcessTaskRecover1Req(STQ* pTq, SRpcMsg* pMsg) {
   }
 
   // do recovery step 1
-  streamSourceRecoverScanStep1(pTask);
+  tqDebug("s-task:%s start recover step 1 scan", pTask->id.idStr);
+  int64_t st = taosGetTimestampMs();
 
+  streamSourceRecoverScanStep1(pTask);
   if (atomic_load_8(&pTask->status.taskStatus) == TASK_STATUS__DROPPING) {
     streamMetaReleaseTask(pTq->pStreamMeta, pTask);
     return 0;
   }
 
+  double el = (taosGetTimestampMs() - st) / 1000.0;
+  tqDebug("s-task:%s recover step 1 ended, elapsed time:%.2fs", pTask->id.idStr, el);
+
   // build msg to launch next step
   SStreamRecoverStep2Req req;
   code = streamBuildSourceRecover2Req(pTask, &req);
@@ -853,20 +851,17 @@ int32_t tqProcessTaskRecover1Req(STQ* pTq, SRpcMsg* pMsg) {
   memcpy(serializedReq, &req, len);
 
   // dispatch msg
+  tqDebug("s-task:%s start recover block stage", pTask->id.idStr);
+
   SRpcMsg rpcMsg = {
-      .code = 0,
-      .contLen = len,
-      .msgType = TDMT_VND_STREAM_RECOVER_BLOCKING_STAGE,
-      .pCont = serializedReq,
-  };
-
+      .code = 0, .contLen = len, .msgType = TDMT_VND_STREAM_RECOVER_BLOCKING_STAGE, .pCont = serializedReq};
   tmsgPutToQueue(&pTq->pVnode->msgCb, WRITE_QUEUE, &rpcMsg);
-
   return 0;
 }
 
 int32_t tqProcessTaskRecover2Req(STQ* pTq, int64_t sversion, char* msg, int32_t msgLen) {
-  int32_t                 code;
+  int32_t code = 0;
+
   SStreamRecoverStep2Req* pReq = (SStreamRecoverStep2Req*)msg;
   SStreamTask*            pTask = streamMetaAcquireTask(pTq->pStreamMeta, pReq->taskId);
   if (pTask == NULL) {
@@ -1067,67 +1062,36 @@ int32_t tqProcessDelReq(STQ* pTq, void* pReq, int32_t len, int64_t ver) {
   return 0;
 }
 
-int32_t tqProcessSubmitReq(STQ* pTq, SPackedData submit) {
-#if 0
-  void* pIter = NULL;
-  SStreamDataSubmit2* pSubmit = streamDataSubmitNew(submit, STREAM_INPUT__DATA_SUBMIT);
-  if (pSubmit == NULL) {
-    terrno = TSDB_CODE_OUT_OF_MEMORY;
-    tqError("failed to create data submit for stream since out of memory");
-    saveOffsetForAllTasks(pTq, submit.ver);
-    return -1;
-  }
+int32_t tqProcessSubmitReqForSubscribe(STQ* pTq) {
+  int32_t vgId = TD_VID(pTq->pVnode);
 
-  SArray* pInputQueueFullTasks = taosArrayInit(4, POINTER_BYTES);
+  taosWLockLatch(&pTq->lock);
 
-  while (1) {
-    pIter = taosHashIterate(pTq->pStreamMeta->pTasks, pIter);
-    if (pIter == NULL) {
-      break;
-    }
+  if (taosHashGetSize(pTq->pPushMgr) > 0) {
+    void* pIter = taosHashIterate(pTq->pPushMgr, NULL);
 
-    SStreamTask* pTask = *(SStreamTask**)pIter;
-    if (pTask->taskLevel != TASK_LEVEL__SOURCE) {
-      continue;
-    }
+    while (pIter) {
+      STqHandle* pHandle = *(STqHandle**)pIter;
+      tqDebug("vgId:%d start set submit for pHandle:%p, consumer:0x%" PRIx64, vgId, pHandle, pHandle->consumerId);
 
-    if (pTask->status.taskStatus == TASK_STATUS__RECOVER_PREPARE || pTask->status.taskStatus == TASK_STATUS__WAIT_DOWNSTREAM) {
-      tqDebug("stream task:%d skip push data, not ready for processing, status %d", pTask->id.taskId,
-              pTask->status.taskStatus);
-      continue;
-    }
-
-    // check if offset value exists
-    char key[128] = {0};
-    createStreamTaskOffsetKey(key, pTask->id.streamId, pTask->id.taskId);
-
-    if (tInputQueueIsFull(pTask)) {
-      STqOffset* pOffset = tqOffsetRead(pTq->pOffsetStore, key);
-
-      int64_t ver = submit.ver;
-      if (pOffset == NULL) {
-        doSaveTaskOffset(pTq->pOffsetStore, key, submit.ver);
-      } else {
-        ver = pOffset->val.version;
+      if (ASSERT(pHandle->msg != NULL)) {
+        tqError("pHandle->msg should not be null");
+        break;
+      }else{
+        SRpcMsg msg = {.msgType = TDMT_VND_TMQ_CONSUME, .pCont = pHandle->msg->pCont, .contLen = pHandle->msg->contLen, .info = pHandle->msg->info};
+        tmsgPutToQueue(&pTq->pVnode->msgCb, QUERY_QUEUE, &msg);
+        taosMemoryFree(pHandle->msg);
+        pHandle->msg = NULL;
       }
 
-      tqDebug("s-task:%s input queue is full, discard submit block, ver:%" PRId64, pTask->id.idStr, ver);
-      taosArrayPush(pInputQueueFullTasks, &pTask);
-      continue;
+      pIter = taosHashIterate(pTq->pPushMgr, pIter);
     }
 
-    // check if offset value exists
-    STqOffset* pOffset = tqOffsetRead(pTq->pOffsetStore, key);
-    ASSERT(pOffset == NULL);
-
-    addSubmitBlockNLaunchTask(pTq->pOffsetStore, pTask, pSubmit, key, submit.ver);
+    taosHashClear(pTq->pPushMgr);
   }
 
-  streamDataSubmitDestroy(pSubmit);
-  taosFreeQitem(pSubmit);
-#endif
-
-  tqStartStreamTasks(pTq);
+  // unlock
+  taosWUnLockLatch(&pTq->lock);
   return 0;
 }
 
@@ -1145,9 +1109,6 @@ int32_t tqProcessTaskRunReq(STQ* pTq, SRpcMsg* pMsg) {
   SStreamTask* pTask = streamMetaAcquireTask(pTq->pStreamMeta, taskId);
   if (pTask != NULL) {
     if (pTask->status.taskStatus == TASK_STATUS__NORMAL) {
-      tqDebug("vgId:%d s-task:%s start to process run req", vgId, pTask->id.idStr);
-      streamProcessRunReq(pTask);
-    } else if (pTask->status.taskStatus == TASK_STATUS__RESTORE) {
       tqDebug("vgId:%d s-task:%s start to process block from wal, last chk point:%" PRId64, vgId,
               pTask->id.idStr, pTask->chkInfo.version);
       streamProcessRunReq(pTask);
@@ -1300,21 +1261,22 @@ FAIL:
 int32_t tqCheckLogInWal(STQ* pTq, int64_t sversion) { return sversion <= pTq->walLogLastVer; }
 
 int32_t tqStartStreamTasks(STQ* pTq) {
-  int32_t vgId = TD_VID(pTq->pVnode);
-
+  int32_t      vgId = TD_VID(pTq->pVnode);
   SStreamMeta* pMeta = pTq->pStreamMeta;
+
   taosWLockLatch(&pMeta->lock);
-  int32_t numOfTasks = taosHashGetSize(pTq->pStreamMeta->pTasks);
+
+  int32_t numOfTasks = taosArrayGetSize(pMeta->pTaskList);
   if (numOfTasks == 0) {
     tqInfo("vgId:%d no stream tasks exists", vgId);
     taosWUnLockLatch(&pTq->pStreamMeta->lock);
     return 0;
   }
 
-  pMeta->walScan += 1;
+  pMeta->walScanCounter += 1;
 
-  if (pMeta->walScan > 1) {
-    tqDebug("vgId:%d wal read task has been launched, remain scan times:%d", vgId, pMeta->walScan);
+  if (pMeta->walScanCounter > 1) {
+    tqDebug("vgId:%d wal read task has been launched, remain scan times:%d", vgId, pMeta->walScanCounter);
     taosWUnLockLatch(&pTq->pStreamMeta->lock);
     return 0;
   }
diff --git a/source/dnode/vnode/src/tq/tqMeta.c b/source/dnode/vnode/src/tq/tqMeta.c
index cd8cefb307..f3ecaa08f6 100644
--- a/source/dnode/vnode/src/tq/tqMeta.c
+++ b/source/dnode/vnode/src/tq/tqMeta.c
@@ -328,7 +328,7 @@ int32_t tqMetaRestoreHandle(STQ* pTq) {
       }
     } else if (handle.execHandle.subType == TOPIC_SUB_TYPE__DB) {
       handle.pWalReader = walOpenReader(pTq->pVnode->pWal, NULL);
-      handle.execHandle.pTqReader = tqOpenReader(pTq->pVnode);
+      handle.execHandle.pTqReader = tqReaderOpen(pTq->pVnode);
 
       buildSnapContext(reader.meta, reader.version, 0, handle.execHandle.subType, handle.fetchMeta,
                        (SSnapContext**)(&reader.sContext));
@@ -343,7 +343,7 @@ int32_t tqMetaRestoreHandle(STQ* pTq) {
         int64_t tbUid = *(int64_t*)taosArrayGet(tbUidList, i);
         tqDebug("vgId:%d, idx %d, uid:%" PRId64, vgId, i, tbUid);
       }
-      handle.execHandle.pTqReader = tqOpenReader(pTq->pVnode);
+      handle.execHandle.pTqReader = tqReaderOpen(pTq->pVnode);
       tqReaderSetTbUidList(handle.execHandle.pTqReader, tbUidList);
       taosArrayDestroy(tbUidList);
 
diff --git a/source/dnode/vnode/src/tq/tqOffset.c b/source/dnode/vnode/src/tq/tqOffset.c
index e8051a1406..34e93cec2d 100644
--- a/source/dnode/vnode/src/tq/tqOffset.c
+++ b/source/dnode/vnode/src/tq/tqOffset.c
@@ -31,57 +31,67 @@ char* tqOffsetBuildFName(const char* path, int32_t fVer) {
 
 int32_t tqOffsetRestoreFromFile(STqOffsetStore* pStore, const char* fname) {
   TdFilePtr pFile = taosOpenFile(fname, TD_FILE_READ);
-  if (pFile != NULL) {
-    STqOffsetHead head = {0};
-    int64_t       code;
+  if (pFile == NULL) {
+    return TSDB_CODE_SUCCESS;
+  }
 
-    while (1) {
-      if ((code = taosReadFile(pFile, &head, sizeof(STqOffsetHead))) != sizeof(STqOffsetHead)) {
-        if (code == 0) {
-          break;
-        } else {
-          return -1;
-        }
-      }
-      int32_t size = htonl(head.size);
-      void*   memBuf = taosMemoryCalloc(1, size);
-      if (memBuf == NULL) {
+  int32_t vgId = TD_VID(pStore->pTq->pVnode);
+  int64_t code = 0;
+
+  STqOffsetHead head = {0};
+
+  while (1) {
+    if ((code = taosReadFile(pFile, &head, sizeof(STqOffsetHead))) != sizeof(STqOffsetHead)) {
+      if (code == 0) {
+        break;
+      } else {
         return -1;
       }
-      if ((code = taosReadFile(pFile, memBuf, size)) != size) {
-        taosMemoryFree(memBuf);
-        return -1;
-      }
-      STqOffset offset;
-      SDecoder  decoder;
-      tDecoderInit(&decoder, memBuf, size);
-      if (tDecodeSTqOffset(&decoder, &offset) < 0) {
-        taosMemoryFree(memBuf);
-        tDecoderClear(&decoder);
-        return -1;
-      }
-
-      tDecoderClear(&decoder);
-      if (taosHashPut(pStore->pHash, offset.subKey, strlen(offset.subKey), &offset, sizeof(STqOffset)) < 0) {
-        return -1;
-      }
-
-      if (offset.val.type == TMQ_OFFSET__LOG) {
-        STqHandle* pHandle = taosHashGet(pStore->pTq->pHandle, offset.subKey, strlen(offset.subKey));
-        if (pHandle) {
-          if (walRefVer(pHandle->pRef, offset.val.version) < 0) {
-            tqError("vgId: %d, tq handle %s ref ver %" PRId64 "error", pStore->pTq->pVnode->config.vgId,
-                    pHandle->subKey, offset.val.version);
-          }
-        }
-      }
-
-      taosMemoryFree(memBuf);
     }
 
-    taosCloseFile(&pFile);
+    int32_t size = htonl(head.size);
+    void*   pMemBuf = taosMemoryCalloc(1, size);
+    if (pMemBuf == NULL) {
+      tqError("vgId:%d failed to restore offset from file, since out of memory, malloc size:%d", vgId, size);
+      terrno = TSDB_CODE_OUT_OF_MEMORY;
+      return -1;
+    }
+
+    if ((code = taosReadFile(pFile, pMemBuf, size)) != size) {
+      taosMemoryFree(pMemBuf);
+      return -1;
+    }
+
+    STqOffset offset;
+    SDecoder  decoder;
+    tDecoderInit(&decoder, pMemBuf, size);
+    if (tDecodeSTqOffset(&decoder, &offset) < 0) {
+      taosMemoryFree(pMemBuf);
+      tDecoderClear(&decoder);
+      return code;
+    }
+
+    tDecoderClear(&decoder);
+    if (taosHashPut(pStore->pHash, offset.subKey, strlen(offset.subKey), &offset, sizeof(STqOffset)) < 0) {
+      return -1;
+    }
+
+    // todo remove this
+    if (offset.val.type == TMQ_OFFSET__LOG) {
+      STqHandle* pHandle = taosHashGet(pStore->pTq->pHandle, offset.subKey, strlen(offset.subKey));
+      if (pHandle) {
+        if (walRefVer(pHandle->pRef, offset.val.version) < 0) {
+//          tqError("vgId: %d, tq handle %s ref ver %" PRId64 "error", pStore->pTq->pVnode->config.vgId, pHandle->subKey,
+//                  offset.val.version);
+        }
+      }
+    }
+
+    taosMemoryFree(pMemBuf);
   }
-  return 0;
+
+  taosCloseFile(&pFile);
+  return TSDB_CODE_SUCCESS;
 }
 
 STqOffsetStore* tqOffsetOpen(STQ* pTq) {
@@ -89,6 +99,7 @@ STqOffsetStore* tqOffsetOpen(STQ* pTq) {
   if (pStore == NULL) {
     return NULL;
   }
+
   pStore->pTq = pTq;
   pStore->needCommit = 0;
   pTq->pOffsetStore = pStore;
@@ -98,12 +109,14 @@ STqOffsetStore* tqOffsetOpen(STQ* pTq) {
     taosMemoryFree(pStore);
     return NULL;
   }
+
   char* fname = tqOffsetBuildFName(pStore->pTq->path, 0);
   if (tqOffsetRestoreFromFile(pStore, fname) < 0) {
     taosMemoryFree(fname);
     taosMemoryFree(pStore);
     return NULL;
   }
+
   taosMemoryFree(fname);
   return pStore;
 }
diff --git a/source/dnode/vnode/src/tq/tqPush.c b/source/dnode/vnode/src/tq/tqPush.c
index 7a1a6b7454..950c5ea96b 100644
--- a/source/dnode/vnode/src/tq/tqPush.c
+++ b/source/dnode/vnode/src/tq/tqPush.c
@@ -16,342 +16,26 @@
 #include "tq.h"
 #include "vnd.h"
 
-#if 0
-void tqTmrRspFunc(void* param, void* tmrId) {
-  STqHandle* pHandle = (STqHandle*)param;
-  atomic_store_8(&pHandle->pushHandle.tmrStopped, 1);
-}
-
-static int32_t tqLoopExecFromQueue(STQ* pTq, STqHandle* pHandle, SStreamDataSubmit** ppSubmit, SMqDataRsp* pRsp) {
-  SStreamDataSubmit* pSubmit = *ppSubmit;
-  while (pSubmit != NULL) {
-    if (tqLogScanExec(pTq, &pHandle->execHandle, pSubmit->data, pRsp, 0) < 0) {
-    }
-    // update processed
-    atomic_store_64(&pHandle->pushHandle.processedVer, pSubmit->ver);
-    streamQueueProcessSuccess(&pHandle->pushHandle.inputQ);
-    streamDataSubmitDestroy(pSubmit);
-    if (pRsp->blockNum > 0) {
-      *ppSubmit = pSubmit;
-      return 0;
-    } else {
-      pSubmit = streamQueueNextItem(&pHandle->pushHandle.inputQ);
-    }
-  }
-  *ppSubmit = pSubmit;
-  return -1;
-}
-
-int32_t tqExecFromInputQ(STQ* pTq, STqHandle* pHandle) {
-  SMqDataRsp rsp = {0};
-  // 1. guard and set status executing
-  int8_t execStatus = atomic_val_compare_exchange_8(&pHandle->pushHandle.execStatus, TASK_EXEC_STATUS__IDLE,
-                                                    TASK_EXEC_STATUS__EXECUTING);
-  if (execStatus == TASK_EXEC_STATUS__IDLE) {
-    SStreamDataSubmit* pSubmit = NULL;
-    // 2. check processedVer
-    // 2.1. if not missed, get msg from queue
-    // 2.2. if missed, scan wal
-    pSubmit = streamQueueNextItem(&pHandle->pushHandle.inputQ);
-    while (pHandle->pushHandle.processedVer <= pSubmit->ver) {
-      // read from wal
-    }
-    while (pHandle->pushHandle.processedVer > pSubmit->ver + 1) {
-      streamQueueProcessSuccess(&pHandle->pushHandle.inputQ);
-      streamDataSubmitDestroy(pSubmit);
-      pSubmit = streamQueueNextItem(&pHandle->pushHandle.inputQ);
-      if (pSubmit == NULL) break;
-    }
-    // 3. exec, after each success, update processed ver
-    // first run
-    if (tqLoopExecFromQueue(pTq, pHandle, &pSubmit, &rsp) == 0) {
-      goto SEND_RSP;
-    }
-    // set exec status closing
-    atomic_store_8(&pHandle->pushHandle.execStatus, TASK_EXEC_STATUS__CLOSING);
-    // second run
-    if (tqLoopExecFromQueue(pTq, pHandle, &pSubmit, &rsp) == 0) {
-      goto SEND_RSP;
-    }
-    // set exec status idle
-    atomic_store_8(&pHandle->pushHandle.execStatus, TASK_EXEC_STATUS__IDLE);
-  }
-SEND_RSP:
-  // 4. if get result
-  // 4.1 set exec input status blocked and exec status idle
-  atomic_store_8(&pHandle->pushHandle.execStatus, TASK_EXEC_STATUS__IDLE);
-  // 4.2 rpc send
-  rsp.rspOffset = pHandle->pushHandle.processedVer;
-  /*if (tqSendPollRsp(pTq, pMsg, pReq, &rsp) < 0) {*/
-  /*return -1;*/
-  /*}*/
-  // 4.3 clear rpc info
-  memset(&pHandle->pushHandle.rpcInfo, 0, sizeof(SRpcHandleInfo));
-  return 0;
-}
-
-int32_t tqOpenPushHandle(STQ* pTq, STqHandle* pHandle) {
-  memset(&pHandle->pushHandle, 0, sizeof(STqPushHandle));
-  pHandle->pushHandle.inputQ.queue = taosOpenQueue();
-  pHandle->pushHandle.inputQ.qall = taosAllocateQall();
-  if (pHandle->pushHandle.inputQ.queue == NULL || pHandle->pushHandle.inputQ.qall == NULL) {
-    if (pHandle->pushHandle.inputQ.queue) {
-      taosCloseQueue(pHandle->pushHandle.inputQ.queue);
-    }
-    if (pHandle->pushHandle.inputQ.qall) {
-      taosFreeQall(pHandle->pushHandle.inputQ.qall);
-    }
-    return -1;
-  }
-  return 0;
-}
-
-int32_t tqPreparePush(STQ* pTq, STqHandle* pHandle, int64_t reqId, const SRpcHandleInfo* pInfo, int64_t processedVer,
-                      int64_t timeout) {
-  memcpy(&pHandle->pushHandle.rpcInfo, pInfo, sizeof(SRpcHandleInfo));
-  atomic_store_64(&pHandle->pushHandle.reqId, reqId);
-  atomic_store_64(&pHandle->pushHandle.processedVer, processedVer);
-  atomic_store_8(&pHandle->pushHandle.inputStatus, TASK_INPUT_STATUS__NORMAL);
-  atomic_store_8(&pHandle->pushHandle.tmrStopped, 0);
-  taosTmrReset(tqTmrRspFunc, (int32_t)timeout, pHandle, tqMgmt.timer, &pHandle->pushHandle.timerId);
-  return 0;
-}
-
-int32_t tqEnqueue(STqHandle* pHandle, SStreamDataSubmit* pSubmit) {
-  int8_t inputStatus = atomic_load_8(&pHandle->pushHandle.inputStatus);
-  if (inputStatus == TASK_INPUT_STATUS__NORMAL) {
-    SStreamDataSubmit* pSubmitClone = streamSubmitBlockClone(pSubmit);
-    if (pSubmitClone == NULL) {
-      return -1;
-    }
-    taosWriteQitem(pHandle->pushHandle.inputQ.queue, pSubmitClone);
-    return 0;
-  }
-  return -1;
-}
-
-int32_t tqSendExecReq(STQ* pTq, STqHandle* pHandle) {
-  //
-  return 0;
-}
-
-int32_t tqPushMsgNew(STQ* pTq, void* msg, int32_t msgLen, tmsg_t msgType, int64_t ver, SRpcHandleInfo handleInfo) {
-  if (msgType != TDMT_VND_SUBMIT) return 0;
-  void*       pIter = NULL;
-  STqHandle*  pHandle = NULL;
-  SSubmitReq* pReq = (SSubmitReq*)msg;
-  int32_t     workerId = 4;
-  int64_t     fetchOffset = ver;
-
-  while (1) {
-    pIter = taosHashIterate(pTq->pushMgr, pIter);
-    if (pIter == NULL) break;
-    pHandle = *(STqHandle**)pIter;
-
-    taosWLockLatch(&pHandle->pushHandle.lock);
-
-    SMqDataRsp rsp = {0};
-    rsp.reqOffset = pHandle->pushHandle.reqOffset;
-    rsp.blockData = taosArrayInit(0, sizeof(void*));
-    rsp.blockDataLen = taosArrayInit(0, sizeof(int32_t));
-
-    if (msgType == TDMT_VND_SUBMIT) {
-      tqLogScanExec(pTq, &pHandle->execHandle, pReq, &rsp, workerId);
-    } else {
-      tqError("tq push unexpected msg type %d", msgType);
-    }
-
-    if (rsp.blockNum == 0) {
-      taosWUnLockLatch(&pHandle->pushHandle.lock);
-      continue;
-    }
-
-    rsp.rspOffset = fetchOffset;
-
-    int32_t tlen = sizeof(SMqRspHead) + tEncodeSMqDataBlkRsp(NULL, &rsp);
-    void*   buf = rpcMallocCont(tlen);
-    if (buf == NULL) {
-      // todo free
-      return -1;
-    }
-
-    ((SMqRspHead*)buf)->mqMsgType = TMQ_MSG_TYPE__POLL_RSP;
-    ((SMqRspHead*)buf)->epoch = pHandle->pushHandle.epoch;
-    ((SMqRspHead*)buf)->consumerId = pHandle->pushHandle.consumerId;
-
-    void* abuf = POINTER_SHIFT(buf, sizeof(SMqRspHead));
-    tEncodeSMqDataBlkRsp(&abuf, &rsp);
-
-    SRpcMsg resp = {
-        .info = pHandle->pushHandle.rpcInfo,
-        .pCont = buf,
-        .contLen = tlen,
-        .code = 0,
-    };
-    tmsgSendRsp(&resp);
-
-    memset(&pHandle->pushHandle.rpcInfo, 0, sizeof(SRpcHandleInfo));
-    taosWUnLockLatch(&pHandle->pushHandle.lock);
-
-    tqDebug("vgId:%d offset %" PRId64 " from consumer:%" PRId64 ", (epoch %d) send rsp, block num: %d, req:%" PRId64 ", rsp:%" PRId64,
-            TD_VID(pTq->pVnode), fetchOffset, pHandle->pushHandle.consumerId, pHandle->pushHandle.epoch, rsp.blockNum,
-            rsp.reqOffset, rsp.rspOffset);
-
-    // TODO destroy
-    taosArrayDestroy(rsp.blockData);
-    taosArrayDestroy(rsp.blockDataLen);
-  }
-
-  return 0;
-}
-#endif
-
-typedef struct {
-  void*   pKey;
-  int64_t keyLen;
-} SItem;
-
-static void recordPushedEntry(SArray* cachedKey, void* pIter);
-static void doRemovePushedEntry(SArray* pCachedKeys, STQ* pTq);
-
-static void freeItem(void* param) {
-  SItem* p = (SItem*)param;
-  taosMemoryFree(p->pKey);
-}
-
-static void doPushDataForEntry(void* pIter, STqExecHandle* pExec, STQ* pTq, int64_t ver, int32_t vgId, char* pData,
-                               int32_t dataLen, SArray* pCachedKey) {
-  STqPushEntry* pPushEntry = *(STqPushEntry**)pIter;
-
-  SMqDataRsp* pRsp = pPushEntry->pDataRsp;
-  if (pRsp->reqOffset.version >= ver) {
-    tqDebug("vgId:%d, push entry req version %" PRId64 ", while push version %" PRId64 ", skip", vgId,
-            pRsp->reqOffset.version, ver);
-    return;
-  }
-
-  qTaskInfo_t pTaskInfo = pExec->task;
-
-  // prepare scan mem data
-  SPackedData submit = {.msgStr = pData, .msgLen = dataLen, .ver = ver};
-
-  if (qStreamSetScanMemData(pTaskInfo, submit) != 0) {
-    return;
-  }
-  qStreamSetOpen(pTaskInfo);
-  // here start to scan submit block to extract the subscribed data
-  int32_t totalRows = 0;
-
-  while (1) {
-    SSDataBlock* pDataBlock = NULL;
-    uint64_t     ts = 0;
-    if (qExecTask(pTaskInfo, &pDataBlock, &ts) < 0) {
-      tqDebug("vgId:%d, tq exec error since %s", vgId, terrstr());
-    }
-
-    if (pDataBlock == NULL) {
-      break;
-    }
-
-    tqAddBlockDataToRsp(pDataBlock, pRsp, pExec->numOfCols, pTq->pVnode->config.tsdbCfg.precision);
-    pRsp->blockNum++;
-    totalRows += pDataBlock->info.rows;
-  }
-
-  tqDebug("vgId:%d, tq handle push, subkey:%s, block num:%d, rows:%d", vgId, pPushEntry->subKey, pRsp->blockNum,
-          totalRows);
-
-  if (pRsp->blockNum > 0) {
-    tqOffsetResetToLog(&pRsp->rspOffset, ver);
-    tqPushDataRsp(pTq, pPushEntry);
-    recordPushedEntry(pCachedKey, pIter);
-  }
-}
-
 int32_t tqPushMsg(STQ* pTq, void* msg, int32_t msgLen, tmsg_t msgType, int64_t ver) {
-  void*   pReq = POINTER_SHIFT(msg, sizeof(SSubmitReq2Msg));
-  int32_t len = msgLen - sizeof(SSubmitReq2Msg);
-  int32_t vgId = TD_VID(pTq->pVnode);
 
   if (msgType == TDMT_VND_SUBMIT) {
-    // lock push mgr to avoid potential msg lost
-    taosWLockLatch(&pTq->lock);
-
-    int32_t numOfRegisteredPush = taosHashGetSize(pTq->pPushMgr);
-    if (numOfRegisteredPush > 0) {
-      tqDebug("vgId:%d tq push msg version:%" PRId64 " type:%s, head:%p, body:%p len:%d, numOfPushed consumers:%d",
-              vgId, ver, TMSG_INFO(msgType), msg, pReq, len, numOfRegisteredPush);
-
-      void* data = taosMemoryMalloc(len);
-      if (data == NULL) {
-        terrno = TSDB_CODE_OUT_OF_MEMORY;
-        tqError("failed to copy data for stream since out of memory, vgId:%d", vgId);
-        taosWUnLockLatch(&pTq->lock);
-        return -1;
-      }
-
-      memcpy(data, pReq, len);
-
-      SArray* cachedKey = taosArrayInit(0, sizeof(SItem));
-      void*   pIter = NULL;
-
-      while (1) {
-        pIter = taosHashIterate(pTq->pPushMgr, pIter);
-        if (pIter == NULL) {
-          break;
-        }
-
-        STqPushEntry* pPushEntry = *(STqPushEntry**)pIter;
-
-        STqHandle* pHandle = taosHashGet(pTq->pHandle, pPushEntry->subKey, strlen(pPushEntry->subKey));
-        if (pHandle == NULL) {
-          tqDebug("vgId:%d, failed to find handle %s in pushing data to consumer, ignore", pTq->pVnode->config.vgId,
-                  pPushEntry->subKey);
-          continue;
-        }
-
-        STqExecHandle* pExec = &pHandle->execHandle;
-        doPushDataForEntry(pIter, pExec, pTq, ver, vgId, data, len, cachedKey);
-      }
-
-      doRemovePushedEntry(cachedKey, pTq);
-      taosArrayDestroyEx(cachedKey, freeItem);
-      taosMemoryFree(data);
-    }
-
-    // unlock
-    taosWUnLockLatch(&pTq->lock);
+    tqProcessSubmitReqForSubscribe(pTq);
   }
 
-  tqDebug("handle submit, restore:%d, size:%d", pTq->pVnode->restored, (int)taosHashGetSize(pTq->pStreamMeta->pTasks));
+  int32_t numOfTasks = streamMetaGetNumOfTasks(pTq->pStreamMeta);
+  tqDebug("handle submit, restore:%d, size:%d", pTq->pVnode->restored, numOfTasks);
 
   // push data for stream processing:
   // 1. the vnode has already been restored.
   // 2. the vnode should be the leader.
   // 3. the stream is not suspended yet.
   if (!tsDisableStream && vnodeIsRoleLeader(pTq->pVnode) && pTq->pVnode->restored) {
-    if (taosHashGetSize(pTq->pStreamMeta->pTasks) == 0) {
+    if (numOfTasks == 0) {
       return 0;
     }
 
     if (msgType == TDMT_VND_SUBMIT) {
-#if 0
-      void* data = taosMemoryMalloc(len);
-      if (data == NULL) {
-        // todo: for all stream in this vnode, keep this offset in the offset files, and wait for a moment, and then retry
-        terrno = TSDB_CODE_OUT_OF_MEMORY;
-        tqError("vgId:%d, failed to copy submit data for stream processing, since out of memory", vgId);
-        return -1;
-      }
-
-      memcpy(data, pReq, len);
-      SPackedData submit = {.msgStr = data, .msgLen = len, .ver = ver};
-
-      tqDebug("vgId:%d tq copy submit msg:%p len:%d ver:%" PRId64 " from %p for stream", vgId, data, len, ver, pReq);
-      tqProcessSubmitReq(pTq, submit);
-#endif
-      SPackedData submit = {0};
-      tqProcessSubmitReq(pTq, submit);
+      tqStartStreamTasks(pTq);
     }
 
     if (msgType == TDMT_VND_DELETE) {
@@ -362,83 +46,42 @@ int32_t tqPushMsg(STQ* pTq, void* msg, int32_t msgLen, tmsg_t msgType, int64_t v
   return 0;
 }
 
-int32_t tqRegisterPushHandle(STQ* pTq, void* pHandle, const SMqPollReq* pRequest, SRpcMsg* pRpcMsg, SMqDataRsp* pDataRsp,
-                            int32_t type) {
-  uint64_t   consumerId = pRequest->consumerId;
+int32_t tqRegisterPushHandle(STQ* pTq, void* handle, SRpcMsg* pMsg) {
   int32_t    vgId = TD_VID(pTq->pVnode);
-  STqHandle* pTqHandle = pHandle;
+  STqHandle* pHandle = (STqHandle*)handle;
 
-  STqPushEntry* pPushEntry = taosMemoryCalloc(1, sizeof(STqPushEntry));
-  if (pPushEntry == NULL) {
-    tqDebug("tmq poll: consumer:0x%" PRIx64 ", vgId:%d failed to malloc, size:%d", consumerId, vgId,
-            (int32_t)sizeof(STqPushEntry));
-    terrno = TSDB_CODE_OUT_OF_MEMORY;
-    return -1;
+  if (pHandle->msg == NULL) {
+    pHandle->msg = taosMemoryCalloc(1, sizeof(SRpcMsg));
+    memcpy(pHandle->msg, pMsg, sizeof(SRpcMsg));
+    pHandle->msg->pCont = rpcMallocCont(pMsg->contLen);
+  } else {
+    void* tmp = pHandle->msg->pCont;
+    memcpy(pHandle->msg, pMsg, sizeof(SRpcMsg));
+    pHandle->msg->pCont = tmp;
   }
 
-  pPushEntry->info = pRpcMsg->info;
-  memcpy(pPushEntry->subKey, pTqHandle->subKey, TSDB_SUBSCRIBE_KEY_LEN);
-
-  if (type == TMQ_MSG_TYPE__TAOSX_RSP) {
-    pPushEntry->pDataRsp = taosMemoryCalloc(1, sizeof(STaosxRsp));
-    memcpy(pPushEntry->pDataRsp, pDataRsp, sizeof(STaosxRsp));
-  } else if (type == TMQ_MSG_TYPE__POLL_RSP) {
-    pPushEntry->pDataRsp = taosMemoryCalloc(1, sizeof(SMqDataRsp));
-    memcpy(pPushEntry->pDataRsp, pDataRsp, sizeof(SMqDataRsp));
-  }
-
-  SMqRspHead* pHead = &pPushEntry->pDataRsp->head;
-  pHead->consumerId = consumerId;
-  pHead->epoch = pRequest->epoch;
-  pHead->mqMsgType = type;
-
-  taosHashPut(pTq->pPushMgr, pTqHandle->subKey, strlen(pTqHandle->subKey), &pPushEntry, sizeof(void*));
-
-  tqDebug("tmq poll: consumer:0x%" PRIx64 ", subkey %s offset:%" PRId64 ", vgId:%d save handle to push mgr, total:%d",
-          consumerId, pTqHandle->subKey, pDataRsp->reqOffset.version, vgId, taosHashGetSize(pTq->pPushMgr));
+  memcpy(pHandle->msg->pCont, pMsg->pCont, pMsg->contLen);
+  pHandle->msg->contLen = pMsg->contLen;
+  int32_t ret = taosHashPut(pTq->pPushMgr, pHandle->subKey, strlen(pHandle->subKey), &pHandle, POINTER_BYTES);
+  tqDebug("vgId:%d data is over, ret:%d, consumerId:0x%" PRIx64 ", register to pHandle:%p, pCont:%p, len:%d", vgId, ret,
+          pHandle->consumerId, pHandle, pHandle->msg->pCont, pHandle->msg->contLen);
   return 0;
 }
 
-int32_t tqUnregisterPushHandle(STQ* pTq, const char* pKey, int32_t keyLen, uint64_t consumerId, bool rspConsumer) {
-  int32_t        vgId = TD_VID(pTq->pVnode);
-  STqPushEntry** pEntry = taosHashGet(pTq->pPushMgr, pKey, keyLen);
+int32_t tqUnregisterPushHandle(STQ* pTq, void *handle) {
+  STqHandle *pHandle = (STqHandle*)handle;
+  int32_t    vgId = TD_VID(pTq->pVnode);
 
-  if (pEntry != NULL) {
-    uint64_t cId = (*pEntry)->pDataRsp->head.consumerId;
-    ASSERT(consumerId == cId);
+  int32_t ret = taosHashRemove(pTq->pPushMgr, pHandle->subKey, strlen(pHandle->subKey));
+  tqError("vgId:%d remove pHandle:%p,ret:%d consumer Id:0x%" PRIx64, vgId, pHandle, ret, pHandle->consumerId);
 
-    tqDebug("tmq poll: consumer:0x%" PRIx64 ", subkey %s vgId:%d remove from push mgr, remains:%d", consumerId,
-            (*pEntry)->subKey, vgId, taosHashGetSize(pTq->pPushMgr) - 1);
+  if(pHandle->msg != NULL) {
+    tqPushDataRsp(pTq, pHandle);
 
-    if (rspConsumer) {  // rsp the old consumer with empty block.
-      tqPushDataRsp(pTq, *pEntry);
-    }
-
-    taosHashRemove(pTq->pPushMgr, pKey, keyLen);
+    rpcFreeCont(pHandle->msg->pCont);
+    taosMemoryFree(pHandle->msg);
+    pHandle->msg = NULL;
   }
 
   return 0;
 }
-
-void recordPushedEntry(SArray* cachedKey, void* pIter) {
-  size_t kLen = 0;
-  void*  key = taosHashGetKey(pIter, &kLen);
-  SItem  item = {.pKey = strndup(key, kLen), .keyLen = kLen};
-  taosArrayPush(cachedKey, &item);
-}
-
-void doRemovePushedEntry(SArray* pCachedKeys, STQ* pTq) {
-  int32_t vgId = TD_VID(pTq->pVnode);
-  int32_t numOfKeys = (int32_t)taosArrayGetSize(pCachedKeys);
-
-  for (int32_t i = 0; i < numOfKeys; i++) {
-    SItem* pItem = taosArrayGet(pCachedKeys, i);
-    if (taosHashRemove(pTq->pPushMgr, pItem->pKey, pItem->keyLen) != 0) {
-      tqError("vgId:%d, tq push hash remove key error, key: %s", vgId, (char*)pItem->pKey);
-    }
-  }
-
-  if (numOfKeys > 0) {
-    tqDebug("vgId:%d, pushed %d items and remain:%d", vgId, numOfKeys, (int32_t)taosHashGetSize(pTq->pPushMgr));
-  }
-}
diff --git a/source/dnode/vnode/src/tq/tqRead.c b/source/dnode/vnode/src/tq/tqRead.c
index 2cda12c0e1..1fbdb25528 100644
--- a/source/dnode/vnode/src/tq/tqRead.c
+++ b/source/dnode/vnode/src/tq/tqRead.c
@@ -13,6 +13,7 @@
  * along with this program. If not, see .
  */
 
+#include "tmsg.h"
 #include "tq.h"
 
 bool isValValidForTable(STqHandle* pHandle, SWalCont* pHead) {
@@ -249,7 +250,7 @@ END:
   return code;
 }
 
-STqReader* tqOpenReader(SVnode* pVnode) {
+STqReader* tqReaderOpen(SVnode* pVnode) {
   STqReader* pReader = taosMemoryCalloc(1, sizeof(STqReader));
   if (pReader == NULL) {
     return NULL;
@@ -265,9 +266,9 @@ STqReader* tqOpenReader(SVnode* pVnode) {
   pReader->pColIdList = NULL;
   pReader->cachedSchemaVer = 0;
   pReader->cachedSchemaSuid = 0;
-  pReader->pSchema = NULL;
   pReader->pSchemaWrapper = NULL;
   pReader->tbIdHash = NULL;
+  pReader->pResBlock = createDataBlock();
   return pReader;
 }
 
@@ -276,19 +277,19 @@ void tqCloseReader(STqReader* pReader) {
   if (pReader->pWalReader) {
     walCloseReader(pReader->pWalReader);
   }
-  // free cached schema
-  if (pReader->pSchema) {
-    taosMemoryFree(pReader->pSchema);
-  }
+
   if (pReader->pSchemaWrapper) {
-    tDeleteSSchemaWrapper(pReader->pSchemaWrapper);
+    tDeleteSchemaWrapper(pReader->pSchemaWrapper);
   }
+
   if (pReader->pColIdList) {
     taosArrayDestroy(pReader->pColIdList);
   }
+
   // free hash
+  blockDataDestroy(pReader->pResBlock);
   taosHashCleanup(pReader->tbIdHash);
-  tDestroySSubmitReq2(&pReader->submit, TSDB_MSG_FLG_DECODE);
+  tDestroySubmitReq(&pReader->submit, TSDB_MSG_FLG_DECODE);
   taosMemoryFree(pReader);
 }
 
@@ -322,60 +323,111 @@ int32_t extractSubmitMsgFromWal(SWalReader* pReader, SPackedData* pPackedData) {
   return 0;
 }
 
-void tqNextBlock(STqReader* pReader, SFetchRet* ret) {
-  while (1) {
-    if (pReader->msg2.msgStr == NULL) {
-      if (walNextValidMsg(pReader->pWalReader) < 0) {
-        ret->fetchType = FETCH_TYPE__NONE;
-        return;
+// todo ignore the error in wal?
+int32_t tqNextBlockInWal(STqReader* pReader) {
+  SWalReader* pWalReader = pReader->pWalReader;
+
+  while(1) {
+    SArray* pBlockList = pReader->submit.aSubmitTbData;
+    if (pBlockList == NULL || pReader->nextBlk >= taosArrayGetSize(pBlockList)) {
+
+      // try next message in wal file
+      // todo always retry to avoid read failure caused by wal file deletion
+      if (walNextValidMsg(pWalReader) < 0) {
+        return FETCH_TYPE__NONE;
       }
 
-      void*   pBody = POINTER_SHIFT(pReader->pWalReader->pHead->head.body, sizeof(SSubmitReq2Msg));
-      int32_t bodyLen = pReader->pWalReader->pHead->head.bodyLen - sizeof(SSubmitReq2Msg);
-      int64_t ver = pReader->pWalReader->pHead->head.version;
+      void*   pBody = POINTER_SHIFT(pWalReader->pHead->head.body, sizeof(SSubmitReq2Msg));
+      int32_t bodyLen = pWalReader->pHead->head.bodyLen - sizeof(SSubmitReq2Msg);
+      int64_t ver = pWalReader->pHead->head.version;
 
-      tqReaderSetSubmitMsg(pReader, pBody, bodyLen, ver);
-    }
+      SDecoder decoder = {0};
+      tDecoderInit(&decoder, pBody, bodyLen);
 
-    while (tqNextDataBlock(pReader)) {
-      memset(&ret->data, 0, sizeof(SSDataBlock));
-      int32_t code = tqRetrieveDataBlock2(&ret->data, pReader, NULL);
-      if (code != 0 || ret->data.info.rows == 0) {
-        continue;
+      {
+        int32_t nSubmitTbData = taosArrayGetSize(pReader->submit.aSubmitTbData);
+        for (int32_t i = 0; i < nSubmitTbData; i++) {
+          SSubmitTbData* pData = taosArrayGet(pReader->submit.aSubmitTbData, i);
+          if (pData->pCreateTbReq != NULL) {
+            taosArrayDestroy(pData->pCreateTbReq->ctb.tagName);
+            taosMemoryFreeClear(pData->pCreateTbReq);
+          }
+          pData->aRowP = taosArrayDestroy(pData->aRowP);
+        }
+        pReader->submit.aSubmitTbData = taosArrayDestroy(pReader->submit.aSubmitTbData);
       }
 
-      ret->fetchType = FETCH_TYPE__DATA;
-      return;
+      if (tDecodeSubmitReq(&decoder, &pReader->submit) < 0) {
+        tDecoderClear(&decoder);
+        tqError("decode wal file error, msgLen:%d, ver:%"PRId64, bodyLen, ver);
+        return FETCH_TYPE__NONE;
+      }
+
+      tDecoderClear(&decoder);
+      pReader->nextBlk = 0;
     }
+
+    size_t numOfBlocks = taosArrayGetSize(pReader->submit.aSubmitTbData);
+    while (pReader->nextBlk < numOfBlocks) {
+      tqDebug("tq reader next data block %p, %d %" PRId64 " %d", pReader->msg.msgStr, pReader->msg.msgLen,
+              pReader->msg.ver, pReader->nextBlk);
+
+      SSubmitTbData* pSubmitTbData = taosArrayGet(pReader->submit.aSubmitTbData, pReader->nextBlk);
+
+      if (pReader->tbIdHash == NULL) {
+        int32_t code = tqRetrieveDataBlock(pReader, NULL);
+        if (code == TSDB_CODE_SUCCESS && pReader->pResBlock->info.rows > 0) {
+          return FETCH_TYPE__DATA;
+        }
+      }
+
+      void* ret = taosHashGet(pReader->tbIdHash, &pSubmitTbData->uid, sizeof(int64_t));
+      if (ret != NULL) {
+        tqDebug("tq reader return submit block, uid:%"PRId64", ver:%"PRId64, pSubmitTbData->uid, pReader->msg.ver);
+
+        int32_t code = tqRetrieveDataBlock(pReader, NULL);
+        if (code == TSDB_CODE_SUCCESS && pReader->pResBlock->info.rows > 0) {
+          return FETCH_TYPE__DATA;
+        }
+      } else {
+        pReader->nextBlk += 1;
+        tqDebug("tq reader discard submit block, uid:%"PRId64", continue", pSubmitTbData->uid);
+      }
+    }
+
+    tDestroySubmitReq(&pReader->submit, TSDB_MSG_FLG_DECODE);
+    pReader->msg.msgStr = NULL;
   }
 }
 
 int32_t tqReaderSetSubmitMsg(STqReader* pReader, void* msgStr, int32_t msgLen, int64_t ver) {
-  pReader->msg2.msgStr = msgStr;
-  pReader->msg2.msgLen = msgLen;
-  pReader->msg2.ver = ver;
+  pReader->msg.msgStr = msgStr;
+  pReader->msg.msgLen = msgLen;
+  pReader->msg.ver = ver;
 
   tqDebug("tq reader set msg %p %d", msgStr, msgLen);
   SDecoder decoder;
-  tDecoderInit(&decoder, pReader->msg2.msgStr, pReader->msg2.msgLen);
-  if (tDecodeSSubmitReq2(&decoder, &pReader->submit) < 0) {
+
+  tDecoderInit(&decoder, pReader->msg.msgStr, pReader->msg.msgLen);
+  if (tDecodeSubmitReq(&decoder, &pReader->submit) < 0) {
     tDecoderClear(&decoder);
     tqError("DecodeSSubmitReq2 error, msgLen:%d, ver:%"PRId64, msgLen, ver);
     return -1;
   }
+
   tDecoderClear(&decoder);
   return 0;
 }
 
-bool tqNextDataBlock(STqReader* pReader) {
-  if (pReader->msg2.msgStr == NULL) {
+bool tqNextBlockImpl(STqReader* pReader) {
+  if (pReader->msg.msgStr == NULL) {
     return false;
   }
 
   int32_t blockSz = taosArrayGetSize(pReader->submit.aSubmitTbData);
   while (pReader->nextBlk < blockSz) {
-    tqDebug("tq reader next data block %p, %d %" PRId64 " %d", pReader->msg2.msgStr, pReader->msg2.msgLen,
-            pReader->msg2.ver, pReader->nextBlk);
+    tqDebug("tq reader next data block %p, %d %" PRId64 " %d", pReader->msg.msgStr, pReader->msg.msgLen,
+            pReader->msg.ver, pReader->nextBlk);
 
     SSubmitTbData* pSubmitTbData = taosArrayGet(pReader->submit.aSubmitTbData, pReader->nextBlk);
     if (pReader->tbIdHash == NULL) {
@@ -384,24 +436,24 @@ bool tqNextDataBlock(STqReader* pReader) {
 
     void* ret = taosHashGet(pReader->tbIdHash, &pSubmitTbData->uid, sizeof(int64_t));
     if (ret != NULL) {
-      tqDebug("tq reader block found, ver:%"PRId64", uid:%"PRId64, pReader->msg2.ver, pSubmitTbData->uid);
+      tqDebug("tq reader block found, ver:%"PRId64", uid:%"PRId64, pReader->msg.ver, pSubmitTbData->uid);
       return true;
     } else {
-      tqDebug("tq reader discard block, uid:%"PRId64", continue", pSubmitTbData->uid);
+      tqDebug("tq reader discard submit block, uid:%"PRId64", continue", pSubmitTbData->uid);
     }
 
     pReader->nextBlk++;
   }
 
-  tDestroySSubmitReq2(&pReader->submit, TSDB_MSG_FLG_DECODE);
+  tDestroySubmitReq(&pReader->submit, TSDB_MSG_FLG_DECODE);
   pReader->nextBlk = 0;
-  pReader->msg2.msgStr = NULL;
+  pReader->msg.msgStr = NULL;
 
   return false;
 }
 
-bool tqNextDataBlockFilterOut2(STqReader* pReader, SHashObj* filterOutUids) {
-  if (pReader->msg2.msgStr == NULL) return false;
+bool tqNextDataBlockFilterOut(STqReader* pReader, SHashObj* filterOutUids) {
+  if (pReader->msg.msgStr == NULL) return false;
 
   int32_t blockSz = taosArrayGetSize(pReader->submit.aSubmitTbData);
   while (pReader->nextBlk < blockSz) {
@@ -415,9 +467,9 @@ bool tqNextDataBlockFilterOut2(STqReader* pReader, SHashObj* filterOutUids) {
     pReader->nextBlk++;
   }
 
-  tDestroySSubmitReq2(&pReader->submit, TSDB_MSG_FLG_DECODE);
+  tDestroySubmitReq(&pReader->submit, TSDB_MSG_FLG_DECODE);
   pReader->nextBlk = 0;
-  pReader->msg2.msgStr = NULL;
+  pReader->msg.msgStr = NULL;
 
   return false;
 }
@@ -451,212 +503,219 @@ int32_t tqMaskBlock(SSchemaWrapper* pDst, SSDataBlock* pBlock, const SSchemaWrap
   return 0;
 }
 
-int32_t tqRetrieveDataBlock2(SSDataBlock* pBlock, STqReader* pReader, SSubmitTbData** pSubmitTbDataRet) {
-  tqDebug("tq reader retrieve data block %p, index:%d", pReader->msg2.msgStr, pReader->nextBlk);
-  SSubmitTbData* pSubmitTbData = taosArrayGet(pReader->submit.aSubmitTbData, pReader->nextBlk);
-  pReader->nextBlk++;
+int32_t tqRetrieveDataBlock(STqReader* pReader, SSubmitTbData** pSubmitTbDataRet) {
+  tqDebug("tq reader retrieve data block %p, index:%d", pReader->msg.msgStr, pReader->nextBlk);
 
+  SSubmitTbData* pSubmitTbData = taosArrayGet(pReader->submit.aSubmitTbData, pReader->nextBlk++);
   if (pSubmitTbDataRet) {
     *pSubmitTbDataRet = pSubmitTbData;
   }
 
+  SSDataBlock* pBlock = pReader->pResBlock;
+  blockDataCleanup(pBlock);
+
   int32_t sversion = pSubmitTbData->sver;
   int64_t suid = pSubmitTbData->suid;
   int64_t uid = pSubmitTbData->uid;
   pReader->lastBlkUid = uid;
 
   pBlock->info.id.uid = uid;
-  pBlock->info.version = pReader->msg2.ver;
+  pBlock->info.version = pReader->msg.ver;
 
-  if (pReader->cachedSchemaSuid == 0 || pReader->cachedSchemaVer != sversion || pReader->cachedSchemaSuid != suid) {
-    taosMemoryFree(pReader->pSchema);
-    pReader->pSchema = metaGetTbTSchema(pReader->pVnodeMeta, uid, sversion, 1);
-    if (pReader->pSchema == NULL) {
-      tqWarn("vgId:%d, cannot found tsschema for table: uid:%" PRId64 " (suid:%" PRId64
-             "), version %d, possibly dropped table",
-             pReader->pWalReader->pWal->cfg.vgId, uid, suid, sversion);
-      pReader->cachedSchemaSuid = 0;
-      terrno = TSDB_CODE_TQ_TABLE_SCHEMA_NOT_FOUND;
-      return -1;
-    }
+  if ((suid != 0 && pReader->cachedSchemaSuid != suid) || (suid == 0 && pReader->cachedSchemaUid != uid) || (pReader->cachedSchemaVer != sversion)) {
+    tDeleteSchemaWrapper(pReader->pSchemaWrapper);
 
-    tDeleteSSchemaWrapper(pReader->pSchemaWrapper);
     pReader->pSchemaWrapper = metaGetTableSchema(pReader->pVnodeMeta, uid, sversion, 1);
     if (pReader->pSchemaWrapper == NULL) {
-      tqWarn("vgId:%d, cannot found schema wrapper for table: suid:%" PRId64 ", version %d, possibly dropped table",
-             pReader->pWalReader->pWal->cfg.vgId, uid, pReader->cachedSchemaVer);
+      tqWarn("vgId:%d, cannot found schema wrapper for table: suid:%" PRId64 ", uid:%" PRId64 "version %d, possibly dropped table",
+             pReader->pWalReader->pWal->cfg.vgId, suid, uid, pReader->cachedSchemaVer);
       pReader->cachedSchemaSuid = 0;
       terrno = TSDB_CODE_TQ_TABLE_SCHEMA_NOT_FOUND;
       return -1;
     }
 
-    STSchema*       pTschema = pReader->pSchema;
+    pReader->cachedSchemaUid = uid;
+    pReader->cachedSchemaSuid = suid;
+    pReader->cachedSchemaVer = sversion;
+
     SSchemaWrapper* pSchemaWrapper = pReader->pSchemaWrapper;
+    if (blockDataGetNumOfCols(pBlock) > 0) {
+      blockDataDestroy(pReader->pResBlock);
+      pReader->pResBlock = createDataBlock();
+      pBlock = pReader->pResBlock;
 
-    int32_t colNumNeed = taosArrayGetSize(pReader->pColIdList);
+      pBlock->info.id.uid = uid;
+      pBlock->info.version = pReader->msg.ver;
+    }
 
-    if (colNumNeed == 0) {
-      int32_t colMeta = 0;
-      while (colMeta < pSchemaWrapper->nCols) {
-        SSchema*        pColSchema = &pSchemaWrapper->pSchema[colMeta];
+    int32_t numOfCols = taosArrayGetSize(pReader->pColIdList);
+    if (numOfCols == 0) {  // all columns are required
+      for (int32_t i = 0; i < pSchemaWrapper->nCols; ++i) {
+        SSchema*        pColSchema = &pSchemaWrapper->pSchema[i];
         SColumnInfoData colInfo = createColumnInfoData(pColSchema->type, pColSchema->bytes, pColSchema->colId);
-        int32_t         code = blockDataAppendColInfo(pBlock, &colInfo);
+
+        int32_t code = blockDataAppendColInfo(pBlock, &colInfo);
         if (code != TSDB_CODE_SUCCESS) {
-          goto FAIL;
+          blockDataFreeRes(pBlock);
+          return -1;
         }
-        colMeta++;
       }
     } else {
-      if (colNumNeed > pSchemaWrapper->nCols) {
-        colNumNeed = pSchemaWrapper->nCols;
+      if (numOfCols > pSchemaWrapper->nCols) {
+        numOfCols = pSchemaWrapper->nCols;
       }
 
-      int32_t colMeta = 0;
-      int32_t colNeed = 0;
-      while (colMeta < pSchemaWrapper->nCols && colNeed < colNumNeed) {
-        SSchema* pColSchema = &pSchemaWrapper->pSchema[colMeta];
+      int32_t i = 0;
+      int32_t j = 0;
+      while (i < pSchemaWrapper->nCols && j < numOfCols) {
+        SSchema* pColSchema = &pSchemaWrapper->pSchema[i];
         col_id_t colIdSchema = pColSchema->colId;
-        col_id_t colIdNeed = *(col_id_t*)taosArrayGet(pReader->pColIdList, colNeed);
+
+        col_id_t colIdNeed = *(col_id_t*)taosArrayGet(pReader->pColIdList, j);
         if (colIdSchema < colIdNeed) {
-          colMeta++;
+          i++;
         } else if (colIdSchema > colIdNeed) {
-          colNeed++;
+          j++;
         } else {
           SColumnInfoData colInfo = createColumnInfoData(pColSchema->type, pColSchema->bytes, pColSchema->colId);
           int32_t         code = blockDataAppendColInfo(pBlock, &colInfo);
           if (code != TSDB_CODE_SUCCESS) {
-            goto FAIL;
+            return -1;
           }
-          colMeta++;
-          colNeed++;
+          i++;
+          j++;
         }
       }
     }
+  }
 
-    int32_t numOfRows = 0;
+  int32_t numOfRows = 0;
+  if (pSubmitTbData->flags & SUBMIT_REQ_COLUMN_DATA_FORMAT) {
+    SColData* pCol = taosArrayGet(pSubmitTbData->aCol, 0);
+    numOfRows = pCol->nVal;
+  } else {
+    numOfRows = taosArrayGetSize(pSubmitTbData->aRowP);
+  }
 
-    if (pSubmitTbData->flags & SUBMIT_REQ_COLUMN_DATA_FORMAT) {
-      SArray*   pCols = pSubmitTbData->aCol;
-      SColData* pCol = taosArrayGet(pCols, 0);
-      numOfRows = pCol->nVal;
-    } else {
-      SArray* pRows = pSubmitTbData->aRowP;
-      numOfRows = taosArrayGetSize(pRows);
+  if (blockDataEnsureCapacity(pBlock, numOfRows) < 0) {
+    terrno = TSDB_CODE_OUT_OF_MEMORY;
+    return -1;
+  }
+
+  pBlock->info.rows = numOfRows;
+
+  int32_t colActual = blockDataGetNumOfCols(pBlock);
+
+  // convert and scan one block
+  if (pSubmitTbData->flags & SUBMIT_REQ_COLUMN_DATA_FORMAT) {
+    SArray* pCols = pSubmitTbData->aCol;
+    int32_t numOfCols = taosArrayGetSize(pCols);
+    int32_t targetIdx = 0;
+    int32_t sourceIdx = 0;
+    while (targetIdx < colActual) {
+      if (sourceIdx >= numOfCols) {
+        tqError("tqRetrieveDataBlock sourceIdx:%d >= numOfCols:%d", sourceIdx, numOfCols);
+        return -1;
+      }
+
+      SColData*        pCol = taosArrayGet(pCols, sourceIdx);
+      SColumnInfoData* pColData = taosArrayGet(pBlock->pDataBlock, targetIdx);
+      SColVal          colVal;
+
+      if (pCol->nVal != numOfRows) {
+        tqError("tqRetrieveDataBlock pCol->nVal:%d != numOfRows:%d", pCol->nVal, numOfRows);
+        return -1;
+      }
+
+      if (pCol->cid < pColData->info.colId) {
+        sourceIdx++;
+      } else if (pCol->cid == pColData->info.colId) {
+        for (int32_t i = 0; i < pCol->nVal; i++) {
+          tColDataGetValue(pCol, i, &colVal);
+          if (IS_STR_DATA_TYPE(colVal.type)) {
+            if (colVal.value.pData != NULL) {
+              char val[65535 + 2] = {0};
+              memcpy(varDataVal(val), colVal.value.pData, colVal.value.nData);
+              varDataSetLen(val, colVal.value.nData);
+              if (colDataAppend(pColData, i, val, !COL_VAL_IS_VALUE(&colVal)) < 0) {
+                return -1;
+              }
+            } else {
+              colDataSetNULL(pColData, i);
+            }
+          } else {
+            if (colDataAppend(pColData, i, (void*)&colVal.value.val, !COL_VAL_IS_VALUE(&colVal)) < 0) {
+              return -1;
+            }
+          }
+        }
+        sourceIdx++;
+        targetIdx++;
+      } else {
+        for (int32_t i = 0; i < pCol->nVal; i++) {
+          colDataSetNULL(pColData, i);
+        }
+
+        targetIdx++;
+      }
     }
+  } else {
+    SArray*         pRows = pSubmitTbData->aRowP;
+    SSchemaWrapper* pWrapper = pReader->pSchemaWrapper;
+    STSchema*       pTSchema = tBuildTSchema(pWrapper->pSchema, pWrapper->nCols, pWrapper->version);
 
-    if (blockDataEnsureCapacity(pBlock, numOfRows) < 0) {
-      terrno = TSDB_CODE_OUT_OF_MEMORY;
-      goto FAIL;
-    }
-    pBlock->info.rows = numOfRows;
-
-    int32_t colActual = blockDataGetNumOfCols(pBlock);
-
-    // convert and scan one block
-    if (pSubmitTbData->flags & SUBMIT_REQ_COLUMN_DATA_FORMAT) {
-      SArray* pCols = pSubmitTbData->aCol;
-      int32_t numOfCols = taosArrayGetSize(pCols);
-      int32_t targetIdx = 0;
+    for (int32_t i = 0; i < numOfRows; i++) {
+      SRow*   pRow = taosArrayGetP(pRows, i);
       int32_t sourceIdx = 0;
-      while (targetIdx < colActual) {
-        if(sourceIdx >= numOfCols){
-          tqError("tqRetrieveDataBlock2 sourceIdx:%d >= numOfCols:%d", sourceIdx, numOfCols);
-          goto FAIL;
-        }
-        SColData*        pCol = taosArrayGet(pCols, sourceIdx);
-        SColumnInfoData* pColData = taosArrayGet(pBlock->pDataBlock, targetIdx);
-        SColVal          colVal;
 
-        if(pCol->nVal != numOfRows){
-          tqError("tqRetrieveDataBlock2 pCol->nVal:%d != numOfRows:%d", pCol->nVal, numOfRows);
-          goto FAIL;
-        }
+      for (int32_t j = 0; j < colActual; j++) {
+        SColumnInfoData* pColData = taosArrayGet(pBlock->pDataBlock, j);
+        while (1) {
+          SColVal colVal;
+          tqDebug("start to extract column id:%d, index:%d", pColData->info.colId, sourceIdx);
 
-        if (pCol->cid < pColData->info.colId) {
-          sourceIdx++;
-        } else if (pCol->cid == pColData->info.colId) {
-          for (int32_t i = 0; i < pCol->nVal; i++) {
-            tColDataGetValue(pCol, i, &colVal);
+          tRowGet(pRow, pTSchema, sourceIdx, &colVal);
+          if (colVal.cid < pColData->info.colId) {
+            tqDebug("colIndex:%d column id:%d in row, ignore, the required colId:%d, total cols in schema:%d",
+                    sourceIdx, colVal.cid, pColData->info.colId, pTSchema->numOfCols);
+            sourceIdx++;
+            continue;
+          } else if (colVal.cid == pColData->info.colId) {
             if (IS_STR_DATA_TYPE(colVal.type)) {
               if (colVal.value.pData != NULL) {
                 char val[65535 + 2] = {0};
                 memcpy(varDataVal(val), colVal.value.pData, colVal.value.nData);
                 varDataSetLen(val, colVal.value.nData);
                 if (colDataAppend(pColData, i, val, !COL_VAL_IS_VALUE(&colVal)) < 0) {
-                  goto FAIL;
+                  return -1;
                 }
               } else {
                 colDataSetNULL(pColData, i);
               }
             } else {
               if (colDataAppend(pColData, i, (void*)&colVal.value.val, !COL_VAL_IS_VALUE(&colVal)) < 0) {
-                goto FAIL;
+                return -1;
               }
             }
-          }
-          sourceIdx++;
-          targetIdx++;
-        } else {
-          for (int32_t i = 0; i < pCol->nVal; i++) {
+
+            sourceIdx++;
+            break;
+          } else {
             colDataSetNULL(pColData, i);
-          }
-          targetIdx++;
-        }
-      }
-    } else {
-      SArray* pRows = pSubmitTbData->aRowP;
-
-      for (int32_t i = 0; i < numOfRows; i++) {
-        SRow*   pRow = taosArrayGetP(pRows, i);
-        int32_t sourceIdx = 0;
-
-        for (int32_t j = 0; j < colActual; j++) {
-          SColumnInfoData* pColData = taosArrayGet(pBlock->pDataBlock, j);
-          while (1) {
-            SColVal colVal;
-            tRowGet(pRow, pTschema, sourceIdx, &colVal);
-            if (colVal.cid < pColData->info.colId) {
-              sourceIdx++;
-              continue;
-            } else if (colVal.cid == pColData->info.colId) {
-              if (IS_STR_DATA_TYPE(colVal.type)) {
-                if (colVal.value.pData != NULL) {
-                  char val[65535 + 2] = {0};
-                  memcpy(varDataVal(val), colVal.value.pData, colVal.value.nData);
-                  varDataSetLen(val, colVal.value.nData);
-                  if (colDataAppend(pColData, i, val, !COL_VAL_IS_VALUE(&colVal)) < 0) {
-                    goto FAIL;
-                  }
-                } else {
-                  colDataSetNULL(pColData, i);
-                }
-              } else {
-                if (colDataAppend(pColData, i, (void*)&colVal.value.val, !COL_VAL_IS_VALUE(&colVal)) < 0) {
-                  goto FAIL;
-                }
-              }
-
-              sourceIdx++;
-              break;
-            } else {
-              colDataSetNULL(pColData, i);
-              break;
-            }
+            break;
           }
         }
       }
     }
+
+    taosMemoryFreeClear(pTSchema);
   }
 
   return 0;
-
-FAIL:
-  blockDataFreeRes(pBlock);
-  return -1;
 }
 
-int32_t tqRetrieveTaosxBlock2(STqReader* pReader, SArray* blocks, SArray* schemas, SSubmitTbData** pSubmitTbDataRet) {
-  tqDebug("tq reader retrieve data block %p, %d", pReader->msg2.msgStr, pReader->nextBlk);
+int32_t tqRetrieveTaosxBlock(STqReader* pReader, SArray* blocks, SArray* schemas, SSubmitTbData** pSubmitTbDataRet) {
+  tqDebug("tq reader retrieve data block %p, %d", pReader->msg.msgStr, pReader->nextBlk);
 
   SSubmitTbData* pSubmitTbData = taosArrayGet(pReader->submit.aSubmitTbData, pReader->nextBlk);
   pReader->nextBlk++;
@@ -667,18 +726,7 @@ int32_t tqRetrieveTaosxBlock2(STqReader* pReader, SArray* blocks, SArray* schema
   int64_t uid = pSubmitTbData->uid;
   pReader->lastBlkUid = uid;
 
-  taosMemoryFree(pReader->pSchema);
-  pReader->pSchema = metaGetTbTSchema(pReader->pVnodeMeta, uid, sversion, 1);
-  if (pReader->pSchema == NULL) {
-    tqWarn("vgId:%d, cannot found tsschema for table: uid:%" PRId64 " (suid:%" PRId64
-           "), version %d, possibly dropped table",
-           pReader->pWalReader->pWal->cfg.vgId, uid, suid, sversion);
-    pReader->cachedSchemaSuid = 0;
-    terrno = TSDB_CODE_TQ_TABLE_SCHEMA_NOT_FOUND;
-    return -1;
-  }
-
-  tDeleteSSchemaWrapper(pReader->pSchemaWrapper);
+  tDeleteSchemaWrapper(pReader->pSchemaWrapper);
   pReader->pSchemaWrapper = metaGetTableSchema(pReader->pVnodeMeta, uid, sversion, 1);
   if (pReader->pSchemaWrapper == NULL) {
     tqWarn("vgId:%d, cannot found schema wrapper for table: suid:%" PRId64 ", version %d, possibly dropped table",
@@ -688,7 +736,6 @@ int32_t tqRetrieveTaosxBlock2(STqReader* pReader, SArray* blocks, SArray* schema
     return -1;
   }
 
-  STSchema*       pTschema = pReader->pSchema;
   SSchemaWrapper* pSchemaWrapper = pReader->pSchemaWrapper;
   int32_t         numOfRows = 0;
 
@@ -745,18 +792,18 @@ int32_t tqRetrieveTaosxBlock2(STqReader* pReader, SArray* blocks, SArray* schema
 
         if (tqMaskBlock(pSW, &block, pSchemaWrapper, assigned) < 0) {
           blockDataFreeRes(&block);
-          tDeleteSSchemaWrapper(pSW);
+          tDeleteSchemaWrapper(pSW);
           goto FAIL;
         }
         tqDebug("vgId:%d, build new block, col %d", pReader->pWalReader->pWal->cfg.vgId,
                 (int32_t)taosArrayGetSize(block.pDataBlock));
 
         block.info.id.uid = uid;
-        block.info.version = pReader->msg2.ver;
+        block.info.version = pReader->msg.ver;
         if (blockDataEnsureCapacity(&block, numOfRows - curRow) < 0) {
           terrno = TSDB_CODE_OUT_OF_MEMORY;
           blockDataFreeRes(&block);
-          tDeleteSSchemaWrapper(pSW);
+          tDeleteSchemaWrapper(pSW);
           goto FAIL;
         }
         taosArrayPush(blocks, &block);
@@ -805,14 +852,17 @@ int32_t tqRetrieveTaosxBlock2(STqReader* pReader, SArray* blocks, SArray* schema
       curRow++;
     }
   } else {
+    SSchemaWrapper* pWrapper = pReader->pSchemaWrapper;
+    STSchema* pTSchema = tBuildTSchema(pWrapper->pSchema, pWrapper->nCols, pWrapper->version);
     SArray* pRows = pSubmitTbData->aRowP;
+
     for (int32_t i = 0; i < numOfRows; i++) {
       SRow* pRow = taosArrayGetP(pRows, i);
       bool  buildNew = false;
 
-      for (int32_t j = 0; j < pTschema->numOfCols; j++) {
+      for (int32_t j = 0; j < pTSchema->numOfCols; j++) {
         SColVal colVal;
-        tRowGet(pRow, pTschema, j, &colVal);
+        tRowGet(pRow, pTSchema, j, &colVal);
         if (curRow == 0) {
           assigned[j] = !COL_VAL_IS_NONE(&colVal);
           buildNew = true;
@@ -841,18 +891,18 @@ int32_t tqRetrieveTaosxBlock2(STqReader* pReader, SArray* blocks, SArray* schema
 
         if (tqMaskBlock(pSW, &block, pSchemaWrapper, assigned) < 0) {
           blockDataFreeRes(&block);
-          tDeleteSSchemaWrapper(pSW);
+          tDeleteSchemaWrapper(pSW);
           goto FAIL;
         }
         tqDebug("vgId:%d, build new block, col %d", pReader->pWalReader->pWal->cfg.vgId,
                 (int32_t)taosArrayGetSize(block.pDataBlock));
 
         block.info.id.uid = uid;
-        block.info.version = pReader->msg2.ver;
+        block.info.version = pReader->msg.ver;
         if (blockDataEnsureCapacity(&block, numOfRows - curRow) < 0) {
           terrno = TSDB_CODE_OUT_OF_MEMORY;
           blockDataFreeRes(&block);
-          tDeleteSSchemaWrapper(pSW);
+          tDeleteSchemaWrapper(pSW);
           goto FAIL;
         }
         taosArrayPush(blocks, &block);
@@ -870,7 +920,7 @@ int32_t tqRetrieveTaosxBlock2(STqReader* pReader, SArray* blocks, SArray* schema
       while (targetIdx < colActual) {
         SColumnInfoData* pColData = taosArrayGet(pBlock->pDataBlock, targetIdx);
         SColVal          colVal;
-        tRowGet(pRow, pTschema, sourceIdx, &colVal);
+        tRowGet(pRow, pTSchema, sourceIdx, &colVal);
 
         if (colVal.cid < pColData->info.colId) {
           sourceIdx++;
@@ -897,6 +947,8 @@ int32_t tqRetrieveTaosxBlock2(STqReader* pReader, SArray* blocks, SArray* schema
       }
       curRow++;
     }
+
+    taosMemoryFreeClear(pTSchema);
   }
 
   SSDataBlock* pLastBlock = taosArrayGetLast(blocks);
@@ -1041,6 +1093,5 @@ int32_t tqUpdateTbUidList(STQ* pTq, const SArray* tbUidList, bool isAdd) {
   }
 
   taosWUnLockLatch(&pTq->pStreamMeta->lock);
-
   return 0;
 }
diff --git a/source/dnode/vnode/src/tq/tqRestore.c b/source/dnode/vnode/src/tq/tqRestore.c
index c164d037e0..0bb33b1215 100644
--- a/source/dnode/vnode/src/tq/tqRestore.c
+++ b/source/dnode/vnode/src/tq/tqRestore.c
@@ -18,16 +18,15 @@
 static int32_t createStreamRunReq(SStreamMeta* pStreamMeta, bool* pScanIdle);
 
 // this function should be executed by stream threads.
-// there is a case that the WAL increases more fast than the restore procedure, and this restore procedure
-// will not stop eventually.
+// extract submit block from WAL, and add them into the input queue for the sources tasks.
 int32_t tqStreamTasksScanWal(STQ* pTq) {
-  int32_t vgId = TD_VID(pTq->pVnode);
+  int32_t      vgId = TD_VID(pTq->pVnode);
   SStreamMeta* pMeta = pTq->pStreamMeta;
-  int64_t st = taosGetTimestampMs();
+  int64_t      st = taosGetTimestampMs();
 
   while (1) {
-    int32_t scan = pMeta->walScan;
-    tqDebug("vgId:%d continue check if data in wal are available, scan:%d", vgId, scan);
+    int32_t scan = pMeta->walScanCounter;
+    tqDebug("vgId:%d continue check if data in wal are available, walScanCounter:%d", vgId, scan);
 
     // check all restore tasks
     bool shouldIdle = true;
@@ -37,12 +36,13 @@ int32_t tqStreamTasksScanWal(STQ* pTq) {
 
     if (shouldIdle) {
       taosWLockLatch(&pMeta->lock);
-      pMeta->walScan -= 1;
-      times = pMeta->walScan;
 
-      ASSERT(pMeta->walScan >= 0);
+      pMeta->walScanCounter -= 1;
+      times = pMeta->walScanCounter;
 
-      if (pMeta->walScan <= 0) {
+      ASSERT(pMeta->walScanCounter >= 0);
+
+      if (pMeta->walScanCounter <= 0) {
         taosWUnLockLatch(&pMeta->lock);
         break;
       }
@@ -57,42 +57,28 @@ int32_t tqStreamTasksScanWal(STQ* pTq) {
   return 0;
 }
 
-static SArray* extractTaskIdList(SStreamMeta* pStreamMeta, int32_t numOfTasks) {
-  SArray* pTaskIdList = taosArrayInit(numOfTasks, sizeof(int32_t));
-  void*   pIter = NULL;
-
-  taosWLockLatch(&pStreamMeta->lock);
-  while(1) {
-    pIter = taosHashIterate(pStreamMeta->pTasks, pIter);
-    if (pIter == NULL) {
-      break;
-    }
-
-    SStreamTask* pTask = *(SStreamTask**)pIter;
-    taosArrayPush(pTaskIdList, &pTask->id.taskId);
-  }
-
-  taosWUnLockLatch(&pStreamMeta->lock);
-  return pTaskIdList;
-}
-
 int32_t createStreamRunReq(SStreamMeta* pStreamMeta, bool* pScanIdle) {
   *pScanIdle = true;
   bool    noNewDataInWal = true;
   int32_t vgId = pStreamMeta->vgId;
 
-  int32_t numOfTasks = taosHashGetSize(pStreamMeta->pTasks);
+  int32_t numOfTasks = taosArrayGetSize(pStreamMeta->pTaskList);
   if (numOfTasks == 0) {
     return TSDB_CODE_SUCCESS;
   }
 
+  SArray* pTaskList = NULL;
+  taosWLockLatch(&pStreamMeta->lock);
+  pTaskList = taosArrayDup(pStreamMeta->pTaskList, NULL);
+  taosWUnLockLatch(&pStreamMeta->lock);
+
   tqDebug("vgId:%d start to check wal to extract new submit block for %d tasks", vgId, numOfTasks);
-  SArray* pTaskIdList = extractTaskIdList(pStreamMeta, numOfTasks);
 
   // update the new task number
-  numOfTasks = taosArrayGetSize(pTaskIdList);
+  numOfTasks = taosArrayGetSize(pTaskList);
+
   for (int32_t i = 0; i < numOfTasks; ++i) {
-    int32_t*     pTaskId = taosArrayGet(pTaskIdList, i);
+    int32_t*     pTaskId = taosArrayGet(pTaskList, i);
     SStreamTask* pTask = streamMetaAcquireTask(pStreamMeta, *pTaskId);
     if (pTask == NULL) {
       continue;
@@ -107,7 +93,7 @@ int32_t createStreamRunReq(SStreamMeta* pStreamMeta, bool* pScanIdle) {
 
     if (streamTaskShouldStop(&pTask->status) || status == TASK_STATUS__RECOVER_PREPARE ||
         status == TASK_STATUS__WAIT_DOWNSTREAM) {
-      tqDebug("s-task:%s skip push data, not ready for processing, status %d", pTask->id.idStr, status);
+      tqDebug("s-task:%s not ready for new submit block from wal, status:%d", pTask->id.idStr, status);
       streamMetaReleaseTask(pStreamMeta, pTask);
       continue;
     }
@@ -123,6 +109,15 @@ int32_t createStreamRunReq(SStreamMeta* pStreamMeta, bool* pScanIdle) {
     // seek the stored version and extract data from WAL
     int32_t code = walReadSeekVer(pTask->exec.pWalReader, pTask->chkInfo.currentVer);
     if (code != TSDB_CODE_SUCCESS) {  // no data in wal, quit
+      SWal *pWal = pTask->exec.pWalReader->pWal;
+      if (pTask->chkInfo.currentVer < pWal->vers.firstVer ) {
+        pTask->chkInfo.currentVer = pWal->vers.firstVer;
+        code = walReadSeekVer(pTask->exec.pWalReader, pTask->chkInfo.currentVer);
+        if (code != TSDB_CODE_SUCCESS) {
+          streamMetaReleaseTask(pStreamMeta, pTask);
+          continue;
+        }
+      }
       streamMetaReleaseTask(pStreamMeta, pTask);
       continue;
     }
@@ -166,7 +161,7 @@ int32_t createStreamRunReq(SStreamMeta* pStreamMeta, bool* pScanIdle) {
     *pScanIdle = true;
   }
 
-  taosArrayDestroy(pTaskIdList);
+  taosArrayDestroy(pTaskList);
   return 0;
 }
 
diff --git a/source/dnode/vnode/src/tq/tqScan.c b/source/dnode/vnode/src/tq/tqScan.c
index 27db66f048..800bcc8b71 100644
--- a/source/dnode/vnode/src/tq/tqScan.c
+++ b/source/dnode/vnode/src/tq/tqScan.c
@@ -66,15 +66,15 @@ static int32_t tqAddTbNameToRsp(const STQ* pTq, int64_t uid, STaosxRsp* pRsp, in
 
 int32_t tqScanData(STQ* pTq, const STqHandle* pHandle, SMqDataRsp* pRsp, STqOffsetVal* pOffset) {
   const int32_t MAX_ROWS_TO_RETURN = 4096;
-  int32_t       vgId = TD_VID(pTq->pVnode);
-  int32_t       code = 0;
-  int32_t       totalRows = 0;
+
+  int32_t vgId = TD_VID(pTq->pVnode);
+  int32_t code = 0;
+  int32_t totalRows = 0;
 
   const STqExecHandle* pExec = &pHandle->execHandle;
   qTaskInfo_t          task = pExec->task;
 
   if (qStreamPrepareScan(task, pOffset, pHandle->execHandle.subType) < 0) {
-    tqError("prepare scan failed, return");
     return -1;
   }
 
@@ -119,7 +119,6 @@ int32_t tqScanTaosx(STQ* pTq, const STqHandle* pHandle, STaosxRsp* pRsp, SMqMeta
   qTaskInfo_t          task = pExec->task;
 
   if (qStreamPrepareScan(task, pOffset, pHandle->execHandle.subType) < 0) {
-    tqDebug("tqScanTaosx prepare scan failed, return");
     return -1;
   }
 
@@ -132,6 +131,7 @@ int32_t tqScanTaosx(STQ* pTq, const STqHandle* pHandle, STaosxRsp* pRsp, SMqMeta
       tqError("vgId:%d, task exec error since %s", pTq->pVnode->config.vgId, terrstr());
       return -1;
     }
+
     tqDebug("tmqsnap task execute end, get %p", pDataBlock);
 
     if (pDataBlock != NULL && pDataBlock->info.rows > 0) {
@@ -205,18 +205,18 @@ int32_t tqTaosxScanLog(STQ* pTq, STqHandle* pHandle, SPackedData submit, STaosxR
   if (pExec->subType == TOPIC_SUB_TYPE__TABLE) {
     STqReader* pReader = pExec->pTqReader;
     tqReaderSetSubmitMsg(pReader, submit.msgStr, submit.msgLen, submit.ver);
-    while (tqNextDataBlock(pReader)) {
+    while (tqNextBlockImpl(pReader)) {
       taosArrayClear(pBlocks);
       taosArrayClear(pSchemas);
       SSubmitTbData* pSubmitTbDataRet = NULL;
-      if (tqRetrieveTaosxBlock2(pReader, pBlocks, pSchemas, &pSubmitTbDataRet) < 0) {
+      if (tqRetrieveTaosxBlock(pReader, pBlocks, pSchemas, &pSubmitTbDataRet) < 0) {
         if (terrno == TSDB_CODE_TQ_TABLE_SCHEMA_NOT_FOUND) continue;
       }
       if (pRsp->withTbName) {
         int64_t uid = pExec->pTqReader->lastBlkUid;
         if (tqAddTbNameToRsp(pTq, uid, pRsp, taosArrayGetSize(pBlocks)) < 0) {
           taosArrayDestroyEx(pBlocks, (FDelete)blockDataFreeRes);
-          taosArrayDestroyP(pSchemas, (FDelete)tDeleteSSchemaWrapper);
+          taosArrayDestroyP(pSchemas, (FDelete)tDeleteSchemaWrapper);
           pBlocks = taosArrayInit(0, sizeof(SSDataBlock));
           pSchemas = taosArrayInit(0, sizeof(void*));
           continue;
@@ -264,18 +264,18 @@ int32_t tqTaosxScanLog(STQ* pTq, STqHandle* pHandle, SPackedData submit, STaosxR
   } else if (pExec->subType == TOPIC_SUB_TYPE__DB) {
     STqReader* pReader = pExec->pTqReader;
     tqReaderSetSubmitMsg(pReader, submit.msgStr, submit.msgLen, submit.ver);
-    while (tqNextDataBlockFilterOut2(pReader, pExec->execDb.pFilterOutTbUid)) {
+    while (tqNextDataBlockFilterOut(pReader, pExec->execDb.pFilterOutTbUid)) {
       taosArrayClear(pBlocks);
       taosArrayClear(pSchemas);
       SSubmitTbData* pSubmitTbDataRet = NULL;
-      if (tqRetrieveTaosxBlock2(pReader, pBlocks, pSchemas, &pSubmitTbDataRet) < 0) {
+      if (tqRetrieveTaosxBlock(pReader, pBlocks, pSchemas, &pSubmitTbDataRet) < 0) {
         if (terrno == TSDB_CODE_TQ_TABLE_SCHEMA_NOT_FOUND) continue;
       }
       if (pRsp->withTbName) {
         int64_t uid = pExec->pTqReader->lastBlkUid;
         if (tqAddTbNameToRsp(pTq, uid, pRsp, taosArrayGetSize(pBlocks)) < 0) {
           taosArrayDestroyEx(pBlocks, (FDelete)blockDataFreeRes);
-          taosArrayDestroyP(pSchemas, (FDelete)tDeleteSSchemaWrapper);
+          taosArrayDestroyP(pSchemas, (FDelete)tDeleteSchemaWrapper);
           pBlocks = taosArrayInit(0, sizeof(SSDataBlock));
           pSchemas = taosArrayInit(0, sizeof(void*));
           continue;
diff --git a/source/dnode/vnode/src/tq/tqSink.c b/source/dnode/vnode/src/tq/tqSink.c
index 62b81305b7..33d1e08c9c 100644
--- a/source/dnode/vnode/src/tq/tqSink.c
+++ b/source/dnode/vnode/src/tq/tqSink.c
@@ -672,7 +672,7 @@ void tqSinkToTablePipeline2(SStreamTask* pTask, void* vnode, int64_t ver, void*
         }
         SRow* pRow = NULL;
         if ((terrno = tRowBuild(pVals, (STSchema*)pTSchema, &pRow)) < 0) {
-          tDestroySSubmitTbData(&tbData, TSDB_MSG_FLG_ENCODE);
+          tDestroySubmitTbData(&tbData, TSDB_MSG_FLG_ENCODE);
           goto _end;
         }
         ASSERT(pRow);
@@ -681,7 +681,7 @@ void tqSinkToTablePipeline2(SStreamTask* pTask, void* vnode, int64_t ver, void*
 
       SSubmitReq2 submitReq = {0};
       if (!(submitReq.aSubmitTbData = taosArrayInit(1, sizeof(SSubmitTbData)))) {
-        tDestroySSubmitTbData(&tbData, TSDB_MSG_FLG_ENCODE);
+        tDestroySubmitTbData(&tbData, TSDB_MSG_FLG_ENCODE);
         goto _end;
       }
 
@@ -690,28 +690,28 @@ void tqSinkToTablePipeline2(SStreamTask* pTask, void* vnode, int64_t ver, void*
       // encode
       int32_t len;
       int32_t code;
-      tEncodeSize(tEncodeSSubmitReq2, &submitReq, len, code);
+      tEncodeSize(tEncodeSubmitReq, &submitReq, len, code);
       SEncoder encoder;
       len += sizeof(SSubmitReq2Msg);
       pBuf = rpcMallocCont(len);
       if (NULL == pBuf) {
-        tDestroySSubmitReq2(&submitReq, TSDB_MSG_FLG_ENCODE);
+        tDestroySubmitReq(&submitReq, TSDB_MSG_FLG_ENCODE);
         goto _end;
       }
       ((SSubmitReq2Msg*)pBuf)->header.vgId = TD_VID(pVnode);
       ((SSubmitReq2Msg*)pBuf)->header.contLen = htonl(len);
       ((SSubmitReq2Msg*)pBuf)->version = htobe64(1);
       tEncoderInit(&encoder, POINTER_SHIFT(pBuf, sizeof(SSubmitReq2Msg)), len - sizeof(SSubmitReq2Msg));
-      if (tEncodeSSubmitReq2(&encoder, &submitReq) < 0) {
+      if (tEncodeSubmitReq(&encoder, &submitReq) < 0) {
         terrno = TSDB_CODE_OUT_OF_MEMORY;
         tqError("failed to encode submit req since %s", terrstr());
         tEncoderClear(&encoder);
         rpcFreeCont(pBuf);
-        tDestroySSubmitReq2(&submitReq, TSDB_MSG_FLG_ENCODE);
+        tDestroySubmitReq(&submitReq, TSDB_MSG_FLG_ENCODE);
         continue;
       }
       tEncoderClear(&encoder);
-      tDestroySSubmitReq2(&submitReq, TSDB_MSG_FLG_ENCODE);
+      tDestroySubmitReq(&submitReq, TSDB_MSG_FLG_ENCODE);
 
       SRpcMsg msg = {
           .msgType = TDMT_VND_SUBMIT,
diff --git a/source/dnode/vnode/src/tq/tqUtil.c b/source/dnode/vnode/src/tq/tqUtil.c
index 017b479c1b..94803ef438 100644
--- a/source/dnode/vnode/src/tq/tqUtil.c
+++ b/source/dnode/vnode/src/tq/tqUtil.c
@@ -16,6 +16,7 @@
 #include "tq.h"
 
 #define IS_OFFSET_RESET_TYPE(_t)  ((_t) < 0)
+#define NO_POLL_CNT 5
 
 static int32_t tqSendMetaPollRsp(STQ* pTq, const SRpcMsg* pMsg, const SMqPollReq* pReq, const SMqMetaRsp* pRsp);
 
@@ -165,25 +166,38 @@ static int32_t extractDataAndRspForNormalSubscribe(STQ* pTq, STqHandle* pHandle,
                                                    SRpcMsg* pMsg, STqOffsetVal* pOffset) {
   uint64_t consumerId = pRequest->consumerId;
   int32_t  vgId = TD_VID(pTq->pVnode);
+  int      code = 0;
 
   SMqDataRsp dataRsp = {0};
   tqInitDataRsp(&dataRsp, pRequest, pHandle->execHandle.subType);
-
-  // lock
-  taosWLockLatch(&pTq->lock);
+  qTaskInfo_t task = pHandle->execHandle.task;
+  if(qTaskIsExecuting(task)){
+    code = tqSendDataRsp(pTq, pMsg, pRequest, &dataRsp, TMQ_MSG_TYPE__POLL_RSP);
+    tDeleteSMqDataRsp(&dataRsp);
+    return code;
+  }
 
   qSetTaskId(pHandle->execHandle.task, consumerId, pRequest->reqId);
-  int code = tqScanData(pTq, pHandle, &dataRsp, pOffset);
+  code = tqScanData(pTq, pHandle, &dataRsp, pOffset);
   if(code != 0) {
     goto end;
   }
 
-  // till now, all data has been transferred to consumer, new data needs to push client once arrived.
+  //   till now, all data has been transferred to consumer, new data needs to push client once arrived.
   if (dataRsp.blockNum == 0 && dataRsp.reqOffset.type == TMQ_OFFSET__LOG &&
       dataRsp.reqOffset.version == dataRsp.rspOffset.version && pHandle->consumerId == pRequest->consumerId) {
-    code = tqRegisterPushHandle(pTq, pHandle, pRequest, pMsg, &dataRsp, TMQ_MSG_TYPE__POLL_RSP);
-    taosWUnLockLatch(&pTq->lock);
-    return code;
+    if(pHandle->noDataPollCnt >= NO_POLL_CNT){  // send poll result to client if no data 5 times to avoid lost data
+      pHandle->noDataPollCnt = 0;
+      // lock
+      taosWLockLatch(&pTq->lock);
+      code = tqRegisterPushHandle(pTq, pHandle, pMsg);
+      taosWUnLockLatch(&pTq->lock);
+      tDeleteSMqDataRsp(&dataRsp);
+      return code;
+    }
+    else{
+      pHandle->noDataPollCnt++;
+    }
   }
 
 
@@ -197,7 +211,7 @@ static int32_t extractDataAndRspForNormalSubscribe(STQ* pTq, STqHandle* pHandle,
     tFormatOffset(buf, 80, &dataRsp.rspOffset);
     tqDebug("tmq poll: consumer:0x%" PRIx64 ", subkey %s, vgId:%d, rsp block:%d, rsp offset type:%s, reqId:0x%" PRIx64 " code:%d",
             consumerId, pHandle->subKey, vgId, dataRsp.blockNum, buf, pRequest->reqId, code);
-    taosWUnLockLatch(&pTq->lock);
+//    taosWUnLockLatch(&pTq->lock);
     tDeleteSMqDataRsp(&dataRsp);
   }
   return code;
@@ -211,6 +225,12 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle,
   SMqMetaRsp metaRsp = {0};
   STaosxRsp taosxRsp = {0};
   tqInitTaosxRsp(&taosxRsp, pRequest);
+  qTaskInfo_t task = pHandle->execHandle.task;
+  if(qTaskIsExecuting(task)){
+    code = tqSendDataRsp(pTq, pMsg, pRequest, (SMqDataRsp*)&taosxRsp, TMQ_MSG_TYPE__TAOSX_RSP);
+    tDeleteSTaosxRsp(&taosxRsp);
+    return code;
+  }
 
   if (offset->type != TMQ_OFFSET__LOG) {
     if (tqScanTaosx(pTq, pHandle, &taosxRsp, &metaRsp, offset) < 0) {
@@ -240,6 +260,7 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle,
 
 
   if (offset->type == TMQ_OFFSET__LOG) {
+    verifyOffset(pHandle->pWalReader, offset);
     int64_t fetchVer = offset->version + 1;
     pCkHead = taosMemoryMalloc(sizeof(SWalCkHead) + 2048);
     if (pCkHead == NULL) {
@@ -355,11 +376,10 @@ int32_t tqExtractDataForMq(STQ* pTq, STqHandle* pHandle, const SMqPollReq* pRequ
   // this is a normal subscribe requirement
   if (pHandle->execHandle.subType == TOPIC_SUB_TYPE__COLUMN) {
     return extractDataAndRspForNormalSubscribe(pTq, pHandle, pRequest, pMsg, &offset);
+  } else { // todo handle the case where re-balance occurs.
+    // for taosx
+    return extractDataAndRspForDbStbSubscribe(pTq, pHandle, pRequest, pMsg, &offset);
   }
-
-  // todo handle the case where re-balance occurs.
-  // for taosx
-  return extractDataAndRspForDbStbSubscribe(pTq, pHandle, pRequest, pMsg, &offset);
 }
 
 int32_t tqSendMetaPollRsp(STQ* pTq, const SRpcMsg* pMsg, const SMqPollReq* pReq, const SMqMetaRsp* pRsp) {
diff --git a/source/dnode/vnode/src/tsdb/tsdbCache.c b/source/dnode/vnode/src/tsdb/tsdbCache.c
index 3c7edd931b..65fc086f8d 100644
--- a/source/dnode/vnode/src/tsdb/tsdbCache.c
+++ b/source/dnode/vnode/src/tsdb/tsdbCache.c
@@ -598,6 +598,7 @@ typedef struct {
   SMergeTree         mergeTree;
   SMergeTree        *pMergeTree;
   SSttBlockLoadInfo *pLoadInfo;
+  SLDataIter*        pDataIter;
   int64_t            lastTs;
 } SFSLastNextRowIter;
 
@@ -645,7 +646,7 @@ static int32_t getNextRowFromFSLast(void *iter, TSDBROW **ppRow, bool *pIgnoreEa
       }
       tMergeTreeOpen(&state->mergeTree, 1, *state->pDataFReader, state->suid, state->uid,
                      &(STimeWindow){.skey = state->lastTs, .ekey = TSKEY_MAX},
-                     &(SVersionRange){.minVer = 0, .maxVer = UINT64_MAX}, state->pLoadInfo, false, NULL, true);
+                     &(SVersionRange){.minVer = 0, .maxVer = UINT64_MAX}, state->pLoadInfo, false, NULL, true, state->pDataIter);
       state->pMergeTree = &state->mergeTree;
       state->state = SFSLASTNEXTROW_BLOCKROW;
     }
@@ -667,7 +668,7 @@ static int32_t getNextRowFromFSLast(void *iter, TSDBROW **ppRow, bool *pIgnoreEa
         state->state = SFSLASTNEXTROW_FILESET;
         goto _next_fileset;
       }
-      state->row = tMergeTreeGetRow(&state->mergeTree);
+      state->row = *tMergeTreeGetRow(&state->mergeTree);
       *ppRow = &state->row;
 
       if (TSDBROW_TS(&state->row) <= state->lastTs) {
@@ -1211,7 +1212,7 @@ typedef struct {
 } CacheNextRowIter;
 
 static int32_t nextRowIterOpen(CacheNextRowIter *pIter, tb_uid_t uid, STsdb *pTsdb, STSchema *pTSchema, tb_uid_t suid,
-                               SSttBlockLoadInfo *pLoadInfo, STsdbReadSnap *pReadSnap, SDataFReader **pDataFReader,
+                               SSttBlockLoadInfo *pLoadInfo, SLDataIter* pLDataIter, STsdbReadSnap *pReadSnap, SDataFReader **pDataFReader,
                                SDataFReader **pDataFReaderLast, int64_t lastTs) {
   int code = 0;
 
@@ -1274,6 +1275,7 @@ static int32_t nextRowIterOpen(CacheNextRowIter *pIter, tb_uid_t uid, STsdb *pTs
   pIter->fsLastState.pLoadInfo = pLoadInfo;
   pIter->fsLastState.pDataFReader = pDataFReaderLast;
   pIter->fsLastState.lastTs = lastTs;
+  pIter->fsLastState.pDataIter = pLDataIter;
 
   pIter->fsState.state = SFSNEXTROW_FS;
   pIter->fsState.pTsdb = pTsdb;
@@ -1465,7 +1467,7 @@ static int32_t mergeLastRow(tb_uid_t uid, STsdb *pTsdb, bool *dup, SArray **ppCo
   TSKEY lastRowTs = TSKEY_MAX;
 
   CacheNextRowIter iter = {0};
-  nextRowIterOpen(&iter, uid, pTsdb, pTSchema, pr->suid, pr->pLoadInfo, pr->pReadSnap, &pr->pDataFReader,
+  nextRowIterOpen(&iter, uid, pTsdb, pTSchema, pr->suid, pr->pLoadInfo, pr->pDataIter, pr->pReadSnap, &pr->pDataFReader,
                   &pr->pDataFReaderLast, pr->lastTs);
 
   do {
@@ -1622,7 +1624,7 @@ static int32_t mergeLast(tb_uid_t uid, STsdb *pTsdb, SArray **ppLastArray, SCach
   TSKEY lastRowTs = TSKEY_MAX;
 
   CacheNextRowIter iter = {0};
-  nextRowIterOpen(&iter, uid, pTsdb, pTSchema, pr->suid, pr->pLoadInfo, pr->pReadSnap, &pr->pDataFReader,
+  nextRowIterOpen(&iter, uid, pTsdb, pTSchema, pr->suid, pr->pLoadInfo, pr->pDataIter, pr->pReadSnap, &pr->pDataFReader,
                   &pr->pDataFReaderLast, pr->lastTs);
 
   do {
diff --git a/source/dnode/vnode/src/tsdb/tsdbCacheRead.c b/source/dnode/vnode/src/tsdb/tsdbCacheRead.c
index f1c257e6a5..a196c2d398 100644
--- a/source/dnode/vnode/src/tsdb/tsdbCacheRead.c
+++ b/source/dnode/vnode/src/tsdb/tsdbCacheRead.c
@@ -199,13 +199,21 @@ int32_t tsdbCacherowsReaderOpen(void* pVnode, int32_t type, void* pTableIdList,
     }
   }
 
-  int32_t numOfStt = ((SVnode*)pVnode)->config.sttTrigger;
+  SVnodeCfg* pCfg = &((SVnode*)pVnode)->config;
+
+  int32_t numOfStt = pCfg->sttTrigger;
   p->pLoadInfo = tCreateLastBlockLoadInfo(p->pSchema, NULL, 0, numOfStt);
   if (p->pLoadInfo == NULL) {
     tsdbCacherowsReaderClose(p);
     return TSDB_CODE_OUT_OF_MEMORY;
   }
 
+  p->pDataIter = taosMemoryCalloc(pCfg->sttTrigger, sizeof(SLDataIter));
+  if (p->pDataIter == NULL) {
+    tsdbCacherowsReaderClose(p);
+    return TSDB_CODE_OUT_OF_MEMORY;
+  }
+
   p->idstr = taosStrdup(idstr);
   taosThreadMutexInit(&p->readerMutex, NULL);
 
@@ -227,6 +235,7 @@ void* tsdbCacherowsReaderClose(void* pReader) {
     taosMemoryFree(p->pSchema);
   }
 
+  taosMemoryFreeClear(p->pDataIter);
   taosMemoryFree(p->pCurrSchema);
 
   destroyLastBlockLoadInfo(p->pLoadInfo);
diff --git a/source/dnode/vnode/src/tsdb/tsdbDataIter.c b/source/dnode/vnode/src/tsdb/tsdbDataIter.c
index 3299a2f497..e27aec5b1b 100644
--- a/source/dnode/vnode/src/tsdb/tsdbDataIter.c
+++ b/source/dnode/vnode/src/tsdb/tsdbDataIter.c
@@ -14,6 +14,7 @@
  */
 
 #include "tsdb.h"
+#include "vnodeInt.h"
 
 // STsdbDataIter2
 /* open */
@@ -202,13 +203,6 @@ static int32_t tsdbDataFileDataIterNext(STsdbDataIter2* pIter, STsdbFilterInfo*
   for (;;) {
     while (pIter->dIter.iRow < pIter->dIter.bData.nRow) {
       if (pFilterInfo) {
-        if (pFilterInfo->flag & TSDB_FILTER_FLAG_BY_TABLEID) {
-          if (pFilterInfo->tbid.uid == pIter->dIter.bData.uid) {
-            pIter->dIter.iRow = pIter->dIter.bData.nRow;
-            continue;
-          }
-        }
-
         if (pFilterInfo->flag & TSDB_FILTER_FLAG_BY_VERSION) {
           if (pIter->dIter.bData.aVersion[pIter->dIter.iRow] < pFilterInfo->sver ||
               pIter->dIter.bData.aVersion[pIter->dIter.iRow] > pFilterInfo->ever) {
@@ -232,13 +226,6 @@ static int32_t tsdbDataFileDataIterNext(STsdbDataIter2* pIter, STsdbFilterInfo*
 
         // filter
         if (pFilterInfo) {
-          if (pFilterInfo->flag & TSDB_FILTER_FLAG_BY_TABLEID) {
-            if (tTABLEIDCmprFn(&pFilterInfo->tbid, &pIter->rowInfo) == 0) {
-              pIter->dIter.iDataBlk = pIter->dIter.mDataBlk.nItem;
-              continue;
-            }
-          }
-
           if (pFilterInfo->flag & TSDB_FILTER_FLAG_BY_VERSION) {
             if (pFilterInfo->sver > dataBlk.maxVer || pFilterInfo->ever < dataBlk.minVer) {
               pIter->dIter.iDataBlk++;
@@ -262,13 +249,23 @@ static int32_t tsdbDataFileDataIterNext(STsdbDataIter2* pIter, STsdbFilterInfo*
         if (pIter->dIter.iBlockIdx < taosArrayGetSize(pIter->dIter.aBlockIdx)) {
           SBlockIdx* pBlockIdx = taosArrayGet(pIter->dIter.aBlockIdx, pIter->dIter.iBlockIdx);
 
-          if (pFilterInfo && (pFilterInfo->flag & TSDB_FILTER_FLAG_BY_TABLEID)) {
-            int32_t c = tTABLEIDCmprFn(pBlockIdx, &pFilterInfo->tbid);
-            if (c == 0) {
-              pIter->dIter.iBlockIdx++;
-              continue;
-            } else if (c < 0) {
-              ASSERT(0);
+          if (pFilterInfo) {
+            if (pFilterInfo->flag & TSDB_FILTER_FLAG_BY_TABLEID) {
+              int32_t c = tTABLEIDCmprFn(pBlockIdx, &pFilterInfo->tbid);
+              if (c == 0) {
+                pIter->dIter.iBlockIdx++;
+                continue;
+              } else if (c < 0) {
+                ASSERT(0);
+              }
+            }
+
+            if (pFilterInfo->flag & TSDB_FILTER_FLAG_IGNORE_DROPPED_TABLE) {
+              SMetaInfo info;
+              if (metaGetInfo(pIter->dIter.pReader->pTsdb->pVnode->pMeta, pBlockIdx->uid, &info, NULL)) {
+                pIter->dIter.iBlockIdx++;
+                continue;
+              }
             }
           }
 
@@ -304,14 +301,24 @@ static int32_t tsdbSttFileDataIterNext(STsdbDataIter2* pIter, STsdbFilterInfo* p
   for (;;) {
     while (pIter->sIter.iRow < pIter->sIter.bData.nRow) {
       if (pFilterInfo) {
+        int64_t uid = pIter->sIter.bData.uid ? pIter->sIter.bData.uid : pIter->sIter.bData.aUid[pIter->sIter.iRow];
         if (pFilterInfo->flag & TSDB_FILTER_FLAG_BY_TABLEID) {
-          int64_t uid = pIter->sIter.bData.uid ? pIter->sIter.bData.uid : pIter->sIter.bData.aUid[pIter->sIter.iRow];
           if (pFilterInfo->tbid.uid == uid) {
             pIter->sIter.iRow++;
             continue;
           }
         }
 
+        if (pFilterInfo->flag & TSDB_FILTER_FLAG_IGNORE_DROPPED_TABLE) {
+          if (pIter->rowInfo.uid != uid) {
+            SMetaInfo info;
+            if (metaGetInfo(pIter->sIter.pReader->pTsdb->pVnode->pMeta, uid, &info, NULL)) {
+              pIter->sIter.iRow++;
+              continue;
+            }
+          }
+        }
+
         if (pFilterInfo->flag & TSDB_FILTER_FLAG_BY_VERSION) {
           if (pFilterInfo->sver > pIter->sIter.bData.aVersion[pIter->sIter.iRow] ||
               pFilterInfo->ever < pIter->sIter.bData.aVersion[pIter->sIter.iRow]) {
@@ -395,6 +402,16 @@ static int32_t tsdbTombFileDataIterNext(STsdbDataIter2* pIter, STsdbFilterInfo*
       if (pIter->tIter.iDelIdx < taosArrayGetSize(pIter->tIter.aDelIdx)) {
         SDelIdx* pDelIdx = taosArrayGet(pIter->tIter.aDelIdx, pIter->tIter.iDelIdx);
 
+        if (pFilterInfo) {
+          if (pFilterInfo->flag & TSDB_FILTER_FLAG_IGNORE_DROPPED_TABLE) {
+            SMetaInfo info;
+            if (metaGetInfo(pIter->dIter.pReader->pTsdb->pVnode->pMeta, pDelIdx->uid, &info, NULL)) {
+              pIter->tIter.iDelIdx++;
+              continue;
+            }
+          }
+        }
+
         code = tsdbReadDelData(pIter->tIter.pReader, pDelIdx, pIter->tIter.aDelData);
         TSDB_CHECK_CODE(code, lino, _exit);
 
diff --git a/source/dnode/vnode/src/tsdb/tsdbMemTable.c b/source/dnode/vnode/src/tsdb/tsdbMemTable.c
index d0ff403bf7..f27a28acb3 100644
--- a/source/dnode/vnode/src/tsdb/tsdbMemTable.c
+++ b/source/dnode/vnode/src/tsdb/tsdbMemTable.c
@@ -13,6 +13,7 @@
  * along with this program. If not, see .
  */
 
+#include 
 #include "tsdb.h"
 
 #define MEM_MIN_HASH 1024
@@ -298,12 +299,12 @@ int64_t tsdbCountTbDataRows(STbData *pTbData) {
   return rowsNum;
 }
 
-void tsdbMemTableCountRows(SMemTable *pMemTable, SHashObj*        pTableMap, int64_t *rowsNum) {
+void tsdbMemTableCountRows(SMemTable *pMemTable, SSHashObj* pTableMap, int64_t *rowsNum) {
   taosRLockLatch(&pMemTable->latch);
   for (int32_t i = 0; i < pMemTable->nBucket; ++i) {
     STbData *pTbData = pMemTable->aBucket[i];
     while (pTbData) {
-      void* p = taosHashGet(pTableMap, &pTbData->uid, sizeof(pTbData->uid));
+      void* p = tSimpleHashGet(pTableMap, &pTbData->uid, sizeof(pTbData->uid));
       if (p == NULL) {
         pTbData = pTbData->next;
         continue;
diff --git a/source/dnode/vnode/src/tsdb/tsdbMergeTree.c b/source/dnode/vnode/src/tsdb/tsdbMergeTree.c
index fa8870835c..79f4a17f65 100644
--- a/source/dnode/vnode/src/tsdb/tsdbMergeTree.c
+++ b/source/dnode/vnode/src/tsdb/tsdbMergeTree.c
@@ -16,22 +16,6 @@
 #include "tsdb.h"
 
 // SLDataIter =================================================
-struct SLDataIter {
-  SRBTreeNode        node;
-  SSttBlk           *pSttBlk;
-  SDataFReader      *pReader;
-  int32_t            iStt;
-  int8_t             backward;
-  int32_t            iSttBlk;
-  int32_t            iRow;
-  SRowInfo           rInfo;
-  uint64_t           uid;
-  STimeWindow        timeWindow;
-  SVersionRange      verRange;
-  SSttBlockLoadInfo *pBlockLoadInfo;
-  bool               ignoreEarlierTs;
-};
-
 SSttBlockLoadInfo *tCreateLastBlockLoadInfo(STSchema *pSchema, int16_t *colList, int32_t numOfCols,
                                             int32_t numOfSttTrigger) {
   SSttBlockLoadInfo *pLoadInfo = taosMemoryCalloc(numOfSttTrigger, sizeof(SSttBlockLoadInfo));
@@ -88,6 +72,10 @@ void getLastBlockLoadInfo(SSttBlockLoadInfo *pLoadInfo, int64_t *blocks, double
 }
 
 void *destroyLastBlockLoadInfo(SSttBlockLoadInfo *pLoadInfo) {
+  if (pLoadInfo == NULL) {
+    return NULL;
+  }
+
   for (int32_t i = 0; i < pLoadInfo->numOfStt; ++i) {
     pLoadInfo[i].currentLoadBlockIndex = 1;
     pLoadInfo[i].blockIndex[0] = -1;
@@ -264,25 +252,21 @@ static int32_t binarySearchForStartRowIndex(uint64_t *uidList, int32_t num, uint
   }
 }
 
-int32_t tLDataIterOpen(struct SLDataIter **pIter, SDataFReader *pReader, int32_t iStt, int8_t backward, uint64_t suid,
+int32_t tLDataIterOpen(struct SLDataIter *pIter, SDataFReader *pReader, int32_t iStt, int8_t backward, uint64_t suid,
                        uint64_t uid, STimeWindow *pTimeWindow, SVersionRange *pRange, SSttBlockLoadInfo *pBlockLoadInfo,
                        const char *idStr, bool strictTimeRange) {
   int32_t code = TSDB_CODE_SUCCESS;
 
-  *pIter = taosMemoryCalloc(1, sizeof(SLDataIter));
-  if (*pIter == NULL) {
-    code = TSDB_CODE_OUT_OF_MEMORY;
-    goto _exit;
-  }
+  pIter->uid = uid;
+  pIter->pReader = pReader;
+  pIter->iStt = iStt;
+  pIter->backward = backward;
+  pIter->verRange.minVer = pRange->minVer;
+  pIter->verRange.maxVer = pRange->maxVer;
+  pIter->timeWindow.skey = pTimeWindow->skey;
+  pIter->timeWindow.ekey = pTimeWindow->ekey;
 
-  (*pIter)->uid = uid;
-  (*pIter)->pReader = pReader;
-  (*pIter)->iStt = iStt;
-  (*pIter)->backward = backward;
-  (*pIter)->verRange = *pRange;
-  (*pIter)->timeWindow = *pTimeWindow;
-
-  (*pIter)->pBlockLoadInfo = pBlockLoadInfo;
+  pIter->pBlockLoadInfo = pBlockLoadInfo;
 
   if (!pBlockLoadInfo->sttBlockLoaded) {
     int64_t st = taosGetTimestampUs();
@@ -290,7 +274,7 @@ int32_t tLDataIterOpen(struct SLDataIter **pIter, SDataFReader *pReader, int32_t
 
     code = tsdbReadSttBlk(pReader, iStt, pBlockLoadInfo->aSttBlk);
     if (code) {
-      goto _exit;
+      return code;
     }
 
     // only apply to the child tables, ordinary tables will not incur this filter procedure.
@@ -306,7 +290,7 @@ int32_t tLDataIterOpen(struct SLDataIter **pIter, SDataFReader *pReader, int32_t
           // no qualified stt block existed
           taosArrayClear(pBlockLoadInfo->aSttBlk);
 
-          (*pIter)->iSttBlk = -1;
+          pIter->iSttBlk = -1;
           double el = (taosGetTimestampUs() - st) / 1000.0;
           tsdbDebug("load the last file info completed, elapsed time:%.2fms, %s", el, idStr);
           return code;
@@ -339,31 +323,27 @@ int32_t tLDataIterOpen(struct SLDataIter **pIter, SDataFReader *pReader, int32_t
   size_t size = taosArrayGetSize(pBlockLoadInfo->aSttBlk);
 
   // find the start block
-  (*pIter)->iSttBlk = binarySearchForStartBlock(pBlockLoadInfo->aSttBlk->pData, size, uid, backward);
-  if ((*pIter)->iSttBlk != -1) {
-    (*pIter)->pSttBlk = taosArrayGet(pBlockLoadInfo->aSttBlk, (*pIter)->iSttBlk);
-    (*pIter)->iRow = ((*pIter)->backward) ? (*pIter)->pSttBlk->nRow : -1;
+  pIter->iSttBlk = binarySearchForStartBlock(pBlockLoadInfo->aSttBlk->pData, size, uid, backward);
+  if (pIter->iSttBlk != -1) {
+    pIter->pSttBlk = taosArrayGet(pBlockLoadInfo->aSttBlk, pIter->iSttBlk);
+    pIter->iRow = (pIter->backward) ? pIter->pSttBlk->nRow : -1;
 
-    if ((!backward) && ((strictTimeRange && (*pIter)->pSttBlk->minKey >= (*pIter)->timeWindow.ekey) ||
-                        (!strictTimeRange && (*pIter)->pSttBlk->minKey > (*pIter)->timeWindow.ekey))) {
-      (*pIter)->pSttBlk = NULL;
+    if ((!backward) && ((strictTimeRange && pIter->pSttBlk->minKey >= pIter->timeWindow.ekey) ||
+                        (!strictTimeRange && pIter->pSttBlk->minKey > pIter->timeWindow.ekey))) {
+      pIter->pSttBlk = NULL;
     }
 
-    if (backward && ((strictTimeRange && (*pIter)->pSttBlk->maxKey <= (*pIter)->timeWindow.skey) ||
-                     (!strictTimeRange && (*pIter)->pSttBlk->maxKey < (*pIter)->timeWindow.skey))) {
-      (*pIter)->pSttBlk = NULL;
-      (*pIter)->ignoreEarlierTs = true;
+    if (backward && ((strictTimeRange && pIter->pSttBlk->maxKey <= pIter->timeWindow.skey) ||
+                     (!strictTimeRange && pIter->pSttBlk->maxKey < pIter->timeWindow.skey))) {
+      pIter->pSttBlk = NULL;
+      pIter->ignoreEarlierTs = true;
     }
   }
 
   return code;
-
-_exit:
-  taosMemoryFree(*pIter);
-  return code;
 }
 
-void tLDataIterClose(SLDataIter *pIter) { taosMemoryFree(pIter); }
+void tLDataIterClose(SLDataIter *pIter) { /*taosMemoryFree(pIter); */}
 
 void tLDataIterNextBlock(SLDataIter *pIter, const char *idStr) {
   int32_t step = pIter->backward ? -1 : 1;
@@ -590,43 +570,38 @@ static FORCE_INLINE int32_t tLDataIterDescCmprFn(const SRBTreeNode *p1, const SR
 
 int32_t tMergeTreeOpen(SMergeTree *pMTree, int8_t backward, SDataFReader *pFReader, uint64_t suid, uint64_t uid,
                        STimeWindow *pTimeWindow, SVersionRange *pVerRange, SSttBlockLoadInfo *pBlockLoadInfo,
-                       bool destroyLoadInfo, const char *idStr, bool strictTimeRange) {
+                       bool destroyLoadInfo, const char *idStr, bool strictTimeRange, SLDataIter* pLDataIter) {
+  int32_t code = TSDB_CODE_SUCCESS;
+
   pMTree->backward = backward;
   pMTree->pIter = NULL;
-  pMTree->pIterList = taosArrayInit(4, POINTER_BYTES);
-  if (pMTree->pIterList == NULL) {
-    return TSDB_CODE_OUT_OF_MEMORY;
-  }
-
   pMTree->idStr = idStr;
+
   if (!pMTree->backward) {  // asc
     tRBTreeCreate(&pMTree->rbt, tLDataIterCmprFn);
   } else {  // desc
     tRBTreeCreate(&pMTree->rbt, tLDataIterDescCmprFn);
   }
-  int32_t code = TSDB_CODE_SUCCESS;
 
   pMTree->pLoadInfo = pBlockLoadInfo;
   pMTree->destroyLoadInfo = destroyLoadInfo;
   pMTree->ignoreEarlierTs = false;
 
   for (int32_t i = 0; i < pFReader->pSet->nSttF; ++i) {  // open all last file
-    struct SLDataIter *pIter = NULL;
-    code = tLDataIterOpen(&pIter, pFReader, i, pMTree->backward, suid, uid, pTimeWindow, pVerRange,
+    memset(&pLDataIter[i], 0, sizeof(SLDataIter));
+    code = tLDataIterOpen(&pLDataIter[i], pFReader, i, pMTree->backward, suid, uid, pTimeWindow, pVerRange,
                           &pMTree->pLoadInfo[i], pMTree->idStr, strictTimeRange);
     if (code != TSDB_CODE_SUCCESS) {
       goto _end;
     }
 
-    bool hasVal = tLDataIterNextRow(pIter, pMTree->idStr);
+    bool hasVal = tLDataIterNextRow(&pLDataIter[i], pMTree->idStr);
     if (hasVal) {
-      taosArrayPush(pMTree->pIterList, &pIter);
-      tMergeTreeAddIter(pMTree, pIter);
+      tMergeTreeAddIter(pMTree, &pLDataIter[i]);
     } else {
       if (!pMTree->ignoreEarlierTs) {
-        pMTree->ignoreEarlierTs = pIter->ignoreEarlierTs;
+        pMTree->ignoreEarlierTs = pLDataIter[i].ignoreEarlierTs;
       }
-      tLDataIterClose(pIter);
     }
   }
 
@@ -674,18 +649,8 @@ bool tMergeTreeNext(SMergeTree *pMTree) {
   return pMTree->pIter != NULL;
 }
 
-TSDBROW tMergeTreeGetRow(SMergeTree *pMTree) { return pMTree->pIter->rInfo.row; }
-
 void tMergeTreeClose(SMergeTree *pMTree) {
-  size_t size = taosArrayGetSize(pMTree->pIterList);
-  for (int32_t i = 0; i < size; ++i) {
-    SLDataIter *pIter = taosArrayGetP(pMTree->pIterList, i);
-    tLDataIterClose(pIter);
-  }
-
-  pMTree->pIterList = taosArrayDestroy(pMTree->pIterList);
   pMTree->pIter = NULL;
-
   if (pMTree->destroyLoadInfo) {
     pMTree->pLoadInfo = destroyLastBlockLoadInfo(pMTree->pLoadInfo);
     pMTree->destroyLoadInfo = false;
diff --git a/source/dnode/vnode/src/tsdb/tsdbRead.c b/source/dnode/vnode/src/tsdb/tsdbRead.c
index 2b6f175158..89cfe19de9 100644
--- a/source/dnode/vnode/src/tsdb/tsdbRead.c
+++ b/source/dnode/vnode/src/tsdb/tsdbRead.c
@@ -18,6 +18,12 @@
 #include "tsimplehash.h"
 
 #define ASCENDING_TRAVERSE(o) (o == TSDB_ORDER_ASC)
+#define getCurrentKeyInLastBlock(_r) ((_r)->currentKey)
+
+typedef enum {
+  READER_STATUS_SUSPEND = 0x1,
+  READER_STATUS_NORMAL = 0x2,
+} EReaderStatus;
 
 typedef enum {
   EXTERNAL_ROWS_PREV = 0x1,
@@ -108,6 +114,7 @@ typedef struct SLastBlockReader {
   uint64_t           uid;
   SMergeTree         mergeTree;
   SSttBlockLoadInfo* pInfo;
+  int64_t            currentKey;
 } SLastBlockReader;
 
 typedef struct SFilesetIter {
@@ -125,12 +132,12 @@ typedef struct SFileDataBlockInfo {
 } SFileDataBlockInfo;
 
 typedef struct SDataBlockIter {
-  int32_t   numOfBlocks;
-  int32_t   index;
-  SArray*   blockList;  // SArray
-  int32_t   order;
-  SDataBlk  block;  // current SDataBlk data
-  SHashObj* pTableMap;
+  int32_t    numOfBlocks;
+  int32_t    index;
+  SArray*    blockList;  // SArray
+  int32_t    order;
+  SDataBlk   block;  // current SDataBlk data
+  SSHashObj* pTableMap;
 } SDataBlockIter;
 
 typedef struct SFileBlockDumpInfo {
@@ -148,7 +155,8 @@ typedef struct STableUidList {
 typedef struct SReaderStatus {
   bool                  loadFromFile;       // check file stage
   bool                  composedDataBlock;  // the returned data block is a composed block or not
-  SHashObj*             pTableMap;          // SHash
+  bool                  mapDataCleaned;     // mapData has been cleaned up alreay or not
+  SSHashObj*            pTableMap;          // SHash
   STableBlockScanInfo** pTableIter;         // table iterator used in building in-memory buffer data blocks.
   STableUidList         uidList;            // check tables in uid order, to avoid the repeatly load of blocks in STT.
   SFileBlockDumpInfo    fBlockDumpInfo;
@@ -156,6 +164,9 @@ typedef struct SReaderStatus {
   SBlockData            fileBlockData;
   SFilesetIter          fileIter;
   SDataBlockIter        blockIter;
+  SLDataIter*           pLDataIter;
+  SRowMerger            merger;
+  SColumnInfoData*      pPrimaryTsCol;      // primary time stamp output col info data
 } SReaderStatus;
 
 typedef struct SBlockInfoBuf {
@@ -165,57 +176,69 @@ typedef struct SBlockInfoBuf {
   int32_t numOfTables;
 } SBlockInfoBuf;
 
+typedef struct STsdbReaderAttr {
+  STSchema*     pSchema;
+  EReadMode     readMode;
+  uint64_t      rowsNum;
+  STimeWindow   window;
+  bool          freeBlock;
+  SVersionRange verRange;
+  int16_t       order;
+} STsdbReaderAttr;
+
+typedef struct SResultBlockInfo {
+  SSDataBlock* pResBlock;
+  bool         freeBlock;
+  int64_t      capacity;
+} SResultBlockInfo;
+
 struct STsdbReader {
   STsdb*             pTsdb;
   SVersionRange      verRange;
   TdThreadMutex      readerMutex;
-  bool               suspended;
+  EReaderStatus      flag;
+  int32_t            code;
   uint64_t           suid;
   int16_t            order;
-  bool               freeBlock;
   EReadMode          readMode;
   uint64_t           rowsNum;
   STimeWindow        window;  // the primary query time window that applies to all queries
-  SSDataBlock*       pResBlock;
-  int32_t            capacity;
+  SResultBlockInfo   resBlockInfo;
   SReaderStatus      status;
   char*              idStr;  // query info handle, for debug purpose
   int32_t            type;   // query type: 1. retrieve all data blocks, 2. retrieve direct prev|next rows
   SBlockLoadSuppInfo suppInfo;
   STsdbReadSnap*     pReadSnap;
   SIOCostSummary     cost;
-  STSchema*          pSchema;  // the newest version schema
-  //  STSchema*          pMemSchema;   // the previous schema for in-memory data, to avoid load schema too many times
-  SSHashObj*    pSchemaMap;   // keep the retrieved schema info, to avoid the overhead by repeatly load schema
-  SDataFReader* pFileReader;  // the file reader
-  SDelFReader*  pDelFReader;  // the del file reader
-  SArray*       pDelIdx;      // del file block index;
-  SBlockInfoBuf blockInfoBuf;
-  int32_t       step;
-  STsdbReader*  innerReader[2];
-  SHashObj**    pIgnoreTables;
+  SHashObj**         pIgnoreTables;
+  STSchema*          pSchema;      // the newest version schema
+  SSHashObj*         pSchemaMap;   // keep the retrieved schema info, to avoid the overhead by repeatly load schema
+  SDataFReader*      pFileReader;  // the file reader
+  SDelFReader*       pDelFReader;  // the del file reader
+  SArray*            pDelIdx;      // del file block index;
+  SBlockInfoBuf      blockInfoBuf;
+  EContentData       step;
+  STsdbReader*       innerReader[2];
 };
 
 static SFileDataBlockInfo* getCurrentBlockInfo(SDataBlockIter* pBlockIter);
 static int      buildDataBlockFromBufImpl(STableBlockScanInfo* pBlockScanInfo, int64_t endKey, int32_t capacity,
                                           STsdbReader* pReader);
 static TSDBROW* getValidMemRow(SIterInfo* pIter, const SArray* pDelList, STsdbReader* pReader);
-static int32_t  doMergeRowsInFileBlocks(SBlockData* pBlockData, STableBlockScanInfo* pScanInfo, STsdbReader* pReader,
-                                        SRowMerger* pMerger);
+static int32_t  doMergeRowsInFileBlocks(SBlockData* pBlockData, STableBlockScanInfo* pScanInfo, STsdbReader* pReader);
 static int32_t  doMergeRowsInLastBlock(SLastBlockReader* pLastBlockReader, STableBlockScanInfo* pScanInfo, int64_t ts,
                                        SRowMerger* pMerger, SVersionRange* pVerRange, const char* id);
-static int32_t  doMergeRowsInBuf(SIterInfo* pIter, uint64_t uid, int64_t ts, SArray* pDelList, SRowMerger* pMerger,
-                                 STsdbReader* pReader);
+static int32_t  doMergeRowsInBuf(SIterInfo* pIter, uint64_t uid, int64_t ts, SArray* pDelList, STsdbReader* pReader);
 static int32_t  doAppendRowFromTSRow(SSDataBlock* pBlock, STsdbReader* pReader, SRow* pTSRow,
-                                     STableBlockScanInfo* pInfo);
+                                     STableBlockScanInfo* pScanInfo);
 static int32_t  doAppendRowFromFileBlock(SSDataBlock* pResBlock, STsdbReader* pReader, SBlockData* pBlockData,
                                          int32_t rowIndex);
 static void     setComposedBlockFlag(STsdbReader* pReader, bool composed);
-static bool     hasBeenDropped(const SArray* pDelList, int32_t* index, TSDBKEY* pKey, int32_t order,
+static bool     hasBeenDropped(const SArray* pDelList, int32_t* index, int64_t key, int64_t ver, int32_t order,
                                SVersionRange* pVerRange);
 
 static int32_t doMergeMemTableMultiRows(TSDBROW* pRow, uint64_t uid, SIterInfo* pIter, SArray* pDelList,
-                                        TSDBROW* pTSRow, STsdbReader* pReader, bool* freeTSRow);
+                                        TSDBROW* pResRow, STsdbReader* pReader, bool* freeTSRow);
 static int32_t doMergeMemIMemRows(TSDBROW* pRow, TSDBROW* piRow, STableBlockScanInfo* pBlockScanInfo,
                                   STsdbReader* pReader, SRow** pTSRow);
 static int32_t mergeRowsInFileBlocks(SBlockData* pBlockData, STableBlockScanInfo* pBlockScanInfo, int64_t key,
@@ -226,7 +249,6 @@ static int32_t initDelSkylineIterator(STableBlockScanInfo* pBlockScanInfo, STsdb
 static STsdb*  getTsdbByRetentions(SVnode* pVnode, TSKEY winSKey, SRetention* retentions, const char* idstr,
                                    int8_t* pLevel);
 static SVersionRange getQueryVerRange(SVnode* pVnode, SQueryTableDataCond* pCond, int8_t level);
-static int64_t       getCurrentKeyInLastBlock(SLastBlockReader* pLastBlockReader);
 static bool          hasDataInLastBlock(SLastBlockReader* pLastBlockReader);
 static int32_t       doBuildDataBlock(STsdbReader* pReader);
 static TSDBKEY       getCurrentKeyInBuf(STableBlockScanInfo* pScanInfo, STsdbReader* pReader);
@@ -234,9 +256,7 @@ static bool          hasDataInFileBlock(const SBlockData* pBlockData, const SFil
 static void          initBlockDumpInfo(STsdbReader* pReader, SDataBlockIter* pBlockIter);
 static int32_t       getInitialDelIndex(const SArray* pDelSkyline, int32_t order);
 
-static STableBlockScanInfo* getTableBlockScanInfo(SHashObj* pTableMap, uint64_t uid, const char* id);
-
-static FORCE_INLINE STSchema* getLatestTableSchema(STsdbReader* pReader, uint64_t uid);
+static STableBlockScanInfo* getTableBlockScanInfo(SSHashObj* pTableMap, uint64_t uid, const char* id);
 
 static bool outOfTimeWindow(int64_t ts, STimeWindow* pWindow) { return (ts > pWindow->ekey) || (ts < pWindow->skey); }
 
@@ -385,12 +405,11 @@ static int32_t uidComparFunc(const void* p1, const void* p2) {
 }
 
 // NOTE: speedup the whole processing by preparing the buffer for STableBlockScanInfo in batch model
-static SHashObj* createDataBlockScanInfo(STsdbReader* pTsdbReader, SBlockInfoBuf* pBuf, const STableKeyInfo* idList,
+static SSHashObj* createDataBlockScanInfo(STsdbReader* pTsdbReader, SBlockInfoBuf* pBuf, const STableKeyInfo* idList,
                                          STableUidList* pUidList, int32_t numOfTables) {
   // allocate buffer in order to load data blocks from file
   // todo use simple hash instead, optimize the memory consumption
-  SHashObj* pTableMap =
-      taosHashInit(numOfTables, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK);
+  SSHashObj* pTableMap = tSimpleHashInit(numOfTables, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT));
   if (pTableMap == NULL) {
     return NULL;
   }
@@ -400,7 +419,7 @@ static SHashObj* createDataBlockScanInfo(STsdbReader* pTsdbReader, SBlockInfoBuf
 
   pUidList->tableUidList = taosMemoryMalloc(numOfTables * sizeof(uint64_t));
   if (pUidList->tableUidList == NULL) {
-    taosHashCleanup(pTableMap);
+    tSimpleHashCleanup(pTableMap);
     return NULL;
   }
 
@@ -422,7 +441,7 @@ static SHashObj* createDataBlockScanInfo(STsdbReader* pTsdbReader, SBlockInfoBuf
       pScanInfo->lastKeyInStt = ekey;
     }
 
-    taosHashPut(pTableMap, &pScanInfo->uid, sizeof(uint64_t), &pScanInfo, POINTER_BYTES);
+    tSimpleHashPut(pTableMap, &pScanInfo->uid, sizeof(uint64_t), &pScanInfo, POINTER_BYTES);
     tsdbTrace("%p check table uid:%" PRId64 " from lastKey:%" PRId64 " %s", pTsdbReader, pScanInfo->uid,
               pScanInfo->lastKey, pTsdbReader->idStr);
   }
@@ -437,9 +456,11 @@ static SHashObj* createDataBlockScanInfo(STsdbReader* pTsdbReader, SBlockInfoBuf
   return pTableMap;
 }
 
-static void resetAllDataBlockScanInfo(SHashObj* pTableMap, int64_t ts, int32_t step) {
-  STableBlockScanInfo** p = NULL;
-  while ((p = taosHashIterate(pTableMap, p)) != NULL) {
+static void resetAllDataBlockScanInfo(SSHashObj* pTableMap, int64_t ts, int32_t step) {
+  void   *p = NULL;
+  int32_t iter = 0;
+
+  while ((p = tSimpleHashIterate(pTableMap, p, &iter)) != NULL) {
     STableBlockScanInfo* pInfo = *(STableBlockScanInfo**)p;
 
     pInfo->iterInit = false;
@@ -479,13 +500,15 @@ static void clearBlockScanInfo(STableBlockScanInfo* p) {
   tMapDataClear(&p->mapData);
 }
 
-static void destroyAllBlockScanInfo(SHashObj* pTableMap) {
+static void destroyAllBlockScanInfo(SSHashObj* pTableMap) {
   void* p = NULL;
-  while ((p = taosHashIterate(pTableMap, p)) != NULL) {
+  int32_t iter = 0;
+
+  while ((p = tSimpleHashIterate(pTableMap, p, &iter)) != NULL) {
     clearBlockScanInfo(*(STableBlockScanInfo**)p);
   }
 
-  taosHashCleanup(pTableMap);
+  tSimpleHashCleanup(pTableMap);
 }
 
 static bool isEmptyQueryTimeWindow(STimeWindow* pWindow) { return pWindow->skey > pWindow->ekey; }
@@ -716,6 +739,21 @@ void tsdbReleaseDataBlock(STsdbReader* pReader) {
   }
 }
 
+static int32_t initResBlockInfo(SResultBlockInfo* pResBlockInfo, int64_t capacity, SSDataBlock* pResBlock, SQueryTableDataCond* pCond) {
+  pResBlockInfo->capacity = capacity;
+  pResBlockInfo->pResBlock = pResBlock;
+  terrno = 0;
+
+  if (pResBlockInfo->pResBlock == NULL) {
+    pResBlockInfo->freeBlock = true;
+    pResBlockInfo->pResBlock = createResBlock(pCond, pResBlockInfo->capacity);
+  } else {
+    pResBlockInfo->freeBlock = false;
+  }
+
+  return terrno;
+}
+
 static int32_t tsdbReaderCreate(SVnode* pVnode, SQueryTableDataCond* pCond, STsdbReader** ppReader, int32_t capacity,
                                 SSDataBlock* pResBlock, const char* idstr) {
   int32_t      code = 0;
@@ -735,21 +773,16 @@ static int32_t tsdbReaderCreate(SVnode* pVnode, SQueryTableDataCond* pCond, STsd
   pReader->pTsdb = getTsdbByRetentions(pVnode, pCond->twindows.skey, pVnode->config.tsdbCfg.retentions, idstr, &level);
   pReader->suid = pCond->suid;
   pReader->order = pCond->order;
-  pReader->capacity = capacity;
-  pReader->pResBlock = pResBlock;
+
   pReader->idStr = (idstr != NULL) ? taosStrdup(idstr) : NULL;
   pReader->verRange = getQueryVerRange(pVnode, pCond, level);
   pReader->type = pCond->type;
   pReader->window = updateQueryTimeWindow(pReader->pTsdb, &pCond->twindows);
   pReader->blockInfoBuf.numPerBucket = 1000;  // 1000 tables per bucket
 
-  if (pReader->pResBlock == NULL) {
-    pReader->freeBlock = true;
-    pReader->pResBlock = createResBlock(pCond, pReader->capacity);
-    if (pReader->pResBlock == NULL) {
-      code = terrno;
-      goto _end;
-    }
+  code = initResBlockInfo(&pReader->resBlockInfo, capacity, pResBlock, pCond);
+  if (code != TSDB_CODE_SUCCESS) {
+    goto _end;
   }
 
   if (pCond->numOfCols <= 0) {
@@ -767,6 +800,7 @@ static int32_t tsdbReaderCreate(SVnode* pVnode, SQueryTableDataCond* pCond, STsd
   }
 
   pSup->tsColAgg.colId = PRIMARYKEY_TIMESTAMP_COL_ID;
+  setColumnIdSlotList(pSup, pCond->colList, pCond->pSlotList, pCond->numOfCols);
 
   code = tBlockDataCreate(&pReader->status.fileBlockData);
   if (code != TSDB_CODE_SUCCESS) {
@@ -774,7 +808,20 @@ static int32_t tsdbReaderCreate(SVnode* pVnode, SQueryTableDataCond* pCond, STsd
     goto _end;
   }
 
-  setColumnIdSlotList(pSup, pCond->colList, pCond->pSlotList, pCond->numOfCols);
+  if (pReader->suppInfo.colId[0] != PRIMARYKEY_TIMESTAMP_COL_ID) {
+    tsdbError("the first column isn't primary timestamp, %d, %s", pReader->suppInfo.colId[0], pReader->idStr);
+    terrno = TSDB_CODE_INVALID_PARA;
+    goto _end;
+  }
+
+  pReader->status.pPrimaryTsCol = taosArrayGet(pReader->resBlockInfo.pResBlock->pDataBlock, pSup->slotId[0]);
+  int32_t type = pReader->status.pPrimaryTsCol->info.type;
+  if (type != TSDB_DATA_TYPE_TIMESTAMP) {
+    tsdbError("the first column isn't primary timestamp in result block, actual: %s, %s", tDataTypes[type].name,
+              pReader->idStr);
+    terrno = TSDB_CODE_INVALID_PARA;
+    goto _end;
+  }
 
   tsdbInitReaderLock(pReader);
 
@@ -795,7 +842,7 @@ static int32_t doLoadBlockIndex(STsdbReader* pReader, SDataFReader* pFileReader,
     goto _end;
   }
 
-  int32_t numOfTables = taosHashGetSize(pReader->status.pTableMap);
+  int32_t numOfTables = tSimpleHashGetSize(pReader->status.pTableMap);
 
   SArray* aBlockIdx = (SArray*)taosLRUCacheValue(pFileReader->pTsdb->biCache, handle);
   size_t  num = taosArrayGetSize(aBlockIdx);
@@ -859,28 +906,42 @@ _end:
   return code;
 }
 
-static void cleanupTableScanInfo(SHashObj* pTableMap) {
+static void doCleanupTableScanInfo(STableBlockScanInfo* pScanInfo) {
+  // reset the index in last block when handing a new file
+  tMapDataClear(&pScanInfo->mapData);
+  taosArrayClear(pScanInfo->pBlockList);
+}
+
+static void cleanupTableScanInfo(SReaderStatus* pStatus) {
+  if (pStatus->mapDataCleaned) {
+    return;
+  }
+
+  SSHashObj* pTableMap = pStatus->pTableMap;
   STableBlockScanInfo** px = NULL;
+  int32_t iter = 0;
+
   while (1) {
-    px = taosHashIterate(pTableMap, px);
+    px = tSimpleHashIterate(pTableMap, px, &iter);
     if (px == NULL) {
       break;
     }
 
-    // reset the index in last block when handing a new file
-    tMapDataClear(&(*px)->mapData);
-    taosArrayClear((*px)->pBlockList);
+    doCleanupTableScanInfo(*px);
   }
+
+  pStatus->mapDataCleaned = true;
 }
 
-static int32_t doLoadFileBlock(STsdbReader* pReader, SArray* pIndexList, SBlockNumber* pBlockNum) {
-  int32_t numOfQTable = 0;
+static int32_t doLoadFileBlock(STsdbReader* pReader, SArray* pIndexList, SBlockNumber* pBlockNum, SArray* pTableScanInfoList) {
   size_t  sizeInDisk = 0;
   size_t  numOfTables = taosArrayGetSize(pIndexList);
 
   int64_t st = taosGetTimestampUs();
-  cleanupTableScanInfo(pReader->status.pTableMap);
+  cleanupTableScanInfo(&pReader->status);
 
+  // set the flag for the new file
+  pReader->status.mapDataCleaned = false;
   for (int32_t i = 0; i < numOfTables; ++i) {
     SBlockIdx*           pBlockIdx = taosArrayGet(pIndexList, i);
     STableBlockScanInfo* pScanInfo = getTableBlockScanInfo(pReader->status.pTableMap, pBlockIdx->uid, pReader->idStr);
@@ -934,7 +995,7 @@ static int32_t doLoadFileBlock(STsdbReader* pReader, SArray* pIndexList, SBlockN
     }
 
     if (taosArrayGetSize(pScanInfo->pBlockList) > 0) {
-      numOfQTable += 1;
+      taosArrayPush(pTableScanInfoList, &pScanInfo);
     }
   }
 
@@ -945,8 +1006,8 @@ static int32_t doLoadFileBlock(STsdbReader* pReader, SArray* pIndexList, SBlockN
   tsdbDebug(
       "load block of %ld tables completed, blocks:%d in %d tables, last-files:%d, block-info-size:%.2f Kb, elapsed "
       "time:%.2f ms %s",
-      numOfTables, pBlockNum->numOfBlocks, numOfQTable, pBlockNum->numOfLastFiles, sizeInDisk / 1000.0, el,
-      pReader->idStr);
+      numOfTables, pBlockNum->numOfBlocks, (int32_t)taosArrayGetSize(pTableScanInfoList), pBlockNum->numOfLastFiles,
+      sizeInDisk / 1000.0, el, pReader->idStr);
 
   pReader->cost.numOfBlocks += total;
   pReader->cost.headFileLoadTime += el;
@@ -1182,7 +1243,7 @@ static int32_t copyBlockDataToSDataBlock(STsdbReader* pReader) {
   SBlockData*         pBlockData = &pStatus->fileBlockData;
   SFileDataBlockInfo* pBlockInfo = getCurrentBlockInfo(pBlockIter);
   SDataBlk*           pBlock = getCurrentBlock(pBlockIter);
-  SSDataBlock*        pResBlock = pReader->pResBlock;
+  SSDataBlock*        pResBlock = pReader->resBlockInfo.pResBlock;
   int32_t             numOfOutputCols = pSupInfo->numOfCols;
   int32_t             code = TSDB_CODE_SUCCESS;
 
@@ -1230,8 +1291,8 @@ static int32_t copyBlockDataToSDataBlock(STsdbReader* pReader) {
 
   endIndex += step;
   int32_t dumpedRows = asc ? (endIndex - pDumpInfo->rowIndex) : (pDumpInfo->rowIndex - endIndex);
-  if (dumpedRows > pReader->capacity) {  // output buffer check
-    dumpedRows = pReader->capacity;
+  if (dumpedRows > pReader->resBlockInfo.capacity) {  // output buffer check
+    dumpedRows = pReader->resBlockInfo.capacity;
   }
 
   int32_t i = 0;
@@ -1313,16 +1374,40 @@ static int32_t copyBlockDataToSDataBlock(STsdbReader* pReader) {
   return TSDB_CODE_SUCCESS;
 }
 
+static FORCE_INLINE STSchema* getTableSchemaImpl(STsdbReader* pReader, uint64_t uid) {
+  ASSERT(pReader->pSchema == NULL);
+
+  int32_t code = metaGetTbTSchemaEx(pReader->pTsdb->pVnode->pMeta, pReader->suid, uid, -1, &pReader->pSchema);
+  if (code != TSDB_CODE_SUCCESS || pReader->pSchema == NULL) {
+    terrno = code;
+    tsdbError("failed to get table schema, uid:%" PRIu64 ", it may have been dropped, ver:-1, %s", uid, pReader->idStr);
+    return NULL;
+  }
+
+  code = tsdbRowMergerInit(&pReader->status.merger, pReader->pSchema);
+  if (code != TSDB_CODE_SUCCESS) {
+    terrno = code;
+    tsdbError("failed to init merger, code:%s, %s", tstrerror(code), pReader->idStr);
+    return NULL;
+  }
+
+  return pReader->pSchema;
+}
+
 static int32_t doLoadFileBlockData(STsdbReader* pReader, SDataBlockIter* pBlockIter, SBlockData* pBlockData,
                                    uint64_t uid) {
-  int32_t code = 0;
-  int64_t st = taosGetTimestampUs();
+  int32_t   code = 0;
+  STSchema* pSchema = pReader->pSchema;
+  int64_t   st = taosGetTimestampUs();
 
   tBlockDataReset(pBlockData);
-  STSchema* pSchema = getLatestTableSchema(pReader, uid);
-  if (pSchema == NULL) {
-    tsdbDebug("%p table uid:%" PRIu64 " has been dropped, no data existed, %s", pReader, uid, pReader->idStr);
-    return code;
+
+  if (pReader->pSchema == NULL) {
+    pSchema = getTableSchemaImpl(pReader, uid);
+    if (pSchema == NULL) {
+      tsdbDebug("%p table uid:%" PRIu64 " has been dropped, no data existed, %s", pReader, uid, pReader->idStr);
+      return code;
+    }
   }
 
   SBlockLoadSuppInfo* pSup = &pReader->suppInfo;
@@ -1425,7 +1510,7 @@ static int32_t doSetCurrentBlock(SDataBlockIter* pBlockIter, const char* idStr)
   return TSDB_CODE_SUCCESS;
 }
 
-static int32_t initBlockIterator(STsdbReader* pReader, SDataBlockIter* pBlockIter, int32_t numOfBlocks) {
+static int32_t initBlockIterator(STsdbReader* pReader, SDataBlockIter* pBlockIter, int32_t numOfBlocks, SArray* pTableList) {
   bool asc = ASCENDING_TRAVERSE(pReader->order);
 
   SBlockOrderSupporter sup = {0};
@@ -1434,7 +1519,7 @@ static int32_t initBlockIterator(STsdbReader* pReader, SDataBlockIter* pBlockIte
   pBlockIter->pTableMap = pReader->status.pTableMap;
 
   // access data blocks according to the offset of each block in asc/desc order.
-  int32_t numOfTables = (int32_t)taosHashGetSize(pReader->status.pTableMap);
+  int32_t numOfTables = taosArrayGetSize(pTableList);
 
   int64_t st = taosGetTimestampUs();
   int32_t code = initBlockOrderSupporter(&sup, numOfTables);
@@ -1443,17 +1528,10 @@ static int32_t initBlockIterator(STsdbReader* pReader, SDataBlockIter* pBlockIte
   }
 
   int32_t cnt = 0;
-  void*   ptr = NULL;
-  while (1) {
-    ptr = taosHashIterate(pReader->status.pTableMap, ptr);
-    if (ptr == NULL) {
-      break;
-    }
 
-    STableBlockScanInfo* pTableScanInfo = *(STableBlockScanInfo**)ptr;
-    if (pTableScanInfo->pBlockList == NULL || taosArrayGetSize(pTableScanInfo->pBlockList) == 0) {
-      continue;
-    }
+  for (int32_t i = 0; i < numOfTables; ++i) {
+    STableBlockScanInfo* pTableScanInfo = taosArrayGetP(pTableList, i);
+    ASSERT(pTableScanInfo->pBlockList != NULL && taosArrayGetSize(pTableScanInfo->pBlockList) > 0);
 
     size_t num = taosArrayGetSize(pTableScanInfo->pBlockList);
     sup.numOfBlocksPerTable[sup.numOfTables] = num;
@@ -1729,7 +1807,7 @@ static void getBlockToLoadInfo(SDataBlockToLoadInfo* pInfo, SFileDataBlockInfo*
     pInfo->overlapWithLastBlock = !(pBlock->maxKey.ts < tsLast || pBlock->minKey.ts > tsLast);
   }
 
-  pInfo->moreThanCapcity = pBlock->nRow > pReader->capacity;
+  pInfo->moreThanCapcity = pBlock->nRow > pReader->resBlockInfo.capacity;
   pInfo->partiallyRequired = dataBlockPartiallyRequired(&pReader->window, &pReader->verRange, pBlock);
   pInfo->overlapWithKeyInBuf = keyOverlapFileBlock(keyInBuf, pBlock, &pReader->verRange);
 }
@@ -1776,10 +1854,10 @@ static int32_t buildDataBlockFromBuf(STsdbReader* pReader, STableBlockScanInfo*
     return TSDB_CODE_SUCCESS;
   }
 
-  SSDataBlock* pBlock = pReader->pResBlock;
+  SSDataBlock* pBlock = pReader->resBlockInfo.pResBlock;
 
   int64_t st = taosGetTimestampUs();
-  int32_t code = buildDataBlockFromBufImpl(pBlockScanInfo, endKey, pReader->capacity, pReader);
+  int32_t code = buildDataBlockFromBufImpl(pBlockScanInfo, endKey, pReader->resBlockInfo.capacity, pReader);
 
   blockDataUpdateTsWindow(pBlock, pReader->suppInfo.slotId[0]);
   pBlock->info.id.uid = pBlockScanInfo->uid;
@@ -1810,7 +1888,7 @@ static bool tryCopyDistinctRowFromFileBlock(STsdbReader* pReader, SBlockData* pB
 
     int64_t nextKey = pBlockData->aTSKEY[pDumpInfo->rowIndex + step];
     if (nextKey != key) {  // merge is not needed
-      code = doAppendRowFromFileBlock(pReader->pResBlock, pReader, pBlockData, pDumpInfo->rowIndex);
+      code = doAppendRowFromFileBlock(pReader->resBlockInfo.pResBlock, pReader, pBlockData, pDumpInfo->rowIndex);
       if (code) {
         return code;
       }
@@ -1833,13 +1911,14 @@ static bool nextRowFromLastBlocks(SLastBlockReader* pLastBlockReader, STableBloc
       return false;
     }
 
-    TSDBROW row = tMergeTreeGetRow(&pLastBlockReader->mergeTree);
-    TSDBKEY k = TSDBROW_KEY(&row);
-    pScanInfo->lastKeyInStt = k.ts;
+    TSDBROW* pRow = tMergeTreeGetRow(&pLastBlockReader->mergeTree);
+    int64_t key = pRow->pBlockData->aTSKEY[pRow->iRow];
+    int64_t ver = pRow->pBlockData->aVersion[pRow->iRow];
 
-    if (!hasBeenDropped(pScanInfo->delSkyline, &pScanInfo->lastBlockDelIndex, &k, pLastBlockReader->order, pVerRange)) {
-      // the qualifed ts may equal to k.ts, only a greater version one.
-      // here we need to fallback one step.
+    pLastBlockReader->currentKey = key;
+    pScanInfo->lastKeyInStt = key;
+
+    if (!hasBeenDropped(pScanInfo->delSkyline, &pScanInfo->lastBlockDelIndex, key, ver, pLastBlockReader->order, pVerRange)) {
       return true;
     }
   }
@@ -1856,7 +1935,7 @@ static bool tryCopyDistinctRowFromSttBlock(TSDBROW* fRow, SLastBlockReader* pLas
   if (hasVal) {
     int64_t next1 = getCurrentKeyInLastBlock(pLastBlockReader);
     if (next1 != ts) {
-      code = doAppendRowFromFileBlock(pReader->pResBlock, pReader, fRow->pBlockData, fRow->iRow);
+      code = doAppendRowFromFileBlock(pReader->resBlockInfo.pResBlock, pReader, fRow->pBlockData, fRow->iRow);
       if (code) {
         return code;
       }
@@ -1865,7 +1944,7 @@ static bool tryCopyDistinctRowFromSttBlock(TSDBROW* fRow, SLastBlockReader* pLas
       return code;
     }
   } else {
-    code = doAppendRowFromFileBlock(pReader->pResBlock, pReader, fRow->pBlockData, fRow->iRow);
+    code = doAppendRowFromFileBlock(pReader->resBlockInfo.pResBlock, pReader, fRow->pBlockData, fRow->iRow);
     if (code) {
       return code;
     }
@@ -1877,27 +1956,11 @@ static bool tryCopyDistinctRowFromSttBlock(TSDBROW* fRow, SLastBlockReader* pLas
   return code;
 }
 
-static FORCE_INLINE STSchema* getLatestTableSchema(STsdbReader* pReader, uint64_t uid) {
-  if (pReader->pSchema != NULL) {
-    return pReader->pSchema;
-  }
-
-  int32_t code = metaGetTbTSchemaEx(pReader->pTsdb->pVnode->pMeta, pReader->suid, uid, -1, &pReader->pSchema);
-  if (code != TSDB_CODE_SUCCESS || pReader->pSchema == NULL) {
-    tsdbError("failed to get table schema, uid:%" PRIu64 ", it may have been dropped, ver:-1, %s", uid, pReader->idStr);
-  }
-
-  return pReader->pSchema;
-}
-
 static FORCE_INLINE STSchema* doGetSchemaForTSRow(int32_t sversion, STsdbReader* pReader, uint64_t uid) {
-  int32_t code = 0;
-
   // always set the newest schema version in pReader->pSchema
   if (pReader->pSchema == NULL) {
-    code = metaGetTbTSchemaEx(pReader->pTsdb->pVnode->pMeta, pReader->suid, uid, -1, &pReader->pSchema);
-    if (code != TSDB_CODE_SUCCESS) {
-      terrno = code;
+    STSchema* ps = getTableSchemaImpl(pReader, uid);
+    if (ps == NULL) {
       return NULL;
     }
   }
@@ -1912,7 +1975,7 @@ static FORCE_INLINE STSchema* doGetSchemaForTSRow(int32_t sversion, STsdbReader*
   }
 
   STSchema* ptr = NULL;
-  code = metaGetTbTSchemaEx(pReader->pTsdb->pVnode->pMeta, pReader->suid, uid, sversion, &ptr);
+  int32_t code = metaGetTbTSchemaEx(pReader->pTsdb->pVnode->pMeta, pReader->suid, uid, sversion, &ptr);
   if (code != TSDB_CODE_SUCCESS) {
     terrno = code;
     return NULL;
@@ -1928,7 +1991,7 @@ static FORCE_INLINE STSchema* doGetSchemaForTSRow(int32_t sversion, STsdbReader*
 
 static int32_t doMergeBufAndFileRows(STsdbReader* pReader, STableBlockScanInfo* pBlockScanInfo, TSDBROW* pRow,
                                      SIterInfo* pIter, int64_t key, SLastBlockReader* pLastBlockReader) {
-  SRowMerger          merge = {0};
+  SRowMerger*         pMerger = &pReader->status.merger;
   SRow*               pTSRow = NULL;
   SBlockData*         pBlockData = &pReader->status.fileBlockData;
   SFileBlockDumpInfo* pDumpInfo = &pReader->status.fBlockDumpInfo;
@@ -1941,6 +2004,15 @@ static int32_t doMergeBufAndFileRows(STsdbReader* pReader, STableBlockScanInfo*
   TSDBKEY k = TSDBROW_KEY(pRow);
   TSDBROW fRow = tsdbRowFromBlockData(pBlockData, pDumpInfo->rowIndex);
 
+  // merge is not initialized yet, due to the fact that the pReader->pSchema is not initialized
+  if (pMerger->pArray == NULL) {
+    ASSERT(pReader->pSchema == NULL);
+    STSchema* ps = getTableSchemaImpl(pReader, pBlockScanInfo->uid);
+    if (ps == NULL) {
+      return terrno;
+    }
+  }
+
   int64_t minKey = 0;
   if (pReader->order == TSDB_ORDER_ASC) {
     minKey = INT64_MAX;  // chosen the minimum value
@@ -1970,32 +2042,33 @@ static int32_t doMergeBufAndFileRows(STsdbReader* pReader, STableBlockScanInfo*
     }
   }
 
+  // todo remove init
   bool init = false;
 
   // ASC: file block ---> last block -----> imem -----> mem
   // DESC: mem -----> imem -----> last block -----> file block
   if (pReader->order == TSDB_ORDER_ASC) {
     if (minKey == key) {
-      init = true;  // todo check if pReader->pSchema is null or not
-      int32_t code = tsdbRowMergerInit(&merge, NULL, &fRow, pReader->pSchema);
+      init = true;
+      int32_t code = tsdbRowMergerAdd(pMerger, &fRow, pReader->pSchema);
       if (code != TSDB_CODE_SUCCESS) {
         return code;
       }
-      doMergeRowsInFileBlocks(pBlockData, pBlockScanInfo, pReader, &merge);
+      doMergeRowsInFileBlocks(pBlockData, pBlockScanInfo, pReader);
     }
 
     if (minKey == tsLast) {
-      TSDBROW fRow1 = tMergeTreeGetRow(&pLastBlockReader->mergeTree);
+      TSDBROW* fRow1 = tMergeTreeGetRow(&pLastBlockReader->mergeTree);
       if (init) {
-        tsdbRowMergerAdd(&merge, &fRow1, NULL);
+        tsdbRowMergerAdd(pMerger, fRow1, NULL);
       } else {
         init = true;
-        int32_t code = tsdbRowMergerInit(&merge, NULL, &fRow1, pReader->pSchema);
+        int32_t code = tsdbRowMergerAdd(pMerger, fRow1, pReader->pSchema);
         if (code != TSDB_CODE_SUCCESS) {
           return code;
         }
       }
-      doMergeRowsInLastBlock(pLastBlockReader, pBlockScanInfo, tsLast, &merge, &pReader->verRange, pReader->idStr);
+      doMergeRowsInLastBlock(pLastBlockReader, pBlockScanInfo, tsLast, pMerger, &pReader->verRange, pReader->idStr);
     }
 
     if (minKey == k.ts) {
@@ -2004,15 +2077,15 @@ static int32_t doMergeBufAndFileRows(STsdbReader* pReader, STableBlockScanInfo*
         return terrno;
       }
       if (init) {
-        tsdbRowMergerAdd(&merge, pRow, pSchema);
+        tsdbRowMergerAdd(pMerger, pRow, pSchema);
       } else {
         init = true;
-        int32_t code = tsdbRowMergerInit(&merge, NULL, pRow, pSchema);
+        int32_t code = tsdbRowMergerAdd(pMerger, pRow, pSchema);
         if (code != TSDB_CODE_SUCCESS) {
           return code;
         }
       }
-      int32_t code = doMergeRowsInBuf(pIter, pBlockScanInfo->uid, k.ts, pBlockScanInfo->delSkyline, &merge, pReader);
+      int32_t code = doMergeRowsInBuf(pIter, pBlockScanInfo->uid, k.ts, pBlockScanInfo->delSkyline, pReader);
       if (code != TSDB_CODE_SUCCESS) {
         return code;
       }
@@ -2025,54 +2098,54 @@ static int32_t doMergeBufAndFileRows(STsdbReader* pReader, STableBlockScanInfo*
         return terrno;
       }
 
-      int32_t   code = tsdbRowMergerInit(&merge, NULL, pRow, pSchema);
+      int32_t   code = tsdbRowMergerAdd(pMerger, pRow, pSchema);
       if (code != TSDB_CODE_SUCCESS) {
         return code;
       }
 
-      code = doMergeRowsInBuf(pIter, pBlockScanInfo->uid, k.ts, pBlockScanInfo->delSkyline, &merge, pReader);
-      if (code != TSDB_CODE_SUCCESS || merge.pTSchema == NULL) {
+      code = doMergeRowsInBuf(pIter, pBlockScanInfo->uid, k.ts, pBlockScanInfo->delSkyline, pReader);
+      if (code != TSDB_CODE_SUCCESS || pMerger->pTSchema == NULL) {
         return code;
       }
     }
 
     if (minKey == tsLast) {
-      TSDBROW fRow1 = tMergeTreeGetRow(&pLastBlockReader->mergeTree);
+      TSDBROW* fRow1 = tMergeTreeGetRow(&pLastBlockReader->mergeTree);
       if (init) {
-        tsdbRowMergerAdd(&merge, &fRow1, NULL);
+        tsdbRowMergerAdd(pMerger, fRow1, NULL);
       } else {
         init = true;
-        int32_t code = tsdbRowMergerInit(&merge, NULL, &fRow1, pReader->pSchema);
+        int32_t code = tsdbRowMergerAdd(pMerger, fRow1, pReader->pSchema);
         if (code != TSDB_CODE_SUCCESS) {
           return code;
         }
       }
-      doMergeRowsInLastBlock(pLastBlockReader, pBlockScanInfo, tsLast, &merge, &pReader->verRange, pReader->idStr);
+      doMergeRowsInLastBlock(pLastBlockReader, pBlockScanInfo, tsLast, pMerger, &pReader->verRange, pReader->idStr);
     }
 
     if (minKey == key) {
       if (init) {
-        tsdbRowMergerAdd(&merge, &fRow, NULL);
+        tsdbRowMergerAdd(pMerger, &fRow, NULL);
       } else {
         init = true;
-        int32_t code = tsdbRowMergerInit(&merge, NULL, &fRow, pReader->pSchema);
+        int32_t code = tsdbRowMergerAdd(pMerger, &fRow, pReader->pSchema);
         if (code != TSDB_CODE_SUCCESS) {
           return code;
         }
       }
-      doMergeRowsInFileBlocks(pBlockData, pBlockScanInfo, pReader, &merge);
+      doMergeRowsInFileBlocks(pBlockData, pBlockScanInfo, pReader);
     }
   }
 
-  int32_t code = tsdbRowMergerGetRow(&merge, &pTSRow);
+  int32_t code = tsdbRowMergerGetRow(pMerger, &pTSRow);
   if (code != TSDB_CODE_SUCCESS) {
     return code;
   }
 
-  code = doAppendRowFromTSRow(pReader->pResBlock, pReader, pTSRow, pBlockScanInfo);
+  code = doAppendRowFromTSRow(pReader->resBlockInfo.pResBlock, pReader, pTSRow, pBlockScanInfo);
 
   taosMemoryFree(pTSRow);
-  tsdbRowMergerClear(&merge);
+  tsdbRowMergerClear(pMerger);
 
   return code;
 }
@@ -2080,14 +2153,19 @@ static int32_t doMergeBufAndFileRows(STsdbReader* pReader, STableBlockScanInfo*
 static int32_t doMergeFileBlockAndLastBlock(SLastBlockReader* pLastBlockReader, STsdbReader* pReader,
                                             STableBlockScanInfo* pBlockScanInfo, SBlockData* pBlockData,
                                             bool mergeBlockData) {
+  SRowMerger* pMerger = &pReader->status.merger;
   SFileBlockDumpInfo* pDumpInfo = &pReader->status.fBlockDumpInfo;
-  int64_t             tsLastBlock = getCurrentKeyInLastBlock(pLastBlockReader);
-  bool                copied = false;
-  int32_t             code = TSDB_CODE_SUCCESS;
-  SRow*               pTSRow = NULL;
-  SRowMerger          merge = {0};
-  TSDBROW             fRow = tMergeTreeGetRow(&pLastBlockReader->mergeTree);
-  tsdbTrace("fRow ptr:%p, %d, uid:%" PRIu64 ", %s", fRow.pBlockData, fRow.iRow, pLastBlockReader->uid, pReader->idStr);
+
+  int64_t  tsLastBlock = getCurrentKeyInLastBlock(pLastBlockReader);
+  bool     copied = false;
+  int32_t  code = TSDB_CODE_SUCCESS;
+  SRow*    pTSRow = NULL;
+  TSDBROW* pRow = tMergeTreeGetRow(&pLastBlockReader->mergeTree);
+
+  // create local variable to hold the row value
+  TSDBROW  fRow = {.iRow = pRow->iRow, .type = TSDBROW_COL_FMT, .pBlockData = pRow->pBlockData};
+
+  tsdbTrace("fRow ptr:%p, %d, uid:%" PRIu64 ", %s", pRow->pBlockData, pRow->iRow, pLastBlockReader->uid, pReader->idStr);
 
   // only last block exists
   if ((!mergeBlockData) || (tsLastBlock != pBlockData->aTSKEY[pDumpInfo->rowIndex])) {
@@ -2100,51 +2178,51 @@ static int32_t doMergeFileBlockAndLastBlock(SLastBlockReader* pLastBlockReader,
       pBlockScanInfo->lastKey = tsLastBlock;
       return TSDB_CODE_SUCCESS;
     } else {
-      code = tsdbRowMergerInit(&merge, NULL, &fRow, pReader->pSchema);
+      code = tsdbRowMergerAdd(pMerger, &fRow, pReader->pSchema);
       if (code != TSDB_CODE_SUCCESS) {
         return code;
       }
 
-      TSDBROW fRow1 = tMergeTreeGetRow(&pLastBlockReader->mergeTree);
-      tsdbRowMergerAdd(&merge, &fRow1, NULL);
-      doMergeRowsInLastBlock(pLastBlockReader, pBlockScanInfo, tsLastBlock, &merge, &pReader->verRange, pReader->idStr);
+      TSDBROW* pRow1 = tMergeTreeGetRow(&pLastBlockReader->mergeTree);
+      tsdbRowMergerAdd(pMerger, pRow1, NULL);
+      doMergeRowsInLastBlock(pLastBlockReader, pBlockScanInfo, tsLastBlock, pMerger, &pReader->verRange, pReader->idStr);
 
-      code = tsdbRowMergerGetRow(&merge, &pTSRow);
+      code = tsdbRowMergerGetRow(pMerger, &pTSRow);
       if (code != TSDB_CODE_SUCCESS) {
         return code;
       }
 
-      code = doAppendRowFromTSRow(pReader->pResBlock, pReader, pTSRow, pBlockScanInfo);
+      code = doAppendRowFromTSRow(pReader->resBlockInfo.pResBlock, pReader, pTSRow, pBlockScanInfo);
 
       taosMemoryFree(pTSRow);
-      tsdbRowMergerClear(&merge);
+      tsdbRowMergerClear(pMerger);
 
       if (code != TSDB_CODE_SUCCESS) {
         return code;
       }
     }
   } else {  // not merge block data
-    code = tsdbRowMergerInit(&merge, NULL, &fRow, pReader->pSchema);
+    code = tsdbRowMergerAdd(pMerger, &fRow, pReader->pSchema);
     if (code != TSDB_CODE_SUCCESS) {
       return code;
     }
 
-    doMergeRowsInLastBlock(pLastBlockReader, pBlockScanInfo, tsLastBlock, &merge, &pReader->verRange, pReader->idStr);
+    doMergeRowsInLastBlock(pLastBlockReader, pBlockScanInfo, tsLastBlock, pMerger, &pReader->verRange, pReader->idStr);
 
     // merge with block data if ts == key
     if (tsLastBlock == pBlockData->aTSKEY[pDumpInfo->rowIndex]) {
-      doMergeRowsInFileBlocks(pBlockData, pBlockScanInfo, pReader, &merge);
+      doMergeRowsInFileBlocks(pBlockData, pBlockScanInfo, pReader);
     }
 
-    code = tsdbRowMergerGetRow(&merge, &pTSRow);
+    code = tsdbRowMergerGetRow(pMerger, &pTSRow);
     if (code != TSDB_CODE_SUCCESS) {
       return code;
     }
 
-    code = doAppendRowFromTSRow(pReader->pResBlock, pReader, pTSRow, pBlockScanInfo);
+    code = doAppendRowFromTSRow(pReader->resBlockInfo.pResBlock, pReader, pTSRow, pBlockScanInfo);
 
     taosMemoryFree(pTSRow);
-    tsdbRowMergerClear(&merge);
+    tsdbRowMergerClear(pMerger);
 
     if (code != TSDB_CODE_SUCCESS) {
       return code;
@@ -2157,6 +2235,16 @@ static int32_t doMergeFileBlockAndLastBlock(SLastBlockReader* pLastBlockReader,
 static int32_t mergeFileBlockAndLastBlock(STsdbReader* pReader, SLastBlockReader* pLastBlockReader, int64_t key,
                                           STableBlockScanInfo* pBlockScanInfo, SBlockData* pBlockData) {
   SFileBlockDumpInfo* pDumpInfo = &pReader->status.fBlockDumpInfo;
+  SRowMerger* pMerger = &pReader->status.merger;
+
+  // merge is not initialized yet, due to the fact that the pReader->pSchema is not initialized
+  if (pMerger->pArray == NULL) {
+    ASSERT(pReader->pSchema == NULL);
+    STSchema* ps = getTableSchemaImpl(pReader, pBlockScanInfo->uid);
+    if (ps == NULL) {
+      return terrno;
+    }
+  }
 
   if (hasDataInFileBlock(pBlockData, pDumpInfo)) {
     // no last block available, only data block exists
@@ -2173,30 +2261,28 @@ static int32_t mergeFileBlockAndLastBlock(STsdbReader* pReader, SLastBlockReader
       if (key < ts) {  // imem, mem are all empty, file blocks (data blocks and last block) exist
         return mergeRowsInFileBlocks(pBlockData, pBlockScanInfo, key, pReader);
       } else if (key == ts) {
-        SRow*      pTSRow = NULL;
-        SRowMerger merge = {0};
-
-        int32_t code = tsdbRowMergerInit(&merge, NULL, &fRow, pReader->pSchema);
+        SRow*       pTSRow = NULL;
+        int32_t code = tsdbRowMergerAdd(pMerger, &fRow, pReader->pSchema);
         if (code != TSDB_CODE_SUCCESS) {
           return code;
         }
 
-        doMergeRowsInFileBlocks(pBlockData, pBlockScanInfo, pReader, &merge);
+        doMergeRowsInFileBlocks(pBlockData, pBlockScanInfo, pReader);
 
-        TSDBROW fRow1 = tMergeTreeGetRow(&pLastBlockReader->mergeTree);
-        tsdbRowMergerAdd(&merge, &fRow1, NULL);
+        TSDBROW* pRow1 = tMergeTreeGetRow(&pLastBlockReader->mergeTree);
+        tsdbRowMergerAdd(pMerger, pRow1, NULL);
 
-        doMergeRowsInLastBlock(pLastBlockReader, pBlockScanInfo, ts, &merge, &pReader->verRange, pReader->idStr);
+        doMergeRowsInLastBlock(pLastBlockReader, pBlockScanInfo, ts, pMerger, &pReader->verRange, pReader->idStr);
 
-        code = tsdbRowMergerGetRow(&merge, &pTSRow);
+        code = tsdbRowMergerGetRow(pMerger, &pTSRow);
         if (code != TSDB_CODE_SUCCESS) {
           return code;
         }
 
-        code = doAppendRowFromTSRow(pReader->pResBlock, pReader, pTSRow, pBlockScanInfo);
+        code = doAppendRowFromTSRow(pReader->resBlockInfo.pResBlock, pReader, pTSRow, pBlockScanInfo);
 
         taosMemoryFree(pTSRow);
-        tsdbRowMergerClear(&merge);
+        tsdbRowMergerClear(pMerger);
         return code;
       } else {
         return TSDB_CODE_SUCCESS;
@@ -2211,7 +2297,7 @@ static int32_t mergeFileBlockAndLastBlock(STsdbReader* pReader, SLastBlockReader
 
 static int32_t doMergeMultiLevelRows(STsdbReader* pReader, STableBlockScanInfo* pBlockScanInfo, SBlockData* pBlockData,
                                      SLastBlockReader* pLastBlockReader) {
-  SRowMerger          merge = {0};
+  SRowMerger*         pMerger = &pReader->status.merger;
   SRow*               pTSRow = NULL;
   int32_t             code = TSDB_CODE_SUCCESS;
   SFileBlockDumpInfo* pDumpInfo = &pReader->status.fBlockDumpInfo;
@@ -2239,6 +2325,15 @@ static int32_t doMergeMultiLevelRows(STsdbReader* pReader, STableBlockScanInfo*
     return code;
   }
 
+  // merge is not initialized yet, due to the fact that the pReader->pSchema is not initialized
+  if (pMerger->pArray == NULL) {
+    ASSERT(pReader->pSchema == NULL);
+    STSchema* ps = getTableSchemaImpl(pReader, pBlockScanInfo->uid);
+    if (ps == NULL) {
+      return terrno;
+    }
+  }
+
   int64_t minKey = 0;
   if (ASCENDING_TRAVERSE(pReader->order)) {
     minKey = INT64_MAX;  // let's find the minimum
@@ -2284,42 +2379,41 @@ static int32_t doMergeMultiLevelRows(STsdbReader* pReader, STableBlockScanInfo*
     if (minKey == key) {
       init = true;
       TSDBROW fRow = tsdbRowFromBlockData(pBlockData, pDumpInfo->rowIndex);
-      code = tsdbRowMergerInit(&merge, NULL, &fRow, pReader->pSchema);
+      code = tsdbRowMergerAdd(pMerger, &fRow, pReader->pSchema);
       if (code != TSDB_CODE_SUCCESS) {
         return code;
       }
 
-      doMergeRowsInFileBlocks(pBlockData, pBlockScanInfo, pReader, &merge);
+      doMergeRowsInFileBlocks(pBlockData, pBlockScanInfo, pReader);
     }
 
     if (minKey == tsLast) {
-      TSDBROW fRow1 = tMergeTreeGetRow(&pLastBlockReader->mergeTree);
+      TSDBROW* pRow1 = tMergeTreeGetRow(&pLastBlockReader->mergeTree);
       if (init) {
-        tsdbRowMergerAdd(&merge, &fRow1, NULL);
+        tsdbRowMergerAdd(pMerger, pRow1, NULL);
       } else {
         init = true;
-        code = tsdbRowMergerInit(&merge, NULL, &fRow1, pReader->pSchema);
+        code = tsdbRowMergerAdd(pMerger, pRow1, pReader->pSchema);
         if (code != TSDB_CODE_SUCCESS) {
           return code;
         }
       }
 
-      doMergeRowsInLastBlock(pLastBlockReader, pBlockScanInfo, tsLast, &merge, &pReader->verRange, pReader->idStr);
+      doMergeRowsInLastBlock(pLastBlockReader, pBlockScanInfo, tsLast, pMerger, &pReader->verRange, pReader->idStr);
     }
 
     if (minKey == ik.ts) {
       if (init) {
-        tsdbRowMergerAdd(&merge, piRow, piSchema);
+        tsdbRowMergerAdd(pMerger, piRow, piSchema);
       } else {
         init = true;
-        code = tsdbRowMergerInit(&merge, pSchema, piRow, piSchema);
+        code = tsdbRowMergerAdd(pMerger, piRow, piSchema);
         if (code != TSDB_CODE_SUCCESS) {
           return code;
         }
       }
 
-      code = doMergeRowsInBuf(&pBlockScanInfo->iiter, pBlockScanInfo->uid, ik.ts, pBlockScanInfo->delSkyline, &merge,
-                              pReader);
+      code = doMergeRowsInBuf(&pBlockScanInfo->iiter, pBlockScanInfo->uid, ik.ts, pBlockScanInfo->delSkyline, pReader);
       if (code != TSDB_CODE_SUCCESS) {
         return code;
       }
@@ -2327,20 +2421,15 @@ static int32_t doMergeMultiLevelRows(STsdbReader* pReader, STableBlockScanInfo*
 
     if (minKey == k.ts) {
       if (init) {
-        if (merge.pTSchema == NULL) {
-          return code;
-        }
-
-        tsdbRowMergerAdd(&merge, pRow, pSchema);
+        tsdbRowMergerAdd(pMerger, pRow, pSchema);
       } else {
         // STSchema* pSchema = doGetSchemaForTSRow(TSDBROW_SVERSION(pRow), pReader, pBlockScanInfo->uid);
-        code = tsdbRowMergerInit(&merge, NULL, pRow, pSchema);
+        code = tsdbRowMergerAdd(pMerger, pRow, pSchema);
         if (code != TSDB_CODE_SUCCESS) {
           return code;
         }
       }
-      code = doMergeRowsInBuf(&pBlockScanInfo->iter, pBlockScanInfo->uid, k.ts, pBlockScanInfo->delSkyline, &merge,
-                              pReader);
+      code = doMergeRowsInBuf(&pBlockScanInfo->iter, pBlockScanInfo->uid, k.ts, pBlockScanInfo->delSkyline, pReader);
       if (code != TSDB_CODE_SUCCESS) {
         return code;
       }
@@ -2348,13 +2437,12 @@ static int32_t doMergeMultiLevelRows(STsdbReader* pReader, STableBlockScanInfo*
   } else {
     if (minKey == k.ts) {
       init = true;
-      code = tsdbRowMergerInit(&merge, NULL, pRow, pSchema);
+      code = tsdbRowMergerAdd(pMerger, pRow, pSchema);
       if (code != TSDB_CODE_SUCCESS) {
         return code;
       }
 
-      code = doMergeRowsInBuf(&pBlockScanInfo->iter, pBlockScanInfo->uid, k.ts, pBlockScanInfo->delSkyline, &merge,
-                              pReader);
+      code = doMergeRowsInBuf(&pBlockScanInfo->iter, pBlockScanInfo->uid, k.ts, pBlockScanInfo->delSkyline, pReader);
       if (code != TSDB_CODE_SUCCESS) {
         return code;
       }
@@ -2362,66 +2450,57 @@ static int32_t doMergeMultiLevelRows(STsdbReader* pReader, STableBlockScanInfo*
 
     if (minKey == ik.ts) {
       if (init) {
-        tsdbRowMergerAdd(&merge, piRow, piSchema);
+        tsdbRowMergerAdd(pMerger, piRow, piSchema);
       } else {
         init = true;
-        // STSchema* pSchema = doGetSchemaForTSRow(TSDBROW_SVERSION(piRow), pReader, pBlockScanInfo->uid);
-        code = tsdbRowMergerInit(&merge, pSchema, piRow, piSchema);
+        code = tsdbRowMergerAdd(pMerger, piRow, piSchema);
         if (code != TSDB_CODE_SUCCESS) {
           return code;
         }
       }
-      code = doMergeRowsInBuf(&pBlockScanInfo->iiter, pBlockScanInfo->uid, ik.ts, pBlockScanInfo->delSkyline, &merge,
-                              pReader);
+      code = doMergeRowsInBuf(&pBlockScanInfo->iiter, pBlockScanInfo->uid, ik.ts, pBlockScanInfo->delSkyline, pReader);
       if (code != TSDB_CODE_SUCCESS) {
         return code;
       }
     }
 
     if (minKey == tsLast) {
-      TSDBROW fRow1 = tMergeTreeGetRow(&pLastBlockReader->mergeTree);
+      TSDBROW* pRow1 = tMergeTreeGetRow(&pLastBlockReader->mergeTree);
       if (init) {
-        tsdbRowMergerAdd(&merge, &fRow1, NULL);
+        tsdbRowMergerAdd(pMerger, pRow1, NULL);
       } else {
         init = true;
-        code = tsdbRowMergerInit(&merge, NULL, &fRow1, pReader->pSchema);
+        code = tsdbRowMergerAdd(pMerger, pRow1, pReader->pSchema);
         if (code != TSDB_CODE_SUCCESS) {
           return code;
         }
       }
-      doMergeRowsInLastBlock(pLastBlockReader, pBlockScanInfo, tsLast, &merge, &pReader->verRange, pReader->idStr);
+      doMergeRowsInLastBlock(pLastBlockReader, pBlockScanInfo, tsLast, pMerger, &pReader->verRange, pReader->idStr);
     }
 
     if (minKey == key) {
       TSDBROW fRow = tsdbRowFromBlockData(pBlockData, pDumpInfo->rowIndex);
       if (!init) {
-        code = tsdbRowMergerInit(&merge, NULL, &fRow, pReader->pSchema);
+        code = tsdbRowMergerAdd(pMerger, &fRow, pReader->pSchema);
         if (code != TSDB_CODE_SUCCESS) {
           return code;
         }
       } else {
-        if (merge.pTSchema == NULL) {
-          return code;
-        }
-        tsdbRowMergerAdd(&merge, &fRow, NULL);
+        tsdbRowMergerAdd(pMerger, &fRow, NULL);
       }
-      doMergeRowsInFileBlocks(pBlockData, pBlockScanInfo, pReader, &merge);
+      doMergeRowsInFileBlocks(pBlockData, pBlockScanInfo, pReader);
     }
   }
 
-  if (merge.pTSchema == NULL) {
-    return code;
-  }
-
-  code = tsdbRowMergerGetRow(&merge, &pTSRow);
+  code = tsdbRowMergerGetRow(pMerger, &pTSRow);
   if (code != TSDB_CODE_SUCCESS) {
     return code;
   }
 
-  code = doAppendRowFromTSRow(pReader->pResBlock, pReader, pTSRow, pBlockScanInfo);
+  code = doAppendRowFromTSRow(pReader->resBlockInfo.pResBlock, pReader, pTSRow, pBlockScanInfo);
 
   taosMemoryFree(pTSRow);
-  tsdbRowMergerClear(&merge);
+  tsdbRowMergerClear(pMerger);
   return code;
 }
 
@@ -2515,8 +2594,7 @@ static bool isValidFileBlockRow(SBlockData* pBlockData, SFileBlockDumpInfo* pDum
     return false;
   }
 
-  TSDBKEY k = {.ts = ts, .version = ver};
-  if (hasBeenDropped(pBlockScanInfo->delSkyline, &pBlockScanInfo->fileDelIndex, &k, pReader->order,
+  if (hasBeenDropped(pBlockScanInfo->delSkyline, &pBlockScanInfo->fileDelIndex, ts, ver, pReader->order,
                      &pReader->verRange)) {
     return false;
   }
@@ -2548,7 +2626,7 @@ static bool initLastBlockReader(SLastBlockReader* pLBlockReader, STableBlockScan
             pScanInfo->uid, pReader->idStr);
   int32_t code = tMergeTreeOpen(&pLBlockReader->mergeTree, (pLBlockReader->order == TSDB_ORDER_DESC),
                                 pReader->pFileReader, pReader->suid, pScanInfo->uid, &w, &pLBlockReader->verRange,
-                                pLBlockReader->pInfo, false, pReader->idStr, false);
+                                pLBlockReader->pInfo, false, pReader->idStr, false, pReader->status.pLDataIter);
   if (code != TSDB_CODE_SUCCESS) {
     return false;
   }
@@ -2556,11 +2634,6 @@ static bool initLastBlockReader(SLastBlockReader* pLBlockReader, STableBlockScan
   return nextRowFromLastBlocks(pLBlockReader, pScanInfo, &pReader->verRange);
 }
 
-static int64_t getCurrentKeyInLastBlock(SLastBlockReader* pLastBlockReader) {
-  TSDBROW row = tMergeTreeGetRow(&pLastBlockReader->mergeTree);
-  return TSDBROW_TS(&row);
-}
-
 static bool hasDataInLastBlock(SLastBlockReader* pLastBlockReader) { return pLastBlockReader->mergeTree.pIter != NULL; }
 
 bool hasDataInFileBlock(const SBlockData* pBlockData, const SFileBlockDumpInfo* pDumpInfo) {
@@ -2572,6 +2645,7 @@ bool hasDataInFileBlock(const SBlockData* pBlockData, const SFileBlockDumpInfo*
 
 int32_t mergeRowsInFileBlocks(SBlockData* pBlockData, STableBlockScanInfo* pBlockScanInfo, int64_t key,
                               STsdbReader* pReader) {
+  SRowMerger*         pMerger = &pReader->status.merger;
   SFileBlockDumpInfo* pDumpInfo = &pReader->status.fBlockDumpInfo;
   bool                copied = false;
   int32_t             code = tryCopyDistinctRowFromFileBlock(pReader, pBlockData, key, pDumpInfo, &copied);
@@ -2579,6 +2653,15 @@ int32_t mergeRowsInFileBlocks(SBlockData* pBlockData, STableBlockScanInfo* pBloc
     return code;
   }
 
+  // merge is not initialized yet, due to the fact that the pReader->pSchema is not initialized
+  if (pMerger->pArray == NULL) {
+    ASSERT(pReader->pSchema == NULL);
+    STSchema* ps = getTableSchemaImpl(pReader, pBlockScanInfo->uid);
+    if (ps == NULL) {
+      return terrno;
+    }
+  }
+
   if (copied) {
     pBlockScanInfo->lastKey = key;
     return TSDB_CODE_SUCCESS;
@@ -2586,23 +2669,21 @@ int32_t mergeRowsInFileBlocks(SBlockData* pBlockData, STableBlockScanInfo* pBloc
     TSDBROW fRow = tsdbRowFromBlockData(pBlockData, pDumpInfo->rowIndex);
 
     SRow*      pTSRow = NULL;
-    SRowMerger merge = {0};
-
-    code = tsdbRowMergerInit(&merge, NULL, &fRow, pReader->pSchema);
+    code = tsdbRowMergerAdd(pMerger, &fRow, pReader->pSchema);
     if (code != TSDB_CODE_SUCCESS) {
       return code;
     }
 
-    doMergeRowsInFileBlocks(pBlockData, pBlockScanInfo, pReader, &merge);
-    code = tsdbRowMergerGetRow(&merge, &pTSRow);
+    doMergeRowsInFileBlocks(pBlockData, pBlockScanInfo, pReader);
+    code = tsdbRowMergerGetRow(pMerger, &pTSRow);
     if (code != TSDB_CODE_SUCCESS) {
       return code;
     }
 
-    code = doAppendRowFromTSRow(pReader->pResBlock, pReader, pTSRow, pBlockScanInfo);
+    code = doAppendRowFromTSRow(pReader->resBlockInfo.pResBlock, pReader, pTSRow, pBlockScanInfo);
 
     taosMemoryFree(pTSRow);
-    tsdbRowMergerClear(&merge);
+    tsdbRowMergerClear(pMerger);
     return code;
   }
 }
@@ -2681,7 +2762,7 @@ static int32_t loadNeighborIfOverlap(SFileDataBlockInfo* pBlockInfo, STableBlock
 }
 
 static void updateComposedBlockInfo(STsdbReader* pReader, double el, STableBlockScanInfo* pBlockScanInfo) {
-  SSDataBlock* pResBlock = pReader->pResBlock;
+  SSDataBlock* pResBlock = pReader->resBlockInfo.pResBlock;
 
   pResBlock->info.id.uid = (pBlockScanInfo != NULL) ? pBlockScanInfo->uid : 0;
   pResBlock->info.dataLoad = 1;
@@ -2696,7 +2777,7 @@ static void updateComposedBlockInfo(STsdbReader* pReader, double el, STableBlock
 static int32_t buildComposedDataBlock(STsdbReader* pReader) {
   int32_t code = TSDB_CODE_SUCCESS;
 
-  SSDataBlock* pResBlock = pReader->pResBlock;
+  SSDataBlock* pResBlock = pReader->resBlockInfo.pResBlock;
 
   SFileDataBlockInfo* pBlockInfo = getCurrentBlockInfo(&pReader->status.blockIter);
   SLastBlockReader*   pLastBlockReader = pReader->status.fileIter.pLastBlockReader;
@@ -2724,7 +2805,7 @@ static int32_t buildComposedDataBlock(STsdbReader* pReader) {
 
     // it is a clean block, load it directly
     if (isCleanFileDataBlock(pReader, pBlockInfo, pBlock, pBlockScanInfo, keyInBuf, pLastBlockReader) &&
-        pBlock->nRow <= pReader->capacity) {
+        pBlock->nRow <= pReader->resBlockInfo.capacity) {
       if (asc || ((!asc) && (!hasDataInLastBlock(pLastBlockReader)))) {
         code = copyBlockDataToSDataBlock(pReader);
         if (code) {
@@ -2791,7 +2872,7 @@ static int32_t buildComposedDataBlock(STsdbReader* pReader) {
       break;
     }
 
-    if (pResBlock->info.rows >= pReader->capacity) {
+    if (pResBlock->info.rows >= pReader->resBlockInfo.capacity) {
       break;
     }
   }
@@ -2915,18 +2996,24 @@ TSDBKEY getCurrentKeyInBuf(STableBlockScanInfo* pScanInfo, STsdbReader* pReader)
   }
 }
 
-static int32_t moveToNextFile(STsdbReader* pReader, SBlockNumber* pBlockNum) {
+static int32_t moveToNextFile(STsdbReader* pReader, SBlockNumber* pBlockNum, SArray* pTableList) {
   SReaderStatus* pStatus = &pReader->status;
   pBlockNum->numOfBlocks = 0;
   pBlockNum->numOfLastFiles = 0;
 
-  size_t  numOfTables = taosHashGetSize(pReader->status.pTableMap);
+  size_t  numOfTables = tSimpleHashGetSize(pReader->status.pTableMap);
   SArray* pIndexList = taosArrayInit(numOfTables, sizeof(SBlockIdx));
 
   while (1) {
+    // only check here, since the iterate data in memory is very fast.
+    if (pReader->code != TSDB_CODE_SUCCESS) {
+      tsdbWarn("tsdb reader is stopped ASAP, code:%s, %s", strerror(pReader->code), pReader->idStr);
+      return pReader->code;
+    }
+
     bool    hasNext = false;
     int32_t code = filesetIteratorNext(&pStatus->fileIter, pReader, &hasNext);
-    if (code) {
+    if (code != TSDB_CODE_SUCCESS) {
       taosArrayDestroy(pIndexList);
       return code;
     }
@@ -2943,7 +3030,7 @@ static int32_t moveToNextFile(STsdbReader* pReader, SBlockNumber* pBlockNum) {
     }
 
     if (taosArrayGetSize(pIndexList) > 0 || pReader->pFileReader->pSet->nSttF > 0) {
-      code = doLoadFileBlock(pReader, pIndexList, pBlockNum);
+      code = doLoadFileBlock(pReader, pIndexList, pBlockNum, pTableList);
       if (code != TSDB_CODE_SUCCESS) {
         taosArrayDestroy(pIndexList);
         return code;
@@ -2989,18 +3076,18 @@ static void resetTableListIndex(SReaderStatus* pStatus) {
 
   pList->currentIndex = 0;
   uint64_t uid = pList->tableUidList[0];
-  pStatus->pTableIter = taosHashGet(pStatus->pTableMap, &uid, sizeof(uid));
+  pStatus->pTableIter = tSimpleHashGet(pStatus->pTableMap, &uid, sizeof(uid));
 }
 
 static bool moveToNextTable(STableUidList* pOrderedCheckInfo, SReaderStatus* pStatus) {
   pOrderedCheckInfo->currentIndex += 1;
-  if (pOrderedCheckInfo->currentIndex >= taosHashGetSize(pStatus->pTableMap)) {
+  if (pOrderedCheckInfo->currentIndex >= tSimpleHashGetSize(pStatus->pTableMap)) {
     pStatus->pTableIter = NULL;
     return false;
   }
 
   uint64_t uid = pOrderedCheckInfo->tableUidList[pOrderedCheckInfo->currentIndex];
-  pStatus->pTableIter = taosHashGet(pStatus->pTableMap, &uid, sizeof(uid));
+  pStatus->pTableIter = tSimpleHashGet(pStatus->pTableMap, &uid, sizeof(uid));
   return (pStatus->pTableIter != NULL);
 }
 
@@ -3010,13 +3097,18 @@ static int32_t doLoadLastBlockSequentially(STsdbReader* pReader) {
   STableUidList*    pUidList = &pStatus->uidList;
   int32_t           code = TSDB_CODE_SUCCESS;
 
-  if (taosHashGetSize(pStatus->pTableMap) == 0) {
+  if (tSimpleHashGetSize(pStatus->pTableMap) == 0) {
     return TSDB_CODE_SUCCESS;
   }
 
-  SSDataBlock* pResBlock = pReader->pResBlock;
+  SSDataBlock* pResBlock = pReader->resBlockInfo.pResBlock;
 
   while (1) {
+    if (pReader->code != TSDB_CODE_SUCCESS) {
+      tsdbWarn("tsdb reader is stopped ASAP, code:%s, %s", strerror(pReader->code), pReader->idStr);
+      return pReader->code;
+    }
+
     // load the last data block of current table
     STableBlockScanInfo* pScanInfo = *(STableBlockScanInfo**)pStatus->pTableIter;
     if (*pReader->pIgnoreTables && taosHashGet(*pReader->pIgnoreTables, &pScanInfo->uid, sizeof(pScanInfo->uid))) {
@@ -3028,8 +3120,12 @@ static int32_t doLoadLastBlockSequentially(STsdbReader* pReader) {
       continue;
     }
 
-    bool hasVal = initLastBlockReader(pLastBlockReader, pScanInfo, pReader);
-    if (!hasVal) {
+    // reset the index in last block when handing a new file
+    doCleanupTableScanInfo(pScanInfo);
+    pStatus->mapDataCleaned = true;
+
+    bool hasDataInLastFile = initLastBlockReader(pLastBlockReader, pScanInfo, pReader);
+    if (!hasDataInLastFile) {
       bool hasNexTable = moveToNextTable(pUidList, pStatus);
       if (!hasNexTable) {
         return TSDB_CODE_SUCCESS;
@@ -3052,7 +3148,7 @@ static int32_t doLoadLastBlockSequentially(STsdbReader* pReader) {
         return code;
       }
 
-      if (pResBlock->info.rows >= pReader->capacity) {
+      if (pResBlock->info.rows >= pReader->resBlockInfo.capacity) {
         break;
       }
     }
@@ -3122,7 +3218,7 @@ static int32_t doBuildDataBlock(STsdbReader* pReader) {
       SBlockData* pBData = &pReader->status.fileBlockData;
       tBlockDataReset(pBData);
 
-      SSDataBlock* pResBlock = pReader->pResBlock;
+      SSDataBlock* pResBlock = pReader->resBlockInfo.pResBlock;
       tsdbDebug("load data in last block firstly, due to desc scan data, %s", pReader->idStr);
 
       int64_t st = taosGetTimestampUs();
@@ -3140,7 +3236,7 @@ static int32_t doBuildDataBlock(STsdbReader* pReader) {
           return code;
         }
 
-        if (pResBlock->info.rows >= pReader->capacity) {
+        if (pResBlock->info.rows >= pReader->resBlockInfo.capacity) {
           break;
         }
       }
@@ -3155,7 +3251,7 @@ static int32_t doBuildDataBlock(STsdbReader* pReader) {
                   pResBlock->info.rows, el, pReader->idStr);
       }
     } else {  // whole block is required, return it directly
-      SDataBlockInfo* pInfo = &pReader->pResBlock->info;
+      SDataBlockInfo* pInfo = &pReader->resBlockInfo.pResBlock->info;
       pInfo->rows = pBlock->nRow;
       pInfo->id.uid = pScanInfo->uid;
       pInfo->dataLoad = 0;
@@ -3173,7 +3269,7 @@ static int32_t doBuildDataBlock(STsdbReader* pReader) {
     }
   }
 
-  return code;
+  return (pReader->code != TSDB_CODE_SUCCESS)? pReader->code:code;
 }
 
 static int32_t doSumFileBlockRows(STsdbReader* pReader, SDataFReader* pFileReader) {
@@ -3184,7 +3280,7 @@ static int32_t doSumFileBlockRows(STsdbReader* pReader, SDataFReader* pFileReade
     goto _end;
   }
 
-  int32_t numOfTables = taosHashGetSize(pReader->status.pTableMap);
+  int32_t numOfTables = tSimpleHashGetSize(pReader->status.pTableMap);
 
   SArray* aBlockIdx = (SArray*)taosLRUCacheValue(pFileReader->pTsdb->biCache, handle);
   size_t  num = taosArrayGetSize(aBlockIdx);
@@ -3194,14 +3290,13 @@ static int32_t doSumFileBlockRows(STsdbReader* pReader, SDataFReader* pFileReade
   }
 
   SBlockIdx* pBlockIdx = NULL;
-  int32_t    i = 0;
   for (int32_t i = 0; i < num; ++i) {
     pBlockIdx = (SBlockIdx*)taosArrayGet(aBlockIdx, i);
     if (pBlockIdx->suid != pReader->suid) {
       continue;
     }
 
-    STableBlockScanInfo** p = taosHashGet(pReader->status.pTableMap, &pBlockIdx->uid, sizeof(pBlockIdx->uid));
+    STableBlockScanInfo** p = tSimpleHashGet(pReader->status.pTableMap, &pBlockIdx->uid, sizeof(pBlockIdx->uid));
     if (p == NULL) {
       continue;
     }
@@ -3247,13 +3342,13 @@ static int32_t doSumSttBlockRows(STsdbReader* pReader) {
           taosArrayClear(pBlockLoadInfo->aSttBlk);
           continue;
         }
-        for (int32_t i = 0; i < size; ++i) {
-          SSttBlk* p = taosArrayGet(pBlockLoadInfo->aSttBlk, i);
+        for (int32_t j = 0; j < size; ++j) {
+          SSttBlk* p = taosArrayGet(pBlockLoadInfo->aSttBlk, j);
           pReader->rowsNum += p->nRow;
         }
       } else {
-        for (int32_t i = 0; i < size; ++i) {
-          SSttBlk* p = taosArrayGet(pBlockLoadInfo->aSttBlk, i);
+        for (int32_t j = 0; j < size; ++j) {
+          SSttBlk* p = taosArrayGet(pBlockLoadInfo->aSttBlk, j);
           uint64_t s = p->suid;
           if (s < pReader->suid) {
             continue;
@@ -3323,12 +3418,10 @@ static int32_t buildBlockFromBufferSequentially(STsdbReader* pReader) {
   STableUidList* pUidList = &pStatus->uidList;
 
   while (1) {
-    //    if (pStatus->pTableIter == NULL) {
-    //      pStatus->pTableIter = taosHashIterate(pStatus->pTableMap, NULL);
-    //      if (pStatus->pTableIter == NULL) {
-    //        return TSDB_CODE_SUCCESS;
-    //      }
-    //    }
+    if (pReader->code != TSDB_CODE_SUCCESS) {
+      tsdbWarn("tsdb reader is stopped ASAP, code:%s, %s", strerror(pReader->code), pReader->idStr);
+      return pReader->code;
+    }
 
     STableBlockScanInfo** pBlockScanInfo = pStatus->pTableIter;
     if (*pReader->pIgnoreTables && taosHashGet(*pReader->pIgnoreTables, &(*pBlockScanInfo)->uid, sizeof((*pBlockScanInfo)->uid))) {
@@ -3346,7 +3439,7 @@ static int32_t buildBlockFromBufferSequentially(STsdbReader* pReader) {
       return code;
     }
 
-    if (pReader->pResBlock->info.rows > 0) {
+    if (pReader->resBlockInfo.pResBlock->info.rows > 0) {
       return TSDB_CODE_SUCCESS;
     }
 
@@ -3364,7 +3457,7 @@ static void initBlockDumpInfo(STsdbReader* pReader, SDataBlockIter* pBlockIter)
   SDataBlk*           pBlock = getCurrentBlock(pBlockIter);
   SFileDataBlockInfo* pBlockInfo = getCurrentBlockInfo(pBlockIter);
   if (pBlockInfo) {
-    STableBlockScanInfo* pScanInfo = taosHashGet(pBlockIter->pTableMap, &pBlockInfo->uid, sizeof(pBlockInfo->uid));
+    STableBlockScanInfo* pScanInfo = tSimpleHashGet(pBlockIter->pTableMap, &pBlockInfo->uid, sizeof(pBlockInfo->uid));
     if (pScanInfo) {
       lastKey = pScanInfo->lastKey;
     }
@@ -3381,20 +3474,24 @@ static void initBlockDumpInfo(STsdbReader* pReader, SDataBlockIter* pBlockIter)
 
 static int32_t initForFirstBlockInFile(STsdbReader* pReader, SDataBlockIter* pBlockIter) {
   SBlockNumber num = {0};
-  int32_t      code = moveToNextFile(pReader, &num);
+  SArray* pTableList = taosArrayInit(40, POINTER_BYTES);
+
+  int32_t code = moveToNextFile(pReader, &num, pTableList);
   if (code != TSDB_CODE_SUCCESS) {
+    taosArrayDestroy(pTableList);
     return code;
   }
 
   // all data files are consumed, try data in buffer
   if (num.numOfBlocks + num.numOfLastFiles == 0) {
     pReader->status.loadFromFile = false;
+    taosArrayDestroy(pTableList);
     return code;
   }
 
   // initialize the block iterator for a new fileset
   if (num.numOfBlocks > 0) {
-    code = initBlockIterator(pReader, pBlockIter, num.numOfBlocks);
+    code = initBlockIterator(pReader, pBlockIter, num.numOfBlocks, pTableList);
   } else {  // no block data, only last block exists
     tBlockDataReset(&pReader->status.fileBlockData);
     resetDataBlockIterator(pBlockIter, pReader->order);
@@ -3403,6 +3500,7 @@ static int32_t initForFirstBlockInFile(STsdbReader* pReader, SDataBlockIter* pBl
 
   // set the correct start position according to the query time window
   initBlockDumpInfo(pReader, pBlockIter);
+  taosArrayDestroy(pTableList);
   return code;
 }
 
@@ -3411,47 +3509,65 @@ static bool fileBlockPartiallyRead(SFileBlockDumpInfo* pDumpInfo, bool asc) {
          ((pDumpInfo->rowIndex > 0 && asc) || (pDumpInfo->rowIndex < (pDumpInfo->totalRows - 1) && (!asc)));
 }
 
+typedef enum {
+  TSDB_READ_RETURN = 0x1,
+  TSDB_READ_CONTINUE = 0x2,
+} ERetrieveType;
+
+static ERetrieveType doReadDataFromLastFiles(STsdbReader* pReader) {
+  int32_t         code = TSDB_CODE_SUCCESS;
+  SSDataBlock*    pResBlock = pReader->resBlockInfo.pResBlock;
+  SDataBlockIter* pBlockIter = &pReader->status.blockIter;
+
+  while(1) {
+    terrno = 0;
+
+    code = doLoadLastBlockSequentially(pReader);
+    if (code != TSDB_CODE_SUCCESS) {
+      terrno = code;
+      return TSDB_READ_RETURN;
+    }
+
+    if (pResBlock->info.rows > 0) {
+      return TSDB_READ_RETURN;
+    }
+
+    // all data blocks are checked in this last block file, now let's try the next file
+    ASSERT(pReader->status.pTableIter == NULL);
+    code = initForFirstBlockInFile(pReader, pBlockIter);
+
+    // error happens or all the data files are completely checked
+    if ((code != TSDB_CODE_SUCCESS) || (pReader->status.loadFromFile == false)) {
+      terrno = code;
+      return TSDB_READ_RETURN;
+    }
+
+    if (pBlockIter->numOfBlocks > 0) { // there are data blocks existed.
+      return TSDB_READ_CONTINUE;
+    } else {  // all blocks in data file are checked, let's check the data in last files
+      resetTableListIndex(&pReader->status);
+    }
+  }
+}
+
 static int32_t buildBlockFromFiles(STsdbReader* pReader) {
   int32_t code = TSDB_CODE_SUCCESS;
   bool    asc = ASCENDING_TRAVERSE(pReader->order);
 
   SDataBlockIter* pBlockIter = &pReader->status.blockIter;
+  SSDataBlock* pResBlock = pReader->resBlockInfo.pResBlock;
 
   if (pBlockIter->numOfBlocks == 0) {
-  _begin:
-    code = doLoadLastBlockSequentially(pReader);
-    if (code != TSDB_CODE_SUCCESS) {
-      return code;
-    }
-
-    if (pReader->pResBlock->info.rows > 0) {
-      return TSDB_CODE_SUCCESS;
-    }
-
-    // all data blocks are checked in this last block file, now let's try the next file
-    if (pReader->status.pTableIter == NULL) {
-      code = initForFirstBlockInFile(pReader, pBlockIter);
-
-      // error happens or all the data files are completely checked
-      if ((code != TSDB_CODE_SUCCESS) || (pReader->status.loadFromFile == false)) {
-        return code;
-      }
-
-      // this file does not have data files, let's start check the last block file if exists
-      if (pBlockIter->numOfBlocks == 0) {
-        resetTableListIndex(&pReader->status);
-        goto _begin;
-      }
+    // let's try to extract data from stt files.
+    ERetrieveType type = doReadDataFromLastFiles(pReader);
+    if (type == TSDB_READ_RETURN) {
+      return terrno;
     }
 
     code = doBuildDataBlock(pReader);
-    if (code != TSDB_CODE_SUCCESS) {
+    if (code != TSDB_CODE_SUCCESS || pResBlock->info.rows > 0) {
       return code;
     }
-
-    if (pReader->pResBlock->info.rows > 0) {
-      return TSDB_CODE_SUCCESS;
-    }
   }
 
   while (1) {
@@ -3467,30 +3583,22 @@ static int32_t buildBlockFromFiles(STsdbReader* pReader) {
         if (hasNext) {  // check for the next block in the block accessed order list
           initBlockDumpInfo(pReader, pBlockIter);
         } else {
-          if (pReader->status.pCurrentFileset->nSttF > 0) {
-            // data blocks in current file are exhausted, let's try the next file now
-            SBlockData* pBlockData = &pReader->status.fileBlockData;
-            if (pBlockData->uid != 0) {
-              tBlockDataClear(pBlockData);
-            }
+          // all data blocks in files are checked, let's check the data in last files.
+          ASSERT(pReader->status.pCurrentFileset->nSttF > 0);
 
-            tBlockDataReset(pBlockData);
-            resetDataBlockIterator(pBlockIter, pReader->order);
-            resetTableListIndex(&pReader->status);
-            goto _begin;
-          } else {
-            code = initForFirstBlockInFile(pReader, pBlockIter);
+          // data blocks in current file are exhausted, let's try the next file now
+          SBlockData* pBlockData = &pReader->status.fileBlockData;
+          if (pBlockData->uid != 0) {
+            tBlockDataClear(pBlockData);
+          }
 
-            // error happens or all the data files are completely checked
-            if ((code != TSDB_CODE_SUCCESS) || (pReader->status.loadFromFile == false)) {
-              return code;
-            }
+          tBlockDataReset(pBlockData);
+          resetDataBlockIterator(pBlockIter, pReader->order);
+          resetTableListIndex(&pReader->status);
 
-            // this file does not have blocks, let's start check the last block file
-            if (pBlockIter->numOfBlocks == 0) {
-              resetTableListIndex(&pReader->status);
-              goto _begin;
-            }
+          ERetrieveType type = doReadDataFromLastFiles(pReader);
+          if (type == TSDB_READ_RETURN) {
+            return terrno;
           }
         }
       }
@@ -3498,13 +3606,9 @@ static int32_t buildBlockFromFiles(STsdbReader* pReader) {
       code = doBuildDataBlock(pReader);
     }
 
-    if (code != TSDB_CODE_SUCCESS) {
+    if (code != TSDB_CODE_SUCCESS || pResBlock->info.rows > 0) {
       return code;
     }
-
-    if (pReader->pResBlock->info.rows > 0) {
-      return TSDB_CODE_SUCCESS;
-    }
   }
 }
 
@@ -3566,7 +3670,7 @@ SVersionRange getQueryVerRange(SVnode* pVnode, SQueryTableDataCond* pCond, int8_
   return (SVersionRange){.minVer = startVer, .maxVer = endVer};
 }
 
-bool hasBeenDropped(const SArray* pDelList, int32_t* index, TSDBKEY* pKey, int32_t order, SVersionRange* pVerRange) {
+bool hasBeenDropped(const SArray* pDelList, int32_t* index, int64_t key, int64_t ver, int32_t order, SVersionRange* pVerRange) {
   if (pDelList == NULL) {
     return false;
   }
@@ -3578,29 +3682,29 @@ bool hasBeenDropped(const SArray* pDelList, int32_t* index, TSDBKEY* pKey, int32
   if (asc) {
     if (*index >= num - 1) {
       TSDBKEY* last = taosArrayGetLast(pDelList);
-      ASSERT(pKey->ts >= last->ts);
+      ASSERT(key >= last->ts);
 
-      if (pKey->ts > last->ts) {
+      if (key > last->ts) {
         return false;
-      } else if (pKey->ts == last->ts) {
+      } else if (key == last->ts) {
         TSDBKEY* prev = taosArrayGet(pDelList, num - 2);
-        return (prev->version >= pKey->version && prev->version <= pVerRange->maxVer &&
+        return (prev->version >= ver && prev->version <= pVerRange->maxVer &&
                 prev->version >= pVerRange->minVer);
       }
     } else {
       TSDBKEY* pCurrent = taosArrayGet(pDelList, *index);
       TSDBKEY* pNext = taosArrayGet(pDelList, (*index) + 1);
 
-      if (pKey->ts < pCurrent->ts) {
+      if (key < pCurrent->ts) {
         return false;
       }
 
-      if (pCurrent->ts <= pKey->ts && pNext->ts >= pKey->ts && pCurrent->version >= pKey->version &&
+      if (pCurrent->ts <= key && pNext->ts >= key && pCurrent->version >= ver &&
           pVerRange->maxVer >= pCurrent->version) {
         return true;
       }
 
-      while (pNext->ts <= pKey->ts && (*index) < num - 1) {
+      while (pNext->ts <= key && (*index) < num - 1) {
         (*index) += 1;
 
         if ((*index) < num - 1) {
@@ -3612,7 +3716,7 @@ bool hasBeenDropped(const SArray* pDelList, int32_t* index, TSDBKEY* pKey, int32
             continue;
           }
 
-          if (pCurrent->ts <= pKey->ts && pNext->ts >= pKey->ts && pCurrent->version >= pKey->version &&
+          if (pCurrent->ts <= key && pNext->ts >= key && pCurrent->version >= ver &&
               pVerRange->maxVer >= pCurrent->version) {
             return true;
           }
@@ -3625,10 +3729,10 @@ bool hasBeenDropped(const SArray* pDelList, int32_t* index, TSDBKEY* pKey, int32
     if (*index <= 0) {
       TSDBKEY* pFirst = taosArrayGet(pDelList, 0);
 
-      if (pKey->ts < pFirst->ts) {
+      if (key < pFirst->ts) {
         return false;
-      } else if (pKey->ts == pFirst->ts) {
-        return pFirst->version >= pKey->version;
+      } else if (key == pFirst->ts) {
+        return pFirst->version >= ver;
       } else {
         ASSERT(0);
       }
@@ -3636,15 +3740,15 @@ bool hasBeenDropped(const SArray* pDelList, int32_t* index, TSDBKEY* pKey, int32
       TSDBKEY* pCurrent = taosArrayGet(pDelList, *index);
       TSDBKEY* pPrev = taosArrayGet(pDelList, (*index) - 1);
 
-      if (pKey->ts > pCurrent->ts) {
+      if (key > pCurrent->ts) {
         return false;
       }
 
-      if (pPrev->ts <= pKey->ts && pCurrent->ts >= pKey->ts && pPrev->version >= pKey->version) {
+      if (pPrev->ts <= key && pCurrent->ts >= key && pPrev->version >= ver) {
         return true;
       }
 
-      while (pPrev->ts >= pKey->ts && (*index) > 1) {
+      while (pPrev->ts >= key && (*index) > 1) {
         (*index) += step;
 
         if ((*index) >= 1) {
@@ -3656,7 +3760,7 @@ bool hasBeenDropped(const SArray* pDelList, int32_t* index, TSDBKEY* pKey, int32
             continue;
           }
 
-          if (pPrev->ts <= pKey->ts && pCurrent->ts >= pKey->ts && pPrev->version >= pKey->version) {
+          if (pPrev->ts <= key && pCurrent->ts >= key && pPrev->version >= ver) {
             return true;
           }
         }
@@ -3684,7 +3788,7 @@ TSDBROW* getValidMemRow(SIterInfo* pIter, const SArray* pDelList, STsdbReader* p
 
   // it is a valid data version
   if ((key.version <= pReader->verRange.maxVer && key.version >= pReader->verRange.minVer) &&
-      (!hasBeenDropped(pDelList, &pIter->index, &key, pReader->order, &pReader->verRange))) {
+      (!hasBeenDropped(pDelList, &pIter->index, key.ts, key.version, pReader->order, &pReader->verRange))) {
     return pRow;
   }
 
@@ -3703,14 +3807,15 @@ TSDBROW* getValidMemRow(SIterInfo* pIter, const SArray* pDelList, STsdbReader* p
     }
 
     if (key.version <= pReader->verRange.maxVer && key.version >= pReader->verRange.minVer &&
-        (!hasBeenDropped(pDelList, &pIter->index, &key, pReader->order, &pReader->verRange))) {
+        (!hasBeenDropped(pDelList, &pIter->index, key.ts, key.version, pReader->order, &pReader->verRange))) {
       return pRow;
     }
   }
 }
 
-int32_t doMergeRowsInBuf(SIterInfo* pIter, uint64_t uid, int64_t ts, SArray* pDelList, SRowMerger* pMerger,
-                         STsdbReader* pReader) {
+int32_t doMergeRowsInBuf(SIterInfo* pIter, uint64_t uid, int64_t ts, SArray* pDelList, STsdbReader* pReader) {
+  SRowMerger* pMerger = &pReader->status.merger;
+
   while (1) {
     pIter->hasVal = tsdbTbDataIterNext(pIter->iter);
     if (!pIter->hasVal) {
@@ -3789,10 +3894,10 @@ static int32_t checkForNeighborFileBlock(STsdbReader* pReader, STableBlockScanIn
   return code;
 }
 
-int32_t doMergeRowsInFileBlocks(SBlockData* pBlockData, STableBlockScanInfo* pScanInfo, STsdbReader* pReader,
-                                SRowMerger* pMerger) {
+int32_t doMergeRowsInFileBlocks(SBlockData* pBlockData, STableBlockScanInfo* pScanInfo, STsdbReader* pReader) {
   SFileBlockDumpInfo* pDumpInfo = &pReader->status.fBlockDumpInfo;
 
+  SRowMerger* pMerger = &pReader->status.merger;
   bool    asc = ASCENDING_TRAVERSE(pReader->order);
   int64_t key = pBlockData->aTSKEY[pDumpInfo->rowIndex];
   int32_t step = asc ? 1 : -1;
@@ -3830,8 +3935,8 @@ int32_t doMergeRowsInLastBlock(SLastBlockReader* pLastBlockReader, STableBlockSc
   while (nextRowFromLastBlocks(pLastBlockReader, pScanInfo, pVerRange)) {
     int64_t next1 = getCurrentKeyInLastBlock(pLastBlockReader);
     if (next1 == ts) {
-      TSDBROW fRow1 = tMergeTreeGetRow(&pLastBlockReader->mergeTree);
-      tsdbRowMergerAdd(pMerger, &fRow1, NULL);
+      TSDBROW* pRow1 = tMergeTreeGetRow(&pLastBlockReader->mergeTree);
+      tsdbRowMergerAdd(pMerger, pRow1, NULL);
     } else {
       tsdbTrace("uid:%" PRIu64 " last del index:%d, del range:%d, lastKeyInStt:%" PRId64 ", %s", pScanInfo->uid,
                 pScanInfo->lastBlockDelIndex, (int32_t)taosArrayGetSize(pScanInfo->delSkyline), pScanInfo->lastKeyInStt,
@@ -3871,7 +3976,6 @@ int32_t doMergeMemTableMultiRows(TSDBROW* pRow, uint64_t uid, SIterInfo* pIter,
     }
   }
 
-  SRowMerger merge = {0};
   terrno = 0;
   int32_t code = 0;
 
@@ -3883,8 +3987,7 @@ int32_t doMergeMemTableMultiRows(TSDBROW* pRow, uint64_t uid, SIterInfo* pIter,
       return terrno;
     }
 
-    STSchema* ps = (pReader->pSchema != NULL)? pReader->pSchema:pTSchema;
-    code = tsdbRowMergerInit(&merge, ps, ¤t, pTSchema);
+    code = tsdbRowMergerAdd(&pReader->status.merger, ¤t, pTSchema);
     if (code != TSDB_CODE_SUCCESS) {
       return code;
     }
@@ -3894,28 +3997,28 @@ int32_t doMergeMemTableMultiRows(TSDBROW* pRow, uint64_t uid, SIterInfo* pIter,
       return terrno;
     }
 
-    tsdbRowMergerAdd(&merge, pNextRow, pTSchema1);
+    tsdbRowMergerAdd(&pReader->status.merger,pNextRow, pTSchema1);
   } else {  // let's merge rows in file block
-    code = tsdbRowMergerInit(&merge, NULL, ¤t, pReader->pSchema);
+    code = tsdbRowMergerAdd(&pReader->status.merger, ¤t, pReader->pSchema);
     if (code != TSDB_CODE_SUCCESS) {
       return code;
     }
 
-    tsdbRowMergerAdd(&merge, pNextRow, NULL);
+    tsdbRowMergerAdd(&pReader->status.merger,pNextRow, NULL);
   }
 
-  code = doMergeRowsInBuf(pIter, uid, TSDBROW_TS(¤t), pDelList, &merge, pReader);
+  code = doMergeRowsInBuf(pIter, uid, TSDBROW_TS(¤t), pDelList, pReader);
   if (code != TSDB_CODE_SUCCESS) {
     return code;
   }
 
-  code = tsdbRowMergerGetRow(&merge, &pResRow->pTSRow);
+  code = tsdbRowMergerGetRow(&pReader->status.merger, &pResRow->pTSRow);
   if (code != TSDB_CODE_SUCCESS) {
     return code;
   }
 
   pResRow->type = TSDBROW_ROW_FMT;
-  tsdbRowMergerClear(&merge);
+  tsdbRowMergerClear(&pReader->status.merger);
   *freeTSRow = true;
 
   return TSDB_CODE_SUCCESS;
@@ -3923,7 +4026,7 @@ int32_t doMergeMemTableMultiRows(TSDBROW* pRow, uint64_t uid, SIterInfo* pIter,
 
 int32_t doMergeMemIMemRows(TSDBROW* pRow, TSDBROW* piRow, STableBlockScanInfo* pBlockScanInfo, STsdbReader* pReader,
                            SRow** pTSRow) {
-  SRowMerger merge = {0};
+  SRowMerger* pMerger = &pReader->status.merger;
 
   TSDBKEY   k = TSDBROW_KEY(pRow);
   TSDBKEY   ik = TSDBROW_KEY(piRow);
@@ -3938,46 +4041,43 @@ int32_t doMergeMemIMemRows(TSDBROW* pRow, TSDBROW* piRow, STableBlockScanInfo* p
   }
 
   if (ASCENDING_TRAVERSE(pReader->order)) {  // ascending order imem --> mem
-    int32_t code = tsdbRowMergerInit(&merge, pSchema, piRow, piSchema);
+    int32_t code = tsdbRowMergerAdd(&pReader->status.merger, piRow, piSchema);
     if (code != TSDB_CODE_SUCCESS) {
       return code;
     }
 
-    code = doMergeRowsInBuf(&pBlockScanInfo->iiter, pBlockScanInfo->uid, ik.ts, pBlockScanInfo->delSkyline, &merge,
-                            pReader);
+    code = doMergeRowsInBuf(&pBlockScanInfo->iiter, pBlockScanInfo->uid, ik.ts, pBlockScanInfo->delSkyline, pReader);
     if (code != TSDB_CODE_SUCCESS) {
       return code;
     }
 
-    tsdbRowMergerAdd(&merge, pRow, pSchema);
+    tsdbRowMergerAdd(&pReader->status.merger,pRow, pSchema);
     code =
-        doMergeRowsInBuf(&pBlockScanInfo->iter, pBlockScanInfo->uid, k.ts, pBlockScanInfo->delSkyline, &merge, pReader);
+        doMergeRowsInBuf(&pBlockScanInfo->iter, pBlockScanInfo->uid, k.ts, pBlockScanInfo->delSkyline, pReader);
     if (code != TSDB_CODE_SUCCESS) {
       return code;
     }
 
   } else {
-    int32_t code = tsdbRowMergerInit(&merge, NULL, pRow, pSchema);
-    if (code != TSDB_CODE_SUCCESS || merge.pTSchema == NULL) {
+    int32_t code = tsdbRowMergerAdd(&pReader->status.merger, pRow, pSchema);
+    if (code != TSDB_CODE_SUCCESS || pMerger->pTSchema == NULL) {
       return code;
     }
 
-    code =
-        doMergeRowsInBuf(&pBlockScanInfo->iter, pBlockScanInfo->uid, k.ts, pBlockScanInfo->delSkyline, &merge, pReader);
+    code = doMergeRowsInBuf(&pBlockScanInfo->iter, pBlockScanInfo->uid, k.ts, pBlockScanInfo->delSkyline, pReader);
     if (code != TSDB_CODE_SUCCESS) {
       return code;
     }
 
-    tsdbRowMergerAdd(&merge, piRow, piSchema);
-    code = doMergeRowsInBuf(&pBlockScanInfo->iiter, pBlockScanInfo->uid, ik.ts, pBlockScanInfo->delSkyline, &merge,
-                            pReader);
+    tsdbRowMergerAdd(&pReader->status.merger, piRow, piSchema);
+    code = doMergeRowsInBuf(&pBlockScanInfo->iiter, pBlockScanInfo->uid, ik.ts, pBlockScanInfo->delSkyline, pReader);
     if (code != TSDB_CODE_SUCCESS) {
       return code;
     }
   }
 
-  int32_t code = tsdbRowMergerGetRow(&merge, pTSRow);
-  tsdbRowMergerClear(&merge);
+  int32_t code = tsdbRowMergerGetRow(pMerger, pTSRow);
+  tsdbRowMergerClear(pMerger);
   return code;
 }
 
@@ -4102,11 +4202,8 @@ int32_t doAppendRowFromFileBlock(SSDataBlock* pResBlock, STsdbReader* pReader, S
   int32_t code = TSDB_CODE_SUCCESS;
 
   SBlockLoadSuppInfo* pSupInfo = &pReader->suppInfo;
-  if (pReader->suppInfo.colId[i] == PRIMARYKEY_TIMESTAMP_COL_ID) {
-    SColumnInfoData* pColData = taosArrayGet(pResBlock->pDataBlock, pSupInfo->slotId[i]);
-    ((int64_t*)pColData->pData)[outputRowIndex] = pBlockData->aTSKEY[rowIndex];
-    i += 1;
-  }
+  ((int64_t*)pReader->status.pPrimaryTsCol->pData)[outputRowIndex] = pBlockData->aTSKEY[rowIndex];
+  i += 1;
 
   SColVal cv = {0};
   int32_t numOfInputCols = pBlockData->nColData;
@@ -4148,7 +4245,7 @@ int32_t doAppendRowFromFileBlock(SSDataBlock* pResBlock, STsdbReader* pReader, S
 
 int32_t buildDataBlockFromBufImpl(STableBlockScanInfo* pBlockScanInfo, int64_t endKey, int32_t capacity,
                                   STsdbReader* pReader) {
-  SSDataBlock* pBlock = pReader->pResBlock;
+  SSDataBlock* pBlock = pReader->resBlockInfo.pResBlock;
   int32_t      code = TSDB_CODE_SUCCESS;
 
   do {
@@ -4192,10 +4289,12 @@ int32_t buildDataBlockFromBufImpl(STableBlockScanInfo* pBlockScanInfo, int64_t e
 
 // TODO refactor: with createDataBlockScanInfo
 int32_t tsdbSetTableList(STsdbReader* pReader, const void* pTableList, int32_t num) {
-  int32_t size = taosHashGetSize(pReader->status.pTableMap);
+  int32_t size = tSimpleHashGetSize(pReader->status.pTableMap);
 
   STableBlockScanInfo** p = NULL;
-  while ((p = taosHashIterate(pReader->status.pTableMap, p)) != NULL) {
+  int32_t iter = 0;
+
+  while ((p = tSimpleHashIterate(pReader->status.pTableMap, p, &iter)) != NULL) {
     clearBlockScanInfo(*p);
   }
 
@@ -4213,7 +4312,7 @@ int32_t tsdbSetTableList(STsdbReader* pReader, const void* pTableList, int32_t n
     pReader->status.uidList.tableUidList = (uint64_t*)p1;
   }
 
-  taosHashClear(pReader->status.pTableMap);
+  tSimpleHashClear(pReader->status.pTableMap);
   STableUidList* pUidList = &pReader->status.uidList;
   pUidList->currentIndex = 0;
 
@@ -4234,7 +4333,7 @@ int32_t tsdbSetTableList(STsdbReader* pReader, const void* pTableList, int32_t n
       pInfo->lastKeyInStt = ekey;
     }
 
-    taosHashPut(pReader->status.pTableMap, &pInfo->uid, sizeof(uint64_t), &pInfo, POINTER_BYTES);
+    tSimpleHashPut(pReader->status.pTableMap, &pInfo->uid, sizeof(uint64_t), &pInfo, POINTER_BYTES);
   }
 
   return TDB_CODE_SUCCESS;
@@ -4254,7 +4353,7 @@ void* tsdbGetIvtIdx(SMeta* pMeta) {
   return metaGetIvtIdx(pMeta);
 }
 
-uint64_t getReaderMaxVersion(STsdbReader* pReader) { return pReader->verRange.maxVer; }
+uint64_t tsdbGetReaderMaxVersion(STsdbReader* pReader) { return pReader->verRange.maxVer; }
 
 static int32_t doOpenReaderImpl(STsdbReader* pReader) {
   SReaderStatus*  pStatus = &pReader->status;
@@ -4356,6 +4455,10 @@ int32_t tsdbReaderOpen(SVnode* pVnode, SQueryTableDataCond* pCond, void* pTableL
     }
   }
 
+  if (pReader->pSchema != NULL) {
+    tsdbRowMergerInit(&pReader->status.merger, pReader->pSchema);
+  }
+
   pReader->pSchemaMap = tSimpleHashInit(8, taosFastHash);
   if (pReader->pSchemaMap == NULL) {
     tsdbError("failed init schema hash for reader %s", pReader->idStr);
@@ -4380,7 +4483,13 @@ int32_t tsdbReaderOpen(SVnode* pVnode, SQueryTableDataCond* pCond, void* pTableL
     goto _err;
   }
 
-  pReader->suspended = true;
+  pReader->status.pLDataIter = taosMemoryCalloc(pVnode->config.sttTrigger, sizeof(SLDataIter));
+  if (pReader->status.pLDataIter == NULL) {
+    terrno = TSDB_CODE_OUT_OF_MEMORY;
+    goto _err;
+  }
+
+  pReader->flag = READER_STATUS_SUSPEND;
 
   if (countOnly) {
     pReader->readMode = READ_MODE_COUNT_ONLY;
@@ -4398,29 +4507,42 @@ _err:
   return code;
 }
 
+static void clearSharedPtr(STsdbReader* p) {
+  p->status.pLDataIter = NULL;
+  p->status.pTableMap = NULL;
+  p->status.uidList.tableUidList = NULL;
+  p->pReadSnap = NULL;
+  p->pSchema = NULL;
+  p->pSchemaMap = NULL;
+}
+
+static void setSharedPtr(STsdbReader* pDst, const STsdbReader* pSrc) {
+  pDst->status.pTableMap = pSrc->status.pTableMap;
+  pDst->status.pLDataIter = pSrc->status.pLDataIter;
+  pDst->status.uidList = pSrc->status.uidList;
+  pDst->pSchema = pSrc->pSchema;
+  pDst->pSchemaMap = pSrc->pSchemaMap;
+  pDst->pReadSnap = pSrc->pReadSnap;
+
+  if (pDst->pSchema) {
+    tsdbRowMergerInit(&pDst->status.merger, pDst->pSchema);
+  }
+}
+
 void tsdbReaderClose(STsdbReader* pReader) {
   if (pReader == NULL) {
     return;
   }
 
   tsdbAcquireReader(pReader);
+
   {
     if (pReader->innerReader[0] != NULL || pReader->innerReader[1] != NULL) {
       STsdbReader* p = pReader->innerReader[0];
-
-      p->status.pTableMap = NULL;
-      p->status.uidList.tableUidList = NULL;
-      p->pReadSnap = NULL;
-      p->pSchema = NULL;
-      p->pSchemaMap = NULL;
+      clearSharedPtr(p);
 
       p = pReader->innerReader[1];
-
-      p->status.pTableMap = NULL;
-      p->status.uidList.tableUidList = NULL;
-      p->pReadSnap = NULL;
-      p->pSchema = NULL;
-      p->pSchemaMap = NULL;
+      clearSharedPtr(p);
 
       tsdbReaderClose(pReader->innerReader[0]);
       tsdbReaderClose(pReader->innerReader[1]);
@@ -4436,15 +4558,15 @@ void tsdbReaderClose(STsdbReader* pReader) {
     }
   }
 
-  if (pReader->freeBlock) {
-    pReader->pResBlock = blockDataDestroy(pReader->pResBlock);
+  if (pReader->resBlockInfo.freeBlock) {
+    pReader->resBlockInfo.pResBlock = blockDataDestroy(pReader->resBlockInfo.pResBlock);
   }
 
   taosMemoryFree(pSupInfo->colId);
   tBlockDataDestroy(&pReader->status.fileBlockData);
   cleanupDataBlockIterator(&pReader->status.blockIter);
 
-  size_t numOfTables = taosHashGetSize(pReader->status.pTableMap);
+  size_t numOfTables = tSimpleHashGetSize(pReader->status.pTableMap);
   if (pReader->status.pTableMap != NULL) {
     destroyAllBlockScanInfo(pReader->status.pTableMap);
     clearBlockScanInfoBuf(&pReader->blockInfoBuf);
@@ -4471,7 +4593,8 @@ void tsdbReaderClose(STsdbReader* pReader) {
 
   tsdbUninitReaderLock(pReader);
 
-  taosMemoryFree(pReader->status.uidList.tableUidList);
+  taosMemoryFreeClear(pReader->status.pLDataIter);
+  taosMemoryFreeClear(pReader->status.uidList.tableUidList);
   SIOCostSummary* pCost = &pReader->cost;
 
   SFilesetIter* pFilesetIter = &pReader->status.fileIter;
@@ -4498,6 +4621,8 @@ void tsdbReaderClose(STsdbReader* pReader) {
       pCost->initDelSkylineIterTime, pReader->idStr);
 
   taosMemoryFree(pReader->idStr);
+
+  tsdbRowMergerCleanup(&pReader->status.merger);
   taosMemoryFree(pReader->pSchema);
 
   tSimpleHashCleanup(pReader->pSchemaMap);
@@ -4526,8 +4651,9 @@ int32_t tsdbReaderSuspend(STsdbReader* pReader) {
 
     // resetDataBlockScanInfo excluding lastKey
     STableBlockScanInfo** p = NULL;
+    int32_t iter = 0;
 
-    while ((p = taosHashIterate(pStatus->pTableMap, p)) != NULL) {
+    while ((p = tSimpleHashIterate(pStatus->pTableMap, p, &iter)) != NULL) {
       STableBlockScanInfo* pInfo = *(STableBlockScanInfo**)p;
 
       pInfo->iterInit = false;
@@ -4543,13 +4669,13 @@ int32_t tsdbReaderSuspend(STsdbReader* pReader) {
       }
 
       pInfo->delSkyline = taosArrayDestroy(pInfo->delSkyline);
-      // pInfo->lastKey = ts;
     }
   } else {
     // resetDataBlockScanInfo excluding lastKey
     STableBlockScanInfo** p = NULL;
+    int32_t iter = 0;
 
-    while ((p = taosHashIterate(pStatus->pTableMap, p)) != NULL) {
+    while ((p = tSimpleHashIterate(pStatus->pTableMap, p, &iter)) != NULL) {
       STableBlockScanInfo* pInfo = *(STableBlockScanInfo**)p;
 
       pInfo->iterInit = false;
@@ -4565,13 +4691,12 @@ int32_t tsdbReaderSuspend(STsdbReader* pReader) {
       }
 
       pInfo->delSkyline = taosArrayDestroy(pInfo->delSkyline);
-      // pInfo->lastKey = ts;
     }
 
     pBlockScanInfo = pStatus->pTableIter == NULL ? NULL : *pStatus->pTableIter;
     if (pBlockScanInfo) {
       // save lastKey to restore memory iterator
-      STimeWindow w = pReader->pResBlock->info.window;
+      STimeWindow w = pReader->resBlockInfo.pResBlock->info.window;
       pBlockScanInfo->lastKey = ASCENDING_TRAVERSE(pReader->order) ? w.ekey : w.skey;
 
       // reset current current table's data block scan info,
@@ -4595,8 +4720,7 @@ int32_t tsdbReaderSuspend(STsdbReader* pReader) {
 
   tsdbUntakeReadSnap(pReader, pReader->pReadSnap, false);
   pReader->pReadSnap = NULL;
-
-  pReader->suspended = true;
+  pReader->flag = READER_STATUS_SUSPEND;
 
   tsdbDebug("reader: %p suspended uid %" PRIu64 " in this query %s", pReader, pBlockScanInfo ? pBlockScanInfo->uid : 0,
             pReader->idStr);
@@ -4613,7 +4737,7 @@ static int32_t tsdbSetQueryReseek(void* pQHandle) {
 
   code = tsdbTryAcquireReader(pReader);
   if (code == 0) {
-    if (pReader->suspended) {
+    if (pReader->flag == READER_STATUS_SUSPEND) {
       tsdbReleaseReader(pReader);
       return code;
     }
@@ -4638,7 +4762,7 @@ int32_t tsdbReaderResume(STsdbReader* pReader) {
 
   //  restore reader's state
   //  task snapshot
-  int32_t numOfTables = taosHashGetSize(pReader->status.pTableMap);
+  int32_t numOfTables = tSimpleHashGetSize(pReader->status.pTableMap);
   if (numOfTables > 0) {
     qTrace("tsdb/reader: %p, take snapshot", pReader);
     code = tsdbTakeReadSnap(pReader, tsdbSetQueryReseek, &pReader->pReadSnap);
@@ -4656,19 +4780,11 @@ int32_t tsdbReaderResume(STsdbReader* pReader) {
       STsdbReader* pNextReader = pReader->innerReader[1];
 
       // we need only one row
-      pPrevReader->capacity = 1;
-      pPrevReader->status.pTableMap = pReader->status.pTableMap;
-      pPrevReader->status.uidList = pReader->status.uidList;
-      pPrevReader->pSchema = pReader->pSchema;
-      pPrevReader->pSchemaMap = pReader->pSchemaMap;
-      pPrevReader->pReadSnap = pReader->pReadSnap;
+      pPrevReader->resBlockInfo.capacity = 1;
+      setSharedPtr(pPrevReader, pReader);
 
-      pNextReader->capacity = 1;
-      pNextReader->status.pTableMap = pReader->status.pTableMap;
-      pNextReader->status.uidList = pReader->status.uidList;
-      pNextReader->pSchema = pReader->pSchema;
-      pNextReader->pSchemaMap = pReader->pSchemaMap;
-      pNextReader->pReadSnap = pReader->pReadSnap;
+      pNextReader->resBlockInfo.capacity = 1;
+      setSharedPtr(pNextReader, pReader);
 
       code = doOpenReaderImpl(pPrevReader);
       if (code != TSDB_CODE_SUCCESS) {
@@ -4677,8 +4793,7 @@ int32_t tsdbReaderResume(STsdbReader* pReader) {
     }
   }
 
-  pReader->suspended = false;
-
+  pReader->flag = READER_STATUS_NORMAL;
   tsdbDebug("reader: %p resumed uid %" PRIu64 ", numOfTable:%" PRId32 ", in this query %s", pReader,
             pBlockScanInfo ? (*pBlockScanInfo)->uid : 0, numOfTables, pReader->idStr);
   return code;
@@ -4690,7 +4805,7 @@ _err:
 
 static bool tsdbReadRowsCountOnly(STsdbReader* pReader) {
   int32_t      code = TSDB_CODE_SUCCESS;
-  SSDataBlock* pBlock = pReader->pResBlock;
+  SSDataBlock* pBlock = pReader->resBlockInfo.pResBlock;
 
   if (pReader->status.loadFromFile == false) {
     return false;
@@ -4719,13 +4834,13 @@ static int32_t doTsdbNextDataBlock(STsdbReader* pReader, bool* hasNext) {
   int32_t code = TSDB_CODE_SUCCESS;
 
   // cleanup the data that belongs to the previous data block
-  SSDataBlock* pBlock = pReader->pResBlock;
+  SSDataBlock* pBlock = pReader->resBlockInfo.pResBlock;
   blockDataCleanup(pBlock);
 
   *hasNext = false;
 
   SReaderStatus* pStatus = &pReader->status;
-  if (taosHashGetSize(pStatus->pTableMap) == 0) {
+  if (tSimpleHashGetSize(pStatus->pTableMap) == 0) {
     return code;
   }
 
@@ -4757,8 +4872,8 @@ int32_t tsdbNextDataBlock(STsdbReader* pReader, bool* hasNext) {
 
   *hasNext = false;
 
-  if (isEmptyQueryTimeWindow(&pReader->window) || pReader->step == EXTERNAL_ROWS_NEXT) {
-    return code;
+  if (isEmptyQueryTimeWindow(&pReader->window) || pReader->step == EXTERNAL_ROWS_NEXT || pReader->code != TSDB_CODE_SUCCESS) {
+    return (pReader->code != TSDB_CODE_SUCCESS)? pReader->code:code;
   }
 
   SReaderStatus* pStatus = &pReader->status;
@@ -4766,8 +4881,12 @@ int32_t tsdbNextDataBlock(STsdbReader* pReader, bool* hasNext) {
   code = tsdbAcquireReader(pReader);
   qTrace("tsdb/read: %p, take read mutex, code: %d", pReader, code);
 
-  if (pReader->suspended) {
-    tsdbReaderResume(pReader);
+  if (pReader->flag == READER_STATUS_SUSPEND) {
+    code = tsdbReaderResume(pReader);
+    if (code != TSDB_CODE_SUCCESS) {
+      tsdbReleaseReader(pReader);
+      return code;
+    }
   }
 
   if (pReader->innerReader[0] != NULL && pReader->step == 0) {
@@ -4904,7 +5023,7 @@ int32_t tsdbRetrieveDatablockSMA(STsdbReader* pReader, SSDataBlock* pDataBlock,
   SFileDataBlockInfo* pFBlock = getCurrentBlockInfo(&pReader->status.blockIter);
   SBlockLoadSuppInfo* pSup = &pReader->suppInfo;
 
-  if (pReader->pResBlock->info.id.uid != pFBlock->uid) {
+  if (pReader->resBlockInfo.pResBlock->info.id.uid != pFBlock->uid) {
     return TSDB_CODE_SUCCESS;
   }
 
@@ -4930,8 +5049,8 @@ int32_t tsdbRetrieveDatablockSMA(STsdbReader* pReader, SSDataBlock* pDataBlock,
 
   pTsAgg->numOfNull = 0;
   pTsAgg->colId = PRIMARYKEY_TIMESTAMP_COL_ID;
-  pTsAgg->min = pReader->pResBlock->info.window.skey;
-  pTsAgg->max = pReader->pResBlock->info.window.ekey;
+  pTsAgg->min = pReader->resBlockInfo.pResBlock->info.window.skey;
+  pTsAgg->max = pReader->resBlockInfo.pResBlock->info.window.ekey;
 
   // update the number of NULL data rows
   size_t numOfCols = pSup->numOfCols;
@@ -4942,7 +5061,7 @@ int32_t tsdbRetrieveDatablockSMA(STsdbReader* pReader, SSDataBlock* pDataBlock,
     taosArrayEnsureCap(pSup->pColAgg, colsNum);
   }
 
-  SSDataBlock* pResBlock = pReader->pResBlock;
+  SSDataBlock* pResBlock = pReader->resBlockInfo.pResBlock;
   if (pResBlock->pBlockAgg == NULL) {
     size_t num = taosArrayGetSize(pResBlock->pDataBlock);
     pResBlock->pBlockAgg = taosMemoryCalloc(num, POINTER_BYTES);
@@ -4978,11 +5097,11 @@ int32_t tsdbRetrieveDatablockSMA(STsdbReader* pReader, SSDataBlock* pDataBlock,
   return code;
 }
 
-STableBlockScanInfo* getTableBlockScanInfo(SHashObj* pTableMap, uint64_t uid, const char* id) {
-  STableBlockScanInfo** p = taosHashGet(pTableMap, &uid, sizeof(uid));
+STableBlockScanInfo* getTableBlockScanInfo(SSHashObj* pTableMap, uint64_t uid, const char* id) {
+  STableBlockScanInfo** p = tSimpleHashGet(pTableMap, &uid, sizeof(uid));
   if (p == NULL || *p == NULL) {
     terrno = TSDB_CODE_INVALID_PARA;
-    int32_t size = taosHashGetSize(pTableMap);
+    int32_t size = tSimpleHashGetSize(pTableMap);
     tsdbError("failed to locate the uid:%" PRIu64 " in query table uid list, total tables:%d, %s", uid, size, id);
     return NULL;
   }
@@ -5013,7 +5132,7 @@ static SSDataBlock* doRetrieveDataBlock(STsdbReader* pReader) {
     return NULL;
   }
 
-  return pReader->pResBlock;
+  return pReader->resBlockInfo.pResBlock;
 }
 
 SSDataBlock* tsdbRetrieveDataBlock(STsdbReader* pReader, SArray* pIdList) {
@@ -5028,7 +5147,7 @@ SSDataBlock* tsdbRetrieveDataBlock(STsdbReader* pReader, SArray* pIdList) {
 
   SReaderStatus* pStatus = &pTReader->status;
   if (pStatus->composedDataBlock) {
-    return pTReader->pResBlock;
+    return pTReader->resBlockInfo.pResBlock;
   }
 
   SSDataBlock* ret = doRetrieveDataBlock(pTReader);
@@ -5040,11 +5159,17 @@ SSDataBlock* tsdbRetrieveDataBlock(STsdbReader* pReader, SArray* pIdList) {
 }
 
 int32_t tsdbReaderReset(STsdbReader* pReader, SQueryTableDataCond* pCond) {
+  int32_t code = TSDB_CODE_SUCCESS;
+
   qTrace("tsdb/reader-reset: %p, take read mutex", pReader);
   tsdbAcquireReader(pReader);
 
-  if (pReader->suspended) {
-    tsdbReaderResume(pReader);
+  if (pReader->flag == READER_STATUS_SUSPEND) {
+    code = tsdbReaderResume(pReader);
+    if (code != TSDB_CODE_SUCCESS) {
+      tsdbReleaseReader(pReader);
+      return code;
+    }
   }
 
   if (isEmptyQueryTimeWindow(&pReader->window) || pReader->pReadSnap == NULL) {
@@ -5068,7 +5193,7 @@ int32_t tsdbReaderReset(STsdbReader* pReader, SQueryTableDataCond* pCond) {
   pReader->suppInfo.tsColAgg.colId = PRIMARYKEY_TIMESTAMP_COL_ID;
   tsdbDataFReaderClose(&pReader->pFileReader);
 
-  int32_t numOfTables = taosHashGetSize(pStatus->pTableMap);
+  int32_t numOfTables = tSimpleHashGetSize(pStatus->pTableMap);
 
   initFilesetIterator(&pStatus->fileIter, pReader->pReadSnap->fs.aDFileSet, pReader);
   resetDataBlockIterator(pBlockIter, pReader->order);
@@ -5079,8 +5204,6 @@ int32_t tsdbReaderReset(STsdbReader* pReader, SQueryTableDataCond* pCond) {
   int64_t ts = asc ? pReader->window.skey - 1 : pReader->window.ekey + 1;
   resetAllDataBlockScanInfo(pStatus->pTableMap, ts, step);
 
-  int32_t code = 0;
-
   // no data in files, let's try buffer in memory
   if (pStatus->fileIter.numOfFiles == 0) {
     pStatus->loadFromFile = false;
@@ -5122,12 +5245,14 @@ int32_t tsdbGetFileBlocksDistInfo(STsdbReader* pReader, STableBlockDistInfo* pTa
 
   const int32_t numOfBuckets = 20.0;
 
-  // find the start data block in file
-
   // find the start data block in file
   tsdbAcquireReader(pReader);
-  if (pReader->suspended) {
-    tsdbReaderResume(pReader);
+  if (pReader->flag == READER_STATUS_SUSPEND) {
+    code = tsdbReaderResume(pReader);
+    if (code != TSDB_CODE_SUCCESS) {
+      tsdbReleaseReader(pReader);
+      return code;
+    }
   }
   SReaderStatus* pStatus = &pReader->status;
 
@@ -5139,7 +5264,7 @@ int32_t tsdbGetFileBlocksDistInfo(STsdbReader* pReader, STableBlockDistInfo* pTa
 
   pTableBlockInfo->numOfFiles += 1;
 
-  int32_t numOfTables = (int32_t)taosHashGetSize(pStatus->pTableMap);
+  int32_t numOfTables = (int32_t)tSimpleHashGetSize(pStatus->pTableMap);
   int     defaultRows = 4096;
 
   SDataBlockIter* pBlockIter = &pStatus->blockIter;
@@ -5195,15 +5320,21 @@ int32_t tsdbGetFileBlocksDistInfo(STsdbReader* pReader, STableBlockDistInfo* pTa
 }
 
 int64_t tsdbGetNumOfRowsInMemTable(STsdbReader* pReader) {
+  int32_t code = TSDB_CODE_SUCCESS;
   int64_t rows = 0;
 
   SReaderStatus* pStatus = &pReader->status;
   tsdbAcquireReader(pReader);
-  if (pReader->suspended) {
-    tsdbReaderResume(pReader);
+  if (pReader->flag == READER_STATUS_SUSPEND) {
+    code = tsdbReaderResume(pReader);
+    if (code != TSDB_CODE_SUCCESS) {
+      tsdbReleaseReader(pReader);
+      return code;
+    }
   }
 
-  pStatus->pTableIter = taosHashIterate(pStatus->pTableMap, NULL);
+  int32_t iter = 0;
+  pStatus->pTableIter = tSimpleHashIterate(pStatus->pTableMap, NULL, &iter);
 
   while (pStatus->pTableIter != NULL) {
     STableBlockScanInfo* pBlockScanInfo = *(STableBlockScanInfo**)pStatus->pTableIter;
@@ -5225,7 +5356,7 @@ int64_t tsdbGetNumOfRowsInMemTable(STsdbReader* pReader) {
     }
 
     // current table is exhausted, let's try the next table
-    pStatus->pTableIter = taosHashIterate(pStatus->pTableMap, pStatus->pTableIter);
+    pStatus->pTableIter = tSimpleHashIterate(pStatus->pTableMap, pStatus->pTableIter, &iter);
   }
 
   tsdbReleaseReader(pReader);
@@ -5364,3 +5495,5 @@ void tsdbReaderSetId(STsdbReader* pReader, const char* idstr) {
   taosMemoryFreeClear(pReader->idStr);
   pReader->idStr = taosStrdup(idstr);
 }
+
+void tsdbReaderSetCloseFlag(STsdbReader* pReader) { pReader->code = TSDB_CODE_TSC_QUERY_CANCELLED; }
diff --git a/source/dnode/vnode/src/tsdb/tsdbSnapshot.c b/source/dnode/vnode/src/tsdb/tsdbSnapshot.c
index aed863d194..dfea125cc1 100644
--- a/source/dnode/vnode/src/tsdb/tsdbSnapshot.c
+++ b/source/dnode/vnode/src/tsdb/tsdbSnapshot.c
@@ -70,10 +70,11 @@ static int32_t tsdbSnapReadFileDataStart(STsdbSnapReader* pReader) {
 
   if (pReader->pIter) {
     // iter to next with filter info (sver, ever)
-    code = tsdbDataIterNext2(pReader->pIter,
-                             &(STsdbFilterInfo){.flag = TSDB_FILTER_FLAG_BY_VERSION,  // flag
-                                                .sver = pReader->sver,
-                                                .ever = pReader->ever});
+    code = tsdbDataIterNext2(
+        pReader->pIter,
+        &(STsdbFilterInfo){.flag = TSDB_FILTER_FLAG_BY_VERSION | TSDB_FILTER_FLAG_IGNORE_DROPPED_TABLE,  // flag
+                           .sver = pReader->sver,
+                           .ever = pReader->ever});
     TSDB_CHECK_CODE(code, lino, _exit);
 
     if (pReader->pIter->rowInfo.suid || pReader->pIter->rowInfo.uid) {
@@ -94,10 +95,11 @@ static int32_t tsdbSnapReadFileDataStart(STsdbSnapReader* pReader) {
 
     if (pReader->pIter) {
       // iter to valid row
-      code = tsdbDataIterNext2(pReader->pIter,
-                               &(STsdbFilterInfo){.flag = TSDB_FILTER_FLAG_BY_VERSION,  // flag
-                                                  .sver = pReader->sver,
-                                                  .ever = pReader->ever});
+      code = tsdbDataIterNext2(
+          pReader->pIter,
+          &(STsdbFilterInfo){.flag = TSDB_FILTER_FLAG_BY_VERSION | TSDB_FILTER_FLAG_IGNORE_DROPPED_TABLE,  // flag
+                             .sver = pReader->sver,
+                             .ever = pReader->ever});
       TSDB_CHECK_CODE(code, lino, _exit);
 
       if (pReader->pIter->rowInfo.suid || pReader->pIter->rowInfo.uid) {
@@ -139,7 +141,8 @@ static int32_t tsdbSnapReadNextRow(STsdbSnapReader* pReader, SRowInfo** ppRowInf
   int32_t lino = 0;
 
   if (pReader->pIter) {
-    code = tsdbDataIterNext2(pReader->pIter, &(STsdbFilterInfo){.flag = TSDB_FILTER_FLAG_BY_VERSION,  // flag
+    code = tsdbDataIterNext2(pReader->pIter, &(STsdbFilterInfo){.flag = TSDB_FILTER_FLAG_BY_VERSION |
+                                                                        TSDB_FILTER_FLAG_IGNORE_DROPPED_TABLE,  // flag
                                                                 .sver = pReader->sver,
                                                                 .ever = pReader->ever});
     TSDB_CHECK_CODE(code, lino, _exit);
@@ -346,8 +349,9 @@ static int32_t tsdbSnapReadNextTombData(STsdbSnapReader* pReader, SDelInfo** ppD
   int32_t lino = 0;
 
   code = tsdbDataIterNext2(
-      pReader->pTIter,
-      &(STsdbFilterInfo){.flag = TSDB_FILTER_FLAG_BY_VERSION, .sver = pReader->sver, .ever = pReader->ever});
+      pReader->pTIter, &(STsdbFilterInfo){.flag = TSDB_FILTER_FLAG_BY_VERSION | TSDB_FILTER_FLAG_IGNORE_DROPPED_TABLE,
+                                          .sver = pReader->sver,
+                                          .ever = pReader->ever});
   TSDB_CHECK_CODE(code, lino, _exit);
 
   if (ppDelInfo) {
diff --git a/source/dnode/vnode/src/tsdb/tsdbUtil.c b/source/dnode/vnode/src/tsdb/tsdbUtil.c
index 8e778da877..556ec33526 100644
--- a/source/dnode/vnode/src/tsdb/tsdbUtil.c
+++ b/source/dnode/vnode/src/tsdb/tsdbUtil.c
@@ -637,201 +637,157 @@ SColVal *tsdbRowIterNext(STSDBRowIter *pIter) {
 }
 
 // SRowMerger ======================================================
-
-int32_t tsdbRowMergerInit(SRowMerger *pMerger, STSchema *pResTSchema, TSDBROW *pRow, STSchema *pTSchema) {
-  int32_t   code = 0;
-  TSDBKEY   key = TSDBROW_KEY(pRow);
-  SColVal  *pColVal = &(SColVal){0};
-  STColumn *pTColumn;
-  int32_t   iCol, jCol = 0;
-
-  if (NULL == pResTSchema) {
-    pResTSchema = pTSchema;
-  }
-
-  pMerger->pTSchema = pResTSchema;
-  pMerger->version = key.version;
-
-  pMerger->pArray = taosArrayInit(pResTSchema->numOfCols, sizeof(SColVal));
-  if (pMerger->pArray == NULL) {
-    code = TSDB_CODE_OUT_OF_MEMORY;
-    goto _exit;
-  }
-
-  // ts
-  pTColumn = &pTSchema->columns[jCol++];
-
-  ASSERT(pTColumn->type == TSDB_DATA_TYPE_TIMESTAMP);
-
-  *pColVal = COL_VAL_VALUE(pTColumn->colId, pTColumn->type, (SValue){.val = key.ts});
-  if (taosArrayPush(pMerger->pArray, pColVal) == NULL) {
-    code = TSDB_CODE_OUT_OF_MEMORY;
-    goto _exit;
-  }
-
-  // other
-  for (iCol = 1; jCol < pTSchema->numOfCols && iCol < pResTSchema->numOfCols; ++iCol) {
-    pTColumn = &pResTSchema->columns[iCol];
-    if (pTSchema->columns[jCol].colId < pTColumn->colId) {
-      ++jCol;
-      --iCol;
-      continue;
-    } else if (pTSchema->columns[jCol].colId > pTColumn->colId) {
-      taosArrayPush(pMerger->pArray, &COL_VAL_NONE(pTColumn->colId, pTColumn->type));
-      continue;
-    }
-
-    tsdbRowGetColVal(pRow, pTSchema, jCol++, pColVal);
-    if ((!COL_VAL_IS_NONE(pColVal)) && (!COL_VAL_IS_NULL(pColVal)) && IS_VAR_DATA_TYPE(pColVal->type)) {
-      uint8_t *pVal = pColVal->value.pData;
-
-      pColVal->value.pData = NULL;
-      code = tRealloc(&pColVal->value.pData, pColVal->value.nData);
-      if (code) goto _exit;
-
-      if (pColVal->value.nData) {
-        memcpy(pColVal->value.pData, pVal, pColVal->value.nData);
-      }
-    }
-
-    if (taosArrayPush(pMerger->pArray, pColVal) == NULL) {
-      code = TSDB_CODE_OUT_OF_MEMORY;
-      goto _exit;
-    }
-  }
-
-  for (; iCol < pResTSchema->numOfCols; ++iCol) {
-    pTColumn = &pResTSchema->columns[iCol];
-    taosArrayPush(pMerger->pArray, &COL_VAL_NONE(pTColumn->colId, pTColumn->type));
-  }
-
-_exit:
-  return code;
-}
-
 int32_t tsdbRowMergerAdd(SRowMerger *pMerger, TSDBROW *pRow, STSchema *pTSchema) {
   int32_t   code = 0;
   TSDBKEY   key = TSDBROW_KEY(pRow);
-  SColVal  *pColVal = &(SColVal){0};
+  SColVal * pColVal = &(SColVal){0};
   STColumn *pTColumn;
   int32_t   iCol, jCol = 1;
 
   if (NULL == pTSchema) {
     pTSchema = pMerger->pTSchema;
   }
-  ASSERT(((SColVal *)pMerger->pArray->pData)->value.val == key.ts);
 
-  for (iCol = 1; iCol < pMerger->pTSchema->numOfCols && jCol < pTSchema->numOfCols; ++iCol) {
-    pTColumn = &pMerger->pTSchema->columns[iCol];
-    if (pTSchema->columns[jCol].colId < pTColumn->colId) {
-      ++jCol;
-      --iCol;
-      continue;
-    } else if (pTSchema->columns[jCol].colId > pTColumn->colId) {
-      continue;
-    }
+  if (taosArrayGetSize(pMerger->pArray) == 0) {
+    // ts
+    jCol = 0;
+    pTColumn = &pTSchema->columns[jCol++];
 
-    tsdbRowGetColVal(pRow, pTSchema, jCol++, pColVal);
-
-    if (key.version > pMerger->version) {
-      if (!COL_VAL_IS_NONE(pColVal)) {
-        if (IS_VAR_DATA_TYPE(pColVal->type)) {
-          SColVal *pTColVal = taosArrayGet(pMerger->pArray, iCol);
-          if (!COL_VAL_IS_NULL(pColVal)) {
-            code = tRealloc(&pTColVal->value.pData, pColVal->value.nData);
-            if (code) return code;
-
-            pTColVal->value.nData = pColVal->value.nData;
-            if (pTColVal->value.nData) {
-              memcpy(pTColVal->value.pData, pColVal->value.pData, pTColVal->value.nData);
-            }
-            pTColVal->flag = 0;
-          } else {
-            tFree(pTColVal->value.pData);
-            taosArraySet(pMerger->pArray, iCol, pColVal);
-          }
-        } else {
-          taosArraySet(pMerger->pArray, iCol, pColVal);
-        }
-      }
-    } else if (key.version < pMerger->version) {
-      SColVal *tColVal = (SColVal *)taosArrayGet(pMerger->pArray, iCol);
-      if (COL_VAL_IS_NONE(tColVal) && !COL_VAL_IS_NONE(pColVal)) {
-        if ((!COL_VAL_IS_NULL(pColVal)) && IS_VAR_DATA_TYPE(pColVal->type)) {
-          code = tRealloc(&tColVal->value.pData, pColVal->value.nData);
-          if (code) return code;
-
-          tColVal->value.nData = pColVal->value.nData;
-          if (pColVal->value.nData) {
-            memcpy(tColVal->value.pData, pColVal->value.pData, pColVal->value.nData);
-          }
-          tColVal->flag = 0;
-        } else {
-          taosArraySet(pMerger->pArray, iCol, pColVal);
-        }
-      }
-    } else {
-      ASSERT(0 && "dup versions not allowed");
-    }
-  }
-
-  pMerger->version = key.version;
-  return code;
-}
-/*
-int32_t tsdbRowMergerInit(SRowMerger *pMerger, TSDBROW *pRow, STSchema *pTSchema) {
-  int32_t   code = 0;
-  TSDBKEY   key = TSDBROW_KEY(pRow);
-  SColVal  *pColVal = &(SColVal){0};
-  STColumn *pTColumn;
-
-  pMerger->pTSchema = pTSchema;
-  pMerger->version = key.version;
-
-  pMerger->pArray = taosArrayInit(pTSchema->numOfCols, sizeof(SColVal));
-  if (pMerger->pArray == NULL) {
-    code = TSDB_CODE_OUT_OF_MEMORY;
-    goto _exit;
-  }
-
-  // ts
-  pTColumn = &pTSchema->columns[0];
-
-  ASSERT(pTColumn->type == TSDB_DATA_TYPE_TIMESTAMP);
-
-  *pColVal = COL_VAL_VALUE(pTColumn->colId, pTColumn->type, (SValue){.val = key.ts});
-  if (taosArrayPush(pMerger->pArray, pColVal) == NULL) {
-    code = TSDB_CODE_OUT_OF_MEMORY;
-    goto _exit;
-  }
-
-  // other
-  for (int16_t iCol = 1; iCol < pTSchema->numOfCols; iCol++) {
-    tsdbRowGetColVal(pRow, pTSchema, iCol, pColVal);
-    if ((!COL_VAL_IS_NONE(pColVal)) && (!COL_VAL_IS_NULL(pColVal)) && IS_VAR_DATA_TYPE(pColVal->type)) {
-      uint8_t *pVal = pColVal->value.pData;
-
-      pColVal->value.pData = NULL;
-      code = tRealloc(&pColVal->value.pData, pColVal->value.nData);
-      if (code) goto _exit;
-
-      if (pColVal->value.nData) {
-        memcpy(pColVal->value.pData, pVal, pColVal->value.nData);
-      }
-    }
+    ASSERT(pTColumn->type == TSDB_DATA_TYPE_TIMESTAMP);
 
+    *pColVal = COL_VAL_VALUE(pTColumn->colId, pTColumn->type, (SValue){.val = key.ts});
     if (taosArrayPush(pMerger->pArray, pColVal) == NULL) {
       code = TSDB_CODE_OUT_OF_MEMORY;
-      goto _exit;
+      return code;
+      //      goto _exit;
+    }
+
+    // other
+    for (iCol = 1; jCol < pTSchema->numOfCols && iCol < pMerger->pTSchema->numOfCols; ++iCol) {
+      pTColumn = &pMerger->pTSchema->columns[iCol];
+      if (pTSchema->columns[jCol].colId < pTColumn->colId) {
+        ++jCol;
+        --iCol;
+        continue;
+      } else if (pTSchema->columns[jCol].colId > pTColumn->colId) {
+        taosArrayPush(pMerger->pArray, &COL_VAL_NONE(pTColumn->colId, pTColumn->type));
+        continue;
+      }
+
+      tsdbRowGetColVal(pRow, pTSchema, jCol++, pColVal);
+      if ((!COL_VAL_IS_NONE(pColVal)) && (!COL_VAL_IS_NULL(pColVal)) && IS_VAR_DATA_TYPE(pColVal->type)) {
+        uint8_t *pVal = pColVal->value.pData;
+
+        pColVal->value.pData = NULL;
+        code = tRealloc(&pColVal->value.pData, pColVal->value.nData);
+        if (code) {
+          return TSDB_CODE_OUT_OF_MEMORY;
+        }
+
+        if (pColVal->value.nData) {
+          memcpy(pColVal->value.pData, pVal, pColVal->value.nData);
+        }
+      }
+
+      if (taosArrayPush(pMerger->pArray, pColVal) == NULL) {
+        code = TSDB_CODE_OUT_OF_MEMORY;
+        return code;
+      }
+    }
+
+    for (; iCol < pMerger->pTSchema->numOfCols; ++iCol) {
+      pTColumn = &pMerger->pTSchema->columns[iCol];
+      taosArrayPush(pMerger->pArray, &COL_VAL_NONE(pTColumn->colId, pTColumn->type));
+    }
+
+    pMerger->version = key.version;
+    return 0;
+  } else {
+    ASSERT(((SColVal *)pMerger->pArray->pData)->value.val == key.ts);
+
+    for (iCol = 1; iCol < pMerger->pTSchema->numOfCols && jCol < pTSchema->numOfCols; ++iCol) {
+      pTColumn = &pMerger->pTSchema->columns[iCol];
+      if (pTSchema->columns[jCol].colId < pTColumn->colId) {
+        ++jCol;
+        --iCol;
+        continue;
+      } else if (pTSchema->columns[jCol].colId > pTColumn->colId) {
+        continue;
+      }
+
+      tsdbRowGetColVal(pRow, pTSchema, jCol++, pColVal);
+
+      if (key.version > pMerger->version) {
+        if (!COL_VAL_IS_NONE(pColVal)) {
+          if (IS_VAR_DATA_TYPE(pColVal->type)) {
+            SColVal *pTColVal = taosArrayGet(pMerger->pArray, iCol);
+            if (!COL_VAL_IS_NULL(pColVal)) {
+              code = tRealloc(&pTColVal->value.pData, pColVal->value.nData);
+              if (code) return code;
+
+              pTColVal->value.nData = pColVal->value.nData;
+              if (pTColVal->value.nData) {
+                memcpy(pTColVal->value.pData, pColVal->value.pData, pTColVal->value.nData);
+              }
+              pTColVal->flag = 0;
+            } else {
+              tFree(pTColVal->value.pData);
+              taosArraySet(pMerger->pArray, iCol, pColVal);
+            }
+          } else {
+            taosArraySet(pMerger->pArray, iCol, pColVal);
+          }
+        }
+      } else if (key.version < pMerger->version) {
+        SColVal *tColVal = (SColVal *)taosArrayGet(pMerger->pArray, iCol);
+        if (COL_VAL_IS_NONE(tColVal) && !COL_VAL_IS_NONE(pColVal)) {
+          if ((!COL_VAL_IS_NULL(pColVal)) && IS_VAR_DATA_TYPE(pColVal->type)) {
+            code = tRealloc(&tColVal->value.pData, pColVal->value.nData);
+            if (code) return code;
+
+            tColVal->value.nData = pColVal->value.nData;
+            if (pColVal->value.nData) {
+              memcpy(tColVal->value.pData, pColVal->value.pData, pColVal->value.nData);
+            }
+            tColVal->flag = 0;
+          } else {
+            taosArraySet(pMerger->pArray, iCol, pColVal);
+          }
+        }
+      } else {
+        ASSERT(0 && "dup versions not allowed");
+      }
+    }
+
+    pMerger->version = key.version;
+    return code;
+  }
+}
+
+int32_t tsdbRowMergerInit(SRowMerger* pMerger, STSchema *pSchema) {
+  pMerger->pTSchema = pSchema;
+  pMerger->pArray = taosArrayInit(pSchema->numOfCols, sizeof(SColVal));
+  if (pMerger->pArray == NULL) {
+    return TSDB_CODE_OUT_OF_MEMORY;
+  } else {
+    return TSDB_CODE_SUCCESS;
+  }
+}
+
+void tsdbRowMergerClear(SRowMerger* pMerger) {
+  for (int32_t iCol = 1; iCol < pMerger->pTSchema->numOfCols; iCol++) {
+    SColVal *pTColVal = taosArrayGet(pMerger->pArray, iCol);
+    if (IS_VAR_DATA_TYPE(pTColVal->type)) {
+      tFree(pTColVal->value.pData);
     }
   }
 
-_exit:
-  return code;
+  taosArrayClear(pMerger->pArray);
 }
-*/
-void tsdbRowMergerClear(SRowMerger *pMerger) {
-  for (int32_t iCol = 1; iCol < pMerger->pTSchema->numOfCols; iCol++) {
+
+void tsdbRowMergerCleanup(SRowMerger* pMerger) {
+  int32_t numOfCols = taosArrayGetSize(pMerger->pArray);
+  for (int32_t iCol = 1; iCol < numOfCols; iCol++) {
     SColVal *pTColVal = taosArrayGet(pMerger->pArray, iCol);
     if (IS_VAR_DATA_TYPE(pTColVal->type)) {
       tFree(pTColVal->value.pData);
@@ -840,72 +796,7 @@ void tsdbRowMergerClear(SRowMerger *pMerger) {
 
   taosArrayDestroy(pMerger->pArray);
 }
-/*
-int32_t tsdbRowMerge(SRowMerger *pMerger, TSDBROW *pRow) {
-  int32_t  code = 0;
-  TSDBKEY  key = TSDBROW_KEY(pRow);
-  SColVal *pColVal = &(SColVal){0};
 
-  ASSERT(((SColVal *)pMerger->pArray->pData)->value.val == key.ts);
-
-  for (int32_t iCol = 1; iCol < pMerger->pTSchema->numOfCols; iCol++) {
-    tsdbRowGetColVal(pRow, pMerger->pTSchema, iCol, pColVal);
-
-    if (key.version > pMerger->version) {
-      if (!COL_VAL_IS_NONE(pColVal)) {
-        if (IS_VAR_DATA_TYPE(pColVal->type)) {
-          SColVal *pTColVal = taosArrayGet(pMerger->pArray, iCol);
-          if (!COL_VAL_IS_NULL(pColVal)) {
-            code = tRealloc(&pTColVal->value.pData, pColVal->value.nData);
-            if (code) goto _exit;
-
-            pTColVal->value.nData = pColVal->value.nData;
-            if (pTColVal->value.nData) {
-              memcpy(pTColVal->value.pData, pColVal->value.pData, pTColVal->value.nData);
-            }
-            pTColVal->flag = 0;
-          } else {
-            tFree(pTColVal->value.pData);
-            pTColVal->value.pData = NULL;
-            taosArraySet(pMerger->pArray, iCol, pColVal);
-          }
-        } else {
-          taosArraySet(pMerger->pArray, iCol, pColVal);
-        }
-      }
-    } else if (key.version < pMerger->version) {
-      SColVal *tColVal = (SColVal *)taosArrayGet(pMerger->pArray, iCol);
-      if (COL_VAL_IS_NONE(tColVal) && !COL_VAL_IS_NONE(pColVal)) {
-        if (IS_VAR_DATA_TYPE(pColVal->type)) {
-          if (!COL_VAL_IS_NULL(pColVal)) {
-            code = tRealloc(&tColVal->value.pData, pColVal->value.nData);
-            if (code) goto _exit;
-
-            tColVal->value.nData = pColVal->value.nData;
-            if (tColVal->value.nData) {
-              memcpy(tColVal->value.pData, pColVal->value.pData, tColVal->value.nData);
-            }
-            tColVal->flag = 0;
-          } else {
-            tFree(tColVal->value.pData);
-            tColVal->value.pData = NULL;
-            taosArraySet(pMerger->pArray, iCol, pColVal);
-          }
-        } else {
-          taosArraySet(pMerger->pArray, iCol, pColVal);
-        }
-      }
-    } else {
-      ASSERT(0);
-    }
-  }
-
-  pMerger->version = key.version;
-
-_exit:
-  return code;
-}
-*/
 int32_t tsdbRowMergerGetRow(SRowMerger *pMerger, SRow **ppRow) {
   return tRowBuild(pMerger->pArray, pMerger->pTSchema, ppRow);
 }
@@ -1160,8 +1051,6 @@ int32_t tBlockDataCreate(SBlockData *pBlockData) {
   pBlockData->aTSKEY = NULL;
   pBlockData->nColData = 0;
   pBlockData->aColData = NULL;
-
-_exit:
   return code;
 }
 
@@ -1218,9 +1107,10 @@ int32_t tBlockDataInit(SBlockData *pBlockData, TABLEID *pId, STSchema *pTSchema,
     int32_t   iColumn = 1;
     STColumn *pTColumn = &pTSchema->columns[iColumn];
     for (int32_t iCid = 0; iCid < nCid; iCid++) {
-      if (ASSERTS(pTColumn != NULL, "invalid input param")) {
-        code = TSDB_CODE_INVALID_PARA;
-        goto _exit;
+
+      // aCid array (from taos client catalog) contains columns that does not exist in the pTSchema. the pTSchema is newer
+      if (pTColumn == NULL) {
+        continue;
       }
 
       while (pTColumn->colId < aCid[iCid]) {
@@ -1229,9 +1119,8 @@ int32_t tBlockDataInit(SBlockData *pBlockData, TABLEID *pId, STSchema *pTSchema,
         pTColumn = &pTSchema->columns[iColumn];
       }
 
-      if (ASSERTS(pTColumn->colId == aCid[iCid], "invalid input param")) {
-        code = TSDB_CODE_INVALID_PARA;
-        goto _exit;
+      if (pTColumn->colId != aCid[iCid]) {
+        continue;
       }
 
       tColDataInit(&pBlockData->aColData[iCid], pTColumn->colId, pTColumn->type,
diff --git a/source/dnode/vnode/src/vnd/vnodeSvr.c b/source/dnode/vnode/src/vnd/vnodeSvr.c
index b62bf27def..c608403456 100644
--- a/source/dnode/vnode/src/vnd/vnodeSvr.c
+++ b/source/dnode/vnode/src/vnd/vnodeSvr.c
@@ -448,7 +448,6 @@ int32_t vnodeProcessWriteMsg(SVnode *pVnode, SRpcMsg *pMsg, int64_t version, SRp
   walApplyVer(pVnode->pWal, version);
 
   if (tqPushMsg(pVnode->pTq, pMsg->pCont, pMsg->contLen, pMsg->msgType, version) < 0) {
-    /*vInfo("vgId:%d, push msg end", pVnode->config.vgId);*/
     vError("vgId:%d, failed to push msg to TQ since %s", TD_VID(pVnode), tstrerror(terrno));
     return -1;
   }
@@ -487,11 +486,16 @@ int32_t vnodePreprocessQueryMsg(SVnode *pVnode, SRpcMsg *pMsg) {
 
 int32_t vnodeProcessQueryMsg(SVnode *pVnode, SRpcMsg *pMsg) {
   vTrace("message in vnode query queue is processing");
-  if ((pMsg->msgType == TDMT_SCH_QUERY) && !syncIsReadyForRead(pVnode->sync)) {
+  if ((pMsg->msgType == TDMT_SCH_QUERY || pMsg->msgType == TDMT_VND_TMQ_CONSUME) && !syncIsReadyForRead(pVnode->sync)) {
     vnodeRedirectRpcMsg(pVnode, pMsg, terrno);
     return 0;
   }
 
+  if (pMsg->msgType == TDMT_VND_TMQ_CONSUME && !pVnode->restored) {
+    vnodeRedirectRpcMsg(pVnode, pMsg, TSDB_CODE_SYN_RESTORING);
+    return 0;
+  }
+
   SReadHandle handle = {.meta = pVnode->pMeta, .config = &pVnode->config, .vnode = pVnode, .pMsgCb = &pVnode->msgCb};
   switch (pMsg->msgType) {
     case TDMT_SCH_QUERY:
@@ -499,6 +503,8 @@ int32_t vnodeProcessQueryMsg(SVnode *pVnode, SRpcMsg *pMsg) {
       return qWorkerProcessQueryMsg(&handle, pVnode->pQuery, pMsg, 0);
     case TDMT_SCH_QUERY_CONTINUE:
       return qWorkerProcessCQueryMsg(&handle, pVnode->pQuery, pMsg, 0);
+    case TDMT_VND_TMQ_CONSUME:
+      return tqProcessPollReq(pVnode->pTq, pMsg);
     default:
       vError("unknown msg type:%d in query queue", pMsg->msgType);
       return TSDB_CODE_APP_ERROR;
@@ -508,17 +514,12 @@ int32_t vnodeProcessQueryMsg(SVnode *pVnode, SRpcMsg *pMsg) {
 int32_t vnodeProcessFetchMsg(SVnode *pVnode, SRpcMsg *pMsg, SQueueInfo *pInfo) {
   vTrace("vgId:%d, msg:%p in fetch queue is processing", pVnode->config.vgId, pMsg);
   if ((pMsg->msgType == TDMT_SCH_FETCH || pMsg->msgType == TDMT_VND_TABLE_META || pMsg->msgType == TDMT_VND_TABLE_CFG ||
-       pMsg->msgType == TDMT_VND_BATCH_META || pMsg->msgType == TDMT_VND_TMQ_CONSUME) &&
+       pMsg->msgType == TDMT_VND_BATCH_META) &&
       !syncIsReadyForRead(pVnode->sync)) {
     vnodeRedirectRpcMsg(pVnode, pMsg, terrno);
     return 0;
   }
 
-  if (pMsg->msgType == TDMT_VND_TMQ_CONSUME && !pVnode->restored) {
-    vnodeRedirectRpcMsg(pVnode, pMsg, TSDB_CODE_SYN_RESTORING);
-    return 0;
-  }
-
   switch (pMsg->msgType) {
     case TDMT_SCH_FETCH:
     case TDMT_SCH_MERGE_FETCH:
@@ -537,8 +538,6 @@ int32_t vnodeProcessFetchMsg(SVnode *pVnode, SRpcMsg *pMsg, SQueueInfo *pInfo) {
       return vnodeGetTableCfg(pVnode, pMsg, true);
     case TDMT_VND_BATCH_META:
       return vnodeGetBatchMeta(pVnode, pMsg);
-    case TDMT_VND_TMQ_CONSUME:
-      return tqProcessPollReq(pVnode->pTq, pMsg);
     case TDMT_STREAM_TASK_RUN:
       return tqProcessTaskRunReq(pVnode->pTq, pMsg);
     case TDMT_STREAM_TASK_DISPATCH:
@@ -1007,7 +1006,7 @@ static int32_t vnodeResetTableCxt(SMeta *pMeta, SSubmitReqConvertCxt *pCxt) {
   }
   tdSTSRowIterInit(&pCxt->rowIter, pCxt->pTbSchema);
 
-  tDestroySSubmitTbData(pCxt->pTbData, TSDB_MSG_FLG_ENCODE);
+  tDestroySubmitTbData(pCxt->pTbData, TSDB_MSG_FLG_ENCODE);
   if (NULL == pCxt->pTbData) {
     pCxt->pTbData = taosMemoryCalloc(1, sizeof(SSubmitTbData));
     if (NULL == pCxt->pTbData) {
@@ -1039,7 +1038,7 @@ static int32_t vnodeResetTableCxt(SMeta *pMeta, SSubmitReqConvertCxt *pCxt) {
 
 static void vnodeDestroySubmitReqConvertCxt(SSubmitReqConvertCxt *pCxt) {
   taosMemoryFreeClear(pCxt->pTbSchema);
-  tDestroySSubmitTbData(pCxt->pTbData, TSDB_MSG_FLG_ENCODE);
+  tDestroySubmitTbData(pCxt->pTbData, TSDB_MSG_FLG_ENCODE);
   taosMemoryFreeClear(pCxt->pTbData);
   taosArrayDestroy(pCxt->pColValues);
 }
@@ -1149,7 +1148,7 @@ static int32_t vnodeRebuildSubmitReqMsg(SSubmitReq2 *pSubmitReq, void **ppMsg) {
   int32_t  code = TSDB_CODE_SUCCESS;
   char    *pMsg = NULL;
   uint32_t msglen = 0;
-  tEncodeSize(tEncodeSSubmitReq2, pSubmitReq, msglen, code);
+  tEncodeSize(tEncodeSubmitReq, pSubmitReq, msglen, code);
   if (TSDB_CODE_SUCCESS == code) {
     pMsg = taosMemoryMalloc(msglen);
     if (NULL == pMsg) {
@@ -1159,7 +1158,7 @@ static int32_t vnodeRebuildSubmitReqMsg(SSubmitReq2 *pSubmitReq, void **ppMsg) {
   if (TSDB_CODE_SUCCESS == code) {
     SEncoder encoder;
     tEncoderInit(&encoder, pMsg, msglen);
-    code = tEncodeSSubmitReq2(&encoder, pSubmitReq);
+    code = tEncodeSubmitReq(&encoder, pSubmitReq);
     tEncoderClear(&encoder);
   }
   if (TSDB_CODE_SUCCESS == code) {
@@ -1199,7 +1198,7 @@ static int32_t vnodeProcessSubmitReq(SVnode *pVnode, int64_t version, void *pReq
     len -= sizeof(SSubmitReq2Msg);
     SDecoder dc = {0};
     tDecoderInit(&dc, pReq, len);
-    if (tDecodeSSubmitReq2(&dc, pSubmitReq) < 0) {
+    if (tDecodeSubmitReq(&dc, pSubmitReq) < 0) {
       code = TSDB_CODE_INVALID_MSG;
       goto _exit;
     }
@@ -1348,6 +1347,7 @@ static int32_t vnodeProcessSubmitReq(SVnode *pVnode, int64_t version, void *pReq
           code = terrno;
           goto _exit;
         }
+        terrno = 0;
         pSubmitTbData->uid = pSubmitTbData->pCreateTbReq->uid;  // update uid if table exist for using below
       }
     }
@@ -1387,7 +1387,7 @@ _exit:
 
   // clear
   taosArrayDestroy(newTbUids);
-  tDestroySSubmitReq2(pSubmitReq, 0 == pMsg->version ? TSDB_MSG_FLG_CMPT : TSDB_MSG_FLG_DECODE);
+  tDestroySubmitReq(pSubmitReq, 0 == pMsg->version ? TSDB_MSG_FLG_CMPT : TSDB_MSG_FLG_DECODE);
   tDestroySSubmitRsp2(pSubmitRsp, TSDB_MSG_FLG_ENCODE);
 
   if (code) terrno = code;
diff --git a/source/dnode/vnode/src/vnd/vnodeSync.c b/source/dnode/vnode/src/vnd/vnodeSync.c
index dc2d709d76..1f958c569f 100644
--- a/source/dnode/vnode/src/vnd/vnodeSync.c
+++ b/source/dnode/vnode/src/vnd/vnodeSync.c
@@ -555,7 +555,12 @@ static void vnodeRestoreFinish(const SSyncFSM *pFsm, const SyncIndex commitIdx)
   vInfo("vgId:%d, sync restore finished, start to restore stream tasks by replay wal", pVnode->config.vgId);
 
   // start to restore all stream tasks
-  tqStartStreamTasks(pVnode->pTq);
+  if (tsDisableStream) {
+    vInfo("vgId:%d, not restore stream tasks, since disabled", pVnode->config.vgId);
+  } else {
+    vInfo("vgId:%d start to restore stream tasks", pVnode->config.vgId);
+    tqStartStreamTasks(pVnode->pTq);
+  }
 }
 
 static void vnodeBecomeFollower(const SSyncFSM *pFsm) {
diff --git a/source/libs/catalog/inc/catalogInt.h b/source/libs/catalog/inc/catalogInt.h
index 0ddeab5cc3..0293584487 100644
--- a/source/libs/catalog/inc/catalogInt.h
+++ b/source/libs/catalog/inc/catalogInt.h
@@ -58,6 +58,7 @@ typedef enum {
   CTG_CI_OTHERTABLE_META,
   CTG_CI_TBL_SMA,
   CTG_CI_TBL_CFG,
+  CTG_CI_TBL_TAG,
   CTG_CI_INDEX_INFO,
   CTG_CI_USER,
   CTG_CI_UDF,
@@ -111,6 +112,7 @@ typedef enum {
   CTG_TASK_GET_SVR_VER,
   CTG_TASK_GET_TB_META_BATCH,
   CTG_TASK_GET_TB_HASH_BATCH,
+  CTG_TASK_GET_TB_TAG,
 } CTG_TASK_TYPE;
 
 typedef enum {
@@ -153,6 +155,11 @@ typedef struct SCtgTbCacheInfo {
   int32_t  tbType;
 } SCtgTbCacheInfo;
 
+typedef struct SCtgTbMetaParam {
+  SName*  pName;
+  int32_t flag;
+} SCtgTbMetaParam;
+
 typedef struct SCtgTbMetaCtx {
   SCtgTbCacheInfo tbInfo;
   int32_t         vgId;
@@ -187,6 +194,11 @@ typedef struct SCtgTbCfgCtx {
   SVgroupInfo* pVgInfo;
 } SCtgTbCfgCtx;
 
+typedef struct SCtgTbTagCtx {
+  SName*       pName;
+  SVgroupInfo* pVgInfo;
+} SCtgTbTagCtx;
+
 typedef struct SCtgDbVgCtx {
   char dbFName[TSDB_DB_FNAME_LEN];
 } SCtgDbVgCtx;
@@ -311,6 +323,7 @@ typedef struct SCtgJob {
   catalogCallback  userFp;
   int32_t          tbMetaNum;
   int32_t          tbHashNum;
+  int32_t          tbTagNum;
   int32_t          dbVgNum;
   int32_t          udfNum;
   int32_t          qnodeNum;
@@ -353,6 +366,7 @@ typedef struct SCtgSubRes {
 
 struct SCtgTask {
   CTG_TASK_TYPE   type;
+  bool            subTask;
   int32_t         taskId;
   SCtgJob*        pJob;
   void*           taskCtx;
@@ -637,6 +651,7 @@ typedef struct SCtgCacheItemInfo {
 #define CTG_FLAG_SYS_DB       0x8
 #define CTG_FLAG_FORCE_UPDATE 0x10
 #define CTG_FLAG_ONLY_CACHE   0x20
+#define CTG_FLAG_SYNC_OP      0x40
 
 #define CTG_FLAG_SET(_flag, _v) ((_flag) |= (_v))
 
@@ -945,6 +960,10 @@ void    ctgReleaseVgMetaToCache(SCatalog* pCtg, SCtgDBCache* dbCache, SCtgTbCach
 void    ctgReleaseTbMetaToCache(SCatalog* pCtg, SCtgDBCache* dbCache, SCtgTbCache* pCache);
 void    ctgGetGlobalCacheStat(SCtgCacheStat* pStat);
 int32_t ctgChkSetAuthRes(SCatalog* pCtg, SCtgAuthReq* req, SCtgAuthRsp* res);
+int32_t ctgGetTbMeta(SCatalog* pCtg, SRequestConnInfo* pConn, SCtgTbMetaCtx* ctx, STableMeta** pTableMeta);
+int32_t ctgGetCachedStbNameFromSuid(SCatalog* pCtg, char* dbFName, uint64_t suid, char **stbName);
+int32_t ctgGetTbTagCb(SCtgTask* pTask);
+int32_t ctgGetUserCb(SCtgTask* pTask);
 
 extern SCatalogMgmt      gCtgMgmt;
 extern SCtgDebug         gCTGDebug;
diff --git a/source/libs/catalog/src/catalog.c b/source/libs/catalog/src/catalog.c
index 6ffef6b181..f8ead25852 100644
--- a/source/libs/catalog/src/catalog.c
+++ b/source/libs/catalog/src/catalog.c
@@ -208,7 +208,7 @@ int32_t ctgGetTbMeta(SCatalog* pCtg, SRequestConnInfo* pConn, SCtgTbMetaCtx* ctx
   }
 
   while (true) {
-    CTG_ERR_JRET(ctgRefreshTbMeta(pCtg, pConn, ctx, &output, false));
+    CTG_ERR_JRET(ctgRefreshTbMeta(pCtg, pConn, ctx, &output, ctx->flag & CTG_FLAG_SYNC_OP));
 
     if (CTG_IS_META_TABLE(output->metaType)) {
       *pTableMeta = output->tbMeta;
@@ -429,6 +429,48 @@ int32_t ctgGetTbCfg(SCatalog* pCtg, SRequestConnInfo* pConn, SName* pTableName,
   CTG_RET(TSDB_CODE_SUCCESS);
 }
 
+int32_t ctgGetTbTag(SCatalog* pCtg, SRequestConnInfo* pConn, SName* pTableName, SArray** pRes) {
+  SVgroupInfo vgroupInfo = {0};
+  STableCfg* pCfg = NULL;
+  int32_t code = 0;
+
+  CTG_ERR_RET(ctgGetTbHashVgroup(pCtg, pConn, pTableName, &vgroupInfo, NULL));
+  CTG_ERR_RET(ctgGetTableCfgFromVnode(pCtg, pConn, pTableName, &vgroupInfo, &pCfg, NULL));
+
+  if (NULL == pCfg->pTags || pCfg->tagsLen <= 0) {
+    ctgError("invalid tag in tbCfg rsp, pTags:%p, len:%d", pCfg->pTags, pCfg->tagsLen);
+    CTG_ERR_JRET(TSDB_CODE_INVALID_MSG);
+  }
+
+  SArray* pTagVals = NULL;
+  STag*   pTag = (STag*)pCfg->pTags;
+
+  if (tTagIsJson(pTag)) {
+    pTagVals = taosArrayInit(1, sizeof(STagVal));
+    if (NULL == pTagVals) {
+      CTG_ERR_JRET(TSDB_CODE_OUT_OF_MEMORY);
+    }
+
+    char* pJson = parseTagDatatoJson(pTag);
+    STagVal tagVal;
+    tagVal.cid = 0;
+    tagVal.type = TSDB_DATA_TYPE_JSON;
+    tagVal.pData = pJson;
+    tagVal.nData = strlen(pJson);
+    taosArrayPush(pTagVals, &tagVal);
+  } else {
+    CTG_ERR_JRET(tTagToValArray((const STag*)pCfg->pTags, &pTagVals));
+  }
+
+  *pRes = pTagVals;
+
+_return:
+
+  tFreeSTableCfgRsp((STableCfgRsp*)pCfg);
+  
+  CTG_RET(code);
+}
+
 int32_t ctgGetTbDistVgInfo(SCatalog* pCtg, SRequestConnInfo* pConn, SName* pTableName, SArray** pVgList) {
   STableMeta*   tbMeta = NULL;
   int32_t       code = 0;
@@ -1448,6 +1490,21 @@ _return:
   CTG_API_LEAVE(code);
 }
 
+int32_t catalogGetTableTag(SCatalog* pCtg, SRequestConnInfo* pConn, const SName* pTableName, SArray** pRes) {
+  CTG_API_ENTER();
+
+  if (NULL == pCtg || NULL == pConn || NULL == pTableName || NULL == pRes) {
+    CTG_API_LEAVE(TSDB_CODE_CTG_INVALID_INPUT);
+  }
+
+  int32_t code = 0;
+  CTG_ERR_JRET(ctgGetTbTag(pCtg, pConn, (SName*)pTableName, pRes));
+
+_return:
+
+  CTG_API_LEAVE(code);
+}
+
 int32_t catalogRefreshGetTableCfg(SCatalog* pCtg, SRequestConnInfo* pConn, const SName* pTableName, STableCfg** pCfg) {
   CTG_API_ENTER();
 
diff --git a/source/libs/catalog/src/ctgAsync.c b/source/libs/catalog/src/ctgAsync.c
index 788cf1f74d..1d904213ba 100644
--- a/source/libs/catalog/src/ctgAsync.c
+++ b/source/libs/catalog/src/ctgAsync.c
@@ -21,7 +21,8 @@
 #include "trpc.h"
 
 int32_t ctgInitGetTbMetaTask(SCtgJob* pJob, int32_t taskIdx, void* param) {
-  SName*   name = (SName*)param;
+  SCtgTbMetaParam* pParam = (SCtgTbMetaParam*)param;
+  SName*   name = pParam->pName;
   SCtgTask task = {0};
 
   task.type = CTG_TASK_GET_TB_META;
@@ -41,7 +42,7 @@ int32_t ctgInitGetTbMetaTask(SCtgJob* pJob, int32_t taskIdx, void* param) {
   }
 
   memcpy(ctx->pName, name, sizeof(*name));
-  ctx->flag = CTG_FLAG_UNKNOWN_STB;
+  ctx->flag = pParam->flag | CTG_FLAG_UNKNOWN_STB;
 
   taosArrayPush(pJob->pTasks, &task);
 
@@ -386,6 +387,37 @@ int32_t ctgInitGetTbCfgTask(SCtgJob* pJob, int32_t taskIdx, void* param) {
   return TSDB_CODE_SUCCESS;
 }
 
+int32_t ctgInitGetTbTagTask(SCtgJob* pJob, int32_t taskIdx, void* param) {
+  SName*   name = (SName*)param;
+  SCtgTask task = {0};
+
+  task.type = CTG_TASK_GET_TB_TAG;
+  task.taskId = taskIdx;
+  task.pJob = pJob;
+
+  task.taskCtx = taosMemoryCalloc(1, sizeof(SCtgTbTagCtx));
+  if (NULL == task.taskCtx) {
+    CTG_ERR_RET(TSDB_CODE_OUT_OF_MEMORY);
+  }
+
+  SCtgTbTagCtx* ctx = task.taskCtx;
+  ctx->pName = taosMemoryMalloc(sizeof(*name));
+  if (NULL == ctx->pName) {
+    taosMemoryFree(task.taskCtx);
+    CTG_ERR_RET(TSDB_CODE_OUT_OF_MEMORY);
+  }
+
+  memcpy(ctx->pName, name, sizeof(*name));
+
+  taosArrayPush(pJob->pTasks, &task);
+
+  qDebug("QID:0x%" PRIx64 " the %dth task type %s initialized, tbName:%s", pJob->queryId, taskIdx,
+         ctgTaskTypeStr(task.type), name->tname);
+
+  return TSDB_CODE_SUCCESS;
+}
+
+
 int32_t ctgHandleForceUpdate(SCatalog* pCtg, int32_t taskNum, SCtgJob* pJob, const SCatalogReq* pReq) {
   SHashObj* pDb = taosHashInit(taskNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK);
   SHashObj* pTb = taosHashInit(taskNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK);
@@ -437,6 +469,15 @@ int32_t ctgHandleForceUpdate(SCatalog* pCtg, int32_t taskNum, SCtgJob* pJob, con
     char   dbFName[TSDB_DB_FNAME_LEN];
     tNameGetFullDbName(name, dbFName);
     taosHashPut(pDb, dbFName, strlen(dbFName), dbFName, TSDB_DB_FNAME_LEN);
+    taosHashPut(pTb, name, sizeof(SName), name, sizeof(SName));
+  }
+
+  for (int32_t i = 0; i < pJob->tbTagNum; ++i) {
+    SName* name = taosArrayGet(pReq->pTableTag, i);
+    char   dbFName[TSDB_DB_FNAME_LEN];
+    tNameGetFullDbName(name, dbFName);
+    taosHashPut(pDb, dbFName, strlen(dbFName), dbFName, TSDB_DB_FNAME_LEN);
+    taosHashPut(pTb, name, sizeof(SName), name, sizeof(SName));
   }
 
   char* dbFName = taosHashIterate(pDb, NULL);
@@ -505,9 +546,10 @@ int32_t ctgInitJob(SCatalog* pCtg, SRequestConnInfo* pConn, SCtgJob** job, const
   int32_t dbInfoNum = (int32_t)taosArrayGetSize(pReq->pDbInfo);
   int32_t tbIndexNum = (int32_t)taosArrayGetSize(pReq->pTableIndex);
   int32_t tbCfgNum = (int32_t)taosArrayGetSize(pReq->pTableCfg);
+  int32_t tbTagNum = (int32_t)taosArrayGetSize(pReq->pTableTag);
 
   int32_t taskNum = tbMetaNum + dbVgNum + udfNum + tbHashNum + qnodeNum + dnodeNum + svrVerNum + dbCfgNum + indexNum +
-                    userNum + dbInfoNum + tbIndexNum + tbCfgNum;
+                    userNum + dbInfoNum + tbIndexNum + tbCfgNum + tbTagNum;
 
   *job = taosMemoryCalloc(1, sizeof(SCtgJob));
   if (NULL == *job) {
@@ -537,6 +579,7 @@ int32_t ctgInitJob(SCatalog* pCtg, SRequestConnInfo* pConn, SCtgJob** job, const
   pJob->tbIndexNum = tbIndexNum;
   pJob->tbCfgNum = tbCfgNum;
   pJob->svrVerNum = svrVerNum;
+  pJob->tbTagNum = tbTagNum;
 
 #if CTG_BATCH_FETCH
   pJob->pBatchs =
@@ -604,6 +647,12 @@ int32_t ctgInitJob(SCatalog* pCtg, SRequestConnInfo* pConn, SCtgJob** job, const
     CTG_ERR_JRET(ctgInitTask(pJob, CTG_TASK_GET_TB_CFG, name, NULL));
   }
 
+  for (int32_t i = 0; i < tbTagNum; ++i) {
+    SName* name = taosArrayGet(pReq->pTableTag, i);
+    CTG_ERR_JRET(ctgInitTask(pJob, CTG_TASK_GET_TB_TAG, name, NULL));
+  }
+
+
   for (int32_t i = 0; i < indexNum; ++i) {
     char* indexName = taosArrayGet(pReq->pIndex, i);
     CTG_ERR_JRET(ctgInitTask(pJob, CTG_TASK_GET_INDEX_INFO, indexName, NULL));
@@ -650,6 +699,10 @@ _return:
 }
 
 int32_t ctgDumpTbMetaRes(SCtgTask* pTask) {
+  if (pTask->subTask) {
+    return TSDB_CODE_SUCCESS;
+  }
+  
   SCtgJob* pJob = pTask->pJob;
   if (NULL == pJob->jobRes.pTableMeta) {
     pJob->jobRes.pTableMeta = taosArrayInit(pJob->tbMetaNum, sizeof(SMetaRes));
@@ -665,6 +718,10 @@ int32_t ctgDumpTbMetaRes(SCtgTask* pTask) {
 }
 
 int32_t ctgDumpTbMetasRes(SCtgTask* pTask) {
+  if (pTask->subTask) {
+    return TSDB_CODE_SUCCESS;
+  }
+
   SCtgJob* pJob = pTask->pJob;
 
   pJob->jobRes.pTableMeta = pTask->res;
@@ -673,6 +730,10 @@ int32_t ctgDumpTbMetasRes(SCtgTask* pTask) {
 }
 
 int32_t ctgDumpDbVgRes(SCtgTask* pTask) {
+  if (pTask->subTask) {
+    return TSDB_CODE_SUCCESS;
+  }
+
   SCtgJob* pJob = pTask->pJob;
   if (NULL == pJob->jobRes.pDbVgroup) {
     pJob->jobRes.pDbVgroup = taosArrayInit(pJob->dbVgNum, sizeof(SMetaRes));
@@ -688,6 +749,10 @@ int32_t ctgDumpDbVgRes(SCtgTask* pTask) {
 }
 
 int32_t ctgDumpTbHashRes(SCtgTask* pTask) {
+  if (pTask->subTask) {
+    return TSDB_CODE_SUCCESS;
+  }
+
   SCtgJob* pJob = pTask->pJob;
   if (NULL == pJob->jobRes.pTableHash) {
     pJob->jobRes.pTableHash = taosArrayInit(pJob->tbHashNum, sizeof(SMetaRes));
@@ -703,6 +768,10 @@ int32_t ctgDumpTbHashRes(SCtgTask* pTask) {
 }
 
 int32_t ctgDumpTbHashsRes(SCtgTask* pTask) {
+  if (pTask->subTask) {
+    return TSDB_CODE_SUCCESS;
+  }
+
   SCtgJob* pJob = pTask->pJob;
 
   pJob->jobRes.pTableHash = pTask->res;
@@ -711,9 +780,17 @@ int32_t ctgDumpTbHashsRes(SCtgTask* pTask) {
 }
 
 int32_t ctgDumpTbIndexRes(SCtgTask* pTask) {
+  if (pTask->subTask) {
+    return TSDB_CODE_SUCCESS;
+  }
+
   SCtgJob* pJob = pTask->pJob;
   if (NULL == pJob->jobRes.pTableIndex) {
-    pJob->jobRes.pTableIndex = taosArrayInit(pJob->tbIndexNum, sizeof(SMetaRes));
+    SArray* pRes = taosArrayInit(pJob->tbIndexNum, sizeof(SMetaRes));
+    if (atomic_val_compare_exchange_ptr(&pJob->jobRes.pTableIndex, NULL, pRes)) {
+      taosArrayDestroy(pRes);
+    }
+
     if (NULL == pJob->jobRes.pTableIndex) {
       CTG_ERR_RET(TSDB_CODE_OUT_OF_MEMORY);
     }
@@ -726,9 +803,17 @@ int32_t ctgDumpTbIndexRes(SCtgTask* pTask) {
 }
 
 int32_t ctgDumpTbCfgRes(SCtgTask* pTask) {
+  if (pTask->subTask) {
+    return TSDB_CODE_SUCCESS;
+  }
+
   SCtgJob* pJob = pTask->pJob;
   if (NULL == pJob->jobRes.pTableCfg) {
-    pJob->jobRes.pTableCfg = taosArrayInit(pJob->tbCfgNum, sizeof(SMetaRes));
+    SArray* pRes = taosArrayInit(pJob->tbCfgNum, sizeof(SMetaRes));
+    if (atomic_val_compare_exchange_ptr(&pJob->jobRes.pTableCfg, NULL, pRes)) {
+      taosArrayDestroy(pRes);
+    }
+
     if (NULL == pJob->jobRes.pTableCfg) {
       CTG_ERR_RET(TSDB_CODE_OUT_OF_MEMORY);
     }
@@ -740,7 +825,35 @@ int32_t ctgDumpTbCfgRes(SCtgTask* pTask) {
   return TSDB_CODE_SUCCESS;
 }
 
+int32_t ctgDumpTbTagRes(SCtgTask* pTask) {
+  if (pTask->subTask) {
+    return TSDB_CODE_SUCCESS;
+  }
+
+  SCtgJob* pJob = pTask->pJob;
+  if (NULL == pJob->jobRes.pTableTag) {
+    SArray* pRes = taosArrayInit(pJob->tbTagNum, sizeof(SMetaRes));
+    if (atomic_val_compare_exchange_ptr(&pJob->jobRes.pTableTag, NULL, pRes)) {
+      taosArrayDestroy(pRes);
+    }
+    
+    if (NULL == pJob->jobRes.pTableTag) {
+      CTG_ERR_RET(TSDB_CODE_OUT_OF_MEMORY);
+    }
+  }
+
+  SMetaRes res = {.code = pTask->code, .pRes = pTask->res};
+  taosArrayPush(pJob->jobRes.pTableTag, &res);
+
+  return TSDB_CODE_SUCCESS;
+}
+
+
 int32_t ctgDumpIndexRes(SCtgTask* pTask) {
+  if (pTask->subTask) {
+    return TSDB_CODE_SUCCESS;
+  }
+
   SCtgJob* pJob = pTask->pJob;
   if (NULL == pJob->jobRes.pIndex) {
     pJob->jobRes.pIndex = taosArrayInit(pJob->indexNum, sizeof(SMetaRes));
@@ -756,6 +869,10 @@ int32_t ctgDumpIndexRes(SCtgTask* pTask) {
 }
 
 int32_t ctgDumpQnodeRes(SCtgTask* pTask) {
+  if (pTask->subTask) {
+    return TSDB_CODE_SUCCESS;
+  }
+
   SCtgJob* pJob = pTask->pJob;
   if (NULL == pJob->jobRes.pQnodeList) {
     pJob->jobRes.pQnodeList = taosArrayInit(1, sizeof(SMetaRes));
@@ -771,6 +888,10 @@ int32_t ctgDumpQnodeRes(SCtgTask* pTask) {
 }
 
 int32_t ctgDumpDnodeRes(SCtgTask* pTask) {
+  if (pTask->subTask) {
+    return TSDB_CODE_SUCCESS;
+  }
+
   SCtgJob* pJob = pTask->pJob;
   if (NULL == pJob->jobRes.pDnodeList) {
     pJob->jobRes.pDnodeList = taosArrayInit(1, sizeof(SMetaRes));
@@ -786,6 +907,10 @@ int32_t ctgDumpDnodeRes(SCtgTask* pTask) {
 }
 
 int32_t ctgDumpDbCfgRes(SCtgTask* pTask) {
+  if (pTask->subTask) {
+    return TSDB_CODE_SUCCESS;
+  }
+
   SCtgJob* pJob = pTask->pJob;
   if (NULL == pJob->jobRes.pDbCfg) {
     pJob->jobRes.pDbCfg = taosArrayInit(pJob->dbCfgNum, sizeof(SMetaRes));
@@ -801,6 +926,10 @@ int32_t ctgDumpDbCfgRes(SCtgTask* pTask) {
 }
 
 int32_t ctgDumpDbInfoRes(SCtgTask* pTask) {
+  if (pTask->subTask) {
+    return TSDB_CODE_SUCCESS;
+  }
+
   SCtgJob* pJob = pTask->pJob;
   if (NULL == pJob->jobRes.pDbInfo) {
     pJob->jobRes.pDbInfo = taosArrayInit(pJob->dbInfoNum, sizeof(SMetaRes));
@@ -816,6 +945,10 @@ int32_t ctgDumpDbInfoRes(SCtgTask* pTask) {
 }
 
 int32_t ctgDumpUdfRes(SCtgTask* pTask) {
+  if (pTask->subTask) {
+    return TSDB_CODE_SUCCESS;
+  }
+
   SCtgJob* pJob = pTask->pJob;
   if (NULL == pJob->jobRes.pUdfList) {
     pJob->jobRes.pUdfList = taosArrayInit(pJob->udfNum, sizeof(SMetaRes));
@@ -831,6 +964,10 @@ int32_t ctgDumpUdfRes(SCtgTask* pTask) {
 }
 
 int32_t ctgDumpUserRes(SCtgTask* pTask) {
+  if (pTask->subTask) {
+    return TSDB_CODE_SUCCESS;
+  }
+
   SCtgJob* pJob = pTask->pJob;
   if (NULL == pJob->jobRes.pUser) {
     pJob->jobRes.pUser = taosArrayInit(pJob->userNum, sizeof(SMetaRes));
@@ -846,6 +983,10 @@ int32_t ctgDumpUserRes(SCtgTask* pTask) {
 }
 
 int32_t ctgDumpSvrVer(SCtgTask* pTask) {
+  if (pTask->subTask) {
+    return TSDB_CODE_SUCCESS;
+  }
+
   SCtgJob* pJob = pTask->pJob;
   if (NULL == pJob->jobRes.pSvrVer) {
     pJob->jobRes.pSvrVer = taosMemoryCalloc(1, sizeof(SMetaRes));
@@ -1075,7 +1216,7 @@ int32_t ctgHandleGetTbMetaRsp(SCtgTaskReq* tReq, int32_t reqType, const SDataBuf
 
   STableMetaOutput* pOut = (STableMetaOutput*)pMsgCtx->out;
 
-  ctgUpdateTbMetaToCache(pCtg, pOut, false);
+  ctgUpdateTbMetaToCache(pCtg, pOut, flag & CTG_FLAG_SYNC_OP);
 
   if (CTG_IS_META_BOTH(pOut->metaType)) {
     memcpy(pOut->tbMeta, &pOut->ctbMeta, sizeof(pOut->ctbMeta));
@@ -1472,6 +1613,49 @@ _return:
   CTG_RET(code);
 }
 
+
+int32_t ctgHandleGetTbTagRsp(SCtgTaskReq* tReq, int32_t reqType, const SDataBuf* pMsg, int32_t rspCode) {
+  int32_t   code = 0;
+  SCtgTask* pTask = tReq->pTask;
+  SCatalog* pCtg = pTask->pJob->pCtg;
+  CTG_ERR_JRET(ctgProcessRspMsg(&pTask->msgCtx.out, reqType, pMsg->pData, pMsg->len, rspCode, pTask->msgCtx.target));
+
+  STableCfgRsp* pRsp = (STableCfgRsp*)pTask->msgCtx.out;
+  if (NULL == pRsp->pTags || pRsp->tagsLen <= 0) {
+    ctgError("invalid tag in tbCfg rsp, pTags:%p, len:%d", pRsp->pTags, pRsp->tagsLen);
+    CTG_ERR_JRET(TSDB_CODE_INVALID_MSG);
+  }
+
+  SArray* pTagVals = NULL;
+  STag*   pTag = (STag*)pRsp->pTags;
+
+  if (tTagIsJson(pTag)) {
+    pTagVals = taosArrayInit(1, sizeof(STagVal));
+    if (NULL == pTagVals) {
+      CTG_ERR_JRET(TSDB_CODE_OUT_OF_MEMORY);
+    }
+
+    char* pJson = parseTagDatatoJson(pTag);
+    STagVal tagVal;
+    tagVal.cid = 0;
+    tagVal.type = TSDB_DATA_TYPE_JSON;
+    tagVal.pData = pJson;
+    tagVal.nData = strlen(pJson);
+    taosArrayPush(pTagVals, &tagVal);
+  } else {
+    CTG_ERR_JRET(tTagToValArray((const STag*)pRsp->pTags, &pTagVals));
+  }
+  
+  pTask->res = pTagVals;
+
+_return:
+
+  ctgHandleTaskEnd(pTask, code);
+
+  CTG_RET(code);
+}
+
+
 int32_t ctgHandleGetDbCfgRsp(SCtgTaskReq* tReq, int32_t reqType, const SDataBuf* pMsg, int32_t rspCode) {
   int32_t   code = 0;
   SCtgTask* pTask = tReq->pTask;
@@ -1910,7 +2094,10 @@ int32_t ctgLaunchGetTbCfgTask(SCtgTask* pTask) {
   if (pCtx->tbType <= 0) {
     CTG_ERR_JRET(ctgReadTbTypeFromCache(pCtg, dbFName, pCtx->pName->tname, &pCtx->tbType));
     if (pCtx->tbType <= 0) {
-      CTG_ERR_JRET(ctgLaunchSubTask(pTask, CTG_TASK_GET_TB_META, ctgGetTbCfgCb, pCtx->pName));
+      SCtgTbMetaParam param;
+      param.pName = pCtx->pName;
+      param.flag = 0;
+      CTG_ERR_JRET(ctgLaunchSubTask(pTask, CTG_TASK_GET_TB_META, ctgGetTbCfgCb, ¶m));
       return TSDB_CODE_SUCCESS;
     }
   }
@@ -1940,6 +2127,45 @@ _return:
   CTG_RET(code);
 }
 
+
+int32_t ctgLaunchGetTbTagTask(SCtgTask* pTask) {
+  int32_t           code = 0;
+  SCatalog*         pCtg = pTask->pJob->pCtg;
+  SRequestConnInfo* pConn = &pTask->pJob->conn;
+  SCtgTbTagCtx*     pCtx = (SCtgTbTagCtx*)pTask->taskCtx;
+  SArray*           pRes = NULL;
+  char              dbFName[TSDB_DB_FNAME_LEN];
+  tNameGetFullDbName(pCtx->pName, dbFName);
+  SCtgJob*    pJob = pTask->pJob;
+  SCtgMsgCtx* pMsgCtx = CTG_GET_TASK_MSGCTX(pTask, -1);
+  if (NULL == pMsgCtx->pBatchs) {
+    pMsgCtx->pBatchs = pJob->pBatchs;
+  }
+
+  if (NULL == pCtx->pVgInfo) {
+    CTG_ERR_JRET(ctgGetTbHashVgroupFromCache(pCtg, pCtx->pName, &pCtx->pVgInfo));
+    if (NULL == pCtx->pVgInfo) {
+      CTG_ERR_JRET(ctgLaunchSubTask(pTask, CTG_TASK_GET_DB_VGROUP, ctgGetTbTagCb, dbFName));
+      return TSDB_CODE_SUCCESS;
+    }
+  }
+
+  CTG_CACHE_NHIT_INC(CTG_CI_TBL_TAG, 1);
+
+  CTG_ERR_JRET(ctgGetTableCfgFromVnode(pCtg, pConn, pCtx->pName, pCtx->pVgInfo, NULL, pTask));
+
+  return TSDB_CODE_SUCCESS;
+
+_return:
+
+  if (CTG_TASK_LAUNCHED == pTask->status) {
+    ctgHandleTaskEnd(pTask, code);
+  }
+
+  CTG_RET(code);
+}
+
+
 int32_t ctgLaunchGetQnodeTask(SCtgTask* pTask) {
   SCatalog*         pCtg = pTask->pJob->pCtg;
   SRequestConnInfo* pConn = &pTask->pJob->conn;
@@ -2093,6 +2319,8 @@ int32_t ctgLaunchGetUserTask(SCtgTask* pTask) {
   if (inCache) {
     pTask->res = rsp.pRawRes;
 
+    ctgTaskDebug("Final res got, pass:%d, pCond:%p", rsp.pRawRes->pass, rsp.pRawRes->pCond);
+
     CTG_ERR_RET(ctgHandleTaskEnd(pTask, 0));
     return TSDB_CODE_SUCCESS;
   }
@@ -2100,7 +2328,10 @@ int32_t ctgLaunchGetUserTask(SCtgTask* pTask) {
   taosMemoryFreeClear(rsp.pRawRes);
 
   if (rsp.metaNotExists) {
-    CTG_ERR_RET(ctgLaunchSubTask(pTask, CTG_TASK_GET_TB_META, ctgGetTbCfgCb, &pCtx->user.tbName));
+    SCtgTbMetaParam param;
+    param.pName = &pCtx->user.tbName;
+    param.flag = CTG_FLAG_SYNC_OP;
+    CTG_ERR_RET(ctgLaunchSubTask(pTask, CTG_TASK_GET_TB_META, ctgGetUserCb, ¶m));
   } else {
     CTG_ERR_RET(ctgGetUserDbAuthFromMnode(pCtg, pConn, pCtx->user.user, NULL, pTask));
   }
@@ -2154,6 +2385,27 @@ _return:
   CTG_RET(ctgHandleTaskEnd(pTask, pTask->subRes.code));
 }
 
+int32_t ctgGetTbTagCb(SCtgTask* pTask) {
+  int32_t code = 0;
+
+  CTG_ERR_JRET(pTask->subRes.code);
+
+  SCtgTbTagCtx* pCtx = (SCtgTbTagCtx*)pTask->taskCtx;
+  SDBVgInfo* pDb = (SDBVgInfo*)pTask->subRes.res;
+
+  if (NULL == pCtx->pVgInfo) {
+    pCtx->pVgInfo = taosMemoryCalloc(1, sizeof(SVgroupInfo));
+    CTG_ERR_JRET(ctgGetVgInfoFromHashValue(pTask->pJob->pCtg, pDb, pCtx->pName, pCtx->pVgInfo));
+  }
+  
+  CTG_RET(ctgLaunchGetTbTagTask(pTask));
+
+_return:
+
+  CTG_RET(ctgHandleTaskEnd(pTask, pTask->subRes.code));
+}
+
+
 
 int32_t ctgGetUserCb(SCtgTask* pTask) {
   int32_t code = 0;
@@ -2178,8 +2430,12 @@ int32_t ctgCompDbVgTasks(SCtgTask* pTask, void* param, bool* equal) {
 
 int32_t ctgCompTbMetaTasks(SCtgTask* pTask, void* param, bool* equal) {
   SCtgTbMetaCtx* ctx = pTask->taskCtx;
+  SCtgTbMetaParam* pParam = (SCtgTbMetaParam*)param;
 
-  *equal = tNameTbNameEqual(ctx->pName, (SName*)param);
+  *equal = tNameTbNameEqual(ctx->pName, (SName*)pParam->pName);
+  if (*equal) {
+    ctx->flag |= pParam->flag;
+  }
 
   return TSDB_CODE_SUCCESS;
 }
@@ -2213,6 +2469,7 @@ SCtgAsyncFps gCtgAsyncFps[] = {
     {ctgInitGetSvrVerTask, ctgLaunchGetSvrVerTask, ctgHandleGetSvrVerRsp, ctgDumpSvrVer, NULL, NULL},
     {ctgInitGetTbMetasTask, ctgLaunchGetTbMetasTask, ctgHandleGetTbMetasRsp, ctgDumpTbMetasRes, NULL, NULL},
     {ctgInitGetTbHashsTask, ctgLaunchGetTbHashsTask, ctgHandleGetTbHashsRsp, ctgDumpTbHashsRes, NULL, NULL},
+    {ctgInitGetTbTagTask, ctgLaunchGetTbTagTask, ctgHandleGetTbTagRsp, ctgDumpTbTagRes, NULL, NULL},
 };
 
 int32_t ctgMakeAsyncRes(SCtgJob* pJob) {
@@ -2300,6 +2557,9 @@ int32_t ctgLaunchSubTask(SCtgTask* pTask, CTG_TASK_TYPE type, ctgSubTaskCbFp fp,
   }
 
   SCtgTask* pSub = taosArrayGet(pJob->pTasks, subTaskId);
+  if (newTask) {
+    pSub->subTask = true;
+  }
 
   CTG_ERR_RET(ctgSetSubTaskCb(pSub, pTask));
 
diff --git a/source/libs/catalog/src/ctgCache.c b/source/libs/catalog/src/ctgCache.c
index 3000f152eb..debd5f567c 100644
--- a/source/libs/catalog/src/ctgCache.c
+++ b/source/libs/catalog/src/ctgCache.c
@@ -746,7 +746,32 @@ _return:
   return code;
 }
 
+int32_t ctgGetCachedStbNameFromSuid(SCatalog* pCtg, char* dbFName, uint64_t suid, char **stbName) {
+  *stbName = NULL;
+
+  SCtgDBCache *dbCache = NULL;
+  ctgAcquireDBCache(pCtg, dbFName, &dbCache);
+  if (NULL == dbCache) {
+    ctgDebug("db %s not in cache", dbFName);
+    return TSDB_CODE_SUCCESS;
+  }  
+  
+  char *stb = taosHashAcquire(dbCache->stbCache, &suid, sizeof(suid));
+  if (NULL == stb) {
+    ctgDebug("stb 0x%" PRIx64 " not in cache, dbFName:%s", suid, dbFName);
+    return TSDB_CODE_SUCCESS;
+  }
+
+  *stbName = taosStrdup(stb);
+
+  taosHashRelease(dbCache->stbCache, stb);
+
+  return TSDB_CODE_SUCCESS;
+}
+
+
 int32_t ctgChkAuthFromCache(SCatalog *pCtg, SUserAuthInfo *pReq, bool *inCache, SCtgAuthRsp *pRes) {
+  int32_t code = 0;
   if (IS_SYS_DBNAME(pReq->tbName.dbname)) {
     *inCache = true;
     pRes->pRawRes->pass = true;
@@ -771,7 +796,7 @@ int32_t ctgChkAuthFromCache(SCatalog *pCtg, SUserAuthInfo *pReq, bool *inCache,
 
   CTG_LOCK(CTG_READ, &pUser->lock);
   memcpy(&req.authInfo, &pUser->userAuth, sizeof(pUser->userAuth));
-  int32_t code = ctgChkSetAuthRes(pCtg, &req, pRes);
+  code = ctgChkSetAuthRes(pCtg, &req, pRes);
   CTG_UNLOCK(CTG_READ, &pUser->lock);
   CTG_ERR_JRET(code);
 
@@ -785,8 +810,9 @@ _return:
 
   *inCache = false;
   CTG_CACHE_NHIT_INC(CTG_CI_USER, 1);
+  ctgDebug("Get user from cache failed, user:%s, metaNotExists:%d, code:%d", pReq->user, pRes->metaNotExists, code);
 
-  return TSDB_CODE_SUCCESS;
+  return code;
 }
 
 void ctgDequeue(SCtgCacheOperation **op) {
@@ -1138,7 +1164,7 @@ int32_t ctgUpdateUserEnqueue(SCatalog *pCtg, SGetUserAuthRsp *pAuth, bool syncOp
   if (NULL == msg) {
     ctgError("malloc %d failed", (int32_t)sizeof(SCtgUpdateUserMsg));
     taosMemoryFree(op);
-    CTG_ERR_RET(TSDB_CODE_OUT_OF_MEMORY);
+    CTG_ERR_JRET(TSDB_CODE_OUT_OF_MEMORY);
   }
 
   msg->pCtg = pCtg;
diff --git a/source/libs/catalog/src/ctgUtil.c b/source/libs/catalog/src/ctgUtil.c
index 3978d7925b..bf858c7b44 100644
--- a/source/libs/catalog/src/ctgUtil.c
+++ b/source/libs/catalog/src/ctgUtil.c
@@ -170,6 +170,9 @@ void ctgFreeSMetaData(SMetaData* pData) {
   taosArrayDestroy(pData->pTableCfg);
   pData->pTableCfg = NULL;
 
+  taosArrayDestroy(pData->pTableTag);
+  pData->pTableTag = NULL;
+
   taosMemoryFreeClear(pData->pSvrVer);
 }
 
@@ -486,6 +489,18 @@ void ctgFreeBatchHash(void* hash) {
   taosMemoryFreeClear(pRes->pRes);
 }
 
+void ctgFreeJsonTagVal(void* val) {
+  if (NULL == val) {
+    return;
+  }
+
+  STagVal* pVal = (STagVal*)val;
+
+  if (TSDB_DATA_TYPE_JSON == pVal->type) {
+    taosMemoryFree(pVal->pData);
+  }
+}
+
 void ctgFreeTaskRes(CTG_TASK_TYPE type, void** pRes) {
   switch (type) {
     case CTG_TASK_GET_QNODE:
@@ -516,16 +531,32 @@ void ctgFreeTaskRes(CTG_TASK_TYPE type, void** pRes) {
       }
       break;
     }
+    case CTG_TASK_GET_USER: {
+      if (*pRes) {
+        SUserAuthRes* pAuth = (SUserAuthRes*)*pRes;
+        nodesDestroyNode(pAuth->pCond);
+        taosMemoryFreeClear(*pRes);
+      }
+      break;
+    }
     case CTG_TASK_GET_TB_HASH:
     case CTG_TASK_GET_DB_INFO:
     case CTG_TASK_GET_INDEX_INFO:
     case CTG_TASK_GET_UDF:
-    case CTG_TASK_GET_USER:
     case CTG_TASK_GET_SVR_VER:
     case CTG_TASK_GET_TB_META: {
       taosMemoryFreeClear(*pRes);
       break;
     }
+    case CTG_TASK_GET_TB_TAG: {
+      if (1 == taosArrayGetSize(*pRes)) {
+        taosArrayDestroyEx(*pRes, ctgFreeJsonTagVal);
+      } else {
+        taosArrayDestroy(*pRes);
+      }
+      *pRes = NULL;
+      break;
+    }
     case CTG_TASK_GET_TB_META_BATCH: {
       SArray* pArray = (SArray*)*pRes;
       int32_t num = taosArrayGetSize(pArray);
@@ -679,6 +710,13 @@ void ctgFreeTaskCtx(SCtgTask* pTask) {
       taosMemoryFreeClear(pTask->taskCtx);
       break;
     }
+    case CTG_TASK_GET_TB_TAG: {
+      SCtgTbTagCtx* taskCtx = (SCtgTbTagCtx*)pTask->taskCtx;
+      taosMemoryFreeClear(taskCtx->pName);
+      taosMemoryFreeClear(taskCtx->pVgInfo);
+      taosMemoryFreeClear(taskCtx);
+      break;
+    }
     case CTG_TASK_GET_DB_VGROUP:
     case CTG_TASK_GET_DB_CFG:
     case CTG_TASK_GET_DB_INFO:
@@ -1340,57 +1378,75 @@ int32_t ctgChkSetTbAuthRes(SCatalog* pCtg, SCtgAuthReq* req, SCtgAuthRsp* res) {
   STableMeta*      pMeta = NULL;
   SGetUserAuthRsp* pInfo = &req->authInfo;
   SHashObj*        pTbs = (AUTH_TYPE_READ == req->singleType) ? pInfo->readTbs : pInfo->writeTbs;
+  char*            stbName = NULL;
 
-  char tbFullName[TSDB_TABLE_FNAME_LEN];
-  tNameExtractFullName(&req->pRawReq->tbName, tbFullName);
-  char* pCond = taosHashGet(pTbs, tbFullName, strlen(tbFullName));
-  if (pCond) {
-    if (strlen(pCond) > 1) {
-      CTG_ERR_RET(nodesStringToNode(pCond, &res->pRawRes->pCond));
+  char tbFName[TSDB_TABLE_FNAME_LEN];
+  char dbFName[TSDB_DB_FNAME_LEN];
+  tNameExtractFullName(&req->pRawReq->tbName, tbFName);
+  tNameGetFullDbName(&req->pRawReq->tbName, dbFName);
+
+  while (true) {
+    taosMemoryFreeClear(pMeta);
+
+    char* pCond = taosHashGet(pTbs, tbFName, strlen(tbFName));
+    if (pCond) {
+      if (strlen(pCond) > 1) {
+        CTG_ERR_JRET(nodesStringToNode(pCond, &res->pRawRes->pCond));
+      }
+
+      res->pRawRes->pass = true;
+      goto _return;
     }
 
-    res->pRawRes->pass = true;
-    return TSDB_CODE_SUCCESS;
+    if (stbName) {
+      res->pRawRes->pass = false;
+      goto _return;
+    }
+
+    CTG_ERR_JRET(catalogGetCachedTableMeta(pCtg, &req->pRawReq->tbName, &pMeta));
+    if (NULL == pMeta) {
+      if (req->onlyCache) {
+        res->metaNotExists = true;
+        ctgDebug("db %s tb %s meta not in cache for auth", req->pRawReq->tbName.dbname, req->pRawReq->tbName.tname);
+        goto _return;
+      }
+
+      SCtgTbMetaCtx ctx = {0};
+      ctx.pName = (SName*)&req->pRawReq->tbName;
+      ctx.flag = CTG_FLAG_UNKNOWN_STB | CTG_FLAG_SYNC_OP;
+
+      CTG_ERR_JRET(ctgGetTbMeta(pCtg, req->pConn, &ctx, &pMeta));
+    }
+
+    if (TSDB_SUPER_TABLE == pMeta->tableType || TSDB_NORMAL_TABLE == pMeta->tableType) {
+      res->pRawRes->pass = false;
+      goto _return;
+    }
+
+    if (TSDB_CHILD_TABLE == pMeta->tableType) {
+      CTG_ERR_JRET(ctgGetCachedStbNameFromSuid(pCtg, dbFName, pMeta->suid, &stbName));
+      if (NULL == stbName) {
+        if (req->onlyCache) {
+          res->metaNotExists = true;
+          ctgDebug("suid %" PRIu64 " name not in cache for auth", pMeta->suid);
+          goto _return;
+        }
+
+        continue;
+      }
+
+      sprintf(tbFName, "%s.%s", dbFName, stbName);
+      continue;
+    }
+
+    ctgError("Invalid table type %d for %s", pMeta->tableType, tbFName);
+    CTG_ERR_JRET(TSDB_CODE_INVALID_PARA);
   }
 
-  res->pRawRes->pass = false;
-
-  // CTG_ERR_RET(catalogGetCachedTableMeta(pCtg, &req->pRawReq->tbName, &pMeta));
-  // if (NULL == pMeta) {
-  //   if (req->onlyCache) {
-  //     res->metaNotExists = true;
-  //     ctgDebug("db %s tb %s meta not in cache for auth", req->pRawReq->tbName.dbname, req->pRawReq->tbName.tname);
-  //     return TSDB_CODE_SUCCESS;
-  //   }
-
-  //   CTG_ERR_RET(catalogGetTableMeta(pCtg, req->pConn, &req->pRawReq->tbName, &pMeta));
-  // }
-
-  // if (TSDB_SUPER_TABLE == pMeta->tableType || TSDB_NORMAL_TABLE == pMeta->tableType) {
-  //   res->pRawRes->pass = false;
-  //   goto _return;
-  // }
-
-  // if (TSDB_CHILD_TABLE == pMeta->tableType) {
-  //   res->pRawRes->pass = true;
-
-  //   /*
-  //       char stbName[TSDB_TABLE_NAME_LEN] = {0};
-  //       CTG_ERR_JRET(ctgGetCachedStbNameFromSuid(pCtg, pMeta->suid, stbName));
-  //       if (0 == stbName[0]) {
-  //         if (req->onlyCache) {
-  //           res->notExists = true;
-  //           return TSDB_CODE_SUCCESS;
-  //         }
-
-  //         CTG_ERR_RET(catalogRefreshTableMeta(pCtg, req->pConn, &req->pRawReq->tbName, 0));
-  //       }
-  //   */
-  // }
-
 _return:
 
   taosMemoryFree(pMeta);
+  taosMemoryFree(stbName);
 
   CTG_RET(code);
 }
@@ -1427,7 +1483,7 @@ int32_t ctgChkSetAuthRes(SCatalog* pCtg, SCtgAuthReq* req, SCtgAuthRsp* res) {
       if (pInfo->readTbs && taosHashGetSize(pInfo->readTbs) > 0) {
         req->singleType = AUTH_TYPE_READ;
         CTG_ERR_RET(ctgChkSetTbAuthRes(pCtg, req, res));
-        if (pRes->pass) {
+        if (pRes->pass || res->metaNotExists) {
           return TSDB_CODE_SUCCESS;
         }
       }
@@ -1443,7 +1499,7 @@ int32_t ctgChkSetAuthRes(SCatalog* pCtg, SCtgAuthReq* req, SCtgAuthRsp* res) {
       if (pInfo->writeTbs && taosHashGetSize(pInfo->writeTbs) > 0) {
         req->singleType = AUTH_TYPE_WRITE;
         CTG_ERR_RET(ctgChkSetTbAuthRes(pCtg, req, res));
-        if (pRes->pass) {
+        if (pRes->pass || res->metaNotExists) {
           return TSDB_CODE_SUCCESS;
         }
       }
diff --git a/source/libs/command/src/command.c b/source/libs/command/src/command.c
index 58c43829cf..6efdd8d8eb 100644
--- a/source/libs/command/src/command.c
+++ b/source/libs/command/src/command.c
@@ -278,7 +278,12 @@ static void setCreateDBResultIntoDataBlock(SSDataBlock* pBlock, char* dbName, ch
 
   char* retentions = buildRetension(pCfg->pRetensions);
   int32_t dbFNameLen = strlen(dbFName);
-  int32_t hashPrefix = (pCfg->hashPrefix > (dbFNameLen + 1)) ? (pCfg->hashPrefix - dbFNameLen - 1) : 0;
+  int32_t hashPrefix = 0;
+  if (pCfg->hashPrefix > 0) {
+    hashPrefix = pCfg->hashPrefix - dbFNameLen - 1;
+  } else if (pCfg->hashPrefix < 0) {
+    hashPrefix = pCfg->hashPrefix + dbFNameLen + 1;
+  }
 
   len += sprintf(
       buf2 + VARSTR_HEADER_SIZE,
diff --git a/source/libs/executor/inc/executil.h b/source/libs/executor/inc/executil.h
index a4a55e91fb..98e321c7b8 100644
--- a/source/libs/executor/inc/executil.h
+++ b/source/libs/executor/inc/executil.h
@@ -39,8 +39,6 @@
 
 #define GET_RES_WINDOW_KEY_LEN(_l)     ((_l) + sizeof(uint64_t))
 
-#define GET_TASKID(_t) (((SExecTaskInfo*)(_t))->id.str)
-
 typedef struct SGroupResInfo {
   int32_t index;
   SArray* pRows;  // SArray
diff --git a/source/libs/executor/inc/executorInt.h b/source/libs/executor/inc/executorInt.h
index d22a7460bb..5db79bba8b 100644
--- a/source/libs/executor/inc/executorInt.h
+++ b/source/libs/executor/inc/executorInt.h
@@ -12,14 +12,75 @@
  * You should have received a copy of the GNU Affero General Public License
  * along with this program. If not, see .
  */
-
-#ifndef _TD_EXECUTOR_INT_H
-#define _TD_EXECUTOR_INT_H
+#ifndef TDENGINE_EXECUTORINT_H
+#define TDENGINE_EXECUTORINT_H
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#include "os.h"
+#include "tcommon.h"
+#include "tlosertree.h"
+#include "tsort.h"
+#include "ttszip.h"
+#include "tvariant.h"
+
+#include "dataSinkMgt.h"
+#include "executil.h"
+#include "executor.h"
+#include "planner.h"
+#include "scalar.h"
+#include "taosdef.h"
+#include "tarray.h"
+#include "tfill.h"
+#include "thash.h"
+#include "tlockfree.h"
+#include "tmsg.h"
+#include "tpagedbuf.h"
+#include "tstream.h"
+#include "tstreamUpdate.h"
+
+#include "vnode.h"
+
+typedef int32_t (*__block_search_fn_t)(char* data, int32_t num, int64_t key, int32_t order);
+
+#define IS_VALID_SESSION_WIN(winInfo)        ((winInfo).sessionWin.win.skey > 0)
+#define SET_SESSION_WIN_INVALID(winInfo)     ((winInfo).sessionWin.win.skey = INT64_MIN)
+#define IS_INVALID_SESSION_WIN_KEY(winKey)   ((winKey).win.skey <= 0)
+#define SET_SESSION_WIN_KEY_INVALID(pWinKey) ((pWinKey)->win.skey = INT64_MIN)
+
+/**
+ * If the number of generated results is greater than this value,
+ * query query will be halt and return results to client immediate.
+ */
+typedef struct SResultInfo {  // TODO refactor
+  int64_t totalRows;          // total generated result size in rows
+  int64_t totalBytes;         // total results in bytes.
+  int32_t capacity;           // capacity of current result output buffer
+  int32_t threshold;          // result size threshold in rows.
+} SResultInfo;
+
+typedef struct STableQueryInfo {
+  TSKEY              lastKey;  // last check ts, todo remove it later
+  SResultRowPosition pos;      // current active time window
+} STableQueryInfo;
+
+typedef struct SLimit {
+  int64_t limit;
+  int64_t offset;
+} SLimit;
+
+typedef struct STableScanAnalyzeInfo SFileBlockLoadRecorder;
+
+enum {
+  STREAM_RECOVER_STEP__NONE = 0,
+  STREAM_RECOVER_STEP__PREPARE1,
+  STREAM_RECOVER_STEP__PREPARE2,
+  STREAM_RECOVER_STEP__SCAN1,
+  STREAM_RECOVER_STEP__SCAN2,
+};
+
 extern int32_t exchangeObjRefPool;
 
 typedef struct {
@@ -29,9 +90,585 @@ typedef struct {
   int32_t bytes;
 } SGroupKeys, SStateKeys;
 
+typedef struct {
+  char*           tablename;
+  char*           dbname;
+  int32_t         tversion;
+  SSchemaWrapper* sw;
+  SSchemaWrapper* qsw;
+} SSchemaInfo;
+
+typedef struct SExchangeOpStopInfo {
+  int32_t operatorType;
+  int64_t refId;
+} SExchangeOpStopInfo;
+
+typedef struct SExprSupp {
+  SExprInfo*      pExprInfo;
+  int32_t         numOfExprs;  // the number of scalar expression in group operator
+  SqlFunctionCtx* pCtx;
+  int32_t*        rowEntryInfoOffset;  // offset value for each row result cell info
+  SFilterInfo*    pFilterInfo;
+} SExprSupp;
+
+typedef enum {
+  EX_SOURCE_DATA_NOT_READY = 0x1,
+  EX_SOURCE_DATA_READY = 0x2,
+  EX_SOURCE_DATA_EXHAUSTED = 0x3,
+} EX_SOURCE_STATUS;
+
+#define COL_MATCH_FROM_COL_ID  0x1
+#define COL_MATCH_FROM_SLOT_ID 0x2
+
+typedef struct SLoadRemoteDataInfo {
+  uint64_t totalSize;     // total load bytes from remote
+  uint64_t totalRows;     // total number of rows
+  uint64_t totalElapsed;  // total elapsed time
+} SLoadRemoteDataInfo;
+
+typedef struct SLimitInfo {
+  SLimit   limit;
+  SLimit   slimit;
+  uint64_t currentGroupId;
+  int64_t  remainGroupOffset;
+  int64_t  numOfOutputGroups;
+  int64_t  remainOffset;
+  int64_t  numOfOutputRows;
+} SLimitInfo;
+
+typedef struct SExchangeInfo {
+  SArray* pSources;
+  SArray* pSourceDataInfo;
+  tsem_t  ready;
+  void*   pTransporter;
+
+  // SArray, result block list, used to keep the multi-block that
+  // passed by downstream operator
+  SArray*      pResultBlockList;
+  SArray*      pRecycledBlocks;  // build a pool for small data block to avoid to repeatly create and then destroy.
+  SSDataBlock* pDummyBlock;      // dummy block, not keep data
+  bool         seqLoadData;      // sequential load data or not, false by default
+  int32_t      current;
+  SLoadRemoteDataInfo loadInfo;
+  uint64_t            self;
+  SLimitInfo          limitInfo;
+  int64_t             openedTs;  // start exec time stamp, todo: move to SLoadRemoteDataInfo
+} SExchangeInfo;
+
+typedef struct SScanInfo {
+  int32_t numOfAsc;
+  int32_t numOfDesc;
+} SScanInfo;
+
+typedef struct SSampleExecInfo {
+  double   sampleRatio;  // data block sample ratio, 1 by default
+  uint32_t seed;         // random seed value
+} SSampleExecInfo;
+
+enum {
+  TABLE_SCAN__TABLE_ORDER = 1,
+  TABLE_SCAN__BLOCK_ORDER = 2,
+};
+
+typedef struct SAggSupporter {
+  SSHashObj*     pResultRowHashTable;  // quick locate the window object for each result
+  char*          keyBuf;               // window key buffer
+  SDiskbasedBuf* pResultBuf;           // query result buffer based on blocked-wised disk file
+  int32_t        resultRowSize;  // the result buffer size for each result row, with the meta data size for each row
+  int32_t        currentPageId;  // current write page id
+} SAggSupporter;
+
+typedef struct {
+  // if the upstream is an interval operator, the interval info is also kept here to get the time window to check if
+  // current data block needs to be loaded.
+  SInterval      interval;
+  SAggSupporter* pAggSup;
+  SExprSupp*     pExprSup;  // expr supporter of aggregate operator
+} SAggOptrPushDownInfo;
+
+typedef struct STableMetaCacheInfo {
+  SLRUCache* pTableMetaEntryCache;  // 100 by default
+  uint64_t   metaFetch;
+  uint64_t   cacheHit;
+} STableMetaCacheInfo;
+
+typedef struct STableScanBase {
+  STsdbReader*           dataReader;
+  SFileBlockLoadRecorder readRecorder;
+  SQueryTableDataCond    cond;
+  SAggOptrPushDownInfo   pdInfo;
+  SColMatchInfo          matchInfo;
+  SReadHandle            readHandle;
+  SExprSupp              pseudoSup;
+  STableMetaCacheInfo    metaCache;
+  int32_t                scanFlag;  // table scan flag to denote if it is a repeat/reverse/main scan
+  int32_t                dataBlockLoadFlag;
+  SLimitInfo             limitInfo;
+  // there are more than one table list exists in one task, if only one vnode exists.
+  STableListInfo* pTableListInfo;
+} STableScanBase;
+
+typedef struct STableScanInfo {
+  STableScanBase  base;
+  SScanInfo       scanInfo;
+  int32_t         scanTimes;
+  SSDataBlock*    pResBlock;
+  SHashObj*       pIgnoreTables;
+  SSampleExecInfo sample;  // sample execution info
+  int32_t         currentGroupId;
+  int32_t         currentTable;
+  int8_t          scanMode;
+  int8_t          assignBlockUid;
+  bool            hasGroupByTag;
+  bool            countOnly;
+} STableScanInfo;
+
+typedef struct STableMergeScanInfo {
+  int32_t         tableStartIndex;
+  int32_t         tableEndIndex;
+  bool            hasGroupId;
+  uint64_t        groupId;
+  SArray*         queryConds;  // array of queryTableDataCond
+  STableScanBase  base;
+  int32_t         bufPageSize;
+  uint32_t        sortBufSize;  // max buffer size for in-memory sort
+  SArray*         pSortInfo;
+  SSortHandle*    pSortHandle;
+  SSDataBlock*    pSortInputBlock;
+  int64_t         startTs;  // sort start time
+  SArray*         sortSourceParams;
+  SLimitInfo      limitInfo;
+  int64_t         numOfRows;
+  SScanInfo       scanInfo;
+  int32_t         scanTimes;
+  SSDataBlock*    pResBlock;
+  SSampleExecInfo sample;  // sample execution info
+  SSortExecInfo   sortExecInfo;
+} STableMergeScanInfo;
+
+typedef struct STagScanInfo {
+  SColumnInfo*    pCols;
+  SSDataBlock*    pRes;
+  SColMatchInfo   matchInfo;
+  int32_t         curPos;
+  SReadHandle     readHandle;
+  STableListInfo* pTableListInfo;
+} STagScanInfo;
+
+typedef enum EStreamScanMode {
+  STREAM_SCAN_FROM_READERHANDLE = 1,
+  STREAM_SCAN_FROM_RES,
+  STREAM_SCAN_FROM_UPDATERES,
+  STREAM_SCAN_FROM_DELETE_DATA,
+  STREAM_SCAN_FROM_DATAREADER_RETRIEVE,
+  STREAM_SCAN_FROM_DATAREADER_RANGE,
+} EStreamScanMode;
+
+enum {
+  PROJECT_RETRIEVE_CONTINUE = 0x1,
+  PROJECT_RETRIEVE_DONE = 0x2,
+};
+
+typedef struct SStreamAggSupporter {
+  int32_t         resultRowSize;  // the result buffer size for each result row, with the meta data size for each row
+  SSDataBlock*    pScanBlock;
+  SStreamState*   pState;
+  int64_t         gap;        // stream session window gap
+  SqlFunctionCtx* pDummyCtx;  // for combine
+  SSHashObj*      pResultRows;
+  int32_t         stateKeySize;
+  int16_t         stateKeyType;
+  SDiskbasedBuf*  pResultBuf;
+} SStreamAggSupporter;
+
+typedef struct SWindowSupporter {
+  SStreamAggSupporter* pStreamAggSup;
+  int64_t              gap;
+  uint16_t             parentType;
+  SAggSupporter*       pIntervalAggSup;
+} SWindowSupporter;
+
+typedef struct SPartitionBySupporter {
+  SArray* pGroupCols;     // group by columns, SArray
+  SArray* pGroupColVals;  // current group column values, SArray
+  char*   keyBuf;         // group by keys for hash
+  bool    needCalc;       // partition by column
+} SPartitionBySupporter;
+
+typedef struct SPartitionDataInfo {
+  uint64_t groupId;
+  char*    tbname;
+  SArray*  tags;
+  SArray*  rowIds;
+} SPartitionDataInfo;
+
+typedef struct STimeWindowAggSupp {
+  int8_t          calTrigger;
+  int8_t          calTriggerSaved;
+  int64_t         deleteMark;
+  int64_t         deleteMarkSaved;
+  int64_t         waterMark;
+  TSKEY           maxTs;
+  TSKEY           minTs;
+  SColumnInfoData timeWindowData;  // query time window info for scalar function execution.
+} STimeWindowAggSupp;
+
+typedef struct SStreamScanInfo {
+  SExprInfo*    pPseudoExpr;
+  int32_t       numOfPseudoExpr;
+  SExprSupp     tbnameCalSup;
+  SExprSupp     tagCalSup;
+  int32_t       primaryTsIndex;  // primary time stamp slot id
+  SReadHandle   readHandle;
+  SInterval     interval;  // if the upstream is an interval operator, the interval info is also kept here.
+  SColMatchInfo matchInfo;
+
+  SArray*      pBlockLists;  // multiple SSDatablock.
+  SSDataBlock* pRes;         // result SSDataBlock
+  SSDataBlock* pUpdateRes;   // update SSDataBlock
+  int32_t      updateResIndex;
+  int32_t      blockType;        // current block type
+  int32_t      validBlockIndex;  // Is current data has returned?
+  uint64_t     numOfExec;        // execution times
+  STqReader*   tqReader;
+
+  uint64_t     groupId;
+  SUpdateInfo* pUpdateInfo;
+
+  EStreamScanMode       scanMode;
+  struct SOperatorInfo*        pStreamScanOp;
+  struct SOperatorInfo*        pTableScanOp;
+  SArray*               childIds;
+  SWindowSupporter      windowSup;
+  SPartitionBySupporter partitionSup;
+  SExprSupp*            pPartScalarSup;
+  bool                  assignBlockUid;  // assign block uid to groupId, temporarily used for generating rollup SMA.
+  int32_t               scanWinIndex;    // for state operator
+  int32_t               pullDataResIndex;
+  SSDataBlock*          pPullDataRes;    // pull data SSDataBlock
+  SSDataBlock*          pDeleteDataRes;  // delete data SSDataBlock
+  int32_t               deleteDataIndex;
+  STimeWindow           updateWin;
+  STimeWindowAggSupp    twAggSup;
+  SSDataBlock*          pUpdateDataRes;
+  // status for tmq
+  SNodeList* pGroupTags;
+  SNode*     pTagCond;
+  SNode*     pTagIndexCond;
+
+  // recover
+  int32_t      blockRecoverContiCnt;
+  int32_t      blockRecoverTotCnt;
+  SSDataBlock* pRecoverRes;
+
+  SSDataBlock* pCreateTbRes;
+  int8_t       igCheckUpdate;
+  int8_t       igExpired;
+} SStreamScanInfo;
+
+typedef struct {
+  SVnode*         vnode;
+  SSDataBlock     pRes;  // result SSDataBlock
+  STsdbReader*    dataReader;
+  SSnapContext*   sContext;
+  STableListInfo* pTableListInfo;
+} SStreamRawScanInfo;
+
+typedef struct STableCountScanSupp {
+  int16_t dbNameSlotId;
+  int16_t stbNameSlotId;
+  int16_t tbCountSlotId;
+  bool    groupByDbName;
+  bool    groupByStbName;
+  char    dbNameFilter[TSDB_DB_NAME_LEN];
+  char    stbNameFilter[TSDB_TABLE_NAME_LEN];
+} STableCountScanSupp;
+
+typedef struct SOptrBasicInfo {
+  SResultRowInfo resultRowInfo;
+  SSDataBlock*   pRes;
+  bool           mergeResultBlock;
+} SOptrBasicInfo;
+
+typedef struct SIntervalAggOperatorInfo {
+  SOptrBasicInfo     binfo;              // basic info
+  SAggSupporter      aggSup;             // aggregate supporter
+  SExprSupp          scalarSupp;         // supporter for perform scalar function
+  SGroupResInfo      groupResInfo;       // multiple results build supporter
+  SInterval          interval;           // interval info
+  int32_t            primaryTsIndex;     // primary time stamp slot id from result of downstream operator.
+  STimeWindow        win;                // query time range
+  bool               timeWindowInterpo;  // interpolation needed or not
+  SArray*            pInterpCols;        // interpolation columns
+  int32_t            resultTsOrder;      // result timestamp order
+  int32_t            inputOrder;         // input data ts order
+  EOPTR_EXEC_MODEL   execModel;          // operator execution model [batch model|stream model]
+  STimeWindowAggSupp twAggSup;
+  SArray*            pPrevValues;  //  SArray used to keep the previous not null value for interpolation.
+} SIntervalAggOperatorInfo;
+
+typedef struct SMergeAlignedIntervalAggOperatorInfo {
+  SIntervalAggOperatorInfo* intervalAggOperatorInfo;
+
+  uint64_t     groupId;  // current groupId
+  int64_t      curTs;    // current ts
+  SSDataBlock* prefetchedBlock;
+  SResultRow*  pResultRow;
+} SMergeAlignedIntervalAggOperatorInfo;
+
+typedef struct SStreamIntervalOperatorInfo {
+  SOptrBasicInfo     binfo;           // basic info
+  SAggSupporter      aggSup;          // aggregate supporter
+  SExprSupp          scalarSupp;      // supporter for perform scalar function
+  SGroupResInfo      groupResInfo;    // multiple results build supporter
+  SInterval          interval;        // interval info
+  int32_t            primaryTsIndex;  // primary time stamp slot id from result of downstream operator.
+  STimeWindowAggSupp twAggSup;
+  bool               invertible;
+  bool               ignoreExpiredData;
+  bool               ignoreExpiredDataSaved;
+  SArray*            pDelWins;  // SWinRes
+  int32_t            delIndex;
+  SSDataBlock*       pDelRes;
+  SPhysiNode*        pPhyNode;  // create new child
+  SHashObj*          pPullDataMap;
+  SArray*            pPullWins;  // SPullWindowInfo
+  int32_t            pullIndex;
+  SSDataBlock*       pPullDataRes;
+  bool               isFinal;
+  SArray*            pChildren;
+  SStreamState*      pState;
+  SWinKey            delKey;
+  uint64_t           numOfDatapack;
+  SArray*            pUpdated;
+  SSHashObj*         pUpdatedMap;
+  int64_t            dataVersion;
+} SStreamIntervalOperatorInfo;
+
+typedef struct SDataGroupInfo {
+  uint64_t groupId;
+  int64_t  numOfRows;
+  SArray*  pPageList;
+} SDataGroupInfo;
+
+typedef struct SWindowRowsSup {
+  STimeWindow win;
+  TSKEY       prevTs;
+  int32_t     startRowIndex;
+  int32_t     numOfRows;
+  uint64_t    groupId;
+} SWindowRowsSup;
+
+typedef struct SResultWindowInfo {
+  void*       pOutputBuf;
+  SSessionKey sessionWin;
+  bool        isOutput;
+} SResultWindowInfo;
+
+typedef struct SStreamSessionAggOperatorInfo {
+  SOptrBasicInfo      binfo;
+  SStreamAggSupporter streamAggSup;
+  SExprSupp           scalarSupp;  // supporter for perform scalar function
+  SGroupResInfo       groupResInfo;
+  int32_t             primaryTsIndex;  // primary timestamp slot id
+  int32_t             endTsIndex;      // window end timestamp slot id
+  int32_t             order;           // current SSDataBlock scan order
+  STimeWindowAggSupp  twAggSup;
+  SSDataBlock*        pWinBlock;   // window result
+  SSDataBlock*        pDelRes;     // delete result
+  SSDataBlock*        pUpdateRes;  // update window
+  bool                returnUpdate;
+  SSHashObj*          pStDeleted;
+  void*               pDelIterator;
+  SArray*             pChildren;  // cache for children's result; final stream operator
+  SPhysiNode*         pPhyNode;   // create new child
+  bool                isFinal;
+  bool                ignoreExpiredData;
+  bool                ignoreExpiredDataSaved;
+  SArray*             pUpdated;
+  SSHashObj*          pStUpdated;
+  int64_t             dataVersion;
+} SStreamSessionAggOperatorInfo;
+
+typedef struct SStreamStateAggOperatorInfo {
+  SOptrBasicInfo      binfo;
+  SStreamAggSupporter streamAggSup;
+  SExprSupp           scalarSupp;  // supporter for perform scalar function
+  SGroupResInfo       groupResInfo;
+  int32_t             primaryTsIndex;  // primary timestamp slot id
+  STimeWindowAggSupp  twAggSup;
+  SColumn             stateCol;
+  SSDataBlock*        pDelRes;
+  SSHashObj*          pSeDeleted;
+  void*               pDelIterator;
+  SArray*             pChildren;  // cache for children's result;
+  bool                ignoreExpiredData;
+  bool                ignoreExpiredDataSaved;
+  SArray*             pUpdated;
+  SSHashObj*          pSeUpdated;
+  int64_t             dataVersion;
+} SStreamStateAggOperatorInfo;
+
+typedef struct SStreamPartitionOperatorInfo {
+  SOptrBasicInfo        binfo;
+  SPartitionBySupporter partitionSup;
+  SExprSupp             scalarSup;
+  SExprSupp             tbnameCalSup;
+  SExprSupp             tagCalSup;
+  SHashObj*             pPartitions;
+  void*                 parIte;
+  void*                 pTbNameIte;
+  SSDataBlock*          pInputDataBlock;
+  int32_t               tsColIndex;
+  SSDataBlock*          pDelRes;
+  SSDataBlock*          pCreateTbRes;
+} SStreamPartitionOperatorInfo;
+
+typedef struct SStreamFillSupporter {
+  int32_t        type;  // fill type
+  SInterval      interval;
+  SResultRowData prev;
+  SResultRowData cur;
+  SResultRowData next;
+  SResultRowData nextNext;
+  SFillColInfo*  pAllColInfo;  // fill exprs and not fill exprs
+  SExprSupp      notFillExprSup;
+  int32_t        numOfAllCols;  // number of all exprs, including the tags columns
+  int32_t        numOfFillCols;
+  int32_t        numOfNotFillCols;
+  int32_t        rowSize;
+  SSHashObj*     pResMap;
+  bool           hasDelete;
+} SStreamFillSupporter;
+
+typedef struct SStreamFillOperatorInfo {
+  SStreamFillSupporter* pFillSup;
+  SSDataBlock*          pRes;
+  SSDataBlock*          pSrcBlock;
+  int32_t               srcRowIndex;
+  SSDataBlock*          pSrcDelBlock;
+  int32_t               srcDelRowIndex;
+  SSDataBlock*          pDelRes;
+  SColMatchInfo         matchInfo;
+  int32_t               primaryTsCol;
+  int32_t               primarySrcSlotId;
+  SStreamFillInfo*      pFillInfo;
+} SStreamFillOperatorInfo;
+
+#define OPTR_IS_OPENED(_optr)  (((_optr)->status & OP_OPENED) == OP_OPENED)
+#define OPTR_SET_OPENED(_optr) ((_optr)->status |= OP_OPENED)
+
+SSchemaWrapper* extractQueriedColumnSchema(SScanPhysiNode* pScanNode);
+int32_t initQueriedTableSchemaInfo(SReadHandle* pHandle, SScanPhysiNode* pScanNode, const char* dbName, SExecTaskInfo* pTaskInfo);
+void    cleanupQueriedTableScanInfo(SSchemaInfo* pSchemaInfo);
+
+void initBasicInfo(SOptrBasicInfo* pInfo, SSDataBlock* pBlock);
+void cleanupBasicInfo(SOptrBasicInfo* pInfo);
+
+int32_t initExprSupp(SExprSupp* pSup, SExprInfo* pExprInfo, int32_t numOfExpr);
+void    cleanupExprSupp(SExprSupp* pSup);
+
+void destroyExprInfo(SExprInfo* pExpr, int32_t numOfExprs);
+
+int32_t initAggSup(SExprSupp* pSup, SAggSupporter* pAggSup, SExprInfo* pExprInfo, int32_t numOfCols, size_t keyBufSize,
+                   const char* pkey, void* pState);
+void    cleanupAggSup(SAggSupporter* pAggSup);
+
+void initResultSizeInfo(SResultInfo* pResultInfo, int32_t numOfRows);
+
+void doBuildStreamResBlock(struct SOperatorInfo* pOperator, SOptrBasicInfo* pbInfo, SGroupResInfo* pGroupResInfo,
+                           SDiskbasedBuf* pBuf);
+void doBuildResultDatablock(struct SOperatorInfo* pOperator, SOptrBasicInfo* pbInfo, SGroupResInfo* pGroupResInfo,
+                            SDiskbasedBuf* pBuf);
+
+bool hasLimitOffsetInfo(SLimitInfo* pLimitInfo);
+bool hasSlimitOffsetInfo(SLimitInfo* pLimitInfo);
+void initLimitInfo(const SNode* pLimit, const SNode* pSLimit, SLimitInfo* pLimitInfo);
+void resetLimitInfoForNextGroup(SLimitInfo* pLimitInfo);
+bool applyLimitOffset(SLimitInfo* pLimitInfo, SSDataBlock* pBlock, SExecTaskInfo* pTaskInfo);
+
+void applyAggFunctionOnPartialTuples(SExecTaskInfo* taskInfo, SqlFunctionCtx* pCtx, SColumnInfoData* pTimeWindowData,
+                                     int32_t offset, int32_t forwardStep, int32_t numOfTotal, int32_t numOfOutput);
+
+int32_t extractDataBlockFromFetchRsp(SSDataBlock* pRes, char* pData, SArray* pColList, char** pNextStart);
+void    updateLoadRemoteInfo(SLoadRemoteDataInfo* pInfo, int64_t numOfRows, int32_t dataLen, int64_t startTs,
+                             struct SOperatorInfo* pOperator);
+
+STimeWindow getFirstQualifiedTimeWindow(int64_t ts, STimeWindow* pWindow, SInterval* pInterval, int32_t order);
+int32_t     getBufferPgSize(int32_t rowSize, uint32_t* defaultPgsz, uint32_t* defaultBufsz);
+
+extern void doDestroyExchangeOperatorInfo(void* param);
+
+void    doFilter(SSDataBlock* pBlock, SFilterInfo* pFilterInfo, SColMatchInfo* pColMatchInfo);
+int32_t addTagPseudoColumnData(SReadHandle* pHandle, const SExprInfo* pExpr, int32_t numOfExpr, SSDataBlock* pBlock,
+                               int32_t rows, const char* idStr, STableMetaCacheInfo* pCache);
+
+void appendOneRowToDataBlock(SSDataBlock* pBlock, STupleHandle* pTupleHandle);
+void setTbNameColData(const SSDataBlock* pBlock, SColumnInfoData* pColInfoData, int32_t functionId, const char* name);
+
+void setResultRowInitCtx(SResultRow* pResult, SqlFunctionCtx* pCtx, int32_t numOfOutput, int32_t* rowEntryInfoOffset);
+void clearResultRowInitFlag(SqlFunctionCtx* pCtx, int32_t numOfOutput);
+
+SResultRow* doSetResultOutBufByKey(SDiskbasedBuf* pResultBuf, SResultRowInfo* pResultRowInfo, char* pData,
+                                   int16_t bytes, bool masterscan, uint64_t groupId, SExecTaskInfo* pTaskInfo,
+                                   bool isIntervalQuery, SAggSupporter* pSup, bool keepGroup);
+
+int32_t projectApplyFunctions(SExprInfo* pExpr, SSDataBlock* pResult, SSDataBlock* pSrcBlock, SqlFunctionCtx* pCtx,
+                              int32_t numOfOutput, SArray* pPseudoList);
+
+void setInputDataBlock(SExprSupp* pExprSupp, SSDataBlock* pBlock, int32_t order, int32_t scanFlag, bool createDummyCol);
+
+int32_t checkForQueryBuf(size_t numOfTables);
+
+int32_t createDataSinkParam(SDataSinkNode* pNode, void** pParam, SExecTaskInfo* pTask, SReadHandle* readHandle);
+
+STimeWindow getActiveTimeWindow(SDiskbasedBuf* pBuf, SResultRowInfo* pResultRowInfo, int64_t ts, SInterval* pInterval,
+                                int32_t order);
+int32_t getNumOfRowsInTimeWindow(SDataBlockInfo* pDataBlockInfo, TSKEY* pPrimaryColumn, int32_t startPos, TSKEY ekey,
+                                 __block_search_fn_t searchFn, STableQueryInfo* item, int32_t order);
+int32_t binarySearchForKey(char* pValue, int num, TSKEY key, int order);
+SResultRow* getNewResultRow(SDiskbasedBuf* pResultBuf, int32_t* currentPageId, int32_t interBufSize);
+void getCurSessionWindow(SStreamAggSupporter* pAggSup, TSKEY startTs, TSKEY endTs, uint64_t groupId, SSessionKey* pKey);
+bool isInTimeWindow(STimeWindow* pWin, TSKEY ts, int64_t gap);
+bool functionNeedToExecute(SqlFunctionCtx* pCtx);
+bool isOverdue(TSKEY ts, STimeWindowAggSupp* pSup);
+bool isCloseWindow(STimeWindow* pWin, STimeWindowAggSupp* pSup);
+bool isDeletedStreamWindow(STimeWindow* pWin, uint64_t groupId, SStreamState* pState, STimeWindowAggSupp* pTwSup);
+void appendOneRowToStreamSpecialBlock(SSDataBlock* pBlock, TSKEY* pStartTs, TSKEY* pEndTs, uint64_t* pUid,
+                                      uint64_t* pGp, void* pTbName);
+uint64_t calGroupIdByData(SPartitionBySupporter* pParSup, SExprSupp* pExprSup, SSDataBlock* pBlock, int32_t rowId);
+
+int32_t finalizeResultRows(SDiskbasedBuf* pBuf, SResultRowPosition* resultRowPosition, SExprSupp* pSup,
+                           SSDataBlock* pBlock, SExecTaskInfo* pTaskInfo);
+
+bool    groupbyTbname(SNodeList* pGroupList);
+int32_t buildDataBlockFromGroupRes(struct SOperatorInfo* pOperator, SStreamState* pState, SSDataBlock* pBlock, SExprSupp* pSup,
+                                   SGroupResInfo* pGroupResInfo);
+int32_t saveSessionDiscBuf(SStreamState* pState, SSessionKey* key, void* buf, int32_t size);
+int32_t buildSessionResultDataBlock(struct SOperatorInfo* pOperator, SStreamState* pState, SSDataBlock* pBlock,
+                                    SExprSupp* pSup, SGroupResInfo* pGroupResInfo);
+int32_t setOutputBuf(SStreamState* pState, STimeWindow* win, SResultRow** pResult, int64_t tableGroupId,
+                     SqlFunctionCtx* pCtx, int32_t numOfOutput, int32_t* rowEntryInfoOffset, SAggSupporter* pAggSup);
+int32_t releaseOutputBuf(SStreamState* pState, SWinKey* pKey, SResultRow* pResult);
+int32_t saveOutputBuf(SStreamState* pState, SWinKey* pKey, SResultRow* pResult, int32_t resSize);
+void    getNextIntervalWindow(SInterval* pInterval, STimeWindow* tw, int32_t order);
+int32_t getForwardStepsInBlock(int32_t numOfRows, __block_search_fn_t searchFn, TSKEY ekey, int32_t pos, int32_t order,
+                               int64_t* pData);
+void    appendCreateTableRow(SStreamState* pState, SExprSupp* pTableSup, SExprSupp* pTagSup, uint64_t groupId,
+                             SSDataBlock* pSrcBlock, int32_t rowId, SSDataBlock* pDestBlock);
+
+SSDataBlock* buildCreateTableBlock(SExprSupp* tbName, SExprSupp* tag);
+SExprInfo*   createExpr(SNodeList* pNodeList, int32_t* numOfExprs);
+
+void copyResultrowToDataBlock(SExprInfo* pExprInfo, int32_t numOfExprs, SResultRow* pRow, SqlFunctionCtx* pCtx,
+                              SSDataBlock* pBlock, const int32_t* rowEntryOffset, SExecTaskInfo* pTaskInfo);
+void doUpdateNumOfRows(SqlFunctionCtx* pCtx, SResultRow* pRow, int32_t numOfExprs, const int32_t* rowEntryOffset);
+void doClearBufferedBlocks(SStreamScanInfo* pInfo);
+
 uint64_t calcGroupId(char* pData, int32_t len);
+
 #ifdef __cplusplus
 }
 #endif
 
-#endif /*_TD_EXECUTOR_INT_H*/
\ No newline at end of file
+#endif  // TDENGINE_EXECUTORINT_H
diff --git a/source/libs/executor/inc/executorimpl.h b/source/libs/executor/inc/executorimpl.h
deleted file mode 100644
index f4e0108b92..0000000000
--- a/source/libs/executor/inc/executorimpl.h
+++ /dev/null
@@ -1,886 +0,0 @@
-/*
- * Copyright (c) 2019 TAOS Data, Inc. 
- *
- * This program is free software: you can use, redistribute, and/or modify
- * it under the terms of the GNU Affero General Public License, version 3
- * or later ("AGPL"), as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-#ifndef TDENGINE_EXECUTORIMPL_H
-#define TDENGINE_EXECUTORIMPL_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "os.h"
-#include "tcommon.h"
-#include "tlosertree.h"
-#include "tsort.h"
-#include "ttszip.h"
-#include "tvariant.h"
-
-#include "dataSinkMgt.h"
-#include "executil.h"
-#include "executor.h"
-#include "planner.h"
-#include "scalar.h"
-#include "taosdef.h"
-#include "tarray.h"
-#include "tfill.h"
-#include "thash.h"
-#include "tlockfree.h"
-#include "tmsg.h"
-#include "tpagedbuf.h"
-#include "tstream.h"
-#include "tstreamUpdate.h"
-
-#include "executorInt.h"
-#include "vnode.h"
-
-typedef int32_t (*__block_search_fn_t)(char* data, int32_t num, int64_t key, int32_t order);
-
-#define IS_VALID_SESSION_WIN(winInfo)        ((winInfo).sessionWin.win.skey > 0)
-#define SET_SESSION_WIN_INVALID(winInfo)     ((winInfo).sessionWin.win.skey = INT64_MIN)
-#define IS_INVALID_SESSION_WIN_KEY(winKey)   ((winKey).win.skey <= 0)
-#define SET_SESSION_WIN_KEY_INVALID(pWinKey) ((pWinKey)->win.skey = INT64_MIN)
-
-enum {
-  // when this task starts to execute, this status will set
-  TASK_NOT_COMPLETED = 0x1u,
-
-  /* Task is over
-   * 1. this status is used in one row result query process, e.g., count/sum/first/last/ avg...etc.
-   * 2. when all data within queried time window, it is also denoted as query_completed
-   */
-  TASK_COMPLETED = 0x2u,
-};
-
-/**
- * If the number of generated results is greater than this value,
- * query query will be halt and return results to client immediate.
- */
-typedef struct SResultInfo {  // TODO refactor
-  int64_t totalRows;          // total generated result size in rows
-  int64_t totalBytes;         // total results in bytes.
-  int32_t capacity;           // capacity of current result output buffer
-  int32_t threshold;          // result size threshold in rows.
-} SResultInfo;
-
-typedef struct STableQueryInfo {
-  TSKEY              lastKey;  // last check ts, todo remove it later
-  SResultRowPosition pos;      // current active time window
-} STableQueryInfo;
-
-typedef struct SLimit {
-  int64_t limit;
-  int64_t offset;
-} SLimit;
-
-typedef struct STableScanAnalyzeInfo SFileBlockLoadRecorder;
-
-typedef struct STaskCostInfo {
-  int64_t                 created;
-  int64_t                 start;
-  uint64_t                elapsedTime;
-  double                  extractListTime;
-  double                  groupIdMapTime;
-  SFileBlockLoadRecorder* pRecoder;
-} STaskCostInfo;
-
-typedef struct SOperatorCostInfo {
-  double openCost;
-  double totalCost;
-} SOperatorCostInfo;
-
-struct SOperatorInfo;
-
-typedef int32_t (*__optr_encode_fn_t)(struct SOperatorInfo* pOperator, char** result, int32_t* length);
-typedef int32_t (*__optr_decode_fn_t)(struct SOperatorInfo* pOperator, char* result);
-
-typedef int32_t (*__optr_open_fn_t)(struct SOperatorInfo* pOptr);
-typedef SSDataBlock* (*__optr_fn_t)(struct SOperatorInfo* pOptr);
-typedef void (*__optr_close_fn_t)(void* param);
-typedef int32_t (*__optr_explain_fn_t)(struct SOperatorInfo* pOptr, void** pOptrExplain, uint32_t* len);
-typedef int32_t (*__optr_reqBuf_fn_t)(struct SOperatorInfo* pOptr);
-
-typedef struct STaskIdInfo {
-  uint64_t queryId;  // this is also a request id
-  uint64_t subplanId;
-  uint64_t templateId;
-  char*    str;
-  int32_t  vgId;
-} STaskIdInfo;
-
-enum {
-  STREAM_RECOVER_STEP__NONE = 0,
-  STREAM_RECOVER_STEP__PREPARE1,
-  STREAM_RECOVER_STEP__PREPARE2,
-  STREAM_RECOVER_STEP__SCAN1,
-  STREAM_RECOVER_STEP__SCAN2,
-};
-
-typedef struct {
-  STqOffsetVal        currentOffset;  // for tmq
-  SMqMetaRsp          metaRsp;        // for tmq fetching meta
-  int64_t             snapshotVer;
-  SPackedData         submit;
-  SSchemaWrapper*     schema;
-  char                tbName[TSDB_TABLE_NAME_LEN];
-  int8_t              recoverStep;
-  int8_t              recoverScanFinished;
-  SQueryTableDataCond tableCond;
-  int64_t             fillHistoryVer1;
-  int64_t             fillHistoryVer2;
-  SStreamState*       pState;
-  int64_t             dataVersion;
-  int64_t             checkPointId;
-} SStreamTaskInfo;
-
-typedef struct {
-  char*           tablename;
-  char*           dbname;
-  int32_t         tversion;
-  SSchemaWrapper* sw;
-  SSchemaWrapper* qsw;
-} SSchemaInfo;
-
-typedef struct SExchangeOpStopInfo {
-  int32_t operatorType;
-  int64_t refId;
-} SExchangeOpStopInfo;
-
-typedef struct STaskStopInfo {
-  SRWLatch lock;
-  SArray*  pStopInfo;
-} STaskStopInfo;
-
-struct SExecTaskInfo {
-  STaskIdInfo           id;
-  uint32_t              status;
-  STimeWindow           window;
-  STaskCostInfo         cost;
-  int64_t               owner;  // if it is in execution
-  int32_t               code;
-  int32_t               qbufQuota;  // total available buffer (in KB) during execution query
-  int64_t               version;    // used for stream to record wal version, why not move to sschemainfo
-  SStreamTaskInfo       streamInfo;
-  SSchemaInfo           schemaInfo;
-  const char*           sql;        // query sql string
-  jmp_buf               env;        // jump to this position when error happens.
-  EOPTR_EXEC_MODEL      execModel;  // operator execution model [batch model|stream model]
-  SSubplan*             pSubplan;
-  struct SOperatorInfo* pRoot;
-  SLocalFetch           localFetch;
-  SArray*               pResultBlockList;  // result block list
-  STaskStopInfo         stopInfo;
-  SRWLatch              lock;  // secure the access of STableListInfo
-};
-
-enum {
-  OP_NOT_OPENED = 0x0,
-  OP_OPENED = 0x1,
-  OP_RES_TO_RETURN = 0x5,
-  OP_EXEC_DONE = 0x9,
-};
-
-typedef struct SOperatorFpSet {
-  __optr_open_fn_t    _openFn;  // DO NOT invoke this function directly
-  __optr_fn_t         getNextFn;
-  __optr_fn_t         cleanupFn;  // call this function to release the allocated resources ASAP
-  __optr_close_fn_t   closeFn;
-  __optr_reqBuf_fn_t  reqBufFn;  // total used buffer for blocking operator
-  __optr_encode_fn_t  encodeResultRow;
-  __optr_decode_fn_t  decodeResultRow;
-  __optr_explain_fn_t getExplainFn;
-} SOperatorFpSet;
-
-typedef struct SExprSupp {
-  SExprInfo*      pExprInfo;
-  int32_t         numOfExprs;  // the number of scalar expression in group operator
-  SqlFunctionCtx* pCtx;
-  int32_t*        rowEntryInfoOffset;  // offset value for each row result cell info
-  SFilterInfo*    pFilterInfo;
-} SExprSupp;
-
-typedef struct SOperatorInfo {
-  uint16_t               operatorType;
-  int16_t                resultDataBlockId;
-  bool                   blocking;  // block operator or not
-  uint8_t                status;    // denote if current operator is completed
-  char*                  name;      // name, for debug purpose
-  void*                  info;      // extension attribution
-  SExprSupp              exprSupp;
-  SExecTaskInfo*         pTaskInfo;
-  SOperatorCostInfo      cost;
-  SResultInfo            resultInfo;
-  struct SOperatorInfo** pDownstream;      // downstram pointer list
-  int32_t                numOfDownstream;  // number of downstream. The value is always ONE expect for join operator
-  SOperatorFpSet         fpSet;
-} SOperatorInfo;
-
-typedef enum {
-  EX_SOURCE_DATA_NOT_READY = 0x1,
-  EX_SOURCE_DATA_READY = 0x2,
-  EX_SOURCE_DATA_EXHAUSTED = 0x3,
-} EX_SOURCE_STATUS;
-
-#define COL_MATCH_FROM_COL_ID  0x1
-#define COL_MATCH_FROM_SLOT_ID 0x2
-
-typedef struct SLoadRemoteDataInfo {
-  uint64_t totalSize;     // total load bytes from remote
-  uint64_t totalRows;     // total number of rows
-  uint64_t totalElapsed;  // total elapsed time
-} SLoadRemoteDataInfo;
-
-typedef struct SLimitInfo {
-  SLimit   limit;
-  SLimit   slimit;
-  uint64_t currentGroupId;
-  int64_t  remainGroupOffset;
-  int64_t  numOfOutputGroups;
-  int64_t  remainOffset;
-  int64_t  numOfOutputRows;
-} SLimitInfo;
-
-typedef struct SExchangeInfo {
-  SArray* pSources;
-  SArray* pSourceDataInfo;
-  tsem_t  ready;
-  void*   pTransporter;
-
-  // SArray, result block list, used to keep the multi-block that
-  // passed by downstream operator
-  SArray*      pResultBlockList;
-  SArray*      pRecycledBlocks;  // build a pool for small data block to avoid to repeatly create and then destroy.
-  SSDataBlock* pDummyBlock;      // dummy block, not keep data
-  bool         seqLoadData;      // sequential load data or not, false by default
-  int32_t      current;
-  SLoadRemoteDataInfo loadInfo;
-  uint64_t            self;
-  SLimitInfo          limitInfo;
-  int64_t             openedTs;  // start exec time stamp, todo: move to SLoadRemoteDataInfo
-} SExchangeInfo;
-
-typedef struct SScanInfo {
-  int32_t numOfAsc;
-  int32_t numOfDesc;
-} SScanInfo;
-
-typedef struct SSampleExecInfo {
-  double   sampleRatio;  // data block sample ratio, 1 by default
-  uint32_t seed;         // random seed value
-} SSampleExecInfo;
-
-enum {
-  TABLE_SCAN__TABLE_ORDER = 1,
-  TABLE_SCAN__BLOCK_ORDER = 2,
-};
-
-typedef struct SAggSupporter {
-  SSHashObj*     pResultRowHashTable;  // quick locate the window object for each result
-  char*          keyBuf;               // window key buffer
-  SDiskbasedBuf* pResultBuf;           // query result buffer based on blocked-wised disk file
-  int32_t        resultRowSize;  // the result buffer size for each result row, with the meta data size for each row
-  int32_t        currentPageId;  // current write page id
-} SAggSupporter;
-
-typedef struct {
-  // if the upstream is an interval operator, the interval info is also kept here to get the time window to check if
-  // current data block needs to be loaded.
-  SInterval      interval;
-  SAggSupporter* pAggSup;
-  SExprSupp*     pExprSup;  // expr supporter of aggregate operator
-} SAggOptrPushDownInfo;
-
-typedef struct STableMetaCacheInfo {
-  SLRUCache* pTableMetaEntryCache;  // 100 by default
-  uint64_t   metaFetch;
-  uint64_t   cacheHit;
-} STableMetaCacheInfo;
-
-typedef struct STableScanBase {
-  STsdbReader*           dataReader;
-  SFileBlockLoadRecorder readRecorder;
-  SQueryTableDataCond    cond;
-  SAggOptrPushDownInfo   pdInfo;
-  SColMatchInfo          matchInfo;
-  SReadHandle            readHandle;
-  SExprSupp              pseudoSup;
-  STableMetaCacheInfo    metaCache;
-  int32_t                scanFlag;  // table scan flag to denote if it is a repeat/reverse/main scan
-  int32_t                dataBlockLoadFlag;
-  SLimitInfo             limitInfo;
-  // there are more than one table list exists in one task, if only one vnode exists.
-  STableListInfo* pTableListInfo;
-} STableScanBase;
-
-typedef struct STableScanInfo {
-  STableScanBase  base;
-  SScanInfo       scanInfo;
-  int32_t         scanTimes;
-  SSDataBlock*    pResBlock;
-  SHashObj*       pIgnoreTables;
-  SSampleExecInfo sample;  // sample execution info
-  int32_t         currentGroupId;
-  int32_t         currentTable;
-  int8_t          scanMode;
-  int8_t          assignBlockUid;
-  bool            hasGroupByTag;
-  bool            countOnly;
-} STableScanInfo;
-
-typedef struct STableMergeScanInfo {
-  int32_t         tableStartIndex;
-  int32_t         tableEndIndex;
-  bool            hasGroupId;
-  uint64_t        groupId;
-  SArray*         queryConds;  // array of queryTableDataCond
-  STableScanBase  base;
-  int32_t         bufPageSize;
-  uint32_t        sortBufSize;  // max buffer size for in-memory sort
-  SArray*         pSortInfo;
-  SSortHandle*    pSortHandle;
-  SSDataBlock*    pSortInputBlock;
-  int64_t         startTs;  // sort start time
-  SArray*         sortSourceParams;
-  SLimitInfo      limitInfo;
-  int64_t         numOfRows;
-  SScanInfo       scanInfo;
-  int32_t         scanTimes;
-  SSDataBlock*    pResBlock;
-  SSampleExecInfo sample;  // sample execution info
-  SSortExecInfo   sortExecInfo;
-} STableMergeScanInfo;
-
-typedef struct STagScanInfo {
-  SColumnInfo*    pCols;
-  SSDataBlock*    pRes;
-  SColMatchInfo   matchInfo;
-  int32_t         curPos;
-  SReadHandle     readHandle;
-  STableListInfo* pTableListInfo;
-} STagScanInfo;
-
-typedef enum EStreamScanMode {
-  STREAM_SCAN_FROM_READERHANDLE = 1,
-  STREAM_SCAN_FROM_RES,
-  STREAM_SCAN_FROM_UPDATERES,
-  STREAM_SCAN_FROM_DELETE_DATA,
-  STREAM_SCAN_FROM_DATAREADER_RETRIEVE,
-  STREAM_SCAN_FROM_DATAREADER_RANGE,
-} EStreamScanMode;
-
-enum {
-  PROJECT_RETRIEVE_CONTINUE = 0x1,
-  PROJECT_RETRIEVE_DONE = 0x2,
-};
-
-typedef struct SStreamAggSupporter {
-  int32_t         resultRowSize;  // the result buffer size for each result row, with the meta data size for each row
-  SSDataBlock*    pScanBlock;
-  SStreamState*   pState;
-  int64_t         gap;        // stream session window gap
-  SqlFunctionCtx* pDummyCtx;  // for combine
-  SSHashObj*      pResultRows;
-  int32_t         stateKeySize;
-  int16_t         stateKeyType;
-  SDiskbasedBuf*  pResultBuf;
-} SStreamAggSupporter;
-
-typedef struct SWindowSupporter {
-  SStreamAggSupporter* pStreamAggSup;
-  int64_t              gap;
-  uint16_t             parentType;
-  SAggSupporter*       pIntervalAggSup;
-} SWindowSupporter;
-
-typedef struct SPartitionBySupporter {
-  SArray* pGroupCols;     // group by columns, SArray
-  SArray* pGroupColVals;  // current group column values, SArray
-  char*   keyBuf;         // group by keys for hash
-  bool    needCalc;       // partition by column
-} SPartitionBySupporter;
-
-typedef struct SPartitionDataInfo {
-  uint64_t groupId;
-  char*    tbname;
-  SArray*  tags;
-  SArray*  rowIds;
-} SPartitionDataInfo;
-
-typedef struct STimeWindowAggSupp {
-  int8_t          calTrigger;
-  int8_t          calTriggerSaved;
-  int64_t         deleteMark;
-  int64_t         deleteMarkSaved;
-  int64_t         waterMark;
-  TSKEY           maxTs;
-  TSKEY           minTs;
-  SColumnInfoData timeWindowData;  // query time window info for scalar function execution.
-} STimeWindowAggSupp;
-
-typedef struct SStreamScanInfo {
-  SExprInfo*    pPseudoExpr;
-  int32_t       numOfPseudoExpr;
-  SExprSupp     tbnameCalSup;
-  SExprSupp     tagCalSup;
-  int32_t       primaryTsIndex;  // primary time stamp slot id
-  SReadHandle   readHandle;
-  SInterval     interval;  // if the upstream is an interval operator, the interval info is also kept here.
-  SColMatchInfo matchInfo;
-
-  SArray*      pBlockLists;  // multiple SSDatablock.
-  SSDataBlock* pRes;         // result SSDataBlock
-  SSDataBlock* pUpdateRes;   // update SSDataBlock
-  int32_t      updateResIndex;
-  int32_t      blockType;        // current block type
-  int32_t      validBlockIndex;  // Is current data has returned?
-  uint64_t     numOfExec;        // execution times
-  STqReader*   tqReader;
-
-  uint64_t     groupId;
-  SUpdateInfo* pUpdateInfo;
-
-  EStreamScanMode       scanMode;
-  SOperatorInfo*        pStreamScanOp;
-  SOperatorInfo*        pTableScanOp;
-  SArray*               childIds;
-  SWindowSupporter      windowSup;
-  SPartitionBySupporter partitionSup;
-  SExprSupp*            pPartScalarSup;
-  bool                  assignBlockUid;  // assign block uid to groupId, temporarily used for generating rollup SMA.
-  int32_t               scanWinIndex;    // for state operator
-  int32_t               pullDataResIndex;
-  SSDataBlock*          pPullDataRes;    // pull data SSDataBlock
-  SSDataBlock*          pDeleteDataRes;  // delete data SSDataBlock
-  int32_t               deleteDataIndex;
-  STimeWindow           updateWin;
-  STimeWindowAggSupp    twAggSup;
-  SSDataBlock*          pUpdateDataRes;
-  // status for tmq
-  SNodeList* pGroupTags;
-  SNode*     pTagCond;
-  SNode*     pTagIndexCond;
-
-  // recover
-  int32_t      blockRecoverContiCnt;
-  int32_t      blockRecoverTotCnt;
-  SSDataBlock* pRecoverRes;
-
-  SSDataBlock* pCreateTbRes;
-  int8_t       igCheckUpdate;
-  int8_t       igExpired;
-} SStreamScanInfo;
-
-typedef struct {
-  SVnode*         vnode;
-  SSDataBlock     pRes;  // result SSDataBlock
-  STsdbReader*    dataReader;
-  SSnapContext*   sContext;
-  STableListInfo* pTableListInfo;
-} SStreamRawScanInfo;
-
-typedef struct STableCountScanSupp {
-  int16_t dbNameSlotId;
-  int16_t stbNameSlotId;
-  int16_t tbCountSlotId;
-  bool    groupByDbName;
-  bool    groupByStbName;
-  char    dbNameFilter[TSDB_DB_NAME_LEN];
-  char    stbNameFilter[TSDB_TABLE_NAME_LEN];
-} STableCountScanSupp;
-
-typedef struct SOptrBasicInfo {
-  SResultRowInfo resultRowInfo;
-  SSDataBlock*   pRes;
-  bool           mergeResultBlock;
-} SOptrBasicInfo;
-
-typedef struct SIntervalAggOperatorInfo {
-  SOptrBasicInfo     binfo;              // basic info
-  SAggSupporter      aggSup;             // aggregate supporter
-  SExprSupp          scalarSupp;         // supporter for perform scalar function
-  SGroupResInfo      groupResInfo;       // multiple results build supporter
-  SInterval          interval;           // interval info
-  int32_t            primaryTsIndex;     // primary time stamp slot id from result of downstream operator.
-  STimeWindow        win;                // query time range
-  bool               timeWindowInterpo;  // interpolation needed or not
-  SArray*            pInterpCols;        // interpolation columns
-  int32_t            resultTsOrder;      // result timestamp order
-  int32_t            inputOrder;         // input data ts order
-  EOPTR_EXEC_MODEL   execModel;          // operator execution model [batch model|stream model]
-  STimeWindowAggSupp twAggSup;
-  SArray*            pPrevValues;  //  SArray used to keep the previous not null value for interpolation.
-} SIntervalAggOperatorInfo;
-
-typedef struct SMergeAlignedIntervalAggOperatorInfo {
-  SIntervalAggOperatorInfo* intervalAggOperatorInfo;
-
-  uint64_t     groupId;  // current groupId
-  int64_t      curTs;    // current ts
-  SSDataBlock* prefetchedBlock;
-  SResultRow*  pResultRow;
-} SMergeAlignedIntervalAggOperatorInfo;
-
-typedef struct SStreamIntervalOperatorInfo {
-  SOptrBasicInfo     binfo;           // basic info
-  SAggSupporter      aggSup;          // aggregate supporter
-  SExprSupp          scalarSupp;      // supporter for perform scalar function
-  SGroupResInfo      groupResInfo;    // multiple results build supporter
-  SInterval          interval;        // interval info
-  int32_t            primaryTsIndex;  // primary time stamp slot id from result of downstream operator.
-  STimeWindowAggSupp twAggSup;
-  bool               invertible;
-  bool               ignoreExpiredData;
-  bool               ignoreExpiredDataSaved;
-  SArray*            pDelWins;  // SWinRes
-  int32_t            delIndex;
-  SSDataBlock*       pDelRes;
-  SPhysiNode*        pPhyNode;  // create new child
-  SHashObj*          pPullDataMap;
-  SArray*            pPullWins;  // SPullWindowInfo
-  int32_t            pullIndex;
-  SSDataBlock*       pPullDataRes;
-  bool               isFinal;
-  SArray*            pChildren;
-  SStreamState*      pState;
-  SWinKey            delKey;
-  uint64_t           numOfDatapack;
-  SArray*            pUpdated;
-  SSHashObj*         pUpdatedMap;
-  int64_t            dataVersion;
-} SStreamIntervalOperatorInfo;
-
-typedef struct SDataGroupInfo {
-  uint64_t groupId;
-  int64_t  numOfRows;
-  SArray*  pPageList;
-} SDataGroupInfo;
-
-typedef struct SWindowRowsSup {
-  STimeWindow win;
-  TSKEY       prevTs;
-  int32_t     startRowIndex;
-  int32_t     numOfRows;
-  uint64_t    groupId;
-} SWindowRowsSup;
-
-typedef struct SResultWindowInfo {
-  void*       pOutputBuf;
-  SSessionKey sessionWin;
-  bool        isOutput;
-} SResultWindowInfo;
-
-typedef struct SStateWindowInfo {
-  SResultWindowInfo winInfo;
-  SStateKeys*       pStateKey;
-} SStateWindowInfo;
-
-typedef struct SStreamSessionAggOperatorInfo {
-  SOptrBasicInfo      binfo;
-  SStreamAggSupporter streamAggSup;
-  SExprSupp           scalarSupp;  // supporter for perform scalar function
-  SGroupResInfo       groupResInfo;
-  int32_t             primaryTsIndex;  // primary timestamp slot id
-  int32_t             endTsIndex;      // window end timestamp slot id
-  int32_t             order;           // current SSDataBlock scan order
-  STimeWindowAggSupp  twAggSup;
-  SSDataBlock*        pWinBlock;   // window result
-  SSDataBlock*        pDelRes;     // delete result
-  SSDataBlock*        pUpdateRes;  // update window
-  bool                returnUpdate;
-  SSHashObj*          pStDeleted;
-  void*               pDelIterator;
-  SArray*             pChildren;  // cache for children's result; final stream operator
-  SPhysiNode*         pPhyNode;   // create new child
-  bool                isFinal;
-  bool                ignoreExpiredData;
-  bool                ignoreExpiredDataSaved;
-  SArray*             pUpdated;
-  SSHashObj*          pStUpdated;
-  int64_t             dataVersion;
-} SStreamSessionAggOperatorInfo;
-
-typedef struct SStreamStateAggOperatorInfo {
-  SOptrBasicInfo      binfo;
-  SStreamAggSupporter streamAggSup;
-  SExprSupp           scalarSupp;  // supporter for perform scalar function
-  SGroupResInfo       groupResInfo;
-  int32_t             primaryTsIndex;  // primary timestamp slot id
-  STimeWindowAggSupp  twAggSup;
-  SColumn             stateCol;
-  SSDataBlock*        pDelRes;
-  SSHashObj*          pSeDeleted;
-  void*               pDelIterator;
-  SArray*             pChildren;  // cache for children's result;
-  bool                ignoreExpiredData;
-  bool                ignoreExpiredDataSaved;
-  SArray*             pUpdated;
-  SSHashObj*          pSeUpdated;
-  int64_t             dataVersion;
-} SStreamStateAggOperatorInfo;
-
-typedef struct SStreamPartitionOperatorInfo {
-  SOptrBasicInfo        binfo;
-  SPartitionBySupporter partitionSup;
-  SExprSupp             scalarSup;
-  SExprSupp             tbnameCalSup;
-  SExprSupp             tagCalSup;
-  SHashObj*             pPartitions;
-  void*                 parIte;
-  void*                 pTbNameIte;
-  SSDataBlock*          pInputDataBlock;
-  int32_t               tsColIndex;
-  SSDataBlock*          pDelRes;
-  SSDataBlock*          pCreateTbRes;
-} SStreamPartitionOperatorInfo;
-
-typedef struct SStreamFillSupporter {
-  int32_t        type;  // fill type
-  SInterval      interval;
-  SResultRowData prev;
-  SResultRowData cur;
-  SResultRowData next;
-  SResultRowData nextNext;
-  SFillColInfo*  pAllColInfo;  // fill exprs and not fill exprs
-  SExprSupp      notFillExprSup;
-  int32_t        numOfAllCols;  // number of all exprs, including the tags columns
-  int32_t        numOfFillCols;
-  int32_t        numOfNotFillCols;
-  int32_t        rowSize;
-  SSHashObj*     pResMap;
-  bool           hasDelete;
-} SStreamFillSupporter;
-
-typedef struct SStreamFillOperatorInfo {
-  SStreamFillSupporter* pFillSup;
-  SSDataBlock*          pRes;
-  SSDataBlock*          pSrcBlock;
-  int32_t               srcRowIndex;
-  SSDataBlock*          pSrcDelBlock;
-  int32_t               srcDelRowIndex;
-  SSDataBlock*          pDelRes;
-  SColMatchInfo         matchInfo;
-  int32_t               primaryTsCol;
-  int32_t               primarySrcSlotId;
-  SStreamFillInfo*      pFillInfo;
-} SStreamFillOperatorInfo;
-
-#define OPTR_IS_OPENED(_optr)  (((_optr)->status & OP_OPENED) == OP_OPENED)
-#define OPTR_SET_OPENED(_optr) ((_optr)->status |= OP_OPENED)
-
-SExecTaskInfo* doCreateExecTaskInfo(uint64_t queryId, uint64_t taskId, int32_t vgId, EOPTR_EXEC_MODEL model,
-                                    char* dbFName);
-
-SOperatorFpSet createOperatorFpSet(__optr_open_fn_t openFn, __optr_fn_t nextFn, __optr_fn_t cleanup,
-                                   __optr_close_fn_t closeFn, __optr_reqBuf_fn_t reqBufFn, __optr_explain_fn_t explain);
-int32_t        optrDummyOpenFn(SOperatorInfo* pOperator);
-int32_t        appendDownstream(SOperatorInfo* p, SOperatorInfo** pDownstream, int32_t num);
-void           setOperatorCompleted(SOperatorInfo* pOperator);
-void           setOperatorInfo(SOperatorInfo* pOperator, const char* name, int32_t type, bool blocking, int32_t status,
-                               void* pInfo, SExecTaskInfo* pTaskInfo);
-void           destroyOperatorInfo(SOperatorInfo* pOperator);
-int32_t        optrDefaultBufFn(SOperatorInfo* pOperator);
-
-void initBasicInfo(SOptrBasicInfo* pInfo, SSDataBlock* pBlock);
-void cleanupBasicInfo(SOptrBasicInfo* pInfo);
-
-int32_t initExprSupp(SExprSupp* pSup, SExprInfo* pExprInfo, int32_t numOfExpr);
-void    cleanupExprSupp(SExprSupp* pSup);
-
-void destroyExprInfo(SExprInfo* pExpr, int32_t numOfExprs);
-
-int32_t initAggSup(SExprSupp* pSup, SAggSupporter* pAggSup, SExprInfo* pExprInfo, int32_t numOfCols, size_t keyBufSize,
-                   const char* pkey, void* pState);
-void    cleanupAggSup(SAggSupporter* pAggSup);
-
-void initResultSizeInfo(SResultInfo* pResultInfo, int32_t numOfRows);
-
-void doBuildStreamResBlock(SOperatorInfo* pOperator, SOptrBasicInfo* pbInfo, SGroupResInfo* pGroupResInfo,
-                           SDiskbasedBuf* pBuf);
-void doBuildResultDatablock(SOperatorInfo* pOperator, SOptrBasicInfo* pbInfo, SGroupResInfo* pGroupResInfo,
-                            SDiskbasedBuf* pBuf);
-
-bool hasLimitOffsetInfo(SLimitInfo* pLimitInfo);
-bool hasSlimitOffsetInfo(SLimitInfo* pLimitInfo);
-void initLimitInfo(const SNode* pLimit, const SNode* pSLimit, SLimitInfo* pLimitInfo);
-void resetLimitInfoForNextGroup(SLimitInfo* pLimitInfo);
-bool applyLimitOffset(SLimitInfo* pLimitInfo, SSDataBlock* pBlock, SExecTaskInfo* pTaskInfo);
-
-void applyAggFunctionOnPartialTuples(SExecTaskInfo* taskInfo, SqlFunctionCtx* pCtx, SColumnInfoData* pTimeWindowData,
-                                     int32_t offset, int32_t forwardStep, int32_t numOfTotal, int32_t numOfOutput);
-
-int32_t extractDataBlockFromFetchRsp(SSDataBlock* pRes, char* pData, SArray* pColList, char** pNextStart);
-void    updateLoadRemoteInfo(SLoadRemoteDataInfo* pInfo, int64_t numOfRows, int32_t dataLen, int64_t startTs,
-                             SOperatorInfo* pOperator);
-
-STimeWindow getFirstQualifiedTimeWindow(int64_t ts, STimeWindow* pWindow, SInterval* pInterval, int32_t order);
-
-SOperatorInfo* extractOperatorInTree(SOperatorInfo* pOperator, int32_t type, const char* id);
-int32_t        getTableScanInfo(SOperatorInfo* pOperator, int32_t* order, int32_t* scanFlag, bool inheritUsOrder);
-int32_t        getBufferPgSize(int32_t rowSize, uint32_t* defaultPgsz, uint32_t* defaultBufsz);
-
-extern void doDestroyExchangeOperatorInfo(void* param);
-
-void    doFilter(SSDataBlock* pBlock, SFilterInfo* pFilterInfo, SColMatchInfo* pColMatchInfo);
-int32_t addTagPseudoColumnData(SReadHandle* pHandle, const SExprInfo* pExpr, int32_t numOfExpr, SSDataBlock* pBlock,
-                               int32_t rows, const char* idStr, STableMetaCacheInfo* pCache);
-
-void appendOneRowToDataBlock(SSDataBlock* pBlock, STupleHandle* pTupleHandle);
-void setTbNameColData(const SSDataBlock* pBlock, SColumnInfoData* pColInfoData, int32_t functionId, const char* name);
-
-void setResultRowInitCtx(SResultRow* pResult, SqlFunctionCtx* pCtx, int32_t numOfOutput, int32_t* rowEntryInfoOffset);
-void clearResultRowInitFlag(SqlFunctionCtx* pCtx, int32_t numOfOutput);
-
-SResultRow* doSetResultOutBufByKey(SDiskbasedBuf* pResultBuf, SResultRowInfo* pResultRowInfo, char* pData,
-                                   int16_t bytes, bool masterscan, uint64_t groupId, SExecTaskInfo* pTaskInfo,
-                                   bool isIntervalQuery, SAggSupporter* pSup, bool keepGroup);
-// operator creater functions
-// clang-format off
-SOperatorInfo* createExchangeOperatorInfo(void* pTransporter, SExchangePhysiNode* pExNode, SExecTaskInfo* pTaskInfo);
-
-SOperatorInfo* createTableScanOperatorInfo(STableScanPhysiNode* pTableScanNode, SReadHandle* pHandle, STableListInfo* pTableList, SExecTaskInfo* pTaskInfo);
-
-SOperatorInfo* createTableMergeScanOperatorInfo(STableScanPhysiNode* pTableScanNode, SReadHandle* readHandle, STableListInfo* pTableListInfo, SExecTaskInfo* pTaskInfo);
-
-SOperatorInfo* createTagScanOperatorInfo(SReadHandle* pReadHandle, STagScanPhysiNode* pPhyNode, STableListInfo* pTableListInfo, SExecTaskInfo* pTaskInfo);
-
-SOperatorInfo* createSysTableScanOperatorInfo(void* readHandle, SSystemTableScanPhysiNode* pScanPhyNode, const char* pUser, SExecTaskInfo* pTaskInfo);
-
-SOperatorInfo* createTableCountScanOperatorInfo(SReadHandle* handle, STableCountScanPhysiNode* pNode, SExecTaskInfo* pTaskInfo);
-
-SOperatorInfo* createAggregateOperatorInfo(SOperatorInfo* downstream, SAggPhysiNode* pNode, SExecTaskInfo* pTaskInfo);
-
-SOperatorInfo* createIndefinitOutputOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pNode, SExecTaskInfo* pTaskInfo);
-
-SOperatorInfo* createProjectOperatorInfo(SOperatorInfo* downstream, SProjectPhysiNode* pProjPhyNode, SExecTaskInfo* pTaskInfo);
-
-SOperatorInfo* createSortOperatorInfo(SOperatorInfo* downstream, SSortPhysiNode* pSortNode, SExecTaskInfo* pTaskInfo);
-
-SOperatorInfo* createMultiwayMergeOperatorInfo(SOperatorInfo** dowStreams, size_t numStreams, SMergePhysiNode* pMergePhysiNode, SExecTaskInfo* pTaskInfo);
-
-SOperatorInfo* createCacherowsScanOperator(SLastRowScanPhysiNode* pTableScanNode, SReadHandle* readHandle, STableListInfo* pTableListInfo, SExecTaskInfo* pTaskInfo);
-
-SOperatorInfo* createIntervalOperatorInfo(SOperatorInfo* downstream, SIntervalPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo);
-
-SOperatorInfo* createMergeIntervalOperatorInfo(SOperatorInfo* downstream, SMergeIntervalPhysiNode* pIntervalPhyNode, SExecTaskInfo* pTaskInfo);
-
-SOperatorInfo* createMergeAlignedIntervalOperatorInfo(SOperatorInfo* downstream, SMergeAlignedIntervalPhysiNode* pNode, SExecTaskInfo* pTaskInfo);
-
-SOperatorInfo* createStreamFinalIntervalOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, int32_t numOfChild);
-
-SOperatorInfo* createSessionAggOperatorInfo(SOperatorInfo* downstream, SSessionWinodwPhysiNode* pSessionNode, SExecTaskInfo* pTaskInfo);
-
-SOperatorInfo* createGroupOperatorInfo(SOperatorInfo* downstream, SAggPhysiNode* pAggNode, SExecTaskInfo* pTaskInfo);
-
-SOperatorInfo* createDataBlockInfoScanOperator(SReadHandle* readHandle, SBlockDistScanPhysiNode* pBlockScanNode, STableListInfo* pTableListInfo, SExecTaskInfo* pTaskInfo);
-
-SOperatorInfo* createStreamScanOperatorInfo(SReadHandle* pHandle, STableScanPhysiNode* pTableScanNode, SNode* pTagCond, STableListInfo* pTableListInfo, SExecTaskInfo* pTaskInfo);
-
-SOperatorInfo* createRawScanOperatorInfo(SReadHandle* pHandle, SExecTaskInfo* pTaskInfo);
-
-SOperatorInfo* createFillOperatorInfo(SOperatorInfo* downstream, SFillPhysiNode* pPhyFillNode, SExecTaskInfo* pTaskInfo);
-
-SOperatorInfo* createStatewindowOperatorInfo(SOperatorInfo* downstream, SStateWinodwPhysiNode* pStateNode, SExecTaskInfo* pTaskInfo);
-
-SOperatorInfo* createPartitionOperatorInfo(SOperatorInfo* downstream, SPartitionPhysiNode* pPartNode, SExecTaskInfo* pTaskInfo);
-
-SOperatorInfo* createStreamPartitionOperatorInfo(SOperatorInfo* downstream, SStreamPartitionPhysiNode* pPartNode, SExecTaskInfo* pTaskInfo);
-
-SOperatorInfo* createTimeSliceOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pNode, SExecTaskInfo* pTaskInfo);
-
-SOperatorInfo* createMergeJoinOperatorInfo(SOperatorInfo** pDownstream, int32_t numOfDownstream, SSortMergeJoinPhysiNode* pJoinNode, SExecTaskInfo* pTaskInfo);
-
-SOperatorInfo* createStreamSessionAggOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo);
-
-SOperatorInfo* createStreamFinalSessionAggOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, int32_t numOfChild);
-
-SOperatorInfo* createStreamIntervalOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo);
-
-SOperatorInfo* createStreamStateAggOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo);
-
-SOperatorInfo* createStreamFillOperatorInfo(SOperatorInfo* downstream, SStreamFillPhysiNode* pPhyFillNode, SExecTaskInfo* pTaskInfo);
-
-SOperatorInfo* createGroupSortOperatorInfo(SOperatorInfo* downstream, SGroupSortPhysiNode* pSortPhyNode, SExecTaskInfo* pTaskInfo);
-
-SOperatorInfo* createEventwindowOperatorInfo(SOperatorInfo* downstream, SPhysiNode* physiNode, SExecTaskInfo* pTaskInfo);
-// clang-format on
-
-int32_t projectApplyFunctions(SExprInfo* pExpr, SSDataBlock* pResult, SSDataBlock* pSrcBlock, SqlFunctionCtx* pCtx,
-                              int32_t numOfOutput, SArray* pPseudoList);
-
-void setInputDataBlock(SExprSupp* pExprSupp, SSDataBlock* pBlock, int32_t order, int32_t scanFlag, bool createDummyCol);
-
-int32_t checkForQueryBuf(size_t numOfTables);
-
-bool isTaskKilled(SExecTaskInfo* pTaskInfo);
-void setTaskKilled(SExecTaskInfo* pTaskInfo, int32_t rspCode);
-void doDestroyTask(SExecTaskInfo* pTaskInfo);
-void setTaskStatus(SExecTaskInfo* pTaskInfo, int8_t status);
-
-void buildTaskId(uint64_t taskId, uint64_t queryId, char* dst);
-
-SArray* getTableListInfo(const SExecTaskInfo* pTaskInfo);
-
-int32_t createExecTaskInfo(SSubplan* pPlan, SExecTaskInfo** pTaskInfo, SReadHandle* pHandle, uint64_t taskId,
-                           int32_t vgId, char* sql, EOPTR_EXEC_MODEL model);
-int32_t createDataSinkParam(SDataSinkNode* pNode, void** pParam, SExecTaskInfo* pTask, SReadHandle* readHandle);
-int32_t getOperatorExplainExecInfo(SOperatorInfo* operatorInfo, SArray* pExecInfoList);
-
-STimeWindow getActiveTimeWindow(SDiskbasedBuf* pBuf, SResultRowInfo* pResultRowInfo, int64_t ts, SInterval* pInterval,
-                                int32_t order);
-int32_t getNumOfRowsInTimeWindow(SDataBlockInfo* pDataBlockInfo, TSKEY* pPrimaryColumn, int32_t startPos, TSKEY ekey,
-                                 __block_search_fn_t searchFn, STableQueryInfo* item, int32_t order);
-int32_t binarySearchForKey(char* pValue, int num, TSKEY key, int order);
-SResultRow* getNewResultRow(SDiskbasedBuf* pResultBuf, int32_t* currentPageId, int32_t interBufSize);
-void getCurSessionWindow(SStreamAggSupporter* pAggSup, TSKEY startTs, TSKEY endTs, uint64_t groupId, SSessionKey* pKey);
-bool isInTimeWindow(STimeWindow* pWin, TSKEY ts, int64_t gap);
-bool functionNeedToExecute(SqlFunctionCtx* pCtx);
-bool isOverdue(TSKEY ts, STimeWindowAggSupp* pSup);
-bool isCloseWindow(STimeWindow* pWin, STimeWindowAggSupp* pSup);
-bool isDeletedStreamWindow(STimeWindow* pWin, uint64_t groupId, SStreamState* pState, STimeWindowAggSupp* pTwSup);
-void appendOneRowToStreamSpecialBlock(SSDataBlock* pBlock, TSKEY* pStartTs, TSKEY* pEndTs, uint64_t* pUid,
-                                      uint64_t* pGp, void* pTbName);
-uint64_t calGroupIdByData(SPartitionBySupporter* pParSup, SExprSupp* pExprSup, SSDataBlock* pBlock, int32_t rowId);
-
-int32_t finalizeResultRows(SDiskbasedBuf* pBuf, SResultRowPosition* resultRowPosition, SExprSupp* pSup,
-                           SSDataBlock* pBlock, SExecTaskInfo* pTaskInfo);
-
-bool    groupbyTbname(SNodeList* pGroupList);
-int32_t buildDataBlockFromGroupRes(SOperatorInfo* pOperator, SStreamState* pState, SSDataBlock* pBlock, SExprSupp* pSup,
-                                   SGroupResInfo* pGroupResInfo);
-int32_t saveSessionDiscBuf(SStreamState* pState, SSessionKey* key, void* buf, int32_t size);
-int32_t buildSessionResultDataBlock(SOperatorInfo* pOperator, SStreamState* pState, SSDataBlock* pBlock,
-                                    SExprSupp* pSup, SGroupResInfo* pGroupResInfo);
-int32_t setOutputBuf(SStreamState* pState, STimeWindow* win, SResultRow** pResult, int64_t tableGroupId,
-                     SqlFunctionCtx* pCtx, int32_t numOfOutput, int32_t* rowEntryInfoOffset, SAggSupporter* pAggSup);
-int32_t releaseOutputBuf(SStreamState* pState, SWinKey* pKey, SResultRow* pResult);
-int32_t saveOutputBuf(SStreamState* pState, SWinKey* pKey, SResultRow* pResult, int32_t resSize);
-void    getNextIntervalWindow(SInterval* pInterval, STimeWindow* tw, int32_t order);
-int32_t qAppendTaskStopInfo(SExecTaskInfo* pTaskInfo, SExchangeOpStopInfo* pInfo);
-int32_t getForwardStepsInBlock(int32_t numOfRows, __block_search_fn_t searchFn, TSKEY ekey, int32_t pos, int32_t order,
-                               int64_t* pData);
-void    appendCreateTableRow(SStreamState* pState, SExprSupp* pTableSup, SExprSupp* pTagSup, uint64_t groupId,
-                             SSDataBlock* pSrcBlock, int32_t rowId, SSDataBlock* pDestBlock);
-
-SSDataBlock* buildCreateTableBlock(SExprSupp* tbName, SExprSupp* tag);
-SExprInfo*   createExpr(SNodeList* pNodeList, int32_t* numOfExprs);
-
-void copyResultrowToDataBlock(SExprInfo* pExprInfo, int32_t numOfExprs, SResultRow* pRow, SqlFunctionCtx* pCtx,
-                              SSDataBlock* pBlock, const int32_t* rowEntryOffset, SExecTaskInfo* pTaskInfo);
-void doUpdateNumOfRows(SqlFunctionCtx* pCtx, SResultRow* pRow, int32_t numOfExprs, const int32_t* rowEntryOffset);
-void doClearBufferedBlocks(SStreamScanInfo* pInfo);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif  // TDENGINE_EXECUTORIMPL_H
diff --git a/source/libs/executor/inc/operator.h b/source/libs/executor/inc/operator.h
new file mode 100644
index 0000000000..632b817a07
--- /dev/null
+++ b/source/libs/executor/inc/operator.h
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2019 TAOS Data, Inc. 
+ *
+ * This program is free software: you can use, redistribute, and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3
+ * or later ("AGPL"), as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef TDENGINE_OPERATOR_H
+#define TDENGINE_OPERATOR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct SOperatorCostInfo {
+  double openCost;
+  double totalCost;
+} SOperatorCostInfo;
+
+struct SOperatorInfo;
+
+typedef int32_t (*__optr_encode_fn_t)(struct SOperatorInfo* pOperator, char** result, int32_t* length);
+typedef int32_t (*__optr_decode_fn_t)(struct SOperatorInfo* pOperator, char* result);
+
+typedef int32_t (*__optr_open_fn_t)(struct SOperatorInfo* pOptr);
+typedef SSDataBlock* (*__optr_fn_t)(struct SOperatorInfo* pOptr);
+typedef void (*__optr_close_fn_t)(void* param);
+typedef int32_t (*__optr_explain_fn_t)(struct SOperatorInfo* pOptr, void** pOptrExplain, uint32_t* len);
+typedef int32_t (*__optr_reqBuf_fn_t)(struct SOperatorInfo* pOptr);
+
+typedef struct SOperatorFpSet {
+  __optr_open_fn_t    _openFn;  // DO NOT invoke this function directly
+  __optr_fn_t         getNextFn;
+  __optr_fn_t         cleanupFn;  // call this function to release the allocated resources ASAP
+  __optr_close_fn_t   closeFn;
+  __optr_reqBuf_fn_t  reqBufFn;  // total used buffer for blocking operator
+  __optr_encode_fn_t  encodeResultRow;
+  __optr_decode_fn_t  decodeResultRow;
+  __optr_explain_fn_t getExplainFn;
+} SOperatorFpSet;
+
+enum {
+  OP_NOT_OPENED = 0x0,
+  OP_OPENED = 0x1,
+  OP_RES_TO_RETURN = 0x5,
+  OP_EXEC_DONE = 0x9,
+};
+
+typedef struct SOperatorInfo {
+  uint16_t               operatorType;
+  int16_t                resultDataBlockId;
+  bool                   blocking;  // block operator or not
+  uint8_t                status;    // denote if current operator is completed
+  char*                  name;      // name, for debug purpose
+  void*                  info;      // extension attribution
+  SExprSupp              exprSupp;
+  SExecTaskInfo*         pTaskInfo;
+  SOperatorCostInfo      cost;
+  SResultInfo            resultInfo;
+  struct SOperatorInfo** pDownstream;      // downstram pointer list
+  int32_t                numOfDownstream;  // number of downstream. The value is always ONE expect for join operator
+  SOperatorFpSet         fpSet;
+} SOperatorInfo;
+
+// operator creater functions
+// clang-format off
+SOperatorInfo* createExchangeOperatorInfo(void* pTransporter, SExchangePhysiNode* pExNode, SExecTaskInfo* pTaskInfo);
+
+SOperatorInfo* createTableScanOperatorInfo(STableScanPhysiNode* pTableScanNode, SReadHandle* pHandle, STableListInfo* pTableList, SExecTaskInfo* pTaskInfo);
+
+SOperatorInfo* createTableMergeScanOperatorInfo(STableScanPhysiNode* pTableScanNode, SReadHandle* readHandle, STableListInfo* pTableListInfo, SExecTaskInfo* pTaskInfo);
+
+SOperatorInfo* createTagScanOperatorInfo(SReadHandle* pReadHandle, STagScanPhysiNode* pPhyNode, STableListInfo* pTableListInfo, SExecTaskInfo* pTaskInfo);
+
+SOperatorInfo* createSysTableScanOperatorInfo(void* readHandle, SSystemTableScanPhysiNode* pScanPhyNode, const char* pUser, SExecTaskInfo* pTaskInfo);
+
+SOperatorInfo* createTableCountScanOperatorInfo(SReadHandle* handle, STableCountScanPhysiNode* pNode, SExecTaskInfo* pTaskInfo);
+
+SOperatorInfo* createAggregateOperatorInfo(SOperatorInfo* downstream, SAggPhysiNode* pNode, SExecTaskInfo* pTaskInfo);
+
+SOperatorInfo* createIndefinitOutputOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pNode, SExecTaskInfo* pTaskInfo);
+
+SOperatorInfo* createProjectOperatorInfo(SOperatorInfo* downstream, SProjectPhysiNode* pProjPhyNode, SExecTaskInfo* pTaskInfo);
+
+SOperatorInfo* createSortOperatorInfo(SOperatorInfo* downstream, SSortPhysiNode* pSortNode, SExecTaskInfo* pTaskInfo);
+
+SOperatorInfo* createMultiwayMergeOperatorInfo(SOperatorInfo** dowStreams, size_t numStreams, SMergePhysiNode* pMergePhysiNode, SExecTaskInfo* pTaskInfo);
+
+SOperatorInfo* createCacherowsScanOperator(SLastRowScanPhysiNode* pTableScanNode, SReadHandle* readHandle, STableListInfo* pTableListInfo, SExecTaskInfo* pTaskInfo);
+
+SOperatorInfo* createIntervalOperatorInfo(SOperatorInfo* downstream, SIntervalPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo);
+
+SOperatorInfo* createMergeIntervalOperatorInfo(SOperatorInfo* downstream, SMergeIntervalPhysiNode* pIntervalPhyNode, SExecTaskInfo* pTaskInfo);
+
+SOperatorInfo* createMergeAlignedIntervalOperatorInfo(SOperatorInfo* downstream, SMergeAlignedIntervalPhysiNode* pNode, SExecTaskInfo* pTaskInfo);
+
+SOperatorInfo* createStreamFinalIntervalOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, int32_t numOfChild);
+
+SOperatorInfo* createSessionAggOperatorInfo(SOperatorInfo* downstream, SSessionWinodwPhysiNode* pSessionNode, SExecTaskInfo* pTaskInfo);
+
+SOperatorInfo* createGroupOperatorInfo(SOperatorInfo* downstream, SAggPhysiNode* pAggNode, SExecTaskInfo* pTaskInfo);
+
+SOperatorInfo* createDataBlockInfoScanOperator(SReadHandle* readHandle, SBlockDistScanPhysiNode* pBlockScanNode, STableListInfo* pTableListInfo, SExecTaskInfo* pTaskInfo);
+
+SOperatorInfo* createStreamScanOperatorInfo(SReadHandle* pHandle, STableScanPhysiNode* pTableScanNode, SNode* pTagCond, STableListInfo* pTableListInfo, SExecTaskInfo* pTaskInfo);
+
+SOperatorInfo* createRawScanOperatorInfo(SReadHandle* pHandle, SExecTaskInfo* pTaskInfo);
+
+SOperatorInfo* createFillOperatorInfo(SOperatorInfo* downstream, SFillPhysiNode* pPhyFillNode, SExecTaskInfo* pTaskInfo);
+
+SOperatorInfo* createStatewindowOperatorInfo(SOperatorInfo* downstream, SStateWinodwPhysiNode* pStateNode, SExecTaskInfo* pTaskInfo);
+
+SOperatorInfo* createPartitionOperatorInfo(SOperatorInfo* downstream, SPartitionPhysiNode* pPartNode, SExecTaskInfo* pTaskInfo);
+
+SOperatorInfo* createStreamPartitionOperatorInfo(SOperatorInfo* downstream, SStreamPartitionPhysiNode* pPartNode, SExecTaskInfo* pTaskInfo);
+
+SOperatorInfo* createTimeSliceOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pNode, SExecTaskInfo* pTaskInfo);
+
+SOperatorInfo* createMergeJoinOperatorInfo(SOperatorInfo** pDownstream, int32_t numOfDownstream, SSortMergeJoinPhysiNode* pJoinNode, SExecTaskInfo* pTaskInfo);
+
+SOperatorInfo* createStreamSessionAggOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo);
+
+SOperatorInfo* createStreamFinalSessionAggOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, int32_t numOfChild);
+
+SOperatorInfo* createStreamIntervalOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo);
+
+SOperatorInfo* createStreamStateAggOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo);
+
+SOperatorInfo* createStreamFillOperatorInfo(SOperatorInfo* downstream, SStreamFillPhysiNode* pPhyFillNode, SExecTaskInfo* pTaskInfo);
+
+SOperatorInfo* createGroupSortOperatorInfo(SOperatorInfo* downstream, SGroupSortPhysiNode* pSortPhyNode, SExecTaskInfo* pTaskInfo);
+
+SOperatorInfo* createEventwindowOperatorInfo(SOperatorInfo* downstream, SPhysiNode* physiNode, SExecTaskInfo* pTaskInfo);
+// clang-format on
+
+SOperatorFpSet createOperatorFpSet(__optr_open_fn_t openFn, __optr_fn_t nextFn, __optr_fn_t cleanup,
+                                   __optr_close_fn_t closeFn, __optr_reqBuf_fn_t reqBufFn, __optr_explain_fn_t explain);
+int32_t        optrDummyOpenFn(SOperatorInfo* pOperator);
+int32_t        appendDownstream(SOperatorInfo* p, SOperatorInfo** pDownstream, int32_t num);
+void           setOperatorCompleted(SOperatorInfo* pOperator);
+void           setOperatorInfo(SOperatorInfo* pOperator, const char* name, int32_t type, bool blocking, int32_t status,
+                               void* pInfo, SExecTaskInfo* pTaskInfo);
+int32_t        optrDefaultBufFn(SOperatorInfo* pOperator);
+
+SOperatorInfo* createOperator(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, SReadHandle* pHandle, SNode* pTagCond,
+                              SNode* pTagIndexCond, const char* pUser, const char* dbname);
+void           destroyOperator(SOperatorInfo* pOperator);
+
+SOperatorInfo* extractOperatorInTree(SOperatorInfo* pOperator, int32_t type, const char* id);
+int32_t        getTableScanInfo(SOperatorInfo* pOperator, int32_t* order, int32_t* scanFlag, bool inheritUsOrder);
+int32_t        stopTableScanOperator(SOperatorInfo* pOperator, const char* pIdStr);
+int32_t        getOperatorExplainExecInfo(struct SOperatorInfo* operatorInfo, SArray* pExecInfoList);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // TDENGINE_OPERATOR_H
\ No newline at end of file
diff --git a/source/libs/executor/inc/querytask.h b/source/libs/executor/inc/querytask.h
new file mode 100644
index 0000000000..37c93fef5c
--- /dev/null
+++ b/source/libs/executor/inc/querytask.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2019 TAOS Data, Inc. 
+ *
+ * This program is free software: you can use, redistribute, and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3
+ * or later ("AGPL"), as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef TDENGINE_QUERYTASK_H
+#define TDENGINE_QUERYTASK_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define GET_TASKID(_t) (((SExecTaskInfo*)(_t))->id.str)
+
+enum {
+  // when this task starts to execute, this status will set
+      TASK_NOT_COMPLETED = 0x1u,
+
+  /* Task is over
+   * 1. this status is used in one row result query process, e.g., count/sum/first/last/ avg...etc.
+   * 2. when all data within queried time window, it is also denoted as query_completed
+   */
+      TASK_COMPLETED = 0x2u,
+};
+
+typedef struct STaskIdInfo {
+  uint64_t queryId;  // this is also a request id
+  uint64_t subplanId;
+  uint64_t templateId;
+  char*    str;
+  int32_t  vgId;
+} STaskIdInfo;
+
+typedef struct STaskCostInfo {
+  int64_t                 created;
+  int64_t                 start;
+  uint64_t                elapsedTime;
+  double                  extractListTime;
+  double                  groupIdMapTime;
+  SFileBlockLoadRecorder* pRecoder;
+} STaskCostInfo;
+
+typedef struct STaskStopInfo {
+  SRWLatch lock;
+  SArray*  pStopInfo;
+} STaskStopInfo;
+
+typedef struct {
+  STqOffsetVal        currentOffset;  // for tmq
+  SMqMetaRsp          metaRsp;        // for tmq fetching meta
+  int64_t             snapshotVer;
+//  SPackedData         submit;  // todo remove it
+  SSchemaWrapper*     schema;
+  char                tbName[TSDB_TABLE_NAME_LEN];   // this is the current scan table: todo refactor
+  int8_t              recoverStep;
+  int8_t              recoverScanFinished;
+  SQueryTableDataCond tableCond;
+  int64_t             fillHistoryVer1;
+  int64_t             fillHistoryVer2;
+  SStreamState*       pState;
+  int64_t             dataVersion;
+  int64_t             checkPointId;
+} SStreamTaskInfo;
+
+struct SExecTaskInfo {
+  STaskIdInfo           id;
+  uint32_t              status;
+  STimeWindow           window;
+  STaskCostInfo         cost;
+  int64_t               owner;  // if it is in execution
+  int32_t               code;
+  int32_t               qbufQuota;  // total available buffer (in KB) during execution query
+  int64_t               version;    // used for stream to record wal version, why not move to sschemainfo
+  SStreamTaskInfo       streamInfo;
+  SSchemaInfo           schemaInfo;
+  const char*           sql;        // query sql string
+  jmp_buf               env;        // jump to this position when error happens.
+  EOPTR_EXEC_MODEL      execModel;  // operator execution model [batch model|stream model]
+  SSubplan*             pSubplan;
+  struct SOperatorInfo* pRoot;
+  SLocalFetch           localFetch;
+  SArray*               pResultBlockList;  // result block list
+  STaskStopInfo         stopInfo;
+  SRWLatch              lock;  // secure the access of STableListInfo
+};
+
+void           buildTaskId(uint64_t taskId, uint64_t queryId, char* dst);
+SExecTaskInfo* doCreateTask(uint64_t queryId, uint64_t taskId, int32_t vgId, EOPTR_EXEC_MODEL model);
+void           doDestroyTask(SExecTaskInfo* pTaskInfo);
+bool           isTaskKilled(SExecTaskInfo* pTaskInfo);
+void           setTaskKilled(SExecTaskInfo* pTaskInfo, int32_t rspCode);
+void           setTaskStatus(SExecTaskInfo* pTaskInfo, int8_t status);
+int32_t        createExecTaskInfo(SSubplan* pPlan, SExecTaskInfo** pTaskInfo, SReadHandle* pHandle, uint64_t taskId,
+                                  int32_t vgId, char* sql, EOPTR_EXEC_MODEL model);
+int32_t        qAppendTaskStopInfo(SExecTaskInfo* pTaskInfo, SExchangeOpStopInfo* pInfo);
+SArray*        getTableListInfo(const SExecTaskInfo* pTaskInfo);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // TDENGINE_QUERYTASK_H
diff --git a/source/libs/executor/src/aggregateoperator.c b/source/libs/executor/src/aggregateoperator.c
index ec8060348d..9b463a3dee 100644
--- a/source/libs/executor/src/aggregateoperator.c
+++ b/source/libs/executor/src/aggregateoperator.c
@@ -15,24 +15,21 @@
 
 #include "filter.h"
 #include "function.h"
-#include "functionMgt.h"
 #include "os.h"
 #include "querynodes.h"
 #include "tfill.h"
 #include "tname.h"
 
+#include "executorInt.h"
+#include "index.h"
+#include "operator.h"
+#include "query.h"
+#include "querytask.h"
+#include "tcompare.h"
 #include "tdatablock.h"
 #include "tglobal.h"
-#include "tmsg.h"
-#include "ttime.h"
-
-#include "executorimpl.h"
-#include "index.h"
-#include "query.h"
-#include "tcompare.h"
 #include "thash.h"
 #include "ttypes.h"
-#include "vnode.h"
 
 typedef struct {
   bool    hasAgg;
diff --git a/source/libs/executor/src/cachescanoperator.c b/source/libs/executor/src/cachescanoperator.c
index d0f7cb08f7..fad1c55b3d 100644
--- a/source/libs/executor/src/cachescanoperator.c
+++ b/source/libs/executor/src/cachescanoperator.c
@@ -20,7 +20,9 @@
 #include "tdatablock.h"
 #include "tmsg.h"
 
-#include "executorimpl.h"
+#include "executorInt.h"
+#include "operator.h"
+#include "querytask.h"
 #include "tcompare.h"
 #include "thash.h"
 #include "ttypes.h"
diff --git a/source/libs/executor/src/dataDeleter.c b/source/libs/executor/src/dataDeleter.c
index d693faf7f1..11074b0e94 100644
--- a/source/libs/executor/src/dataDeleter.c
+++ b/source/libs/executor/src/dataDeleter.c
@@ -15,7 +15,7 @@
 
 #include "dataSinkInt.h"
 #include "dataSinkMgt.h"
-#include "executorimpl.h"
+#include "executorInt.h"
 #include "planner.h"
 #include "tcompression.h"
 #include "tdatablock.h"
@@ -179,7 +179,7 @@ static void getDataLength(SDataSinkHandle* pHandle, int64_t* pLen, bool* pQueryE
 static int32_t getDataBlock(SDataSinkHandle* pHandle, SOutputData* pOutput) {
   SDataDeleterHandle* pDeleter = (SDataDeleterHandle*)pHandle;
   if (NULL == pDeleter->nextOutput.pData) {
-    assert(pDeleter->queryEnd);
+    ASSERT(pDeleter->queryEnd);
     pOutput->useconds = pDeleter->useconds;
     pOutput->precision = pDeleter->pSchema->precision;
     pOutput->bufStatus = DS_BUF_EMPTY;
diff --git a/source/libs/executor/src/dataDispatcher.c b/source/libs/executor/src/dataDispatcher.c
index f8dcd771c0..3d5645128b 100644
--- a/source/libs/executor/src/dataDispatcher.c
+++ b/source/libs/executor/src/dataDispatcher.c
@@ -15,7 +15,7 @@
 
 #include "dataSinkInt.h"
 #include "dataSinkMgt.h"
-#include "executorimpl.h"
+#include "executorInt.h"
 #include "planner.h"
 #include "tcompression.h"
 #include "tdatablock.h"
@@ -185,7 +185,7 @@ static void getDataLength(SDataSinkHandle* pHandle, int64_t* pLen, bool* pQueryE
 static int32_t getDataBlock(SDataSinkHandle* pHandle, SOutputData* pOutput) {
   SDataDispatchHandle* pDispatcher = (SDataDispatchHandle*)pHandle;
   if (NULL == pDispatcher->nextOutput.pData) {
-    assert(pDispatcher->queryEnd);
+    ASSERT(pDispatcher->queryEnd);
     pOutput->useconds = pDispatcher->useconds;
     pOutput->precision = pDispatcher->pSchema->precision;
     pOutput->bufStatus = DS_BUF_EMPTY;
diff --git a/source/libs/executor/src/dataInserter.c b/source/libs/executor/src/dataInserter.c
index 90d740bebd..d31ac0bc51 100644
--- a/source/libs/executor/src/dataInserter.c
+++ b/source/libs/executor/src/dataInserter.c
@@ -15,7 +15,7 @@
 
 #include "dataSinkInt.h"
 #include "dataSinkMgt.h"
-#include "executorimpl.h"
+#include "executorInt.h"
 #include "planner.h"
 #include "tcompression.h"
 #include "tdatablock.h"
@@ -126,7 +126,7 @@ static int32_t submitReqToMsg(int32_t vgId, SSubmitReq2* pReq, void** pData, int
   int32_t code = TSDB_CODE_SUCCESS;
   int32_t len = 0;
   void*   pBuf = NULL;
-  tEncodeSize(tEncodeSSubmitReq2, pReq, len, code);
+  tEncodeSize(tEncodeSubmitReq, pReq, len, code);
   if (TSDB_CODE_SUCCESS == code) {
     SEncoder encoder;
     len += sizeof(SSubmitReq2Msg);
@@ -138,7 +138,7 @@ static int32_t submitReqToMsg(int32_t vgId, SSubmitReq2* pReq, void** pData, int
     ((SSubmitReq2Msg*)pBuf)->header.contLen = htonl(len);
     ((SSubmitReq2Msg*)pBuf)->version = htobe64(1);
     tEncoderInit(&encoder, POINTER_SHIFT(pBuf, sizeof(SSubmitReq2Msg)), len - sizeof(SSubmitReq2Msg));
-    code = tEncodeSSubmitReq2(&encoder, pReq);
+    code = tEncodeSubmitReq(&encoder, pReq);
     tEncoderClear(&encoder);
   }
 
@@ -281,7 +281,7 @@ int32_t buildSubmitReqFromBlock(SDataInserterHandle* pInserter, SSubmitReq2** pp
 
     SRow* pRow = NULL;
     if ((terrno = tRowBuild(pVals, pTSchema, &pRow)) < 0) {
-      tDestroySSubmitTbData(&tbData, TSDB_MSG_FLG_ENCODE);
+      tDestroySubmitTbData(&tbData, TSDB_MSG_FLG_ENCODE);
       goto _end;
     }
     taosArrayPush(tbData.aRowP, &pRow);
@@ -301,7 +301,7 @@ _end:
   if (terrno != 0) {
     *ppReq = NULL;
     if (pReq) {
-      tDestroySSubmitReq2(pReq, TSDB_MSG_FLG_ENCODE);
+      tDestroySubmitReq(pReq, TSDB_MSG_FLG_ENCODE);
       taosMemoryFree(pReq);
     }
     return terrno;
@@ -326,7 +326,7 @@ int32_t dataBlocksToSubmitReq(SDataInserterHandle* pInserter, void** pMsg, int32
     code = buildSubmitReqFromBlock(pInserter, &pReq, pDataBlock, pTSchema, uid, vgId, suid);
     if (code) {
       if (pReq) {
-        tDestroySSubmitReq2(pReq, TSDB_MSG_FLG_ENCODE);
+        tDestroySubmitReq(pReq, TSDB_MSG_FLG_ENCODE);
         taosMemoryFree(pReq);
       }
 
@@ -335,7 +335,7 @@ int32_t dataBlocksToSubmitReq(SDataInserterHandle* pInserter, void** pMsg, int32
   }
 
   code = submitReqToMsg(vgId, pReq, pMsg, msgLen);
-  tDestroySSubmitReq2(pReq, TSDB_MSG_FLG_ENCODE);
+  tDestroySubmitReq(pReq, TSDB_MSG_FLG_ENCODE);
   taosMemoryFree(pReq);
 
   return code;
diff --git a/source/libs/executor/src/eventwindowoperator.c b/source/libs/executor/src/eventwindowoperator.c
index 559fce5224..956d5b714d 100644
--- a/source/libs/executor/src/eventwindowoperator.c
+++ b/source/libs/executor/src/eventwindowoperator.c
@@ -13,10 +13,12 @@
  * along with this program. If not, see .
  */
 
-#include "executorimpl.h"
+#include "executorInt.h"
 #include "filter.h"
 #include "function.h"
 #include "functionMgt.h"
+#include "operator.h"
+#include "querytask.h"
 #include "tcommon.h"
 #include "tcompare.h"
 #include "tdatablock.h"
diff --git a/source/libs/executor/src/exchangeoperator.c b/source/libs/executor/src/exchangeoperator.c
index 326d2c43c5..b4a53be317 100644
--- a/source/libs/executor/src/exchangeoperator.c
+++ b/source/libs/executor/src/exchangeoperator.c
@@ -13,17 +13,19 @@
  * along with this program. If not, see .
  */
 
+#include "executorInt.h"
 #include "filter.h"
 #include "function.h"
+#include "index.h"
+#include "operator.h"
 #include "os.h"
+#include "query.h"
+#include "querytask.h"
+#include "tdatablock.h"
+#include "thash.h"
+#include "tmsg.h"
 #include "tname.h"
 #include "tref.h"
-#include "tdatablock.h"
-#include "tmsg.h"
-#include "executorimpl.h"
-#include "index.h"
-#include "query.h"
-#include "thash.h"
 
 typedef struct SFetchRspHandleWrapper {
   uint32_t exchangeId;
diff --git a/source/libs/executor/src/executil.c b/source/libs/executor/src/executil.c
index c265c0b003..45e8c22aac 100644
--- a/source/libs/executor/src/executil.c
+++ b/source/libs/executor/src/executil.c
@@ -24,7 +24,8 @@
 #include "ttime.h"
 
 #include "executil.h"
-#include "executorimpl.h"
+#include "executorInt.h"
+#include "querytask.h"
 #include "tcompression.h"
 
 typedef struct tagFilterAssist {
@@ -71,7 +72,6 @@ void resetResultRow(SResultRow* pResultRow, size_t entrySize) {
 
 // TODO refactor: use macro
 SResultRowEntryInfo* getResultEntryInfo(const SResultRow* pRow, int32_t index, const int32_t* offset) {
-  assert(index >= 0 && offset != NULL);
   return (SResultRowEntryInfo*)((char*)pRow->pEntryInfo + offset[index]);
 }
 
@@ -1514,14 +1514,23 @@ static int32_t setSelectValueColumnInfo(SqlFunctionCtx* pCtx, int32_t numOfOutpu
     return TSDB_CODE_OUT_OF_MEMORY;
   }
 
+  SHashObj *pSelectFuncs = taosHashInit(8, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_ENTRY_LOCK);
   for (int32_t i = 0; i < numOfOutput; ++i) {
     const char* pName = pCtx[i].pExpr->pExpr->_function.functionName;
     if ((strcmp(pName, "_select_value") == 0) || (strcmp(pName, "_group_key") == 0)) {
       pValCtx[num++] = &pCtx[i];
     } else if (fmIsSelectFunc(pCtx[i].functionId)) {
-      p = &pCtx[i];
+      void* data = taosHashGet(pSelectFuncs, pName, strlen(pName));
+      if (taosHashGetSize(pSelectFuncs) != 0 && data == NULL) {
+        p = NULL;
+        break;
+      } else {
+        taosHashPut(pSelectFuncs, pName, strlen(pName), &num, sizeof(num));
+        p = &pCtx[i];
+      }
     }
   }
+  taosHashCleanup(pSelectFuncs);
 
   if (p != NULL) {
     p->subsidiaries.pCtx = pValCtx;
diff --git a/source/libs/executor/src/executor.c b/source/libs/executor/src/executor.c
index c6f5d3912d..489c4ff650 100644
--- a/source/libs/executor/src/executor.c
+++ b/source/libs/executor/src/executor.c
@@ -14,9 +14,10 @@
  */
 
 #include "executor.h"
-#include 
-#include "executorimpl.h"
+#include "executorInt.h"
+#include "operator.h"
 #include "planner.h"
+#include "querytask.h"
 #include "tdatablock.h"
 #include "tref.h"
 #include "tudf.h"
@@ -138,7 +139,6 @@ static int32_t doSetStreamBlock(SOperatorInfo* pOperator, void* input, size_t nu
       }
       pInfo->blockType = STREAM_INPUT__DATA_SUBMIT;
     } else if (type == STREAM_INPUT__DATA_SUBMIT) {
-      ASSERT(numOfBlocks == 1);
       taosArrayPush(pInfo->pBlockLists, input);
       pInfo->blockType = STREAM_INPUT__DATA_SUBMIT;
     } else if (type == STREAM_INPUT__DATA_BLOCK) {
@@ -249,7 +249,7 @@ int32_t qSetSMAInput(qTaskInfo_t tinfo, const void* pBlocks, size_t numOfBlocks,
 qTaskInfo_t qCreateQueueExecTaskInfo(void* msg, SReadHandle* pReaderHandle, int32_t vgId, int32_t* numOfCols,
                                      uint64_t id) {
   if (msg == NULL) {  // create raw scan
-    SExecTaskInfo* pTaskInfo = doCreateExecTaskInfo(0, id, vgId, OPTR_EXEC_MODEL_QUEUE, "");
+    SExecTaskInfo* pTaskInfo = doCreateTask(0, id, vgId, OPTR_EXEC_MODEL_QUEUE);
     if (NULL == pTaskInfo) {
       terrno = TSDB_CODE_OUT_OF_MEMORY;
       return NULL;
@@ -312,7 +312,6 @@ qTaskInfo_t qCreateStreamExecTaskInfo(void* msg, SReadHandle* readers, int32_t v
   qTaskInfo_t pTaskInfo = NULL;
   code = qCreateExecTask(readers, vgId, 0, pPlan, &pTaskInfo, NULL, NULL, OPTR_EXEC_MODEL_STREAM);
   if (code != TSDB_CODE_SUCCESS) {
-    nodesDestroyNode((SNode*)pPlan);
     qDestroyTask(pTaskInfo);
     terrno = code;
     return NULL;
@@ -717,8 +716,6 @@ void qRemoveTaskStopInfo(SExecTaskInfo* pTaskInfo, SExchangeOpStopInfo* pInfo) {
     taosArrayRemove(pTaskInfo->stopInfo.pStopInfo, idx);
   }
   taosWUnLockLatch(&pTaskInfo->stopInfo.lock);
-
-  return;
 }
 
 void qStopTaskOperators(SExecTaskInfo* pTaskInfo) {
@@ -802,7 +799,11 @@ void qDestroyTask(qTaskInfo_t qTaskHandle) {
     return;
   }
 
-  qDebug("%s execTask completed, numOfRows:%" PRId64, GET_TASKID(pTaskInfo), pTaskInfo->pRoot->resultInfo.totalRows);
+  if (pTaskInfo->pRoot != NULL) {
+    qDebug("%s execTask completed, numOfRows:%" PRId64, GET_TASKID(pTaskInfo), pTaskInfo->pRoot->resultInfo.totalRows);
+  } else {
+    qDebug("%s execTask completed", GET_TASKID(pTaskInfo));
+  }
 
   printTaskExecCostInLog(pTaskInfo);  // print the query cost summary
   doDestroyTask(pTaskInfo);
@@ -855,15 +856,6 @@ int32_t qExtractStreamScanner(qTaskInfo_t tinfo, void** scanner) {
   }
 }
 
-#if 0
-int32_t qStreamInput(qTaskInfo_t tinfo, void* pItem) {
-  SExecTaskInfo* pTaskInfo = (SExecTaskInfo*)tinfo;
-  ASSERT(pTaskInfo->execModel == OPTR_EXEC_MODEL_STREAM);
-  taosWriteQitem(pTaskInfo->streamInfo.inputQueue->queue, pItem);
-  return 0;
-}
-#endif
-
 int32_t qStreamSourceRecoverStep1(qTaskInfo_t tinfo, int64_t ver) {
   SExecTaskInfo* pTaskInfo = (SExecTaskInfo*)tinfo;
   ASSERT(pTaskInfo->execModel == OPTR_EXEC_MODEL_STREAM);
@@ -898,8 +890,7 @@ int32_t qStreamSetParamForRecover(qTaskInfo_t tinfo) {
       SStreamIntervalOperatorInfo* pInfo = pOperator->info;
       ASSERT(pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE ||
              pInfo->twAggSup.calTrigger == STREAM_TRIGGER_WINDOW_CLOSE);
-      ASSERT(pInfo->twAggSup.calTriggerSaved == 0);
-      ASSERT(pInfo->twAggSup.deleteMarkSaved == 0);
+      ASSERT(pInfo->twAggSup.calTriggerSaved == 0 && pInfo->twAggSup.deleteMarkSaved == 0);
 
       qInfo("save stream param for interval: %d,  %" PRId64, pInfo->twAggSup.calTrigger, pInfo->twAggSup.deleteMark);
 
@@ -915,9 +906,8 @@ int32_t qStreamSetParamForRecover(qTaskInfo_t tinfo) {
       SStreamSessionAggOperatorInfo* pInfo = pOperator->info;
       ASSERT(pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE ||
              pInfo->twAggSup.calTrigger == STREAM_TRIGGER_WINDOW_CLOSE);
-      ASSERT(pInfo->twAggSup.calTriggerSaved == 0);
-      ASSERT(pInfo->twAggSup.deleteMarkSaved == 0);
 
+      ASSERT(pInfo->twAggSup.calTriggerSaved == 0 && pInfo->twAggSup.deleteMarkSaved == 0);
       qInfo("save stream param for session: %d,  %" PRId64, pInfo->twAggSup.calTrigger, pInfo->twAggSup.deleteMark);
 
       pInfo->twAggSup.calTriggerSaved = pInfo->twAggSup.calTrigger;
@@ -930,8 +920,7 @@ int32_t qStreamSetParamForRecover(qTaskInfo_t tinfo) {
       SStreamStateAggOperatorInfo* pInfo = pOperator->info;
       ASSERT(pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE ||
              pInfo->twAggSup.calTrigger == STREAM_TRIGGER_WINDOW_CLOSE);
-      ASSERT(pInfo->twAggSup.calTriggerSaved == 0);
-      ASSERT(pInfo->twAggSup.deleteMarkSaved == 0);
+      ASSERT(pInfo->twAggSup.calTriggerSaved == 0 && pInfo->twAggSup.deleteMarkSaved == 0);
 
       qInfo("save stream param for state: %d,  %" PRId64, pInfo->twAggSup.calTrigger, pInfo->twAggSup.deleteMark);
 
@@ -992,7 +981,6 @@ int32_t qStreamRestoreParam(qTaskInfo_t tinfo) {
     if (pOperator->numOfDownstream != 1 || pOperator->pDownstream[0] == NULL) {
       if (pOperator->numOfDownstream > 1) {
         qError("unexpected stream, multiple downstream");
-        /*ASSERT(0);*/
         return -1;
       }
       return 0;
@@ -1064,25 +1052,20 @@ int32_t initQueryTableDataCondForTmq(SQueryTableDataCond* pCond, SSnapContext* s
   return TSDB_CODE_SUCCESS;
 }
 
-int32_t qStreamSetScanMemData(qTaskInfo_t tinfo, SPackedData submit) {
-  SExecTaskInfo* pTaskInfo = (SExecTaskInfo*)tinfo;
-  if ((pTaskInfo->execModel != OPTR_EXEC_MODEL_QUEUE) || (pTaskInfo->streamInfo.submit.msgStr != NULL)) {
-    qError("qStreamSetScanMemData err:%d,%p", pTaskInfo->execModel, pTaskInfo->streamInfo.submit.msgStr);
-    terrno = TSDB_CODE_PAR_INTERNAL_ERROR;
-    return -1;
-  }
-  qDebug("set the submit block for future scan");
-
-  pTaskInfo->streamInfo.submit = submit;
-  return 0;
-}
-
 void qStreamSetOpen(qTaskInfo_t tinfo) {
   SExecTaskInfo* pTaskInfo = (SExecTaskInfo*)tinfo;
   SOperatorInfo* pOperator = pTaskInfo->pRoot;
   pOperator->status = OP_NOT_OPENED;
 }
 
+void verifyOffset(void *pWalReader, STqOffsetVal* pOffset){
+  // if offset version is small than first version , let's seek to first version
+  int64_t firstVer = walGetFirstVer(((SWalReader*)pWalReader)->pWal);
+  if (pOffset->version + 1 < firstVer){
+    pOffset->version = firstVer - 1;
+  }
+}
+
 int32_t qStreamPrepareScan(qTaskInfo_t tinfo, STqOffsetVal* pOffset, int8_t subType) {
   SExecTaskInfo* pTaskInfo = (SExecTaskInfo*)tinfo;
   SOperatorInfo* pOperator = pTaskInfo->pRoot;
@@ -1098,21 +1081,18 @@ int32_t qStreamPrepareScan(qTaskInfo_t tinfo, STqOffsetVal* pOffset, int8_t subT
     if (pOperator == NULL) {
       return -1;
     }
+
     SStreamScanInfo* pInfo = pOperator->info;
     STableScanInfo*  pScanInfo = pInfo->pTableScanOp->info;
     STableScanBase*  pScanBaseInfo = &pScanInfo->base;
     STableListInfo*  pTableListInfo = pScanBaseInfo->pTableListInfo;
 
     if (pOffset->type == TMQ_OFFSET__LOG) {
+      // todo refactor: move away
       tsdbReaderClose(pScanBaseInfo->dataReader);
       pScanBaseInfo->dataReader = NULL;
 
-      // let's seek to the next version in wal file
-      int64_t firstVer = walGetFirstVer(pInfo->tqReader->pWalReader->pWal);
-      if (pOffset->version + 1 < firstVer){
-        pOffset->version = firstVer - 1;
-      }
-
+      verifyOffset(pInfo->tqReader->pWalReader, pOffset);
       if (tqSeekVer(pInfo->tqReader, pOffset->version + 1, id) < 0) {
         qError("tqSeekVer failed ver:%" PRId64 ", %s", pOffset->version + 1, id);
         return -1;
@@ -1233,7 +1213,7 @@ int32_t qStreamPrepareScan(qTaskInfo_t tinfo, STqOffsetVal* pOffset, int8_t subT
 
       cleanupQueryTableDataCond(&pTaskInfo->streamInfo.tableCond);
       strcpy(pTaskInfo->streamInfo.tbName, mtInfo.tbName);
-      tDeleteSSchemaWrapper(pTaskInfo->streamInfo.schema);
+      tDeleteSchemaWrapper(pTaskInfo->streamInfo.schema);
       pTaskInfo->streamInfo.schema = mtInfo.schema;
 
       qDebug("tmqsnap qStreamPrepareScan snapshot data uid:%" PRId64 " ts %" PRId64 " %s", mtInfo.uid, pOffset->ts, id);
@@ -1303,3 +1283,25 @@ SArray* qGetQueriedTableListInfo(qTaskInfo_t tinfo) {
   taosArrayDestroy(plist);
   return pUidList;
 }
+
+static void extractTableList(SArray* pList, const SOperatorInfo* pOperator) {
+  if (pOperator->operatorType == QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN) {
+    SStreamScanInfo* pScanInfo = pOperator->info;
+    STableScanInfo*  pTableScanInfo = pScanInfo->pTableScanOp->info;
+    taosArrayPush(pList, &pTableScanInfo->base.pTableListInfo);
+  } else if (pOperator->operatorType == QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN) {
+    STableScanInfo* pScanInfo = pOperator->info;
+    taosArrayPush(pList, &pScanInfo->base.pTableListInfo);
+  } else {
+    if (pOperator->pDownstream != NULL && pOperator->pDownstream[0] != NULL) {
+      extractTableList(pList, pOperator->pDownstream[0]);
+    }
+  }
+}
+
+SArray* getTableListInfo(const SExecTaskInfo* pTaskInfo) {
+  SArray*        pArray = taosArrayInit(0, POINTER_BYTES);
+  SOperatorInfo* pOperator = pTaskInfo->pRoot;
+  extractTableList(pArray, pOperator);
+  return pArray;
+}
\ No newline at end of file
diff --git a/source/libs/executor/src/executorimpl.c b/source/libs/executor/src/executorInt.c
similarity index 60%
rename from source/libs/executor/src/executorimpl.c
rename to source/libs/executor/src/executorInt.c
index 7594079cfb..62ab2d9df2 100644
--- a/source/libs/executor/src/executorimpl.c
+++ b/source/libs/executor/src/executorInt.c
@@ -22,13 +22,14 @@
 #include "tname.h"
 
 #include "tdatablock.h"
-#include "tglobal.h"
 #include "tmsg.h"
 #include "ttime.h"
 
-#include "executorimpl.h"
+#include "executorInt.h"
 #include "index.h"
+#include "operator.h"
 #include "query.h"
+#include "querytask.h"
 #include "tcompare.h"
 #include "thash.h"
 #include "ttypes.h"
@@ -71,12 +72,8 @@ static UNUSED_FUNC void* u_realloc(void* p, size_t __size) {
 #define realloc u_realloc
 #endif
 
-#define CLEAR_QUERY_STATUS(q, st) ((q)->status &= (~(st)))
-
 static void setBlockSMAInfo(SqlFunctionCtx* pCtx, SExprInfo* pExpr, SSDataBlock* pBlock);
 
-static void releaseQueryBuf(size_t numOfTables);
-
 static void initCtxOutputBuffer(SqlFunctionCtx* pCtx, int32_t size);
 static void doApplyScalarCalculation(SOperatorInfo* pOperator, SSDataBlock* pBlock, int32_t order, int32_t scanFlag);
 
@@ -85,45 +82,7 @@ static void    extractQualifiedTupleByFilterResult(SSDataBlock* pBlock, const SC
 static int32_t doSetInputDataBlock(SExprSupp* pExprSup, SSDataBlock* pBlock, int32_t order, int32_t scanFlag,
                                    bool createDummyCol);
 static int32_t doCopyToSDataBlock(SExecTaskInfo* pTaskInfo, SSDataBlock* pBlock, SExprSupp* pSup, SDiskbasedBuf* pBuf,
-                                  SGroupResInfo* pGroupResInfo);
-static SSchemaWrapper* extractQueriedColumnSchema(SScanPhysiNode* pScanNode);
-
-void setOperatorCompleted(SOperatorInfo* pOperator) {
-  pOperator->status = OP_EXEC_DONE;
-  pOperator->cost.totalCost = (taosGetTimestampUs() - pOperator->pTaskInfo->cost.start) / 1000.0;
-  setTaskStatus(pOperator->pTaskInfo, TASK_COMPLETED);
-}
-
-void setOperatorInfo(SOperatorInfo* pOperator, const char* name, int32_t type, bool blocking, int32_t status,
-                     void* pInfo, SExecTaskInfo* pTaskInfo) {
-  pOperator->name = (char*)name;
-  pOperator->operatorType = type;
-  pOperator->blocking = blocking;
-  pOperator->status = status;
-  pOperator->info = pInfo;
-  pOperator->pTaskInfo = pTaskInfo;
-}
-
-int32_t optrDummyOpenFn(SOperatorInfo* pOperator) {
-  OPTR_SET_OPENED(pOperator);
-  pOperator->cost.openCost = 0;
-  return TSDB_CODE_SUCCESS;
-}
-
-SOperatorFpSet createOperatorFpSet(__optr_open_fn_t openFn, __optr_fn_t nextFn, __optr_fn_t cleanup,
-                                   __optr_close_fn_t closeFn, __optr_reqBuf_fn_t reqBufFn,
-                                   __optr_explain_fn_t explain) {
-  SOperatorFpSet fpSet = {
-      ._openFn = openFn,
-      .getNextFn = nextFn,
-      .cleanupFn = cleanup,
-      .closeFn = closeFn,
-      .reqBufFn = reqBufFn,
-      .getExplainFn = explain,
-  };
-
-  return fpSet;
-}
+                                  SGroupResInfo* pGroupResInfo, int32_t threshold);
 
 SResultRow* getNewResultRow(SDiskbasedBuf* pResultBuf, int32_t* currentPageId, int32_t interBufSize) {
   SFilePage* pData = NULL;
@@ -482,10 +441,6 @@ void setBlockSMAInfo(SqlFunctionCtx* pCtx, SExprInfo* pExprInfo, SSDataBlock* pB
   }
 }
 
-bool isTaskKilled(SExecTaskInfo* pTaskInfo) { return (0 != pTaskInfo->code); }
-
-void setTaskKilled(SExecTaskInfo* pTaskInfo, int32_t rspCode) { pTaskInfo->code = rspCode; }
-
 /////////////////////////////////////////////////////////////////////////////////////////////
 STimeWindow getAlignQueryTimeWindow(SInterval* pInterval, int32_t precision, int64_t key) {
   STimeWindow win = {0};
@@ -503,16 +458,6 @@ STimeWindow getAlignQueryTimeWindow(SInterval* pInterval, int32_t precision, int
   return win;
 }
 
-void setTaskStatus(SExecTaskInfo* pTaskInfo, int8_t status) {
-  if (status == TASK_NOT_COMPLETED) {
-    pTaskInfo->status = status;
-  } else {
-    // QUERY_NOT_COMPLETED is not compatible with any other status, so clear its position first
-    CLEAR_QUERY_STATUS(pTaskInfo, TASK_NOT_COMPLETED);
-    pTaskInfo->status |= status;
-  }
-}
-
 void setResultRowInitCtx(SResultRow* pResult, SqlFunctionCtx* pCtx, int32_t numOfOutput, int32_t* rowEntryInfoOffset) {
   bool init = false;
   for (int32_t i = 0; i < numOfOutput; ++i) {
@@ -831,7 +776,7 @@ int32_t finalizeResultRows(SDiskbasedBuf* pBuf, SResultRowPosition* resultRowPos
 }
 
 int32_t doCopyToSDataBlock(SExecTaskInfo* pTaskInfo, SSDataBlock* pBlock, SExprSupp* pSup, SDiskbasedBuf* pBuf,
-                           SGroupResInfo* pGroupResInfo) {
+                           SGroupResInfo* pGroupResInfo, int32_t threshold) {
   SExprInfo*      pExprInfo = pSup->pExprInfo;
   int32_t         numOfExprs = pSup->numOfExprs;
   int32_t*        rowEntryOffset = pSup->rowEntryInfoOffset;
@@ -880,6 +825,9 @@ int32_t doCopyToSDataBlock(SExecTaskInfo* pTaskInfo, SSDataBlock* pBlock, SExprS
 
     releaseBufPage(pBuf, page);
     pBlock->info.rows += pRow->numOfRows;
+    if (pBlock->info.rows >= threshold) {
+      break;
+    }
   }
 
   qDebug("%s result generated, rows:%" PRId64 ", groupId:%" PRIu64, GET_TASKID(pTaskInfo), pBlock->info.rows,
@@ -905,7 +853,7 @@ void doBuildStreamResBlock(SOperatorInfo* pOperator, SOptrBasicInfo* pbInfo, SGr
   // clear the existed group id
   pBlock->info.id.groupId = 0;
   ASSERT(!pbInfo->mergeResultBlock);
-  doCopyToSDataBlock(pTaskInfo, pBlock, &pOperator->exprSupp, pBuf, pGroupResInfo);
+  doCopyToSDataBlock(pTaskInfo, pBlock, &pOperator->exprSupp, pBuf, pGroupResInfo, pOperator->resultInfo.threshold);
 
   void* tbname = NULL;
   if (streamStateGetParName(pTaskInfo->streamInfo.pState, pBlock->info.id.groupId, &tbname) < 0) {
@@ -932,10 +880,10 @@ void doBuildResultDatablock(SOperatorInfo* pOperator, SOptrBasicInfo* pbInfo, SG
   // clear the existed group id
   pBlock->info.id.groupId = 0;
   if (!pbInfo->mergeResultBlock) {
-    doCopyToSDataBlock(pTaskInfo, pBlock, &pOperator->exprSupp, pBuf, pGroupResInfo);
+    doCopyToSDataBlock(pTaskInfo, pBlock, &pOperator->exprSupp, pBuf, pGroupResInfo, pOperator->resultInfo.threshold);
   } else {
     while (hasRemainResults(pGroupResInfo)) {
-      doCopyToSDataBlock(pTaskInfo, pBlock, &pOperator->exprSupp, pBuf, pGroupResInfo);
+      doCopyToSDataBlock(pTaskInfo, pBlock, &pOperator->exprSupp, pBuf, pGroupResInfo, pOperator->resultInfo.threshold);
       if (pBlock->info.rows >= pOperator->resultInfo.threshold) {
         break;
       }
@@ -949,72 +897,6 @@ void doBuildResultDatablock(SOperatorInfo* pOperator, SOptrBasicInfo* pbInfo, SG
   }
 }
 
-int32_t appendDownstream(SOperatorInfo* p, SOperatorInfo** pDownstream, int32_t num) {
-  p->pDownstream = taosMemoryCalloc(1, num * POINTER_BYTES);
-  if (p->pDownstream == NULL) {
-    return TSDB_CODE_OUT_OF_MEMORY;
-  }
-
-  memcpy(p->pDownstream, pDownstream, num * POINTER_BYTES);
-  p->numOfDownstream = num;
-  return TSDB_CODE_SUCCESS;
-}
-
-int32_t getTableScanInfo(SOperatorInfo* pOperator, int32_t* order, int32_t* scanFlag, bool inheritUsOrder) {
-  // todo add more information about exchange operation
-  int32_t type = pOperator->operatorType;
-  if (type == QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN || type == QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN ||
-      type == QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN || type == QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN ||
-      type == QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN || type == QUERY_NODE_PHYSICAL_PLAN_TABLE_COUNT_SCAN) {
-    *order = TSDB_ORDER_ASC;
-    *scanFlag = MAIN_SCAN;
-    return TSDB_CODE_SUCCESS;
-  } else if (type == QUERY_NODE_PHYSICAL_PLAN_EXCHANGE) {
-    if (!inheritUsOrder) {
-      *order = TSDB_ORDER_ASC;
-    }
-    *scanFlag = MAIN_SCAN;
-    return TSDB_CODE_SUCCESS;
-  } else if (type == QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN) {
-    STableScanInfo* pTableScanInfo = pOperator->info;
-    *order = pTableScanInfo->base.cond.order;
-    *scanFlag = pTableScanInfo->base.scanFlag;
-    return TSDB_CODE_SUCCESS;
-  } else if (type == QUERY_NODE_PHYSICAL_PLAN_TABLE_MERGE_SCAN) {
-    STableMergeScanInfo* pTableScanInfo = pOperator->info;
-    *order = pTableScanInfo->base.cond.order;
-    *scanFlag = pTableScanInfo->base.scanFlag;
-    return TSDB_CODE_SUCCESS;
-  } else {
-    if (pOperator->pDownstream == NULL || pOperator->pDownstream[0] == NULL) {
-      return TSDB_CODE_INVALID_PARA;
-    } else {
-      return getTableScanInfo(pOperator->pDownstream[0], order, scanFlag, inheritUsOrder);
-    }
-  }
-}
-
-// QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN
-SOperatorInfo* extractOperatorInTree(SOperatorInfo* pOperator, int32_t type, const char* id) {
-  if (pOperator == NULL) {
-    qError("invalid operator, failed to find tableScanOperator %s", id);
-    terrno = TSDB_CODE_PAR_INTERNAL_ERROR;
-    return NULL;
-  }
-
-  if (pOperator->operatorType == type) {
-    return pOperator;
-  } else {
-    if (pOperator->pDownstream == NULL || pOperator->pDownstream[0] == NULL) {
-      qError("invalid operator, failed to find tableScanOperator %s", id);
-      terrno = TSDB_CODE_PAR_INTERNAL_ERROR;
-      return NULL;
-    }
-
-    return extractOperatorInTree(pOperator->pDownstream[0], type, id);
-  }
-}
-
 void destroyExprInfo(SExprInfo* pExpr, int32_t numOfExprs) {
   for (int32_t i = 0; i < numOfExprs; ++i) {
     SExprInfo* pExprInfo = &pExpr[i];
@@ -1031,37 +913,6 @@ void destroyExprInfo(SExprInfo* pExpr, int32_t numOfExprs) {
   }
 }
 
-void destroyOperatorInfo(SOperatorInfo* pOperator) {
-  if (pOperator == NULL) {
-    return;
-  }
-
-  if (pOperator->fpSet.closeFn != NULL) {
-    pOperator->fpSet.closeFn(pOperator->info);
-  }
-
-  if (pOperator->pDownstream != NULL) {
-    for (int32_t i = 0; i < pOperator->numOfDownstream; ++i) {
-      destroyOperatorInfo(pOperator->pDownstream[i]);
-    }
-
-    taosMemoryFreeClear(pOperator->pDownstream);
-    pOperator->numOfDownstream = 0;
-  }
-
-  cleanupExprSupp(&pOperator->exprSupp);
-  taosMemoryFreeClear(pOperator);
-}
-
-// each operator should be set their own function to return total cost buffer
-int32_t optrDefaultBufFn(SOperatorInfo* pOperator) {
-  if (pOperator->blocking) {
-    return -1;
-  } else {
-    return 0;
-  }
-}
-
 int32_t getBufferPgSize(int32_t rowSize, uint32_t* defaultPgsz, uint32_t* defaultBufsz) {
   *defaultPgsz = 4096;
   while (*defaultPgsz < rowSize * 4) {
@@ -1151,136 +1002,6 @@ void cleanupExprSupp(SExprSupp* pSupp) {
 
 void cleanupBasicInfo(SOptrBasicInfo* pInfo) { pInfo->pRes = blockDataDestroy(pInfo->pRes); }
 
-void buildTaskId(uint64_t taskId, uint64_t queryId, char* dst) {
-  char* p = dst;
-
-  int32_t offset = 6;
-  memcpy(p, "TID:0x", offset);
-  offset += tintToHex(taskId, &p[offset]);
-
-  memcpy(&p[offset], " QID:0x", 7);
-  offset += 7;
-  offset += tintToHex(queryId, &p[offset]);
-
-  p[offset] = 0;
-}
-
-SExecTaskInfo* doCreateExecTaskInfo(uint64_t queryId, uint64_t taskId, int32_t vgId, EOPTR_EXEC_MODEL model,
-                                    char* dbFName) {
-  SExecTaskInfo* pTaskInfo = taosMemoryCalloc(1, sizeof(SExecTaskInfo));
-  if (pTaskInfo == NULL) {
-    terrno = TSDB_CODE_OUT_OF_MEMORY;
-    return NULL;
-  }
-
-  setTaskStatus(pTaskInfo, TASK_NOT_COMPLETED);
-  pTaskInfo->cost.created = taosGetTimestampUs();
-
-  pTaskInfo->schemaInfo.dbname = taosStrdup(dbFName);
-  pTaskInfo->execModel = model;
-  pTaskInfo->stopInfo.pStopInfo = taosArrayInit(4, sizeof(SExchangeOpStopInfo));
-  pTaskInfo->pResultBlockList = taosArrayInit(128, POINTER_BYTES);
-
-  taosInitRWLatch(&pTaskInfo->lock);
-  pTaskInfo->id.vgId = vgId;
-  pTaskInfo->id.queryId = queryId;
-
-  pTaskInfo->id.str = taosMemoryMalloc(64);
-  buildTaskId(taskId, queryId, pTaskInfo->id.str);
-  return pTaskInfo;
-}
-
-int32_t extractTableSchemaInfo(SReadHandle* pHandle, SScanPhysiNode* pScanNode, SExecTaskInfo* pTaskInfo) {
-  SMetaReader mr = {0};
-  if (pHandle == NULL) {
-    terrno = TSDB_CODE_INVALID_PARA;
-    return terrno;
-  }
-
-  metaReaderInit(&mr, pHandle->meta, 0);
-  int32_t code = metaGetTableEntryByUidCache(&mr, pScanNode->uid);
-  if (code != TSDB_CODE_SUCCESS) {
-    qError("failed to get the table meta, uid:0x%" PRIx64 ", suid:0x%" PRIx64 ", %s", pScanNode->uid, pScanNode->suid,
-           GET_TASKID(pTaskInfo));
-
-    metaReaderClear(&mr);
-    return terrno;
-  }
-
-  SSchemaInfo* pSchemaInfo = &pTaskInfo->schemaInfo;
-  pSchemaInfo->tablename = taosStrdup(mr.me.name);
-
-  if (mr.me.type == TSDB_SUPER_TABLE) {
-    pSchemaInfo->sw = tCloneSSchemaWrapper(&mr.me.stbEntry.schemaRow);
-    pSchemaInfo->tversion = mr.me.stbEntry.schemaTag.version;
-  } else if (mr.me.type == TSDB_CHILD_TABLE) {
-    tDecoderClear(&mr.coder);
-
-    tb_uid_t suid = mr.me.ctbEntry.suid;
-    code = metaGetTableEntryByUidCache(&mr, suid);
-    if (code != TSDB_CODE_SUCCESS) {
-      metaReaderClear(&mr);
-      return terrno;
-    }
-
-    pSchemaInfo->sw = tCloneSSchemaWrapper(&mr.me.stbEntry.schemaRow);
-    pSchemaInfo->tversion = mr.me.stbEntry.schemaTag.version;
-  } else {
-    pSchemaInfo->sw = tCloneSSchemaWrapper(&mr.me.ntbEntry.schemaRow);
-  }
-
-  metaReaderClear(&mr);
-
-  pSchemaInfo->qsw = extractQueriedColumnSchema(pScanNode);
-  return TSDB_CODE_SUCCESS;
-}
-
-SSchemaWrapper* extractQueriedColumnSchema(SScanPhysiNode* pScanNode) {
-  int32_t numOfCols = LIST_LENGTH(pScanNode->pScanCols);
-  int32_t numOfTags = LIST_LENGTH(pScanNode->pScanPseudoCols);
-
-  SSchemaWrapper* pqSw = taosMemoryCalloc(1, sizeof(SSchemaWrapper));
-  pqSw->pSchema = taosMemoryCalloc(numOfCols + numOfTags, sizeof(SSchema));
-
-  for (int32_t i = 0; i < numOfCols; ++i) {
-    STargetNode* pNode = (STargetNode*)nodesListGetNode(pScanNode->pScanCols, i);
-    SColumnNode* pColNode = (SColumnNode*)pNode->pExpr;
-
-    SSchema* pSchema = &pqSw->pSchema[pqSw->nCols++];
-    pSchema->colId = pColNode->colId;
-    pSchema->type = pColNode->node.resType.type;
-    pSchema->bytes = pColNode->node.resType.bytes;
-    tstrncpy(pSchema->name, pColNode->colName, tListLen(pSchema->name));
-  }
-
-  // this the tags and pseudo function columns, we only keep the tag columns
-  for (int32_t i = 0; i < numOfTags; ++i) {
-    STargetNode* pNode = (STargetNode*)nodesListGetNode(pScanNode->pScanPseudoCols, i);
-
-    int32_t type = nodeType(pNode->pExpr);
-    if (type == QUERY_NODE_COLUMN) {
-      SColumnNode* pColNode = (SColumnNode*)pNode->pExpr;
-
-      SSchema* pSchema = &pqSw->pSchema[pqSw->nCols++];
-      pSchema->colId = pColNode->colId;
-      pSchema->type = pColNode->node.resType.type;
-      pSchema->bytes = pColNode->node.resType.bytes;
-      tstrncpy(pSchema->name, pColNode->colName, tListLen(pSchema->name));
-    }
-  }
-
-  return pqSw;
-}
-
-static void cleanupTableSchemaInfo(SSchemaInfo* pSchemaInfo) {
-  taosMemoryFreeClear(pSchemaInfo->dbname);
-  taosMemoryFreeClear(pSchemaInfo->tablename);
-  tDeleteSSchemaWrapper(pSchemaInfo->sw);
-  tDeleteSSchemaWrapper(pSchemaInfo->qsw);
-}
-
-static void cleanupStreamInfo(SStreamTaskInfo* pStreamInfo) { tDeleteSSchemaWrapper(pStreamInfo->schema); }
-
 bool groupbyTbname(SNodeList* pGroupList) {
   bool bytbname = false;
   if (LIST_LENGTH(pGroupList) == 1) {
@@ -1294,306 +1015,6 @@ bool groupbyTbname(SNodeList* pGroupList) {
   return bytbname;
 }
 
-SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, SReadHandle* pHandle, SNode* pTagCond,
-                                  SNode* pTagIndexCond, const char* pUser) {
-  int32_t     type = nodeType(pPhyNode);
-  const char* idstr = GET_TASKID(pTaskInfo);
-
-  if (pPhyNode->pChildren == NULL || LIST_LENGTH(pPhyNode->pChildren) == 0) {
-    SOperatorInfo* pOperator = NULL;
-    if (QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN == type) {
-      STableScanPhysiNode* pTableScanNode = (STableScanPhysiNode*)pPhyNode;
-
-      // NOTE: this is an patch to fix the physical plan
-      // TODO remove it later
-      if (pTableScanNode->scan.node.pLimit != NULL) {
-        pTableScanNode->groupSort = true;
-      }
-
-      STableListInfo* pTableListInfo = tableListCreate();
-      int32_t         code =
-          createScanTableListInfo(&pTableScanNode->scan, pTableScanNode->pGroupTags, pTableScanNode->groupSort, pHandle,
-                                  pTableListInfo, pTagCond, pTagIndexCond, pTaskInfo);
-      if (code) {
-        pTaskInfo->code = code;
-        tableListDestroy(pTableListInfo);
-        qError("failed to createScanTableListInfo, code:%s, %s", tstrerror(code), idstr);
-        return NULL;
-      }
-
-      code = extractTableSchemaInfo(pHandle, &pTableScanNode->scan, pTaskInfo);
-      if (code) {
-        pTaskInfo->code = terrno;
-        tableListDestroy(pTableListInfo);
-        return NULL;
-      }
-
-      pOperator = createTableScanOperatorInfo(pTableScanNode, pHandle, pTableListInfo, pTaskInfo);
-      if (NULL == pOperator) {
-        pTaskInfo->code = terrno;
-        return NULL;
-      }
-
-      STableScanInfo* pScanInfo = pOperator->info;
-      pTaskInfo->cost.pRecoder = &pScanInfo->base.readRecorder;
-    } else if (QUERY_NODE_PHYSICAL_PLAN_TABLE_MERGE_SCAN == type) {
-      STableMergeScanPhysiNode* pTableScanNode = (STableMergeScanPhysiNode*)pPhyNode;
-      STableListInfo*           pTableListInfo = tableListCreate();
-
-      int32_t code = createScanTableListInfo(&pTableScanNode->scan, pTableScanNode->pGroupTags, true, pHandle,
-                                             pTableListInfo, pTagCond, pTagIndexCond, pTaskInfo);
-      if (code) {
-        pTaskInfo->code = code;
-        tableListDestroy(pTableListInfo);
-        qError("failed to createScanTableListInfo, code: %s", tstrerror(code));
-        return NULL;
-      }
-
-      code = extractTableSchemaInfo(pHandle, &pTableScanNode->scan, pTaskInfo);
-      if (code) {
-        pTaskInfo->code = terrno;
-        tableListDestroy(pTableListInfo);
-        return NULL;
-      }
-
-      pOperator = createTableMergeScanOperatorInfo(pTableScanNode, pHandle, pTableListInfo, pTaskInfo);
-      if (NULL == pOperator) {
-        pTaskInfo->code = terrno;
-        tableListDestroy(pTableListInfo);
-        return NULL;
-      }
-
-      STableScanInfo* pScanInfo = pOperator->info;
-      pTaskInfo->cost.pRecoder = &pScanInfo->base.readRecorder;
-    } else if (QUERY_NODE_PHYSICAL_PLAN_EXCHANGE == type) {
-      pOperator = createExchangeOperatorInfo(pHandle ? pHandle->pMsgCb->clientRpc : NULL, (SExchangePhysiNode*)pPhyNode,
-                                             pTaskInfo);
-    } else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN == type) {
-      STableScanPhysiNode* pTableScanNode = (STableScanPhysiNode*)pPhyNode;
-      STableListInfo*      pTableListInfo = tableListCreate();
-
-      if (pHandle->vnode) {
-        int32_t code =
-            createScanTableListInfo(&pTableScanNode->scan, pTableScanNode->pGroupTags, pTableScanNode->groupSort,
-                                    pHandle, pTableListInfo, pTagCond, pTagIndexCond, pTaskInfo);
-        if (code) {
-          pTaskInfo->code = code;
-          tableListDestroy(pTableListInfo);
-          qError("failed to createScanTableListInfo, code: %s", tstrerror(code));
-          return NULL;
-        }
-      }
-
-      pTaskInfo->schemaInfo.qsw = extractQueriedColumnSchema(&pTableScanNode->scan);
-      pOperator = createStreamScanOperatorInfo(pHandle, pTableScanNode, pTagCond, pTableListInfo, pTaskInfo);
-    } else if (QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN == type) {
-      SSystemTableScanPhysiNode* pSysScanPhyNode = (SSystemTableScanPhysiNode*)pPhyNode;
-      pOperator = createSysTableScanOperatorInfo(pHandle, pSysScanPhyNode, pUser, pTaskInfo);
-    } else if (QUERY_NODE_PHYSICAL_PLAN_TABLE_COUNT_SCAN == type) {
-      STableCountScanPhysiNode* pTblCountScanNode = (STableCountScanPhysiNode*)pPhyNode;
-      pOperator = createTableCountScanOperatorInfo(pHandle, pTblCountScanNode, pTaskInfo);
-    } else if (QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN == type) {
-      STagScanPhysiNode* pScanPhyNode = (STagScanPhysiNode*)pPhyNode;
-      STableListInfo*    pTableListInfo = tableListCreate();
-      int32_t            code = createScanTableListInfo(pScanPhyNode, NULL, false, pHandle, pTableListInfo, pTagCond,
-                                                        pTagIndexCond, pTaskInfo);
-      if (code != TSDB_CODE_SUCCESS) {
-        pTaskInfo->code = code;
-        qError("failed to getTableList, code: %s", tstrerror(code));
-        return NULL;
-      }
-
-      pOperator = createTagScanOperatorInfo(pHandle, pScanPhyNode, pTableListInfo, pTaskInfo);
-    } else if (QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN == type) {
-      SBlockDistScanPhysiNode* pBlockNode = (SBlockDistScanPhysiNode*)pPhyNode;
-      STableListInfo*          pTableListInfo = tableListCreate();
-
-      if (pBlockNode->tableType == TSDB_SUPER_TABLE) {
-        SArray* pList = taosArrayInit(4, sizeof(STableKeyInfo));
-        int32_t code = vnodeGetAllTableList(pHandle->vnode, pBlockNode->uid, pList);
-        if (code != TSDB_CODE_SUCCESS) {
-          pTaskInfo->code = terrno;
-          return NULL;
-        }
-
-        size_t num = taosArrayGetSize(pList);
-        for (int32_t i = 0; i < num; ++i) {
-          STableKeyInfo* p = taosArrayGet(pList, i);
-          tableListAddTableInfo(pTableListInfo, p->uid, 0);
-        }
-
-        taosArrayDestroy(pList);
-      } else {  // Create group with only one table
-        tableListAddTableInfo(pTableListInfo, pBlockNode->uid, 0);
-      }
-
-      pOperator = createDataBlockInfoScanOperator(pHandle, pBlockNode, pTableListInfo, pTaskInfo);
-    } else if (QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN == type) {
-      SLastRowScanPhysiNode* pScanNode = (SLastRowScanPhysiNode*)pPhyNode;
-      STableListInfo*        pTableListInfo = tableListCreate();
-
-      int32_t code = createScanTableListInfo(&pScanNode->scan, pScanNode->pGroupTags, true, pHandle, pTableListInfo,
-                                             pTagCond, pTagIndexCond, pTaskInfo);
-      if (code != TSDB_CODE_SUCCESS) {
-        pTaskInfo->code = code;
-        return NULL;
-      }
-
-      code = extractTableSchemaInfo(pHandle, &pScanNode->scan, pTaskInfo);
-      if (code != TSDB_CODE_SUCCESS) {
-        pTaskInfo->code = code;
-        return NULL;
-      }
-
-      pOperator = createCacherowsScanOperator(pScanNode, pHandle, pTableListInfo, pTaskInfo);
-    } else if (QUERY_NODE_PHYSICAL_PLAN_PROJECT == type) {
-      pOperator = createProjectOperatorInfo(NULL, (SProjectPhysiNode*)pPhyNode, pTaskInfo);
-    } else {
-      terrno = TSDB_CODE_INVALID_PARA;
-      return NULL;
-    }
-
-    if (pOperator != NULL) {  // todo moved away
-      pOperator->resultDataBlockId = pPhyNode->pOutputDataBlockDesc->dataBlockId;
-    }
-
-    return pOperator;
-  }
-
-  size_t          size = LIST_LENGTH(pPhyNode->pChildren);
-  SOperatorInfo** ops = taosMemoryCalloc(size, POINTER_BYTES);
-  if (ops == NULL) {
-    return NULL;
-  }
-
-  for (int32_t i = 0; i < size; ++i) {
-    SPhysiNode* pChildNode = (SPhysiNode*)nodesListGetNode(pPhyNode->pChildren, i);
-    ops[i] = createOperatorTree(pChildNode, pTaskInfo, pHandle, pTagCond, pTagIndexCond, pUser);
-    if (ops[i] == NULL) {
-      taosMemoryFree(ops);
-      return NULL;
-    }
-  }
-
-  SOperatorInfo* pOptr = NULL;
-  if (QUERY_NODE_PHYSICAL_PLAN_PROJECT == type) {
-    pOptr = createProjectOperatorInfo(ops[0], (SProjectPhysiNode*)pPhyNode, pTaskInfo);
-  } else if (QUERY_NODE_PHYSICAL_PLAN_HASH_AGG == type) {
-    SAggPhysiNode* pAggNode = (SAggPhysiNode*)pPhyNode;
-    if (pAggNode->pGroupKeys != NULL) {
-      pOptr = createGroupOperatorInfo(ops[0], pAggNode, pTaskInfo);
-    } else {
-      pOptr = createAggregateOperatorInfo(ops[0], pAggNode, pTaskInfo);
-    }
-  } else if (QUERY_NODE_PHYSICAL_PLAN_HASH_INTERVAL == type) {
-    SIntervalPhysiNode* pIntervalPhyNode = (SIntervalPhysiNode*)pPhyNode;
-    pOptr = createIntervalOperatorInfo(ops[0], pIntervalPhyNode, pTaskInfo);
-  } else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL == type) {
-    pOptr = createStreamIntervalOperatorInfo(ops[0], pPhyNode, pTaskInfo);
-  } else if (QUERY_NODE_PHYSICAL_PLAN_MERGE_ALIGNED_INTERVAL == type) {
-    SMergeAlignedIntervalPhysiNode* pIntervalPhyNode = (SMergeAlignedIntervalPhysiNode*)pPhyNode;
-    pOptr = createMergeAlignedIntervalOperatorInfo(ops[0], pIntervalPhyNode, pTaskInfo);
-  } else if (QUERY_NODE_PHYSICAL_PLAN_MERGE_INTERVAL == type) {
-    SMergeIntervalPhysiNode* pIntervalPhyNode = (SMergeIntervalPhysiNode*)pPhyNode;
-    pOptr = createMergeIntervalOperatorInfo(ops[0], pIntervalPhyNode, pTaskInfo);
-  } else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL == type) {
-    int32_t children = 0;
-    pOptr = createStreamFinalIntervalOperatorInfo(ops[0], pPhyNode, pTaskInfo, children);
-  } else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_INTERVAL == type) {
-    int32_t children = pHandle->numOfVgroups;
-    pOptr = createStreamFinalIntervalOperatorInfo(ops[0], pPhyNode, pTaskInfo, children);
-  } else if (QUERY_NODE_PHYSICAL_PLAN_SORT == type) {
-    pOptr = createSortOperatorInfo(ops[0], (SSortPhysiNode*)pPhyNode, pTaskInfo);
-  } else if (QUERY_NODE_PHYSICAL_PLAN_GROUP_SORT == type) {
-    pOptr = createGroupSortOperatorInfo(ops[0], (SGroupSortPhysiNode*)pPhyNode, pTaskInfo);
-  } else if (QUERY_NODE_PHYSICAL_PLAN_MERGE == type) {
-    SMergePhysiNode* pMergePhyNode = (SMergePhysiNode*)pPhyNode;
-    pOptr = createMultiwayMergeOperatorInfo(ops, size, pMergePhyNode, pTaskInfo);
-  } else if (QUERY_NODE_PHYSICAL_PLAN_MERGE_SESSION == type) {
-    SSessionWinodwPhysiNode* pSessionNode = (SSessionWinodwPhysiNode*)pPhyNode;
-    pOptr = createSessionAggOperatorInfo(ops[0], pSessionNode, pTaskInfo);
-  } else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_SESSION == type) {
-    pOptr = createStreamSessionAggOperatorInfo(ops[0], pPhyNode, pTaskInfo);
-  } else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_SESSION == type) {
-    int32_t children = 0;
-    pOptr = createStreamFinalSessionAggOperatorInfo(ops[0], pPhyNode, pTaskInfo, children);
-  } else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_SESSION == type) {
-    int32_t children = pHandle->numOfVgroups;
-    pOptr = createStreamFinalSessionAggOperatorInfo(ops[0], pPhyNode, pTaskInfo, children);
-  } else if (QUERY_NODE_PHYSICAL_PLAN_PARTITION == type) {
-    pOptr = createPartitionOperatorInfo(ops[0], (SPartitionPhysiNode*)pPhyNode, pTaskInfo);
-  } else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_PARTITION == type) {
-    pOptr = createStreamPartitionOperatorInfo(ops[0], (SStreamPartitionPhysiNode*)pPhyNode, pTaskInfo);
-  } else if (QUERY_NODE_PHYSICAL_PLAN_MERGE_STATE == type) {
-    SStateWinodwPhysiNode* pStateNode = (SStateWinodwPhysiNode*)pPhyNode;
-    pOptr = createStatewindowOperatorInfo(ops[0], pStateNode, pTaskInfo);
-  } else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_STATE == type) {
-    pOptr = createStreamStateAggOperatorInfo(ops[0], pPhyNode, pTaskInfo);
-  } else if (QUERY_NODE_PHYSICAL_PLAN_MERGE_JOIN == type) {
-    pOptr = createMergeJoinOperatorInfo(ops, size, (SSortMergeJoinPhysiNode*)pPhyNode, pTaskInfo);
-  } else if (QUERY_NODE_PHYSICAL_PLAN_FILL == type) {
-    pOptr = createFillOperatorInfo(ops[0], (SFillPhysiNode*)pPhyNode, pTaskInfo);
-  } else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_FILL == type) {
-    pOptr = createStreamFillOperatorInfo(ops[0], (SStreamFillPhysiNode*)pPhyNode, pTaskInfo);
-  } else if (QUERY_NODE_PHYSICAL_PLAN_INDEF_ROWS_FUNC == type) {
-    pOptr = createIndefinitOutputOperatorInfo(ops[0], pPhyNode, pTaskInfo);
-  } else if (QUERY_NODE_PHYSICAL_PLAN_INTERP_FUNC == type) {
-    pOptr = createTimeSliceOperatorInfo(ops[0], pPhyNode, pTaskInfo);
-  } else if (QUERY_NODE_PHYSICAL_PLAN_MERGE_EVENT == type) {
-    pOptr = createEventwindowOperatorInfo(ops[0], pPhyNode, pTaskInfo);
-  } else {
-    terrno = TSDB_CODE_INVALID_PARA;
-    taosMemoryFree(ops);
-    return NULL;
-  }
-
-  taosMemoryFree(ops);
-  if (pOptr) {
-    pOptr->resultDataBlockId = pPhyNode->pOutputDataBlockDesc->dataBlockId;
-  }
-
-  return pOptr;
-}
-
-static int32_t extractTbscanInStreamOpTree(SOperatorInfo* pOperator, STableScanInfo** ppInfo) {
-  if (pOperator->operatorType != QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN) {
-    if (pOperator->numOfDownstream == 0) {
-      qError("failed to find stream scan operator");
-      return TSDB_CODE_APP_ERROR;
-    }
-
-    if (pOperator->numOfDownstream > 1) {
-      qError("join not supported for stream block scan");
-      return TSDB_CODE_APP_ERROR;
-    }
-    return extractTbscanInStreamOpTree(pOperator->pDownstream[0], ppInfo);
-  } else {
-    SStreamScanInfo* pInfo = pOperator->info;
-    *ppInfo = pInfo->pTableScanOp->info;
-    return 0;
-  }
-}
-
-int32_t extractTableScanNode(SPhysiNode* pNode, STableScanPhysiNode** ppNode) {
-  if (pNode->pChildren == NULL || LIST_LENGTH(pNode->pChildren) == 0) {
-    if (QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN == pNode->type) {
-      *ppNode = (STableScanPhysiNode*)pNode;
-      return 0;
-    } else {
-      terrno = TSDB_CODE_APP_ERROR;
-      return -1;
-    }
-  } else {
-    if (LIST_LENGTH(pNode->pChildren) != 1) {
-      terrno = TSDB_CODE_APP_ERROR;
-      return -1;
-    }
-    SPhysiNode* pChildNode = (SPhysiNode*)nodesListGetNode(pNode->pChildren, 0);
-    return extractTableScanNode(pChildNode, ppNode);
-  }
-  return -1;
-}
-
 int32_t createDataSinkParam(SDataSinkNode* pNode, void** pParam, SExecTaskInfo* pTask, SReadHandle* readHandle) {
   switch (pNode->type) {
     case QUERY_NODE_PHYSICAL_PLAN_QUERY_INSERT: {
@@ -1641,131 +1062,6 @@ int32_t createDataSinkParam(SDataSinkNode* pNode, void** pParam, SExecTaskInfo*
   return TSDB_CODE_SUCCESS;
 }
 
-int32_t createExecTaskInfo(SSubplan* pPlan, SExecTaskInfo** pTaskInfo, SReadHandle* pHandle, uint64_t taskId,
-                           int32_t vgId, char* sql, EOPTR_EXEC_MODEL model) {
-  *pTaskInfo = doCreateExecTaskInfo(pPlan->id.queryId, taskId, vgId, model, pPlan->dbFName);
-  if (*pTaskInfo == NULL) {
-    goto _complete;
-  }
-
-  if (pHandle) {
-    if (pHandle->pStateBackend) {
-      (*pTaskInfo)->streamInfo.pState = pHandle->pStateBackend;
-    }
-  }
-
-  (*pTaskInfo)->sql = sql;
-  sql = NULL;
-
-  (*pTaskInfo)->pSubplan = pPlan;
-  (*pTaskInfo)->pRoot =
-      createOperatorTree(pPlan->pNode, *pTaskInfo, pHandle, pPlan->pTagCond, pPlan->pTagIndexCond, pPlan->user);
-
-  if (NULL == (*pTaskInfo)->pRoot) {
-    terrno = (*pTaskInfo)->code;
-    goto _complete;
-  }
-
-  return TSDB_CODE_SUCCESS;
-
-_complete:
-  taosMemoryFree(sql);
-  doDestroyTask(*pTaskInfo);
-  return terrno;
-}
-
-static void freeBlock(void* pParam) {
-  SSDataBlock* pBlock = *(SSDataBlock**)pParam;
-  blockDataDestroy(pBlock);
-}
-
-void doDestroyTask(SExecTaskInfo* pTaskInfo) {
-  qDebug("%s execTask is freed", GET_TASKID(pTaskInfo));
-  destroyOperatorInfo(pTaskInfo->pRoot);
-  cleanupTableSchemaInfo(&pTaskInfo->schemaInfo);
-  cleanupStreamInfo(&pTaskInfo->streamInfo);
-
-  if (!pTaskInfo->localFetch.localExec) {
-    nodesDestroyNode((SNode*)pTaskInfo->pSubplan);
-  }
-
-  taosArrayDestroyEx(pTaskInfo->pResultBlockList, freeBlock);
-  taosArrayDestroy(pTaskInfo->stopInfo.pStopInfo);
-  taosMemoryFreeClear(pTaskInfo->sql);
-  taosMemoryFreeClear(pTaskInfo->id.str);
-  taosMemoryFreeClear(pTaskInfo);
-}
-
-static int64_t getQuerySupportBufSize(size_t numOfTables) {
-  size_t s1 = sizeof(STableQueryInfo);
-  //  size_t s3 = sizeof(STableCheckInfo);  buffer consumption in tsdb
-  return (int64_t)(s1 * 1.5 * numOfTables);
-}
-
-int32_t checkForQueryBuf(size_t numOfTables) {
-  int64_t t = getQuerySupportBufSize(numOfTables);
-  if (tsQueryBufferSizeBytes < 0) {
-    return TSDB_CODE_SUCCESS;
-  } else if (tsQueryBufferSizeBytes > 0) {
-    while (1) {
-      int64_t s = tsQueryBufferSizeBytes;
-      int64_t remain = s - t;
-      if (remain >= 0) {
-        if (atomic_val_compare_exchange_64(&tsQueryBufferSizeBytes, s, remain) == s) {
-          return TSDB_CODE_SUCCESS;
-        }
-      } else {
-        return TSDB_CODE_QRY_NOT_ENOUGH_BUFFER;
-      }
-    }
-  }
-
-  // disable query processing if the value of tsQueryBufferSize is zero.
-  return TSDB_CODE_QRY_NOT_ENOUGH_BUFFER;
-}
-
-void releaseQueryBuf(size_t numOfTables) {
-  if (tsQueryBufferSizeBytes < 0) {
-    return;
-  }
-
-  int64_t t = getQuerySupportBufSize(numOfTables);
-
-  // restore value is not enough buffer available
-  atomic_add_fetch_64(&tsQueryBufferSizeBytes, t);
-}
-
-int32_t getOperatorExplainExecInfo(SOperatorInfo* operatorInfo, SArray* pExecInfoList) {
-  SExplainExecInfo  execInfo = {0};
-  SExplainExecInfo* pExplainInfo = taosArrayPush(pExecInfoList, &execInfo);
-
-  pExplainInfo->numOfRows = operatorInfo->resultInfo.totalRows;
-  pExplainInfo->startupCost = operatorInfo->cost.openCost;
-  pExplainInfo->totalCost = operatorInfo->cost.totalCost;
-  pExplainInfo->verboseLen = 0;
-  pExplainInfo->verboseInfo = NULL;
-
-  if (operatorInfo->fpSet.getExplainFn) {
-    int32_t code =
-        operatorInfo->fpSet.getExplainFn(operatorInfo, &pExplainInfo->verboseInfo, &pExplainInfo->verboseLen);
-    if (code) {
-      qError("%s operator getExplainFn failed, code:%s", GET_TASKID(operatorInfo->pTaskInfo), tstrerror(code));
-      return code;
-    }
-  }
-
-  int32_t code = 0;
-  for (int32_t i = 0; i < operatorInfo->numOfDownstream; ++i) {
-    code = getOperatorExplainExecInfo(operatorInfo->pDownstream[i], pExecInfoList);
-    if (code != TSDB_CODE_SUCCESS) {
-      //      taosMemoryFreeClear(*pRes);
-      return TSDB_CODE_OUT_OF_MEMORY;
-    }
-  }
-
-  return TSDB_CODE_SUCCESS;
-}
-
 int32_t setOutputBuf(SStreamState* pState, STimeWindow* win, SResultRow** pResult, int64_t tableGroupId,
                      SqlFunctionCtx* pCtx, int32_t numOfOutput, int32_t* rowEntryInfoOffset, SAggSupporter* pAggSup) {
   SWinKey key = {
@@ -2007,25 +1303,3 @@ void qStreamCloseTsdbReader(void* task) {
     }
   }
 }
-
-static void extractTableList(SArray* pList, const SOperatorInfo* pOperator) {
-  if (pOperator->operatorType == QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN) {
-    SStreamScanInfo* pScanInfo = pOperator->info;
-    STableScanInfo*  pTableScanInfo = pScanInfo->pTableScanOp->info;
-    taosArrayPush(pList, &pTableScanInfo->base.pTableListInfo);
-  } else if (pOperator->operatorType == QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN) {
-    STableScanInfo* pScanInfo = pOperator->info;
-    taosArrayPush(pList, &pScanInfo->base.pTableListInfo);
-  } else {
-    if (pOperator->pDownstream != NULL && pOperator->pDownstream[0] != NULL) {
-      extractTableList(pList, pOperator->pDownstream[0]);
-    }
-  }
-}
-
-SArray* getTableListInfo(const SExecTaskInfo* pTaskInfo) {
-  SArray*        pArray = taosArrayInit(0, POINTER_BYTES);
-  SOperatorInfo* pOperator = pTaskInfo->pRoot;
-  extractTableList(pArray, pOperator);
-  return pArray;
-}
\ No newline at end of file
diff --git a/source/libs/executor/src/filloperator.c b/source/libs/executor/src/filloperator.c
index 234f1a666c..0ac9e6097f 100644
--- a/source/libs/executor/src/filloperator.c
+++ b/source/libs/executor/src/filloperator.c
@@ -20,16 +20,18 @@
 #include "tmsg.h"
 #include "ttypes.h"
 
-#include "executorimpl.h"
+#include "executorInt.h"
 #include "tcommon.h"
 #include "thash.h"
 #include "ttime.h"
 
-#include "executorInt.h"
 #include "function.h"
 #include "querynodes.h"
 #include "tdatablock.h"
 #include "tfill.h"
+#include "operator.h"
+#include "querytask.h"
+
 
 #define FILL_POS_INVALID 0
 #define FILL_POS_START   1
diff --git a/source/libs/executor/src/groupoperator.c b/source/libs/executor/src/groupoperator.c
index 3d9bacf39f..47338d4469 100644
--- a/source/libs/executor/src/groupoperator.c
+++ b/source/libs/executor/src/groupoperator.c
@@ -22,7 +22,8 @@
 #include "tmsg.h"
 
 #include "executorInt.h"
-#include "executorimpl.h"
+#include "operator.h"
+#include "querytask.h"
 #include "tcompare.h"
 #include "thash.h"
 #include "ttypes.h"
@@ -926,7 +927,6 @@ int32_t setGroupResultOutputBuf(SOperatorInfo* pOperator, SOptrBasicInfo* binfo,
 
   SResultRow* pResultRow =
       doSetResultOutBufByKey(pBuf, pResultRowInfo, (char*)pData, bytes, true, groupId, pTaskInfo, false, pAggSup, false);
-  assert(pResultRow != NULL);
 
   setResultRowInitCtx(pResultRow, pCtx, numOfCols, pOperator->exprSupp.rowEntryInfoOffset);
   return TSDB_CODE_SUCCESS;
diff --git a/source/libs/executor/src/joinoperator.c b/source/libs/executor/src/joinoperator.c
index 31ff11eec5..754b5f4737 100644
--- a/source/libs/executor/src/joinoperator.c
+++ b/source/libs/executor/src/joinoperator.c
@@ -13,11 +13,13 @@
  * along with this program. If not, see .
  */
 
+#include "executorInt.h"
 #include "filter.h"
-#include "executorimpl.h"
 #include "function.h"
+#include "operator.h"
 #include "os.h"
 #include "querynodes.h"
+#include "querytask.h"
 #include "tcompare.h"
 #include "tdatablock.h"
 #include "thash.h"
diff --git a/source/libs/executor/src/operator.c b/source/libs/executor/src/operator.c
new file mode 100644
index 0000000000..729178dc60
--- /dev/null
+++ b/source/libs/executor/src/operator.c
@@ -0,0 +1,578 @@
+/*
+ * Copyright (c) 2019 TAOS Data, Inc. 
+ *
+ * This program is free software: you can use, redistribute, and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3
+ * or later ("AGPL"), as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+#include "filter.h"
+#include "function.h"
+#include "os.h"
+#include "tname.h"
+
+#include "tglobal.h"
+
+#include "executorInt.h"
+#include "index.h"
+#include "operator.h"
+#include "query.h"
+#include "querytask.h"
+#include "vnode.h"
+
+SOperatorFpSet createOperatorFpSet(__optr_open_fn_t openFn, __optr_fn_t nextFn, __optr_fn_t cleanup,
+                                   __optr_close_fn_t closeFn, __optr_reqBuf_fn_t reqBufFn,
+                                   __optr_explain_fn_t explain) {
+  SOperatorFpSet fpSet = {
+      ._openFn = openFn,
+      .getNextFn = nextFn,
+      .cleanupFn = cleanup,
+      .closeFn = closeFn,
+      .reqBufFn = reqBufFn,
+      .getExplainFn = explain,
+  };
+
+  return fpSet;
+}
+
+int32_t optrDummyOpenFn(SOperatorInfo* pOperator) {
+  OPTR_SET_OPENED(pOperator);
+  pOperator->cost.openCost = 0;
+  return TSDB_CODE_SUCCESS;
+}
+
+int32_t appendDownstream(SOperatorInfo* p, SOperatorInfo** pDownstream, int32_t num) {
+  p->pDownstream = taosMemoryCalloc(1, num * POINTER_BYTES);
+  if (p->pDownstream == NULL) {
+    return TSDB_CODE_OUT_OF_MEMORY;
+  }
+
+  memcpy(p->pDownstream, pDownstream, num * POINTER_BYTES);
+  p->numOfDownstream = num;
+  return TSDB_CODE_SUCCESS;
+}
+
+void setOperatorCompleted(SOperatorInfo* pOperator) {
+  pOperator->status = OP_EXEC_DONE;
+  pOperator->cost.totalCost = (taosGetTimestampUs() - pOperator->pTaskInfo->cost.start) / 1000.0;
+  setTaskStatus(pOperator->pTaskInfo, TASK_COMPLETED);
+}
+
+void setOperatorInfo(SOperatorInfo* pOperator, const char* name, int32_t type, bool blocking, int32_t status,
+                     void* pInfo, SExecTaskInfo* pTaskInfo) {
+  pOperator->name = (char*)name;
+  pOperator->operatorType = type;
+  pOperator->blocking = blocking;
+  pOperator->status = status;
+  pOperator->info = pInfo;
+  pOperator->pTaskInfo = pTaskInfo;
+}
+
+// each operator should be set their own function to return total cost buffer
+int32_t optrDefaultBufFn(SOperatorInfo* pOperator) {
+  if (pOperator->blocking) {
+    return -1;
+  } else {
+    return 0;
+  }
+}
+
+static int64_t getQuerySupportBufSize(size_t numOfTables) {
+  size_t s1 = sizeof(STableQueryInfo);
+  //  size_t s3 = sizeof(STableCheckInfo);  buffer consumption in tsdb
+  return (int64_t)(s1 * 1.5 * numOfTables);
+}
+
+int32_t checkForQueryBuf(size_t numOfTables) {
+  int64_t t = getQuerySupportBufSize(numOfTables);
+  if (tsQueryBufferSizeBytes < 0) {
+    return TSDB_CODE_SUCCESS;
+  } else if (tsQueryBufferSizeBytes > 0) {
+    while (1) {
+      int64_t s = tsQueryBufferSizeBytes;
+      int64_t remain = s - t;
+      if (remain >= 0) {
+        if (atomic_val_compare_exchange_64(&tsQueryBufferSizeBytes, s, remain) == s) {
+          return TSDB_CODE_SUCCESS;
+        }
+      } else {
+        return TSDB_CODE_QRY_NOT_ENOUGH_BUFFER;
+      }
+    }
+  }
+
+  // disable query processing if the value of tsQueryBufferSize is zero.
+  return TSDB_CODE_QRY_NOT_ENOUGH_BUFFER;
+}
+
+void releaseQueryBuf(size_t numOfTables) {
+  if (tsQueryBufferSizeBytes < 0) {
+    return;
+  }
+
+  int64_t t = getQuerySupportBufSize(numOfTables);
+
+  // restore value is not enough buffer available
+  atomic_add_fetch_64(&tsQueryBufferSizeBytes, t);
+}
+
+typedef enum {
+  OPTR_FN_RET_CONTINUE = 0x1,
+  OPTR_FN_RET_ABORT = 0x2,
+} ERetType;
+
+typedef struct STraverParam {
+  void*   pRet;
+  int32_t code;
+  void*   pParam;
+} STraverParam;
+
+// iterate the operator tree helper
+typedef ERetType (*optr_fn_t)(SOperatorInfo *pOperator, STraverParam *pParam, const char* pIdstr);
+
+void traverseOperatorTree(SOperatorInfo* pOperator, optr_fn_t fn, STraverParam* pParam, const char* id) {
+  if (pOperator == NULL) {
+    return;
+  }
+
+  ERetType ret = fn(pOperator, pParam, id);
+  if (ret == OPTR_FN_RET_ABORT || pParam->code != TSDB_CODE_SUCCESS) {
+    return;
+  }
+
+  for (int32_t i = 0; i < pOperator->numOfDownstream; ++i) {
+    traverseOperatorTree(pOperator->pDownstream[i], fn, pParam, id);
+    if (pParam->code != 0) {
+      break;
+    }
+  }
+}
+
+ERetType extractOperatorInfo(SOperatorInfo* pOperator, STraverParam* pParam, const char* pIdStr) {
+  STraverParam* p = pParam;
+  if (pOperator->operatorType == *(int32_t*)p->pParam) {
+    p->pRet = pOperator;
+    return OPTR_FN_RET_ABORT;
+  } else {
+    return OPTR_FN_RET_CONTINUE;
+  }
+}
+
+// QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN
+SOperatorInfo* extractOperatorInTree(SOperatorInfo* pOperator, int32_t type, const char* id) {
+  if (pOperator == NULL) {
+    qError("invalid operator, failed to find tableScanOperator %s", id);
+    terrno = TSDB_CODE_PAR_INTERNAL_ERROR;
+    return NULL;
+  }
+
+  STraverParam p = {.pParam = &type, .pRet = NULL};
+  traverseOperatorTree(pOperator, extractOperatorInfo, &p, id);
+  if (p.code != 0) {
+    terrno = p.code;
+    return NULL;
+  } else {
+    return p.pRet;
+  }
+}
+
+typedef struct SExtScanInfo {
+  int32_t order;
+  int32_t scanFlag;
+  int32_t inheritUsOrder;
+} SExtScanInfo;
+
+static ERetType extractScanInfo(SOperatorInfo* pOperator, STraverParam* pParam, const char* pIdStr) {
+  int32_t type = pOperator->operatorType;
+  SExtScanInfo* pInfo = pParam->pParam;
+
+  if (type == QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN || type == QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN ||
+      type == QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN || type == QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN ||
+      type == QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN || type == QUERY_NODE_PHYSICAL_PLAN_TABLE_COUNT_SCAN) {
+    pInfo->order = TSDB_ORDER_ASC;
+    pInfo->scanFlag= MAIN_SCAN;
+    return OPTR_FN_RET_ABORT;
+  } else if (type == QUERY_NODE_PHYSICAL_PLAN_EXCHANGE) {
+    if (!pInfo->inheritUsOrder) {
+      pInfo->order = TSDB_ORDER_ASC;
+    }
+    pInfo->scanFlag= MAIN_SCAN;
+    return OPTR_FN_RET_ABORT;
+  } else if (type == QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN) {
+    STableScanInfo* pTableScanInfo = pOperator->info;
+    pInfo->order = pTableScanInfo->base.cond.order;
+    pInfo->scanFlag= pTableScanInfo->base.scanFlag;
+    return OPTR_FN_RET_ABORT;
+  } else if (type == QUERY_NODE_PHYSICAL_PLAN_TABLE_MERGE_SCAN) {
+    STableMergeScanInfo* pTableScanInfo = pOperator->info;
+    pInfo->order = pTableScanInfo->base.cond.order;
+    pInfo->scanFlag= pTableScanInfo->base.scanFlag;
+    return OPTR_FN_RET_ABORT;
+  } else {
+    return OPTR_FN_RET_CONTINUE;
+  }
+}
+
+int32_t getTableScanInfo(SOperatorInfo* pOperator, int32_t* order, int32_t* scanFlag, bool inheritUsOrder) {
+  SExtScanInfo info = {.inheritUsOrder = inheritUsOrder, .order = *order};
+  STraverParam p = {.pParam = &info};
+
+  traverseOperatorTree(pOperator, extractScanInfo, &p, NULL);
+  *order = info.order;
+  *scanFlag = info.scanFlag;
+
+  ASSERT(*order == TSDB_ORDER_ASC || *order == TSDB_ORDER_DESC);
+  return p.code;
+}
+
+static ERetType doStopDataReader(SOperatorInfo* pOperator, STraverParam* pParam, const char* pIdStr) {
+  if (pOperator->operatorType == QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN) {
+    STableScanInfo* pInfo = pOperator->info;
+
+    if (pInfo->base.dataReader != NULL) {
+      tsdbReaderSetCloseFlag(pInfo->base.dataReader);
+    }
+    return OPTR_FN_RET_ABORT;
+  } else if (pOperator->operatorType == QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN) {
+    SStreamScanInfo* pInfo = pOperator->info;
+
+    if (pInfo->pTableScanOp != NULL) {
+      STableScanInfo* pTableScanInfo = pInfo->pTableScanOp->info;
+      if (pTableScanInfo != NULL && pTableScanInfo->base.dataReader != NULL) {
+        tsdbReaderSetCloseFlag(pTableScanInfo->base.dataReader);
+      }
+    }
+
+    return OPTR_FN_RET_ABORT;
+  }
+
+  return OPTR_FN_RET_CONTINUE;
+}
+
+int32_t stopTableScanOperator(SOperatorInfo* pOperator, const char* pIdStr) {
+  STraverParam p = {0};
+  traverseOperatorTree(pOperator, doStopDataReader, &p, pIdStr);
+  return p.code;
+}
+
+SOperatorInfo* createOperator(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, SReadHandle* pHandle, SNode* pTagCond,
+                              SNode* pTagIndexCond, const char* pUser, const char* dbname) {
+  int32_t     type = nodeType(pPhyNode);
+  const char* idstr = GET_TASKID(pTaskInfo);
+
+  if (pPhyNode->pChildren == NULL || LIST_LENGTH(pPhyNode->pChildren) == 0) {
+    SOperatorInfo* pOperator = NULL;
+    if (QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN == type) {
+      STableScanPhysiNode* pTableScanNode = (STableScanPhysiNode*)pPhyNode;
+
+      // NOTE: this is an patch to fix the physical plan
+      // TODO remove it later
+      if (pTableScanNode->scan.node.pLimit != NULL) {
+        pTableScanNode->groupSort = true;
+      }
+
+      STableListInfo* pTableListInfo = tableListCreate();
+      int32_t         code =
+          createScanTableListInfo(&pTableScanNode->scan, pTableScanNode->pGroupTags, pTableScanNode->groupSort, pHandle,
+                                  pTableListInfo, pTagCond, pTagIndexCond, pTaskInfo);
+      if (code) {
+        pTaskInfo->code = code;
+        tableListDestroy(pTableListInfo);
+        qError("failed to createScanTableListInfo, code:%s, %s", tstrerror(code), idstr);
+        return NULL;
+      }
+
+      code = initQueriedTableSchemaInfo(pHandle, &pTableScanNode->scan, dbname, pTaskInfo);
+      if (code) {
+        pTaskInfo->code = code;
+        tableListDestroy(pTableListInfo);
+        return NULL;
+      }
+
+      pOperator = createTableScanOperatorInfo(pTableScanNode, pHandle, pTableListInfo, pTaskInfo);
+      if (NULL == pOperator) {
+        pTaskInfo->code = terrno;
+        tableListDestroy(pTableListInfo);
+        return NULL;
+      }
+
+      STableScanInfo* pScanInfo = pOperator->info;
+      pTaskInfo->cost.pRecoder = &pScanInfo->base.readRecorder;
+    } else if (QUERY_NODE_PHYSICAL_PLAN_TABLE_MERGE_SCAN == type) {
+      STableMergeScanPhysiNode* pTableScanNode = (STableMergeScanPhysiNode*)pPhyNode;
+      STableListInfo*           pTableListInfo = tableListCreate();
+
+      int32_t code = createScanTableListInfo(&pTableScanNode->scan, pTableScanNode->pGroupTags, true, pHandle,
+                                             pTableListInfo, pTagCond, pTagIndexCond, pTaskInfo);
+      if (code) {
+        pTaskInfo->code = code;
+        tableListDestroy(pTableListInfo);
+        qError("failed to createScanTableListInfo, code: %s", tstrerror(code));
+        return NULL;
+      }
+
+      code = initQueriedTableSchemaInfo(pHandle, &pTableScanNode->scan, dbname, pTaskInfo);
+      if (code) {
+        pTaskInfo->code = terrno;
+        tableListDestroy(pTableListInfo);
+        return NULL;
+      }
+
+      pOperator = createTableMergeScanOperatorInfo(pTableScanNode, pHandle, pTableListInfo, pTaskInfo);
+      if (NULL == pOperator) {
+        pTaskInfo->code = terrno;
+        tableListDestroy(pTableListInfo);
+        return NULL;
+      }
+
+      STableScanInfo* pScanInfo = pOperator->info;
+      pTaskInfo->cost.pRecoder = &pScanInfo->base.readRecorder;
+    } else if (QUERY_NODE_PHYSICAL_PLAN_EXCHANGE == type) {
+      pOperator = createExchangeOperatorInfo(pHandle ? pHandle->pMsgCb->clientRpc : NULL, (SExchangePhysiNode*)pPhyNode,
+                                             pTaskInfo);
+    } else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN == type) {
+      STableScanPhysiNode* pTableScanNode = (STableScanPhysiNode*)pPhyNode;
+      STableListInfo*      pTableListInfo = tableListCreate();
+
+      if (pHandle->vnode) {
+        int32_t code =
+            createScanTableListInfo(&pTableScanNode->scan, pTableScanNode->pGroupTags, pTableScanNode->groupSort,
+                                    pHandle, pTableListInfo, pTagCond, pTagIndexCond, pTaskInfo);
+        if (code) {
+          pTaskInfo->code = code;
+          tableListDestroy(pTableListInfo);
+          qError("failed to createScanTableListInfo, code: %s", tstrerror(code));
+          return NULL;
+        }
+      }
+
+      pTaskInfo->schemaInfo.qsw = extractQueriedColumnSchema(&pTableScanNode->scan);
+      pOperator = createStreamScanOperatorInfo(pHandle, pTableScanNode, pTagCond, pTableListInfo, pTaskInfo);
+    } else if (QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN == type) {
+      SSystemTableScanPhysiNode* pSysScanPhyNode = (SSystemTableScanPhysiNode*)pPhyNode;
+      pOperator = createSysTableScanOperatorInfo(pHandle, pSysScanPhyNode, pUser, pTaskInfo);
+    } else if (QUERY_NODE_PHYSICAL_PLAN_TABLE_COUNT_SCAN == type) {
+      STableCountScanPhysiNode* pTblCountScanNode = (STableCountScanPhysiNode*)pPhyNode;
+      pOperator = createTableCountScanOperatorInfo(pHandle, pTblCountScanNode, pTaskInfo);
+    } else if (QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN == type) {
+      STagScanPhysiNode* pScanPhyNode = (STagScanPhysiNode*)pPhyNode;
+      STableListInfo*    pTableListInfo = tableListCreate();
+      int32_t            code = createScanTableListInfo(pScanPhyNode, NULL, false, pHandle, pTableListInfo, pTagCond,
+                                                        pTagIndexCond, pTaskInfo);
+      if (code != TSDB_CODE_SUCCESS) {
+        pTaskInfo->code = code;
+        qError("failed to getTableList, code: %s", tstrerror(code));
+        return NULL;
+      }
+
+      pOperator = createTagScanOperatorInfo(pHandle, pScanPhyNode, pTableListInfo, pTaskInfo);
+    } else if (QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN == type) {
+      SBlockDistScanPhysiNode* pBlockNode = (SBlockDistScanPhysiNode*)pPhyNode;
+      STableListInfo*          pTableListInfo = tableListCreate();
+
+      if (pBlockNode->tableType == TSDB_SUPER_TABLE) {
+        SArray* pList = taosArrayInit(4, sizeof(STableKeyInfo));
+        int32_t code = vnodeGetAllTableList(pHandle->vnode, pBlockNode->uid, pList);
+        if (code != TSDB_CODE_SUCCESS) {
+          pTaskInfo->code = terrno;
+          return NULL;
+        }
+
+        size_t num = taosArrayGetSize(pList);
+        for (int32_t i = 0; i < num; ++i) {
+          STableKeyInfo* p = taosArrayGet(pList, i);
+          tableListAddTableInfo(pTableListInfo, p->uid, 0);
+        }
+
+        taosArrayDestroy(pList);
+      } else {  // Create group with only one table
+        tableListAddTableInfo(pTableListInfo, pBlockNode->uid, 0);
+      }
+
+      pOperator = createDataBlockInfoScanOperator(pHandle, pBlockNode, pTableListInfo, pTaskInfo);
+    } else if (QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN == type) {
+      SLastRowScanPhysiNode* pScanNode = (SLastRowScanPhysiNode*)pPhyNode;
+      STableListInfo*        pTableListInfo = tableListCreate();
+
+      int32_t code = createScanTableListInfo(&pScanNode->scan, pScanNode->pGroupTags, true, pHandle, pTableListInfo,
+                                             pTagCond, pTagIndexCond, pTaskInfo);
+      if (code != TSDB_CODE_SUCCESS) {
+        pTaskInfo->code = code;
+        return NULL;
+      }
+
+      code = initQueriedTableSchemaInfo(pHandle, &pScanNode->scan, dbname, pTaskInfo);
+      if (code != TSDB_CODE_SUCCESS) {
+        pTaskInfo->code = code;
+        return NULL;
+      }
+
+      pOperator = createCacherowsScanOperator(pScanNode, pHandle, pTableListInfo, pTaskInfo);
+    } else if (QUERY_NODE_PHYSICAL_PLAN_PROJECT == type) {
+      pOperator = createProjectOperatorInfo(NULL, (SProjectPhysiNode*)pPhyNode, pTaskInfo);
+    } else {
+      terrno = TSDB_CODE_INVALID_PARA;
+      return NULL;
+    }
+
+    if (pOperator != NULL) {  // todo moved away
+      pOperator->resultDataBlockId = pPhyNode->pOutputDataBlockDesc->dataBlockId;
+    }
+
+    return pOperator;
+  }
+
+  size_t          size = LIST_LENGTH(pPhyNode->pChildren);
+  SOperatorInfo** ops = taosMemoryCalloc(size, POINTER_BYTES);
+  if (ops == NULL) {
+    return NULL;
+  }
+
+  for (int32_t i = 0; i < size; ++i) {
+    SPhysiNode* pChildNode = (SPhysiNode*)nodesListGetNode(pPhyNode->pChildren, i);
+    ops[i] = createOperator(pChildNode, pTaskInfo, pHandle, pTagCond, pTagIndexCond, pUser, dbname);
+    if (ops[i] == NULL) {
+      taosMemoryFree(ops);
+      return NULL;
+    }
+  }
+
+  SOperatorInfo* pOptr = NULL;
+  if (QUERY_NODE_PHYSICAL_PLAN_PROJECT == type) {
+    pOptr = createProjectOperatorInfo(ops[0], (SProjectPhysiNode*)pPhyNode, pTaskInfo);
+  } else if (QUERY_NODE_PHYSICAL_PLAN_HASH_AGG == type) {
+    SAggPhysiNode* pAggNode = (SAggPhysiNode*)pPhyNode;
+    if (pAggNode->pGroupKeys != NULL) {
+      pOptr = createGroupOperatorInfo(ops[0], pAggNode, pTaskInfo);
+    } else {
+      pOptr = createAggregateOperatorInfo(ops[0], pAggNode, pTaskInfo);
+    }
+  } else if (QUERY_NODE_PHYSICAL_PLAN_HASH_INTERVAL == type) {
+    SIntervalPhysiNode* pIntervalPhyNode = (SIntervalPhysiNode*)pPhyNode;
+    pOptr = createIntervalOperatorInfo(ops[0], pIntervalPhyNode, pTaskInfo);
+  } else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL == type) {
+    pOptr = createStreamIntervalOperatorInfo(ops[0], pPhyNode, pTaskInfo);
+  } else if (QUERY_NODE_PHYSICAL_PLAN_MERGE_ALIGNED_INTERVAL == type) {
+    SMergeAlignedIntervalPhysiNode* pIntervalPhyNode = (SMergeAlignedIntervalPhysiNode*)pPhyNode;
+    pOptr = createMergeAlignedIntervalOperatorInfo(ops[0], pIntervalPhyNode, pTaskInfo);
+  } else if (QUERY_NODE_PHYSICAL_PLAN_MERGE_INTERVAL == type) {
+    SMergeIntervalPhysiNode* pIntervalPhyNode = (SMergeIntervalPhysiNode*)pPhyNode;
+    pOptr = createMergeIntervalOperatorInfo(ops[0], pIntervalPhyNode, pTaskInfo);
+  } else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL == type) {
+    int32_t children = 0;
+    pOptr = createStreamFinalIntervalOperatorInfo(ops[0], pPhyNode, pTaskInfo, children);
+  } else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_INTERVAL == type) {
+    int32_t children = pHandle->numOfVgroups;
+    pOptr = createStreamFinalIntervalOperatorInfo(ops[0], pPhyNode, pTaskInfo, children);
+  } else if (QUERY_NODE_PHYSICAL_PLAN_SORT == type) {
+    pOptr = createSortOperatorInfo(ops[0], (SSortPhysiNode*)pPhyNode, pTaskInfo);
+  } else if (QUERY_NODE_PHYSICAL_PLAN_GROUP_SORT == type) {
+    pOptr = createGroupSortOperatorInfo(ops[0], (SGroupSortPhysiNode*)pPhyNode, pTaskInfo);
+  } else if (QUERY_NODE_PHYSICAL_PLAN_MERGE == type) {
+    SMergePhysiNode* pMergePhyNode = (SMergePhysiNode*)pPhyNode;
+    pOptr = createMultiwayMergeOperatorInfo(ops, size, pMergePhyNode, pTaskInfo);
+  } else if (QUERY_NODE_PHYSICAL_PLAN_MERGE_SESSION == type) {
+    SSessionWinodwPhysiNode* pSessionNode = (SSessionWinodwPhysiNode*)pPhyNode;
+    pOptr = createSessionAggOperatorInfo(ops[0], pSessionNode, pTaskInfo);
+  } else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_SESSION == type) {
+    pOptr = createStreamSessionAggOperatorInfo(ops[0], pPhyNode, pTaskInfo);
+  } else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_SESSION == type) {
+    int32_t children = 0;
+    pOptr = createStreamFinalSessionAggOperatorInfo(ops[0], pPhyNode, pTaskInfo, children);
+  } else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_SESSION == type) {
+    int32_t children = pHandle->numOfVgroups;
+    pOptr = createStreamFinalSessionAggOperatorInfo(ops[0], pPhyNode, pTaskInfo, children);
+  } else if (QUERY_NODE_PHYSICAL_PLAN_PARTITION == type) {
+    pOptr = createPartitionOperatorInfo(ops[0], (SPartitionPhysiNode*)pPhyNode, pTaskInfo);
+  } else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_PARTITION == type) {
+    pOptr = createStreamPartitionOperatorInfo(ops[0], (SStreamPartitionPhysiNode*)pPhyNode, pTaskInfo);
+  } else if (QUERY_NODE_PHYSICAL_PLAN_MERGE_STATE == type) {
+    SStateWinodwPhysiNode* pStateNode = (SStateWinodwPhysiNode*)pPhyNode;
+    pOptr = createStatewindowOperatorInfo(ops[0], pStateNode, pTaskInfo);
+  } else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_STATE == type) {
+    pOptr = createStreamStateAggOperatorInfo(ops[0], pPhyNode, pTaskInfo);
+  } else if (QUERY_NODE_PHYSICAL_PLAN_MERGE_JOIN == type) {
+    pOptr = createMergeJoinOperatorInfo(ops, size, (SSortMergeJoinPhysiNode*)pPhyNode, pTaskInfo);
+  } else if (QUERY_NODE_PHYSICAL_PLAN_FILL == type) {
+    pOptr = createFillOperatorInfo(ops[0], (SFillPhysiNode*)pPhyNode, pTaskInfo);
+  } else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_FILL == type) {
+    pOptr = createStreamFillOperatorInfo(ops[0], (SStreamFillPhysiNode*)pPhyNode, pTaskInfo);
+  } else if (QUERY_NODE_PHYSICAL_PLAN_INDEF_ROWS_FUNC == type) {
+    pOptr = createIndefinitOutputOperatorInfo(ops[0], pPhyNode, pTaskInfo);
+  } else if (QUERY_NODE_PHYSICAL_PLAN_INTERP_FUNC == type) {
+    pOptr = createTimeSliceOperatorInfo(ops[0], pPhyNode, pTaskInfo);
+  } else if (QUERY_NODE_PHYSICAL_PLAN_MERGE_EVENT == type) {
+    pOptr = createEventwindowOperatorInfo(ops[0], pPhyNode, pTaskInfo);
+  } else {
+    terrno = TSDB_CODE_INVALID_PARA;
+    taosMemoryFree(ops);
+    return NULL;
+  }
+
+  taosMemoryFree(ops);
+  if (pOptr) {
+    pOptr->resultDataBlockId = pPhyNode->pOutputDataBlockDesc->dataBlockId;
+  }
+
+  return pOptr;
+}
+
+void destroyOperator(SOperatorInfo* pOperator) {
+  if (pOperator == NULL) {
+    return;
+  }
+
+  if (pOperator->fpSet.closeFn != NULL) {
+    pOperator->fpSet.closeFn(pOperator->info);
+  }
+
+  if (pOperator->pDownstream != NULL) {
+    for (int32_t i = 0; i < pOperator->numOfDownstream; ++i) {
+      destroyOperator(pOperator->pDownstream[i]);
+    }
+
+    taosMemoryFreeClear(pOperator->pDownstream);
+    pOperator->numOfDownstream = 0;
+  }
+
+  cleanupExprSupp(&pOperator->exprSupp);
+  taosMemoryFreeClear(pOperator);
+}
+
+int32_t getOperatorExplainExecInfo(SOperatorInfo* operatorInfo, SArray* pExecInfoList) {
+  SExplainExecInfo  execInfo = {0};
+  SExplainExecInfo* pExplainInfo = taosArrayPush(pExecInfoList, &execInfo);
+
+  pExplainInfo->numOfRows = operatorInfo->resultInfo.totalRows;
+  pExplainInfo->startupCost = operatorInfo->cost.openCost;
+  pExplainInfo->totalCost = operatorInfo->cost.totalCost;
+  pExplainInfo->verboseLen = 0;
+  pExplainInfo->verboseInfo = NULL;
+
+  if (operatorInfo->fpSet.getExplainFn) {
+    int32_t code =
+        operatorInfo->fpSet.getExplainFn(operatorInfo, &pExplainInfo->verboseInfo, &pExplainInfo->verboseLen);
+    if (code) {
+      qError("%s operator getExplainFn failed, code:%s", GET_TASKID(operatorInfo->pTaskInfo), tstrerror(code));
+      return code;
+    }
+  }
+
+  int32_t code = 0;
+  for (int32_t i = 0; i < operatorInfo->numOfDownstream; ++i) {
+    code = getOperatorExplainExecInfo(operatorInfo->pDownstream[i], pExecInfoList);
+    if (code != TSDB_CODE_SUCCESS) {
+      //      taosMemoryFreeClear(*pRes);
+      return TSDB_CODE_OUT_OF_MEMORY;
+    }
+  }
+
+  return TSDB_CODE_SUCCESS;
+}
diff --git a/source/libs/executor/src/projectoperator.c b/source/libs/executor/src/projectoperator.c
index 811bcbe0b5..2c98f37388 100644
--- a/source/libs/executor/src/projectoperator.c
+++ b/source/libs/executor/src/projectoperator.c
@@ -13,9 +13,11 @@
  * along with this program. If not, see .
  */
 
-#include "executorimpl.h"
+#include "executorInt.h"
 #include "filter.h"
 #include "functionMgt.h"
+#include "operator.h"
+#include "querytask.h"
 
 typedef struct SProjectOperatorInfo {
   SOptrBasicInfo binfo;
diff --git a/source/libs/executor/src/querytask.c b/source/libs/executor/src/querytask.c
new file mode 100644
index 0000000000..7716b5976b
--- /dev/null
+++ b/source/libs/executor/src/querytask.c
@@ -0,0 +1,239 @@
+/*
+ * Copyright (c) 2019 TAOS Data, Inc. 
+ *
+ * This program is free software: you can use, redistribute, and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3
+ * or later ("AGPL"), as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+#include "filter.h"
+#include "function.h"
+#include "functionMgt.h"
+#include "os.h"
+#include "querynodes.h"
+#include "tfill.h"
+#include "tname.h"
+
+#include "tdatablock.h"
+#include "tmsg.h"
+
+#include "executorInt.h"
+#include "index.h"
+#include "operator.h"
+#include "query.h"
+#include "querytask.h"
+#include "thash.h"
+#include "ttypes.h"
+#include "vnode.h"
+
+#define CLEAR_QUERY_STATUS(q, st) ((q)->status &= (~(st)))
+
+SExecTaskInfo* doCreateTask(uint64_t queryId, uint64_t taskId, int32_t vgId, EOPTR_EXEC_MODEL model) {
+  SExecTaskInfo* pTaskInfo = taosMemoryCalloc(1, sizeof(SExecTaskInfo));
+  if (pTaskInfo == NULL) {
+    terrno = TSDB_CODE_OUT_OF_MEMORY;
+    return NULL;
+  }
+
+  setTaskStatus(pTaskInfo, TASK_NOT_COMPLETED);
+  pTaskInfo->cost.created = taosGetTimestampUs();
+
+  pTaskInfo->execModel = model;
+  pTaskInfo->stopInfo.pStopInfo = taosArrayInit(4, sizeof(SExchangeOpStopInfo));
+  pTaskInfo->pResultBlockList = taosArrayInit(128, POINTER_BYTES);
+
+  taosInitRWLatch(&pTaskInfo->lock);
+
+  pTaskInfo->id.vgId = vgId;
+  pTaskInfo->id.queryId = queryId;
+  pTaskInfo->id.str = taosMemoryMalloc(64);
+  buildTaskId(taskId, queryId, pTaskInfo->id.str);
+
+  return pTaskInfo;
+}
+
+bool isTaskKilled(SExecTaskInfo* pTaskInfo) { return (0 != pTaskInfo->code); }
+
+void setTaskKilled(SExecTaskInfo* pTaskInfo, int32_t rspCode) {
+  pTaskInfo->code = rspCode;
+  stopTableScanOperator(pTaskInfo->pRoot, pTaskInfo->id.str);
+}
+
+void setTaskStatus(SExecTaskInfo* pTaskInfo, int8_t status) {
+  if (status == TASK_NOT_COMPLETED) {
+    pTaskInfo->status = status;
+  } else {
+    // QUERY_NOT_COMPLETED is not compatible with any other status, so clear its position first
+    CLEAR_QUERY_STATUS(pTaskInfo, TASK_NOT_COMPLETED);
+    pTaskInfo->status |= status;
+  }
+}
+
+int32_t createExecTaskInfo(SSubplan* pPlan, SExecTaskInfo** pTaskInfo, SReadHandle* pHandle, uint64_t taskId,
+                           int32_t vgId, char* sql, EOPTR_EXEC_MODEL model) {
+  *pTaskInfo = doCreateTask(pPlan->id.queryId, taskId, vgId, model);
+  if (*pTaskInfo == NULL) {
+    taosMemoryFree(sql);
+    return terrno;
+  }
+
+  if (pHandle) {
+    if (pHandle->pStateBackend) {
+      (*pTaskInfo)->streamInfo.pState = pHandle->pStateBackend;
+    }
+  }
+
+  TSWAP((*pTaskInfo)->sql, sql);
+
+  (*pTaskInfo)->pSubplan = pPlan;
+  (*pTaskInfo)->pRoot = createOperator(pPlan->pNode, *pTaskInfo, pHandle, pPlan->pTagCond, pPlan->pTagIndexCond,
+                                       pPlan->user, pPlan->dbFName);
+
+  if (NULL == (*pTaskInfo)->pRoot) {
+    int32_t code = (*pTaskInfo)->code;
+    doDestroyTask(*pTaskInfo);
+    (*pTaskInfo) = NULL;
+    return code;
+  } else {
+    return TSDB_CODE_SUCCESS;
+  }
+}
+
+void cleanupQueriedTableScanInfo(SSchemaInfo* pSchemaInfo) {
+  taosMemoryFreeClear(pSchemaInfo->dbname);
+  taosMemoryFreeClear(pSchemaInfo->tablename);
+  tDeleteSchemaWrapper(pSchemaInfo->sw);
+  tDeleteSchemaWrapper(pSchemaInfo->qsw);
+}
+
+int32_t initQueriedTableSchemaInfo(SReadHandle* pHandle, SScanPhysiNode* pScanNode, const char* dbName, SExecTaskInfo* pTaskInfo) {
+  SMetaReader mr = {0};
+  if (pHandle == NULL) {
+    terrno = TSDB_CODE_INVALID_PARA;
+    return terrno;
+  }
+
+  metaReaderInit(&mr, pHandle->meta, 0);
+  int32_t code = metaGetTableEntryByUidCache(&mr, pScanNode->uid);
+  if (code != TSDB_CODE_SUCCESS) {
+    qError("failed to get the table meta, uid:0x%" PRIx64 ", suid:0x%" PRIx64 ", %s", pScanNode->uid, pScanNode->suid,
+           GET_TASKID(pTaskInfo));
+
+    metaReaderClear(&mr);
+    return terrno;
+  }
+
+  SSchemaInfo* pSchemaInfo = &pTaskInfo->schemaInfo;
+
+  pSchemaInfo->tablename = taosStrdup(mr.me.name);
+  pSchemaInfo->dbname = taosStrdup(dbName);
+
+  if (mr.me.type == TSDB_SUPER_TABLE) {
+    pSchemaInfo->sw = tCloneSSchemaWrapper(&mr.me.stbEntry.schemaRow);
+    pSchemaInfo->tversion = mr.me.stbEntry.schemaTag.version;
+  } else if (mr.me.type == TSDB_CHILD_TABLE) {
+    tDecoderClear(&mr.coder);
+
+    tb_uid_t suid = mr.me.ctbEntry.suid;
+    code = metaGetTableEntryByUidCache(&mr, suid);
+    if (code != TSDB_CODE_SUCCESS) {
+      metaReaderClear(&mr);
+      return terrno;
+    }
+
+    pSchemaInfo->sw = tCloneSSchemaWrapper(&mr.me.stbEntry.schemaRow);
+    pSchemaInfo->tversion = mr.me.stbEntry.schemaTag.version;
+  } else {
+    pSchemaInfo->sw = tCloneSSchemaWrapper(&mr.me.ntbEntry.schemaRow);
+  }
+
+  metaReaderClear(&mr);
+
+  pSchemaInfo->qsw = extractQueriedColumnSchema(pScanNode);
+  return TSDB_CODE_SUCCESS;
+}
+
+SSchemaWrapper* extractQueriedColumnSchema(SScanPhysiNode* pScanNode) {
+  int32_t numOfCols = LIST_LENGTH(pScanNode->pScanCols);
+  int32_t numOfTags = LIST_LENGTH(pScanNode->pScanPseudoCols);
+
+  SSchemaWrapper* pqSw = taosMemoryCalloc(1, sizeof(SSchemaWrapper));
+  pqSw->pSchema = taosMemoryCalloc(numOfCols + numOfTags, sizeof(SSchema));
+
+  for (int32_t i = 0; i < numOfCols; ++i) {
+    STargetNode* pNode = (STargetNode*)nodesListGetNode(pScanNode->pScanCols, i);
+    SColumnNode* pColNode = (SColumnNode*)pNode->pExpr;
+
+    SSchema* pSchema = &pqSw->pSchema[pqSw->nCols++];
+    pSchema->colId = pColNode->colId;
+    pSchema->type = pColNode->node.resType.type;
+    pSchema->bytes = pColNode->node.resType.bytes;
+    tstrncpy(pSchema->name, pColNode->colName, tListLen(pSchema->name));
+  }
+
+  // this the tags and pseudo function columns, we only keep the tag columns
+  for (int32_t i = 0; i < numOfTags; ++i) {
+    STargetNode* pNode = (STargetNode*)nodesListGetNode(pScanNode->pScanPseudoCols, i);
+
+    int32_t type = nodeType(pNode->pExpr);
+    if (type == QUERY_NODE_COLUMN) {
+      SColumnNode* pColNode = (SColumnNode*)pNode->pExpr;
+
+      SSchema* pSchema = &pqSw->pSchema[pqSw->nCols++];
+      pSchema->colId = pColNode->colId;
+      pSchema->type = pColNode->node.resType.type;
+      pSchema->bytes = pColNode->node.resType.bytes;
+      tstrncpy(pSchema->name, pColNode->colName, tListLen(pSchema->name));
+    }
+  }
+
+  return pqSw;
+}
+
+static void cleanupStreamInfo(SStreamTaskInfo* pStreamInfo) { tDeleteSchemaWrapper(pStreamInfo->schema); }
+
+static void freeBlock(void* pParam) {
+  SSDataBlock* pBlock = *(SSDataBlock**)pParam;
+  blockDataDestroy(pBlock);
+}
+
+void doDestroyTask(SExecTaskInfo* pTaskInfo) {
+  qDebug("%s execTask is freed", GET_TASKID(pTaskInfo));
+  destroyOperator(pTaskInfo->pRoot);
+  pTaskInfo->pRoot = NULL;
+
+  cleanupQueriedTableScanInfo(&pTaskInfo->schemaInfo);
+  cleanupStreamInfo(&pTaskInfo->streamInfo);
+
+  if (!pTaskInfo->localFetch.localExec) {
+    nodesDestroyNode((SNode*)pTaskInfo->pSubplan);
+    pTaskInfo->pSubplan = NULL;
+  }
+
+  taosArrayDestroyEx(pTaskInfo->pResultBlockList, freeBlock);
+  taosArrayDestroy(pTaskInfo->stopInfo.pStopInfo);
+  taosMemoryFreeClear(pTaskInfo->sql);
+  taosMemoryFreeClear(pTaskInfo->id.str);
+  taosMemoryFreeClear(pTaskInfo);
+}
+
+void buildTaskId(uint64_t taskId, uint64_t queryId, char* dst) {
+  char* p = dst;
+
+  int32_t offset = 6;
+  memcpy(p, "TID:0x", offset);
+  offset += tintToHex(taskId, &p[offset]);
+
+  memcpy(&p[offset], " QID:0x", 7);
+  offset += 7;
+  offset += tintToHex(queryId, &p[offset]);
+
+  p[offset] = 0;
+}
diff --git a/source/libs/executor/src/scanoperator.c b/source/libs/executor/src/scanoperator.c
index 1c57db6d71..303fa09c99 100644
--- a/source/libs/executor/src/scanoperator.c
+++ b/source/libs/executor/src/scanoperator.c
@@ -13,7 +13,7 @@
  * along with this program. If not, see .
  */
 
-#include "executorimpl.h"
+#include "executorInt.h"
 #include "filter.h"
 #include "function.h"
 #include "functionMgt.h"
@@ -30,6 +30,8 @@
 #include "tcompare.h"
 #include "thash.h"
 #include "ttypes.h"
+#include "operator.h"
+#include "querytask.h"
 
 int32_t scanDebug = 0;
 
@@ -156,7 +158,7 @@ static bool overlapWithTimeWindow(SInterval* pInterval, SDataBlockInfo* pBlockIn
         break;
       }
 
-      assert(w.skey < pBlockInfo->window.skey);
+      ASSERT(w.skey < pBlockInfo->window.skey);
       if (pBlockInfo->window.skey <= TMIN(w.ekey, pBlockInfo->window.ekey)) {
         return true;
       }
@@ -1650,7 +1652,7 @@ static int32_t setBlockIntoRes(SStreamScanInfo* pInfo, const SSDataBlock* pBlock
 
   pInfo->pRes->info.dataLoad = 1;
   blockDataUpdateTsWindow(pInfo->pRes, pInfo->primaryTsIndex);
-  blockDataFreeRes((SSDataBlock*)pBlock);
+//  blockDataFreeRes((SSDataBlock*)pBlock);
 
   calBlockTbName(pInfo, pInfo->pRes);
   return 0;
@@ -1663,8 +1665,9 @@ static SSDataBlock* doQueueScan(SOperatorInfo* pOperator) {
 
   qDebug("start to exec queue scan, %s", id);
 
+#if 0
   if (pTaskInfo->streamInfo.submit.msgStr != NULL) {
-    if (pInfo->tqReader->msg2.msgStr == NULL) {
+    if (pInfo->tqReader->msg.msgStr == NULL) {
       SPackedData submit = pTaskInfo->streamInfo.submit;
       if (tqReaderSetSubmitMsg(pInfo->tqReader, submit.msgStr, submit.msgLen, submit.ver) < 0) {
         qError("submit msg messed up when initing stream submit block %p", submit.msgStr);
@@ -1675,25 +1678,24 @@ static SSDataBlock* doQueueScan(SOperatorInfo* pOperator) {
     blockDataCleanup(pInfo->pRes);
     SDataBlockInfo* pBlockInfo = &pInfo->pRes->info;
 
-    while (tqNextDataBlock(pInfo->tqReader)) {
-      SSDataBlock block = {0};
-
-      int32_t code = tqRetrieveDataBlock2(&block, pInfo->tqReader, NULL);
-      if (code != TSDB_CODE_SUCCESS || block.info.rows == 0) {
+    while (tqNextBlockImpl(pInfo->tqReader)) {
+      int32_t code = tqRetrieveDataBlock(pInfo->tqReader, NULL);
+      if (code != TSDB_CODE_SUCCESS || pInfo->tqReader->pResBlock->info.rows == 0) {
         continue;
       }
 
-      setBlockIntoRes(pInfo, &block, true);
+      setBlockIntoRes(pInfo, pInfo->tqReader->pResBlock, true);
 
       if (pBlockInfo->rows > 0) {
         return pInfo->pRes;
       }
     }
 
-    pInfo->tqReader->msg2 = (SPackedData){0};
+    pInfo->tqReader->msg = (SPackedData){0};
     pTaskInfo->streamInfo.submit = (SPackedData){0};
     return NULL;
   }
+#endif
 
   if (pTaskInfo->streamInfo.currentOffset.type == TMQ_OFFSET__SNAPSHOT_DATA) {
     SSDataBlock* pResult = doTableScan(pInfo->pTableScanOp);
@@ -1711,28 +1713,28 @@ static SSDataBlock* doQueueScan(SOperatorInfo* pOperator) {
     if (tqSeekVer(pInfo->tqReader, pTaskInfo->streamInfo.snapshotVer + 1, pTaskInfo->id.str) < 0) {
       return NULL;
     }
+
     tqOffsetResetToLog(&pTaskInfo->streamInfo.currentOffset, pTaskInfo->streamInfo.snapshotVer);
   }
 
   if (pTaskInfo->streamInfo.currentOffset.type == TMQ_OFFSET__LOG) {
-    while (1) {
-      SFetchRet ret = {0};
-      tqNextBlock(pInfo->tqReader, &ret);
-      tqOffsetResetToLog(
-          &pTaskInfo->streamInfo.currentOffset,
-          pInfo->tqReader->pWalReader->curVersion - 1);  // curVersion move to next, so currentOffset = curVersion - 1
 
-      if (ret.fetchType == FETCH_TYPE__DATA) {
-        qDebug("doQueueScan get data from log %" PRId64 " rows, version:%" PRId64, ret.data.info.rows,
+    while (1) {
+      int32_t type = tqNextBlockInWal(pInfo->tqReader);
+      SSDataBlock* pRes = pInfo->tqReader->pResBlock;
+
+      // curVersion move to next, so currentOffset = curVersion - 1
+      tqOffsetResetToLog(&pTaskInfo->streamInfo.currentOffset, pInfo->tqReader->pWalReader->curVersion - 1);
+
+      if (type == FETCH_TYPE__DATA) {
+        qDebug("doQueueScan get data from log %" PRId64 " rows, version:%" PRId64, pRes->info.rows,
                pTaskInfo->streamInfo.currentOffset.version);
         blockDataCleanup(pInfo->pRes);
-        setBlockIntoRes(pInfo, &ret.data, true);
+        setBlockIntoRes(pInfo, pRes, true);
         if (pInfo->pRes->info.rows > 0) {
-          qDebug("doQueueScan get data from log %" PRId64 " rows, return, version:%" PRId64, pInfo->pRes->info.rows,
-                 pTaskInfo->streamInfo.currentOffset.version);
           return pInfo->pRes;
         }
-      } else if (ret.fetchType == FETCH_TYPE__NONE) {
+      } else if (type == FETCH_TYPE__NONE) {
         qDebug("doQueueScan get none from log, return, version:%" PRId64, pTaskInfo->streamInfo.currentOffset.version);
         return NULL;
       }
@@ -1884,7 +1886,7 @@ static SSDataBlock* doStreamScan(SOperatorInfo* pOperator) {
         SSDataBlock* pSDB = doRangeScan(pInfo, pInfo->pUpdateRes, pInfo->primaryTsIndex, &pInfo->updateResIndex);
         if (pSDB) {
           STableScanInfo* pTableScanInfo = pInfo->pTableScanOp->info;
-          uint64_t        version = getReaderMaxVersion(pTableScanInfo->base.dataReader);
+          uint64_t        version = tsdbGetReaderMaxVersion(pTableScanInfo->base.dataReader);
           updateInfoSetScanRange(pInfo->pUpdateInfo, &pTableScanInfo->base.cond.twindows, pInfo->groupId, version);
           pSDB->info.type = pInfo->scanMode == STREAM_SCAN_FROM_DATAREADER_RANGE ? STREAM_NORMAL : STREAM_PULL_DATA;
           checkUpdateData(pInfo, true, pSDB, false);
@@ -2050,7 +2052,7 @@ FETCH_NEXT_BLOCK:
         SSDataBlock* pSDB = doRangeScan(pInfo, pInfo->pUpdateRes, pInfo->primaryTsIndex, &pInfo->updateResIndex);
         if (pSDB) {
           STableScanInfo* pTableScanInfo = pInfo->pTableScanOp->info;
-          uint64_t        version = getReaderMaxVersion(pTableScanInfo->base.dataReader);
+          uint64_t        version = tsdbGetReaderMaxVersion(pTableScanInfo->base.dataReader);
           updateInfoSetScanRange(pInfo->pUpdateInfo, &pTableScanInfo->base.cond.twindows, pInfo->groupId, version);
           pSDB->info.type = pInfo->scanMode == STREAM_SCAN_FROM_DATAREADER_RANGE ? STREAM_NORMAL : STREAM_PULL_DATA;
           checkUpdateData(pInfo, true, pSDB, false);
@@ -2082,7 +2084,7 @@ FETCH_NEXT_BLOCK:
 
   NEXT_SUBMIT_BLK:
     while (1) {
-      if (pInfo->tqReader->msg2.msgStr == NULL) {
+      if (pInfo->tqReader->msg.msgStr == NULL) {
         if (pInfo->validBlockIndex >= totBlockNum) {
           updateInfoDestoryColseWinSBF(pInfo->pUpdateInfo);
           doClearBufferedBlocks(pInfo);
@@ -2101,16 +2103,13 @@ FETCH_NEXT_BLOCK:
 
       blockDataCleanup(pInfo->pRes);
 
-      while (tqNextDataBlock(pInfo->tqReader)) {
-        SSDataBlock block = {0};
-
-        int32_t code = tqRetrieveDataBlock2(&block, pInfo->tqReader, NULL);
-
-        if (code != TSDB_CODE_SUCCESS || block.info.rows == 0) {
+      while (tqNextBlockImpl(pInfo->tqReader)) {
+        int32_t code = tqRetrieveDataBlock(pInfo->tqReader, NULL);
+        if (code != TSDB_CODE_SUCCESS || pInfo->tqReader->pResBlock->info.rows == 0) {
           continue;
         }
 
-        setBlockIntoRes(pInfo, &block, false);
+        setBlockIntoRes(pInfo, pInfo->tqReader->pResBlock, false);
 
         if (updateInfoIgnore(pInfo->pUpdateInfo, &pInfo->pRes->info.window, pInfo->pRes->info.id.groupId,
                              pInfo->pRes->info.version)) {
@@ -2143,7 +2142,6 @@ FETCH_NEXT_BLOCK:
     // record the scan action.
     pInfo->numOfExec++;
     pOperator->resultInfo.totalRows += pBlockInfo->rows;
-    // printDataBlock(pInfo->pRes, "stream scan");
 
     qDebug("scan rows: %" PRId64, pBlockInfo->rows);
     if (pBlockInfo->rows > 0) {
@@ -2219,7 +2217,7 @@ static SSDataBlock* doRawScan(SOperatorInfo* pOperator) {
       qDebug("tmqsnap change get data uid:%" PRId64 "", mtInfo.uid);
     }
     qStreamPrepareScan(pTaskInfo, &offset, pInfo->sContext->subType);
-    tDeleteSSchemaWrapper(mtInfo.schema);
+    tDeleteSchemaWrapper(mtInfo.schema);
     return NULL;
   } else if (pTaskInfo->streamInfo.currentOffset.type == TMQ_OFFSET__SNAPSHOT_META) {
     SSnapContext* sContext = pInfo->sContext;
@@ -2334,7 +2332,7 @@ static void destroyStreamScanOperatorInfo(void* param) {
   SStreamScanInfo* pStreamScan = (SStreamScanInfo*)param;
 
   if (pStreamScan->pTableScanOp && pStreamScan->pTableScanOp->info) {
-    destroyOperatorInfo(pStreamScan->pTableScanOp);
+    destroyOperator(pStreamScan->pTableScanOp);
   }
 
   if (pStreamScan->tqReader) {
@@ -2456,7 +2454,7 @@ SOperatorInfo* createStreamScanOperatorInfo(SReadHandle* pHandle, STableScanPhys
 
     if (pHandle->initTqReader) {
       ASSERT(pHandle->tqReader == NULL);
-      pInfo->tqReader = tqOpenReader(pHandle->vnode);
+      pInfo->tqReader = tqReaderOpen(pHandle->vnode);
       ASSERT(pInfo->tqReader);
     } else {
       ASSERT(pHandle->tqReader);
diff --git a/source/libs/executor/src/sortoperator.c b/source/libs/executor/src/sortoperator.c
index cb0f1aa068..10933f285c 100644
--- a/source/libs/executor/src/sortoperator.c
+++ b/source/libs/executor/src/sortoperator.c
@@ -13,8 +13,10 @@
  * along with this program. If not, see .
  */
 
+#include "executorInt.h"
 #include "filter.h"
-#include "executorimpl.h"
+#include "operator.h"
+#include "querytask.h"
 #include "tdatablock.h"
 
 typedef struct SSortOperatorInfo {
diff --git a/source/libs/executor/src/sysscanoperator.c b/source/libs/executor/src/sysscanoperator.c
index 7dbf182d9a..04c6c619aa 100644
--- a/source/libs/executor/src/sysscanoperator.c
+++ b/source/libs/executor/src/sysscanoperator.c
@@ -13,7 +13,7 @@
  * along with this program. If not, see .
  */
 
-#include "executorimpl.h"
+#include "executorInt.h"
 #include "filter.h"
 #include "function.h"
 #include "functionMgt.h"
@@ -31,6 +31,9 @@
 #include "thash.h"
 #include "ttypes.h"
 #include "vnode.h"
+#include "operator.h"
+#include "querytask.h"
+
 
 typedef int (*__optSysFilter)(void* a, void* b, int16_t dtype);
 typedef int32_t (*__sys_filte)(void* pMeta, SNode* cond, SArray* result);
@@ -1482,11 +1485,7 @@ static SSDataBlock* sysTableScanUserTables(SOperatorInfo* pOperator) {
           pInfo->pIdx->init = 1;
           SSDataBlock* blk = sysTableBuildUserTablesByUids(pOperator);
           return blk;
-        } else if (flt == -2) {
-          qDebug("%s failed to get sys table info by idx, empty result", GET_TASKID(pTaskInfo));
-          return NULL;
-        } else if (flt == -1) {
-          // not idx
+        } else if ((flt == -1) || (flt == -2)) {
           qDebug("%s failed to get sys table info by idx, scan sys table one by one", GET_TASKID(pTaskInfo));
         }
       } else if (pCondition != NULL && (pInfo->pIdx != NULL && pInfo->pIdx->init == 1)) {
diff --git a/source/libs/executor/src/tfill.c b/source/libs/executor/src/tfill.c
index e59ea253cc..fc4e82b57f 100644
--- a/source/libs/executor/src/tfill.c
+++ b/source/libs/executor/src/tfill.c
@@ -20,7 +20,7 @@
 #include "tmsg.h"
 #include "ttypes.h"
 
-#include "executorimpl.h"
+#include "executorInt.h"
 #include "tcommon.h"
 #include "thash.h"
 #include "ttime.h"
@@ -408,7 +408,7 @@ static int64_t appendFilledResult(SFillInfo* pFillInfo, SSDataBlock* pBlock, int
 
   pFillInfo->numOfTotal += pFillInfo->numOfCurrent;
 
-  assert(pFillInfo->numOfCurrent == resultCapacity);
+  ASSERT(pFillInfo->numOfCurrent == resultCapacity);
   return resultCapacity;
 }
 
@@ -558,7 +558,7 @@ int64_t getNumOfResultsAfterFillGap(SFillInfo* pFillInfo, TSKEY ekey, int32_t ma
     numOfRes = taosTimeCountInterval(lastKey, pFillInfo->currentKey, pFillInfo->interval.sliding,
                                      pFillInfo->interval.slidingUnit, pFillInfo->interval.precision);
     numOfRes += 1;
-    assert(numOfRes >= numOfRows);
+    ASSERT(numOfRes >= numOfRows);
   } else {  // reach the end of data
     if ((ekey1 < pFillInfo->currentKey && FILL_IS_ASC_FILL(pFillInfo)) ||
         (ekey1 >= pFillInfo->currentKey && !FILL_IS_ASC_FILL(pFillInfo))) {
@@ -593,14 +593,14 @@ int64_t taosFillResultDataBlock(SFillInfo* pFillInfo, SSDataBlock* p, int32_t ca
   int32_t remain = taosNumOfRemainRows(pFillInfo);
 
   int64_t numOfRes = getNumOfResultsAfterFillGap(pFillInfo, pFillInfo->end, capacity);
-  assert(numOfRes <= capacity);
+  ASSERT(numOfRes <= capacity);
 
   // no data existed for fill operation now, append result according to the fill strategy
   if (remain == 0) {
     appendFilledResult(pFillInfo, p, numOfRes);
   } else {
     fillResultImpl(pFillInfo, p, (int32_t)numOfRes);
-    assert(numOfRes == pFillInfo->numOfCurrent);
+    ASSERT(numOfRes == pFillInfo->numOfCurrent);
   }
 
   qDebug("fill:%p, generated fill result, src block:%d, index:%d, brange:%" PRId64 "-%" PRId64 ", currentKey:%" PRId64
diff --git a/source/libs/executor/src/timesliceoperator.c b/source/libs/executor/src/timesliceoperator.c
index f0e25d8cc5..29e3668ec4 100644
--- a/source/libs/executor/src/timesliceoperator.c
+++ b/source/libs/executor/src/timesliceoperator.c
@@ -12,10 +12,12 @@
  * You should have received a copy of the GNU Affero General Public License
  * along with this program. If not, see .
  */
-#include "executorimpl.h"
+#include "executorInt.h"
 #include "filter.h"
 #include "function.h"
 #include "functionMgt.h"
+#include "operator.h"
+#include "querytask.h"
 #include "tcommon.h"
 #include "tcompare.h"
 #include "tdatablock.h"
diff --git a/source/libs/executor/src/timewindowoperator.c b/source/libs/executor/src/timewindowoperator.c
index fd502f51a8..1ba23e09c9 100644
--- a/source/libs/executor/src/timewindowoperator.c
+++ b/source/libs/executor/src/timewindowoperator.c
@@ -12,10 +12,12 @@
  * You should have received a copy of the GNU Affero General Public License
  * along with this program. If not, see .
  */
-#include "executorimpl.h"
+#include "executorInt.h"
 #include "filter.h"
 #include "function.h"
 #include "functionMgt.h"
+#include "operator.h"
+#include "querytask.h"
 #include "tcommon.h"
 #include "tcompare.h"
 #include "tdatablock.h"
@@ -25,6 +27,12 @@
 #define IS_FINAL_OP(op)    ((op)->isFinal)
 #define DEAULT_DELETE_MARK (1000LL * 60LL * 60LL * 24LL * 365LL * 10LL);
 
+typedef struct SStateWindowInfo {
+  SResultWindowInfo winInfo;
+  SStateKeys*       pStateKey;
+} SStateWindowInfo;
+
+
 typedef struct SSessionAggOperatorInfo {
   SOptrBasicInfo     binfo;
   SAggSupporter      aggSup;
@@ -153,7 +161,7 @@ FORCE_INLINE int32_t getForwardStepsInBlock(int32_t numOfRows, __block_search_fn
     //    }
   }
 
-  assert(forwardRows >= 0);
+  ASSERT(forwardRows >= 0);
   return forwardRows;
 }
 
@@ -165,8 +173,6 @@ int32_t binarySearchForKey(char* pValue, int num, TSKEY key, int order) {
     return -1;
   }
 
-  assert(order == TSDB_ORDER_ASC || order == TSDB_ORDER_DESC);
-
   TSKEY*  keyList = (TSKEY*)pValue;
   int32_t firstPos = 0;
   int32_t lastPos = num - 1;
@@ -230,7 +236,7 @@ int32_t binarySearchForKey(char* pValue, int num, TSKEY key, int order) {
 
 int32_t getNumOfRowsInTimeWindow(SDataBlockInfo* pDataBlockInfo, TSKEY* pPrimaryColumn, int32_t startPos, TSKEY ekey,
                                  __block_search_fn_t searchFn, STableQueryInfo* item, int32_t order) {
-  assert(startPos >= 0 && startPos < pDataBlockInfo->rows);
+  ASSERT(startPos >= 0 && startPos < pDataBlockInfo->rows);
 
   int32_t num = -1;
   int32_t step = GET_FORWARD_DIRECTION_FACTOR(order);
@@ -261,7 +267,6 @@ int32_t getNumOfRowsInTimeWindow(SDataBlockInfo* pDataBlockInfo, TSKEY* pPrimary
     }
   }
 
-  assert(num >= 0);
   return num;
 }
 
@@ -433,7 +438,7 @@ static bool setTimeWindowInterpolationEndTs(SIntervalAggOperatorInfo* pInfo, SEx
   }
 
   int32_t nextRowIndex = endRowIndex + 1;
-  assert(nextRowIndex >= 0);
+  ASSERT(nextRowIndex >= 0);
 
   TSKEY nextKey = tsCols[nextRowIndex];
   doTimeWindowInterpolation(pInfo->pPrevValues, pDataBlock, actualEndKey, endRowIndex, nextKey, nextRowIndex, key,
@@ -494,9 +499,9 @@ static int32_t getNextQualifiedWindow(SInterval* pInterval, STimeWindow* pNext,
    */
   if (primaryKeys == NULL) {
     if (ascQuery) {
-      assert(pDataBlockInfo->window.skey <= pNext->ekey);
+      ASSERT(pDataBlockInfo->window.skey <= pNext->ekey);
     } else {
-      assert(pDataBlockInfo->window.ekey >= pNext->skey);
+      ASSERT(pDataBlockInfo->window.ekey >= pNext->skey);
     }
   } else {
     if (ascQuery && primaryKeys[startPos] > pNext->ekey) {
@@ -533,7 +538,6 @@ static bool isResultRowInterpolated(SResultRow* pResult, SResultTsInterpType typ
 }
 
 static void setResultRowInterpo(SResultRow* pResult, SResultTsInterpType type) {
-  assert(pResult != NULL && (type == RESULT_ROW_START_INTERP || type == RESULT_ROW_END_INTERP));
   if (type == RESULT_ROW_START_INTERP) {
     pResult->startInterp = true;
   } else {
@@ -1616,7 +1620,7 @@ void destroyStreamFinalIntervalOperatorInfo(void* param) {
     int32_t size = taosArrayGetSize(pInfo->pChildren);
     for (int32_t i = 0; i < size; i++) {
       SOperatorInfo* pChildOp = taosArrayGetP(pInfo->pChildren, i);
-      destroyOperatorInfo(pChildOp);
+      destroyOperator(pChildOp);
     }
     taosArrayDestroy(pInfo->pChildren);
   }
@@ -2845,7 +2849,7 @@ void destroyStreamSessionAggOperatorInfo(void* param) {
     int32_t size = taosArrayGetSize(pInfo->pChildren);
     for (int32_t i = 0; i < size; i++) {
       SOperatorInfo* pChild = taosArrayGetP(pInfo->pChildren, i);
-      destroyOperatorInfo(pChild);
+      destroyOperator(pChild);
     }
     taosArrayDestroy(pInfo->pChildren);
   }
@@ -3822,7 +3826,7 @@ void destroyStreamStateOperatorInfo(void* param) {
     int32_t size = taosArrayGetSize(pInfo->pChildren);
     for (int32_t i = 0; i < size; i++) {
       SOperatorInfo* pChild = taosArrayGetP(pInfo->pChildren, i);
-      destroyOperatorInfo(pChild);
+      destroyOperator(pChild);
     }
     taosArrayDestroy(pInfo->pChildren);
   }
diff --git a/source/libs/executor/src/tsort.c b/source/libs/executor/src/tsort.c
index 6c8e581b3f..36e41b0c5d 100644
--- a/source/libs/executor/src/tsort.c
+++ b/source/libs/executor/src/tsort.c
@@ -155,7 +155,7 @@ void tsortDestroySortHandle(SSortHandle* pSortHandle) {
 
   int64_t fetchUs = 0, fetchNum = 0;
   tsortClearOrderdSource(pSortHandle->pOrderedSource, &fetchUs, &fetchNum);
-  qError("all source fetch time: %" PRId64 "us num:%" PRId64 " %s", fetchUs, fetchNum, pSortHandle->idStr);
+  qDebug("all source fetch time: %" PRId64 "us num:%" PRId64 " %s", fetchUs, fetchNum, pSortHandle->idStr);
   
   taosArrayDestroy(pSortHandle->pOrderedSource);
   taosMemoryFreeClear(pSortHandle);
@@ -229,7 +229,7 @@ static int32_t doAddToBuf(SSDataBlock* pDataBlock, SSortHandle* pHandle) {
     taosArrayPush(pPageIdList, &pageId);
 
     int32_t size = blockDataGetSize(p) + sizeof(int32_t) + taosArrayGetSize(p->pDataBlock) * sizeof(int32_t);
-    assert(size <= getBufPageSize(pHandle->pBuf));
+    ASSERT(size <= getBufPageSize(pHandle->pBuf));
 
     blockDataToBuf(pPage, p);
 
@@ -316,7 +316,7 @@ static int32_t sortComparInit(SMsortComparParam* pParam, SArray* pSources, int32
     }
 
     int64_t et = taosGetTimestampUs();
-    qError("init for merge sort completed, elapsed time:%.2f ms, %s", (et - st) / 1000.0, pHandle->idStr);
+    qDebug("init for merge sort completed, elapsed time:%.2f ms, %s", (et - st) / 1000.0, pHandle->idStr);
   }
 
   return code;
@@ -592,7 +592,7 @@ static int32_t doInternalMergeSort(SSortHandle* pHandle) {
 
         int32_t size =
             blockDataGetSize(pDataBlock) + sizeof(int32_t) + taosArrayGetSize(pDataBlock->pDataBlock) * sizeof(int32_t);
-        assert(size <= getBufPageSize(pHandle->pBuf));
+        ASSERT(size <= getBufPageSize(pHandle->pBuf));
 
         blockDataToBuf(pPage, pDataBlock);
 
diff --git a/source/libs/executor/test/executorTests.cpp b/source/libs/executor/test/executorTests.cpp
index b9a696170a..cefe12990d 100644
--- a/source/libs/executor/test/executorTests.cpp
+++ b/source/libs/executor/test/executorTests.cpp
@@ -24,15 +24,12 @@
 #include "os.h"
 
 #include "executor.h"
-#include "executorimpl.h"
+#include "executorInt.h"
 #include "function.h"
+#include "operator.h"
 #include "taos.h"
 #include "tdatablock.h"
 #include "tdef.h"
-#include "tglobal.h"
-#include "tmsg.h"
-#include "tname.h"
-#include "trpc.h"
 #include "tvariant.h"
 
 namespace {
diff --git a/source/libs/executor/test/lhashTests.cpp b/source/libs/executor/test/lhashTests.cpp
index 24570ff788..92f7652d8d 100644
--- a/source/libs/executor/test/lhashTests.cpp
+++ b/source/libs/executor/test/lhashTests.cpp
@@ -15,7 +15,7 @@
 
 #include 
 #include 
-#include "executorimpl.h"
+#include "executorInt.h"
 #include "tlinearhash.h"
 
 #pragma GCC diagnostic push
diff --git a/source/libs/executor/test/sortTests.cpp b/source/libs/executor/test/sortTests.cpp
index f35d07804e..8122d7d6a9 100644
--- a/source/libs/executor/test/sortTests.cpp
+++ b/source/libs/executor/test/sortTests.cpp
@@ -26,7 +26,7 @@
 #include "os.h"
 
 #include "executor.h"
-#include "executorimpl.h"
+#include "executorInt.h"
 #include "taos.h"
 #include "tcompare.h"
 #include "tdatablock.h"
diff --git a/source/libs/function/src/builtinsimpl.c b/source/libs/function/src/builtinsimpl.c
index a8ecd9b0a2..4c019b3e71 100644
--- a/source/libs/function/src/builtinsimpl.c
+++ b/source/libs/function/src/builtinsimpl.c
@@ -5572,7 +5572,7 @@ int32_t blockDistFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
   }
 
   int32_t len = sprintf(st + VARSTR_HEADER_SIZE,
-                        "Total_Blocks=[%d] Total_Size=[%.2f Kb] Average_size=[%.2f Kb] Compression_Ratio=[%.2f %c]",
+                        "Total_Blocks=[%d] Total_Size=[%.2f KB] Average_size=[%.2f KB] Compression_Ratio=[%.2f %c]",
                         pData->numOfBlocks, pData->totalSize / 1024.0, averageSize / 1024.0, compRatio, '%');
 
   varDataSetLen(st, len);
diff --git a/source/libs/index/src/indexFilter.c b/source/libs/index/src/indexFilter.c
index ec5fc5ad2a..02ed0d2d05 100644
--- a/source/libs/index/src/indexFilter.c
+++ b/source/libs/index/src/indexFilter.c
@@ -221,6 +221,71 @@ static FORCE_INLINE int32_t sifInitJsonParam(SNode *node, SIFParam *param, SIFCt
   param->status = SFLT_COARSE_INDEX;
   return 0;
 }
+static int32_t sifNeedConvertCond(SNode *l, SNode *r) {
+  if (nodeType(l) != QUERY_NODE_COLUMN || nodeType(r) != QUERY_NODE_VALUE) {
+    return 0;
+  }
+  SColumnNode *c = (SColumnNode *)l;
+  SValueNode  *v = (SValueNode *)r;
+  int32_t      ctype = c->node.resType.type;
+  int32_t      vtype = v->node.resType.type;
+  if (!IS_VAR_DATA_TYPE(ctype) && IS_VAR_DATA_TYPE(vtype)) {
+    return 1;
+  }
+  return 0;
+}
+static int32_t sifInitParamValByCol(SNode *r, SNode *l, SIFParam *param, SIFCtx *ctx) {
+  param->status = SFLT_COARSE_INDEX;
+  SColumnNode *cn = (SColumnNode *)r;
+  SValueNode  *vn = (SValueNode *)l;
+  if (vn->typeData == TSDB_DATA_TYPE_NULL && (vn->literal == NULL || strlen(vn->literal) == 0)) {
+    param->status = SFLT_NOT_INDEX;
+    return 0;
+  }
+  SDataType *pType = &cn->node.resType;
+  int32_t    type = pType->type;
+
+  SDataType *pVType = &vn->node.resType;
+  int32_t    vtype = pVType->type;
+  char      *pData = nodesGetValueFromNode(vn);
+  int32_t    valLen = 0;
+  char     **value = ¶m->condValue;
+
+  if (IS_VAR_DATA_TYPE(type)) {
+    int32_t dataLen = varDataTLen(pData);
+    if (type == TSDB_DATA_TYPE_JSON) {
+      if (*pData == TSDB_DATA_TYPE_NULL) {
+        dataLen = 0;
+      } else if (*pData == TSDB_DATA_TYPE_NCHAR) {
+        dataLen = varDataTLen(pData);
+      } else if (*pData == TSDB_DATA_TYPE_DOUBLE) {
+        dataLen = LONG_BYTES;
+      } else if (*pData == TSDB_DATA_TYPE_BOOL) {
+        dataLen = CHAR_BYTES;
+      }
+      dataLen += CHAR_BYTES;
+    }
+    valLen = dataLen;
+  } else {
+    valLen = pType->bytes;
+  }
+  char *tv = taosMemoryCalloc(1, valLen + 1);
+  if (tv == NULL) {
+    return TSDB_CODE_OUT_OF_MEMORY;
+  }
+
+  memcpy(tv, pData, valLen);
+  *value = tv;
+
+  param->colId = -1;
+  param->colValType = (uint8_t)(vn->node.resType.type);
+  if (vn->literal != NULL && strlen(vn->literal) <= sizeof(param->colName)) {
+    memcpy(param->colName, vn->literal, strlen(vn->literal));
+  } else {
+    param->status = SFLT_NOT_INDEX;
+  }
+  return 0;
+}
 static int32_t sifInitParam(SNode *node, SIFParam *param, SIFCtx *ctx) {
   param->status = SFLT_COARSE_INDEX;
   switch (nodeType(node)) {
@@ -317,8 +382,13 @@ static int32_t sifInitOperParams(SIFParam **params, SOperatorNode *node, SIFCtx
     return TSDB_CODE_SUCCESS;
   } else {
     SIF_ERR_JRET(sifInitParam(node->pLeft, ¶mList[0], ctx));
+
     if (nParam > 1) {
+      // if (sifNeedConvertCond(node->pLeft, node->pRight)) {
+      // SIF_ERR_JRET(sifInitParamValByCol(node->pLeft, node->pRight, ¶mList[1], ctx));
+      // } else {
       SIF_ERR_JRET(sifInitParam(node->pRight, ¶mList[1], ctx));
+      // }
       // if (paramList[0].colValType == TSDB_DATA_TYPE_JSON &&
       //    ((SOperatorNode *)(node))->opType == OP_TYPE_JSON_CONTAINS) {
       //  return TSDB_CODE_OUT_OF_MEMORY;
@@ -404,60 +474,149 @@ static FORCE_INLINE FilterFunc sifGetFilterFunc(EIndexQueryType type, bool *reve
   }
   return NULL;
 }
+int32_t sifStr2Num(char *buf, int32_t len, int8_t type, void *val) {
+  // signed/unsigned/float
+  if (IS_SIGNED_NUMERIC_TYPE(type)) {
+    int64_t v = 0;
+    if (0 != toInteger(buf, len, 10, &v)) {
+      return -1;
+    }
+    if (type == TSDB_DATA_TYPE_BIGINT) {
+      *(int64_t *)val = v;
+    } else if (type == TSDB_DATA_TYPE_INT) {
+      *(int32_t *)val = v;
+    } else if (type == TSDB_DATA_TYPE_TINYINT) {
+      *(int8_t *)val = v;
+    } else if (type == TSDB_DATA_TYPE_SMALLINT) {
+      *(int16_t *)val = v;
+    }
+  } else if (IS_FLOAT_TYPE(type)) {
+    if (type == TSDB_DATA_TYPE_FLOAT) {
+      *(float *)val = taosStr2Float(buf, NULL);
+    } else {
+      *(double *)val = taosStr2Double(buf, NULL);
+    }
+  } else if (IS_UNSIGNED_NUMERIC_TYPE(type)) {
+    uint64_t v = 0;
+    if (0 != toUInteger(buf, len, 10, &v)) {
+      return -1;
+    }
+    if (type == TSDB_DATA_TYPE_UBIGINT) {
+      *(uint64_t *)val = v;
+    } else if (type == TSDB_DATA_TYPE_UINT) {
+      *(uint32_t *)val = v;
+    } else if (type == TSDB_DATA_TYPE_UTINYINT) {
+      *(uint8_t *)val = v;
+    } else if (type == TSDB_DATA_TYPE_USMALLINT) {
+      *(uint16_t *)val = v;
+    }
+  } else {
+    return -1;
+  }
+  return 0;
+}
 
-static void sifSetFltParam(SIFParam *left, SIFParam *right, SDataTypeBuf *typedata, SMetaFltParam *param) {
-  int8_t ltype = left->colValType, rtype = right->colValType;
+static int32_t sifSetFltParam(SIFParam *left, SIFParam *right, SDataTypeBuf *typedata, SMetaFltParam *param) {
+  int32_t code = 0;
+  int8_t  ltype = left->colValType, rtype = right->colValType;
+  if (!IS_NUMERIC_TYPE(ltype) || !((IS_NUMERIC_TYPE(rtype)) || rtype == TSDB_DATA_TYPE_VARCHAR)) {
+    return -1;
+  }
   if (ltype == TSDB_DATA_TYPE_FLOAT) {
     float f = 0;
-    SIF_DATA_CONVERT(rtype, right->condValue, f);
+    if (IS_NUMERIC_TYPE(rtype)) {
+      SIF_DATA_CONVERT(rtype, right->condValue, f);
+    } else {
+      SIF_ERR_RET(sifStr2Num(varDataVal(right->condValue), varDataLen(right->condValue), TSDB_DATA_TYPE_FLOAT, &f));
+    }
     typedata->f = f;
     param->val = &typedata->f;
   } else if (ltype == TSDB_DATA_TYPE_DOUBLE) {
     double d = 0;
-    SIF_DATA_CONVERT(rtype, right->condValue, d);
+    if (IS_NUMERIC_TYPE(rtype)) {
+      SIF_DATA_CONVERT(rtype, right->condValue, d);
+    } else {
+      SIF_ERR_RET(sifStr2Num(varDataVal(right->condValue), varDataLen(right->condValue), TSDB_DATA_TYPE_DOUBLE, &d));
+    }
     typedata->d = d;
     param->val = &typedata->d;
   } else if (ltype == TSDB_DATA_TYPE_BIGINT) {
     int64_t i64 = 0;
-    SIF_DATA_CONVERT(rtype, right->condValue, i64);
+    if (IS_NUMERIC_TYPE(rtype)) {
+      SIF_DATA_CONVERT(rtype, right->condValue, i64);
+    } else {
+      SIF_ERR_RET(sifStr2Num(varDataVal(right->condValue), varDataLen(right->condValue), TSDB_DATA_TYPE_BIGINT, &i64));
+    }
     typedata->i64 = i64;
     param->val = &typedata->i64;
   } else if (ltype == TSDB_DATA_TYPE_INT) {
     int32_t i32 = 0;
-    SIF_DATA_CONVERT(rtype, right->condValue, i32);
+    if (IS_NUMERIC_TYPE(rtype)) {
+      SIF_DATA_CONVERT(rtype, right->condValue, i32);
+    } else {
+      SIF_ERR_RET(sifStr2Num(varDataVal(right->condValue), varDataLen(right->condValue), TSDB_DATA_TYPE_INT, &i32));
+    }
     typedata->i32 = i32;
     param->val = &typedata->i32;
   } else if (ltype == TSDB_DATA_TYPE_SMALLINT) {
     int16_t i16 = 0;
-    SIF_DATA_CONVERT(rtype, right->condValue, i16);
+    if (IS_NUMERIC_TYPE(rtype)) {
+      SIF_DATA_CONVERT(rtype, right->condValue, i16);
+    } else {
+      SIF_ERR_RET(
+          sifStr2Num(varDataVal(right->condValue), varDataLen(right->condValue), TSDB_DATA_TYPE_SMALLINT, &i16));
+    }
+
     typedata->i16 = i16;
     param->val = &typedata->i16;
   } else if (ltype == TSDB_DATA_TYPE_TINYINT) {
     int8_t i8 = 0;
-    SIF_DATA_CONVERT(rtype, right->condValue, i8)
+    if (IS_NUMERIC_TYPE(rtype)) {
+      SIF_DATA_CONVERT(rtype, right->condValue, i8);
+    } else {
+      SIF_ERR_RET(sifStr2Num(varDataVal(right->condValue), varDataLen(right->condValue), TSDB_DATA_TYPE_TINYINT, &i8));
+    }
     typedata->i8 = i8;
     param->val = &typedata->i8;
   } else if (ltype == TSDB_DATA_TYPE_UBIGINT) {
     uint64_t u64 = 0;
-    SIF_DATA_CONVERT(rtype, right->condValue, u64);
+    if (IS_NUMERIC_TYPE(rtype)) {
+      SIF_DATA_CONVERT(rtype, right->condValue, u64);
+    } else {
+      SIF_ERR_RET(sifStr2Num(varDataVal(right->condValue), varDataLen(right->condValue), TSDB_DATA_TYPE_UBIGINT, &u64));
+    }
     typedata->u64 = u64;
     param->val = &typedata->u64;
   } else if (ltype == TSDB_DATA_TYPE_UINT) {
     uint32_t u32 = 0;
-    SIF_DATA_CONVERT(rtype, right->condValue, u32);
+    if (IS_NUMERIC_TYPE(rtype)) {
+      SIF_DATA_CONVERT(rtype, right->condValue, u32);
+    } else {
+      SIF_ERR_RET(sifStr2Num(varDataVal(right->condValue), varDataLen(right->condValue), TSDB_DATA_TYPE_UINT, &u32));
+    }
     typedata->u32 = u32;
     param->val = &typedata->u32;
   } else if (ltype == TSDB_DATA_TYPE_USMALLINT) {
     uint16_t u16 = 0;
-    SIF_DATA_CONVERT(rtype, right->condValue, u16);
+    if (IS_NUMERIC_TYPE(rtype)) {
+      SIF_DATA_CONVERT(rtype, right->condValue, u16);
+    } else {
+      SIF_ERR_RET(
+          sifStr2Num(varDataVal(right->condValue), varDataLen(right->condValue), TSDB_DATA_TYPE_USMALLINT, &u16));
+    }
     typedata->u16 = u16;
     param->val = &typedata->u16;
   } else if (ltype == TSDB_DATA_TYPE_UTINYINT) {
     uint8_t u8 = 0;
-    SIF_DATA_CONVERT(rtype, right->condValue, u8);
+    if (IS_NUMERIC_TYPE(rtype)) {
+      SIF_DATA_CONVERT(rtype, right->condValue, u8);
+    } else {
+      SIF_ERR_RET(sifStr2Num(varDataVal(right->condValue), varDataLen(right->condValue), TSDB_DATA_TYPE_UTINYINT, &u8));
+    }
     typedata->u8 = u8;
     param->val = &typedata->u8;
   }
+  return 0;
 }
 static int32_t sifDoIndex(SIFParam *left, SIFParam *right, int8_t operType, SIFParam *output) {
   int             ret = 0;
@@ -498,7 +657,7 @@ static int32_t sifDoIndex(SIFParam *left, SIFParam *right, int8_t operType, SIFP
         param.val = buf;
       }
     } else {
-      sifSetFltParam(left, right, &typedata, ¶m);
+      if (sifSetFltParam(left, right, &typedata, ¶m) != 0) return -1;
     }
     ret = metaFilterTableIds(arg->metaEx, ¶m, output->result);
   }
diff --git a/source/libs/index/src/indexFstDfa.c b/source/libs/index/src/indexFstDfa.c
index 4d348e76f2..a3e26d8518 100644
--- a/source/libs/index/src/indexFstDfa.c
+++ b/source/libs/index/src/indexFstDfa.c
@@ -188,7 +188,6 @@ void dfaAdd(FstDfa *dfa, FstSparseSet *set, uint32_t ip) {
     return;
   }
   bool succ = sparSetAdd(set, ip, NULL);
-  // assert(succ == true);
   Inst *inst = taosArrayGet(dfa->insts, ip);
   if (inst->ty == MATCH || inst->ty == RANGE) {
     // do nothing
diff --git a/source/libs/nodes/src/nodesUtilFuncs.c b/source/libs/nodes/src/nodesUtilFuncs.c
index 4fb49afaf4..4720ddbd7a 100644
--- a/source/libs/nodes/src/nodesUtilFuncs.c
+++ b/source/libs/nodes/src/nodesUtilFuncs.c
@@ -827,6 +827,8 @@ void nodesDestroyNode(SNode* pNode) {
       SVnodeModifyOpStmt* pStmt = (SVnodeModifyOpStmt*)pNode;
       destroyVgDataBlockArray(pStmt->pDataBlocks);
       taosMemoryFreeClear(pStmt->pTableMeta);
+      nodesDestroyNode(pStmt->pTagCond);
+      taosArrayDestroy(pStmt->pTableTag);
       taosHashCleanup(pStmt->pVgroupsHashObj);
       taosHashCleanup(pStmt->pSubTableHashObj);
       taosHashCleanup(pStmt->pTableNameHashObj);
@@ -953,8 +955,12 @@ void nodesDestroyNode(SNode* pNode) {
       break;
     case QUERY_NODE_SPLIT_VGROUP_STMT:  // no pointer field
     case QUERY_NODE_SYNCDB_STMT:        // no pointer field
-    case QUERY_NODE_GRANT_STMT:         // no pointer field
-    case QUERY_NODE_REVOKE_STMT:        // no pointer field
+      break;
+    case QUERY_NODE_GRANT_STMT:
+      nodesDestroyNode(((SGrantStmt*)pNode)->pTagCond);
+      break;
+    case QUERY_NODE_REVOKE_STMT:
+      nodesDestroyNode(((SRevokeStmt*)pNode)->pTagCond);
       break;
     case QUERY_NODE_SHOW_DNODES_STMT:
     case QUERY_NODE_SHOW_MNODES_STMT:
diff --git a/source/libs/parser/inc/sql.y b/source/libs/parser/inc/sql.y
old mode 100644
new mode 100755
index f99976e0df..5918b488b4
--- a/source/libs/parser/inc/sql.y
+++ b/source/libs/parser/inc/sql.y
@@ -221,8 +221,8 @@ db_options(A) ::= db_options(B) WAL_RETENTION_SIZE NK_MINUS(D) NK_INTEGER(C).
 db_options(A) ::= db_options(B) WAL_ROLL_PERIOD NK_INTEGER(C).                    { A = setDatabaseOption(pCxt, B, DB_OPTION_WAL_ROLL_PERIOD, &C); }
 db_options(A) ::= db_options(B) WAL_SEGMENT_SIZE NK_INTEGER(C).                   { A = setDatabaseOption(pCxt, B, DB_OPTION_WAL_SEGMENT_SIZE, &C); }
 db_options(A) ::= db_options(B) STT_TRIGGER NK_INTEGER(C).                        { A = setDatabaseOption(pCxt, B, DB_OPTION_STT_TRIGGER, &C); }
-db_options(A) ::= db_options(B) TABLE_PREFIX NK_INTEGER(C).                       { A = setDatabaseOption(pCxt, B, DB_OPTION_TABLE_PREFIX, &C); }
-db_options(A) ::= db_options(B) TABLE_SUFFIX NK_INTEGER(C).                       { A = setDatabaseOption(pCxt, B, DB_OPTION_TABLE_SUFFIX, &C); }
+db_options(A) ::= db_options(B) TABLE_PREFIX signed(C).                           { A = setDatabaseOption(pCxt, B, DB_OPTION_TABLE_PREFIX, C); }
+db_options(A) ::= db_options(B) TABLE_SUFFIX signed(C).                           { A = setDatabaseOption(pCxt, B, DB_OPTION_TABLE_SUFFIX, C); }
 
 alter_db_options(A) ::= alter_db_option(B).                                       { A = createAlterDatabaseOptions(pCxt); A = setAlterDatabaseOption(pCxt, A, &B); }
 alter_db_options(A) ::= alter_db_options(B) alter_db_option(C).                   { A = setAlterDatabaseOption(pCxt, B, &C); }
diff --git a/source/libs/parser/src/parAstCreater.c b/source/libs/parser/src/parAstCreater.c
index 2afe34c1f7..5a47ed731d 100644
--- a/source/libs/parser/src/parAstCreater.c
+++ b/source/libs/parser/src/parAstCreater.c
@@ -1024,12 +1024,28 @@ static SNode* setDatabaseOptionImpl(SAstCreateContext* pCxt, SNode* pOptions, ED
     case DB_OPTION_STT_TRIGGER:
       pDbOptions->sstTrigger = taosStr2Int32(((SToken*)pVal)->z, NULL, 10);
       break;
-    case DB_OPTION_TABLE_PREFIX:
-      pDbOptions->tablePrefix = taosStr2Int32(((SToken*)pVal)->z, NULL, 10);
+    case DB_OPTION_TABLE_PREFIX: {
+      SValueNode *pNode = (SValueNode *)pVal;
+      if (TSDB_DATA_TYPE_BIGINT == pNode->node.resType.type || TSDB_DATA_TYPE_UBIGINT == pNode->node.resType.type) {
+        pDbOptions->tablePrefix = taosStr2Int32(pNode->literal, NULL, 10);
+      } else {
+        snprintf(pCxt->pQueryCxt->pMsg, pCxt->pQueryCxt->msgLen, "invalid table_prefix data type");
+        pCxt->errCode = TSDB_CODE_PAR_SYNTAX_ERROR;        
+      }
+      nodesDestroyNode((SNode*)pNode);
       break;
-    case DB_OPTION_TABLE_SUFFIX:
-      pDbOptions->tableSuffix = taosStr2Int32(((SToken*)pVal)->z, NULL, 10);
+    }
+    case DB_OPTION_TABLE_SUFFIX:{
+      SValueNode *pNode = (SValueNode *)pVal;
+      if (TSDB_DATA_TYPE_BIGINT == pNode->node.resType.type || TSDB_DATA_TYPE_UBIGINT == pNode->node.resType.type) {
+        pDbOptions->tableSuffix = taosStr2Int32(pNode->literal, NULL, 10);
+      } else {
+        snprintf(pCxt->pQueryCxt->pMsg, pCxt->pQueryCxt->msgLen, "invalid table_suffix data type");
+        pCxt->errCode = TSDB_CODE_PAR_SYNTAX_ERROR;        
+      }
+      nodesDestroyNode((SNode*)pNode);
       break;
+    }
     default:
       break;
   }
diff --git a/source/libs/parser/src/parAuthenticator.c b/source/libs/parser/src/parAuthenticator.c
index b06d48a690..1586d8128b 100644
--- a/source/libs/parser/src/parAuthenticator.c
+++ b/source/libs/parser/src/parAuthenticator.c
@@ -70,7 +70,7 @@ static EDealRes authSubquery(SAuthCxt* pCxt, SNode* pStmt) {
   return TSDB_CODE_SUCCESS == authQuery(pCxt, pStmt) ? DEAL_RES_CONTINUE : DEAL_RES_ERROR;
 }
 
-static int32_t mergeStableTagCond(SNode** pWhere, SNode** pTagCond) {
+static int32_t mergeStableTagCond(SNode** pWhere, SNode* pTagCond) {
   SLogicConditionNode* pLogicCond = (SLogicConditionNode*)nodesMakeNode(QUERY_NODE_LOGIC_CONDITION);
   if (NULL == pLogicCond) {
     return TSDB_CODE_OUT_OF_MEMORY;
@@ -78,7 +78,7 @@ static int32_t mergeStableTagCond(SNode** pWhere, SNode** pTagCond) {
   pLogicCond->node.resType.type = TSDB_DATA_TYPE_BOOL;
   pLogicCond->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_BOOL].bytes;
   pLogicCond->condType = LOGIC_COND_TYPE_AND;
-  int32_t code = nodesListMakeStrictAppend(&pLogicCond->pParameterList, *pTagCond);
+  int32_t code = nodesListMakeStrictAppend(&pLogicCond->pParameterList, pTagCond);
   if (TSDB_CODE_SUCCESS == code) {
     code = nodesListMakeAppend(&pLogicCond->pParameterList, *pWhere);
   }
@@ -106,7 +106,7 @@ static int32_t appendStableTagCond(SNode** pWhere, SNode* pTagCond) {
     return nodesListStrictAppend(((SLogicConditionNode*)*pWhere)->pParameterList, pTagCondCopy);
   }
 
-  return mergeStableTagCond(pWhere, &pTagCondCopy);
+  return mergeStableTagCond(pWhere, pTagCondCopy);
 }
 
 static EDealRes authSelectImpl(SNode* pNode, void* pContext) {
diff --git a/source/libs/parser/src/parInsertSql.c b/source/libs/parser/src/parInsertSql.c
index eb2efd573d..02de9f227d 100644
--- a/source/libs/parser/src/parInsertSql.c
+++ b/source/libs/parser/src/parInsertSql.c
@@ -53,6 +53,7 @@ typedef struct SInsertParseContext {
   bool           missCache;
   bool           usingDuplicateTable;
   bool           forceUpdate;
+  bool           needTableTagVal;
 } SInsertParseContext;
 
 typedef int32_t (*_row_append_fn_t)(SMsgBuf* pMsgBuf, const void* value, int32_t len, void* param);
@@ -577,28 +578,39 @@ static int32_t rewriteTagCondColumnImpl(STagVal* pVal, SNode** pNode) {
   if (NULL == pValue) {
     return TSDB_CODE_OUT_OF_MEMORY;
   }
-  pValue->node.resType.type = pVal->type;
+
+  pValue->node.resType = ((SColumnNode*)*pNode)->node.resType;
+  nodesDestroyNode(*pNode);
+  *pNode = (SNode*)pValue;
+
   switch (pVal->type) {
     case TSDB_DATA_TYPE_BOOL:
       pValue->datum.b = *(int8_t*)(&pVal->i64);
+      *(bool*)&pValue->typeData = pValue->datum.b;
       break;
     case TSDB_DATA_TYPE_TINYINT:
       pValue->datum.i = *(int8_t*)(&pVal->i64);
+      *(int8_t*)&pValue->typeData = pValue->datum.i;
       break;
     case TSDB_DATA_TYPE_SMALLINT:
       pValue->datum.i = *(int16_t*)(&pVal->i64);
+      *(int16_t*)&pValue->typeData = pValue->datum.i;
       break;
     case TSDB_DATA_TYPE_INT:
       pValue->datum.i = *(int32_t*)(&pVal->i64);
+      *(int32_t*)&pValue->typeData = pValue->datum.i;
       break;
     case TSDB_DATA_TYPE_BIGINT:
       pValue->datum.i = pVal->i64;
+      pValue->typeData = pValue->datum.i;
       break;
     case TSDB_DATA_TYPE_FLOAT:
       pValue->datum.d = *(float*)(&pVal->i64);
+      *(float*)&pValue->typeData = pValue->datum.d;
       break;
     case TSDB_DATA_TYPE_DOUBLE:
       pValue->datum.d = *(double*)(&pVal->i64);
+      *(double*)&pValue->typeData = pValue->datum.d;
       break;
     case TSDB_DATA_TYPE_VARCHAR:
     case TSDB_DATA_TYPE_NCHAR:
@@ -611,18 +623,23 @@ static int32_t rewriteTagCondColumnImpl(STagVal* pVal, SNode** pNode) {
       break;
     case TSDB_DATA_TYPE_TIMESTAMP:
       pValue->datum.i = pVal->i64;
+      pValue->typeData = pValue->datum.i;
       break;
     case TSDB_DATA_TYPE_UTINYINT:
       pValue->datum.i = *(uint8_t*)(&pVal->i64);
+      *(uint8_t*)&pValue->typeData = pValue->datum.i;
       break;
     case TSDB_DATA_TYPE_USMALLINT:
       pValue->datum.i = *(uint16_t*)(&pVal->i64);
+      *(uint16_t*)&pValue->typeData = pValue->datum.i;
       break;
     case TSDB_DATA_TYPE_UINT:
       pValue->datum.i = *(uint32_t*)(&pVal->i64);
+      *(uint32_t*)&pValue->typeData = pValue->datum.i;
       break;
     case TSDB_DATA_TYPE_UBIGINT:
       pValue->datum.i = *(uint64_t*)(&pVal->i64);
+      *(uint64_t*)&pValue->typeData = pValue->datum.i;
       break;
     case TSDB_DATA_TYPE_JSON:
     case TSDB_DATA_TYPE_VARBINARY:
@@ -667,16 +684,15 @@ static int32_t checkTagCondResult(SNode* pResult) {
                                                                                     : TSDB_CODE_PAR_PERMISSION_DENIED;
 }
 
-int32_t checkSubtablePrivilege(SArray* pTagVals, SArray* pTagName, SNode* pCond) {
-  int32_t code = setTagVal(pTagVals, pTagName, pCond);
-  SNode*  pNew = NULL;
+static int32_t checkSubtablePrivilege(SArray* pTagVals, SArray* pTagName, SNode** pCond) {
+  int32_t code = setTagVal(pTagVals, pTagName, *pCond);
   if (TSDB_CODE_SUCCESS == code) {
-    code = scalarCalculateConstants(pCond, &pNew);
+    code = scalarCalculateConstants(*pCond, pCond);
   }
   if (TSDB_CODE_SUCCESS == code) {
-    code = checkTagCondResult(pNew);
+    code = checkTagCondResult(*pCond);
   }
-  nodesDestroyNode(pNew);
+  NODES_DESTORY_NODE(*pCond);
   return code;
 }
 
@@ -716,6 +732,10 @@ static int32_t parseTagsClauseImpl(SInsertParseContext* pCxt, SVnodeModifyOpStmt
     }
   }
 
+  if (TSDB_CODE_SUCCESS == code && NULL != pStmt->pTagCond) {
+    code = checkSubtablePrivilege(pTagVals, pTagName, &pStmt->pTagCond);
+  }
+
   if (TSDB_CODE_SUCCESS == code && !isParseBindParam && !isJson) {
     code = tTagNew(pTagVals, 1, false, &pTag);
   }
@@ -843,7 +863,7 @@ static void setUserAuthInfo(SParseContext* pCxt, SName* pTbName, SUserAuthInfo*
   pInfo->type = AUTH_TYPE_WRITE;
 }
 
-static int32_t checkAuth(SParseContext* pCxt, SName* pTbName, bool* pMissCache) {
+static int32_t checkAuth(SParseContext* pCxt, SName* pTbName, bool* pMissCache, SNode** pTagCond) {
   int32_t       code = TSDB_CODE_SUCCESS;
   SUserAuthInfo authInfo = {0};
   setUserAuthInfo(pCxt, pTbName, &authInfo);
@@ -863,11 +883,28 @@ static int32_t checkAuth(SParseContext* pCxt, SName* pTbName, bool* pMissCache)
       *pMissCache = true;
     } else if (!authRes.pass) {
       code = TSDB_CODE_PAR_PERMISSION_DENIED;
+    } else if (NULL != authRes.pCond) {
+      *pTagCond = authRes.pCond;
     }
   }
   return code;
 }
 
+static int32_t checkAuthForTable(SParseContext* pCxt, SName* pTbName, bool* pMissCache, bool* pNeedTableTagVal) {
+  SNode*  pTagCond = NULL;
+  int32_t code = checkAuth(pCxt, pTbName, pMissCache, &pTagCond);
+  if (TSDB_CODE_SUCCESS == code) {
+    *pNeedTableTagVal = ((*pMissCache) || (NULL != pTagCond));
+    *pMissCache = (NULL != pTagCond);
+  }
+  nodesDestroyNode(pTagCond);
+  return code;
+}
+
+static int32_t checkAuthForStable(SParseContext* pCxt, SName* pTbName, bool* pMissCache, SNode** pTagCond) {
+  return checkAuth(pCxt, pTbName, pMissCache, pTagCond);
+}
+
 static int32_t getTableMeta(SInsertParseContext* pCxt, SName* pTbName, bool isStb, STableMeta** pTableMeta,
                             bool* pMissCache) {
   SParseContext* pComCxt = pCxt->pComCxt;
@@ -970,7 +1007,7 @@ static int32_t getTargetTableSchema(SInsertParseContext* pCxt, SVnodeModifyOpStm
     return TSDB_CODE_SUCCESS;
   }
 
-  int32_t code = checkAuth(pCxt->pComCxt, &pStmt->targetTableName, &pCxt->missCache);
+  int32_t code = checkAuthForTable(pCxt->pComCxt, &pStmt->targetTableName, &pCxt->missCache, &pCxt->needTableTagVal);
   if (TSDB_CODE_SUCCESS == code && !pCxt->missCache) {
     code = getTableMetaAndVgroup(pCxt, pStmt, &pCxt->missCache);
   }
@@ -993,7 +1030,7 @@ static int32_t getUsingTableSchema(SInsertParseContext* pCxt, SVnodeModifyOpStmt
     return TSDB_CODE_SUCCESS;
   }
 
-  int32_t code = checkAuth(pCxt->pComCxt, &pStmt->targetTableName, &pCxt->missCache);
+  int32_t code = checkAuthForStable(pCxt->pComCxt, &pStmt->usingTableName, &pCxt->missCache, &pStmt->pTagCond);
   if (TSDB_CODE_SUCCESS == code && !pCxt->missCache) {
     code = getTableMeta(pCxt, &pStmt->usingTableName, true, &pStmt->pTableMeta, &pCxt->missCache);
   }
@@ -1606,6 +1643,8 @@ static int32_t parseInsertTableClauseBottom(SInsertParseContext* pCxt, SVnodeMod
 static void resetEnvPreTable(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt) {
   insDestroyBoundColInfo(&pCxt->tags);
   taosMemoryFreeClear(pStmt->pTableMeta);
+  nodesDestroyNode(pStmt->pTagCond);
+  taosArrayDestroy(pStmt->pTableTag);
   tdDestroySVCreateTbReq(pStmt->pCreateTblReq);
   taosMemoryFreeClear(pStmt->pCreateTblReq);
   pCxt->missCache = false;
@@ -1780,14 +1819,18 @@ static int32_t createInsertQuery(SInsertParseContext* pCxt, SQuery** pOutput) {
   return code;
 }
 
-static int32_t checkAuthFromMetaData(const SArray* pUsers) {
+static int32_t checkAuthFromMetaData(const SArray* pUsers, SNode** pTagCond) {
   if (1 != taosArrayGetSize(pUsers)) {
     return TSDB_CODE_FAILED;
   }
 
   SMetaRes* pRes = taosArrayGet(pUsers, 0);
   if (TSDB_CODE_SUCCESS == pRes->code) {
-    return (*(bool*)pRes->pRes) ? TSDB_CODE_SUCCESS : TSDB_CODE_PAR_PERMISSION_DENIED;
+    SUserAuthRes* pAuth = pRes->pRes;
+    if (NULL != pAuth->pCond) {
+      *pTagCond = nodesCloneNode(pAuth->pCond);
+    }
+    return pAuth->pass ? TSDB_CODE_SUCCESS : TSDB_CODE_PAR_PERMISSION_DENIED;
   }
   return pRes->code;
 }
@@ -1826,9 +1869,40 @@ static int32_t getTableVgroupFromMetaData(const SArray* pTables, SVnodeModifyOpS
                      sizeof(SVgroupInfo));
 }
 
+static int32_t buildTagNameFromMeta(STableMeta* pMeta, SArray** pTagName) {
+  *pTagName = taosArrayInit(pMeta->tableInfo.numOfTags, TSDB_COL_NAME_LEN);
+  if (NULL == *pTagName) {
+    return TSDB_CODE_OUT_OF_MEMORY;
+  }
+  SSchema* pSchema = getTableTagSchema(pMeta);
+  for (int32_t i = 0; i < pMeta->tableInfo.numOfTags; ++i) {
+    taosArrayPush(*pTagName, pSchema[i].name);
+  }
+  return TSDB_CODE_SUCCESS;
+}
+
+static int32_t checkSubtablePrivilegeForTable(const SArray* pTables, SVnodeModifyOpStmt* pStmt) {
+  if (1 != taosArrayGetSize(pTables)) {
+    return TSDB_CODE_FAILED;
+  }
+
+  SMetaRes* pRes = taosArrayGet(pTables, 0);
+  if (TSDB_CODE_SUCCESS != pRes->code) {
+    return pRes->code;
+  }
+
+  SArray* pTagName = NULL;
+  int32_t code = buildTagNameFromMeta(pStmt->pTableMeta, &pTagName);
+  if (TSDB_CODE_SUCCESS == code) {
+    code = checkSubtablePrivilege((SArray*)pRes->pRes, pTagName, &pStmt->pTagCond);
+  }
+  taosArrayDestroy(pTagName);
+  return code;
+}
+
 static int32_t getTableSchemaFromMetaData(SInsertParseContext* pCxt, const SMetaData* pMetaData,
                                           SVnodeModifyOpStmt* pStmt, bool isStb) {
-  int32_t code = checkAuthFromMetaData(pMetaData->pUser);
+  int32_t code = checkAuthFromMetaData(pMetaData->pUser, &pStmt->pTagCond);
   if (TSDB_CODE_SUCCESS == code) {
     code = getTableMetaFromMetaData(pMetaData->pTableMeta, &pStmt->pTableMeta);
   }
@@ -1841,6 +1915,9 @@ static int32_t getTableSchemaFromMetaData(SInsertParseContext* pCxt, const SMeta
   if (TSDB_CODE_SUCCESS == code) {
     code = getTableVgroupFromMetaData(pMetaData->pTableHash, pStmt, isStb);
   }
+  if (TSDB_CODE_SUCCESS == code && !isStb && NULL != pStmt->pTagCond) {
+    code = checkSubtablePrivilegeForTable(pMetaData->pTableTag, pStmt);
+  }
   return code;
 }
 
@@ -1860,6 +1937,8 @@ static void clearCatalogReq(SCatalogReq* pCatalogReq) {
   pCatalogReq->pTableHash = NULL;
   taosArrayDestroy(pCatalogReq->pUser);
   pCatalogReq->pUser = NULL;
+  taosArrayDestroy(pCatalogReq->pTableTag);
+  pCatalogReq->pTableTag = NULL;
 }
 
 static int32_t setVnodeModifOpStmt(SInsertParseContext* pCxt, SCatalogReq* pCatalogReq, const SMetaData* pMetaData,
@@ -2033,8 +2112,15 @@ static int32_t buildInsertUserAuthReq(const char* pUser, SName* pName, SArray**
   return TSDB_CODE_SUCCESS;
 }
 
+static int32_t buildInsertTableTagReq(SName* pName, SArray** pTables) { return buildInsertTableReq(pName, pTables); }
+
 static int32_t buildInsertCatalogReq(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt, SCatalogReq* pCatalogReq) {
-  int32_t code = buildInsertUserAuthReq(pCxt->pComCxt->pUser, &pStmt->targetTableName, &pCatalogReq->pUser);
+  int32_t code = buildInsertUserAuthReq(
+      pCxt->pComCxt->pUser, (0 == pStmt->usingTableName.type ? &pStmt->targetTableName : &pStmt->usingTableName),
+      &pCatalogReq->pUser);
+  if (TSDB_CODE_SUCCESS == code && pCxt->needTableTagVal) {
+    code = buildInsertTableTagReq(&pStmt->targetTableName, &pCatalogReq->pTableTag);
+  }
   if (TSDB_CODE_SUCCESS == code) {
     if (0 == pStmt->usingTableName.type) {
       code = buildInsertDbReq(&pStmt->targetTableName, &pCatalogReq->pTableMeta);
diff --git a/source/libs/parser/src/parInsertUtil.c b/source/libs/parser/src/parInsertUtil.c
index ac504b9809..f921094752 100644
--- a/source/libs/parser/src/parInsertUtil.c
+++ b/source/libs/parser/src/parInsertUtil.c
@@ -313,7 +313,7 @@ void insDestroyTableDataCxt(STableDataCxt* pTableCxt) {
   insDestroyBoundColInfo(&pTableCxt->boundColsInfo);
   taosArrayDestroyEx(pTableCxt->pValues, destroyColVal);
   if (pTableCxt->pData) {
-    tDestroySSubmitTbData(pTableCxt->pData, TSDB_MSG_FLG_ENCODE);
+    tDestroySubmitTbData(pTableCxt->pData, TSDB_MSG_FLG_ENCODE);
     taosMemoryFree(pTableCxt->pData);
   }
   taosMemoryFree(pTableCxt);
@@ -324,7 +324,7 @@ void insDestroyVgroupDataCxt(SVgroupDataCxt* pVgCxt) {
     return;
   }
 
-  tDestroySSubmitReq2(pVgCxt->pData, TSDB_MSG_FLG_ENCODE);
+  tDestroySubmitReq(pVgCxt->pData, TSDB_MSG_FLG_ENCODE);
   taosMemoryFree(pVgCxt->pData);
   taosMemoryFree(pVgCxt);
 }
@@ -499,7 +499,7 @@ static int32_t buildSubmitReq(int32_t vgId, SSubmitReq2* pReq, void** pData, uin
   int32_t  code = TSDB_CODE_SUCCESS;
   uint32_t len = 0;
   void*    pBuf = NULL;
-  tEncodeSize(tEncodeSSubmitReq2, pReq, len, code);
+  tEncodeSize(tEncodeSubmitReq, pReq, len, code);
   if (TSDB_CODE_SUCCESS == code) {
     SEncoder encoder;
     len += sizeof(SSubmitReq2Msg);
@@ -511,7 +511,7 @@ static int32_t buildSubmitReq(int32_t vgId, SSubmitReq2* pReq, void** pData, uin
     ((SSubmitReq2Msg*)pBuf)->header.contLen = htonl(len);
     ((SSubmitReq2Msg*)pBuf)->version = htobe64(1);
     tEncoderInit(&encoder, POINTER_SHIFT(pBuf, sizeof(SSubmitReq2Msg)), len - sizeof(SSubmitReq2Msg));
-    code = tEncodeSSubmitReq2(&encoder, pReq);
+    code = tEncodeSubmitReq(&encoder, pReq);
     tEncoderClear(&encoder);
   }
 
diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c
index b44c36dde1..db1e82b910 100644
--- a/source/libs/parser/src/parTranslater.c
+++ b/source/libs/parser/src/parTranslater.c
@@ -30,6 +30,11 @@
 
 #define SYSTABLE_SHOW_TYPE_OFFSET QUERY_NODE_SHOW_DNODES_STMT
 
+typedef struct SRewriteTbNameContext {
+  int32_t          errCode;
+  char*            pTbName;
+} SRewriteTbNameContext;
+
 typedef struct STranslateContext {
   SParseContext*   pParseCxt;
   int32_t          errCode;
@@ -1310,7 +1315,8 @@ static EDealRes translateOperator(STranslateContext* pCxt, SOperatorNode* pOp) {
 }
 
 static EDealRes haveVectorFunction(SNode* pNode, void* pContext) {
-  if (isAggFunc(pNode) || isIndefiniteRowsFunc(pNode) || isWindowPseudoColumnFunc(pNode) || isInterpPseudoColumnFunc(pNode)) {
+  if (isAggFunc(pNode) || isIndefiniteRowsFunc(pNode) || isWindowPseudoColumnFunc(pNode) ||
+      isInterpPseudoColumnFunc(pNode)) {
     *((bool*)pContext) = true;
     return DEAL_RES_END;
   }
@@ -2540,6 +2546,64 @@ static int32_t setTableCacheLastMode(STranslateContext* pCxt, SSelectStmt* pSele
   return code;
 }
 
+static EDealRes doTranslateTbName(SNode** pNode, void* pContext) {
+  switch (nodeType(*pNode)) {
+    case QUERY_NODE_FUNCTION: {
+      SFunctionNode *pFunc = (SFunctionNode *)*pNode;
+      if (FUNCTION_TYPE_TBNAME == pFunc->funcType) {
+        SRewriteTbNameContext *pCxt = (SRewriteTbNameContext*)pContext;
+        SValueNode* pVal = (SValueNode*)nodesMakeNode(QUERY_NODE_VALUE);
+        if (NULL == pVal) {
+          pCxt->errCode = TSDB_CODE_OUT_OF_MEMORY;
+          return DEAL_RES_ERROR;
+        }
+
+        int32_t tbLen = strlen(pCxt->pTbName);
+        pVal->literal = taosStrdup(pCxt->pTbName);
+        if (NULL == pVal->literal) {
+          pCxt->errCode = TSDB_CODE_OUT_OF_MEMORY;
+          return DEAL_RES_ERROR;
+        }
+        pVal->isDuration = false;
+        pVal->translate = true;
+        pVal->node.resType.type = TSDB_DATA_TYPE_BINARY;
+        pVal->node.resType.bytes = tbLen + VARSTR_HEADER_SIZE;
+        pVal->datum.p = taosMemoryCalloc(1, tbLen + VARSTR_HEADER_SIZE + 1);
+        varDataSetLen(pVal->datum.p, tbLen);
+        strncpy(varDataVal(pVal->datum.p), pVal->literal, tbLen);
+        strcpy(pVal->node.userAlias, pFunc->node.userAlias);
+        strcpy(pVal->node.aliasName, pFunc->node.aliasName);
+
+        nodesDestroyNode(*pNode);
+        *pNode = (SNode*)pVal;
+      }
+      break;
+    }
+    default:
+      break;
+  }
+  return DEAL_RES_CONTINUE;
+}
+
+static int32_t replaceTbName(STranslateContext* pCxt, SSelectStmt* pSelect) {
+  if (QUERY_NODE_REAL_TABLE != nodeType(pSelect->pFromTable)) {
+    return TSDB_CODE_SUCCESS;
+  }
+
+  SRealTableNode* pTable = (SRealTableNode*)pSelect->pFromTable;
+  if (TSDB_CHILD_TABLE != pTable->pMeta->tableType && TSDB_NORMAL_TABLE != pTable->pMeta->tableType && TSDB_SYSTEM_TABLE != pTable->pMeta->tableType) {
+    return TSDB_CODE_SUCCESS;
+  }
+
+  SNode** pNode = NULL;
+  SRewriteTbNameContext pRewriteCxt = {0};
+  pRewriteCxt.pTbName = pTable->table.tableName;
+  
+  nodesRewriteExprPostOrder(&pSelect->pWhere, doTranslateTbName, &pRewriteCxt);
+
+  return pRewriteCxt.errCode;
+}
+
 static int32_t checkJoinTable(STranslateContext* pCxt, SJoinTableNode* pJoinTable) {
   if ((QUERY_NODE_TEMP_TABLE == nodeType(pJoinTable->pLeft) &&
        !isTimeLineQuery(((STempTableNode*)pJoinTable->pLeft)->pSubquery)) ||
@@ -2577,8 +2641,13 @@ static int32_t translateTable(STranslateContext* pCxt, SNode* pTable) {
         if (TSDB_SUPER_TABLE == pRealTable->pMeta->tableType) {
           pCxt->stableQuery = true;
         }
-        if (TSDB_SYSTEM_TABLE == pRealTable->pMeta->tableType && isSelectStmt(pCxt->pCurrStmt)) {
-          ((SSelectStmt*)pCxt->pCurrStmt)->isTimeLineResult = false;
+        if (TSDB_SYSTEM_TABLE == pRealTable->pMeta->tableType) {
+          if (isSelectStmt(pCxt->pCurrStmt)) {
+            ((SSelectStmt*)pCxt->pCurrStmt)->isTimeLineResult = false;
+          } else if (isDeleteStmt(pCxt->pCurrStmt)) {
+            code = TSDB_CODE_TSC_INVALID_OPERATION;
+            break;
+          }
         }
         code = addNamespace(pCxt, pRealTable);
       }
@@ -3643,6 +3712,10 @@ static int32_t translateSelectFrom(STranslateContext* pCxt, SSelectStmt* pSelect
   if (TSDB_CODE_SUCCESS == code) {
     code = setTableCacheLastMode(pCxt, pSelect);
   }
+  if (TSDB_CODE_SUCCESS == code) {
+    code = replaceTbName(pCxt, pSelect);
+  }
+  
   return code;
 }
 
@@ -4177,6 +4250,34 @@ static int32_t checkDbRetentionsOption(STranslateContext* pCxt, SNodeList* pRete
   return TSDB_CODE_SUCCESS;
 }
 
+
+static int32_t checkDbTbPrefixSuffixOptions(STranslateContext* pCxt, int32_t tbPrefix, int32_t tbSuffix) {
+  if (tbPrefix < TSDB_MIN_HASH_PREFIX || tbPrefix > TSDB_MAX_HASH_PREFIX) {
+    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_DB_OPTION,
+                                   "Invalid option table_prefix: %d valid range: [%d, %d]", tbPrefix,
+                                   TSDB_MIN_HASH_PREFIX, TSDB_MAX_HASH_PREFIX);
+  }
+
+  if (tbSuffix < TSDB_MIN_HASH_SUFFIX || tbSuffix > TSDB_MAX_HASH_SUFFIX) {
+    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_DB_OPTION,
+                                   "Invalid option table_suffix: %d valid range: [%d, %d]", tbSuffix,
+                                   TSDB_MIN_HASH_SUFFIX, TSDB_MAX_HASH_SUFFIX);
+  }
+
+  if ((tbPrefix * tbSuffix) < 0) {
+    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_DB_OPTION,
+                                   "Invalid option table_prefix & table_suffix: mixed usage not allowed");
+  }
+
+  if ((tbPrefix + tbSuffix) >= (TSDB_TABLE_NAME_LEN - 1)) {
+    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_DB_OPTION,
+                                   "Invalid option table_prefix & table_suffix: exceed max table name length");
+  }
+
+  return TSDB_CODE_SUCCESS;
+}
+
+
 static int32_t checkOptionsDependency(STranslateContext* pCxt, const char* pDbName, SDatabaseOptions* pOptions) {
   int32_t daysPerFile = pOptions->daysPerFile;
   int64_t daysToKeep0 = pOptions->keep[0];
@@ -4284,10 +4385,7 @@ static int32_t checkDatabaseOptions(STranslateContext* pCxt, const char* pDbName
     code = checkDbRangeOption(pCxt, "sstTrigger", pOptions->sstTrigger, TSDB_MIN_STT_TRIGGER, TSDB_MAX_STT_TRIGGER);
   }
   if (TSDB_CODE_SUCCESS == code) {
-    code = checkDbRangeOption(pCxt, "tablePrefix", pOptions->tablePrefix, TSDB_MIN_HASH_PREFIX, TSDB_MAX_HASH_PREFIX);
-  }
-  if (TSDB_CODE_SUCCESS == code) {
-    code = checkDbRangeOption(pCxt, "tableSuffix", pOptions->tableSuffix, TSDB_MIN_HASH_SUFFIX, TSDB_MAX_HASH_SUFFIX);
+    code = checkDbTbPrefixSuffixOptions(pCxt, pOptions->tablePrefix, pOptions->tableSuffix);
   }
   if (TSDB_CODE_SUCCESS == code) {
     code = checkOptionsDependency(pCxt, pDbName, pOptions);
@@ -5228,7 +5326,8 @@ static int32_t checkAlterSuperTableBySchema(STranslateContext* pCxt, SAlterTable
     }
 
     if (TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES == pStmt->alterType) {
-      if (calcTypeBytes(pStmt->dataType) > TSDB_MAX_FIELD_LEN) {
+      if ((TSDB_DATA_TYPE_VARCHAR == pStmt->dataType.type && calcTypeBytes(pStmt->dataType) > TSDB_MAX_BINARY_LEN) ||
+          (TSDB_DATA_TYPE_NCHAR == pStmt->dataType.type && calcTypeBytes(pStmt->dataType) > TSDB_MAX_NCHAR_LEN)) {
         return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_VAR_COLUMN_LEN);
       }
 
@@ -5253,6 +5352,11 @@ static int32_t checkAlterSuperTableBySchema(STranslateContext* pCxt, SAlterTable
       return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_TOO_MANY_COLUMNS);
     }
 
+    if ((TSDB_DATA_TYPE_VARCHAR == pStmt->dataType.type && calcTypeBytes(pStmt->dataType) > TSDB_MAX_BINARY_LEN) ||
+        (TSDB_DATA_TYPE_NCHAR == pStmt->dataType.type && calcTypeBytes(pStmt->dataType) > TSDB_MAX_NCHAR_LEN)) {
+      return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_VAR_COLUMN_LEN);
+    }
+
     if (pTableMeta->tableInfo.rowSize + calcTypeBytes(pStmt->dataType) > TSDB_MAX_BYTES_PER_ROW) {
       return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ROW_LENGTH, TSDB_MAX_BYTES_PER_ROW);
     }
@@ -6020,17 +6124,50 @@ static bool isEventWindowQuery(SSelectStmt* pSelect) {
   return NULL != pSelect->pWindow && QUERY_NODE_EVENT_WINDOW == nodeType(pSelect->pWindow);
 }
 
+static bool hasJsonTypeProjection(SSelectStmt* pSelect) {
+  SNode* pProj = NULL;
+  FOREACH(pProj, pSelect->pProjectionList) {
+    if (TSDB_DATA_TYPE_JSON == ((SExprNode*)pProj)->resType.type) {
+      return true;
+    }
+  }
+  return false;
+}
+
+static EDealRes hasColumnOrPseudoColumn(SNode* pNode, void* pContext) {
+  if (QUERY_NODE_COLUMN == nodeType(pNode)) {
+    *(bool*)pContext = true;
+    return DEAL_RES_END;
+  }
+  if (QUERY_NODE_FUNCTION == nodeType(pNode) && fmIsPseudoColumnFunc(((SFunctionNode*)pNode)->funcId)) {
+    *(bool*)pContext = true;
+    return DEAL_RES_END;
+  }
+  return DEAL_RES_CONTINUE;
+}
+
+static int32_t subtableExprHasColumnOrPseudoColumn(SNode* pNode) {
+  bool hasColumn = false;
+  nodesWalkExprPostOrder(pNode, hasColumnOrPseudoColumn, &hasColumn);
+  return hasColumn;
+}
+
 static int32_t checkStreamQuery(STranslateContext* pCxt, SCreateStreamStmt* pStmt) {
   SSelectStmt* pSelect = (SSelectStmt*)pStmt->pQuery;
   if (TSDB_DATA_TYPE_TIMESTAMP != ((SExprNode*)nodesListGetNode(pSelect->pProjectionList, 0))->resType.type ||
       !pSelect->isTimeLineResult || crossTableWithoutAggOper(pSelect) || NULL != pSelect->pOrderByList ||
-      crossTableWithUdaf(pSelect) || isEventWindowQuery(pSelect)) {
+      crossTableWithUdaf(pSelect) || isEventWindowQuery(pSelect) || hasJsonTypeProjection(pSelect)) {
     return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_STREAM_QUERY, "Unsupported stream query");
   }
   if (NULL != pSelect->pSubtable && TSDB_DATA_TYPE_VARCHAR != ((SExprNode*)pSelect->pSubtable)->resType.type) {
     return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_STREAM_QUERY,
                                    "SUBTABLE expression must be of VARCHAR type");
   }
+  if (NULL != pSelect->pSubtable && 0 == LIST_LENGTH(pSelect->pPartitionByList) && subtableExprHasColumnOrPseudoColumn(pSelect->pSubtable)) {
+    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_STREAM_QUERY,
+                                   "SUBTABLE expression must not has column when no partition by clause");
+  }
+
   if (NULL == pSelect->pWindow && STREAM_TRIGGER_AT_ONCE != pStmt->pOptions->triggerType) {
     return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_STREAM_QUERY,
                                    "The trigger mode of non window query can only be AT_ONCE");
@@ -6568,22 +6705,40 @@ static int32_t createRealTableForGrantTable(SGrantStmt* pStmt, SRealTableNode**
 }
 
 static int32_t translateGrantTagCond(STranslateContext* pCxt, SGrantStmt* pStmt, SAlterUserReq* pReq) {
-  if (NULL == pStmt->pTagCond) {
-    return TSDB_CODE_SUCCESS;
-  }
+  SRealTableNode* pTable = NULL;
   if ('\0' == pStmt->tabName[0] || '*' == pStmt->tabName[0]) {
-    return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_SYNTAX_ERROR,
-                                   "The With clause can only be used for table level privilege");
+    if (pStmt->pTagCond) {
+      return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_SYNTAX_ERROR,
+                                     "The With clause can only be used for table level privilege");
+    } else {
+      return TSDB_CODE_SUCCESS;
+    }
   }
 
-  pCxt->pCurrStmt = (SNode*)pStmt;
-  SRealTableNode* pTable = NULL;
   int32_t         code = createRealTableForGrantTable(pStmt, &pTable);
   if (TSDB_CODE_SUCCESS == code) {
     SName name;
     code = getTableMetaImpl(pCxt, toName(pCxt->pParseCxt->acctId, pTable->table.dbName, pTable->table.tableName, &name),
                             &(pTable->pMeta));
+    if (code) {
+      nodesDestroyNode((SNode*)pTable);
+      return code;
+    }
+
+    if (TSDB_SUPER_TABLE != pTable->pMeta->tableType && TSDB_NORMAL_TABLE != pTable->pMeta->tableType) {
+      nodesDestroyNode((SNode*)pTable);
+      return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_SYNTAX_ERROR,
+                                     "Only supertable and normal table can be granted");
+    }
   }
+
+  if (TSDB_CODE_SUCCESS == code && NULL == pStmt->pTagCond) {
+    nodesDestroyNode((SNode*)pTable);
+    return TSDB_CODE_SUCCESS;
+  }
+
+  pCxt->pCurrStmt = (SNode*)pStmt;
+
   if (TSDB_CODE_SUCCESS == code) {
     code = addNamespace(pCxt, pTable);
   }
@@ -6617,6 +6772,7 @@ static int32_t translateGrant(STranslateContext* pCxt, SGrantStmt* pStmt) {
   if (TSDB_CODE_SUCCESS == code) {
     code = buildCmdMsg(pCxt, TDMT_MND_ALTER_USER, (FSerializeFunc)tSerializeSAlterUserReq, &req);
   }
+  tFreeSAlterUserReq(&req);
   return code;
 }
 
@@ -8115,6 +8271,11 @@ static int32_t buildAddColReq(STranslateContext* pCxt, SAlterTableStmt* pStmt, S
     return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_DUPLICATED_COLUMN);
   }
 
+  if ((TSDB_DATA_TYPE_VARCHAR == pStmt->dataType.type && calcTypeBytes(pStmt->dataType) > TSDB_MAX_BINARY_LEN) ||
+      (TSDB_DATA_TYPE_NCHAR == pStmt->dataType.type && calcTypeBytes(pStmt->dataType) > TSDB_MAX_NCHAR_LEN)) {
+    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_VAR_COLUMN_LEN);
+  }
+
   if (TSDB_MAX_COLUMNS == pTableMeta->tableInfo.numOfColumns) {
     return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_TOO_MANY_COLUMNS);
   }
@@ -8167,6 +8328,11 @@ static int32_t buildUpdateColReq(STranslateContext* pCxt, SAlterTableStmt* pStmt
     return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_MODIFY_COL);
   }
 
+  if ((TSDB_DATA_TYPE_VARCHAR == pStmt->dataType.type && calcTypeBytes(pStmt->dataType) > TSDB_MAX_BINARY_LEN) ||
+      (TSDB_DATA_TYPE_NCHAR == pStmt->dataType.type && calcTypeBytes(pStmt->dataType) > TSDB_MAX_NCHAR_LEN)) {
+    return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_VAR_COLUMN_LEN);
+  }
+
   if (pTableMeta->tableInfo.rowSize + pReq->colModBytes - pSchema->bytes > TSDB_MAX_BYTES_PER_ROW) {
     return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ROW_LENGTH, TSDB_MAX_BYTES_PER_ROW);
   }
diff --git a/source/libs/parser/src/sql.c b/source/libs/parser/src/sql.c
index 9ad5bcf644..2e473455e4 100644
--- a/source/libs/parser/src/sql.c
+++ b/source/libs/parser/src/sql.c
@@ -142,6 +142,7 @@ typedef union {
 #define YYFALLBACK 1
 #define YYNSTATE             762
 #define YYNRULE              583
+#define YYNRULE_WITH_ACTION  583
 #define YYNTOKEN             330
 #define YY_MAX_SHIFT         761
 #define YY_MIN_SHIFTREDUCE   1136
@@ -217,711 +218,744 @@ typedef union {
 **  yy_default[]       Default action for each state.
 **
 *********** Begin parsing tables **********************************************/
-#define YY_ACTTAB_COUNT (2905)
+#define YY_ACTTAB_COUNT (2904)
 static const YYACTIONTYPE yy_action[] = {
- /*     0 */  2116, 1881, 2010,  499,  432, 1877,  500, 1758,  431, 2102,
- /*    10 */   670, 2051,   46,   44, 1646, 1722, 2102, 2008,  640, 2098,
- /*    20 */   393,  504, 1495, 1520,   39,   38, 2098,  501,   45,   43,
- /*    30 */    42,   41,   40, 1576, 1791, 1493, 2134, 2010, 1520,  132,
- /*    40 */   131,  130,  129,  128,  127,  126,  125,  124, 2084,  384,
- /*    50 */   669,  591, 2007,  640, 2275, 2094, 2100,  374,  244, 1571,
- /*    60 */    28, 1944, 2094, 2100,  375,   19,  663,  652,  371, 2281,
- /*    70 */   184,  638, 1501,  663, 2276,  617, 1942,  628,  140, 1869,
- /*    80 */   507, 2115,  107,  500, 1758, 2151,   36,  296,  169, 2117,
- /*    90 */   673, 2119, 2120,  668,  168,  663, 1734,  758,  141,    9,
- /*   100 */    15,  735,  734,  733,  732,  403, 1884,  731,  730,  144,
+ /*     0 */  2116, 2010, 1881,  396,  434,  168,  636, 1734,  433, 1989,
+ /*    10 */   672,  162,   46,   44, 1646, 1723, 2008,  642,  374, 1894,
+ /*    20 */   393,  506, 1495,  440,   39,   38, 1942,  503,   45,   43,
+ /*    30 */    42,   41,   40, 1576, 1791, 1493,  123, 2134, 1520,  122,
+ /*    40 */   121,  120,  119,  118,  117,  116,  115,  114, 2279, 2084,
+ /*    50 */   593,  671,  593, 2275,  194, 2275,   39,   38,  167, 1571,
+ /*    60 */    45,   43,   42,   41,   40,   19, 1833,  340, 2281,  186,
+ /*    70 */  2281,  186, 1501, 2276,  619, 2276,  619,   45,   43,   42,
+ /*    80 */    41,   40, 2115,  501,  654, 2151,  502, 1758,  169, 2117,
+ /*    90 */   675, 2119, 2120,  670,  182,  665, 1520,  758,   36,  298,
+ /*   100 */    15,  735,  734,  733,  732,  405, 1931,  731,  730,  144,
  /*   110 */   725,  724,  723,  722,  721,  720,  719,  157,  715,  714,
- /*   120 */   713,  402,  401,  710,  709,  708,  707,  706,  592, 2241,
- /*   130 */   398, 2219, 1320, 1937, 1939,  123, 1578, 1579,  122,  121,
- /*   140 */   120,  119,  118,  117,  116,  115,  114, 1311,  695,  694,
- /*   150 */   693, 1315,  692, 1317, 1318,  691,  688, 2216, 1326,  685,
- /*   160 */  1328, 1329,  682,  679,  177,  652, 1551, 1561, 2280, 1409,
- /*   170 */  1410, 2275, 1577, 1580, 1944,  653, 1892,  630,  182, 2212,
- /*   180 */  2213,  356,  138, 2217,  358, 1993, 1496, 2279, 1494, 1942,
- /*   190 */  1720, 2276, 2278,  133,  287,  288,  516,   39,   38,  286,
- /*   200 */   537,   45,   43,   42,   41,   40,  278,   62,  703,  155,
- /*   210 */   154,  700,  699,  698,  152, 1499, 1500, 1794, 1550, 1553,
- /*   220 */  1554, 1555, 1556, 1557, 1558, 1559, 1560,  665,  661, 1569,
- /*   230 */  1570, 1572, 1573, 1574, 1575,    2,   46,   44,  425, 1169,
- /*   240 */  1522,  341,   62, 1518,  393,   49, 1495,   62,  611,   93,
- /*   250 */   469, 2116,  616,  483,  350, 2275,  482, 1576,  177, 1493,
- /*   260 */   406,  670,  427,  423,  405,   45,   43,   42,   41,   40,
- /*   270 */   615,  184,  452,   50,  484, 2276,  617,  454, 1171, 1994,
- /*   280 */  1174, 1175,  180, 1571,  555,  554,  553, 2134, 1723,   19,
- /*   290 */   106,  545,  137,  549, 1931, 1520, 1501,  548, 1605, 2084,
- /*   300 */   103,  669,  547,  552,  366,  365, 1521,  591,  546,  123,
- /*   310 */  2275, 1639,  122,  121,  120,  119,  118,  117,  116,  115,
- /*   320 */   114,  758,  359,  101,   15, 2281,  184,  430, 2280,  429,
- /*   330 */  2276,  617, 2115, 1191,  442, 1190, 2151,  653, 1892,  110,
- /*   340 */  2117,  673, 2119, 2120,  668, 1522,  663, 1885,  226,  143,
- /*   350 */   438,  150, 2175, 2204, 1606,  133,  428,  387, 2200,  187,
- /*   360 */  1578, 1579,  542,  480, 1519, 1192,  474,  473,  472,  471,
- /*   370 */   468,  467,  466,  465,  464,  460,  459,  458,  457,  340,
- /*   380 */   449,  448,  447,  209,  444,  443,  357,  502,  277, 1765,
- /*   390 */  1551, 1561, 2280,  338,  187, 2275, 1577, 1580, 1650,  187,
- /*   400 */   555,  554,  553,  705, 1520, 1938, 1939,  545,  137,  549,
- /*   410 */  1496, 2279, 1494,  548,  606, 2276, 2277, 1868,  547,  552,
- /*   420 */   366,  365, 1354, 1355,  546,  187, 1708, 1264,   35,  391,
+ /*   120 */   713,  404,  403,  710,  709,  708,  175,  174,  594, 2241,
+ /*   130 */   509,  654, 1320,  502, 1758,  123, 1578, 1579,  122,  121,
+ /*   140 */   120,  119,  118,  117,  116,  115,  114, 1311,  697,  696,
+ /*   150 */   695, 1315,  694, 1317, 1318,  693,  690,  179, 1326,  687,
+ /*   160 */  1328, 1329,  684,  681,   49,  640, 1551, 1561,  654, 2219,
+ /*   170 */   655, 1892, 1577, 1580, 1720,   39,   38,  360, 1993,   45,
+ /*   180 */    43,   42,   41,   40, 1409, 1410, 1496, 1523, 1494,  133,
+ /*   190 */   655, 1892,  387,   62, 1715, 2216,  539,   39,   38,  280,
+ /*   200 */   165,   45,   43,   42,   41,   40,   39,   38, 1894,  191,
+ /*   210 */    45,   43,   42,   41,   40, 1499, 1500, 1868, 1550, 1553,
+ /*   220 */  1554, 1555, 1556, 1557, 1558, 1559, 1560,  667,  663, 1569,
+ /*   230 */  1570, 1572, 1573, 1574, 1575,    2,   46,   44, 1722,  179,
+ /*   240 */    62,  343,   93, 1518,  393,  408, 1495,   62,   49,  407,
+ /*   250 */   471, 2116, 2280,  485,  352, 2275,  484, 1576, 1989, 1493,
+ /*   260 */  1994,  672,  132,  131,  130,  129,  128,  127,  126,  125,
+ /*   270 */   124, 2279,  454, 1522,  486, 2276, 2278,  456,  432,  396,
+ /*   280 */   431,  707, 2280, 1571, 1275, 2275,  211,  165, 2134,   19,
+ /*   290 */   504,  593, 1765, 1714, 2275, 1894, 1501, 1274, 1605, 1685,
+ /*   300 */  2084, 2279,  671,  196, 2010, 2276, 2277,  430,  618, 2281,
+ /*   310 */   186, 2275,  518, 2116, 2276,  619,  386,  621,   66, 2007,
+ /*   320 */   642,  758,  361,  672,   15, 1767,  617,  186, 1264,  655,
+ /*   330 */  1892, 2276,  619, 2115,  444,  257, 2151,  655, 1892,  110,
+ /*   340 */  2117,  675, 2119, 2120,  670,  189,  665, 1521,  133,  143,
+ /*   350 */  2134,  150, 2175, 2204, 1606,  544,   55,  389, 2200,  487,
+ /*   360 */  1578, 1579, 2084,  482,  671, 1266,  476,  475,  474,  473,
+ /*   370 */   470,  469,  468,  467,  466,  462,  461,  460,  459,  342,
+ /*   380 */   451,  450,  449,  613,  446,  445,  359, 1650, 1520, 1521,
+ /*   390 */  1551, 1561,  189, 1520,  545, 2115, 1577, 1580, 2151,  189,
+ /*   400 */   189,  110, 2117,  675, 2119, 2120,  670,  707,  665, 1191,
+ /*   410 */  1496, 1190, 1494, 2295,   62, 2204, 1262,  630,  140,  389,
+ /*   420 */  2200,  279,   50,  608,  641,  630,  140, 1745,   35,  391,
  /*   430 */  1600, 1601, 1602, 1603, 1604, 1608, 1609, 1610, 1611, 1499,
- /*   440 */  1500, 1552, 1550, 1553, 1554, 1555, 1556, 1557, 1558, 1559,
- /*   450 */  1560,  665,  661, 1569, 1570, 1572, 1573, 1574, 1575,    2,
- /*   460 */    12,   46,   44,  227, 1266, 1495,  167, 1521,  211,  393,
- /*   470 */  2116, 1495,  502, 1833, 1765, 1674,  578,  652, 1493,  172,
- /*   480 */   631,  705, 1576,  476, 1493,  533,  529,  525,  521,  224,
- /*   490 */  2219,   39,   38,  277, 1745,   45,   43,   42,   41,   40,
- /*   500 */   612,  607,  600, 1523, 1523,   66, 2134, 1883, 1571,  551,
- /*   510 */   550, 1501, 1520,  610,   19, 1501, 2215, 2098, 2084,  639,
- /*   520 */   669, 1501,  603,  602, 1672, 1673, 1675, 1676, 1677,   88,
- /*   530 */    39,   38,  222,   12,   45,   43,   42,   41,   40, 2134,
- /*   540 */   758, 1944, 2084,  200,  199,  543,  758, 1744,  381,   15,
- /*   550 */  1552, 2115, 1607, 2094, 2100, 2151, 1942,   49,  110, 2117,
- /*   560 */   673, 2119, 2120,  668,  663,  663,  475, 1262,  166,  514,
- /*   570 */   181, 2003, 2204,  316,   39,   38,  387, 2200,   45,   43,
- /*   580 */    42,   41,   40, 1426, 1427, 1578, 1579,  314,   73,  186,
- /*   590 */  1743,   72,   62,  609,  560, 2084, 1191, 2230, 1190,  221,
- /*   600 */   215,   62,   87,  639,  220,   12,  512,   10, 2219,  570,
- /*   610 */   207,  495,  493,  490,  696, 1551, 1561,  396,  360, 1425,
- /*   620 */  1428, 1577, 1580,  240,  213,  162,   33, 1887, 1192, 1496,
- /*   630 */   717, 1494,  372, 1894, 2214, 1496, 1612, 1494, 2084,  563,
- /*   640 */  1942, 2067,  653, 1892,  557,  653, 1892, 1944, 1742,  239,
- /*   650 */    62,  255,  193,  637,  386, 2003, 2102,  541, 1499, 1500,
- /*   660 */   189,  540, 1942,   55, 1499, 1500, 2098, 1550, 1553, 1554,
- /*   670 */  1555, 1556, 1557, 1558, 1559, 1560,  665,  661, 1569, 1570,
+ /*   440 */  1500, 1192, 1550, 1553, 1554, 1555, 1556, 1557, 1558, 1559,
+ /*   450 */  1560,  667,  663, 1569, 1570, 1572, 1573, 1574, 1575,    2,
+ /*   460 */    12,   46,   44, 1354, 1355, 1495,  402,  401,   62,  393,
+ /*   470 */  1279, 1495,  557,  556,  555,  516, 2084, 2003, 1493,  547,
+ /*   480 */   137,  551, 1576, 1278, 1493,  550, 2280, 2116,   32, 1502,
+ /*   490 */   549,  554,  368,  367,   39,   38,  548,  672,   45,   43,
+ /*   500 */    42,   41,   40, 1522, 1523, 1426, 1427, 2116, 1571,  614,
+ /*   510 */   609,  602, 1674,  699,   19, 1501, 1935,  669,  185, 2212,
+ /*   520 */  2213, 1501,  138, 2217, 2134,  632,  184, 2212, 2213,  398,
+ /*   530 */   138, 2217, 1937, 1939, 2051, 1191, 2084, 1190,  671, 1552,
+ /*   540 */   758, 1425, 1428, 1519, 2134,  489,  758,   39,   38,   15,
+ /*   550 */   228,   45,   43,   42,   41,   40, 2084,  153,  671,  605,
+ /*   560 */   604, 1672, 1673, 1675, 1676, 1677,  189, 1192,  166, 2115,
+ /*   570 */  1744,  580, 2151,  318,  189,  170, 2117,  675, 2119, 2120,
+ /*   580 */   670,  246,  665,   28, 1708, 1578, 1579,  316,   73, 2115,
+ /*   590 */    12,   72, 2151, 2094,  562,  334, 2117,  675, 2119, 2120,
+ /*   600 */   670,  668,  665,  656, 2169,  655, 1892, 2102,  107,  572,
+ /*   610 */   209,  497,  495,  492,   54, 1551, 1561, 2098,  612, 2084,
+ /*   620 */   189, 1577, 1580,  242,  438,  141,  620, 2296,  213, 1496,
+ /*   630 */   478, 1494,  504, 1884, 1765, 1496, 1794, 1494,  165,  565,
+ /*   640 */  1944, 1944, 1505,  641,  559, 2134, 1895,  358,  373,  241,
+ /*   650 */    62,  279,  195, 2100,  376, 1942, 1942, 1501, 1499, 1500,
+ /*   660 */  1169,  289,  290,  665, 1499, 1500,  288, 1550, 1553, 1554,
+ /*   670 */  1555, 1556, 1557, 1558, 1559, 1560,  667,  663, 1569, 1570,
  /*   680 */  1572, 1573, 1574, 1575,    2,   46,   44, 1581,  109,   70,
- /*   690 */  1944, 2116,   69,  393, 1879, 1495, 2084,  397,  653, 1892,
- /*   700 */  1715,  631, 2094, 2100,  388, 1942, 1576, 1741, 1493,  187,
- /*   710 */   718,   32, 1854,  663,  628,  140,  436,   39,   38,  653,
- /*   720 */  1892,   45,   43,   42,   41,   40, 1834, 2134,   81,   80,
- /*   730 */   435,   87, 1571,  191,  164,  729,  727,  437,  639, 2084,
- /*   740 */  1875,  669,   39,   38,  187, 1501,   45,   43,   42,   41,
- /*   750 */    40,  653, 1892,  187,  339, 2084, 1888,  421, 1974, 1989,
- /*   760 */   419,  415,  411,  408,  428, 1177, 1740,  653, 1892,  446,
- /*   770 */   758, 1519, 2115,   47,  653, 1892, 2151, 2116, 1739,  110,
- /*   780 */  2117,  673, 2119, 2120,  668,  461,  663,  670,  648, 1767,
- /*   790 */  2003,  181,  462, 2204,   34, 1643, 1738,  387, 2200, 1714,
- /*   800 */    39,   38,  187,  192,   45,   43,   42,   41,   40, 1578,
- /*   810 */  1579,  653, 1892, 2134, 2084,  275, 2212,  627, 2231,  134,
- /*   820 */   626,  569, 2275,  628,  140, 2084, 2084,  669, 1896,  515,
- /*   830 */  1523,  653, 1892,  196,  567, 1685,  565,  615,  184, 1551,
- /*   840 */  1561, 1989, 2276,  617, 2084, 1577, 1580,   39,   38, 1889,
- /*   850 */   420,   45,   43,   42,   41,   40, 1867,  142, 2115, 1496,
- /*   860 */  2175, 1494, 2151,  653, 1892,  110, 2117,  673, 2119, 2120,
- /*   870 */   668, 1944,  663,   84,  242,  249,   83, 2295,  241, 2204,
- /*   880 */   363,  245,  165,  387, 2200,  194, 1943,  634, 1499, 1500,
- /*   890 */  1895, 1550, 1553, 1554, 1555, 1556, 1557, 1558, 1559, 1560,
- /*   900 */   665,  661, 1569, 1570, 1572, 1573, 1574, 1575,    2,   46,
- /*   910 */    44, 2116,  655,  456, 2176,  653, 1892,  393, 1737, 1495,
- /*   920 */  1736,  670,  455, 2238,  183, 2212, 2213,  253,  138, 2217,
- /*   930 */  1576, 2116, 1493,  587,  591, 1174, 1175, 2275,   90,  345,
- /*   940 */  1662,  667,  370,  657,  571, 2176,  364, 2134,  362,  361,
- /*   950 */  1733,  539, 2281,  184, 1586, 1735, 1571, 2276,  617, 2084,
- /*   960 */  1520,  669,  653, 1892,  653, 1892, 2084, 2134, 2084, 1501,
- /*   970 */    91, 1275,  541,   42,   41,   40,  540, 2279,  254, 2084,
- /*   980 */   632,  669,  636, 2103, 1274,  703,  155,  154,  700,  699,
- /*   990 */   698,  152, 2115, 2098,  758, 2077, 2151,   47, 2084,  110,
- /*  1000 */  2117,  673, 2119, 2120,  668, 2116,  663, 2078,   14,   13,
- /*  1010 */  1732, 2295, 2115, 2204, 1731,  670, 2151,  387, 2200,  332,
- /*  1020 */  2117,  673, 2119, 2120,  668,  666,  663,  654, 2169, 2094,
- /*  1030 */  2100,   39,   38, 1578, 1579,   45,   43,   42,   41,   40,
- /*  1040 */   663, 2134,  591,  385, 1642, 2275,  485, 1989,  620,  653,
- /*  1050 */  1892,  165,  660, 2084,  591,  669,  664, 2275, 2084, 1894,
- /*  1060 */  2281,  184, 2084, 1551, 1561, 2276,  617,  291,  697, 1577,
- /*  1070 */  1580, 1935, 2281,  184, 2224, 1639,  396, 2276,  617, 1717,
- /*  1080 */  1718,  653, 1892, 1496,  165, 1494, 2115,  653, 1892, 1279,
- /*  1090 */  2151,  198, 1894,  170, 2117,  673, 2119, 2120,  668,  650,
- /*  1100 */   663,  576, 1278,  628,  140,  651, 1552,   52, 1619,    3,
- /*  1110 */   243,  701, 1499, 1500, 1935, 1550, 1553, 1554, 1555, 1556,
- /*  1120 */  1557, 1558, 1559, 1560,  665,  661, 1569, 1570, 1572, 1573,
- /*  1130 */  1574, 1575,    2,   46,   44,  653, 1892,  653, 1892, 1730,
- /*  1140 */  1729,  393,  399, 1495,  618, 2296, 1728, 2116,  591, 2070,
- /*  1150 */   165, 2275, 1727,  297, 1576,  400, 1493,  670, 1894, 2251,
- /*  1160 */   153,  623,  439, 1726,  487, 1725, 2281,  184, 1870,  252,
- /*  1170 */   310, 2276,  617, 1921, 2116,  440,  702, 1468, 1469, 1935,
- /*  1180 */  1571,   74,  232, 2134,  670,  230,  598, 2084, 2084,  146,
- /*  1190 */   573,  135,  572, 1501, 2084, 2084,  616,  669,  413, 2275,
- /*  1200 */  2084,  590, 1597,  544,  185, 2212, 2213, 1781,  138, 2217,
- /*  1210 */  2134, 2084,  148, 2084,  615,  184, 2244,   54,  758, 2276,
- /*  1220 */   617,   15, 2084,  234,  669, 1260,  233,  272, 2115,  556,
- /*  1230 */    82, 1504, 2151,  153, 2116,  110, 2117,  673, 2119, 2120,
- /*  1240 */   668, 1503,  663,  604,  670,  236,  619, 2295,  235, 2204,
- /*  1250 */  1774, 1772,  225,  387, 2200, 2115,  153, 1578, 1579, 2151,
- /*  1260 */    64,  711,  110, 2117,  673, 2119, 2120,  668,  238,  663,
- /*  1270 */  2134,  237,  558,  561, 2295,   64, 2204,  259,  621,  266,
- /*  1280 */   387, 2200, 2084, 1240,  669, 2105, 2135, 1551, 1561, 1998,
- /*  1290 */  1463, 1221,  404, 1577, 1580, 1759,  703,  155,  154,  700,
- /*  1300 */   699,  698,  152,   14,   13,  153, 1764, 1496,   48, 1494,
- /*  1310 */  1932,  284, 2234, 1466,   71, 2115,  151, 1671,  153, 2151,
- /*  1320 */   629,   53,  169, 2117,  673, 2119, 2120,  668, 1222,  663,
- /*  1330 */    48, 1768, 1670,   64,  261,   48, 1499, 1500, 2107, 1550,
- /*  1340 */  1553, 1554, 1555, 1556, 1557, 1558, 1559, 1560,  665,  661,
- /*  1350 */  1569, 1570, 1572, 1573, 1574, 1575,    2,  271,  274,  390,
- /*  1360 */   389,  677,  635, 2242,  151, 1423,  153, 2116,  289, 1509,
- /*  1370 */   136,  645,  151,  293,  712, 1305,    1,  670,    5, 2269,
- /*  1380 */  1576,  753, 1502,  407, 1507,  412,  354,  309, 1446,  441,
- /*  1390 */  1613,  304, 1562,  624, 1506,  197, 1238, 2116, 1523, 1999,
- /*  1400 */   445,  478,  450, 2134, 1518,  463, 1571,  670, 1991, 2223,
- /*  1410 */   470,  477,  479,  488,  489, 2084,  202,  669, 1332, 1501,
- /*  1420 */   486, 1336,  201, 1343,  491,  492,  204, 1341,  494,  156,
- /*  1430 */   496, 1524,  497, 2134,    4,  498,  505,  506, 1526,  508,
- /*  1440 */   212, 1521,  509,  214,  659, 2084, 1525,  669, 2115,  510,
- /*  1450 */  1527,  511, 2151,  217,  513,  110, 2117,  673, 2119, 2120,
- /*  1460 */   668,  219,  663,   85,   86, 2116, 1194, 2295,  517, 2204,
- /*  1470 */   223,  536,  534,  387, 2200,  670,  535,  538, 2115,  344,
- /*  1480 */  2060, 1882, 2151, 2057,  229,  110, 2117,  673, 2119, 2120,
- /*  1490 */   668, 1878,  663,  112,  577,  575,  231, 2295,   89, 2204,
- /*  1500 */   158, 2134,  159,  387, 2200,  149, 1880, 1876,  160, 2056,
- /*  1510 */   246,  161,  582, 2084,  580,  669,  305,  581,  585,  250,
- /*  1520 */  1453,  588,    8,  605, 2250,  248,  643,  595, 2249,  586,
- /*  1530 */   257,  601,  614, 1510, 2235, 1505, 2245,  376,  608, 2226,
- /*  1540 */   265,  173,  596,  594,  260,  268, 2115,  267,  593,  622,
- /*  1550 */  2151, 2298,  625,  110, 2117,  673, 2119, 2120,  668,  269,
- /*  1560 */   663,  377, 1513, 1515, 2274, 2179,  139, 2204,  270, 1639,
- /*  1570 */  1522,  387, 2200, 2116, 2220,  661, 1569, 1570, 1572, 1573,
- /*  1580 */  1574, 1575,  279,  670,  633,  380, 1528,   96, 2004,  306,
- /*  1590 */   641,  642, 2018, 2116, 2017, 2016,  307,  646,  273,  383,
- /*  1600 */    98,  647,  308,  670,   61,  100, 1893, 2185,  102, 2134,
- /*  1610 */  1936,  311,  754, 1855, 2076,  755,  675,  757,   51,  346,
- /*  1620 */  2075, 2084,  347,  669, 2074,  315,  300,  335,  320, 2134,
- /*  1630 */   313,  334,   78, 2071,  409, 1486,  410, 1487,  324,  190,
- /*  1640 */   414, 2084,  416,  669, 2069,  417,  418, 2068,  355, 2066,
- /*  1650 */   422, 2065,  424, 2064, 2115,   79,  426, 1449, 2151, 1448,
- /*  1660 */  2030,  110, 2117,  673, 2119, 2120,  668, 2029,  663, 2028,
- /*  1670 */   433,  434, 2027, 2177, 2115, 2204, 1400, 2116, 2151,  387,
- /*  1680 */  2200,  110, 2117,  673, 2119, 2120,  668,  670,  663, 2026,
- /*  1690 */  1982, 1981, 1979,  656,  145, 2204, 1978, 1977, 1980,  387,
- /*  1700 */  2200, 2116, 1976, 1975, 1973, 1972, 1971,  195,  451, 1970,
- /*  1710 */   453,  670, 1984, 2134, 1969, 1968, 1967, 1966, 1965, 1964,
- /*  1720 */  1963, 1962, 1961, 1960, 1959, 2084, 1958,  669, 1957, 1956,
- /*  1730 */  1955, 1954, 1953, 1952, 1983,  147, 1951, 2134, 1950, 1949,
- /*  1740 */  1948, 1947,  481, 1946, 1945, 1797,  203, 1402,  342, 2084,
- /*  1750 */  1796,  669, 1795,  205,  206,  343, 1793, 1276, 2115, 1280,
- /*  1760 */  1754, 1176, 2151,  218, 2024,  111, 2117,  673, 2119, 2120,
- /*  1770 */   668,  178,  663, 1753, 2047, 2037, 2025, 1272, 2116, 2204,
- /*  1780 */  2002, 1871, 2115, 2203, 2200,   76, 2151,   77,  670,  111,
- /*  1790 */  2117,  673, 2119, 2120,  668,  208,  663,  216, 2104,  210,
- /*  1800 */  1792, 2116,  179, 2204,  503, 1790,  518,  658, 2200,  520,
- /*  1810 */   519,  670, 1788,  522, 2134, 1214,  523, 1786,  524,  526,
- /*  1820 */  1784,  527,  528,  530, 2116,  532, 2084, 1771,  669, 1770,
- /*  1830 */  1750,  531, 1873, 1348,  670, 1347, 1872, 2134, 1263, 1261,
- /*  1840 */   726, 1259, 1258, 1257, 1256, 1255,  728, 2116, 1250, 2084,
- /*  1850 */  1252,  669, 1782, 1251, 1249,  367, 1775,  670, 1773,  671,
- /*  1860 */  2134,  228,  368, 2151,  369,  559,  111, 2117,  673, 2119,
- /*  1870 */  2120,  668, 2084,  663,  669,   63,  562, 1749,  564, 1748,
- /*  1880 */  2204,  566, 2115, 2134,  349, 2200, 2151, 1747,  568,  111,
- /*  1890 */  2117,  673, 2119, 2120,  668, 2084,  663,  669,  113, 1473,
- /*  1900 */  1475,   27, 1472, 2204, 2046, 2115, 1459, 1455, 2201, 2151,
- /*  1910 */  2116,   67,  326, 2117,  673, 2119, 2120,  668, 1457,  663,
- /*  1920 */   670, 2036, 1477,  583, 2023, 2021, 2280,   20, 2115, 1687,
- /*  1930 */    56,   17, 2151,    6,   29,  170, 2117,  673, 2119, 2120,
- /*  1940 */   668,    7,  663,  589,  256,  584, 2134,  597,  258,  599,
- /*  1950 */    59,  382,   60,  373,  163,  613, 1669,  171, 2084,  251,
- /*  1960 */   669,  262,   30,  263, 1661,  264,   21,   65,   92, 2105,
- /*  1970 */    31, 1707, 1708,   22, 1702, 2116, 1701,  378, 1706, 1705,
- /*  1980 */   379, 1636, 1635, 2022,  276,  667, 2020, 2297, 2019, 2001,
- /*  1990 */    58, 2115,   94,   95,  174, 2151, 2116,  282,  333, 2117,
- /*  2000 */   673, 2119, 2120,  668,  283,  663,  670,   23,  644, 2116,
- /*  2010 */  1667, 2134,  285,  290,   68, 2000,   97,  292,  295,  670,
- /*  2020 */   103,   13,   24, 2084, 1511,  669, 1588,   99, 1587,   11,
- /*  2030 */  1543, 1598, 2134, 2154,  175, 1566, 1564,  392,  662,  188,
- /*  2040 */    57, 1563,  672,  674, 2084, 2134,  669,   18,   37,   16,
- /*  2050 */   394,   25,  676, 1535, 1333,   26, 2115, 2084,  395,  669,
- /*  2060 */  2151,  579,  678,  332, 2117,  673, 2119, 2120,  668, 1330,
- /*  2070 */   663,  680, 2170,  681,  683, 1327,  684, 2115,  686,  761,
- /*  2080 */  1321, 2151,  687,  689,  333, 2117,  673, 2119, 2120,  668,
- /*  2090 */  2115,  663, 1319,  303, 2151,  690, 2116,  333, 2117,  673,
- /*  2100 */  2119, 2120,  668, 1325,  663,  104,  670, 1324,  298,  176,
- /*  2110 */   105, 1342, 1323,   75, 1338,  751,  747,  743,  739,  301,
- /*  2120 */  2116, 1322, 1212,  704, 1246, 1245, 1244, 1270, 1243, 1242,
- /*  2130 */   670, 1241, 2134, 1239, 1237, 1236, 1235, 1233,  716,  299,
- /*  2140 */  1232, 1231, 1230, 1229, 2084, 1228,  669, 1227, 1265, 1267,
- /*  2150 */  1224, 1223, 1218, 1220, 1219, 1789, 2134, 1217,  736,  108,
- /*  2160 */   737, 1787,  294,  738,  740,  742, 1785,  744, 2084, 1783,
- /*  2170 */   669,  748, 1769,  746,  741,  752,  745,  574,  750, 1166,
- /*  2180 */   749, 2151, 1746, 2116,  328, 2117,  673, 2119, 2120,  668,
- /*  2190 */   302,  663,  756,  670,  649, 1497,  312,  759,  760, 1721,
- /*  2200 */  1721, 2115, 1721, 1721, 1721, 2151, 1721, 2116,  317, 2117,
- /*  2210 */   673, 2119, 2120,  668, 1721,  663, 1721,  670, 1721, 2134,
- /*  2220 */  1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721,  281,
- /*  2230 */  1721, 2084, 1721,  669,  280, 1721, 1721, 1721, 1721, 1721,
- /*  2240 */  1721, 1721, 1721, 2134, 1721, 1721, 1721, 1721, 1721, 1721,
- /*  2250 */  1721, 1721, 1721, 2116,  247, 2084, 1721,  669, 1721, 1721,
- /*  2260 */  1721, 1721, 1721,  670, 2115, 1721, 1721, 1721, 2151, 2116,
- /*  2270 */  1721,  318, 2117,  673, 2119, 2120,  668, 1721,  663,  670,
- /*  2280 */  1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 2115, 2134,
- /*  2290 */  1721, 1721, 2151, 1721, 1721,  319, 2117,  673, 2119, 2120,
- /*  2300 */   668, 2084,  663,  669, 1721, 2134, 1721, 1721, 1721, 1721,
- /*  2310 */  1721, 1721, 1721, 1721, 1721, 1721, 1721, 2084, 1721,  669,
- /*  2320 */  1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 2116,
- /*  2330 */  1721, 1721, 1721, 1721, 2115, 1721, 1721, 1721, 2151,  670,
- /*  2340 */  1721,  325, 2117,  673, 2119, 2120,  668, 1721,  663, 1721,
- /*  2350 */  2115, 1721, 1721, 2116, 2151, 1721, 1721,  329, 2117,  673,
- /*  2360 */  2119, 2120,  668,  670,  663, 2134, 1721, 1721, 1721, 1721,
- /*  2370 */  1721, 1721, 1721, 1721, 1721, 1721, 1721, 2084, 1721,  669,
- /*  2380 */  2116, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 2134,
- /*  2390 */   670, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 2116,
- /*  2400 */  1721, 2084, 1721,  669, 1721, 1721, 1721, 1721, 1721,  670,
- /*  2410 */  2115, 1721, 1721, 1721, 2151, 1721, 2134,  321, 2117,  673,
- /*  2420 */  2119, 2120,  668, 1721,  663, 1721, 1721, 1721, 2084, 1721,
- /*  2430 */   669, 1721, 1721, 1721, 2115, 2134, 1721, 1721, 2151, 1721,
- /*  2440 */  1721,  330, 2117,  673, 2119, 2120,  668, 2084,  663,  669,
- /*  2450 */  2116, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721,
- /*  2460 */   670, 2115, 1721, 1721, 1721, 2151, 2116, 1721,  322, 2117,
- /*  2470 */   673, 2119, 2120,  668, 1721,  663,  670, 1721, 1721, 1721,
- /*  2480 */  2115, 1721, 1721, 1721, 2151, 1721, 2134,  331, 2117,  673,
- /*  2490 */  2119, 2120,  668, 1721,  663, 1721, 2116, 1721, 2084, 1721,
- /*  2500 */   669, 1721, 2134, 1721, 1721, 1721,  670, 1721, 1721, 1721,
- /*  2510 */  1721, 1721, 1721, 1721, 2084, 1721,  669, 2116, 1721, 1721,
- /*  2520 */  1721, 1721, 1721, 1721, 1721, 1721, 1721,  670, 1721, 1721,
- /*  2530 */  1721, 2115, 2134, 1721, 1721, 2151, 1721, 1721,  323, 2117,
- /*  2540 */   673, 2119, 2120,  668, 2084,  663,  669, 2115, 1721, 1721,
- /*  2550 */  1721, 2151, 1721, 2134,  336, 2117,  673, 2119, 2120,  668,
- /*  2560 */  1721,  663, 1721, 2116, 1721, 2084, 1721,  669, 1721, 1721,
- /*  2570 */  1721, 1721, 1721,  670, 1721, 1721, 1721, 2115, 1721, 1721,
- /*  2580 */  1721, 2151, 1721, 1721,  337, 2117,  673, 2119, 2120,  668,
- /*  2590 */  1721,  663, 1721, 1721, 1721, 1721, 1721, 1721, 2115, 2134,
- /*  2600 */  1721, 1721, 2151, 1721, 1721, 2128, 2117,  673, 2119, 2120,
- /*  2610 */   668, 2084,  663,  669, 1721, 1721, 1721, 1721, 1721, 1721,
- /*  2620 */  1721, 1721, 1721, 2116, 1721, 1721, 1721, 1721, 1721, 1721,
- /*  2630 */  1721, 1721, 1721,  670, 1721, 1721, 2116, 1721, 1721, 1721,
- /*  2640 */  1721, 1721, 1721, 1721, 2115, 1721,  670, 1721, 2151, 1721,
- /*  2650 */  1721, 2127, 2117,  673, 2119, 2120,  668, 1721,  663, 2134,
- /*  2660 */  1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721,
- /*  2670 */  1721, 2084, 2134,  669, 1721, 1721, 1721, 1721, 1721, 1721,
- /*  2680 */  1721, 1721, 1721, 1721, 2084, 1721,  669, 2116, 1721, 1721,
- /*  2690 */  1721, 1721, 1721, 1721, 1721, 1721, 1721,  670, 1721, 1721,
- /*  2700 */  1721, 1721, 1721, 1721, 2115, 1721, 1721, 1721, 2151, 1721,
- /*  2710 */  1721, 2126, 2117,  673, 2119, 2120,  668, 2115,  663, 1721,
- /*  2720 */  1721, 2151, 1721, 2134,  351, 2117,  673, 2119, 2120,  668,
- /*  2730 */  1721,  663, 1721, 2116, 1721, 2084, 1721,  669, 1721, 1721,
- /*  2740 */  1721, 1721, 1721,  670, 1721, 1721, 1721, 1721, 2116, 1721,
- /*  2750 */  1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721,  670, 1721,
- /*  2760 */  1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 2115, 2134,
- /*  2770 */  1721, 1721, 2151, 1721, 1721,  352, 2117,  673, 2119, 2120,
- /*  2780 */   668, 2084,  663,  669, 2134, 1721, 1721, 1721, 1721, 1721,
- /*  2790 */  1721, 1721, 1721, 1721, 2116, 1721, 2084, 1721,  669, 1721,
- /*  2800 */  1721, 1721, 1721, 1721,  670, 1721, 1721, 1721, 1721, 2116,
- /*  2810 */  1721, 1721, 1721, 1721, 2115, 1721, 1721, 1721, 2151,  670,
- /*  2820 */  1721,  348, 2117,  673, 2119, 2120,  668, 1721,  663, 2115,
- /*  2830 */  2134, 1721, 1721, 2151, 1721, 1721,  353, 2117,  673, 2119,
- /*  2840 */  2120,  668, 2084,  663,  669, 2134, 1721, 1721, 1721, 1721,
- /*  2850 */  1721, 1721, 1721, 1721, 1721, 1721, 1721, 2084, 1721,  669,
+ /*   690 */   202,  201,   69,  393,  639, 1495, 2003, 2116,  611, 1171,
+ /*   700 */  1974, 1174, 1175,  557,  556,  555, 1576,  633, 1493,  365,
+ /*   710 */   547,  137,  551,  477,  641,  698,  550,  618,  655, 1892,
+ /*   720 */  2275,  549,  554,  368,  367,  630,  140,  548,   81,   80,
+ /*   730 */   437, 1643, 1571,  193, 2134,  617,  186,  439, 1938, 1939,
+ /*   740 */  2276,  619,  717,  244, 1944, 1501, 2084,  243,  671,  655,
+ /*   750 */  1892,  383,   14,   13,  341,  655, 1892,  423, 1877, 1942,
+ /*   760 */   421,  417,  413,  410,  430,  650, 1743, 2003,  448, 1944,
+ /*   770 */   758,  106, 2077,   47,  463,  366,  388,  364,  363, 2115,
+ /*   780 */   541,  103, 2151, 2116, 1942,  110, 2117,  675, 2119, 2120,
+ /*   790 */   670, 1944,  665,  672, 1869,  655, 1892,  183,  397, 2204,
+ /*   800 */   101,  543,  189,  389, 2200,  542, 1942,   90,  347, 1578,
+ /*   810 */  1579,  372,   87,  573,  464, 2084,  188, 2078,  593, 1735,
+ /*   820 */  2134, 2275,  553,  552, 2230, 1885,  277, 2212,  629,  362,
+ /*   830 */   134,  628, 2084, 2275,  671, 1742, 2281,  186, 1887, 1551,
+ /*   840 */  1561, 2276,  619,  630,  140, 1577, 1580,  245,  617,  186,
+ /*   850 */   655, 1892, 1619, 2276,  619,  458, 1586, 2219,   12, 1496,
+ /*   860 */    10, 1494, 1520,  593,  457, 2115, 2275, 1741, 2151,  517,
+ /*   870 */  1879,  111, 2117,  675, 2119, 2120,  670,  657,  665, 2176,
+ /*   880 */   622, 2281,  186, 2215, 2084, 2204, 2276,  619, 1499, 1500,
+ /*   890 */  2201, 1550, 1553, 1554, 1555, 1556, 1557, 1558, 1559, 1560,
+ /*   900 */   667,  663, 1569, 1570, 1572, 1573, 1574, 1575,    2,   46,
+ /*   910 */    44,  659, 1523, 2176, 1468, 1469, 2084,  393,  427, 1495,
+ /*   920 */    52, 2116,    3,  705,  155,  154,  702,  701,  700,  152,
+ /*   930 */  1576,  633, 1493,   39,   38,  655, 1892,   45,   43,   42,
+ /*   940 */    41,   40,  429,  425,  187, 2212, 2213, 2116,  138, 2217,
+ /*   950 */   198, 1875,  655, 1892, 1889,  578, 1571,  672, 2134, 2238,
+ /*   960 */   705,  155,  154,  702,  701,  700,  152,  399, 1520, 1501,
+ /*   970 */  2084,  247,  671,  655, 1892,  165,   42,   41,   40, 2219,
+ /*   980 */  1642,   39,   38, 1894, 2134,   45,   43,   42,   41,   40,
+ /*   990 */    84,  543,  589,   83,  758,  542, 2084,   47,  671,  655,
+ /*  1000 */  1892,  593, 1740, 2115, 2275, 2214, 2151, 2116, 1552,  110,
+ /*  1010 */  2117,  675, 2119, 2120,  670, 2067,  665,  672,  634, 2281,
+ /*  1020 */   186,  183,    9, 2204, 2276,  619, 1739,  389, 2200, 2115,
+ /*  1030 */  1867,   87, 2151, 1578, 1579,  110, 2117,  675, 2119, 2120,
+ /*  1040 */   670, 2094,  665,  254, 2134, 1738,  571, 2295, 2231, 2204,
+ /*  1050 */   146, 2084,  135,  389, 2200, 1883, 2084, 1888,  671,  569,
+ /*  1060 */   256,  567, 1989, 1551, 1561, 2098,   34,  655, 1892, 1577,
+ /*  1070 */  1580, 1607,   39,   38, 1662, 2084,   45,   43,   42,   41,
+ /*  1080 */    40,  729,  727, 1496, 1896, 1494,  638,  655, 1892, 2115,
+ /*  1090 */   655, 1892, 2151,  164, 2084,  169, 2117,  675, 2119, 2120,
+ /*  1100 */   670, 2100,  665, 1174, 1175,  312,  293,  200, 1921,  652,
+ /*  1110 */   623,  665, 1499, 1500, 1552, 1550, 1553, 1554, 1555, 1556,
+ /*  1120 */  1557, 1558, 1559, 1560,  667,  663, 1569, 1570, 1572, 1573,
+ /*  1130 */  1574, 1575,    2,   46,   44, 1737, 2242, 2116,  655, 1892,
+ /*  1140 */  1736,  393, 1733, 1495, 2094,   33, 1732,  672, 1731, 2251,
+ /*  1150 */   655, 1892,  655, 1892, 1576, 1612, 1493,  653, 2102,  705,
+ /*  1160 */   155,  154,  702,  701,  700,  152, 1730,  142, 2098,  299,
+ /*  1170 */  2175,  400, 2224, 1639, 2134, 1944,  703, 1177,  704, 1935,
+ /*  1180 */  1571, 1935, 1729, 1519, 2084, 2094, 2084, 1728,  671, 2084,
+ /*  1190 */  1943, 2084, 2094, 1501, 1870, 2084,  625, 2084, 1727, 2102,
+ /*  1200 */  1726, 1725, 2070,  251, 2100,  377, 2103,  718,  234, 2098,
+ /*  1210 */  1854,  232,   74,  592,  665, 2084, 2098,  236,  758, 2115,
+ /*  1220 */   235,   15, 2151, 2116,  422,  110, 2117,  675, 2119, 2120,
+ /*  1230 */   670, 2084,  665,  672, 1639,  600, 2084, 2295,  148, 2204,
+ /*  1240 */   153,  441,  546,  389, 2200, 2100,  390, 2084, 1781, 2084,
+ /*  1250 */  2084,  415, 2100,  238,  442,  665,  237, 1578, 1579, 1774,
+ /*  1260 */  2134,   82,  665,  240, 1260,  153,  239, 1772,  711,  575,
+ /*  1270 */   558,  574, 2084,  662,  671,   64,  255,   64,  261, 1717,
+ /*  1280 */  1718,  560,   14,   13,  666, 2105, 1834, 1551, 1561,  563,
+ /*  1290 */  1240, 2244,  274, 1577, 1580,  227,  268, 1463,  606, 1832,
+ /*  1300 */  1504, 1503,  712, 1831,  153, 2115,   48, 1496, 2151, 1494,
+ /*  1310 */  2135,  110, 2117,  675, 2119, 2120,  670,  286,  665,   91,
+ /*  1320 */    71,  151, 1466, 2295, 1238, 2204,  406,   64,   48,  389,
+ /*  1330 */  2200, 1998, 1671,   53, 1670,  263, 1499, 1500, 2107, 1550,
+ /*  1340 */  1553, 1554, 1555, 1556, 1557, 1558, 1559, 1560,  667,  663,
+ /*  1350 */  1569, 1570, 1572, 1573, 1574, 1575,    2, 2116,  402,  401,
+ /*  1360 */  1221,  637,  153, 1423,   48,  679, 1768,  672, 1509, 2269,
+ /*  1370 */   151, 1764,  153, 1759,  291, 1932, 2234,  647,  295, 1576,
+ /*  1380 */   136, 1502,  631, 2116, 1613, 1562,  276,  151,  273,    1,
+ /*  1390 */     5,  409,  356,  672, 2134, 2223,  414, 1222, 1446,  306,
+ /*  1400 */   199,  443, 1523, 1999,  480, 1571, 2084,  447,  671,  452,
+ /*  1410 */  1518,  490,  465, 1991,  479,  472,  753,  491, 1501, 1305,
+ /*  1420 */  2134,  311, 1332, 1597,  481,  488,  203, 1336,  626, 1343,
+ /*  1430 */  2116,  204, 2084,  493,  671,  494,  206, 1341,  496, 2115,
+ /*  1440 */   672,  498, 2151,  661,  156,  110, 2117,  675, 2119, 2120,
+ /*  1450 */   670, 2116,  665, 1507, 1506, 1524,    4, 2295,  499, 2204,
+ /*  1460 */   507,  672, 1526,  389, 2200, 2115,  500, 2134, 2151,  508,
+ /*  1470 */   510,  110, 2117,  675, 2119, 2120,  670, 1521,  665, 2084,
+ /*  1480 */  1525,  671,  214, 2295,  511, 2204,  512,  216, 2134,  389,
+ /*  1490 */  2200, 1527,  513, 1194,  219,  515,  221,   85,   86,  519,
+ /*  1500 */  2084,  536,  671,  225,  538,  537,  112,  346,  540, 1882,
+ /*  1510 */   231, 1878, 2115, 2060,  577, 2151, 2057, 2056,  170, 2117,
+ /*  1520 */   675, 2119, 2120,  670,  579,  665,  233,   89,  149,  307,
+ /*  1530 */   158,  159, 1510, 2115, 1505,  248, 2151, 1880, 1876,  110,
+ /*  1540 */  2117,  675, 2119, 2120,  670,  160,  665,  161,  583,  252,
+ /*  1550 */   582, 2179, 1453, 2204,  584, 2116,  597,  389, 2200,  607,
+ /*  1560 */   587, 1513, 1515,  250, 2250,  672,  590,  645,  259,  588,
+ /*  1570 */  2297, 2235, 2245,  603,  663, 1569, 1570, 1572, 1573, 1574,
+ /*  1580 */  1575,  262, 2249,    8,  616,  378,  610, 2226,  598,  596,
+ /*  1590 */   595,  267, 2134,  379,  139,  272, 1639, 2298,  627, 1522,
+ /*  1600 */   624, 2220,  382,  635, 2084,  269,  671, 1528, 2004,  308,
+ /*  1610 */   643,  281,   96,  309,  644,  648,   98, 2018, 2017, 2016,
+ /*  1620 */   649, 2116,  173,  385,  270, 1893,  271,  100,   61,  102,
+ /*  1630 */  2185,  672, 1936,  313, 1855,  310,  754, 2115,  302,  755,
+ /*  1640 */  2151,  757,  348,  110, 2117,  675, 2119, 2120,  670, 2116,
+ /*  1650 */   665, 2274,  677,  275,  337, 2177,   51, 2204, 2134,  672,
+ /*  1660 */   322,  389, 2200,  336,  326,  317, 2076, 2075,  349, 2074,
+ /*  1670 */  2084,  315,  671,   78, 2071,  411,  412, 1486, 1487,  192,
+ /*  1680 */   416, 2116, 2069,  418,  419,  420, 2134, 2068,  357, 2066,
+ /*  1690 */   424,  672,  426, 2064,  428,   79, 1449, 1448, 2084, 2065,
+ /*  1700 */   671, 2030, 2029, 2115, 2028,  435, 2151,  436, 2027,  110,
+ /*  1710 */  2117,  675, 2119, 2120,  670, 2026,  665, 1982, 2134, 1400,
+ /*  1720 */  1981,  658, 1979, 2204, 1978,  145, 1977,  389, 2200, 1980,
+ /*  1730 */  2084, 2115,  671, 1976, 2151, 1975, 1973,  111, 2117,  675,
+ /*  1740 */  2119, 2120,  670, 1972,  665, 1971,  197,  453, 1970,  455,
+ /*  1750 */  1984, 2204, 2116, 1969, 1968, 2203, 2200,  483,  147, 1954,
+ /*  1760 */  1953, 1952,  672, 2115, 1967, 1966, 2151, 1965, 1964,  111,
+ /*  1770 */  2117,  675, 2119, 2120,  670, 1963,  665, 1962, 1961, 1960,
+ /*  1780 */  2116, 1959, 1958, 2204, 1957, 1956, 1955,  660, 2200, 2134,
+ /*  1790 */   672, 1983, 1951, 1950, 1402, 1949, 1948, 1947, 1946, 2116,
+ /*  1800 */  1945, 2084, 1276,  671,  344, 1280,  345, 1797,  205,  669,
+ /*  1810 */  1796, 1272, 1795, 1793,  207, 2116, 1754, 2134,  180, 1176,
+ /*  1820 */  2104,  208, 1753, 2047, 2037,  672,   76, 2025,   77, 2084,
+ /*  1830 */   210,  671, 2024,  218,  673,  220, 2134, 2151, 2002, 1871,
+ /*  1840 */   111, 2117,  675, 2119, 2120,  670,  181,  665, 2084,  505,
+ /*  1850 */   671,  212, 2134, 1792, 2204, 1790, 1214,  384,  351, 2200,
+ /*  1860 */   520, 1788, 2115,  521, 2084, 2151,  671,  522,  328, 2117,
+ /*  1870 */   675, 2119, 2120,  670,  526,  665, 2116,  524,  525, 1786,
+ /*  1880 */   528, 2115,  529,  530, 2151, 1784,  672,  334, 2117,  675,
+ /*  1890 */  2119, 2120,  670,  532,  665,  533, 2170, 2115,  581, 2116,
+ /*  1900 */  2151,  534, 1771,  335, 2117,  675, 2119, 2120,  670,  672,
+ /*  1910 */   665,  615, 1770, 2134, 1750, 1873,  761,   63,  392, 1348,
+ /*  1920 */  1347, 1872,  230, 1263, 1261, 2084, 1259,  671, 1258, 1257,
+ /*  1930 */   305, 1256, 1250, 1782, 1255,  369, 2134,  561, 1252,  726,
+ /*  1940 */  1251,  394, 1249, 1775,  728,  370,  178, 1773, 2084,  371,
+ /*  1950 */   671,  564,  751,  747,  743,  739,  303,  566, 2115, 1749,
+ /*  1960 */  1748, 2151, 1747,  568,  335, 2117,  675, 2119, 2120,  670,
+ /*  1970 */   570,  665,  113, 1473, 1475, 1472, 1477,   27, 2046, 1455,
+ /*  1980 */    67, 2115, 2036, 1457, 2151,   56,  585,  335, 2117,  675,
+ /*  1990 */  2119, 2120,  670, 2116,  665,  163,  108, 2023,  586,  296,
+ /*  2000 */  2021,  253, 1459,  672,  375, 2280,   29,   20,   17,  591,
+ /*  2010 */  1687,  258,   59,    6,    7,  599,  601,   60,  265,  260,
+ /*  2020 */  1669,   31,  266, 2105,  171, 2116,  264,   21,   65,   30,
+ /*  2030 */  2134,  651, 1661, 1707,   92,  672, 1708,   22, 1702,  278,
+ /*  2040 */  1701,  380, 2084, 2116,  671, 1706, 1705,  381,  176, 2022,
+ /*  2050 */  1636, 1635,   58,  672, 2020, 2019, 2001,   18,   94,   95,
+ /*  2060 */   284,  646, 2134, 2000,  103,   97,  283,   23,   57,  297,
+ /*  2070 */   285,  282, 1667,  294, 2084,  576,  671,   24, 2151,  287,
+ /*  2080 */  2134,  330, 2117,  675, 2119, 2120,  670,  292,  665,   68,
+ /*  2090 */  2116,  249, 2084,   11,  671,   99, 1588, 1587,   13, 1511,
+ /*  2100 */   672, 1543, 1598,  678,  177,  190,  395, 2115, 1566, 2154,
+ /*  2110 */  2151,  682, 1325,  319, 2117,  675, 2119, 2120,  670,  664,
+ /*  2120 */   665,  685, 1564,   37,   16, 2115,  676, 2134, 2151, 1563,
+ /*  2130 */    25,  320, 2117,  675, 2119, 2120,  670, 2116,  665, 2084,
+ /*  2140 */  1535,  671,  674,   26,  688, 1333,  680,  672, 1330, 1327,
+ /*  2150 */   683,  686,  691, 1321, 1319,  300, 1324, 1323, 1322, 2116,
+ /*  2160 */   689,  692,  104, 1342,  105,   75, 1338, 1212,  706,  672,
+ /*  2170 */  1244, 1243, 2115,  301, 2134, 2151, 1242, 1241,  321, 2117,
+ /*  2180 */   675, 2119, 2120,  670, 2116,  665, 2084, 1239,  671, 1237,
+ /*  2190 */  1236, 1235, 1270,  716,  672, 1233, 2134, 1232, 1231, 1230,
+ /*  2200 */  1229, 1228, 1227, 1267, 1265, 1224, 2116, 1223, 2084, 1220,
+ /*  2210 */   671, 1219, 1218, 1217, 1789,  736,  672,  737,  738, 2115,
+ /*  2220 */  1787, 2134, 2151,  740,  741,  327, 2117,  675, 2119, 2120,
+ /*  2230 */   670,  742,  665, 2084, 1785,  671,  744,  746,  745, 1783,
+ /*  2240 */   748, 2115,  749, 2134, 2151,  750, 1769,  331, 2117,  675,
+ /*  2250 */  2119, 2120,  670,  752,  665, 2084, 1166,  671,  304,  756,
+ /*  2260 */  1721, 1721, 1497,  314,  759,  760, 2115, 1746, 1721, 2151,
+ /*  2270 */  2116, 1721,  323, 2117,  675, 2119, 2120,  670, 1721,  665,
+ /*  2280 */   672, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 2115, 1721,
+ /*  2290 */  2116, 2151, 1721, 1721,  332, 2117,  675, 2119, 2120,  670,
+ /*  2300 */   672,  665, 1721, 1721, 1721, 2116, 1721, 2134, 1721, 1721,
+ /*  2310 */  1721, 1721, 1721, 1721, 1721,  672, 1721, 1721, 1721, 2084,
+ /*  2320 */  1721,  671, 1721, 1721, 1721, 1721, 1721, 2134, 1721, 1721,
+ /*  2330 */  1721, 1721, 1721, 1721, 1721, 1721, 1721, 2116, 1721, 2084,
+ /*  2340 */  1721,  671, 2134, 1721, 1721, 1721, 1721,  672, 1721, 1721,
+ /*  2350 */  1721, 1721, 2115, 1721, 2084, 2151,  671, 1721,  324, 2117,
+ /*  2360 */   675, 2119, 2120,  670, 1721,  665, 1721, 1721, 1721, 1721,
+ /*  2370 */  1721, 1721, 2115, 1721, 2134, 2151, 1721, 1721,  333, 2117,
+ /*  2380 */   675, 2119, 2120,  670, 1721,  665, 2084, 2115,  671, 1721,
+ /*  2390 */  2151, 1721, 1721,  325, 2117,  675, 2119, 2120,  670, 1721,
+ /*  2400 */   665, 1721, 1721, 1721, 1721, 2116, 1721, 1721, 1721, 1721,
+ /*  2410 */  1721, 1721, 1721, 1721, 1721,  672, 1721, 1721, 1721, 2115,
+ /*  2420 */  1721, 1721, 2151, 1721, 2116,  338, 2117,  675, 2119, 2120,
+ /*  2430 */   670, 1721,  665, 1721,  672, 1721, 1721, 1721, 1721, 1721,
+ /*  2440 */  1721, 1721, 2134, 1721, 1721, 1721, 1721, 1721, 1721, 1721,
+ /*  2450 */  1721, 1721, 2116, 1721, 2084, 1721,  671, 1721, 1721, 1721,
+ /*  2460 */  1721, 2134,  672, 1721, 1721, 1721, 1721, 1721, 1721, 1721,
+ /*  2470 */  1721, 2116, 1721, 2084, 1721,  671, 1721, 1721, 1721, 1721,
+ /*  2480 */  1721,  672, 1721, 1721, 1721, 1721, 1721, 2115, 1721, 2134,
+ /*  2490 */  2151, 1721, 1721,  339, 2117,  675, 2119, 2120,  670, 1721,
+ /*  2500 */   665, 2084, 1721,  671, 1721, 1721, 2115, 1721, 2134, 2151,
+ /*  2510 */  1721, 1721, 2128, 2117,  675, 2119, 2120,  670, 2116,  665,
+ /*  2520 */  2084, 1721,  671, 1721, 1721, 1721, 1721, 1721,  672, 1721,
+ /*  2530 */  1721, 1721, 1721, 1721, 2115, 1721, 1721, 2151, 1721, 1721,
+ /*  2540 */  2127, 2117,  675, 2119, 2120,  670, 1721,  665, 1721, 1721,
+ /*  2550 */  1721, 1721, 1721, 2115, 1721, 2134, 2151, 1721, 1721, 2126,
+ /*  2560 */  2117,  675, 2119, 2120,  670, 1721,  665, 2084, 1721,  671,
+ /*  2570 */  1721, 1721, 1721, 1721, 1721, 2116, 1721, 1721, 1721, 1721,
+ /*  2580 */  1721, 1721, 1721, 1721, 1721,  672, 1721, 1721, 1721, 1721,
+ /*  2590 */  1721, 2116, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721,
+ /*  2600 */  2115,  672, 1721, 2151, 1721, 1721,  353, 2117,  675, 2119,
+ /*  2610 */  2120,  670, 2134,  665, 1721, 1721, 1721, 1721, 1721, 1721,
+ /*  2620 */  1721, 1721, 1721, 1721, 2084, 1721,  671, 1721, 2134, 1721,
+ /*  2630 */  1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721,
+ /*  2640 */  2084, 2116,  671, 1721, 1721, 1721, 1721, 1721, 1721, 1721,
+ /*  2650 */  1721,  672, 1721, 1721, 1721, 1721, 1721, 2115, 1721, 1721,
+ /*  2660 */  2151, 2116, 1721,  354, 2117,  675, 2119, 2120,  670, 1721,
+ /*  2670 */   665,  672, 1721, 2115, 1721, 1721, 2151, 1721, 2134,  350,
+ /*  2680 */  2117,  675, 2119, 2120,  670, 1721,  665, 1721, 1721, 1721,
+ /*  2690 */  2084, 1721,  671, 1721, 1721, 1721, 1721, 1721, 2134, 1721,
+ /*  2700 */  1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 2116, 1721,
+ /*  2710 */  2084, 1721,  671, 1721, 1721, 1721, 1721, 1721,  672, 1721,
+ /*  2720 */  1721, 1721, 1721, 2115, 1721, 1721, 2151, 1721, 1721,  355,
+ /*  2730 */  2117,  675, 2119, 2120,  670, 1721,  665, 1721, 1721, 1721,
+ /*  2740 */  1721, 1721,  229,  673, 1721, 2134, 2151, 1721, 1721,  330,
+ /*  2750 */  2117,  675, 2119, 2120,  670, 1721,  665, 2084,  172,  671,
+ /*  2760 */  1721, 1721, 1721, 1721,  535,  531,  527,  523,  226, 1721,
+ /*  2770 */  1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721,
+ /*  2780 */  1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721,
+ /*  2790 */  2115, 1721, 1721, 2151, 1721, 1721,  329, 2117,  675, 2119,
+ /*  2800 */  2120,  670, 1721,  665, 1721, 1721, 1721, 1721,   88, 1721,
+ /*  2810 */  1721,  224, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721,
+ /*  2820 */  1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721,
+ /*  2830 */  1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721,
+ /*  2840 */  1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721,
+ /*  2850 */  1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721,
  /*  2860 */  1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721,
- /*  2870 */  1721, 1721, 1721, 1721, 1721,  671, 1721, 1721, 1721, 2151,
- /*  2880 */  1721, 1721,  328, 2117,  673, 2119, 2120,  668, 1721,  663,
- /*  2890 */  2115, 1721, 1721, 1721, 2151, 1721, 1721,  327, 2117,  673,
- /*  2900 */  2119, 2120,  668, 1721,  663,
+ /*  2870 */  1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721,  223,  217,
+ /*  2880 */  1721, 1721, 1721,  222, 1721,  514, 1721, 1721, 1721, 1721,
+ /*  2890 */  1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721,
+ /*  2900 */  1721, 1721, 1721,  215,
 };
 static const YYCODETYPE yy_lookahead[] = {
- /*     0 */   333,  370,  383,  337,  400,  370,  340,  341,  404,  371,
- /*    10 */   343,  365,   12,   13,   14,    0,  371,  398,  399,  381,
- /*    20 */    20,   14,   22,   20,    8,    9,  381,   20,   12,   13,
- /*    30 */    14,   15,   16,   33,    0,   35,  369,  383,   20,   24,
- /*    40 */    25,   26,   27,   28,   29,   30,   31,   32,  381,  395,
- /*    50 */   383,  447,  398,  399,  450,  417,  418,  419,  412,   59,
- /*    60 */    44,  369,  417,  418,  419,   65,  428,   20,  376,  465,
- /*    70 */   466,   20,   72,  428,  470,  471,  384,  342,  343,    0,
- /*    80 */   337,  414,  348,  340,  341,  418,  436,  437,  421,  422,
- /*    90 */   423,  424,  425,  426,  332,  428,  334,   97,  364,   39,
- /*   100 */   100,   67,   68,   69,   70,   71,  372,   73,   74,   75,
+ /*     0 */   333,  384,  371,  362,  401,  332,  401,  334,  405,  343,
+ /*    10 */   343,  370,   12,   13,   14,    0,  399,  400,  377,  378,
+ /*    20 */    20,   14,   22,  342,    8,    9,  385,   20,   12,   13,
+ /*    30 */    14,   15,   16,   33,    0,   35,   21,  370,   20,   24,
+ /*    40 */    25,   26,   27,   28,   29,   30,   31,   32,    3,  382,
+ /*    50 */   447,  384,  447,  450,  388,  450,    8,    9,  351,   59,
+ /*    60 */    12,   13,   14,   15,   16,   65,  359,  386,  465,  466,
+ /*    70 */   465,  466,   72,  470,  471,  470,  471,   12,   13,   14,
+ /*    80 */    15,   16,  415,  337,   20,  418,  340,  341,  421,  422,
+ /*    90 */   423,  424,  425,  426,  369,  428,   20,   97,  436,  437,
+ /*   100 */   100,   67,   68,   69,   70,   71,  381,   73,   74,   75,
  /*   110 */    76,   77,   78,   79,   80,   81,   82,   83,   84,   85,
  /*   120 */    86,   87,   88,   89,   90,   91,   92,   93,  461,  462,
- /*   130 */   379,  420,   97,  382,  383,   21,  136,  137,   24,   25,
+ /*   130 */   337,   20,   97,  340,  341,   21,  136,  137,   24,   25,
  /*   140 */    26,   27,   28,   29,   30,   31,   32,  112,  113,  114,
- /*   150 */   115,  116,  117,  118,  119,  120,  121,  446,  123,  124,
- /*   160 */   125,  126,  127,  128,  369,   20,  166,  167,  447,  166,
- /*   170 */   167,  450,  172,  173,  369,  342,  343,  442,  443,  444,
- /*   180 */   445,  376,  447,  448,  389,  390,  186,  466,  188,  384,
- /*   190 */   330,  470,  471,  360,  130,  131,   64,    8,    9,  135,
- /*   200 */   367,   12,   13,   14,   15,   16,   59,  100,  129,  130,
- /*   210 */   131,  132,  133,  134,  135,  215,  216,    0,  218,  219,
+ /*   150 */   115,  116,  117,  118,  119,  120,  121,  370,  123,  124,
+ /*   160 */   125,  126,  127,  128,  100,   20,  166,  167,   20,  420,
+ /*   170 */   342,  343,  172,  173,  330,    8,    9,  390,  391,   12,
+ /*   180 */    13,   14,   15,   16,  166,  167,  186,   20,  188,  361,
+ /*   190 */   342,  343,  362,  100,  178,  446,  368,    8,    9,   59,
+ /*   200 */   370,   12,   13,   14,   15,   16,    8,    9,  378,  361,
+ /*   210 */    12,   13,   14,   15,   16,  215,  216,    0,  218,  219,
  /*   220 */   220,  221,  222,  223,  224,  225,  226,  227,  228,  229,
- /*   230 */   230,  231,  232,  233,  234,  235,   12,   13,  181,    4,
- /*   240 */    20,   18,  100,   20,   20,  100,   22,  100,   20,  102,
- /*   250 */    27,  333,  447,   30,   65,  450,   33,   33,  369,   35,
- /*   260 */   400,  343,  205,  206,  404,   12,   13,   14,   15,   16,
- /*   270 */   465,  466,   49,  100,   51,  470,  471,   54,   43,  390,
- /*   280 */    45,   46,  368,   59,   67,   68,   69,  369,    0,   65,
- /*   290 */   100,   74,   75,   76,  380,   20,   72,   80,  109,  381,
- /*   300 */   110,  383,   85,   86,   87,   88,   20,  447,   91,   21,
- /*   310 */   450,  251,   24,   25,   26,   27,   28,   29,   30,   31,
- /*   320 */    32,   97,   99,  348,  100,  465,  466,  185,    3,  187,
- /*   330 */   470,  471,  414,   20,  111,   22,  418,  342,  343,  421,
- /*   340 */   422,  423,  424,  425,  426,   20,  428,  372,   35,  431,
- /*   350 */   342,  433,  434,  435,  165,  360,  214,  439,  440,  252,
- /*   360 */   136,  137,  367,  140,   20,   52,  143,  144,  145,  146,
+ /*   230 */   230,  231,  232,  233,  234,  235,   12,   13,    0,  370,
+ /*   240 */   100,   18,  102,   20,   20,  401,   22,  100,  100,  405,
+ /*   250 */    27,  333,  447,   30,   65,  450,   33,   33,  343,   35,
+ /*   260 */   391,  343,   24,   25,   26,   27,   28,   29,   30,   31,
+ /*   270 */    32,  466,   49,   20,   51,  470,  471,   54,  185,  362,
+ /*   280 */   187,   64,  447,   59,   22,  450,  338,  370,  370,   65,
+ /*   290 */   342,  447,  344,  277,  450,  378,   72,   35,  109,  101,
+ /*   300 */   382,  466,  384,  388,  384,  470,  471,  214,  447,  465,
+ /*   310 */   466,  450,   64,  333,  470,  471,  396,  272,    4,  399,
+ /*   320 */   400,   97,   99,  343,  100,  345,  465,  466,   35,  342,
+ /*   330 */   343,  470,  471,  415,  111,  168,  418,  342,  343,  421,
+ /*   340 */   422,  423,  424,  425,  426,  252,  428,   20,  361,  431,
+ /*   350 */   370,  433,  434,  435,  165,  368,  361,  439,  440,   97,
+ /*   360 */   136,  137,  382,  140,  384,   72,  143,  144,  145,  146,
  /*   370 */   147,  148,  149,  150,  151,  152,  153,  154,  155,  156,
- /*   380 */   157,  158,  159,  338,  161,  162,  163,  342,  168,  344,
- /*   390 */   166,  167,  447,  385,  252,  450,  172,  173,   14,  252,
- /*   400 */    67,   68,   69,   64,   20,  382,  383,   74,   75,   76,
- /*   410 */   186,  466,  188,   80,  171,  470,  471,    0,   85,   86,
- /*   420 */    87,   88,  136,  137,   91,  252,  101,   35,  239,  240,
+ /*   380 */   157,  158,  159,   20,  161,  162,  163,   14,   20,   20,
+ /*   390 */   166,  167,  252,   20,   13,  415,  172,  173,  418,  252,
+ /*   400 */   252,  421,  422,  423,  424,  425,  426,   64,  428,   20,
+ /*   410 */   186,   22,  188,  433,  100,  435,   35,  342,  343,  439,
+ /*   420 */   440,  168,  100,  171,  342,  342,  343,  333,  239,  240,
  /*   430 */   241,  242,  243,  244,  245,  246,  247,  248,  249,  215,
- /*   440 */   216,  166,  218,  219,  220,  221,  222,  223,  224,  225,
+ /*   440 */   216,   52,  218,  219,  220,  221,  222,  223,  224,  225,
  /*   450 */   226,  227,  228,  229,  230,  231,  232,  233,  234,  235,
- /*   460 */   236,   12,   13,   33,   72,   22,  351,   20,  338,   20,
- /*   470 */   333,   22,  342,  358,  344,  215,  111,   20,   35,   49,
- /*   480 */   343,   64,   33,   81,   35,   55,   56,   57,   58,   59,
- /*   490 */   420,    8,    9,  168,  333,   12,   13,   14,   15,   16,
- /*   500 */   257,  258,  259,   20,   20,    4,  369,  371,   59,  355,
- /*   510 */   356,   72,   20,  343,   65,   72,  446,  381,  381,  342,
- /*   520 */   383,   72,  262,  263,  264,  265,  266,  267,  268,   99,
- /*   530 */     8,    9,  102,  236,   12,   13,   14,   15,   16,  369,
- /*   540 */    97,  369,  381,  141,  142,   13,   97,  333,  376,  100,
- /*   550 */   166,  414,  165,  417,  418,  418,  384,  100,  421,  422,
- /*   560 */   423,  424,  425,  426,  428,  428,  164,   35,   18,  392,
- /*   570 */   433,  394,  435,   23,    8,    9,  439,  440,   12,   13,
- /*   580 */    14,   15,   16,  136,  137,  136,  137,   37,   38,  452,
- /*   590 */   333,   41,  100,  423,    4,  381,   20,  460,   22,  169,
- /*   600 */   170,  100,  350,  342,  174,  236,  176,  238,  420,   19,
- /*   610 */    60,   61,   62,   63,  111,  166,  167,  361,  366,  172,
- /*   620 */   173,  172,  173,   33,  194,  369,  239,  375,   52,  186,
- /*   630 */    72,  188,  376,  377,  446,  186,  249,  188,  381,   49,
- /*   640 */   384,    0,  342,  343,   54,  342,  343,  369,  333,   59,
- /*   650 */   100,  168,  168,  392,  376,  394,  371,  129,  215,  216,
- /*   660 */   360,  133,  384,  360,  215,  216,  381,  218,  219,  220,
+ /*   460 */   236,   12,   13,  136,  137,   22,   12,   13,  100,   20,
+ /*   470 */    22,   22,   67,   68,   69,  393,  382,  395,   35,   74,
+ /*   480 */    75,   76,   33,   35,   35,   80,    3,  333,    2,   35,
+ /*   490 */    85,   86,   87,   88,    8,    9,   91,  343,   12,   13,
+ /*   500 */    14,   15,   16,   20,   20,  136,  137,  333,   59,  257,
+ /*   510 */   258,  259,  215,  379,   65,   72,  382,  343,  443,  444,
+ /*   520 */   445,   72,  447,  448,  370,  442,  443,  444,  445,  380,
+ /*   530 */   447,  448,  383,  384,  366,   20,  382,   22,  384,  166,
+ /*   540 */    97,  172,  173,   20,  370,   97,   97,    8,    9,  100,
+ /*   550 */    35,   12,   13,   14,   15,   16,  382,   44,  384,  262,
+ /*   560 */   263,  264,  265,  266,  267,  268,  252,   52,   18,  415,
+ /*   570 */   333,  111,  418,   23,  252,  421,  422,  423,  424,  425,
+ /*   580 */   426,  413,  428,   44,  101,  136,  137,   37,   38,  415,
+ /*   590 */   236,   41,  418,  358,    4,  421,  422,  423,  424,  425,
+ /*   600 */   426,  427,  428,  429,  430,  342,  343,  372,  348,   19,
+ /*   610 */    60,   61,   62,   63,  101,  166,  167,  382,  343,  382,
+ /*   620 */   252,  172,  173,   33,  361,  365,  472,  473,  338,  186,
+ /*   630 */    81,  188,  342,  373,  344,  186,    0,  188,  370,   49,
+ /*   640 */   370,  370,  188,  342,   54,  370,  378,  377,  377,   59,
+ /*   650 */   100,  168,  168,  418,  419,  385,  385,   72,  215,  216,
+ /*   660 */     4,  130,  131,  428,  215,  216,  135,  218,  219,  220,
  /*   670 */   221,  222,  223,  224,  225,  226,  227,  228,  229,  230,
  /*   680 */   231,  232,  233,  234,  235,   12,   13,   14,  138,   99,
- /*   690 */   369,  333,  102,   20,  370,   22,  381,  376,  342,  343,
- /*   700 */   178,  343,  417,  418,  419,  384,   33,  333,   35,  252,
- /*   710 */   357,    2,  359,  428,  342,  343,  360,    8,    9,  342,
- /*   720 */   343,   12,   13,   14,   15,   16,  358,  369,  178,  179,
- /*   730 */   180,  350,   59,  183,  168,  355,  356,  360,  342,  381,
- /*   740 */   370,  383,    8,    9,  252,   72,   12,   13,   14,   15,
- /*   750 */    16,  342,  343,  252,  204,  381,  375,  207,    0,  343,
- /*   760 */   210,  211,  212,  213,  214,   14,  333,  342,  343,  360,
- /*   770 */    97,   20,  414,  100,  342,  343,  418,  333,  333,  421,
- /*   780 */   422,  423,  424,  425,  426,  360,  428,  343,  392,  345,
- /*   790 */   394,  433,  360,  435,    2,    4,  333,  439,  440,  277,
- /*   800 */     8,    9,  252,  387,   12,   13,   14,   15,   16,  136,
- /*   810 */   137,  342,  343,  369,  381,  443,  444,  445,  460,  447,
- /*   820 */   448,   21,  450,  342,  343,  381,  381,  383,  370,  360,
- /*   830 */    20,  342,  343,   59,   34,  101,   36,  465,  466,  166,
- /*   840 */   167,  343,  470,  471,  381,  172,  173,    8,    9,  360,
- /*   850 */   209,   12,   13,   14,   15,   16,    0,  431,  414,  186,
- /*   860 */   434,  188,  418,  342,  343,  421,  422,  423,  424,  425,
- /*   870 */   426,  369,  428,   99,  131,  370,  102,  433,  135,  435,
- /*   880 */    37,  360,  369,  439,  440,  387,  384,  400,  215,  216,
- /*   890 */   377,  218,  219,  220,  221,  222,  223,  224,  225,  226,
+ /*   690 */   141,  142,  102,   20,  393,   22,  395,  333,  423,   43,
+ /*   700 */     0,   45,   46,   67,   68,   69,   33,  343,   35,   37,
+ /*   710 */    74,   75,   76,  164,  342,  111,   80,  447,  342,  343,
+ /*   720 */   450,   85,   86,   87,   88,  342,  343,   91,  178,  179,
+ /*   730 */   180,    4,   59,  183,  370,  465,  466,  361,  383,  384,
+ /*   740 */   470,  471,   72,  131,  370,   72,  382,  135,  384,  342,
+ /*   750 */   343,  377,    1,    2,  204,  342,  343,  207,  371,  385,
+ /*   760 */   210,  211,  212,  213,  214,  393,  333,  395,  361,  370,
+ /*   770 */    97,  100,  401,  100,  361,  103,  377,  105,  106,  415,
+ /*   780 */   108,  110,  418,  333,  385,  421,  422,  423,  424,  425,
+ /*   790 */   426,  370,  428,  343,    0,  342,  343,  433,  377,  435,
+ /*   800 */   348,  129,  252,  439,  440,  133,  385,  195,  196,  136,
+ /*   810 */   137,  199,  350,  201,  361,  382,  452,  401,  447,  334,
+ /*   820 */   370,  450,  355,  356,  460,  373,  443,  444,  445,  367,
+ /*   830 */   447,  448,  382,  450,  384,  333,  465,  466,  376,  166,
+ /*   840 */   167,  470,  471,  342,  343,  172,  173,  130,  465,  466,
+ /*   850 */   342,  343,  101,  470,  471,  155,   14,  420,  236,  186,
+ /*   860 */   238,  188,   20,  447,  164,  415,  450,  333,  418,  361,
+ /*   870 */   371,  421,  422,  423,  424,  425,  426,  432,  428,  434,
+ /*   880 */    44,  465,  466,  446,  382,  435,  470,  471,  215,  216,
+ /*   890 */   440,  218,  219,  220,  221,  222,  223,  224,  225,  226,
  /*   900 */   227,  228,  229,  230,  231,  232,  233,  234,  235,   12,
- /*   910 */    13,  333,  432,  155,  434,  342,  343,   20,  333,   22,
- /*   920 */   333,  343,  164,  345,  443,  444,  445,   59,  447,  448,
- /*   930 */    33,  333,   35,  360,  447,   45,   46,  450,  195,  196,
- /*   940 */   101,  343,  199,  432,  201,  434,  103,  369,  105,  106,
- /*   950 */   333,  108,  465,  466,   14,  334,   59,  470,  471,  381,
- /*   960 */    20,  383,  342,  343,  342,  343,  381,  369,  381,   72,
- /*   970 */   102,   22,  129,   14,   15,   16,  133,    3,  168,  381,
- /*   980 */   360,  383,  360,  371,   35,  129,  130,  131,  132,  133,
- /*   990 */   134,  135,  414,  381,   97,  400,  418,  100,  381,  421,
- /*  1000 */   422,  423,  424,  425,  426,  333,  428,  400,    1,    2,
- /*  1010 */   333,  433,  414,  435,  333,  343,  418,  439,  440,  421,
- /*  1020 */   422,  423,  424,  425,  426,  427,  428,  429,  430,  417,
- /*  1030 */   418,    8,    9,  136,  137,   12,   13,   14,   15,   16,
- /*  1040 */   428,  369,  447,  361,  253,  450,   97,  343,   44,  342,
- /*  1050 */   343,  369,   65,  381,  447,  383,  370,  450,  381,  377,
- /*  1060 */   465,  466,  381,  166,  167,  470,  471,  360,  378,  172,
- /*  1070 */   173,  381,  465,  466,  250,  251,  361,  470,  471,  136,
- /*  1080 */   137,  342,  343,  186,  369,  188,  414,  342,  343,   22,
- /*  1090 */   418,  387,  377,  421,  422,  423,  424,  425,  426,  360,
- /*  1100 */   428,  400,   35,  342,  343,  360,  166,   42,  101,   44,
- /*  1110 */   130,  378,  215,  216,  381,  218,  219,  220,  221,  222,
+ /*   910 */    13,  432,   20,  434,  197,  198,  382,   20,  181,   22,
+ /*   920 */    42,  333,   44,  129,  130,  131,  132,  133,  134,  135,
+ /*   930 */    33,  343,   35,    8,    9,  342,  343,   12,   13,   14,
+ /*   940 */    15,   16,  205,  206,  443,  444,  445,  333,  447,  448,
+ /*   950 */    59,  371,  342,  343,  361,  401,   59,  343,  370,  345,
+ /*   960 */   129,  130,  131,  132,  133,  134,  135,  362,   20,   72,
+ /*   970 */   382,  361,  384,  342,  343,  370,   14,   15,   16,  420,
+ /*   980 */   253,    8,    9,  378,  370,   12,   13,   14,   15,   16,
+ /*   990 */    99,  129,  361,  102,   97,  133,  382,  100,  384,  342,
+ /*  1000 */   343,  447,  333,  415,  450,  446,  418,  333,  166,  421,
+ /*  1010 */   422,  423,  424,  425,  426,    0,  428,  343,  361,  465,
+ /*  1020 */   466,  433,   39,  435,  470,  471,  333,  439,  440,  415,
+ /*  1030 */     0,  350,  418,  136,  137,  421,  422,  423,  424,  425,
+ /*  1040 */   426,  358,  428,  406,  370,  333,   21,  433,  460,  435,
+ /*  1050 */    42,  382,   44,  439,  440,  372,  382,  376,  384,   34,
+ /*  1060 */   168,   36,  343,  166,  167,  382,    2,  342,  343,  172,
+ /*  1070 */   173,  165,    8,    9,  101,  382,   12,   13,   14,   15,
+ /*  1080 */    16,  355,  356,  186,  371,  188,  361,  342,  343,  415,
+ /*  1090 */   342,  343,  418,  168,  382,  421,  422,  423,  424,  425,
+ /*  1100 */   426,  418,  428,   45,   46,  363,  361,  388,  366,  361,
+ /*  1110 */   274,  428,  215,  216,  166,  218,  219,  220,  221,  222,
  /*  1120 */   223,  224,  225,  226,  227,  228,  229,  230,  231,  232,
- /*  1130 */   233,  234,  235,   12,   13,  342,  343,  342,  343,  333,
- /*  1140 */   333,   20,  361,   22,  472,  473,  333,  333,  447,    0,
- /*  1150 */   369,  450,  333,  360,   33,  360,   35,  343,  377,  345,
- /*  1160 */    44,   44,   22,  333,   97,  333,  465,  466,    0,  405,
- /*  1170 */   362,  470,  471,  365,  333,   35,  378,  197,  198,  381,
- /*  1180 */    59,  111,  104,  369,  343,  107,  345,  381,  381,   42,
- /*  1190 */   200,   44,  202,   72,  381,  381,  447,  383,   49,  450,
- /*  1200 */   381,   48,  215,   13,  443,  444,  445,    0,  447,  448,
- /*  1210 */   369,  381,   44,  381,  465,  466,  391,  101,   97,  470,
- /*  1220 */   471,  100,  381,  104,  383,   35,  107,  474,  414,   22,
- /*  1230 */   160,   35,  418,   44,  333,  421,  422,  423,  424,  425,
- /*  1240 */   426,   35,  428,  463,  343,  104,  272,  433,  107,  435,
- /*  1250 */     0,    0,  346,  439,  440,  414,   44,  136,  137,  418,
- /*  1260 */    44,   13,  421,  422,  423,  424,  425,  426,  104,  428,
- /*  1270 */   369,  107,   22,   22,  433,   44,  435,   44,  274,  457,
- /*  1280 */   439,  440,  381,   35,  383,   47,  369,  166,  167,  391,
- /*  1290 */   101,   35,  346,  172,  173,  341,  129,  130,  131,  132,
- /*  1300 */   133,  134,  135,    1,    2,   44,  343,  186,   44,  188,
- /*  1310 */   380,   44,  391,  101,   44,  414,   44,  101,   44,  418,
- /*  1320 */   449,  168,  421,  422,  423,  424,  425,  426,   72,  428,
- /*  1330 */    44,    0,  101,   44,  101,   44,  215,  216,  100,  218,
+ /*  1130 */   233,  234,  235,   12,   13,  333,  462,  333,  342,  343,
+ /*  1140 */   333,   20,  333,   22,  358,  239,  333,  343,  333,  345,
+ /*  1150 */   342,  343,  342,  343,   33,  249,   35,  361,  372,  129,
+ /*  1160 */   130,  131,  132,  133,  134,  135,  333,  431,  382,  361,
+ /*  1170 */   434,  361,  250,  251,  370,  370,  379,   14,  379,  382,
+ /*  1180 */    59,  382,  333,   20,  382,  358,  382,  333,  384,  382,
+ /*  1190 */   385,  382,  358,   72,    0,  382,   44,  382,  333,  372,
+ /*  1200 */   333,  333,    0,  371,  418,  419,  372,  357,  104,  382,
+ /*  1210 */   360,  107,  111,   48,  428,  382,  382,  104,   97,  415,
+ /*  1220 */   107,  100,  418,  333,  209,  421,  422,  423,  424,  425,
+ /*  1230 */   426,  382,  428,  343,  251,  345,  382,  433,   44,  435,
+ /*  1240 */    44,   22,   13,  439,  440,  418,  419,  382,    0,  382,
+ /*  1250 */   382,   49,  418,  104,   35,  428,  107,  136,  137,    0,
+ /*  1260 */   370,  160,  428,  104,   35,   44,  107,    0,   13,  200,
+ /*  1270 */    22,  202,  382,   65,  384,   44,   59,   44,   44,  136,
+ /*  1280 */   137,   22,    1,    2,  371,   47,  359,  166,  167,   22,
+ /*  1290 */    35,  392,  474,  172,  173,  346,  457,  101,  463,  358,
+ /*  1300 */    35,   35,   13,  358,   44,  415,   44,  186,  418,  188,
+ /*  1310 */   370,  421,  422,  423,  424,  425,  426,   44,  428,  102,
+ /*  1320 */    44,   44,  101,  433,   35,  435,  346,   44,   44,  439,
+ /*  1330 */   440,  392,  101,  168,  101,  101,  215,  216,  100,  218,
  /*  1340 */   219,  220,  221,  222,  223,  224,  225,  226,  227,  228,
- /*  1350 */   229,  230,  231,  232,  233,  234,  235,  441,  467,   12,
- /*  1360 */    13,   44,  101,  462,   44,  101,   44,  333,  101,   22,
- /*  1370 */    44,  101,   44,  101,   13,  101,  451,  343,  254,  345,
- /*  1380 */    33,   50,   35,  416,  188,   49,  415,  101,  184,  388,
- /*  1390 */   101,  402,  101,  276,  188,   42,   35,  333,   20,  391,
- /*  1400 */   388,  165,  386,  369,   20,  342,   59,  343,  342,  345,
- /*  1410 */   388,  386,  386,   98,  354,  381,  342,  383,  101,   72,
- /*  1420 */    96,  101,  353,  101,   95,  352,  342,  101,  342,  101,
- /*  1430 */   342,   20,  335,  369,   48,  339,  335,  339,   20,  409,
- /*  1440 */   350,   20,  383,  350,   97,  381,   20,  383,  414,  344,
- /*  1450 */    20,  401,  418,  350,  344,  421,  422,  423,  424,  425,
- /*  1460 */   426,  350,  428,  350,  350,  333,   53,  433,  342,  435,
- /*  1470 */   350,  335,  347,  439,  440,  343,  347,  369,  414,  335,
- /*  1480 */   381,  369,  418,  381,  369,  421,  422,  423,  424,  425,
- /*  1490 */   426,  369,  428,  342,  413,  203,  369,  433,  100,  435,
- /*  1500 */   369,  369,  369,  439,  440,  411,  369,  369,  369,  381,
- /*  1510 */   348,  369,  408,  381,  191,  383,  409,  192,  383,  348,
- /*  1520 */   190,  342,  269,  261,  456,  407,  260,  381,  456,  406,
- /*  1530 */   396,  381,  177,  186,  391,  188,  391,  381,  381,  459,
- /*  1540 */   458,  456,  271,  270,  396,  454,  414,  455,  255,  273,
- /*  1550 */   418,  475,  275,  421,  422,  423,  424,  425,  426,  453,
- /*  1560 */   428,  278,  215,  216,  469,  433,  343,  435,  416,  251,
- /*  1570 */    20,  439,  440,  333,  420,  228,  229,  230,  231,  232,
- /*  1580 */   233,  234,  348,  343,  342,  344,   20,  348,  394,  396,
- /*  1590 */   381,  381,  381,  333,  381,  381,  396,  170,  468,  381,
- /*  1600 */   348,  393,  365,  343,  100,  348,  343,  438,  100,  369,
- /*  1610 */   381,  342,   36,  359,    0,  336,  373,  335,  403,  397,
- /*  1620 */     0,  381,  397,  383,    0,  331,  348,  410,  363,  369,
- /*  1630 */   349,  363,   42,    0,   35,   35,  208,   35,  363,   35,
- /*  1640 */   208,  381,   35,  383,    0,   35,  208,    0,  208,    0,
- /*  1650 */    35,    0,   22,    0,  414,  195,   35,  188,  418,  186,
- /*  1660 */     0,  421,  422,  423,  424,  425,  426,    0,  428,    0,
- /*  1670 */   182,  181,    0,  433,  414,  435,   47,  333,  418,  439,
- /*  1680 */   440,  421,  422,  423,  424,  425,  426,  343,  428,    0,
- /*  1690 */     0,    0,    0,  433,   42,  435,    0,    0,    0,  439,
- /*  1700 */   440,  333,    0,    0,    0,    0,    0,  155,   35,    0,
- /*  1710 */   155,  343,    0,  369,    0,    0,    0,    0,    0,    0,
- /*  1720 */     0,    0,    0,    0,    0,  381,    0,  383,    0,    0,
- /*  1730 */     0,    0,    0,    0,    0,   42,    0,  369,    0,    0,
- /*  1740 */     0,    0,  139,    0,    0,    0,   59,   22,   48,  381,
- /*  1750 */     0,  383,    0,   59,   59,   48,    0,   22,  414,   22,
- /*  1760 */     0,   14,  418,  177,    0,  421,  422,  423,  424,  425,
- /*  1770 */   426,   44,  428,    0,    0,    0,    0,   35,  333,  435,
- /*  1780 */     0,    0,  414,  439,  440,   39,  418,   39,  343,  421,
- /*  1790 */   422,  423,  424,  425,  426,   42,  428,   39,   47,   40,
- /*  1800 */     0,  333,   47,  435,   47,    0,   35,  439,  440,   39,
- /*  1810 */    49,  343,    0,   35,  369,   66,   49,    0,   39,   35,
- /*  1820 */     0,   49,   39,   35,  333,   39,  381,    0,  383,    0,
- /*  1830 */     0,   49,    0,   35,  343,   22,    0,  369,   35,   35,
- /*  1840 */    44,   35,   35,   35,   35,   35,   44,  333,   22,  381,
- /*  1850 */    35,  383,    0,   35,   35,   22,    0,  343,    0,  414,
- /*  1860 */   369,  107,   22,  418,   22,   51,  421,  422,  423,  424,
- /*  1870 */   425,  426,  381,  428,  383,  109,   35,    0,   35,    0,
- /*  1880 */   435,   35,  414,  369,  439,  440,  418,    0,   22,  421,
- /*  1890 */   422,  423,  424,  425,  426,  381,  428,  383,   20,   35,
- /*  1900 */    35,  100,   35,  435,    0,  414,  193,   35,  440,  418,
- /*  1910 */   333,  100,  421,  422,  423,  424,  425,  426,   22,  428,
- /*  1920 */   343,    0,  101,   22,    0,    0,    3,   44,  414,  101,
- /*  1930 */   168,  256,  418,   48,  100,  421,  422,  423,  424,  425,
- /*  1940 */   426,   48,  428,  175,  100,  168,  369,   98,  101,   96,
- /*  1950 */    44,  374,   44,  168,  189,  464,  101,  100,  381,  170,
- /*  1960 */   383,  100,  100,   44,  101,   47,  256,    3,  100,   47,
- /*  1970 */    44,  101,  101,   44,   35,  333,   35,   35,   35,   35,
- /*  1980 */    35,  101,  101,    0,   47,  343,    0,  473,    0,    0,
- /*  1990 */    44,  414,  100,   39,   47,  418,  333,   47,  421,  422,
- /*  2000 */   423,  424,  425,  426,  101,  428,  343,  100,  171,  333,
- /*  2010 */   101,  369,  100,  100,  100,    0,   39,  169,   47,  343,
- /*  2020 */   110,    2,   44,  381,   22,  383,   98,  100,   98,  237,
- /*  2030 */    22,  215,  369,  100,   47,  101,  101,  374,  100,   47,
- /*  2040 */   250,  101,  217,  111,  381,  369,  383,  256,  100,  100,
- /*  2050 */   374,  100,   35,  101,  101,  100,  414,  381,   35,  383,
- /*  2060 */   418,    1,  100,  421,  422,  423,  424,  425,  426,  101,
- /*  2070 */   428,   35,  430,  100,   35,  101,  100,  414,   35,   19,
- /*  2080 */   101,  418,  100,   35,  421,  422,  423,  424,  425,  426,
- /*  2090 */   414,  428,  101,   33,  418,  100,  333,  421,  422,  423,
- /*  2100 */   424,  425,  426,  122,  428,  100,  343,  122,   44,   49,
- /*  2110 */   100,   35,  122,  100,   22,   55,   56,   57,   58,   59,
- /*  2120 */   333,  122,   66,   65,   35,   35,   35,   72,   35,   35,
- /*  2130 */   343,   35,  369,   35,   35,   35,   35,   35,   94,   44,
- /*  2140 */    35,   35,   22,   35,  381,   35,  383,   35,   35,   72,
- /*  2150 */    35,   35,   22,   35,   35,    0,  369,   35,   35,   99,
- /*  2160 */    49,    0,  102,   39,   35,   39,    0,   35,  381,    0,
- /*  2170 */   383,   35,    0,   39,   49,   35,   49,  414,   39,   35,
- /*  2180 */    49,  418,    0,  333,  421,  422,  423,  424,  425,  426,
- /*  2190 */    22,  428,   21,  343,  134,   22,   22,   21,   20,  476,
- /*  2200 */   476,  414,  476,  476,  476,  418,  476,  333,  421,  422,
- /*  2210 */   423,  424,  425,  426,  476,  428,  476,  343,  476,  369,
- /*  2220 */   476,  476,  476,  476,  476,  476,  476,  476,  476,  169,
- /*  2230 */   476,  381,  476,  383,  174,  476,  476,  476,  476,  476,
- /*  2240 */   476,  476,  476,  369,  476,  476,  476,  476,  476,  476,
- /*  2250 */   476,  476,  476,  333,  194,  381,  476,  383,  476,  476,
- /*  2260 */   476,  476,  476,  343,  414,  476,  476,  476,  418,  333,
- /*  2270 */   476,  421,  422,  423,  424,  425,  426,  476,  428,  343,
- /*  2280 */   476,  476,  476,  476,  476,  476,  476,  476,  414,  369,
- /*  2290 */   476,  476,  418,  476,  476,  421,  422,  423,  424,  425,
- /*  2300 */   426,  381,  428,  383,  476,  369,  476,  476,  476,  476,
- /*  2310 */   476,  476,  476,  476,  476,  476,  476,  381,  476,  383,
- /*  2320 */   476,  476,  476,  476,  476,  476,  476,  476,  476,  333,
- /*  2330 */   476,  476,  476,  476,  414,  476,  476,  476,  418,  343,
- /*  2340 */   476,  421,  422,  423,  424,  425,  426,  476,  428,  476,
- /*  2350 */   414,  476,  476,  333,  418,  476,  476,  421,  422,  423,
- /*  2360 */   424,  425,  426,  343,  428,  369,  476,  476,  476,  476,
- /*  2370 */   476,  476,  476,  476,  476,  476,  476,  381,  476,  383,
- /*  2380 */   333,  476,  476,  476,  476,  476,  476,  476,  476,  369,
- /*  2390 */   343,  476,  476,  476,  476,  476,  476,  476,  476,  333,
- /*  2400 */   476,  381,  476,  383,  476,  476,  476,  476,  476,  343,
- /*  2410 */   414,  476,  476,  476,  418,  476,  369,  421,  422,  423,
- /*  2420 */   424,  425,  426,  476,  428,  476,  476,  476,  381,  476,
- /*  2430 */   383,  476,  476,  476,  414,  369,  476,  476,  418,  476,
- /*  2440 */   476,  421,  422,  423,  424,  425,  426,  381,  428,  383,
- /*  2450 */   333,  476,  476,  476,  476,  476,  476,  476,  476,  476,
- /*  2460 */   343,  414,  476,  476,  476,  418,  333,  476,  421,  422,
- /*  2470 */   423,  424,  425,  426,  476,  428,  343,  476,  476,  476,
- /*  2480 */   414,  476,  476,  476,  418,  476,  369,  421,  422,  423,
- /*  2490 */   424,  425,  426,  476,  428,  476,  333,  476,  381,  476,
- /*  2500 */   383,  476,  369,  476,  476,  476,  343,  476,  476,  476,
- /*  2510 */   476,  476,  476,  476,  381,  476,  383,  333,  476,  476,
- /*  2520 */   476,  476,  476,  476,  476,  476,  476,  343,  476,  476,
- /*  2530 */   476,  414,  369,  476,  476,  418,  476,  476,  421,  422,
- /*  2540 */   423,  424,  425,  426,  381,  428,  383,  414,  476,  476,
- /*  2550 */   476,  418,  476,  369,  421,  422,  423,  424,  425,  426,
- /*  2560 */   476,  428,  476,  333,  476,  381,  476,  383,  476,  476,
- /*  2570 */   476,  476,  476,  343,  476,  476,  476,  414,  476,  476,
- /*  2580 */   476,  418,  476,  476,  421,  422,  423,  424,  425,  426,
- /*  2590 */   476,  428,  476,  476,  476,  476,  476,  476,  414,  369,
- /*  2600 */   476,  476,  418,  476,  476,  421,  422,  423,  424,  425,
- /*  2610 */   426,  381,  428,  383,  476,  476,  476,  476,  476,  476,
- /*  2620 */   476,  476,  476,  333,  476,  476,  476,  476,  476,  476,
- /*  2630 */   476,  476,  476,  343,  476,  476,  333,  476,  476,  476,
- /*  2640 */   476,  476,  476,  476,  414,  476,  343,  476,  418,  476,
- /*  2650 */   476,  421,  422,  423,  424,  425,  426,  476,  428,  369,
- /*  2660 */   476,  476,  476,  476,  476,  476,  476,  476,  476,  476,
- /*  2670 */   476,  381,  369,  383,  476,  476,  476,  476,  476,  476,
- /*  2680 */   476,  476,  476,  476,  381,  476,  383,  333,  476,  476,
- /*  2690 */   476,  476,  476,  476,  476,  476,  476,  343,  476,  476,
- /*  2700 */   476,  476,  476,  476,  414,  476,  476,  476,  418,  476,
- /*  2710 */   476,  421,  422,  423,  424,  425,  426,  414,  428,  476,
- /*  2720 */   476,  418,  476,  369,  421,  422,  423,  424,  425,  426,
- /*  2730 */   476,  428,  476,  333,  476,  381,  476,  383,  476,  476,
- /*  2740 */   476,  476,  476,  343,  476,  476,  476,  476,  333,  476,
- /*  2750 */   476,  476,  476,  476,  476,  476,  476,  476,  343,  476,
- /*  2760 */   476,  476,  476,  476,  476,  476,  476,  476,  414,  369,
- /*  2770 */   476,  476,  418,  476,  476,  421,  422,  423,  424,  425,
- /*  2780 */   426,  381,  428,  383,  369,  476,  476,  476,  476,  476,
- /*  2790 */   476,  476,  476,  476,  333,  476,  381,  476,  383,  476,
- /*  2800 */   476,  476,  476,  476,  343,  476,  476,  476,  476,  333,
- /*  2810 */   476,  476,  476,  476,  414,  476,  476,  476,  418,  343,
- /*  2820 */   476,  421,  422,  423,  424,  425,  426,  476,  428,  414,
- /*  2830 */   369,  476,  476,  418,  476,  476,  421,  422,  423,  424,
- /*  2840 */   425,  426,  381,  428,  383,  369,  476,  476,  476,  476,
- /*  2850 */   476,  476,  476,  476,  476,  476,  476,  381,  476,  383,
+ /*  1350 */   229,  230,  231,  232,  233,  234,  235,  333,   12,   13,
+ /*  1360 */    35,  101,   44,  101,   44,   44,    0,  343,   22,  345,
+ /*  1370 */    44,  343,   44,  341,  101,  381,  392,  101,  101,   33,
+ /*  1380 */    44,   35,  449,  333,  101,  101,  467,   44,  441,  451,
+ /*  1390 */   254,  417,  416,  343,  370,  345,   49,   72,  184,  403,
+ /*  1400 */    42,  389,   20,  392,  165,   59,  382,  389,  384,  387,
+ /*  1410 */    20,   98,  342,  342,  387,  389,   50,  354,   72,  101,
+ /*  1420 */   370,  101,  101,  215,  387,   96,  353,  101,  276,  101,
+ /*  1430 */   333,  342,  382,   95,  384,  352,  342,  101,  342,  415,
+ /*  1440 */   343,  342,  418,   97,  101,  421,  422,  423,  424,  425,
+ /*  1450 */   426,  333,  428,  188,  188,   20,   48,  433,  335,  435,
+ /*  1460 */   335,  343,   20,  439,  440,  415,  339,  370,  418,  339,
+ /*  1470 */   410,  421,  422,  423,  424,  425,  426,   20,  428,  382,
+ /*  1480 */    20,  384,  350,  433,  384,  435,  344,  350,  370,  439,
+ /*  1490 */   440,   20,  402,   53,  350,  344,  350,  350,  350,  342,
+ /*  1500 */   382,  347,  384,  350,  335,  347,  342,  335,  370,  370,
+ /*  1510 */   370,  370,  415,  382,  203,  418,  382,  382,  421,  422,
+ /*  1520 */   423,  424,  425,  426,  414,  428,  370,  100,  412,  410,
+ /*  1530 */   370,  370,  186,  415,  188,  348,  418,  370,  370,  421,
+ /*  1540 */   422,  423,  424,  425,  426,  370,  428,  370,  192,  348,
+ /*  1550 */   191,  433,  190,  435,  409,  333,  382,  439,  440,  261,
+ /*  1560 */   384,  215,  216,  408,  456,  343,  342,  260,  397,  407,
+ /*  1570 */   473,  392,  392,  382,  228,  229,  230,  231,  232,  233,
+ /*  1580 */   234,  397,  456,  269,  177,  382,  382,  459,  271,  270,
+ /*  1590 */   255,  458,  370,  278,  343,  417,  251,  475,  275,   20,
+ /*  1600 */   273,  420,  344,  342,  382,  455,  384,   20,  395,  397,
+ /*  1610 */   382,  348,  348,  397,  382,  170,  348,  382,  382,  382,
+ /*  1620 */   394,  333,  456,  382,  454,  343,  453,  348,  100,  100,
+ /*  1630 */   438,  343,  382,  342,  360,  366,   36,  415,  348,  336,
+ /*  1640 */   418,  335,  398,  421,  422,  423,  424,  425,  426,  333,
+ /*  1650 */   428,  469,  374,  468,  411,  433,  404,  435,  370,  343,
+ /*  1660 */   364,  439,  440,  364,  364,  331,    0,    0,  398,    0,
+ /*  1670 */   382,  349,  384,   42,    0,   35,  208,   35,   35,   35,
+ /*  1680 */   208,  333,    0,   35,   35,  208,  370,    0,  208,    0,
+ /*  1690 */    35,  343,   22,    0,   35,  195,  188,  186,  382,    0,
+ /*  1700 */   384,    0,    0,  415,    0,  182,  418,  181,    0,  421,
+ /*  1710 */   422,  423,  424,  425,  426,    0,  428,    0,  370,   47,
+ /*  1720 */     0,  433,    0,  435,    0,   42,    0,  439,  440,    0,
+ /*  1730 */   382,  415,  384,    0,  418,    0,    0,  421,  422,  423,
+ /*  1740 */   424,  425,  426,    0,  428,    0,  155,   35,    0,  155,
+ /*  1750 */     0,  435,  333,    0,    0,  439,  440,  139,   42,    0,
+ /*  1760 */     0,    0,  343,  415,    0,    0,  418,    0,    0,  421,
+ /*  1770 */   422,  423,  424,  425,  426,    0,  428,    0,    0,    0,
+ /*  1780 */   333,    0,    0,  435,    0,    0,    0,  439,  440,  370,
+ /*  1790 */   343,    0,    0,    0,   22,    0,    0,    0,    0,  333,
+ /*  1800 */     0,  382,   22,  384,   48,   22,   48,    0,   59,  343,
+ /*  1810 */     0,   35,    0,    0,   59,  333,    0,  370,   44,   14,
+ /*  1820 */    47,   59,    0,    0,    0,  343,   39,    0,   39,  382,
+ /*  1830 */    42,  384,    0,   39,  415,  177,  370,  418,    0,    0,
+ /*  1840 */   421,  422,  423,  424,  425,  426,   47,  428,  382,   47,
+ /*  1850 */   384,   40,  370,    0,  435,    0,   66,  375,  439,  440,
+ /*  1860 */    35,    0,  415,   49,  382,  418,  384,   39,  421,  422,
+ /*  1870 */   423,  424,  425,  426,   39,  428,  333,   35,   49,    0,
+ /*  1880 */    35,  415,   49,   39,  418,    0,  343,  421,  422,  423,
+ /*  1890 */   424,  425,  426,   35,  428,   49,  430,  415,    1,  333,
+ /*  1900 */   418,   39,    0,  421,  422,  423,  424,  425,  426,  343,
+ /*  1910 */   428,  464,    0,  370,    0,    0,   19,  109,  375,   35,
+ /*  1920 */    22,    0,  107,   35,   35,  382,   35,  384,   35,   35,
+ /*  1930 */    33,   35,   22,    0,   35,   22,  370,   51,   35,   44,
+ /*  1940 */    35,  375,   35,    0,   44,   22,   49,    0,  382,   22,
+ /*  1950 */   384,   35,   55,   56,   57,   58,   59,   35,  415,    0,
+ /*  1960 */     0,  418,    0,   35,  421,  422,  423,  424,  425,  426,
+ /*  1970 */    22,  428,   20,   35,   35,   35,  101,  100,    0,   35,
+ /*  1980 */   100,  415,    0,   22,  418,  168,   22,  421,  422,  423,
+ /*  1990 */   424,  425,  426,  333,  428,  189,   99,    0,  168,  102,
+ /*  2000 */     0,  170,  193,  343,  168,    3,  100,   44,  256,  175,
+ /*  2010 */   101,  100,   44,   48,   48,   98,   96,   44,   44,  101,
+ /*  2020 */   101,   44,   47,   47,  100,  333,  100,  256,    3,  100,
+ /*  2030 */   370,  134,  101,  101,  100,  343,  101,   44,   35,   47,
+ /*  2040 */    35,   35,  382,  333,  384,   35,   35,   35,   47,    0,
+ /*  2050 */   101,  101,   44,  343,    0,    0,    0,  256,  100,   39,
+ /*  2060 */    47,  171,  370,    0,  110,   39,  169,  100,  250,   47,
+ /*  2070 */   101,  174,  101,  169,  382,  415,  384,   44,  418,  100,
+ /*  2080 */   370,  421,  422,  423,  424,  425,  426,  100,  428,  100,
+ /*  2090 */   333,  194,  382,  237,  384,  100,   98,   98,    2,   22,
+ /*  2100 */   343,   22,  215,   35,   47,   47,   35,  415,  101,  100,
+ /*  2110 */   418,   35,  122,  421,  422,  423,  424,  425,  426,  100,
+ /*  2120 */   428,   35,  101,  100,  100,  415,  111,  370,  418,  101,
+ /*  2130 */   100,  421,  422,  423,  424,  425,  426,  333,  428,  382,
+ /*  2140 */   101,  384,  217,  100,   35,  101,  100,  343,  101,  101,
+ /*  2150 */   100,  100,   35,  101,  101,   44,  122,  122,  122,  333,
+ /*  2160 */   100,  100,  100,   35,  100,  100,   22,   66,   65,  343,
+ /*  2170 */    35,   35,  415,   44,  370,  418,   35,   35,  421,  422,
+ /*  2180 */   423,  424,  425,  426,  333,  428,  382,   35,  384,   35,
+ /*  2190 */    35,   35,   72,   94,  343,   35,  370,   35,   35,   22,
+ /*  2200 */    35,   35,   35,   72,   35,   35,  333,   35,  382,   35,
+ /*  2210 */   384,   35,   22,   35,    0,   35,  343,   49,   39,  415,
+ /*  2220 */     0,  370,  418,   35,   49,  421,  422,  423,  424,  425,
+ /*  2230 */   426,   39,  428,  382,    0,  384,   35,   39,   49,    0,
+ /*  2240 */    35,  415,   49,  370,  418,   39,    0,  421,  422,  423,
+ /*  2250 */   424,  425,  426,   35,  428,  382,   35,  384,   22,   21,
+ /*  2260 */   476,  476,   22,   22,   21,   20,  415,    0,  476,  418,
+ /*  2270 */   333,  476,  421,  422,  423,  424,  425,  426,  476,  428,
+ /*  2280 */   343,  476,  476,  476,  476,  476,  476,  476,  415,  476,
+ /*  2290 */   333,  418,  476,  476,  421,  422,  423,  424,  425,  426,
+ /*  2300 */   343,  428,  476,  476,  476,  333,  476,  370,  476,  476,
+ /*  2310 */   476,  476,  476,  476,  476,  343,  476,  476,  476,  382,
+ /*  2320 */   476,  384,  476,  476,  476,  476,  476,  370,  476,  476,
+ /*  2330 */   476,  476,  476,  476,  476,  476,  476,  333,  476,  382,
+ /*  2340 */   476,  384,  370,  476,  476,  476,  476,  343,  476,  476,
+ /*  2350 */   476,  476,  415,  476,  382,  418,  384,  476,  421,  422,
+ /*  2360 */   423,  424,  425,  426,  476,  428,  476,  476,  476,  476,
+ /*  2370 */   476,  476,  415,  476,  370,  418,  476,  476,  421,  422,
+ /*  2380 */   423,  424,  425,  426,  476,  428,  382,  415,  384,  476,
+ /*  2390 */   418,  476,  476,  421,  422,  423,  424,  425,  426,  476,
+ /*  2400 */   428,  476,  476,  476,  476,  333,  476,  476,  476,  476,
+ /*  2410 */   476,  476,  476,  476,  476,  343,  476,  476,  476,  415,
+ /*  2420 */   476,  476,  418,  476,  333,  421,  422,  423,  424,  425,
+ /*  2430 */   426,  476,  428,  476,  343,  476,  476,  476,  476,  476,
+ /*  2440 */   476,  476,  370,  476,  476,  476,  476,  476,  476,  476,
+ /*  2450 */   476,  476,  333,  476,  382,  476,  384,  476,  476,  476,
+ /*  2460 */   476,  370,  343,  476,  476,  476,  476,  476,  476,  476,
+ /*  2470 */   476,  333,  476,  382,  476,  384,  476,  476,  476,  476,
+ /*  2480 */   476,  343,  476,  476,  476,  476,  476,  415,  476,  370,
+ /*  2490 */   418,  476,  476,  421,  422,  423,  424,  425,  426,  476,
+ /*  2500 */   428,  382,  476,  384,  476,  476,  415,  476,  370,  418,
+ /*  2510 */   476,  476,  421,  422,  423,  424,  425,  426,  333,  428,
+ /*  2520 */   382,  476,  384,  476,  476,  476,  476,  476,  343,  476,
+ /*  2530 */   476,  476,  476,  476,  415,  476,  476,  418,  476,  476,
+ /*  2540 */   421,  422,  423,  424,  425,  426,  476,  428,  476,  476,
+ /*  2550 */   476,  476,  476,  415,  476,  370,  418,  476,  476,  421,
+ /*  2560 */   422,  423,  424,  425,  426,  476,  428,  382,  476,  384,
+ /*  2570 */   476,  476,  476,  476,  476,  333,  476,  476,  476,  476,
+ /*  2580 */   476,  476,  476,  476,  476,  343,  476,  476,  476,  476,
+ /*  2590 */   476,  333,  476,  476,  476,  476,  476,  476,  476,  476,
+ /*  2600 */   415,  343,  476,  418,  476,  476,  421,  422,  423,  424,
+ /*  2610 */   425,  426,  370,  428,  476,  476,  476,  476,  476,  476,
+ /*  2620 */   476,  476,  476,  476,  382,  476,  384,  476,  370,  476,
+ /*  2630 */   476,  476,  476,  476,  476,  476,  476,  476,  476,  476,
+ /*  2640 */   382,  333,  384,  476,  476,  476,  476,  476,  476,  476,
+ /*  2650 */   476,  343,  476,  476,  476,  476,  476,  415,  476,  476,
+ /*  2660 */   418,  333,  476,  421,  422,  423,  424,  425,  426,  476,
+ /*  2670 */   428,  343,  476,  415,  476,  476,  418,  476,  370,  421,
+ /*  2680 */   422,  423,  424,  425,  426,  476,  428,  476,  476,  476,
+ /*  2690 */   382,  476,  384,  476,  476,  476,  476,  476,  370,  476,
+ /*  2700 */   476,  476,  476,  476,  476,  476,  476,  476,  333,  476,
+ /*  2710 */   382,  476,  384,  476,  476,  476,  476,  476,  343,  476,
+ /*  2720 */   476,  476,  476,  415,  476,  476,  418,  476,  476,  421,
+ /*  2730 */   422,  423,  424,  425,  426,  476,  428,  476,  476,  476,
+ /*  2740 */   476,  476,   33,  415,  476,  370,  418,  476,  476,  421,
+ /*  2750 */   422,  423,  424,  425,  426,  476,  428,  382,   49,  384,
+ /*  2760 */   476,  476,  476,  476,   55,   56,   57,   58,   59,  476,
+ /*  2770 */   476,  476,  476,  476,  476,  476,  476,  476,  476,  476,
+ /*  2780 */   476,  476,  476,  476,  476,  476,  476,  476,  476,  476,
+ /*  2790 */   415,  476,  476,  418,  476,  476,  421,  422,  423,  424,
+ /*  2800 */   425,  426,  476,  428,  476,  476,  476,  476,   99,  476,
+ /*  2810 */   476,  102,  476,  476,  476,  476,  476,  476,  476,  476,
+ /*  2820 */   476,  476,  476,  476,  476,  476,  476,  476,  476,  476,
+ /*  2830 */   476,  476,  476,  476,  476,  476,  476,  476,  476,  476,
+ /*  2840 */   476,  476,  476,  476,  476,  476,  476,  476,  476,  476,
+ /*  2850 */   476,  476,  476,  476,  476,  476,  476,  476,  476,  476,
  /*  2860 */   476,  476,  476,  476,  476,  476,  476,  476,  476,  476,
- /*  2870 */   476,  476,  476,  476,  476,  414,  476,  476,  476,  418,
- /*  2880 */   476,  476,  421,  422,  423,  424,  425,  426,  476,  428,
- /*  2890 */   414,  476,  476,  476,  418,  476,  476,  421,  422,  423,
- /*  2900 */   424,  425,  426,  476,  428,
+ /*  2870 */   476,  476,  476,  476,  476,  476,  476,  476,  169,  170,
+ /*  2880 */   476,  476,  476,  174,  476,  176,  476,  476,  476,  476,
+ /*  2890 */   476,  476,  476,  476,  476,  476,  476,  476,  476,  476,
+ /*  2900 */   476,  476,  476,  194,  476,  476,  476,  476,  476,  476,
+ /*  2910 */   476,  476,  476,  476,  476,  476,  476,  476,  476,  476,
+ /*  2920 */   476,  476,  476,  476,  476,  476,  476,  476,  476,  476,
+ /*  2930 */   476,  476,  476,  476,  476,  476,  476,  476,  476,  476,
+ /*  2940 */   476,  476,  476,  476,  476,  476,  476,  476,  476,  476,
+ /*  2950 */   476,  476,  476,  476,  476,  476,  476,  476,  476,  476,
+ /*  2960 */   476,  476,  476,  476,  476,  476,  476,  476,  476,  476,
+ /*  2970 */   476,  476,  476,  476,  476,  476,  476,  476,  476,  476,
+ /*  2980 */   476,  476,  476,  476,  476,  476,  476,  476,  476,  476,
+ /*  2990 */   476,  476,  476,  476,  476,  476,  476,  476,  476,  476,
+ /*  3000 */   476,  476,  476,  476,  476,  476,  476,  476,  476,  476,
+ /*  3010 */   476,  476,  476,  476,  476,  476,  476,  476,  476,  476,
+ /*  3020 */   476,  476,  476,  476,  476,  476,  476,  476,  476,  476,
+ /*  3030 */   476,  476,  476,  476,  476,  476,  476,  476,  476,  476,
+ /*  3040 */   476,  476,  476,  476,  476,  476,  476,  476,  476,  476,
+ /*  3050 */   476,  476,  476,  476,  476,  476,  476,  476,  476,  476,
+ /*  3060 */   476,  476,  476,  476,  476,  476,  476,  476,  476,  476,
+ /*  3070 */   476,  476,  476,  330,  330,  330,  330,  330,  330,  330,
+ /*  3080 */   330,  330,  330,  330,  330,  330,  330,  330,  330,  330,
+ /*  3090 */   330,  330,  330,  330,  330,  330,  330,  330,  330,  330,
+ /*  3100 */   330,  330,  330,  330,  330,  330,  330,  330,  330,  330,
+ /*  3110 */   330,  330,  330,  330,  330,  330,  330,  330,  330,  330,
+ /*  3120 */   330,  330,  330,  330,  330,  330,  330,  330,  330,  330,
+ /*  3130 */   330,  330,  330,  330,  330,  330,  330,  330,  330,  330,
+ /*  3140 */   330,  330,  330,  330,  330,  330,  330,  330,  330,  330,
+ /*  3150 */   330,  330,  330,  330,  330,  330,  330,  330,  330,  330,
+ /*  3160 */   330,  330,  330,  330,  330,  330,  330,  330,  330,  330,
+ /*  3170 */   330,  330,  330,  330,  330,  330,  330,  330,  330,  330,
+ /*  3180 */   330,  330,  330,  330,  330,  330,  330,  330,  330,  330,
+ /*  3190 */   330,  330,  330,  330,  330,  330,  330,  330,  330,  330,
+ /*  3200 */   330,  330,  330,  330,  330,  330,  330,  330,  330,  330,
+ /*  3210 */   330,  330,  330,  330,  330,  330,  330,  330,  330,  330,
+ /*  3220 */   330,  330,  330,  330,  330,  330,  330,  330,  330,  330,
+ /*  3230 */   330,  330,  330,  330,
 };
 #define YY_SHIFT_COUNT    (761)
 #define YY_SHIFT_MIN      (0)
-#define YY_SHIFT_MAX      (2182)
+#define YY_SHIFT_MAX      (2709)
 static const unsigned short int yy_shift_ofst[] = {
  /*     0 */   550,    0,  224,    0,  449,  449,  449,  449,  449,  449,
  /*    10 */   449,  449,  449,  449,  449,  449,  673,  897,  897, 1121,
  /*    20 */   897,  897,  897,  897,  897,  897,  897,  897,  897,  897,
  /*    30 */   897,  897,  897,  897,  897,  897,  897,  897,  897,  897,
- /*    40 */   897,  897,  897,  897,  897,  897,  897,  897,  897,  457,
- /*    50 */   492,  142,  145,  147,  107,  173,  107,  145,  145, 1347,
- /*    60 */  1347, 1347,  107, 1347, 1347,  501,  107,   18,  447,   47,
- /*    70 */    47,  447,  235,  235,    3,  286,    7,    7,   47,   47,
- /*    80 */    47,   47,   47,   47,   47,   51,   47,   47,  132,   18,
- /*    90 */    47,   47,  228,   47,   18,   47,   51,   47,   51,   18,
- /*   100 */    47,   47,   18,   47,   18,   18,   18,   47,  339,  223,
- /*   110 */   189,  189,  333,  114,  443,  443,  443,  443,  443,  443,
+ /*    40 */   897,  897,  897,  897,  897,  897,  897,  897,  897,  148,
+ /*    50 */   368,   93,   64,  140,  147,  322,  147,   64,   64, 1346,
+ /*    60 */  1346, 1346,  147, 1346, 1346,  314,  147,   76,  369,  111,
+ /*    70 */   111,  369,  656,  656,   18,  327,    7,    7,  111,  111,
+ /*    80 */   111,  111,  111,  111,  111,  145,  111,  111,  248,   76,
+ /*    90 */   111,  111,  363,  111,   76,  111,  145,  111,  145,   76,
+ /*   100 */   111,  111,   76,  111,   76,   76,   76,  111,  343,  223,
+ /*   110 */   189,  189,  405,  114,  443,  443,  443,  443,  443,  443,
  /*   120 */   443,  443,  443,  443,  443,  443,  443,  443,  443,  443,
- /*   130 */   443,  443,  443,  843,  325,    3,  286,  392,  220,  220,
- /*   140 */   220,  417,  369,  369,  392,  344,  344,  344,  132,  365,
- /*   150 */   297,   18,  439,   18,  439,  439,  503,  558,   35,   35,
- /*   160 */    35,   35,   35,   35,   35,   35, 2060,  217,  288,  483,
- /*   170 */   522,  260,  313,  243,  384,  940,  576,  484,  890,  751,
- /*   180 */   528,  810,  824,   60,  974,  824, 1065,  791,  275, 1124,
- /*   190 */  1336, 1204, 1353, 1378, 1353, 1236, 1384, 1384, 1353, 1236,
- /*   200 */  1236, 1315, 1324, 1384, 1329, 1384, 1384, 1384, 1411, 1386,
- /*   210 */  1411, 1386, 1418,  132, 1421,  132, 1426, 1430,  132, 1426,
- /*   220 */   132,  132,  132, 1384,  132, 1413, 1413, 1411,   18,   18,
- /*   230 */    18,   18,   18,   18,   18,   18,   18,   18,   18, 1384,
- /*   240 */  1411,  439,  439,  439, 1292, 1398, 1418,  339, 1325, 1323,
- /*   250 */  1421,  339, 1330, 1384, 1378, 1378,  439, 1262, 1266,  439,
- /*   260 */  1262, 1266,  439,  439,   18, 1253, 1355, 1262, 1271, 1273,
- /*   270 */  1293, 1124, 1283, 1277, 1276, 1318,  344, 1550, 1384, 1426,
- /*   280 */   339,  339, 1566, 1266,  439,  439,  439,  439,  439, 1266,
- /*   290 */   439, 1427,  339,  503,  339,  344, 1504, 1508,  439,  558,
- /*   300 */  1384,  339, 1576, 1411, 2905, 2905, 2905, 2905, 2905, 2905,
- /*   310 */  2905, 2905, 2905,   34,  430,   15,  590,  734,   16,  839,
- /*   320 */    79,  709,  792,  566,  856, 1023, 1023, 1023, 1023, 1023,
- /*   330 */  1023, 1023, 1023, 1023, 1167,  743,  253,  253,  402,   57,
- /*   340 */   758,  774,  949, 1067,  800,  980,   64,   64,  959, 1007,
- /*   350 */   387,  959,  959,  959, 1149,  641, 1116, 1140, 1147, 1070,
- /*   360 */  1168, 1078, 1119, 1141, 1164,  532, 1190, 1207, 1250, 1251,
- /*   370 */   990, 1189, 1212,  868, 1216, 1231, 1233,  943, 1004, 1117,
- /*   380 */  1153, 1261, 1264, 1267, 1270, 1272, 1274, 1302, 1289, 1196,
- /*   390 */  1206,  987, 1291, 1238, 1286, 1317, 1320, 1322, 1326, 1328,
- /*   400 */   190, 1248, 1361, 1256, 1331, 1614, 1620, 1624, 1590, 1633,
- /*   410 */  1599, 1428, 1600, 1602, 1604, 1432, 1644, 1607, 1610, 1438,
- /*   420 */  1647, 1440, 1649, 1615, 1651, 1630, 1653, 1621, 1460, 1469,
- /*   430 */  1473, 1660, 1667, 1669, 1488, 1490, 1672, 1689, 1629, 1690,
- /*   440 */  1691, 1692, 1652, 1696, 1697, 1698, 1702, 1703, 1704, 1705,
- /*   450 */  1706, 1552, 1673, 1709, 1555, 1712, 1714, 1715, 1716, 1717,
- /*   460 */  1718, 1719, 1720, 1721, 1722, 1723, 1724, 1726, 1728, 1729,
- /*   470 */  1730, 1693, 1731, 1732, 1733, 1734, 1736, 1738, 1725, 1739,
- /*   480 */  1740, 1741, 1603, 1743, 1744, 1735, 1700, 1737, 1707, 1745,
- /*   490 */  1687, 1742, 1750, 1694, 1752, 1695, 1756, 1760, 1753, 1746,
- /*   500 */  1727, 1751, 1755, 1747, 1757, 1773, 1759, 1748, 1774, 1775,
- /*   510 */  1776, 1758, 1586, 1764, 1780, 1781, 1749, 1800, 1805, 1771,
- /*   520 */  1761, 1770, 1812, 1778, 1767, 1779, 1817, 1784, 1772, 1783,
- /*   530 */  1820, 1788, 1782, 1786, 1827, 1829, 1830, 1832, 1766, 1754,
- /*   540 */  1798, 1813, 1836, 1803, 1804, 1806, 1807, 1808, 1809, 1810,
- /*   550 */  1796, 1802, 1815, 1818, 1826, 1819, 1852, 1833, 1856, 1840,
- /*   560 */  1814, 1858, 1842, 1841, 1877, 1843, 1879, 1846, 1887, 1866,
- /*   570 */  1878, 1864, 1865, 1867, 1821, 1801, 1904, 1762, 1811, 1713,
- /*   580 */  1872, 1896, 1921, 1765, 1901, 1777, 1789, 1924, 1925, 1785,
- /*   590 */  1768, 1923, 1883, 1675, 1834, 1828, 1844, 1885, 1849, 1893,
- /*   600 */  1853, 1847, 1906, 1908, 1855, 1857, 1861, 1862, 1863, 1919,
- /*   610 */  1918, 1922, 1868, 1926, 1710, 1870, 1871, 1964, 1929, 1791,
- /*   620 */  1939, 1941, 1942, 1943, 1944, 1945, 1880, 1881, 1937, 1790,
- /*   630 */  1946, 1947, 1983, 1986, 1988, 1989, 1892, 1954, 1751, 1950,
- /*   640 */  1907, 1903, 1909, 1912, 1913, 1837, 1914, 2015, 1977, 1848,
- /*   650 */  1927, 1910, 1751, 1971, 1978, 1928, 1792, 1930, 2019, 2002,
- /*   660 */  1816, 1933, 1934, 1938, 1935, 1948, 1940, 1987, 1949, 1951,
- /*   670 */  1992, 1952, 2008, 1825, 1955, 1932, 1953, 2017, 2023, 1962,
- /*   680 */  1968, 2036, 1973, 1974, 2039, 1976, 1979, 2043, 1982, 1991,
- /*   690 */  2048, 1995, 1981, 1985, 1990, 1999, 2005, 2064, 2010, 2076,
- /*   700 */  2013, 2064, 2064, 2092, 2056, 2058, 2089, 2090, 2091, 2093,
- /*   710 */  2094, 2096, 2098, 2099, 2100, 2101, 2055, 2044, 2095, 2102,
- /*   720 */  2105, 2106, 2120, 2108, 2110, 2112, 2077, 1796, 2113, 1802,
- /*   730 */  2115, 2116, 2118, 2119, 2130, 2122, 2155, 2123, 2111, 2124,
- /*   740 */  2161, 2129, 2125, 2126, 2166, 2132, 2127, 2134, 2169, 2136,
- /*   750 */  2131, 2139, 2172, 2140, 2144, 2182, 2168, 2171, 2173, 2174,
- /*   760 */  2176, 2178,
+ /*   130 */   443,  443,  443,  672,  483,   18,  327,  293,  253,  253,
+ /*   140 */   253,  217,  622,  622,  293,  523,  523,  523,  248,  460,
+ /*   150 */   354,   76,  585,   76,  585,  585,  604,  670,   35,   35,
+ /*   160 */    35,   35,   35,   35,   35,   35, 1897,  636,   15,  167,
+ /*   170 */    16,  297,  515,  252,  454,  454,  373,  842,  389,  484,
+ /*   180 */  1058, 1163,  862,  892,  922,  983,   45,  922,  878,  727,
+ /*   190 */   948, 1136, 1347, 1214, 1358, 1382, 1358, 1239, 1390, 1390,
+ /*   200 */  1358, 1239, 1239, 1313, 1329, 1390, 1338, 1390, 1390, 1390,
+ /*   210 */  1435, 1408, 1435, 1408, 1442,  248, 1457,  248, 1460, 1471,
+ /*   220 */   248, 1460,  248,  248,  248, 1390,  248, 1440, 1440, 1435,
+ /*   230 */    76,   76,   76,   76,   76,   76,   76,   76,   76,   76,
+ /*   240 */    76, 1390, 1435,  585,  585,  585, 1311, 1427, 1442,  343,
+ /*   250 */  1356, 1359, 1457,  343, 1362, 1390, 1382, 1382,  585, 1298,
+ /*   260 */  1307,  585, 1298, 1307,  585,  585,   76, 1314, 1407, 1298,
+ /*   270 */  1317, 1319, 1335, 1136, 1315, 1323, 1327, 1345,  523, 1579,
+ /*   280 */  1390, 1460,  343,  343, 1587, 1307,  585,  585,  585,  585,
+ /*   290 */   585, 1307,  585, 1445,  343,  604,  343,  523, 1528, 1529,
+ /*   300 */   585,  670, 1390,  343, 1600, 1435, 2904, 2904, 2904, 2904,
+ /*   310 */  2904, 2904, 2904, 2904, 2904,   34, 2709,  238,  590,  198,
+ /*   320 */   539,  973,  794,  486, 1064,  925, 1030,   48,   48,   48,
+ /*   330 */    48,   48,   48,   48,   48,   48,  831,  612,   65,   65,
+ /*   340 */   549,  737,  700,  891,  262,  448, 1025,  717,  531,  531,
+ /*   350 */   962,  751,  906,  962,  962,  962, 1202, 1015,  513, 1219,
+ /*   360 */  1008, 1101, 1194, 1104, 1113, 1149, 1159,  381, 1229, 1248,
+ /*   370 */  1259, 1267, 1069, 1196, 1221, 1217, 1231, 1233, 1234, 1143,
+ /*   380 */   836, 1152, 1165, 1260, 1262, 1273, 1276, 1277, 1318, 1281,
+ /*   390 */  1283, 1208, 1284, 1238, 1320, 1321, 1326, 1328, 1336, 1343,
+ /*   400 */   671, 1265, 1266, 1255, 1289, 1325, 1366, 1666, 1667, 1669,
+ /*   410 */  1631, 1674, 1640, 1468, 1642, 1643, 1644, 1472, 1682, 1648,
+ /*   420 */  1649, 1477, 1687, 1480, 1689, 1655, 1699, 1670, 1693, 1659,
+ /*   430 */  1500, 1508, 1511, 1701, 1702, 1704, 1523, 1526, 1708, 1715,
+ /*   440 */  1672, 1717, 1720, 1722, 1683, 1724, 1726, 1729, 1733, 1735,
+ /*   450 */  1736, 1743, 1745, 1591, 1712, 1748, 1594, 1750, 1753, 1754,
+ /*   460 */  1764, 1765, 1767, 1768, 1775, 1777, 1778, 1779, 1781, 1782,
+ /*   470 */  1784, 1785, 1786, 1716, 1759, 1760, 1761, 1791, 1792, 1793,
+ /*   480 */  1772, 1795, 1796, 1797, 1618, 1798, 1800, 1780, 1756, 1783,
+ /*   490 */  1758, 1807, 1749, 1776, 1810, 1755, 1812, 1762, 1813, 1816,
+ /*   500 */  1788, 1787, 1774, 1773, 1799, 1805, 1802, 1822, 1811, 1789,
+ /*   510 */  1823, 1824, 1827, 1794, 1658, 1832, 1838, 1839, 1790, 1853,
+ /*   520 */  1855, 1825, 1814, 1828, 1861, 1842, 1829, 1835, 1879, 1845,
+ /*   530 */  1833, 1844, 1885, 1858, 1846, 1862, 1902, 1912, 1914, 1915,
+ /*   540 */  1808, 1815, 1884, 1898, 1921, 1888, 1889, 1891, 1893, 1894,
+ /*   550 */  1896, 1899, 1895, 1900, 1903, 1905, 1910, 1907, 1933, 1913,
+ /*   560 */  1943, 1923, 1886, 1947, 1927, 1916, 1959, 1922, 1960, 1928,
+ /*   570 */  1962, 1948, 1952, 1938, 1939, 1940, 1875, 1877, 1978, 1817,
+ /*   580 */  1880, 1809, 1944, 1961, 1982, 1806, 1964, 1830, 1831, 1997,
+ /*   590 */  2000, 1836, 1834, 2002, 1963, 1752, 1906, 1909, 1911, 1965,
+ /*   600 */  1917, 1966, 1920, 1918, 1968, 1973, 1919, 1924, 1926, 1929,
+ /*   610 */  1931, 1974, 1975, 1976, 1934, 1977, 1771, 1932, 1935, 2025,
+ /*   620 */  1993, 1801, 2003, 2005, 2006, 2010, 2011, 2012, 1949, 1950,
+ /*   630 */  1992, 1818, 2008, 2001, 2049, 2054, 2055, 2056, 1958, 2020,
+ /*   640 */  1773, 2013, 1967, 1969, 1971, 1979, 1987, 1890, 1989, 2063,
+ /*   650 */  2026, 1904, 1995, 1954, 1773, 2022, 2033, 1998, 1856, 1999,
+ /*   660 */  2096, 2077, 1887, 2009, 2007, 2019, 2021, 2023, 2028, 2057,
+ /*   670 */  2024, 2030, 2058, 2039, 2079, 1925, 2043, 2015, 2044, 2068,
+ /*   680 */  2071, 2046, 2047, 2076, 2050, 2048, 2086, 2051, 2052, 2109,
+ /*   690 */  2060, 2053, 2117, 2061, 1990, 2034, 2035, 2036, 2062, 2111,
+ /*   700 */  2064, 2128, 2065, 2111, 2111, 2144, 2101, 2103, 2135, 2136,
+ /*   710 */  2141, 2142, 2152, 2154, 2155, 2156, 2120, 2099, 2129, 2160,
+ /*   720 */  2162, 2163, 2177, 2165, 2166, 2167, 2131, 1895, 2169, 1900,
+ /*   730 */  2170, 2172, 2174, 2176, 2190, 2178, 2214, 2180, 2168, 2179,
+ /*   740 */  2220, 2188, 2175, 2192, 2234, 2201, 2189, 2198, 2239, 2205,
+ /*   750 */  2193, 2206, 2246, 2218, 2221, 2267, 2236, 2238, 2240, 2241,
+ /*   760 */  2243, 2245,
 };
-#define YY_REDUCE_COUNT (312)
-#define YY_REDUCE_MIN   (-396)
-#define YY_REDUCE_MAX   (2476)
+#define YY_REDUCE_COUNT (314)
+#define YY_REDUCE_MIN   (-397)
+#define YY_REDUCE_MAX   (2375)
 static const short yy_reduce_ofst[] = {
- /*     0 */  -140,  137,  -82,  358,  444,  578,  814,  841, 1034, 1064,
- /*    10 */  1132, 1240, 1260, 1344, 1368, 1445,  598, -333,  672, 1468,
- /*    20 */   901, 1491, 1514, 1577, 1642, 1663, 1676, 1763, 1787, 1850,
- /*    30 */  1874, 1920, 1936, 1996, 2020, 2047, 2066, 2117, 2133, 2163,
- /*    40 */  2184, 2230, 2290, 2303, 2354, 2400, 2415, 2461, 2476,  372,
- /*    50 */  -195, -396, -265,  487,  595,  607,  701,  481,  761, -362,
- /*    60 */  -355,  285,  749,  136,  612, -279,  -55,  256, -346, -167,
- /*    70 */    -5, -381, -334, -257, -205, -249,   45,  130,  300,  303,
- /*    80 */   356,  377,  409,  425,  432,  177,  469,  489,  252, -308,
- /*    90 */   521,  573,  170,  620,  172,  622,  261,  707,  396,  682,
- /*   100 */   739,  745,  278,  793,  715,  321,  781,  795, -266,    8,
- /*   110 */  -350, -350,  115, -238,  161,  214,  257,  315,  374,  433,
- /*   120 */   445,  463,  585,  587,  617,  677,  681,  806,  807,  813,
- /*   130 */   819,  830,  832,  -86, -289, -111,   23,  154, -289,   70,
- /*   140 */   188,  -25,  480,  511,  380,  416,  498,  704,  381, -354,
- /*   150 */   426,  513,  690,  502,  733,  798,  808,  353, -369, -365,
- /*   160 */   324,  370,  458,  505,  686,  458,  764,  368,  621,  825,
- /*   170 */   753,  780,  906,  822,  917,  917,  946,  898,  954,  963,
- /*   180 */   930,  921,  871,  871,  891,  871,  916,  925,  917,  967,
- /*   190 */   971,  989, 1001, 1008, 1012, 1016, 1063, 1066, 1022, 1025,
- /*   200 */  1026, 1060, 1069, 1074, 1073, 1084, 1086, 1088, 1097, 1096,
- /*   210 */  1101, 1098, 1030, 1090, 1059, 1093, 1105, 1050, 1103, 1110,
- /*   220 */  1111, 1113, 1114, 1126, 1120, 1125, 1129, 1136, 1108, 1112,
- /*   230 */  1115, 1122, 1127, 1131, 1133, 1137, 1138, 1139, 1142, 1151,
- /*   240 */  1144, 1099, 1102, 1128, 1081, 1094, 1107, 1162, 1104, 1118,
- /*   250 */  1135, 1171, 1123, 1179, 1143, 1145, 1146, 1068, 1134, 1150,
- /*   260 */  1072, 1148, 1156, 1157,  917, 1080, 1082, 1085, 1092, 1091,
- /*   270 */  1106, 1152, 1076, 1095, 1130,  871, 1223, 1154, 1242, 1241,
- /*   280 */  1234, 1239, 1194, 1193, 1209, 1210, 1211, 1213, 1214, 1200,
- /*   290 */  1218, 1208, 1252, 1237, 1257, 1263, 1169, 1243, 1229, 1254,
- /*   300 */  1269, 1278, 1279, 1282, 1215, 1217, 1222, 1225, 1265, 1268,
- /*   310 */  1275, 1281, 1294,
+ /*     0 */  -156,  364,  -82,  588,  -20,  614,  804,  890, 1024, 1050,
+ /*    10 */  1118, 1222, 1288, 1316, 1348, 1419,  174, -333,  154,  450,
+ /*    20 */   674, 1447, 1097, 1482, 1466, 1543, 1566, 1660, 1692, 1710,
+ /*    30 */  1757, 1804, 1826, 1851, 1873, 1937, 1957, 1972, 2004, 2072,
+ /*    40 */  2091, 2119, 2138, 2185, 2242, 2258, 2308, 2328, 2375,  383,
+ /*    50 */   270, -397,   83, -395,  371,  416,  554,   75,  501,  235,
+ /*    60 */   786,  827, -139,  683,  834, -195, -165, -359,  -80, -172,
+ /*    70 */   -13, -383, -254, -207, -213,  149,  -52,  290, -152,   -5,
+ /*    80 */   263,  376,  407,  413,  453,   82,  508,  593,  462,  271,
+ /*    90 */   610,  631,  275,  657,  374,  725,  301,  745,  372, -170,
+ /*   100 */   748,  796,  399,  808,  -83,  421,  605,  810,  260, -319,
+ /*   110 */  -338, -338, -293, -327,   94,  237,  433,  502,  534,  669,
+ /*   120 */   693,  712,  802,  807,  809,  813,  815,  833,  849,  854,
+ /*   130 */   865,  867,  868, -275, -251, -131,  355,  467, -251,  437,
+ /*   140 */   559,  452,  445,  479,  726, -334,  -85,  719,  681,  168,
+ /*   150 */   736,  268,  134,  805,  797,  799,  742,  850, -369,  387,
+ /*   160 */   499,  580,  713,  832,  913,  713,  637,  927,  485,  899,
+ /*   170 */   818,  835,  949,  839,  941,  945,  940,  940,  980,  939,
+ /*   180 */  1032, 1028,  994,  984,  933,  933,  919,  933,  947,  938,
+ /*   190 */   940,  974,  976,  996, 1012, 1011, 1018, 1022, 1070, 1071,
+ /*   200 */  1026, 1027, 1037, 1063, 1073, 1089, 1083, 1094, 1096, 1099,
+ /*   210 */  1123, 1127, 1125, 1130, 1060, 1132, 1100, 1137, 1142, 1090,
+ /*   220 */  1144, 1151, 1146, 1147, 1148, 1157, 1153, 1154, 1158, 1169,
+ /*   230 */  1138, 1139, 1140, 1141, 1156, 1160, 1161, 1167, 1168, 1175,
+ /*   240 */  1177, 1164, 1172, 1131, 1134, 1135, 1110, 1116, 1119, 1187,
+ /*   250 */  1145, 1155, 1176, 1201, 1162, 1224, 1179, 1180, 1174, 1108,
+ /*   260 */  1171, 1191, 1126, 1184, 1203, 1204,  940, 1128, 1133, 1166,
+ /*   270 */  1150, 1170, 1173, 1178, 1122, 1182, 1185,  933, 1251, 1181,
+ /*   280 */  1261, 1258, 1263, 1264, 1213, 1212, 1228, 1232, 1235, 1236,
+ /*   290 */  1237, 1216, 1241, 1226, 1268, 1269, 1279, 1282, 1192, 1278,
+ /*   300 */  1250, 1274, 1291, 1290, 1303, 1306, 1252, 1243, 1244, 1270,
+ /*   310 */  1296, 1299, 1300, 1322, 1334,
 };
 static const YYACTIONTYPE yy_default[] = {
  /*     0 */  1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719,
@@ -941,28 +975,28 @@ static const YYACTIONTYPE yy_default[] = {
  /*   140 */  2218, 1799, 2178, 2178, 1719, 1719, 1719, 1719, 1801, 2050,
  /*   150 */  1719, 1719, 1719, 1719, 1719, 1719, 1920, 1719, 1719, 1719,
  /*   160 */  1719, 1719, 1944, 1719, 1719, 1719, 2044, 1719, 1719, 2243,
- /*   170 */  2299, 1719, 1719, 2246, 1719, 1719, 1719, 1997, 1719, 1719,
- /*   180 */  1874, 2233, 2210, 2224, 2283, 2211, 2208, 2227, 1719, 2237,
- /*   190 */  1719, 2031, 1990, 1719, 1990, 1987, 1719, 1719, 1990, 1987,
- /*   200 */  1987, 1863, 1859, 1719, 1857, 1719, 1719, 1719, 1719, 1766,
- /*   210 */  1719, 1766, 1719, 1801, 1719, 1801, 1719, 1719, 1801, 1719,
- /*   220 */  1801, 1801, 1801, 1719, 1801, 1779, 1779, 1719, 1719, 1719,
+ /*   170 */  2299, 1719, 1719, 2246, 1719, 1719, 1719, 1719, 1719, 1997,
+ /*   180 */  1719, 1719, 1874, 2233, 2210, 2224, 2283, 2211, 2208, 2227,
+ /*   190 */  1719, 2237, 1719, 2031, 1990, 1719, 1990, 1987, 1719, 1719,
+ /*   200 */  1990, 1987, 1987, 1863, 1859, 1719, 1857, 1719, 1719, 1719,
+ /*   210 */  1719, 1766, 1719, 1766, 1719, 1801, 1719, 1801, 1719, 1719,
+ /*   220 */  1801, 1719, 1801, 1801, 1801, 1719, 1801, 1779, 1779, 1719,
  /*   230 */  1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719,
- /*   240 */  1719, 1719, 1719, 1719, 2062, 2048, 1719, 1799, 2042, 2040,
- /*   250 */  1719, 1799, 2038, 1719, 1719, 1719, 1719, 2254, 2252, 1719,
- /*   260 */  2254, 2252, 1719, 1719, 1719, 2268, 2264, 2254, 2272, 2270,
- /*   270 */  2239, 2237, 2302, 2289, 2285, 2224, 1719, 1719, 1719, 1719,
- /*   280 */  1799, 1799, 1719, 2252, 1719, 1719, 1719, 1719, 1719, 2252,
- /*   290 */  1719, 1719, 1799, 1719, 1799, 1719, 1719, 1890, 1719, 1719,
- /*   300 */  1719, 1799, 1751, 1719, 2033, 2053, 2015, 2015, 1923, 1923,
- /*   310 */  1923, 1802, 1724, 1719, 1719, 1719, 1719, 1719, 1719, 1719,
- /*   320 */  1719, 1719, 1719, 1719, 1719, 2267, 2266, 2133, 1719, 2182,
- /*   330 */  2181, 2180, 2171, 2132, 1886, 1719, 2131, 2130, 1719, 1719,
- /*   340 */  1719, 1719, 1719, 1719, 1719, 1719, 2006, 2005, 2124, 1719,
- /*   350 */  1719, 2125, 2123, 2122, 1719, 1719, 1719, 1719, 1719, 1719,
+ /*   240 */  1719, 1719, 1719, 1719, 1719, 1719, 2062, 2048, 1719, 1799,
+ /*   250 */  2042, 2040, 1719, 1799, 2038, 1719, 1719, 1719, 1719, 2254,
+ /*   260 */  2252, 1719, 2254, 2252, 1719, 1719, 1719, 2268, 2264, 2254,
+ /*   270 */  2272, 2270, 2239, 2237, 2302, 2289, 2285, 2224, 1719, 1719,
+ /*   280 */  1719, 1719, 1799, 1799, 1719, 2252, 1719, 1719, 1719, 1719,
+ /*   290 */  1719, 2252, 1719, 1719, 1799, 1719, 1799, 1719, 1719, 1890,
+ /*   300 */  1719, 1719, 1719, 1799, 1751, 1719, 2033, 2053, 2015, 2015,
+ /*   310 */  1923, 1923, 1923, 1802, 1724, 1719, 1719, 1719, 1719, 1719,
+ /*   320 */  1719, 1719, 1719, 1719, 1719, 1719, 1719, 2267, 2266, 2133,
+ /*   330 */  1719, 2182, 2181, 2180, 2171, 2132, 1886, 1719, 2131, 2130,
+ /*   340 */  1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 2006, 2005,
+ /*   350 */  2124, 1719, 1719, 2125, 2123, 2122, 1719, 1719, 1719, 1719,
  /*   360 */  1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719,
- /*   370 */  1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 2286, 2290,
- /*   380 */  1719, 1719, 1719, 1719, 1719, 1719, 1719, 2207, 1719, 1719,
+ /*   370 */  1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719,
+ /*   380 */  2286, 2290, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 2207,
  /*   390 */  1719, 1719, 1719, 2106, 1719, 1719, 1719, 1719, 1719, 1719,
  /*   400 */  1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719,
  /*   410 */  1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719,
@@ -974,27 +1008,27 @@ static const YYACTIONTYPE yy_default[] = {
  /*   470 */  1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719,
  /*   480 */  1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719,
  /*   490 */  1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719,
- /*   500 */  1756, 2111, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719,
+ /*   500 */  1719, 1719, 1756, 2111, 1719, 1719, 1719, 1719, 1719, 1719,
  /*   510 */  1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719,
  /*   520 */  1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719,
  /*   530 */  1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719,
  /*   540 */  1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719,
- /*   550 */  1840, 1839, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719,
+ /*   550 */  1719, 1719, 1840, 1839, 1719, 1719, 1719, 1719, 1719, 1719,
  /*   560 */  1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719,
- /*   570 */  1719, 1719, 1719, 1719, 2115, 1719, 1719, 1719, 1719, 1719,
+ /*   570 */  1719, 1719, 1719, 1719, 1719, 1719, 2115, 1719, 1719, 1719,
  /*   580 */  1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719,
- /*   590 */  1719, 2282, 2240, 1719, 1719, 1719, 1719, 1719, 1719, 1719,
+ /*   590 */  1719, 1719, 1719, 2282, 2240, 1719, 1719, 1719, 1719, 1719,
  /*   600 */  1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719,
- /*   610 */  1719, 2106, 1719, 2265, 1719, 1719, 2280, 1719, 2284, 1719,
- /*   620 */  1719, 1719, 1719, 1719, 1719, 1719, 2217, 2213, 1719, 1719,
- /*   630 */  2209, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 2114, 1719,
- /*   640 */  1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719,
- /*   650 */  1719, 1719, 2105, 1719, 2168, 1719, 1719, 1719, 2202, 1719,
- /*   660 */  1719, 2153, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719,
- /*   670 */  1719, 2115, 1719, 2118, 1719, 1719, 1719, 1719, 1719, 1917,
- /*   680 */  1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719,
- /*   690 */  1719, 1719, 1902, 1900, 1899, 1898, 1719, 1930, 1719, 1719,
- /*   700 */  1719, 1926, 1925, 1719, 1719, 1719, 1719, 1719, 1719, 1719,
+ /*   610 */  1719, 1719, 1719, 2106, 1719, 2265, 1719, 1719, 2280, 1719,
+ /*   620 */  2284, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 2217, 2213,
+ /*   630 */  1719, 1719, 2209, 1719, 1719, 1719, 1719, 1719, 1719, 1719,
+ /*   640 */  2114, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719,
+ /*   650 */  1719, 1719, 1719, 1719, 2105, 1719, 2168, 1719, 1719, 1719,
+ /*   660 */  2202, 1719, 1719, 2153, 1719, 1719, 1719, 1719, 1719, 1719,
+ /*   670 */  1719, 1719, 1719, 2115, 1719, 2118, 1719, 1719, 1719, 1719,
+ /*   680 */  1719, 1917, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719,
+ /*   690 */  1719, 1719, 1719, 1719, 1902, 1900, 1899, 1898, 1719, 1930,
+ /*   700 */  1719, 1719, 1719, 1926, 1925, 1719, 1719, 1719, 1719, 1719,
  /*   710 */  1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1820, 1719,
  /*   720 */  1719, 1719, 1719, 1719, 1719, 1719, 1719, 1812, 1719, 1811,
  /*   730 */  1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719,
@@ -1795,66 +1829,66 @@ static const char *const yyTokenName[] = {
   /*  355 */ "integer_list",
   /*  356 */ "variable_list",
   /*  357 */ "retention_list",
-  /*  358 */ "alter_db_option",
-  /*  359 */ "retention",
-  /*  360 */ "full_table_name",
-  /*  361 */ "column_def_list",
-  /*  362 */ "tags_def_opt",
-  /*  363 */ "table_options",
-  /*  364 */ "multi_create_clause",
-  /*  365 */ "tags_def",
-  /*  366 */ "multi_drop_clause",
-  /*  367 */ "alter_table_clause",
-  /*  368 */ "alter_table_options",
-  /*  369 */ "column_name",
-  /*  370 */ "type_name",
-  /*  371 */ "signed_literal",
-  /*  372 */ "create_subtable_clause",
-  /*  373 */ "specific_cols_opt",
-  /*  374 */ "expression_list",
-  /*  375 */ "drop_table_clause",
-  /*  376 */ "col_name_list",
-  /*  377 */ "column_def",
-  /*  378 */ "duration_list",
-  /*  379 */ "rollup_func_list",
-  /*  380 */ "alter_table_option",
-  /*  381 */ "duration_literal",
-  /*  382 */ "rollup_func_name",
-  /*  383 */ "function_name",
-  /*  384 */ "col_name",
-  /*  385 */ "db_name_cond_opt",
-  /*  386 */ "like_pattern_opt",
-  /*  387 */ "table_name_cond",
-  /*  388 */ "from_db_opt",
-  /*  389 */ "tag_list_opt",
-  /*  390 */ "tag_item",
-  /*  391 */ "column_alias",
-  /*  392 */ "full_index_name",
-  /*  393 */ "index_options",
-  /*  394 */ "index_name",
-  /*  395 */ "func_list",
-  /*  396 */ "sliding_opt",
-  /*  397 */ "sma_stream_opt",
-  /*  398 */ "func",
-  /*  399 */ "sma_func_name",
-  /*  400 */ "query_or_subquery",
-  /*  401 */ "cgroup_name",
-  /*  402 */ "analyze_opt",
-  /*  403 */ "explain_options",
-  /*  404 */ "insert_query",
-  /*  405 */ "or_replace_opt",
-  /*  406 */ "agg_func_opt",
-  /*  407 */ "bufsize_opt",
-  /*  408 */ "language_opt",
-  /*  409 */ "stream_name",
-  /*  410 */ "stream_options",
-  /*  411 */ "col_list_opt",
-  /*  412 */ "tag_def_or_ref_opt",
-  /*  413 */ "subtable_opt",
-  /*  414 */ "expression",
-  /*  415 */ "dnode_list",
-  /*  416 */ "where_clause_opt",
-  /*  417 */ "signed",
+  /*  358 */ "signed",
+  /*  359 */ "alter_db_option",
+  /*  360 */ "retention",
+  /*  361 */ "full_table_name",
+  /*  362 */ "column_def_list",
+  /*  363 */ "tags_def_opt",
+  /*  364 */ "table_options",
+  /*  365 */ "multi_create_clause",
+  /*  366 */ "tags_def",
+  /*  367 */ "multi_drop_clause",
+  /*  368 */ "alter_table_clause",
+  /*  369 */ "alter_table_options",
+  /*  370 */ "column_name",
+  /*  371 */ "type_name",
+  /*  372 */ "signed_literal",
+  /*  373 */ "create_subtable_clause",
+  /*  374 */ "specific_cols_opt",
+  /*  375 */ "expression_list",
+  /*  376 */ "drop_table_clause",
+  /*  377 */ "col_name_list",
+  /*  378 */ "column_def",
+  /*  379 */ "duration_list",
+  /*  380 */ "rollup_func_list",
+  /*  381 */ "alter_table_option",
+  /*  382 */ "duration_literal",
+  /*  383 */ "rollup_func_name",
+  /*  384 */ "function_name",
+  /*  385 */ "col_name",
+  /*  386 */ "db_name_cond_opt",
+  /*  387 */ "like_pattern_opt",
+  /*  388 */ "table_name_cond",
+  /*  389 */ "from_db_opt",
+  /*  390 */ "tag_list_opt",
+  /*  391 */ "tag_item",
+  /*  392 */ "column_alias",
+  /*  393 */ "full_index_name",
+  /*  394 */ "index_options",
+  /*  395 */ "index_name",
+  /*  396 */ "func_list",
+  /*  397 */ "sliding_opt",
+  /*  398 */ "sma_stream_opt",
+  /*  399 */ "func",
+  /*  400 */ "sma_func_name",
+  /*  401 */ "query_or_subquery",
+  /*  402 */ "cgroup_name",
+  /*  403 */ "analyze_opt",
+  /*  404 */ "explain_options",
+  /*  405 */ "insert_query",
+  /*  406 */ "or_replace_opt",
+  /*  407 */ "agg_func_opt",
+  /*  408 */ "bufsize_opt",
+  /*  409 */ "language_opt",
+  /*  410 */ "stream_name",
+  /*  411 */ "stream_options",
+  /*  412 */ "col_list_opt",
+  /*  413 */ "tag_def_or_ref_opt",
+  /*  414 */ "subtable_opt",
+  /*  415 */ "expression",
+  /*  416 */ "dnode_list",
+  /*  417 */ "where_clause_opt",
   /*  418 */ "literal_func",
   /*  419 */ "literal_list",
   /*  420 */ "table_alias",
@@ -2029,8 +2063,8 @@ static const char *const yyRuleName[] = {
  /* 106 */ "db_options ::= db_options WAL_ROLL_PERIOD NK_INTEGER",
  /* 107 */ "db_options ::= db_options WAL_SEGMENT_SIZE NK_INTEGER",
  /* 108 */ "db_options ::= db_options STT_TRIGGER NK_INTEGER",
- /* 109 */ "db_options ::= db_options TABLE_PREFIX NK_INTEGER",
- /* 110 */ "db_options ::= db_options TABLE_SUFFIX NK_INTEGER",
+ /* 109 */ "db_options ::= db_options TABLE_PREFIX signed",
+ /* 110 */ "db_options ::= db_options TABLE_SUFFIX signed",
  /* 111 */ "alter_db_options ::= alter_db_option",
  /* 112 */ "alter_db_options ::= alter_db_options alter_db_option",
  /* 113 */ "alter_db_option ::= BUFFER NK_INTEGER",
@@ -2637,36 +2671,36 @@ static void yy_destructor(
     case 351: /* alter_db_options */
     case 353: /* start_opt */
     case 354: /* end_opt */
-    case 359: /* retention */
-    case 360: /* full_table_name */
-    case 363: /* table_options */
-    case 367: /* alter_table_clause */
-    case 368: /* alter_table_options */
-    case 371: /* signed_literal */
-    case 372: /* create_subtable_clause */
-    case 375: /* drop_table_clause */
-    case 377: /* column_def */
-    case 381: /* duration_literal */
-    case 382: /* rollup_func_name */
-    case 384: /* col_name */
-    case 385: /* db_name_cond_opt */
-    case 386: /* like_pattern_opt */
-    case 387: /* table_name_cond */
-    case 388: /* from_db_opt */
-    case 390: /* tag_item */
-    case 392: /* full_index_name */
-    case 393: /* index_options */
-    case 396: /* sliding_opt */
-    case 397: /* sma_stream_opt */
-    case 398: /* func */
-    case 400: /* query_or_subquery */
-    case 403: /* explain_options */
-    case 404: /* insert_query */
-    case 410: /* stream_options */
-    case 413: /* subtable_opt */
-    case 414: /* expression */
-    case 416: /* where_clause_opt */
-    case 417: /* signed */
+    case 358: /* signed */
+    case 360: /* retention */
+    case 361: /* full_table_name */
+    case 364: /* table_options */
+    case 368: /* alter_table_clause */
+    case 369: /* alter_table_options */
+    case 372: /* signed_literal */
+    case 373: /* create_subtable_clause */
+    case 376: /* drop_table_clause */
+    case 378: /* column_def */
+    case 382: /* duration_literal */
+    case 383: /* rollup_func_name */
+    case 385: /* col_name */
+    case 386: /* db_name_cond_opt */
+    case 387: /* like_pattern_opt */
+    case 388: /* table_name_cond */
+    case 389: /* from_db_opt */
+    case 391: /* tag_item */
+    case 393: /* full_index_name */
+    case 394: /* index_options */
+    case 397: /* sliding_opt */
+    case 398: /* sma_stream_opt */
+    case 399: /* func */
+    case 401: /* query_or_subquery */
+    case 404: /* explain_options */
+    case 405: /* insert_query */
+    case 411: /* stream_options */
+    case 414: /* subtable_opt */
+    case 415: /* expression */
+    case 417: /* where_clause_opt */
     case 418: /* literal_func */
     case 421: /* expr_or_subquery */
     case 422: /* pseudo_column */
@@ -2711,7 +2745,7 @@ static void yy_destructor(
     case 332: /* alter_account_options */
     case 334: /* alter_account_option */
     case 352: /* speed_opt */
-    case 407: /* bufsize_opt */
+    case 408: /* bufsize_opt */
 {
  
 }
@@ -2721,14 +2755,14 @@ static void yy_destructor(
     case 343: /* table_name */
     case 344: /* topic_name */
     case 346: /* dnode_endpoint */
-    case 369: /* column_name */
-    case 383: /* function_name */
-    case 391: /* column_alias */
-    case 394: /* index_name */
-    case 399: /* sma_func_name */
-    case 401: /* cgroup_name */
-    case 408: /* language_opt */
-    case 409: /* stream_name */
+    case 370: /* column_name */
+    case 384: /* function_name */
+    case 392: /* column_alias */
+    case 395: /* index_name */
+    case 400: /* sma_func_name */
+    case 402: /* cgroup_name */
+    case 409: /* language_opt */
+    case 410: /* stream_name */
     case 420: /* table_alias */
     case 426: /* star_func */
     case 428: /* noarg_func */
@@ -2757,9 +2791,9 @@ static void yy_destructor(
     case 347: /* force_opt */
     case 348: /* not_exists_opt */
     case 350: /* exists_opt */
-    case 402: /* analyze_opt */
-    case 405: /* or_replace_opt */
-    case 406: /* agg_func_opt */
+    case 403: /* analyze_opt */
+    case 406: /* or_replace_opt */
+    case 407: /* agg_func_opt */
     case 451: /* set_quantifier_opt */
 {
  
@@ -2768,21 +2802,21 @@ static void yy_destructor(
     case 355: /* integer_list */
     case 356: /* variable_list */
     case 357: /* retention_list */
-    case 361: /* column_def_list */
-    case 362: /* tags_def_opt */
-    case 364: /* multi_create_clause */
-    case 365: /* tags_def */
-    case 366: /* multi_drop_clause */
-    case 373: /* specific_cols_opt */
-    case 374: /* expression_list */
-    case 376: /* col_name_list */
-    case 378: /* duration_list */
-    case 379: /* rollup_func_list */
-    case 389: /* tag_list_opt */
-    case 395: /* func_list */
-    case 411: /* col_list_opt */
-    case 412: /* tag_def_or_ref_opt */
-    case 415: /* dnode_list */
+    case 362: /* column_def_list */
+    case 363: /* tags_def_opt */
+    case 365: /* multi_create_clause */
+    case 366: /* tags_def */
+    case 367: /* multi_drop_clause */
+    case 374: /* specific_cols_opt */
+    case 375: /* expression_list */
+    case 377: /* col_name_list */
+    case 379: /* duration_list */
+    case 380: /* rollup_func_list */
+    case 390: /* tag_list_opt */
+    case 396: /* func_list */
+    case 412: /* col_list_opt */
+    case 413: /* tag_def_or_ref_opt */
+    case 416: /* dnode_list */
     case 419: /* literal_list */
     case 427: /* star_func_para_list */
     case 429: /* other_para_list */
@@ -2798,13 +2832,13 @@ static void yy_destructor(
  nodesDestroyList((yypminor->yy432)); 
 }
       break;
-    case 358: /* alter_db_option */
-    case 380: /* alter_table_option */
+    case 359: /* alter_db_option */
+    case 381: /* alter_table_option */
 {
  
 }
       break;
-    case 370: /* type_name */
+    case 371: /* type_name */
 {
  
 }
@@ -2958,15 +2992,18 @@ static YYACTIONTYPE yy_find_shift_action(
   do{
     i = yy_shift_ofst[stateno];
     assert( i>=0 );
-    /* assert( i+YYNTOKEN<=(int)YY_NLOOKAHEAD ); */
+    assert( i<=YY_ACTTAB_COUNT );
+    assert( i+YYNTOKEN<=(int)YY_NLOOKAHEAD );
     assert( iLookAhead!=YYNOCODE );
     assert( iLookAhead < YYNTOKEN );
     i += iLookAhead;
-    if( i>=YY_NLOOKAHEAD || yy_lookahead[i]!=iLookAhead ){
+    assert( i<(int)YY_NLOOKAHEAD );
+    if( yy_lookahead[i]!=iLookAhead ){
 #ifdef YYFALLBACK
       YYCODETYPE iFallback;            /* Fallback token */
-      if( iLookAhead %s\n",
@@ -2981,16 +3018,8 @@ static YYACTIONTYPE yy_find_shift_action(
 #ifdef YYWILDCARD
       {
         int j = i - iLookAhead + YYWILDCARD;
-        if( 
-#if YY_SHIFT_MIN+YYWILDCARD<0
-          j>=0 &&
-#endif
-#if YY_SHIFT_MAX+YYWILDCARD>=YY_ACTTAB_COUNT
-          j0
-        ){
+        assert( j<(int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0])) );
+        if( yy_lookahead[j]==YYWILDCARD && iLookAhead>0 ){
 #ifndef NDEBUG
           if( yyTraceFILE ){
             fprintf(yyTraceFILE, "%sWILDCARD %s => %s\n",
@@ -3004,6 +3033,7 @@ static YYACTIONTYPE yy_find_shift_action(
 #endif /* YYWILDCARD */
       return yy_default[stateno];
     }else{
+      assert( i>=0 && iyytos;
 #ifndef NDEBUG
   if( yyTraceFILE && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){
-    yysize = yyRuleInfo[yyruleno].nrhs;
+    yysize = yyRuleInfoNRhs[yyruleno];
     if( yysize ){
-      fprintf(yyTraceFILE, "%sReduce %d [%s], go to state %d.\n",
+      fprintf(yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n",
         yyTracePrompt,
-        yyruleno, yyRuleName[yyruleno], yymsp[yysize].stateno);
+        yyruleno, yyRuleName[yyruleno],
+        yyrulenoyytos - yypParser->yystack)>yypParser->yyhwm ){
       yypParser->yyhwm++;
@@ -4183,12 +4800,12 @@ static YYACTIONTYPE yy_reduce(
 { yylhsminor.yy448 = setDatabaseOption(pCxt, yymsp[-2].minor.yy448, DB_OPTION_STT_TRIGGER, &yymsp[0].minor.yy0); }
   yymsp[-2].minor.yy448 = yylhsminor.yy448;
         break;
-      case 109: /* db_options ::= db_options TABLE_PREFIX NK_INTEGER */
-{ yylhsminor.yy448 = setDatabaseOption(pCxt, yymsp[-2].minor.yy448, DB_OPTION_TABLE_PREFIX, &yymsp[0].minor.yy0); }
+      case 109: /* db_options ::= db_options TABLE_PREFIX signed */
+{ yylhsminor.yy448 = setDatabaseOption(pCxt, yymsp[-2].minor.yy448, DB_OPTION_TABLE_PREFIX, yymsp[0].minor.yy448); }
   yymsp[-2].minor.yy448 = yylhsminor.yy448;
         break;
-      case 110: /* db_options ::= db_options TABLE_SUFFIX NK_INTEGER */
-{ yylhsminor.yy448 = setDatabaseOption(pCxt, yymsp[-2].minor.yy448, DB_OPTION_TABLE_SUFFIX, &yymsp[0].minor.yy0); }
+      case 110: /* db_options ::= db_options TABLE_SUFFIX signed */
+{ yylhsminor.yy448 = setDatabaseOption(pCxt, yymsp[-2].minor.yy448, DB_OPTION_TABLE_SUFFIX, yymsp[0].minor.yy448); }
   yymsp[-2].minor.yy448 = yylhsminor.yy448;
         break;
       case 111: /* alter_db_options ::= alter_db_option */
@@ -5444,9 +6061,9 @@ static YYACTIONTYPE yy_reduce(
         break;
 /********** End reduce actions ************************************************/
   };
-  assert( yyrulenopFromTable, false, (SLogicNode**)&pScan);
+  int32_t          code = makeScanLogicNode(pCxt, (SRealTableNode*)pDelete->pFromTable, false, (SLogicNode**)&pScan);
 
   // set columns to scan
   if (TSDB_CODE_SUCCESS == code) {
diff --git a/source/libs/qcom/src/querymsg.c b/source/libs/qcom/src/querymsg.c
index b62a3e4932..01b136d5e0 100644
--- a/source/libs/qcom/src/querymsg.c
+++ b/source/libs/qcom/src/querymsg.c
@@ -407,7 +407,7 @@ int32_t queryCreateTableMetaFromMsg(STableMetaRsp *msg, bool isStb, STableMeta *
     pTableMeta->tableInfo.rowSize += pTableMeta->schema[i].bytes;
   }
 
-  qDebug("table %s uid %" PRIx64 " meta returned, type %d vgId:%d db %s stb %s suid %" PRIx64 " sver %d tver %d" PRIx64
+  qDebug("table %s uid %" PRIx64 " meta returned, type %d vgId:%d db %s stb %s suid %" PRIx64 " sver %d tver %d"
          " tagNum %d colNum %d precision %d rowSize %d",
          msg->tbName, pTableMeta->uid, pTableMeta->tableType, pTableMeta->vgId, msg->dbFName, msg->stbName,
          pTableMeta->suid, pTableMeta->sversion, pTableMeta->tversion, pTableMeta->tableInfo.numOfTags,
diff --git a/source/libs/scalar/src/scalar.c b/source/libs/scalar/src/scalar.c
index 0521076d23..d9295656e8 100644
--- a/source/libs/scalar/src/scalar.c
+++ b/source/libs/scalar/src/scalar.c
@@ -53,6 +53,7 @@ int32_t sclCreateColumnInfoData(SDataType *pType, int32_t numOfRows, SScalarPara
   int32_t code = colInfoDataEnsureCapacity(pColumnData, numOfRows, true);
   if (code != TSDB_CODE_SUCCESS) {
     terrno = TSDB_CODE_OUT_OF_MEMORY;
+    colDataDestroy(pColumnData);
     taosMemoryFree(pColumnData);
     return terrno;
   }
@@ -1061,17 +1062,20 @@ int32_t sclConvertOpValueNodeTs(SOperatorNode *node, SScalarCtx *ctx) {
 
   if (node->pLeft && SCL_IS_VAR_VALUE_NODE(node->pLeft)) {
     if (node->pRight && (TSDB_DATA_TYPE_TIMESTAMP == ((SExprNode *)node->pRight)->resType.type)) {
-      SCL_ERR_JRET(sclConvertToTsValueNode(sclGetOpValueNodeTsPrecision(node->pLeft, node->pRight), (SValueNode*)node->pLeft));
+      SCL_ERR_JRET(
+          sclConvertToTsValueNode(sclGetOpValueNodeTsPrecision(node->pLeft, node->pRight), (SValueNode *)node->pLeft));
     }
   } else if (node->pRight && SCL_IS_NOTNULL_CONST_NODE(node->pRight)) {
     if (node->pLeft && (TSDB_DATA_TYPE_TIMESTAMP == ((SExprNode *)node->pLeft)->resType.type)) {
       if (SCL_IS_VAR_VALUE_NODE(node->pRight)) {
-        SCL_ERR_JRET(sclConvertToTsValueNode(sclGetOpValueNodeTsPrecision(node->pLeft, node->pRight), (SValueNode*)node->pRight));
+        SCL_ERR_JRET(sclConvertToTsValueNode(sclGetOpValueNodeTsPrecision(node->pLeft, node->pRight),
+                                             (SValueNode *)node->pRight));
       } else if (QUERY_NODE_NODE_LIST == node->pRight->type) {
-        SNode* pNode;
-        FOREACH(pNode, ((SNodeListNode*)node->pRight)->pNodeList) {
+        SNode *pNode;
+        FOREACH(pNode, ((SNodeListNode *)node->pRight)->pNodeList) {
           if (SCL_IS_VAR_VALUE_NODE(pNode)) {
-            SCL_ERR_JRET(sclConvertToTsValueNode(sclGetOpValueNodeTsPrecision(node->pLeft, pNode), (SValueNode*)pNode));
+            SCL_ERR_JRET(
+                sclConvertToTsValueNode(sclGetOpValueNodeTsPrecision(node->pLeft, pNode), (SValueNode *)pNode));
           }
         }
       }
@@ -1086,8 +1090,6 @@ _return:
   return DEAL_RES_ERROR;
 }
 
-
-
 int32_t sclConvertCaseWhenValueNodeTs(SCaseWhenNode *node, SScalarCtx *ctx) {
   int32_t code = 0;
 
@@ -1096,19 +1098,20 @@ int32_t sclConvertCaseWhenValueNodeTs(SCaseWhenNode *node, SScalarCtx *ctx) {
   }
 
   if (SCL_IS_VAR_VALUE_NODE(node->pCase)) {
-    SNode* pNode;
+    SNode *pNode;
     FOREACH(pNode, node->pWhenThenList) {
       SExprNode *pExpr = (SExprNode *)((SWhenThenNode *)pNode)->pWhen;
       if (TSDB_DATA_TYPE_TIMESTAMP == pExpr->resType.type) {
-        SCL_ERR_JRET(sclConvertToTsValueNode(pExpr->resType.precision, (SValueNode*)node->pCase));
+        SCL_ERR_JRET(sclConvertToTsValueNode(pExpr->resType.precision, (SValueNode *)node->pCase));
         break;
       }
     }
   } else if (TSDB_DATA_TYPE_TIMESTAMP == ((SExprNode *)node->pCase)->resType.type) {
-    SNode* pNode;
+    SNode *pNode;
     FOREACH(pNode, node->pWhenThenList) {
       if (SCL_IS_VAR_VALUE_NODE(((SWhenThenNode *)pNode)->pWhen)) {
-        SCL_ERR_JRET(sclConvertToTsValueNode(((SExprNode *)node->pCase)->resType.precision, (SValueNode*)((SWhenThenNode *)pNode)->pWhen));
+        SCL_ERR_JRET(sclConvertToTsValueNode(((SExprNode *)node->pCase)->resType.precision,
+                                             (SValueNode *)((SWhenThenNode *)pNode)->pWhen));
       }
     }
   }
@@ -1271,7 +1274,6 @@ EDealRes sclRewriteLogic(SNode **pNode, SScalarCtx *ctx) {
   return DEAL_RES_CONTINUE;
 }
 
-
 EDealRes sclRewriteOperator(SNode **pNode, SScalarCtx *ctx) {
   SOperatorNode *node = (SOperatorNode *)*pNode;
 
diff --git a/source/libs/scalar/src/sclfunc.c b/source/libs/scalar/src/sclfunc.c
index 24b25cec80..df32707529 100644
--- a/source/libs/scalar/src/sclfunc.c
+++ b/source/libs/scalar/src/sclfunc.c
@@ -1662,73 +1662,6 @@ int32_t charLengthFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam
   return doLengthFunction(pInput, inputNum, pOutput, tcharlength);
 }
 
-#if 0
-static void reverseCopy(char* dest, const char* src, int16_t type, int32_t numOfRows) {
-  switch(type) {
-    case TSDB_DATA_TYPE_TINYINT:
-    case TSDB_DATA_TYPE_UTINYINT:{
-      int8_t* p = (int8_t*) dest;
-      int8_t* pSrc = (int8_t*) src;
-
-      for(int32_t i = 0; i < numOfRows; ++i) {
-        p[i] = pSrc[numOfRows - i - 1];
-      }
-      return;
-    }
-
-    case TSDB_DATA_TYPE_SMALLINT:
-    case TSDB_DATA_TYPE_USMALLINT:{
-      int16_t* p = (int16_t*) dest;
-      int16_t* pSrc = (int16_t*) src;
-
-      for(int32_t i = 0; i < numOfRows; ++i) {
-        p[i] = pSrc[numOfRows - i - 1];
-      }
-      return;
-    }
-    case TSDB_DATA_TYPE_INT:
-    case TSDB_DATA_TYPE_UINT: {
-      int32_t* p = (int32_t*) dest;
-      int32_t* pSrc = (int32_t*) src;
-
-      for(int32_t i = 0; i < numOfRows; ++i) {
-        p[i] = pSrc[numOfRows - i - 1];
-      }
-      return;
-    }
-    case TSDB_DATA_TYPE_BIGINT:
-    case TSDB_DATA_TYPE_UBIGINT: {
-      int64_t* p = (int64_t*) dest;
-      int64_t* pSrc = (int64_t*) src;
-
-      for(int32_t i = 0; i < numOfRows; ++i) {
-        p[i] = pSrc[numOfRows - i - 1];
-      }
-      return;
-    }
-    case TSDB_DATA_TYPE_FLOAT: {
-      float* p = (float*) dest;
-      float* pSrc = (float*) src;
-
-      for(int32_t i = 0; i < numOfRows; ++i) {
-        p[i] = pSrc[numOfRows - i - 1];
-      }
-      return;
-    }
-    case TSDB_DATA_TYPE_DOUBLE: {
-      double* p = (double*) dest;
-      double* pSrc = (double*) src;
-
-      for(int32_t i = 0; i < numOfRows; ++i) {
-        p[i] = pSrc[numOfRows - i - 1];
-      }
-      return;
-    }
-    default: assert(0);
-  }
-}
-#endif
-
 bool getTimePseudoFuncEnv(SFunctionNode *UNUSED_PARAM(pFunc), SFuncExecEnv *pEnv) {
   pEnv->calcMemSize = sizeof(int64_t);
   return true;
diff --git a/source/libs/scalar/test/CMakeLists.txt b/source/libs/scalar/test/CMakeLists.txt
index 32f5e098c5..caaf86264c 100644
--- a/source/libs/scalar/test/CMakeLists.txt
+++ b/source/libs/scalar/test/CMakeLists.txt
@@ -1,4 +1,4 @@
 enable_testing()
 
-#add_subdirectory(filter)
+add_subdirectory(filter)
 add_subdirectory(scalar)
diff --git a/source/libs/scalar/test/filter/filterTests.cpp b/source/libs/scalar/test/filter/filterTests.cpp
index b59e89fe0d..51ee9b6570 100644
--- a/source/libs/scalar/test/filter/filterTests.cpp
+++ b/source/libs/scalar/test/filter/filterTests.cpp
@@ -33,6 +33,7 @@
 #include "os.h"
 
 #include "filter.h"
+#include "filterInt.h"
 #include "nodes.h"
 #include "scalar.h"
 #include "stub.h"
@@ -344,6 +345,7 @@ TEST(timerangeTest, greater_and_lower_not_strict) {
   nodesDestroyNode(logicNode1);
 }
 
+#if 0
 TEST(columnTest, smallint_column_greater_double_value) {
   SNode       *pLeft = NULL, *pRight = NULL, *opNode = NULL;
   int16_t      leftv[5] = {1, 2, 3, 4, 5};
@@ -1337,6 +1339,127 @@ TEST(scalarModelogicTest, diff_columns_or_and_or) {
   nodesDestroyNode(logicNode1);
   blockDataDestroy(src);
 }
+#endif
+
+template 
+int32_t compareSignedWithUnsigned(SignedT l, UnsignedT r) {
+  if (l < 0) return -1;
+  auto l_uint64 = static_cast(l);
+  auto r_uint64 = static_cast(r);
+  if (l_uint64 < r_uint64) return -1;
+  if (l_uint64 > r_uint64) return 1;
+  return 0;
+}
+
+template 
+int32_t compareUnsignedWithSigned(UnsignedT l, SignedT r) {
+  if (r < 0) return 1;
+  auto l_uint64 = static_cast(l);
+  auto r_uint64 = static_cast(r);
+  if (l_uint64 < r_uint64) return -1;
+  if (l_uint64 > r_uint64) return 1;
+  return 0;
+}
+
+template 
+void doCompareWithValueRange_SignedWithUnsigned(__compar_fn_t fp) {
+  int32_t signedMin = -10, signedMax = 10;
+  int32_t unsignedMin = 0, unsignedMax = 10;
+  for (SignedT l = signedMin; l <= signedMax; ++l) {
+    for (UnsignedT r = unsignedMin; r <= unsignedMax; ++r) {
+      ASSERT_EQ(fp(&l, &r), compareSignedWithUnsigned(l, r));
+    }
+  }
+}
+
+template 
+void doCompareWithValueRange_UnsignedWithSigned(__compar_fn_t fp) {
+  int32_t signedMin = -10, signedMax = 10;
+  int32_t unsignedMin = 0, unsignedMax = 10;
+  for (UnsignedT l = unsignedMin; l <= unsignedMax; ++l) {
+    for (SignedT r = signedMin; r <= signedMax; ++r) {
+      ASSERT_EQ(fp(&l, &r), compareUnsignedWithSigned(l, r));
+    }
+  }
+}
+
+template 
+void doCompareWithValueRange_OnlyLeftType(__compar_fn_t fp, int32_t rType) {
+  switch (rType) {
+    case TSDB_DATA_TYPE_UTINYINT:
+      doCompareWithValueRange_SignedWithUnsigned(fp);
+      break;
+    case TSDB_DATA_TYPE_USMALLINT:
+      doCompareWithValueRange_SignedWithUnsigned(fp);
+      break;
+    case TSDB_DATA_TYPE_UINT:
+      doCompareWithValueRange_SignedWithUnsigned(fp);
+      break;
+    case TSDB_DATA_TYPE_UBIGINT:
+      doCompareWithValueRange_SignedWithUnsigned(fp);
+      break;
+    case TSDB_DATA_TYPE_TINYINT:
+      doCompareWithValueRange_UnsignedWithSigned(fp);
+      break;
+    case TSDB_DATA_TYPE_SMALLINT:
+      doCompareWithValueRange_UnsignedWithSigned(fp);
+      break;
+    case TSDB_DATA_TYPE_INT:
+      doCompareWithValueRange_UnsignedWithSigned(fp);
+      break;
+    case TSDB_DATA_TYPE_BIGINT:
+      doCompareWithValueRange_UnsignedWithSigned(fp);
+      break;
+    default:
+      FAIL();
+  }
+}
+
+void doCompare(const std::vector &lTypes, const std::vector &rTypes, int32_t oper) {
+  for (int i = 0; i < lTypes.size(); ++i) {
+    for (int j = 0; j < rTypes.size(); ++j) {
+      auto fp = filterGetCompFuncEx(lTypes[i], rTypes[j], oper);
+      switch (lTypes[i]) {
+        case TSDB_DATA_TYPE_TINYINT:
+          doCompareWithValueRange_OnlyLeftType(fp, rTypes[j]);
+          break;
+        case TSDB_DATA_TYPE_SMALLINT:
+          doCompareWithValueRange_OnlyLeftType(fp, rTypes[j]);
+          break;
+        case TSDB_DATA_TYPE_INT:
+          doCompareWithValueRange_OnlyLeftType(fp, rTypes[j]);
+          break;
+        case TSDB_DATA_TYPE_BIGINT:
+          doCompareWithValueRange_OnlyLeftType(fp, rTypes[j]);
+          break;
+        case TSDB_DATA_TYPE_UTINYINT:
+          doCompareWithValueRange_OnlyLeftType(fp, rTypes[j]);
+          break;
+        case TSDB_DATA_TYPE_USMALLINT:
+          doCompareWithValueRange_OnlyLeftType(fp, rTypes[j]);
+          break;
+        case TSDB_DATA_TYPE_UINT:
+          doCompareWithValueRange_OnlyLeftType(fp, rTypes[j]);
+          break;
+        case TSDB_DATA_TYPE_UBIGINT:
+          doCompareWithValueRange_OnlyLeftType(fp, rTypes[j]);
+          break;
+        default:
+          FAIL();
+      }
+    }
+  }
+}
+
+TEST(dataCompareTest, signed_and_unsigned_int) {
+  std::vector lType = {TSDB_DATA_TYPE_TINYINT, TSDB_DATA_TYPE_SMALLINT, TSDB_DATA_TYPE_INT,
+                                TSDB_DATA_TYPE_BIGINT};
+  std::vector rType = {TSDB_DATA_TYPE_UTINYINT, TSDB_DATA_TYPE_USMALLINT, TSDB_DATA_TYPE_UINT,
+                                TSDB_DATA_TYPE_UBIGINT};
+
+  doCompare(lType, rType, OP_TYPE_GREATER_THAN);
+  doCompare(rType, lType, OP_TYPE_GREATER_THAN);
+}
 
 int main(int argc, char **argv) {
   taosSeedRand(taosGetTimestampSec());
diff --git a/source/libs/stream/inc/streamInc.h b/source/libs/stream/inc/streamInc.h
index 876b80697a..b17afeec98 100644
--- a/source/libs/stream/inc/streamInc.h
+++ b/source/libs/stream/inc/streamInc.h
@@ -39,7 +39,7 @@ int32_t streamBroadcastToChildren(SStreamTask* pTask, const SSDataBlock* pBlock)
 
 int32_t tEncodeStreamRetrieveReq(SEncoder* pEncoder, const SStreamRetrieveReq* pReq);
 
-int32_t streamDispatchOneCheckReq(SStreamTask* pTask, const SStreamTaskCheckReq* pReq, int32_t nodeId, SEpSet* pEpSet);
+int32_t streamDispatchCheckMsg(SStreamTask* pTask, const SStreamTaskCheckReq* pReq, int32_t nodeId, SEpSet* pEpSet);
 
 int32_t streamDispatchOneRecoverFinishReq(SStreamTask* pTask, const SStreamRecoverFinishReq* pReq, int32_t vgId,
                                           SEpSet* pEpSet);
diff --git a/source/libs/stream/src/stream.c b/source/libs/stream/src/stream.c
index 86ba91f76d..9ed297bd6b 100644
--- a/source/libs/stream/src/stream.c
+++ b/source/libs/stream/src/stream.c
@@ -52,7 +52,7 @@ void streamCleanUp() {
 void streamSchedByTimer(void* param, void* tmrId) {
   SStreamTask* pTask = (void*)param;
 
-  if (atomic_load_8(&pTask->status.taskStatus) == TASK_STATUS__DROPPING) {
+  if (streamTaskShouldStop(&pTask->status)) {
     streamMetaReleaseTask(NULL, pTask);
     return;
   }
@@ -212,9 +212,10 @@ int32_t streamTaskOutput(SStreamTask* pTask, SStreamDataBlock* pBlock) {
 }
 
 int32_t streamProcessDispatchReq(SStreamTask* pTask, SStreamDispatchReq* pReq, SRpcMsg* pRsp, bool exec) {
-  qDebug("vgId:%d s-task:%s receive dispatch req from taskId:%d", pReq->upstreamNodeId, pTask->id.idStr,
-         pReq->upstreamTaskId);
+  qDebug("s-task:%s receive dispatch req from taskId:%d(vgId:%d)", pTask->id.idStr, pReq->upstreamTaskId,
+         pReq->upstreamNodeId);
 
+  // todo add the input queue buffer limitation
   streamTaskEnqueueBlocks(pTask, pReq, pRsp);
   tDeleteStreamDispatchReq(pReq);
 
@@ -222,10 +223,6 @@ int32_t streamProcessDispatchReq(SStreamTask* pTask, SStreamDispatchReq* pReq, S
     if (streamTryExec(pTask) < 0) {
       return -1;
     }
-
-    /*if (pTask->outputType == TASK_OUTPUT__FIXED_DISPATCH || pTask->outputType == TASK_OUTPUT__SHUFFLE_DISPATCH) {*/
-    /*streamDispatch(pTask);*/
-    /*}*/
   } else {
     streamSchedExec(pTask);
   }
diff --git a/source/libs/stream/src/streamDispatch.c b/source/libs/stream/src/streamDispatch.c
index 549374ed94..d12eca7ce3 100644
--- a/source/libs/stream/src/streamDispatch.c
+++ b/source/libs/stream/src/streamDispatch.c
@@ -208,7 +208,7 @@ static int32_t streamAddBlockToDispatchMsg(const SSDataBlock* pBlock, SStreamDis
   return 0;
 }
 
-int32_t streamDispatchOneCheckReq(SStreamTask* pTask, const SStreamTaskCheckReq* pReq, int32_t nodeId, SEpSet* pEpSet) {
+int32_t streamDispatchCheckMsg(SStreamTask* pTask, const SStreamTaskCheckReq* pReq, int32_t nodeId, SEpSet* pEpSet) {
   void*   buf = NULL;
   int32_t code = -1;
   SRpcMsg msg = {0};
@@ -240,7 +240,7 @@ int32_t streamDispatchOneCheckReq(SStreamTask* pTask, const SStreamTaskCheckReq*
   msg.pCont = buf;
   msg.msgType = TDMT_STREAM_TASK_CHECK;
 
-  qDebug("dispatch from s-task:%s to downstream s-task:%" PRIx64 ":%d node %d: check msg", pTask->id.idStr,
+  qDebug("s-task:%s dispatch check msg to downstream s-task:%" PRIx64 ":%d node %d: check msg", pTask->id.idStr,
          pReq->streamId, pReq->downstreamTaskId, nodeId);
 
   tmsgSendReq(pEpSet, &msg);
diff --git a/source/libs/stream/src/streamExec.c b/source/libs/stream/src/streamExec.c
index 325d315262..e10562f5cb 100644
--- a/source/libs/stream/src/streamExec.c
+++ b/source/libs/stream/src/streamExec.c
@@ -28,7 +28,7 @@ static int32_t streamTaskExecImpl(SStreamTask* pTask, const void* data, SArray*
 
   while (pTask->taskLevel == TASK_LEVEL__SOURCE) {
     int8_t status = atomic_load_8(&pTask->status.taskStatus);
-    if (status != TASK_STATUS__NORMAL && status != TASK_STATUS__RESTORE) {
+    if (status != TASK_STATUS__NORMAL) {
       qError("stream task wait for the end of fill history, s-task:%s, status:%d", pTask->id.idStr,
              atomic_load_8(&pTask->status.taskStatus));
       taosMsleep(2);
@@ -165,20 +165,24 @@ int32_t streamScanExec(SStreamTask* pTask, int32_t batchSz) {
 
       batchCnt++;
 
-      qDebug("task %d scan exec block num %d, block limit %d", pTask->id.taskId, batchCnt, batchSz);
+      qDebug("s-task:%s scan exec block num %d, block limit %d", pTask->id.idStr, batchCnt, batchSz);
 
-      if (batchCnt >= batchSz) break;
+      if (batchCnt >= batchSz) {
+        break;
+      }
     }
+
     if (taosArrayGetSize(pRes) == 0) {
       if (finished) {
         taosArrayDestroy(pRes);
-        qDebug("task %d finish recover exec task ", pTask->id.taskId);
+        qDebug("s-task:%s finish recover exec task ", pTask->id.idStr);
         break;
       } else {
-        qDebug("task %d continue recover exec task ", pTask->id.taskId);
+        qDebug("s-task:%s continue recover exec task ", pTask->id.idStr);
         continue;
       }
     }
+
     SStreamDataBlock* qRes = taosAllocateQitem(sizeof(SStreamDataBlock), DEF_QITEM, 0);
     if (qRes == NULL) {
       taosArrayDestroyEx(pRes, (FDelete)blockDataFreeRes);
@@ -246,10 +250,11 @@ int32_t streamExecForAll(SStreamTask* pTask) {
     void*   pInput = NULL;
 
     // merge multiple input data if possible in the input queue.
+    qDebug("s-task:%s start to extract data block from inputQ", pTask->id.idStr);
+
     while (1) {
       SStreamQueueItem* qItem = streamQueueNextItem(pTask->inputQueue);
       if (qItem == NULL) {
-//        qDebug("s-task:%s extract data from input queue, queue is empty, abort", pTask->id.idStr);
         break;
       }
 
@@ -294,7 +299,7 @@ int32_t streamExecForAll(SStreamTask* pTask) {
     }
 
     SArray* pRes = taosArrayInit(0, sizeof(SSDataBlock));
-    qDebug("s-task:%s exec begin, numOfBlocks:%d", pTask->id.idStr, batchSize);
+    qDebug("s-task:%s start to execute, numOfBlocks:%d", pTask->id.idStr, batchSize);
 
     streamTaskExecImpl(pTask, pInput, pRes);
 
@@ -309,6 +314,7 @@ int32_t streamExecForAll(SStreamTask* pTask) {
       pTask->chkInfo = (SCheckpointInfo) {.version = dataVer, .id = ckId, .currentVer = pTask->chkInfo.currentVer};
 
       taosWLockLatch(&pTask->pMeta->lock);
+
       streamMetaSaveTask(pTask->pMeta, pTask);
       if (streamMetaCommit(pTask->pMeta) < 0) {
         taosWUnLockLatch(&pTask->pMeta->lock);
diff --git a/source/libs/stream/src/streamMeta.c b/source/libs/stream/src/streamMeta.c
index 065e9d280f..af54904c43 100644
--- a/source/libs/stream/src/streamMeta.c
+++ b/source/libs/stream/src/streamMeta.c
@@ -57,6 +57,13 @@ SStreamMeta* streamMetaOpen(const char* path, void* ahandle, FTaskExpand expandF
     goto _err;
   }
 
+  // task list
+  pMeta->pTaskList = taosArrayInit(4, sizeof(int32_t));
+  if (pMeta->pTaskList == NULL) {
+    terrno = TSDB_CODE_OUT_OF_MEMORY;
+    goto _err;
+  }
+
   if (streamMetaBegin(pMeta) < 0) {
     goto _err;
   }
@@ -70,6 +77,7 @@ SStreamMeta* streamMetaOpen(const char* path, void* ahandle, FTaskExpand expandF
 _err:
   taosMemoryFree(pMeta->path);
   if (pMeta->pTasks) taosHashCleanup(pMeta->pTasks);
+  if (pMeta->pTaskList) taosArrayDestroy(pMeta->pTaskList);
   if (pMeta->pTaskDb) tdbTbClose(pMeta->pTaskDb);
   if (pMeta->pCheckpointDb) tdbTbClose(pMeta->pCheckpointDb);
   if (pMeta->db) tdbClose(pMeta->db);
@@ -100,6 +108,7 @@ void streamMetaClose(SStreamMeta* pMeta) {
   }
 
   taosHashCleanup(pMeta->pTasks);
+  pMeta->pTaskList = taosArrayDestroy(pMeta->pTaskList);
   taosMemoryFree(pMeta->path);
   taosMemoryFree(pMeta);
 }
@@ -179,12 +188,21 @@ int32_t streamMetaAddDeployedTask(SStreamMeta* pMeta, int64_t ver, SStreamTask*
     return -1;
   }
 
+  if (streamMetaCommit(pMeta) < 0) {
+    tFreeStreamTask(pTask);
+    return -1;
+  }
+
   taosHashPut(pMeta->pTasks, &pTask->id.taskId, sizeof(int32_t), &pTask, POINTER_BYTES);
+  taosArrayPush(pMeta->pTaskList, &pTask->id.taskId);
   return 0;
 }
 
 int32_t streamMetaGetNumOfTasks(const SStreamMeta* pMeta) {
-  return (int32_t) taosHashGetSize(pMeta->pTasks);
+  size_t size = taosHashGetSize(pMeta->pTasks);
+  ASSERT(taosArrayGetSize(pMeta->pTaskList) == taosHashGetSize(pMeta->pTasks));
+
+  return (int32_t) size;
 }
 
 SStreamTask* streamMetaAcquireTask(SStreamMeta* pMeta, int32_t taskId) {
@@ -216,12 +234,23 @@ void streamMetaRemoveTask(SStreamMeta* pMeta, int32_t taskId) {
   SStreamTask** ppTask = (SStreamTask**)taosHashGet(pMeta->pTasks, &taskId, sizeof(int32_t));
   if (ppTask) {
     SStreamTask* pTask = *ppTask;
+
+    taosWLockLatch(&pMeta->lock);
+
     taosHashRemove(pMeta->pTasks, &taskId, sizeof(int32_t));
     tdbTbDelete(pMeta->pTaskDb, &taskId, sizeof(int32_t), pMeta->txn);
 
     atomic_store_8(&pTask->status.taskStatus, TASK_STATUS__STOP);
 
-    taosWLockLatch(&pMeta->lock);
+    int32_t num = taosArrayGetSize(pMeta->pTaskList);
+    for(int32_t i = 0; i < num; ++i) {
+      int32_t* pTaskId = taosArrayGet(pMeta->pTaskList, i);
+      if (*pTaskId == taskId) {
+        taosArrayRemove(pMeta->pTaskList, i);
+        break;
+      }
+    }
+
     streamMetaReleaseTask(pMeta, pTask);
     taosWUnLockLatch(&pMeta->lock);
   }
@@ -287,6 +316,7 @@ int32_t streamLoadTasks(SStreamMeta* pMeta, int64_t ver) {
       tdbTbcClose(pCur);
       return -1;
     }
+
     tDecoderInit(&decoder, (uint8_t*)pVal, vLen);
     tDecodeStreamTask(&decoder, pTask);
     tDecoderClear(&decoder);
@@ -305,7 +335,8 @@ int32_t streamLoadTasks(SStreamMeta* pMeta, int64_t ver) {
       return -1;
     }
 
-    /*pTask->status.taskStatus = TASK_STATUS__NORMAL;*/
+    taosArrayPush(pMeta->pTaskList, &pTask->id.taskId);
+
     if (pTask->fillHistory) {
       pTask->status.taskStatus = TASK_STATUS__WAIT_DOWNSTREAM;
       streamTaskCheckDownstream(pTask, ver);
diff --git a/source/libs/stream/src/streamRecover.c b/source/libs/stream/src/streamRecover.c
index 55c745e417..0324580885 100644
--- a/source/libs/stream/src/streamRecover.c
+++ b/source/libs/stream/src/streamRecover.c
@@ -20,6 +20,8 @@ int32_t streamTaskLaunchRecover(SStreamTask* pTask, int64_t version) {
 
   if (pTask->taskLevel == TASK_LEVEL__SOURCE) {
     atomic_store_8(&pTask->status.taskStatus, TASK_STATUS__RECOVER_PREPARE);
+    qDebug("s-task:%s set task status:%d and start recover", pTask->id.idStr, pTask->status.taskStatus);
+
     streamSetParamForRecover(pTask);
     streamSourceRecoverPrepareStep1(pTask, version);
 
@@ -52,6 +54,8 @@ int32_t streamTaskLaunchRecover(SStreamTask* pTask, int64_t version) {
 
 // checkstatus
 int32_t streamTaskCheckDownstream(SStreamTask* pTask, int64_t version) {
+  qDebug("s-taks:%s in fill history stage, ver:%"PRId64, pTask->id.idStr, version);
+
   SStreamTaskCheckReq req = {
       .streamId = pTask->id.streamId,
       .upstreamTaskId = pTask->id.taskId,
@@ -61,16 +65,18 @@ int32_t streamTaskCheckDownstream(SStreamTask* pTask, int64_t version) {
 
   // serialize
   if (pTask->outputType == TASK_OUTPUT__FIXED_DISPATCH) {
+
     req.reqId = tGenIdPI64();
     req.downstreamNodeId = pTask->fixedEpDispatcher.nodeId;
     req.downstreamTaskId = pTask->fixedEpDispatcher.taskId;
     pTask->checkReqId = req.reqId;
 
-    qDebug("task %d at node %d check downstream task %d at node %d", pTask->id.taskId, pTask->nodeId, req.downstreamTaskId,
+    qDebug("s-task:%s at node %d check downstream task %d at node %d", pTask->id.idStr, pTask->nodeId, req.downstreamTaskId,
            req.downstreamNodeId);
-    streamDispatchOneCheckReq(pTask, &req, pTask->fixedEpDispatcher.nodeId, &pTask->fixedEpDispatcher.epSet);
+    streamDispatchCheckMsg(pTask, &req, pTask->fixedEpDispatcher.nodeId, &pTask->fixedEpDispatcher.epSet);
   } else if (pTask->outputType == TASK_OUTPUT__SHUFFLE_DISPATCH) {
     SArray* vgInfo = pTask->shuffleDispatcher.dbInfo.pVgroupInfos;
+
     int32_t vgSz = taosArrayGetSize(vgInfo);
     pTask->recoverTryingDownstream = vgSz;
     pTask->checkReqIds = taosArrayInit(vgSz, sizeof(int64_t));
@@ -81,14 +87,15 @@ int32_t streamTaskCheckDownstream(SStreamTask* pTask, int64_t version) {
       taosArrayPush(pTask->checkReqIds, &req.reqId);
       req.downstreamNodeId = pVgInfo->vgId;
       req.downstreamTaskId = pVgInfo->taskId;
-      qDebug("task %d at node %d check downstream task %d at node %d (shuffle)", pTask->id.taskId, pTask->nodeId,
+      qDebug("s-task:%s at node %d check downstream task %d at node %d (shuffle)", pTask->id.idStr, pTask->nodeId,
              req.downstreamTaskId, req.downstreamNodeId);
-      streamDispatchOneCheckReq(pTask, &req, pVgInfo->vgId, &pVgInfo->epSet);
+      streamDispatchCheckMsg(pTask, &req, pVgInfo->vgId, &pVgInfo->epSet);
     }
   } else {
-    qDebug("task %d at node %d direct launch recover since no downstream", pTask->id.taskId, pTask->nodeId);
+    qDebug("s-task:%s at node %d direct launch recover since no downstream", pTask->id.idStr, pTask->nodeId);
     streamTaskLaunchRecover(pTask, version);
   }
+
   return 0;
 }
 
@@ -107,14 +114,14 @@ int32_t streamRecheckOneDownstream(SStreamTask* pTask, const SStreamTaskCheckRsp
          req.downstreamTaskId, req.downstreamNodeId);
 
   if (pTask->outputType == TASK_OUTPUT__FIXED_DISPATCH) {
-    streamDispatchOneCheckReq(pTask, &req, pRsp->downstreamNodeId, &pTask->fixedEpDispatcher.epSet);
+    streamDispatchCheckMsg(pTask, &req, pRsp->downstreamNodeId, &pTask->fixedEpDispatcher.epSet);
   } else if (pTask->outputType == TASK_OUTPUT__SHUFFLE_DISPATCH) {
     SArray* vgInfo = pTask->shuffleDispatcher.dbInfo.pVgroupInfos;
     int32_t vgSz = taosArrayGetSize(vgInfo);
     for (int32_t i = 0; i < vgSz; i++) {
       SVgroupInfo* pVgInfo = taosArrayGet(vgInfo, i);
       if (pVgInfo->taskId == req.downstreamTaskId) {
-        streamDispatchOneCheckReq(pTask, &req, pRsp->downstreamNodeId, &pVgInfo->epSet);
+        streamDispatchCheckMsg(pTask, &req, pRsp->downstreamNodeId, &pVgInfo->epSet);
       }
     }
   }
@@ -122,8 +129,8 @@ int32_t streamRecheckOneDownstream(SStreamTask* pTask, const SStreamTaskCheckRsp
   return 0;
 }
 
-int32_t streamProcessTaskCheckReq(SStreamTask* pTask, const SStreamTaskCheckReq* pReq) {
-  return atomic_load_8(&pTask->status.taskStatus) == TASK_STATUS__NORMAL;
+int32_t streamTaskCheckStatus(SStreamTask* pTask) {
+  return atomic_load_8(&pTask->status.taskStatus) == TASK_STATUS__NORMAL? 1:0;
 }
 
 int32_t streamProcessTaskCheckRsp(SStreamTask* pTask, const SStreamTaskCheckRsp* pRsp, int64_t version) {
@@ -133,7 +140,9 @@ int32_t streamProcessTaskCheckRsp(SStreamTask* pTask, const SStreamTaskCheckRsp*
   if (pRsp->status == 1) {
     if (pTask->outputType == TASK_OUTPUT__SHUFFLE_DISPATCH) {
       bool found = false;
-      for (int32_t i = 0; i < taosArrayGetSize(pTask->checkReqIds); i++) {
+
+      int32_t numOfReqs = taosArrayGetSize(pTask->checkReqIds);
+      for (int32_t i = 0; i < numOfReqs; i++) {
         int64_t reqId = *(int64_t*)taosArrayGet(pTask->checkReqIds, i);
         if (reqId == pRsp->reqId) {
           found = true;
@@ -147,9 +156,12 @@ int32_t streamProcessTaskCheckRsp(SStreamTask* pTask, const SStreamTaskCheckRsp*
 
       int32_t left = atomic_sub_fetch_32(&pTask->recoverTryingDownstream, 1);
       ASSERT(left >= 0);
+
       if (left == 0) {
         taosArrayDestroy(pTask->checkReqIds);
         pTask->checkReqIds = NULL;
+
+        qDebug("s-task:%s all downstream tasks:%d are ready, now enter into recover stage", pTask->id.idStr, numOfReqs);
         streamTaskLaunchRecover(pTask, version);
       }
     } else if (pTask->outputType == TASK_OUTPUT__FIXED_DISPATCH) {
@@ -161,7 +173,10 @@ int32_t streamProcessTaskCheckRsp(SStreamTask* pTask, const SStreamTaskCheckRsp*
     } else {
       ASSERT(0);
     }
-  } else { // not ready, it should wait for at least 100ms and then retry
+  } else { // not ready, wait for 100ms and retry
+    qDebug("s-task:%s downstream taskId:%d (vgId:%d) not ready, wait for 100ms and retry", pTask->id.idStr,
+        pRsp->downstreamTaskId, pRsp->downstreamNodeId);
+    taosMsleep(100);
     streamRecheckOneDownstream(pTask, pRsp);
   }
 
@@ -197,7 +212,6 @@ int32_t streamBuildSourceRecover1Req(SStreamTask* pTask, SStreamRecoverStep1Req*
 }
 
 int32_t streamSourceRecoverScanStep1(SStreamTask* pTask) {
-  //
   return streamScanExec(pTask, 100);
 }
 
@@ -210,8 +224,11 @@ int32_t streamBuildSourceRecover2Req(SStreamTask* pTask, SStreamRecoverStep2Req*
 
 int32_t streamSourceRecoverScanStep2(SStreamTask* pTask, int64_t ver) {
   void* exec = pTask->exec.pExecutor;
+
+  qDebug("s-task:%s recover step2(blocking stage) started", pTask->id.idStr);
   if (qStreamSourceRecoverStep2(exec, ver) < 0) {
   }
+
   return streamScanExec(pTask, 100);
 }
 
diff --git a/source/libs/stream/src/streamTask.c b/source/libs/stream/src/streamTask.c
index 67c60008fd..f301d9d517 100644
--- a/source/libs/stream/src/streamTask.c
+++ b/source/libs/stream/src/streamTask.c
@@ -193,7 +193,7 @@ void tFreeStreamTask(SStreamTask* pTask) {
 
   taosArrayDestroyP(pTask->childEpInfo, taosMemoryFree);
   if (pTask->outputType == TASK_OUTPUT__TABLE) {
-    tDeleteSSchemaWrapper(pTask->tbSink.pSchemaWrapper);
+    tDeleteSchemaWrapper(pTask->tbSink.pSchemaWrapper);
     taosMemoryFree(pTask->tbSink.pTSchema);
   }
 
diff --git a/source/libs/sync/src/syncRespMgr.c b/source/libs/sync/src/syncRespMgr.c
index f9f14c2e00..3506d477d3 100644
--- a/source/libs/sync/src/syncRespMgr.c
+++ b/source/libs/sync/src/syncRespMgr.c
@@ -171,6 +171,8 @@ static void syncRespCleanByTTL(SSyncRespMgr *pObj, int64_t ttl, bool rsp) {
 }
 
 void syncRespCleanRsp(SSyncRespMgr *pObj) {
+  if (pObj == NULL) return;
+
   SSyncNode *pNode = pObj->data;
   sTrace("vgId:%d, clean all resp", pNode->vgId);
 
diff --git a/source/libs/tdb/src/db/tdbBtree.c b/source/libs/tdb/src/db/tdbBtree.c
index 6df2b40000..c49b5726b6 100644
--- a/source/libs/tdb/src/db/tdbBtree.c
+++ b/source/libs/tdb/src/db/tdbBtree.c
@@ -1814,6 +1814,11 @@ int tdbBtreeNext(SBTC *pBtc, void **ppKey, int *kLen, void **ppVal, int *vLen) {
 
     *ppVal = pVal;
     *vLen = cd.vLen;
+  } else {
+    if (TDB_CELLDECODER_FREE_VAL(&cd)) {
+      tdbTrace("tdb/btree-next2 decoder: %p pVal free: %p", &cd, cd.pVal);
+      tdbFree(cd.pVal);
+    }
   }
 
   ret = tdbBtcMoveToNext(pBtc);
diff --git a/source/libs/transport/src/transCli.c b/source/libs/transport/src/transCli.c
index 73d611a8a7..7fcc5921ae 100644
--- a/source/libs/transport/src/transCli.c
+++ b/source/libs/transport/src/transCli.c
@@ -587,12 +587,12 @@ void* destroyConnPool(SCliThrd* pThrd) {
 
 static SCliConn* getConnFromPool(SCliThrd* pThrd, char* key, bool* exceed) {
   void*      pool = pThrd->pool;
-  SConnList* plist = taosHashGet((SHashObj*)pool, key, strlen(key));
+  SConnList* plist = taosHashGet((SHashObj*)pool, key, strlen(key) + 1);
   STrans*    pTranInst = pThrd->pTransInst;
   if (plist == NULL) {
     SConnList list = {0};
-    taosHashPut((SHashObj*)pool, key, strlen(key), (void*)&list, sizeof(list));
-    plist = taosHashGet(pool, key, strlen(key));
+    taosHashPut((SHashObj*)pool, key, strlen(key) + 1, (void*)&list, sizeof(list));
+    plist = taosHashGet(pool, key, strlen(key) + 1);
 
     SMsgList* nList = taosMemoryCalloc(1, sizeof(SMsgList));
     QUEUE_INIT(&nList->msgQ);
@@ -627,11 +627,11 @@ static SCliConn* getConnFromPool(SCliThrd* pThrd, char* key, bool* exceed) {
 static SCliConn* getConnFromPool2(SCliThrd* pThrd, char* key, SCliMsg** pMsg) {
   void*      pool = pThrd->pool;
   STrans*    pTransInst = pThrd->pTransInst;
-  SConnList* plist = taosHashGet((SHashObj*)pool, key, strlen(key));
+  SConnList* plist = taosHashGet((SHashObj*)pool, key, strlen(key) + 1);
   if (plist == NULL) {
     SConnList list = {0};
-    taosHashPut((SHashObj*)pool, key, strlen(key), (void*)&list, sizeof(list));
-    plist = taosHashGet(pool, key, strlen(key));
+    taosHashPut((SHashObj*)pool, key, strlen(key) + 1, (void*)&list, sizeof(list));
+    plist = taosHashGet(pool, key, strlen(key) + 1);
 
     SMsgList* nList = taosMemoryCalloc(1, sizeof(SMsgList));
     QUEUE_INIT(&nList->msgQ);
@@ -717,7 +717,7 @@ static void addConnToPool(void* pool, SCliConn* conn) {
   cliDestroyConnMsgs(conn, false);
 
   if (conn->list == NULL) {
-    conn->list = taosHashGet((SHashObj*)pool, conn->ip, strlen(conn->ip));
+    conn->list = taosHashGet((SHashObj*)pool, conn->ip, strlen(conn->ip) + 1);
   }
 
   SConnList* pList = conn->list;
@@ -822,7 +822,8 @@ static void cliRecvCb(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf) {
     return;
   }
   if (nread < 0) {
-    tWarn("%s conn %p read error:%s, ref:%d", CONN_GET_INST_LABEL(conn), conn, uv_err_name(nread), T_REF_VAL_GET(conn));
+    tDebug("%s conn %p read error:%s, ref:%d", CONN_GET_INST_LABEL(conn), conn, uv_err_name(nread),
+           T_REF_VAL_GET(conn));
     conn->broken = true;
     cliHandleExcept(conn);
   }
@@ -875,8 +876,8 @@ static void cliDestroyConn(SCliConn* conn, bool clear) {
     connList->list->numOfConn--;
     connList->size--;
   } else {
-    SConnList* connList = taosHashGet((SHashObj*)pThrd->pool, conn->ip, strlen(conn->ip));
-    connList->list->numOfConn--;
+    SConnList* connList = taosHashGet((SHashObj*)pThrd->pool, conn->ip, strlen(conn->ip) + 1);
+    if (connList != NULL) connList->list->numOfConn--;
   }
   conn->list = NULL;
   pThrd->newConnCount--;
@@ -1269,7 +1270,7 @@ static void cliHandleFastFail(SCliConn* pConn, int status) {
 
     if (pMsg != NULL && REQUEST_NO_RESP(&pMsg->msg) &&
         (pTransInst->failFastFp != NULL && pTransInst->failFastFp(pMsg->msg.msgType))) {
-      SFailFastItem* item = taosHashGet(pThrd->failFastCache, pConn->ip, strlen(pConn->ip));
+      SFailFastItem* item = taosHashGet(pThrd->failFastCache, pConn->ip, strlen(pConn->ip) + 1);
       int64_t        cTimestamp = taosGetTimestampMs();
       if (item != NULL) {
         int32_t elapse = cTimestamp - item->timestamp;
@@ -1281,7 +1282,7 @@ static void cliHandleFastFail(SCliConn* pConn, int status) {
         }
       } else {
         SFailFastItem item = {.count = 1, .timestamp = cTimestamp};
-        taosHashPut(pThrd->failFastCache, pConn->ip, strlen(pConn->ip), &item, sizeof(SFailFastItem));
+        taosHashPut(pThrd->failFastCache, pConn->ip, strlen(pConn->ip) + 1, &item, sizeof(SFailFastItem));
       }
     }
   } else {
@@ -1459,7 +1460,7 @@ FORCE_INLINE int32_t cliBuildExceptResp(SCliMsg* pMsg, STransMsg* pResp) {
 }
 static FORCE_INLINE uint32_t cliGetIpFromFqdnCache(SHashObj* cache, char* fqdn) {
   uint32_t  addr = 0;
-  uint32_t* v = taosHashGet(cache, fqdn, strlen(fqdn));
+  uint32_t* v = taosHashGet(cache, fqdn, strlen(fqdn) + 1);
   if (v == NULL) {
     addr = taosGetIpv4FromFqdn(fqdn);
     if (addr == 0xffffffff) {
@@ -1468,7 +1469,7 @@ static FORCE_INLINE uint32_t cliGetIpFromFqdnCache(SHashObj* cache, char* fqdn)
       return addr;
     }
 
-    taosHashPut(cache, fqdn, strlen(fqdn), &addr, sizeof(addr));
+    taosHashPut(cache, fqdn, strlen(fqdn) + 1, &addr, sizeof(addr));
   } else {
     addr = *v;
   }
diff --git a/source/libs/transport/src/transSvr.c b/source/libs/transport/src/transSvr.c
index 34787fa96d..f5d2f66c9d 100644
--- a/source/libs/transport/src/transSvr.c
+++ b/source/libs/transport/src/transSvr.c
@@ -314,7 +314,7 @@ void uvOnRecvCb(uv_stream_t* cli, ssize_t nread, const uv_buf_t* buf) {
     return;
   }
 
-  tWarn("%s conn %p read error:%s", transLabel(pTransInst), conn, uv_err_name(nread));
+  tDebug("%s conn %p read error:%s", transLabel(pTransInst), conn, uv_err_name(nread));
   if (nread < 0) {
     conn->broken = true;
     if (conn->status == ConnAcquire) {
diff --git a/source/libs/wal/src/walMeta.c b/source/libs/wal/src/walMeta.c
index cda7e35b0f..a12f8051ba 100644
--- a/source/libs/wal/src/walMeta.c
+++ b/source/libs/wal/src/walMeta.c
@@ -295,6 +295,36 @@ void walAlignVersions(SWal* pWal) {
   wInfo("vgId:%d, reset commitVer to %" PRId64, pWal->cfg.vgId, pWal->vers.commitVer);
 }
 
+int walRepairLogFileTs(SWal* pWal, bool* updateMeta) {
+  int32_t sz = taosArrayGetSize(pWal->fileInfoSet);
+  int32_t fileIdx = -1;
+  int32_t lastCloseTs = 0;
+  char    fnameStr[WAL_FILE_LEN] = {0};
+
+  while (++fileIdx < sz - 1) {
+    SWalFileInfo* pFileInfo = taosArrayGet(pWal->fileInfoSet, fileIdx);
+    if (pFileInfo->closeTs != -1) {
+      lastCloseTs = pFileInfo->closeTs;
+      continue;
+    }
+
+    walBuildLogName(pWal, pFileInfo->firstVer, fnameStr);
+    int32_t mtime = 0;
+    if (taosStatFile(fnameStr, NULL, &mtime) < 0) {
+      terrno = TAOS_SYSTEM_ERROR(errno);
+      wError("vgId:%d, failed to stat file due to %s, file:%s", pWal->cfg.vgId, strerror(errno), fnameStr);
+      return -1;
+    }
+
+    if (updateMeta != NULL) *updateMeta = true;
+    if (pFileInfo->createTs == -1) pFileInfo->createTs = lastCloseTs;
+    pFileInfo->closeTs = mtime;
+    lastCloseTs = pFileInfo->closeTs;
+  }
+
+  return 0;
+}
+
 bool walLogEntriesComplete(const SWal* pWal) {
   int32_t sz = taosArrayGetSize(pWal->fileInfoSet);
   bool    complete = true;
@@ -433,15 +463,8 @@ int walCheckAndRepairMeta(SWal* pWal) {
         wError("failed to scan wal last ver since %s", terrstr());
         return -1;
       }
-      // remove the empty wal log, and its idx
-      wInfo("vgId:%d, wal remove empty file %s", pWal->cfg.vgId, fnameStr);
-      taosRemoveFile(fnameStr);
-      walBuildIdxName(pWal, pFileInfo->firstVer, fnameStr);
-      wInfo("vgId:%d, wal remove empty file %s", pWal->cfg.vgId, fnameStr);
-      taosRemoveFile(fnameStr);
-      // remove its meta entry
-      taosArrayRemove(pWal->fileInfoSet, fileIdx);
-      continue;
+      // empty log file
+      lastVer = pFileInfo->firstVer - 1;
     }
 
     // update lastVer
@@ -460,6 +483,11 @@ int walCheckAndRepairMeta(SWal* pWal) {
   }
   (void)walAlignVersions(pWal);
 
+  // repair ts of files
+  if (walRepairLogFileTs(pWal, &updateMeta) < 0) {
+    return -1;
+  }
+
   // update meta file
   if (updateMeta) {
     (void)walSaveMeta(pWal);
diff --git a/source/libs/wal/src/walRead.c b/source/libs/wal/src/walRead.c
index dc3ff3e6de..37d97b35a6 100644
--- a/source/libs/wal/src/walRead.c
+++ b/source/libs/wal/src/walRead.c
@@ -37,7 +37,7 @@ SWalReader *walOpenReader(SWal *pWal, SWalFilterCond *cond) {
   if (cond) {
     pReader->cond = *cond;
   } else {
-    pReader->cond.scanUncommited = 0;
+//    pReader->cond.scanUncommited = 0;
     pReader->cond.scanNotApplied = 0;
     pReader->cond.scanMeta = 0;
     pReader->cond.enableRef = 0;
@@ -74,11 +74,15 @@ int32_t walNextValidMsg(SWalReader *pReader) {
   int64_t lastVer = walGetLastVer(pReader->pWal);
   int64_t committedVer = walGetCommittedVer(pReader->pWal);
   int64_t appliedVer = walGetAppliedVer(pReader->pWal);
-  int64_t endVer = pReader->cond.scanUncommited ? lastVer : committedVer;
-  endVer = TMIN(appliedVer, endVer);
+  if(appliedVer < committedVer){   // wait apply ver equal to commit ver, otherwise may lost data when consume data [TD-24010]
+    wDebug("vgId:%d, wal apply ver:%"PRId64" smaller than commit ver:%"PRId64, pReader->pWal->cfg.vgId, appliedVer, committedVer);
+//    taosMsleep(10);
+  }
+//  int64_t endVer = pReader->cond.scanUncommited ? lastVer : committedVer;
+  int64_t endVer = TMIN(appliedVer, committedVer);
 
   wDebug("vgId:%d, wal start to fetch, index:%" PRId64 ", last index:%" PRId64 " commit index:%" PRId64
-         ", applied index:%" PRId64 ", end index:%" PRId64,
+         ", applied index:%" PRId64", end index:%" PRId64,
          pReader->pWal->cfg.vgId, fetchVer, lastVer, committedVer, appliedVer, endVer);
   while (fetchVer <= endVer) {
     if (walFetchHeadNew(pReader, fetchVer) < 0) {
@@ -237,6 +241,7 @@ static int32_t walFetchHeadNew(SWalReader *pRead, int64_t fetchVer) {
     }
     seeked = true;
   }
+
   while (1) {
     contLen = taosReadFile(pRead->pLogFile, pRead->pHead, sizeof(SWalCkHead));
     if (contLen == sizeof(SWalCkHead)) {
@@ -262,7 +267,7 @@ static int32_t walFetchBodyNew(SWalReader *pReader) {
   SWalCont *pReadHead = &pReader->pHead->head;
   int64_t   ver = pReadHead->version;
 
-  wDebug("vgId:%d, wal starts to fetch body, ver:%" PRId64 " ,len:%d", pReader->pWal->cfg.vgId, ver,
+  wDebug("vgId:%d, wal starts to fetch body, ver:%" PRId64 " ,len:%d, total", pReader->pWal->cfg.vgId, ver,
          pReadHead->bodyLen);
 
   if (pReader->capacity < pReadHead->bodyLen) {
diff --git a/source/libs/wal/src/walWrite.c b/source/libs/wal/src/walWrite.c
index 848de4f36d..9b7b3dfd50 100644
--- a/source/libs/wal/src/walWrite.c
+++ b/source/libs/wal/src/walWrite.c
@@ -284,15 +284,15 @@ int32_t walEndSnapshot(SWal *pWal) {
   if (ver == -1) {
     code = -1;
     goto END;
-  };
+  }
 
   pWal->vers.snapshotVer = ver;
   int ts = taosGetTimestampSec();
-
   ver = TMAX(ver - pWal->vers.logRetention, pWal->vers.firstVer - 1);
 
+  // compatible mode for refVer
   bool hasTopic = false;
-  int64_t refVer = ver;
+  int64_t refVer = INT64_MAX;
   void *pIter = NULL;
   while (1) {
     pIter = taosHashIterate(pWal->pRefHash, pIter);
@@ -300,54 +300,40 @@ int32_t walEndSnapshot(SWal *pWal) {
     SWalRef *pRef = *(SWalRef **)pIter;
     if (pRef->refVer == -1) continue;
     refVer = TMIN(refVer, pRef->refVer - 1);
-    wDebug("vgId:%d, wal found ref %" PRId64 ", refId %" PRId64, pWal->cfg.vgId, pRef->refVer, pRef->refId);
     hasTopic = true;
   }
-  // compatible mode
   if (pWal->cfg.retentionPeriod == 0 && hasTopic) {
+    wInfo("vgId:%d, wal found refVer:%" PRId64 " in compatible mode, ver:%" PRId64, pWal->cfg.vgId, refVer, ver);
     ver = TMIN(ver, refVer);
   }
 
+  // find files safe to delete
   int          deleteCnt = 0;
   int64_t      newTotSize = pWal->totSize;
-  SWalFileInfo tmp;
+  SWalFileInfo tmp = {0};
   tmp.firstVer = ver;
-  // find files safe to delete
   SWalFileInfo *pInfo = taosArraySearch(pWal->fileInfoSet, &tmp, compareWalFileInfo, TD_LE);
+
   if (pInfo) {
-    SWalFileInfo *pLastFileInfo = taosArrayGetLast(pWal->fileInfoSet);
-    wDebug("vgId:%d, wal search found file info: first:%" PRId64 " last:%" PRId64, pWal->cfg.vgId, pInfo->firstVer,
-           pInfo->lastVer);
-    if (ver >= pInfo->lastVer) {
+    wDebug("vgId:%d, wal search found file info. ver:%" PRId64 ", first:%" PRId64 " last:%" PRId64, pWal->cfg.vgId, ver,
+           pInfo->firstVer, pInfo->lastVer);
+    ASSERT(ver <= pInfo->lastVer);
+    if (ver == pInfo->lastVer) {
       pInfo++;
-      wDebug("vgId:%d, wal remove advance one file: first:%" PRId64 " last:%" PRId64, pWal->cfg.vgId, pInfo->firstVer,
-             pInfo->lastVer);
-    }
-    if (pInfo <= pLastFileInfo) {
-      wDebug("vgId:%d, wal end remove for first:%" PRId64 " last:%" PRId64, pWal->cfg.vgId, pInfo->firstVer,
-             pInfo->lastVer);
-    } else {
-      wDebug("vgId:%d, wal no remove", pWal->cfg.vgId);
     }
 
     // iterate files, until the searched result
+    // delete according to file size or close time
     for (SWalFileInfo *iter = pWal->fileInfoSet->pData; iter < pInfo; iter++) {
-      wDebug("vgId:%d, wal check remove file %" PRId64 "(file size %" PRId64 " close ts %" PRId64
-             "), new tot size %" PRId64,
-             pWal->cfg.vgId, iter->firstVer, iter->fileSize, iter->closeTs, newTotSize);
-      if ((pWal->cfg.retentionSize != -1 && pWal->cfg.retentionSize != 0 && newTotSize > pWal->cfg.retentionSize) ||
-          ((pWal->cfg.retentionPeriod == 0) || (pWal->cfg.retentionPeriod != -1 && iter->closeTs != -1 &&
-                                                iter->closeTs + pWal->cfg.retentionPeriod < ts))) {
-        // delete according to file size or close time
-        wDebug("vgId:%d, check pass", pWal->cfg.vgId);
+      if ((pWal->cfg.retentionSize > 0 && newTotSize > pWal->cfg.retentionSize) ||
+          (pWal->cfg.retentionPeriod == 0 ||
+           pWal->cfg.retentionPeriod > 0 && iter->closeTs >= 0 && iter->closeTs + pWal->cfg.retentionPeriod < ts)) {
         deleteCnt++;
         newTotSize -= iter->fileSize;
         taosArrayPush(pWal->toDeleteFiles, iter);
       }
-      wDebug("vgId:%d, check not pass", pWal->cfg.vgId);
     }
 
-  UPDATE_META:
     // make new array, remove files
     taosArrayPopFrontBatch(pWal->fileInfoSet, deleteCnt);
     if (taosArrayGetSize(pWal->fileInfoSet) == 0) {
@@ -357,11 +343,12 @@ int32_t walEndSnapshot(SWal *pWal) {
       pWal->vers.firstVer = ((SWalFileInfo *)taosArrayGet(pWal->fileInfoSet, 0))->firstVer;
     }
   }
+
+  // update meta
   pWal->writeCur = taosArrayGetSize(pWal->fileInfoSet) - 1;
   pWal->totSize = newTotSize;
   pWal->vers.verInSnapshotting = -1;
 
-  // save snapshot ver, commit ver
   code = walSaveMeta(pWal);
   if (code < 0) {
     goto END;
@@ -369,23 +356,27 @@ int32_t walEndSnapshot(SWal *pWal) {
 
   // delete files
   deleteCnt = taosArrayGetSize(pWal->toDeleteFiles);
-  wDebug("vgId:%d, wal should delete %d files", pWal->cfg.vgId, deleteCnt);
-  char fnameStr[WAL_FILE_LEN];
+  char fnameStr[WAL_FILE_LEN] = {0};
+  pInfo = NULL;
+
   for (int i = 0; i < deleteCnt; i++) {
     pInfo = taosArrayGet(pWal->toDeleteFiles, i);
+
     walBuildLogName(pWal, pInfo->firstVer, fnameStr);
-    wDebug("vgId:%d, wal remove file %s", pWal->cfg.vgId, fnameStr);
     if (taosRemoveFile(fnameStr) < 0 && errno != ENOENT) {
       wError("vgId:%d, failed to remove log file %s due to %s", pWal->cfg.vgId, fnameStr, strerror(errno));
       goto END;
     }
     walBuildIdxName(pWal, pInfo->firstVer, fnameStr);
-    wDebug("vgId:%d, wal remove file %s", pWal->cfg.vgId, fnameStr);
     if (taosRemoveFile(fnameStr) < 0 && errno != ENOENT) {
       wError("vgId:%d, failed to remove idx file %s due to %s", pWal->cfg.vgId, fnameStr, strerror(errno));
       goto END;
     }
   }
+  if (pInfo != NULL) {
+    wInfo("vgId:%d, wal log files recycled. count:%d, until ver:%" PRId64 ", closeTs:%" PRId64, pWal->cfg.vgId,
+          deleteCnt, pInfo->lastVer, pInfo->closeTs);
+  }
   taosArrayClear(pWal->toDeleteFiles);
 
 END:
diff --git a/source/os/src/osFile.c b/source/os/src/osFile.c
index aab547223f..dd670595f0 100644
--- a/source/os/src/osFile.c
+++ b/source/os/src/osFile.c
@@ -538,10 +538,11 @@ int32_t taosFStatFile(TdFilePtr pFile, int64_t *size, int32_t *mtime) {
     return -1;
   }
 
-  struct stat fileStat;
 #ifdef WINDOWS
-  int32_t code = _fstat(pFile->fd, &fileStat);
+  struct __stat64 fileStat;
+  int32_t code = _fstat64(pFile->fd, &fileStat);
 #else
+  struct stat fileStat;
   int32_t code = fstat(pFile->fd, &fileStat);
 #endif
   if (code < 0) {
diff --git a/source/os/src/osLocale.c b/source/os/src/osLocale.c
index 7008c38576..136b8cf022 100644
--- a/source/os/src/osLocale.c
+++ b/source/os/src/osLocale.c
@@ -171,7 +171,7 @@ void taosGetSystemLocale(char *outLocale, char *outCharset) {
     strcpy(outLocale, "en_US.UTF-8");
   } else {
     tstrncpy(outLocale, locale, TD_LOCALE_LEN);
-    // printf("locale not configured, set to system default:%s", outLocale);
+    //printf("locale not configured, set to system default:%s\n", outLocale);
   }
 
   // if user does not specify the charset, extract it from locale
diff --git a/source/util/src/tarray.c b/source/util/src/tarray.c
index a786721213..6c7c5ddb0d 100644
--- a/source/util/src/tarray.c
+++ b/source/util/src/tarray.c
@@ -69,8 +69,6 @@ SArray* taosArrayInit_s(size_t elemSize, size_t initialSize) {
 }
 
 static int32_t taosArrayResize(SArray* pArray) {
-  assert(pArray->size >= pArray->capacity);
-
   size_t size = pArray->capacity;
   size = (size << 1u);
 
@@ -252,12 +250,15 @@ void* taosArrayInsert(SArray* pArray, size_t index, void* pData) {
 }
 
 void taosArraySet(SArray* pArray, size_t index, void* pData) {
-  assert(index < pArray->size);
+  ASSERT(index < pArray->size);
   memcpy(TARRAY_GET_ELEM(pArray, index), pData, pArray->elemSize);
 }
 
 void taosArrayPopFrontBatch(SArray* pArray, size_t cnt) {
-  assert(cnt <= pArray->size);
+  if (cnt > pArray->size) {
+    cnt = pArray->size;
+  }
+
   pArray->size = pArray->size - cnt;
   if (pArray->size == 0 || cnt == 0) {
     return;
@@ -266,12 +267,15 @@ void taosArrayPopFrontBatch(SArray* pArray, size_t cnt) {
 }
 
 void taosArrayPopTailBatch(SArray* pArray, size_t cnt) {
-  assert(cnt <= pArray->size);
+  if (cnt >= pArray->size) {
+    cnt = pArray->size;
+  }
+
   pArray->size = pArray->size - cnt;
 }
 
 void taosArrayRemove(SArray* pArray, size_t index) {
-  assert(index < pArray->size);
+  ASSERT(index < pArray->size);
 
   if (index == pArray->size - 1) {
     taosArrayPop(pArray);
@@ -487,7 +491,8 @@ void* taosDecodeArray(const void* buf, SArray** pArray, FDecode decode, int32_t
 // todo remove it
 // order array
 void taosArraySortPWithExt(SArray* pArray, __ext_compar_fn_t fn, const void* param) {
-  taosArrayGetSize(pArray) > 8 ? taosArrayQuickSort(pArray, fn, param) : taosArrayInsertSort(pArray, fn, param);
+  taosqsort(pArray->pData, pArray->size, pArray->elemSize, param, fn);
+//  taosArrayGetSize(pArray) > 8 ? taosArrayQuickSort(pArray, fn, param) : taosArrayInsertSort(pArray, fn, param);
 }
 
 void taosArraySwap(SArray* a, SArray* b) {
diff --git a/source/util/src/tcache.c b/source/util/src/tcache.c
index 1d480e7beb..28d9b412a0 100644
--- a/source/util/src/tcache.c
+++ b/source/util/src/tcache.c
@@ -243,11 +243,6 @@ static FORCE_INLINE STrashElem *doRemoveElemInTrashcan(SCacheObj *pCacheObj, STr
   if (next) {
     next->prev = pElem->prev;
   }
-
-  if (pCacheObj->numOfElemsInTrash == 0) {
-    assert(pCacheObj->pTrash == NULL);
-  }
-
   return next;
 }
 
@@ -261,8 +256,6 @@ static FORCE_INLINE void doDestroyTrashcanElem(SCacheObj *pCacheObj, STrashElem
 }
 
 static void pushfrontNodeInEntryList(SCacheEntry *pEntry, SCacheNode *pNode) {
-  assert(pNode != NULL && pEntry != NULL);
-
   pNode->pNext = pEntry->next;
   pEntry->next = pNode;
   pEntry->num += 1;
@@ -271,7 +264,6 @@ static void pushfrontNodeInEntryList(SCacheEntry *pEntry, SCacheNode *pNode) {
 
 static void removeNodeInEntryList(SCacheEntry *pe, SCacheNode *prev, SCacheNode *pNode) {
   if (prev == NULL) {
-    ASSERT(pe->next == pNode);
     pe->next = pNode->pNext;
   } else {
     prev->pNext = pNode->pNext;
@@ -471,7 +463,6 @@ void *taosCacheAcquireByKey(SCacheObj *pCacheObj, const void *key, size_t keyLen
   SCacheNode *pNode = doSearchInEntryList(pe, key, keyLen, &prev);
   if (pNode != NULL) {
     int32_t ref = T_REF_INC(pNode);
-    ASSERT(ref > 0);
   }
 
   taosRUnLockLatch(&pe->latch);
@@ -503,7 +494,7 @@ void *taosCacheAcquireByData(SCacheObj *pCacheObj, void *data) {
   uDebug("cache:%s, data: %p acquired by data in cache, refcnt:%d", pCacheObj->name, ptNode->data, ref);
 
   // the data if referenced by at least one object, so the reference count must be greater than the value of 2.
-  assert(ref >= 2);
+  ASSERT(ref >= 2);
   return data;
 }
 
@@ -516,7 +507,6 @@ void *taosCacheTransferData(SCacheObj *pCacheObj, void **data) {
     return NULL;
   }
 
-  assert(T_REF_VAL_GET(ptNode) >= 1);
   char *d = *data;
 
   // clear its reference to old area
@@ -575,19 +565,19 @@ void taosCacheRelease(SCacheObj *pCacheObj, void **data, bool _remove) {
       if (ref == 1) {
         // If it is the last ref, remove it from trashcan linked-list first, and then destroy it.Otherwise, it may be
         // destroyed by refresh worker if decrease ref count before removing it from linked-list.
-        assert(pNode->pTNodeHeader->pData == pNode);
+        ASSERT(pNode->pTNodeHeader->pData == pNode);
 
         __trashcan_wr_lock(pCacheObj);
         doRemoveElemInTrashcan(pCacheObj, pNode->pTNodeHeader);
         __trashcan_unlock(pCacheObj);
 
         ref = T_REF_DEC(pNode);
-        assert(ref == 0);
+        ASSERT(ref == 0);
 
         doDestroyTrashcanElem(pCacheObj, pNode->pTNodeHeader);
       } else {
         ref = T_REF_DEC(pNode);
-        assert(ref >= 0);
+        ASSERT(ref >= 0);
       }
     } else {
       // NOTE: remove it from hash in the first place, otherwise, the pNode may have been released by other thread
@@ -609,13 +599,12 @@ void taosCacheRelease(SCacheObj *pCacheObj, void **data, bool _remove) {
               "others already, prev must in trashcan",
               pCacheObj->name, pNode->key, p->data, T_REF_VAL_GET(p), pNode->data, T_REF_VAL_GET(pNode));
 
-          assert(p->pTNodeHeader == NULL && pNode->pTNodeHeader != NULL);
+          ASSERT(p->pTNodeHeader == NULL && pNode->pTNodeHeader != NULL);
         } else {
           removeNodeInEntryList(pe, prev, p);
           uDebug("cache:%s, key:%p, %p successfully removed from hash table, refcnt:%d", pCacheObj->name, pNode->key,
                  pNode->data, ref);
           if (ref > 0) {
-            assert(pNode->pTNodeHeader == NULL);
             taosAddToTrashcan(pCacheObj, pNode);
           } else {  // ref == 0
             atomic_sub_fetch_64(&pCacheObj->sizeInBytes, pNode->size);
@@ -736,7 +725,7 @@ SCacheNode *taosCreateCacheNode(const char *key, size_t keyLen, const char *pDat
 
 void taosAddToTrashcan(SCacheObj *pCacheObj, SCacheNode *pNode) {
   if (pNode->inTrashcan) { /* node is already in trash */
-    assert(pNode->pTNodeHeader != NULL && pNode->pTNodeHeader->pData == pNode);
+    ASSERT(pNode->pTNodeHeader != NULL && pNode->pTNodeHeader->pData == pNode);
     return;
   }
 
@@ -782,7 +771,7 @@ void taosTrashcanEmpty(SCacheObj *pCacheObj, bool force) {
   STrashElem *pElem = pCacheObj->pTrash;
   while (pElem) {
     T_REF_VAL_CHECK(pElem->pData);
-    assert(pElem->next != pElem && pElem->prev != pElem);
+    ASSERT(pElem->next != pElem && pElem->prev != pElem);
 
     if (force || (T_REF_VAL_GET(pElem->pData) == 0)) {
       uDebug("cache:%s, key:%p, %p removed from trashcan. numOfElem in trashcan:%d", pCacheObj->name, pElem->pData->key,
@@ -814,8 +803,6 @@ void doCleanupDataCache(SCacheObj *pCacheObj) {
 }
 
 static void doCacheRefresh(SCacheObj *pCacheObj, int64_t time, __cache_trav_fn_t fp, void *param1) {
-  assert(pCacheObj != NULL);
-
   SCacheObjTravSup sup = {.pCacheObj = pCacheObj, .fp = fp, .time = time, .param1 = param1};
   doTraverseElems(pCacheObj, doRemoveExpiredFn, &sup);
 }
@@ -827,9 +814,7 @@ void taosCacheRefreshWorkerUnexpectedStopped(void) {
 }
 
 void *taosCacheTimedRefresh(void *handle) {
-  assert(pCacheArrayList != NULL);
   uDebug("cache refresh thread starts");
-
   setThreadName("cacheRefresh");
 
   const int32_t SLEEP_DURATION = 500;  // 500 ms
@@ -928,7 +913,6 @@ void taosStopCacheRefreshWorker(void) {
 size_t taosCacheGetNumOfObj(const SCacheObj *pCacheObj) { return pCacheObj->numOfElems + pCacheObj->numOfElemsInTrash; }
 
 SCacheIter *taosCacheCreateIter(const SCacheObj *pCacheObj) {
-  ASSERT(pCacheObj != NULL);
   SCacheIter *pIter = taosMemoryCalloc(1, sizeof(SCacheIter));
   pIter->pCacheObj = (SCacheObj *)pCacheObj;
   pIter->entryIndex = -1;
@@ -978,12 +962,8 @@ bool taosCacheIterNext(SCacheIter *pIter) {
 
       SCacheNode *pNode = pEntry->next;
       for (int32_t i = 0; i < pEntry->num; ++i) {
-        ASSERT(pNode != NULL);
-
         pIter->pCurrent[i] = pNode;
         int32_t ref = T_REF_INC(pIter->pCurrent[i]);
-        ASSERT(ref >= 1);
-
         pNode = pNode->pNext;
       }
 
diff --git a/source/util/src/tcompare.c b/source/util/src/tcompare.c
index f8f78ae6a5..dc57ed97b2 100644
--- a/source/util/src/tcompare.c
+++ b/source/util/src/tcompare.c
@@ -308,17 +308,19 @@ int32_t compareInt8Uint16(const void *pLeft, const void *pRight) {
 
 int32_t compareInt8Uint32(const void *pLeft, const void *pRight) {
   int8_t   left = GET_INT8_VAL(pLeft);
+  if (left < 0) return -1;
   uint32_t right = GET_UINT32_VAL(pRight);
-  if (left > right) return 1;
-  if (left < right) return -1;
+  if ((uint32_t)left > right) return 1;
+  if ((uint32_t)left < right) return -1;
   return 0;
 }
 
 int32_t compareInt8Uint64(const void *pLeft, const void *pRight) {
   int8_t   left = GET_INT8_VAL(pLeft);
+  if (left < 0) return -1;
   uint64_t right = GET_UINT64_VAL(pRight);
-  if (left > right) return 1;
-  if (left < right) return -1;
+  if ((uint64_t)left > right) return 1;
+  if ((uint64_t)left < right) return -1;
   return 0;
 }
 
@@ -380,17 +382,19 @@ int32_t compareInt16Uint16(const void *pLeft, const void *pRight) {
 
 int32_t compareInt16Uint32(const void *pLeft, const void *pRight) {
   int16_t  left = GET_INT16_VAL(pLeft);
+  if (left < 0) return -1;
   uint32_t right = GET_UINT32_VAL(pRight);
-  if (left > right) return 1;
-  if (left < right) return -1;
+  if ((uint32_t)left > right) return 1;
+  if ((uint32_t)left < right) return -1;
   return 0;
 }
 
 int32_t compareInt16Uint64(const void *pLeft, const void *pRight) {
   int16_t  left = GET_INT16_VAL(pLeft);
+  if (left < 0) return -1;
   uint64_t right = GET_UINT64_VAL(pRight);
-  if (left > right) return 1;
-  if (left < right) return -1;
+  if ((uint64_t)left > right) return 1;
+  if ((uint64_t)left < right) return -1;
   return 0;
 }
 
@@ -452,17 +456,19 @@ int32_t compareInt32Uint16(const void *pLeft, const void *pRight) {
 
 int32_t compareInt32Uint32(const void *pLeft, const void *pRight) {
   int32_t  left = GET_INT32_VAL(pLeft);
+  if (left < 0) return -1;
   uint32_t right = GET_UINT32_VAL(pRight);
-  if (left > right) return 1;
-  if (left < right) return -1;
+  if ((uint32_t)left > right) return 1;
+  if ((uint32_t)left < right) return -1;
   return 0;
 }
 
 int32_t compareInt32Uint64(const void *pLeft, const void *pRight) {
   int32_t  left = GET_INT32_VAL(pLeft);
+  if (left < 0) return -1;
   uint64_t right = GET_UINT64_VAL(pRight);
-  if (left > right) return 1;
-  if (left < right) return -1;
+  if ((uint64_t)left > right) return 1;
+  if ((uint64_t)left < right) return -1;
   return 0;
 }
 
@@ -532,9 +538,10 @@ int32_t compareInt64Uint32(const void *pLeft, const void *pRight) {
 
 int32_t compareInt64Uint64(const void *pLeft, const void *pRight) {
   int64_t  left = GET_INT64_VAL(pLeft);
+  if (left < 0) return -1;
   uint64_t right = GET_UINT64_VAL(pRight);
-  if (left > right) return 1;
-  if (left < right) return -1;
+  if ((uint64_t)left > right) return 1;
+  if ((uint64_t)left < right) return -1;
   return 0;
 }
 
@@ -857,24 +864,27 @@ int32_t compareUint16Uint64(const void *pLeft, const void *pRight) {
 int32_t compareUint32Int8(const void *pLeft, const void *pRight) {
   uint32_t left = GET_UINT32_VAL(pLeft);
   int8_t   right = GET_INT8_VAL(pRight);
-  if (left > right) return 1;
-  if (left < right) return -1;
+  if (right < 0) return 1;
+  if (left > (uint32_t)right) return 1;
+  if (left < (uint32_t)right) return -1;
   return 0;
 }
 
 int32_t compareUint32Int16(const void *pLeft, const void *pRight) {
   uint32_t left = GET_UINT32_VAL(pLeft);
   int16_t  right = GET_INT16_VAL(pRight);
-  if (left > right) return 1;
-  if (left < right) return -1;
+  if (right < 0) return 1;
+  if (left > (uint32_t)right) return 1;
+  if (left < (uint32_t)right) return -1;
   return 0;
 }
 
 int32_t compareUint32Int32(const void *pLeft, const void *pRight) {
   uint32_t left = GET_UINT32_VAL(pLeft);
   int32_t  right = GET_INT32_VAL(pRight);
-  if (left > right) return 1;
-  if (left < right) return -1;
+  if (right < 0) return 1;
+  if (left > (uint32_t)right) return 1;
+  if (left < (uint32_t)right) return -1;
   return 0;
 }
 
@@ -929,32 +939,36 @@ int32_t compareUint32Uint64(const void *pLeft, const void *pRight) {
 int32_t compareUint64Int8(const void *pLeft, const void *pRight) {
   uint64_t left = GET_UINT64_VAL(pLeft);
   int8_t   right = GET_INT8_VAL(pRight);
-  if (left > right) return 1;
-  if (left < right) return -1;
+  if (right < 0) return 1;
+  if (left > (uint64_t)right) return 1;
+  if (left < (uint64_t)right) return -1;
   return 0;
 }
 
 int32_t compareUint64Int16(const void *pLeft, const void *pRight) {
   uint64_t left = GET_UINT64_VAL(pLeft);
   int16_t  right = GET_INT16_VAL(pRight);
-  if (left > right) return 1;
-  if (left < right) return -1;
+  if (right < 0) return 1;
+  if (left > (uint64_t)right) return 1;
+  if (left < (uint64_t)right) return -1;
   return 0;
 }
 
 int32_t compareUint64Int32(const void *pLeft, const void *pRight) {
   uint64_t left = GET_UINT64_VAL(pLeft);
   int32_t  right = GET_INT32_VAL(pRight);
-  if (left > right) return 1;
-  if (left < right) return -1;
+  if (right < 0) return 1;
+  if (left > (uint64_t)right) return 1;
+  if (left < (uint64_t)right) return -1;
   return 0;
 }
 
 int32_t compareUint64Int64(const void *pLeft, const void *pRight) {
   uint64_t left = GET_UINT64_VAL(pLeft);
   int64_t  right = GET_INT64_VAL(pRight);
-  if (left > right) return 1;
-  if (left < right) return -1;
+  if (right < 0) return 1;
+  if (left > (uint64_t)right) return 1;
+  if (left < (uint64_t)right) return -1;
   return 0;
 }
 
diff --git a/source/util/src/terror.c b/source/util/src/terror.c
index 002d605793..6f726c7eff 100644
--- a/source/util/src/terror.c
+++ b/source/util/src/terror.c
@@ -122,7 +122,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_TSC_NO_WRITE_AUTH,            "No write permission")
 TAOS_DEFINE_ERROR(TSDB_CODE_TSC_CONN_KILLED,              "Connection killed")
 TAOS_DEFINE_ERROR(TSDB_CODE_TSC_SQL_SYNTAX_ERROR,         "Syntax error in SQL")
 TAOS_DEFINE_ERROR(TSDB_CODE_TSC_DB_NOT_SELECTED,          "Database not specified or available")
-TAOS_DEFINE_ERROR(TSDB_CODE_TSC_INVALID_TABLE_NAME,       "Table does not exist")
+//TAOS_DEFINE_ERROR(TSDB_CODE_TSC_INVALID_TABLE_NAME,       "Table does not exist")
 TAOS_DEFINE_ERROR(TSDB_CODE_TSC_EXCEED_SQL_LIMIT,         "SQL statement too long")
 TAOS_DEFINE_ERROR(TSDB_CODE_TSC_FILE_EMPTY,               "File is empty")
 TAOS_DEFINE_ERROR(TSDB_CODE_TSC_LINE_SYNTAX_ERROR,        "Syntax error in Line")
@@ -203,6 +203,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_MND_COLUMN_ALREADY_EXIST,     "Column already exists
 TAOS_DEFINE_ERROR(TSDB_CODE_MND_COLUMN_NOT_EXIST,         "Column does not exist")
 TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_STB_OPTION,       "Invalid stable options")
 TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_ROW_BYTES,        "Invalid row bytes")
+TAOS_DEFINE_ERROR(TSDB_CODE_MND_FIELD_VALUE_OVERFLOW,          "out of range and overflow")
 
 // mnode-func
 TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_FUNC_NAME,        "Invalid func name")
diff --git a/source/util/src/thash.c b/source/util/src/thash.c
index 926dc304a4..cf4f17bfbc 100644
--- a/source/util/src/thash.c
+++ b/source/util/src/thash.c
@@ -150,7 +150,6 @@ static FORCE_INLINE SHashNode *doSearchInEntryList(SHashObj *pHashObj, SHashEntr
     //atomic_add_fetch_64(&pHashObj->compTimes, 1);
     if ((pNode->keyLen == keyLen) && ((*(pHashObj->equalFp))(GET_HASH_NODE_KEY(pNode), key, keyLen) == 0) &&
         pNode->removed == 0) {
-      assert(pNode->hashVal == hashVal);
       break;
     }
 
@@ -189,8 +188,6 @@ static SHashNode *doCreateHashNode(const void *key, size_t keyLen, const void *p
  */
 static FORCE_INLINE void doUpdateHashNode(SHashObj *pHashObj, SHashEntry *pe, SHashNode *prev, SHashNode *pNode,
                                           SHashNode *pNewNode) {
-  assert(pNode->keyLen == pNewNode->keyLen);
-
   atomic_sub_fetch_16(&pNode->refCount, 1);
   if (prev != NULL) {
     prev->next = pNewNode;
@@ -236,7 +233,7 @@ static FORCE_INLINE bool taosHashTableEmpty(const SHashObj *pHashObj) { return t
 
 SHashObj *taosHashInit(size_t capacity, _hash_fn_t fn, bool update, SHashLockTypeE type) {
   if (fn == NULL) {
-    assert(0);
+    terrno = TSDB_CODE_INVALID_PARA;
     return NULL;
   }
 
@@ -262,8 +259,6 @@ SHashObj *taosHashInit(size_t capacity, _hash_fn_t fn, bool update, SHashLockTyp
   pHashObj->freeFp = NULL;
   pHashObj->callbackFp = NULL;
 
-  ASSERT((pHashObj->capacity & (pHashObj->capacity - 1)) == 0);
-
   pHashObj->hashList = (SHashEntry **)taosMemoryMalloc(pHashObj->capacity * sizeof(void *));
   if (pHashObj->hashList == NULL) {
     taosMemoryFree(pHashObj);
@@ -342,19 +337,10 @@ int32_t taosHashPut(SHashObj *pHashObj, const void *key, size_t keyLen, const vo
   taosHashEntryWLock(pHashObj, pe);
 
   SHashNode *pNode = pe->next;
-#if 0
-  if (pe->num > 0) {
-    assert(pNode != NULL);
-  } else {
-    assert(pNode == NULL);
-  }
-#endif
-
   SHashNode *prev = NULL;
   while (pNode) {
     if ((pNode->keyLen == keyLen) && (*(pHashObj->equalFp))(GET_HASH_NODE_KEY(pNode), key, keyLen) == 0 &&
         pNode->removed == 0) {
-      assert(pNode->hashVal == hashVal);
       break;
     }
 
@@ -370,8 +356,6 @@ int32_t taosHashPut(SHashObj *pHashObj, const void *key, size_t keyLen, const vo
     }
 
     pushfrontNodeInEntryList(pe, pNewNode);
-    assert(pe->next != NULL);
-
     taosHashEntryWUnlock(pHashObj, pe);
 
     // enable resize
@@ -446,14 +430,6 @@ void *taosHashGetImpl(SHashObj *pHashObj, const void *key, size_t keyLen, void *
   char *data = NULL;
   taosHashEntryRLock(pHashObj, pe);
 
-#if 0
-  if (pe->num > 0) {
-    assert(pe->next != NULL);
-  } else {
-    assert(pe->next == NULL);
-  }
-#endif
-
   SHashNode *pNode = doSearchInEntryList(pHashObj, pe, key, keyLen, hashVal);
   if (pNode != NULL) {
     if (pHashObj->callbackFp != NULL) {
@@ -514,8 +490,6 @@ int32_t taosHashRemove(SHashObj *pHashObj, const void *key, size_t keyLen) {
 
   // double check after locked
   if (pe->num == 0) {
-    assert(pe->next == NULL);
-
     taosHashEntryWUnlock(pHashObj, pe);
     taosHashRUnlock(pHashObj);
     return -1;
@@ -568,13 +542,10 @@ void taosHashClear(SHashObj *pHashObj) {
   for (int32_t i = 0; i < pHashObj->capacity; ++i) {
     SHashEntry *pEntry = pHashObj->hashList[i];
     if (pEntry->num == 0) {
-      assert(pEntry->next == NULL);
       continue;
     }
 
     pNode = pEntry->next;
-    assert(pNode != NULL);
-
     while (pNode) {
       pNext = pNode->next;
       FREE_HASH_NODE(pHashObj->freeFp, pNode);
@@ -671,14 +642,11 @@ void taosHashTableResize(SHashObj *pHashObj) {
     SHashNode  *pPrev = NULL;
 
     if (pe->num == 0) {
-      assert(pe->next == NULL);
       continue;
     }
 
     pNode = pe->next;
 
-    assert(pNode != NULL);
-
     while (pNode != NULL) {
       int32_t newIdx = HASH_INDEX(pNode->hashVal, pHashObj->capacity);
       pNext = pNode->next;
@@ -728,12 +696,8 @@ SHashNode *doCreateHashNode(const void *key, size_t keyLen, const void *pData, s
 }
 
 void pushfrontNodeInEntryList(SHashEntry *pEntry, SHashNode *pNode) {
-  assert(pNode != NULL && pEntry != NULL);
-
   pNode->next = pEntry->next;
   pEntry->next = pNode;
-
-  ASSERT(pNode->next != pNode);
   pEntry->num += 1;
 }
 
@@ -847,19 +811,7 @@ void *taosHashIterate(SHashObj *pHashObj, void *p) {
 
     /*uint16_t prevRef = atomic_load_16(&pNode->refCount);*/
     uint16_t afterRef = atomic_add_fetch_16(&pNode->refCount, 1);
-#if 0
-    ASSERT(prevRef < afterRef);
 
-    // the reference count value is overflow, which will cause the delete node operation immediately.
-    if (prevRef > afterRef) {
-      uError("hash entry ref count overflow, prev ref:%d, current ref:%d", prevRef, afterRef);
-      // restore the value
-      atomic_sub_fetch_16(&pNode->refCount, 1);
-      data = NULL;
-    } else {
-      data = GET_HASH_NODE_DATA(pNode);
-    }
-#endif
     data = GET_HASH_NODE_DATA(pNode);
 
     if (afterRef >= MAX_WARNING_REF_COUNT) {
diff --git a/source/util/src/tlist.c b/source/util/src/tlist.c
index 1b12ea0cdd..5d729d27d6 100644
--- a/source/util/src/tlist.c
+++ b/source/util/src/tlist.c
@@ -104,7 +104,6 @@ SListNode *tdListPopNode(SList *list, SListNode *node) {
 
 // Move all node elements from src to dst, the dst is assumed as an empty list
 void tdListMove(SList *src, SList *dst) {
-  // assert(dst->eleSize == src->eleSize);
   SListNode *node = NULL;
   while ((node = tdListPopHead(src)) != NULL) {
     tdListAppendNode(dst, node);
diff --git a/source/util/src/tlog.c b/source/util/src/tlog.c
index 0e75e2022b..e3b1c2fa2f 100644
--- a/source/util/src/tlog.c
+++ b/source/util/src/tlog.c
@@ -347,7 +347,6 @@ static int32_t taosOpenLogFile(char *fn, int32_t maxLines, int32_t maxFileNum) {
 
   char    name[LOG_FILE_NAME_LEN + 50] = "\0";
   int32_t logstat0_mtime, logstat1_mtime;
-  int32_t size;
 
   tsLogObj.maxLines = maxLines;
   tsLogObj.fileNum = maxFileNum;
@@ -395,8 +394,7 @@ static int32_t taosOpenLogFile(char *fn, int32_t maxLines, int32_t maxFileNum) {
     printf("\nfailed to fstat log file:%s, reason:%s\n", fileName, strerror(errno));
     return -1;
   }
-  size = (int32_t)filesize;
-  tsLogObj.lines = size / 60;
+  tsLogObj.lines = (int32_t)(filesize / 60);
 
   taosLSeekFile(tsLogObj.logHandle->pFile, 0, SEEK_END);
 
diff --git a/source/util/src/tlosertree.c b/source/util/src/tlosertree.c
index bf99212b78..c476baa790 100644
--- a/source/util/src/tlosertree.c
+++ b/source/util/src/tlosertree.c
@@ -115,8 +115,6 @@ void tMergeTreeAdjust(SMultiwayMergeTreeInfo* pTree, int32_t idx) {
 }
 
 void tMergeTreeRebuild(SMultiwayMergeTreeInfo* pTree) {
-  ASSERT((pTree->totalSources & 0x1) == 0);
-
   tMergeTreeInit(pTree);
   for (int32_t i = pTree->totalSources - 1; i >= pTree->numOfSources; i--) {
     tMergeTreeAdjust(pTree, i);
diff --git a/source/util/src/tlrucache.c b/source/util/src/tlrucache.c
index f4172fbb44..e182800d9c 100644
--- a/source/util/src/tlrucache.c
+++ b/source/util/src/tlrucache.c
@@ -85,13 +85,13 @@ struct SLRUEntry {
 #define TAOS_LRU_ENTRY_REF(h)      (++(h)->refs)
 
 static bool taosLRUEntryUnref(SLRUEntry *entry) {
-  assert(entry->refs > 0);
+  ASSERT(entry->refs > 0);
   --entry->refs;
   return entry->refs == 0;
 }
 
 static void taosLRUEntryFree(SLRUEntry *entry) {
-  assert(entry->refs == 0);
+  ASSERT(entry->refs == 0);
 
   if (entry->deleter) {
     (*entry->deleter)(entry->keyData, entry->keyLength, entry->value);
@@ -127,7 +127,7 @@ static void taosLRUEntryTableApply(SLRUEntryTable *table, _taos_lru_table_func_t
     SLRUEntry *h = table->list[i];
     while (h) {
       SLRUEntry *n = h->nextHash;
-      assert(TAOS_LRU_ENTRY_IN_CACHE(h));
+      ASSERT(TAOS_LRU_ENTRY_IN_CACHE(h));
       func(h);
       h = n;
     }
@@ -184,7 +184,7 @@ static void taosLRUEntryTableResize(SLRUEntryTable *table) {
       ++count;
     }
   }
-  assert(table->elems == count);
+  ASSERT(table->elems == count);
 
   taosMemoryFree(table->list);
   table->list = newList;
@@ -240,17 +240,16 @@ struct SLRUCacheShard {
 static void taosLRUCacheShardMaintainPoolSize(SLRUCacheShard *shard) {
   while (shard->highPriPoolUsage > shard->highPriPoolCapacity) {
     shard->lruLowPri = shard->lruLowPri->next;
-    assert(shard->lruLowPri != &shard->lru);
+    ASSERT(shard->lruLowPri != &shard->lru);
     TAOS_LRU_ENTRY_SET_IN_HIGH_POOL(shard->lruLowPri, false);
 
-    assert(shard->highPriPoolUsage >= shard->lruLowPri->totalCharge);
+    ASSERT(shard->highPriPoolUsage >= shard->lruLowPri->totalCharge);
     shard->highPriPoolUsage -= shard->lruLowPri->totalCharge;
   }
 }
 
 static void taosLRUCacheShardLRUInsert(SLRUCacheShard *shard, SLRUEntry *e) {
-  assert(e->next == NULL);
-  assert(e->prev == NULL);
+  ASSERT(e->next == NULL && e->prev == NULL);
 
   if (shard->highPriPoolRatio > 0 && (TAOS_LRU_ENTRY_IS_HIGH_PRI(e) || TAOS_LRU_ENTRY_HAS_HIT(e))) {
     e->next = &shard->lru;
@@ -277,8 +276,7 @@ static void taosLRUCacheShardLRUInsert(SLRUCacheShard *shard, SLRUEntry *e) {
 }
 
 static void taosLRUCacheShardLRURemove(SLRUCacheShard *shard, SLRUEntry *e) {
-  assert(e->next);
-  assert(e->prev);
+  ASSERT(e->next && e->prev);
 
   if (shard->lruLowPri == e) {
     shard->lruLowPri = e->prev;
@@ -287,10 +285,10 @@ static void taosLRUCacheShardLRURemove(SLRUCacheShard *shard, SLRUEntry *e) {
   e->prev->next = e->next;
   e->prev = e->next = NULL;
 
-  assert(shard->lruUsage >= e->totalCharge);
+  ASSERT(shard->lruUsage >= e->totalCharge);
   shard->lruUsage -= e->totalCharge;
   if (TAOS_LRU_ENTRY_IN_HIGH_POOL(e)) {
-    assert(shard->highPriPoolUsage >= e->totalCharge);
+    ASSERT(shard->highPriPoolUsage >= e->totalCharge);
     shard->highPriPoolUsage -= e->totalCharge;
   }
 }
@@ -298,13 +296,13 @@ static void taosLRUCacheShardLRURemove(SLRUCacheShard *shard, SLRUEntry *e) {
 static void taosLRUCacheShardEvictLRU(SLRUCacheShard *shard, size_t charge, SArray *deleted) {
   while (shard->usage + charge > shard->capacity && shard->lru.next != &shard->lru) {
     SLRUEntry *old = shard->lru.next;
-    assert(TAOS_LRU_ENTRY_IN_CACHE(old) && !TAOS_LRU_ENTRY_HAS_REFS(old));
+    ASSERT(TAOS_LRU_ENTRY_IN_CACHE(old) && !TAOS_LRU_ENTRY_HAS_REFS(old));
 
     taosLRUCacheShardLRURemove(shard, old);
     taosLRUEntryTableRemove(&shard->table, old->keyData, old->keyLength, old->hash);
 
     TAOS_LRU_ENTRY_SET_IN_CACHE(old, false);
-    assert(shard->usage >= old->totalCharge);
+    ASSERT(shard->usage >= old->totalCharge);
     shard->usage -= old->totalCharge;
 
     taosArrayPush(deleted, &old);
@@ -391,11 +389,11 @@ static LRUStatus taosLRUCacheShardInsertEntry(SLRUCacheShard *shard, SLRUEntry *
     if (old != NULL) {
       status = TAOS_LRU_STATUS_OK_OVERWRITTEN;
 
-      assert(TAOS_LRU_ENTRY_IN_CACHE(old));
+      ASSERT(TAOS_LRU_ENTRY_IN_CACHE(old));
       TAOS_LRU_ENTRY_SET_IN_CACHE(old, false);
       if (!TAOS_LRU_ENTRY_HAS_REFS(old)) {
         taosLRUCacheShardLRURemove(shard, old);
-        assert(shard->usage >= old->totalCharge);
+        ASSERT(shard->usage >= old->totalCharge);
         shard->usage -= old->totalCharge;
 
         taosArrayPush(lastReferenceList, &old);
@@ -455,7 +453,7 @@ static LRUHandle *taosLRUCacheShardLookup(SLRUCacheShard *shard, const void *key
   taosThreadMutexLock(&shard->mutex);
   e = taosLRUEntryTableLookup(&shard->table, key, keyLen, hash);
   if (e != NULL) {
-    assert(TAOS_LRU_ENTRY_IN_CACHE(e));
+    ASSERT(TAOS_LRU_ENTRY_IN_CACHE(e));
     if (!TAOS_LRU_ENTRY_HAS_REFS(e)) {
       taosLRUCacheShardLRURemove(shard, e);
     }
@@ -474,12 +472,12 @@ static void taosLRUCacheShardErase(SLRUCacheShard *shard, const void *key, size_
 
   SLRUEntry *e = taosLRUEntryTableRemove(&shard->table, key, keyLen, hash);
   if (e != NULL) {
-    assert(TAOS_LRU_ENTRY_IN_CACHE(e));
+    ASSERT(TAOS_LRU_ENTRY_IN_CACHE(e));
     TAOS_LRU_ENTRY_SET_IN_CACHE(e, false);
     if (!TAOS_LRU_ENTRY_HAS_REFS(e)) {
       taosLRUCacheShardLRURemove(shard, e);
 
-      assert(shard->usage >= e->totalCharge);
+      ASSERT(shard->usage >= e->totalCharge);
       shard->usage -= e->totalCharge;
       lastReference = true;
     }
@@ -499,11 +497,11 @@ static void taosLRUCacheShardEraseUnrefEntries(SLRUCacheShard *shard) {
 
   while (shard->lru.next != &shard->lru) {
     SLRUEntry *old = shard->lru.next;
-    assert(TAOS_LRU_ENTRY_IN_CACHE(old) && !TAOS_LRU_ENTRY_HAS_REFS(old));
+    ASSERT(TAOS_LRU_ENTRY_IN_CACHE(old) && !TAOS_LRU_ENTRY_HAS_REFS(old));
     taosLRUCacheShardLRURemove(shard, old);
     taosLRUEntryTableRemove(&shard->table, old->keyData, old->keyLength, old->hash);
     TAOS_LRU_ENTRY_SET_IN_CACHE(old, false);
-    assert(shard->usage >= old->totalCharge);
+    ASSERT(shard->usage >= old->totalCharge);
     shard->usage -= old->totalCharge;
 
     taosArrayPush(lastReferenceList, &old);
@@ -524,7 +522,7 @@ static bool taosLRUCacheShardRef(SLRUCacheShard *shard, LRUHandle *handle) {
   SLRUEntry *e = (SLRUEntry *)handle;
   taosThreadMutexLock(&shard->mutex);
 
-  assert(TAOS_LRU_ENTRY_HAS_REFS(e));
+  ASSERT(TAOS_LRU_ENTRY_HAS_REFS(e));
   TAOS_LRU_ENTRY_REF(e);
 
   taosThreadMutexUnlock(&shard->mutex);
@@ -545,7 +543,7 @@ static bool taosLRUCacheShardRelease(SLRUCacheShard *shard, LRUHandle *handle, b
   lastReference = taosLRUEntryUnref(e);
   if (lastReference && TAOS_LRU_ENTRY_IN_CACHE(e)) {
     if (shard->usage > shard->capacity || eraseIfLastRef) {
-      assert(shard->lru.next == &shard->lru || eraseIfLastRef);
+      ASSERT(shard->lru.next == &shard->lru || eraseIfLastRef);
 
       taosLRUEntryTableRemove(&shard->table, e->keyData, e->keyLength, e->hash);
       TAOS_LRU_ENTRY_SET_IN_CACHE(e, false);
@@ -557,7 +555,7 @@ static bool taosLRUCacheShardRelease(SLRUCacheShard *shard, LRUHandle *handle, b
   }
 
   if (lastReference && e->value) {
-    assert(shard->usage >= e->totalCharge);
+    ASSERT(shard->usage >= e->totalCharge);
     shard->usage -= e->totalCharge;
   }
 
@@ -595,7 +593,7 @@ static size_t taosLRUCacheShardGetPinnedUsage(SLRUCacheShard *shard) {
 
   taosThreadMutexLock(&shard->mutex);
 
-  assert(shard->usage >= shard->lruUsage);
+  ASSERT(shard->usage >= shard->lruUsage);
   usage = shard->usage - shard->lruUsage;
 
   taosThreadMutexUnlock(&shard->mutex);
@@ -687,7 +685,7 @@ void taosLRUCacheCleanup(SLRUCache *cache) {
   if (cache) {
     if (cache->shards) {
       int numShards = cache->numShards;
-      assert(numShards > 0);
+      ASSERT(numShards > 0);
       for (int i = 0; i < numShards; ++i) {
         taosLRUCacheShardCleanup(&cache->shards[i]);
       }
diff --git a/source/util/src/tsched.c b/source/util/src/tsched.c
index 467f26b362..5c1706e405 100644
--- a/source/util/src/tsched.c
+++ b/source/util/src/tsched.c
@@ -137,7 +137,6 @@ void *taosProcessSchedQueue(void *scheduler) {
   while (1) {
     if ((ret = tsem_wait(&pSched->fullSem)) != 0) {
       uFatal("wait %s fullSem failed(%s)", pSched->label, strerror(errno));
-      ASSERT(0);
     }
     if (atomic_load_8(&pSched->stop)) {
       break;
@@ -145,7 +144,6 @@ void *taosProcessSchedQueue(void *scheduler) {
 
     if ((ret = taosThreadMutexLock(&pSched->queueMutex)) != 0) {
       uFatal("lock %s queueMutex failed(%s)", pSched->label, strerror(errno));
-      ASSERT(0);
     }
 
     msg = pSched->queue[pSched->fullSlot];
@@ -154,12 +152,10 @@ void *taosProcessSchedQueue(void *scheduler) {
 
     if ((ret = taosThreadMutexUnlock(&pSched->queueMutex)) != 0) {
       uFatal("unlock %s queueMutex failed(%s)", pSched->label, strerror(errno));
-      ASSERT(0);
     }
 
     if ((ret = tsem_post(&pSched->emptySem)) != 0) {
       uFatal("post %s emptySem failed(%s)", pSched->label, strerror(errno));
-      ASSERT(0);
     }
 
     if (msg.fp)
@@ -187,12 +183,10 @@ int taosScheduleTask(void *queueScheduler, SSchedMsg *pMsg) {
 
   if ((ret = tsem_wait(&pSched->emptySem)) != 0) {
     uFatal("wait %s emptySem failed(%s)", pSched->label, strerror(errno));
-    ASSERT(0);
   }
 
   if ((ret = taosThreadMutexLock(&pSched->queueMutex)) != 0) {
     uFatal("lock %s queueMutex failed(%s)", pSched->label, strerror(errno));
-    ASSERT(0);
   }
 
   pSched->queue[pSched->emptySlot] = *pMsg;
@@ -200,12 +194,10 @@ int taosScheduleTask(void *queueScheduler, SSchedMsg *pMsg) {
 
   if ((ret = taosThreadMutexUnlock(&pSched->queueMutex)) != 0) {
     uFatal("unlock %s queueMutex failed(%s)", pSched->label, strerror(errno));
-    ASSERT(0);
   }
 
   if ((ret = tsem_post(&pSched->fullSem)) != 0) {
     uFatal("post %s fullSem failed(%s)", pSched->label, strerror(errno));
-    ASSERT(0);
   }
   return ret;
 }
diff --git a/source/util/src/tsimplehash.c b/source/util/src/tsimplehash.c
index ec1991923f..4c7983a983 100644
--- a/source/util/src/tsimplehash.c
+++ b/source/util/src/tsimplehash.c
@@ -361,10 +361,6 @@ int32_t tSimpleHashIterateRemove(SSHashObj *pHashObj, const void *key, size_t ke
   return TSDB_CODE_SUCCESS;
 }
 
-static void destroyItems(void* pItem) {
-  taosMemoryFree(*(void**)pItem);
-}
-
 void tSimpleHashClear(SSHashObj *pHashObj) {
   if (!pHashObj || taosHashTableEmpty(pHashObj)) {
     return;
diff --git a/source/util/src/tskiplist.c b/source/util/src/tskiplist.c
index c72c5c70ae..222e0e8a51 100644
--- a/source/util/src/tskiplist.c
+++ b/source/util/src/tskiplist.c
@@ -268,8 +268,9 @@ SSkipListIterator *tSkipListCreateIter(SSkipList *pSkipList) {
 }
 
 SSkipListIterator *tSkipListCreateIterFromVal(SSkipList *pSkipList, const char *val, int32_t type, int32_t order) {
-  ASSERT(order == TSDB_ORDER_ASC || order == TSDB_ORDER_DESC);
-  ASSERT(pSkipList != NULL);
+  if (order != TSDB_ORDER_ASC && order != TSDB_ORDER_DESC) {
+    return NULL;
+  }
 
   SSkipListIterator *iter = doCreateSkipListIterator(pSkipList, order);
   if (val == NULL) {
@@ -585,7 +586,6 @@ static FORCE_INLINE int32_t getSkipListRandLevel(SSkipList *pSkipList) {
     }
   }
 
-  ASSERT(level <= pSkipList->maxLevel);
   return level;
 }
 
diff --git a/test1 b/test1
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/json/rest_auto_create_table.json b/tests/develop-test/5-taos-tools/taosbenchmark/json/rest_auto_create_table.json
index 9b99521f52..078688bb7e 100644
--- a/tests/develop-test/5-taos-tools/taosbenchmark/json/rest_auto_create_table.json
+++ b/tests/develop-test/5-taos-tools/taosbenchmark/json/rest_auto_create_table.json
@@ -11,6 +11,7 @@
   "confirm_parameter_prompt": "no",
   "prepared_rand": 100,
   "chinese": "no",
+  "escape_character": "yes",
   "insert_interval": 0,
   "num_of_records_per_req": 10,
   "databases": [{
@@ -29,7 +30,6 @@
       "child_table_exists":"no",
       "childtable_count": 8,
       "childtable_prefix": "stb_",
-      "escape_character": "yes",
       "auto_create_table": "yes",
       "batch_create_tbl_num": 10,
       "data_source": "rand",
@@ -54,7 +54,6 @@
       "child_table_exists":"no",
       "childtable_count": 8,
       "childtable_prefix": "stb3-2_",
-      "escape_character": "yes",
       "auto_create_table": "yes",
       "batch_create_tbl_num": 10,
       "data_source": "rand",
diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_auto_create_table.json b/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_auto_create_table.json
index 7b87919a6d..e808c9d3f3 100644
--- a/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_auto_create_table.json
+++ b/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_auto_create_table.json
@@ -11,6 +11,7 @@
   "confirm_parameter_prompt": "no",
   "prepared_rand": 100,
   "chinese": "no",
+  "escape_character": "yes",
   "insert_interval": 0,
   "num_of_records_per_req": 10,
   "databases": [{
@@ -29,7 +30,6 @@
       "child_table_exists":"no",
       "childtable_count": 8,
       "childtable_prefix": "stb_",
-      "escape_character": "yes",
       "auto_create_table": "yes",
       "batch_create_tbl_num": 10,
       "data_source": "rand",
@@ -54,7 +54,6 @@
       "child_table_exists":"no",
       "childtable_count": 8,
       "childtable_prefix": "stb4-2_",
-      "escape_character": "yes",
       "auto_create_table": "yes",
       "batch_create_tbl_num": 10,
       "data_source": "rand",
diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/json/stmt_auto_create_table.json b/tests/develop-test/5-taos-tools/taosbenchmark/json/stmt_auto_create_table.json
index baf0384e46..0054d985ee 100644
--- a/tests/develop-test/5-taos-tools/taosbenchmark/json/stmt_auto_create_table.json
+++ b/tests/develop-test/5-taos-tools/taosbenchmark/json/stmt_auto_create_table.json
@@ -11,6 +11,7 @@
   "confirm_parameter_prompt": "no",
   "prepared_rand": 100,
   "chinese": "no",
+  "escape_character": "yes",
   "insert_interval": 0,
   "num_of_records_per_req": 10,
   "databases": [{
@@ -29,7 +30,6 @@
       "child_table_exists":"no",
       "childtable_count": 8,
       "childtable_prefix": "stb_",
-      "escape_character": "yes",
       "auto_create_table": "yes",
       "batch_create_tbl_num": 10,
       "data_source": "rand",
@@ -54,7 +54,6 @@
       "child_table_exists":"no",
       "childtable_count": 8,
       "childtable_prefix": "stb2-2_",
-      "escape_character": "yes",
       "auto_create_table": "yes",
       "batch_create_tbl_num": 10,
       "data_source": "rand",
diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_auto_create_table.json b/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_auto_create_table.json
index f683cc016b..bed3598bfe 100644
--- a/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_auto_create_table.json
+++ b/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_auto_create_table.json
@@ -11,6 +11,7 @@
   "confirm_parameter_prompt": "no",
   "prepared_rand": 100,
   "chinese": "no",
+  "escape_character": "yes",
   "insert_interval": 0,
   "num_of_records_per_req": 10,
   "databases": [{
@@ -29,7 +30,6 @@
       "child_table_exists":"no",
       "childtable_count": 8,
       "childtable_prefix": "stb_",
-      "escape_character": "yes",
       "auto_create_table": "yes",
       "batch_create_tbl_num": 10,
       "data_source": "rand",
@@ -55,7 +55,6 @@
       "child_table_exists":"no",
       "childtable_count": 8,
       "childtable_prefix": "stb1-2_",
-      "escape_character": "yes",
       "auto_create_table": "yes",
       "batch_create_tbl_num": 10,
       "data_source": "rand",
diff --git a/tests/parallel_test/cases.task b/tests/parallel_test/cases.task
index dda4ec3e84..4065ac5bee 100644
--- a/tests/parallel_test/cases.task
+++ b/tests/parallel_test/cases.task
@@ -51,6 +51,16 @@
 ,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/nestedQuery_math.py -Q 3
 ,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/nestedQuery_time.py -Q 3
 ,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/nestedQuery_26.py -Q 3
+,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/select_null.py
+,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/select_null.py -R
+,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/select_null.py -Q 2
+,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/select_null.py -Q 3
+,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/select_null.py -Q 4
+,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/slimit.py
+,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/slimit.py -R
+,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/slimit.py -Q 2
+,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/slimit.py -Q 3
+,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/slimit.py -Q 4
 
 ,,y,system-test,./pytest.sh python3 ./test.py -f 7-tmq/create_wrong_topic.py
 ,,y,system-test,./pytest.sh python3 ./test.py -f 7-tmq/dropDbR3ConflictTransaction.py -N 3
@@ -126,12 +136,15 @@
 ,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/sysinfo.py
 ,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/user_control.py
 ,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/user_manage.py
+,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/user_privilege.py
 ,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/fsync.py
+,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/multilevel.py
 ,,n,system-test,python3 ./test.py -f 0-others/compatibility.py
 ,,n,system-test,python3 ./test.py -f 0-others/tag_index_basic.py
 ,,n,system-test,python3 ./test.py -f 0-others/udfpy_main.py
 ,,n,system-test,python3 ./test.py -N 3 -f 0-others/walRetention.py
 ,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/alter_database.py
+,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/alter_replica.py -N 3
 ,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/influxdb_line_taosc_insert.py
 ,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/opentsdb_telnet_line_taosc_insert.py
 ,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/opentsdb_json_taosc_insert.py
@@ -337,6 +350,7 @@
 ,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/tb_100w_data_order.py
 ,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/delete_childtable.py
 ,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/delete_normaltable.py
+,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/delete_systable.py
 ,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/keep_expired.py
 ,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/drop.py
 ,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/drop.py -N 3 -M 3 -i False -n 3
@@ -722,6 +736,7 @@
 ,,y,script,./test.sh -f tsim/user/privilege_db.sim
 ,,y,script,./test.sh -f tsim/user/privilege_sysinfo.sim
 ,,y,script,./test.sh -f tsim/user/privilege_topic.sim
+,,y,script,./test.sh -f tsim/user/privilege_table.sim
 ,,y,script,./test.sh -f tsim/db/alter_option.sim
 ,,y,script,./test.sh -f tsim/db/alter_replica_31.sim
 ,,y,script,./test.sh -f tsim/db/basic1.sim
@@ -746,6 +761,7 @@
 ,,y,script,./test.sh -f tsim/db/show_create_table.sim
 ,,y,script,./test.sh -f tsim/db/tables.sim
 ,,y,script,./test.sh -f tsim/db/taosdlog.sim
+,,y,script,./test.sh -f tsim/db/table_prefix_suffix.sim
 ,,y,script,./test.sh -f tsim/dnode/balance_replica1.sim
 ,,y,script,./test.sh -f tsim/dnode/balance_replica3.sim
 ,,y,script,./test.sh -f tsim/dnode/balance1.sim
diff --git a/tests/parallel_test/run.sh b/tests/parallel_test/run.sh
index de343752c6..f05e0dfc83 100755
--- a/tests/parallel_test/run.sh
+++ b/tests/parallel_test/run.sh
@@ -303,7 +303,7 @@ function run_thread() {
             if [ ! -z "$corefile" ]; then
                 echo -e "\e[34m corefiles: $corefile \e[0m"
                 local build_dir=$log_dir/build_${hosts[index]}
-                local remote_build_dir="${workdirs[index]}/{DEBUGPATH}/build"
+                local remote_build_dir="${workdirs[index]}/${DEBUGPATH}/build"
                 # if [ $ent -ne 0 ]; then
                 #     remote_build_dir="${workdirs[index]}/{DEBUGPATH}/build"
                 # fi
diff --git a/tests/parallel_test/run_case.sh b/tests/parallel_test/run_case.sh
index ffc23ba6d2..2d736e1414 100755
--- a/tests/parallel_test/run_case.sh
+++ b/tests/parallel_test/run_case.sh
@@ -79,7 +79,7 @@ md5sum /home/TDinternal/debug/build/lib/libtaos.so
 #define taospy 2.7.6
 pip3 list|grep taospy
 pip3 uninstall taospy -y
-pip3 install taospy==2.7.6
+pip3 install  --default-timeout=120 taospy==2.7.6 
 
 $TIMEOUT_CMD $cmd
 RET=$?
diff --git a/tests/pytest/auto_crash_gen.py b/tests/pytest/auto_crash_gen.py
index 56629ede13..00e1786399 100755
--- a/tests/pytest/auto_crash_gen.py
+++ b/tests/pytest/auto_crash_gen.py
@@ -1,3 +1,4 @@
+import datetime
 import os
 import socket
 import requests
@@ -238,17 +239,7 @@ def start_taosd():
     start_cmd = 'cd %s && python3 test.py >>/dev/null '%(start_path)
     os.system(start_cmd)
 
-def get_cmds(args_list):
-    # build_path = get_path()
-    # if repo == "community":
-    #     crash_gen_path = build_path[:-5]+"community/tests/pytest/"
-    # elif repo == "TDengine":
-    #     crash_gen_path = build_path[:-5]+"/tests/pytest/"
-    # else:
-    #     pass
-
-    # crash_gen_cmd = 'cd %s && ./crash_gen.sh --valgrind -p -t 10 -s 1000 -g 0x32c,0x32d,0x3d3,0x18,0x2501,0x369,0x388,0x061a,0x2550  '%(crash_gen_path)
-
+def get_cmds(args_list):    
     crash_gen_cmd = get_auto_mix_cmds(args_list,valgrind=valgrind_mode)
     return crash_gen_cmd
 
@@ -295,7 +286,7 @@ def check_status():
     elif "Crash_Gen is now exiting with status code: 0" in run_code:
         return 0
     else:
-        return 2 
+        return 2
 
 
 def main():
@@ -310,7 +301,7 @@ def main():
 
 
     build_path = get_path()
-    os.system("pip install git+https://github.com/taosdata/taos-connector-python.git")
+        
     if repo =="community":
         crash_gen_path = build_path[:-5]+"community/tests/pytest/"
     elif repo =="TDengine":
@@ -334,7 +325,9 @@ def main():
     if not os.path.exists(run_dir):
         os.mkdir(run_dir)
     print(crash_cmds)
+    starttime = datetime.datetime.now()
     run_crash_gen(crash_cmds)
+    endtime = datetime.datetime.now()
     status = check_status()
     
     print("exit status : ", status)
@@ -349,7 +342,29 @@ def main():
         print('======== crash_gen run sucess and exit as expected ========')
 
     try:
-        text = f"crash_gen instance exit status of docker [ {hostname} ] is : {msg_dict[status]}\n  " + f" and git commit :  {git_commit}"
+        cmd = crash_cmds.split('&')[2]
+        if status == 0:
+            log_dir = "none"            
+        else:
+            log_dir= "/root/pxiao/crash_gen_logs" 
+        
+        if status == 3:
+            core_dir = "/root/pxiao/crash_gen_logs"
+        else:
+            core_dir = "none"
+            
+        text = f'''
+        exit status: {msg_dict[status]}
+        test scope: crash_gen
+        owner: pxiao
+        hostname: {hostname}
+        start time: {starttime}
+        end time: {endtime}
+        git commit :  {git_commit}
+        log dir: {log_dir}
+        core dir: {core_dir}
+        cmd: {cmd}'''
+                
         send_msg(get_msg(text))  
     except Exception as e:
         print("exception:", e)
diff --git a/tests/pytest/auto_crash_gen_valgrind.py b/tests/pytest/auto_crash_gen_valgrind.py
index 22fc5a480f..e37cda0a27 100755
--- a/tests/pytest/auto_crash_gen_valgrind.py
+++ b/tests/pytest/auto_crash_gen_valgrind.py
@@ -1,6 +1,7 @@
 #!/usr/bin/python3
 
 
+import datetime
 import os
 import socket
 import requests
@@ -241,15 +242,6 @@ def start_taosd():
     os.system(start_cmd +">>/dev/null")
 
 def get_cmds(args_list):
-    # build_path = get_path()
-    # if repo == "community":
-    #     crash_gen_path = build_path[:-5]+"community/tests/pytest/"
-    # elif repo == "TDengine":
-    #     crash_gen_path = build_path[:-5]+"/tests/pytest/"
-    # else:
-    #     pass
-
-    # crash_gen_cmd = 'cd %s && ./crash_gen.sh --valgrind -p -t 10 -s 1000 -g 0x32c,0x32d,0x3d3,0x18,0x2501,0x369,0x388,0x061a,0x2550  '%(crash_gen_path)
 
     crash_gen_cmd = get_auto_mix_cmds(args_list,valgrind=valgrind_mode)
     return crash_gen_cmd
@@ -343,7 +335,6 @@ def main():
     args = limits(args)
 
     build_path = get_path()
-    os.system("pip install git+https://github.com/taosdata/taos-connector-python.git >>/dev/null")
     if repo =="community":
         crash_gen_path = build_path[:-5]+"community/tests/pytest/"
     elif repo =="TDengine":
@@ -368,7 +359,9 @@ def main():
     if not os.path.exists(run_dir):
         os.mkdir(run_dir)
     print(crash_cmds)
+    starttime = datetime.datetime.now()
     run_crash_gen(crash_cmds)
+    endtime = datetime.datetime.now()
     status = check_status()
     # back_path = os.path.join(core_path,"valgrind_report")
     
@@ -384,8 +377,30 @@ def main():
         print('======== crash_gen run sucess and exit as expected ========')
 
     try:
-        text = f"crash_gen instance exit status of docker [ {hostname} ] is : {msg_dict[status]}\n  " + f" and git commit : {git_commit}"
-        send_msg(get_msg(text))  
+        cmd = crash_cmds.split('&')[2]
+        if status == 0:
+            log_dir = "none"            
+        else:
+            log_dir= "/root/pxiao/crash_gen_logs" 
+        
+        if status == 3:
+            core_dir = "/root/pxiao/crash_gen_logs"
+        else:
+            core_dir = "none"
+            
+        text = f'''
+        exit status: {msg_dict[status]}
+        test scope: crash_gen
+        owner: pxiao
+        hostname: {hostname}
+        start time: {starttime}
+        end time: {endtime}
+        git commit :  {git_commit}
+        log dir: {log_dir}
+        core dir: {core_dir}
+        cmd: {cmd}'''
+        
+        send_msg(get_msg(text))
     except Exception as e:
         print("exception:", e)
     exit(status)
diff --git a/tests/pytest/auto_crash_gen_valgrind_cluster.py b/tests/pytest/auto_crash_gen_valgrind_cluster.py
index 547de9af47..af19836a83 100755
--- a/tests/pytest/auto_crash_gen_valgrind_cluster.py
+++ b/tests/pytest/auto_crash_gen_valgrind_cluster.py
@@ -1,6 +1,7 @@
 #!/usr/bin/python3
 
 
+import datetime
 import os
 import socket
 import requests
@@ -241,16 +242,7 @@ def start_taosd():
     os.system(start_cmd +">>/dev/null")
 
 def get_cmds(args_list):
-    # build_path = get_path()
-    # if repo == "community":
-    #     crash_gen_path = build_path[:-5]+"community/tests/pytest/"
-    # elif repo == "TDengine":
-    #     crash_gen_path = build_path[:-5]+"/tests/pytest/"
-    # else:
-    #     pass
-
-    # crash_gen_cmd = 'cd %s && ./crash_gen.sh --valgrind -p -t 10 -s 1000 -g 0x32c,0x32d,0x3d3,0x18,0x2501,0x369,0x388,0x061a,0x2550  '%(crash_gen_path)
-
+    
     crash_gen_cmd = get_auto_mix_cmds(args_list,valgrind=valgrind_mode)
     return crash_gen_cmd
 
@@ -342,8 +334,7 @@ def main():
     args = random_args(args_list)
     args = limits(args)
 
-    build_path = get_path()
-    os.system("pip install git+https://github.com/taosdata/taos-connector-python.git >>/dev/null")
+    build_path = get_path()    
     if repo =="community":
         crash_gen_path = build_path[:-5]+"community/tests/pytest/"
     elif repo =="TDengine":
@@ -368,7 +359,9 @@ def main():
     if not os.path.exists(run_dir):
         os.mkdir(run_dir)
     print(crash_cmds)
+    starttime = datetime.datetime.now()
     run_crash_gen(crash_cmds)
+    endtime = datetime.datetime.now()
     status = check_status()
     # back_path = os.path.join(core_path,"valgrind_report")
     
@@ -384,7 +377,29 @@ def main():
         print('======== crash_gen run sucess and exit as expected ========')
 
     try:
-        text = f"crash_gen instance exit status of docker [ {hostname} ] is : {msg_dict[status]}\n  " + f" and git commit : {git_commit}"
+        cmd = crash_cmds.split('&')[2]
+        if status == 0:
+            log_dir = "none"            
+        else:
+            log_dir= "/root/pxiao/crash_gen_logs" 
+        
+        if status == 3:
+            core_dir = "/root/pxiao/crash_gen_logs"
+        else:
+            core_dir = "none"
+            
+        text = f'''
+        exit status: {msg_dict[status]}
+        test scope: crash_gen
+        owner: pxiao
+        hostname: {hostname}
+        start time: {starttime}
+        end time: {endtime}
+        git commit :  {git_commit}
+        log dir: {log_dir}
+        core dir: {core_dir}
+        cmd: {cmd}'''
+                
         send_msg(get_msg(text))  
     except Exception as e:
         print("exception:", e)
diff --git a/tests/pytest/util/cluster.py b/tests/pytest/util/cluster.py
index 2607cf63c2..a6e3530dc9 100644
--- a/tests/pytest/util/cluster.py
+++ b/tests/pytest/util/cluster.py
@@ -52,8 +52,9 @@ class ConfigureyCluster:
             dnode.addExtraCfg("secondEp", f"{hostname}:{startPort_sec}")
 
             # configure  dnoe of independent mnodes
-            if num <= self.mnodeNums and self.mnodeNums != 0 and independentMnode == True :
-                dnode.addExtraCfg("supportVnodes", 1024)
+            if num <= self.mnodeNums and self.mnodeNums != 0 and independentMnode == "True" :
+                tdLog.info("set mnode supportVnodes 0")
+                dnode.addExtraCfg("supportVnodes", 0)            
             # print(dnode)
             self.dnodes.append(dnode)
         return self.dnodes
@@ -71,6 +72,7 @@ class ConfigureyCluster:
         tdSql.init(conn.cursor())
         mnodeNums=int(mnodeNums)
         for i in range(2,mnodeNums+1):
+            tdLog.info("create mnode on dnode %d"%i)
             tdSql.execute(" create mnode on  dnode %d;"%i)
 
 
diff --git a/tests/script/tsim/alter/table.sim b/tests/script/tsim/alter/table.sim
index dccfc7f5d6..5f45b446ca 100644
--- a/tests/script/tsim/alter/table.sim
+++ b/tests/script/tsim/alter/table.sim
@@ -657,6 +657,34 @@ if $data20 != null then
   return -1
 endi
 
+print =============== error for normal table
+sql create table tb2023(ts timestamp, f int);
+sql_error alter table tb2023 add column v varchar(16375);
+sql_error alter table tb2023 add column v varchar(16385);
+sql_error alter table tb2023 add column v varchar(33100);
+sql alter table tb2023 add column v varchar(16374);
+sql_error alter table tb2023 modify column v varchar(16375);
+sql desc tb2023
+sql alter table tb2023 drop column v
+sql_error alter table tb2023 add column v nchar(4094);
+sql alter table tb2023 add column v nchar(4093);
+sql_error alter table tb2023 modify column v nchar(4094);
+sql desc tb2023
+
+print =============== error for super table
+sql create table stb2023(ts timestamp, f int) tags(t1 int);
+sql_error alter table stb2023 add column v varchar(16375);
+sql_error alter table stb2023 add column v varchar(16385);
+sql_error alter table stb2023 add column v varchar(33100);
+sql alter table stb2023 add column v varchar(16374);
+sql_error alter table stb2023 modify column v varchar(16375);
+sql desc stb2023
+sql alter table stb2023 drop column v
+sql_error alter table stb2023 add column v nchar(4094);
+sql alter table stb2023 add column v nchar(4093);
+sql_error alter table stb2023 modify column v nchar(4094);
+sql desc stb2023
+
 print ======= over
 sql drop database d1
 sql select * from information_schema.ins_databases
diff --git a/tests/script/tsim/db/error1.sim b/tests/script/tsim/db/error1.sim
index 32dbe826cc..64b17125aa 100644
--- a/tests/script/tsim/db/error1.sim
+++ b/tests/script/tsim/db/error1.sim
@@ -58,16 +58,16 @@ if $data23 != 0 then
   return -1
 endi
 
-print ========== stop dnode2
-system sh/exec.sh -n dnode2 -s stop -x SIGKILL
+#print ========== stop dnode2
+#system sh/exec.sh -n dnode2 -s stop -x SIGKILL
 
-sleep 1000
-print =============== drop database
-sql_error drop database d1
+#sleep 1000
+#print =============== drop database
+sql drop database d1
 
-print ========== start dnode2
-system sh/exec.sh -n dnode2 -s start
-sleep 1000
+#print ========== start dnode2
+#system sh/exec.sh -n dnode2 -s start
+#sleep 1000
 
 print =============== re-create database
 $x = 0
diff --git a/tests/script/tsim/db/table_prefix_suffix.sim b/tests/script/tsim/db/table_prefix_suffix.sim
new file mode 100644
index 0000000000..1b483d7df7
--- /dev/null
+++ b/tests/script/tsim/db/table_prefix_suffix.sim
@@ -0,0 +1,182 @@
+system sh/stop_dnodes.sh
+system sh/deploy.sh -n dnode1 -i 1
+system sh/exec.sh -n dnode1 -s start
+sql connect
+
+sql drop database if exists db1;
+sql create database db1 vgroups 5 TABLE_PREFIX 1 TABLE_SUFFIX 2;
+sql use db1;
+sql create table atb1aa (ts timestamp, f1 int);
+sql create table btb1bb (ts timestamp, f1 int);
+sql create table ctb1cc (ts timestamp, f1 int);
+sql create table dtb1dd (ts timestamp, f1 int);
+sql create table atb2aa (ts timestamp, f1 int);
+sql create table btb2bb (ts timestamp, f1 int);
+sql create table ctb2cc (ts timestamp, f1 int);
+sql create table dtb2dd (ts timestamp, f1 int);
+sql create table etb2ee (ts timestamp, f1 int);
+sql show create database db1;
+sql select count(*) a from information_schema.ins_tables where db_name='db1' group by vgroup_id having(count(*) > 0) order by a;
+if $rows != 2 then
+  return -1
+endi
+if $data00 != 4 then
+  return -1
+endi
+if $data10 != 5 then
+  return -1
+endi
+sql drop database if exists db1;
+ 
+sql drop database if exists db2;
+sql create database db2 vgroups 5 TABLE_PREFIX -1 TABLE_SUFFIX -2;
+sql use db2;
+sql create table taaa11 (ts timestamp, f1 int);
+sql create table tbbb11 (ts timestamp, f1 int);
+sql create table tccc11 (ts timestamp, f1 int);
+sql create table tddd11 (ts timestamp, f1 int);
+sql create table taaa22 (ts timestamp, f1 int);
+sql create table tbbb22 (ts timestamp, f1 int);
+sql create table tccc22 (ts timestamp, f1 int);
+sql create table tddd22 (ts timestamp, f1 int);
+sql create table teee22 (ts timestamp, f1 int);
+sql show create database db2;
+sql select count(*) a from information_schema.ins_tables where db_name='db2' group by vgroup_id having(count(*) > 0) order by a;
+if $rows != 2 then
+  return -1
+endi
+if $data00 != 4 then
+  return -1
+endi
+if $data10 != 5 then
+  return -1
+endi
+sql drop database if exists db2;
+ 
+sql drop database if exists db3;
+sql create database db3 vgroups 5 TABLE_PREFIX -1;
+sql use db3;
+sql create table taaa11 (ts timestamp, f1 int);
+sql create table tbbb11 (ts timestamp, f1 int);
+sql create table tccc11 (ts timestamp, f1 int);
+sql create table tddd11 (ts timestamp, f1 int);
+sql create table zaaa22 (ts timestamp, f1 int);
+sql create table zbbb22 (ts timestamp, f1 int);
+sql create table zccc22 (ts timestamp, f1 int);
+sql create table zddd22 (ts timestamp, f1 int);
+sql create table zeee22 (ts timestamp, f1 int);
+sql show create database db3;
+sql select count(*) a from information_schema.ins_tables where db_name='db3' group by vgroup_id having(count(*) > 0) order by a;
+if $rows != 2 then
+  return -1
+endi
+if $data00 != 4 then
+  return -1
+endi
+if $data10 != 5 then
+  return -1
+endi
+sql drop database if exists db3;
+ 
+sql drop database if exists db4;
+sql create database db4 vgroups 5 TABLE_SUFFIX -2;
+sql use db4;
+sql create table taaa11 (ts timestamp, f1 int);
+sql create table tbbb11 (ts timestamp, f1 int);
+sql create table tccc11 (ts timestamp, f1 int);
+sql create table tddd11 (ts timestamp, f1 int);
+sql create table zaaa22 (ts timestamp, f1 int);
+sql create table zbbb22 (ts timestamp, f1 int);
+sql create table zccc22 (ts timestamp, f1 int);
+sql create table zddd22 (ts timestamp, f1 int);
+sql create table zeee22 (ts timestamp, f1 int);
+sql show create database db4;
+sql select count(*) a from information_schema.ins_tables where db_name='db4' group by vgroup_id having(count(*) > 0) order by a;
+if $rows != 2 then
+  return -1
+endi
+if $data00 != 4 then
+  return -1
+endi
+if $data10 != 5 then
+  return -1
+endi
+sql drop database if exists db4;
+ 
+sql drop database if exists db5;
+sql create database db5 vgroups 5 TABLE_PREFIX 1;
+sql use db5;
+sql create table taaa11 (ts timestamp, f1 int);
+sql create table baaa11 (ts timestamp, f1 int);
+sql create table caaa11 (ts timestamp, f1 int);
+sql create table daaa11 (ts timestamp, f1 int);
+sql create table faaa11 (ts timestamp, f1 int);
+sql create table gbbb11 (ts timestamp, f1 int);
+sql create table hbbb11 (ts timestamp, f1 int);
+sql create table ibbb11 (ts timestamp, f1 int);
+sql create table jbbb11 (ts timestamp, f1 int);
+sql show create database db5;
+sql select count(*) a from information_schema.ins_tables where db_name='db5' group by vgroup_id having(count(*) > 0) order by a;
+if $rows != 2 then
+  return -1
+endi
+if $data00 != 4 then
+  return -1
+endi
+if $data10 != 5 then
+  return -1
+endi
+sql drop database if exists db5;
+ 
+sql drop database if exists db6;
+sql create database db6 vgroups 5 TABLE_SUFFIX 2;
+sql use db6;
+sql create table taaa11 (ts timestamp, f1 int);
+sql create table taaa12 (ts timestamp, f1 int);
+sql create table taaa13 (ts timestamp, f1 int);
+sql create table taaa14 (ts timestamp, f1 int);
+sql create table tbbb23 (ts timestamp, f1 int);
+sql create table tbbb24 (ts timestamp, f1 int);
+sql create table tbbb31 (ts timestamp, f1 int);
+sql create table tbbb32 (ts timestamp, f1 int);
+sql create table tbbb33 (ts timestamp, f1 int);
+sql show create database db6;
+sql select count(*) a from information_schema.ins_tables where db_name='db6' group by vgroup_id having(count(*) > 0) order by a;
+if $rows != 2 then
+  return -1
+endi
+if $data00 != 4 then
+  return -1
+endi
+if $data10 != 5 then
+  return -1
+endi
+sql drop database if exists db6;
+ 
+sql drop database if exists db7;
+sql create database db7 vgroups 5 TABLE_PREFIX -100 TABLE_SUFFIX -92;
+sql use db7;
+sql create table taaa11 (ts timestamp, f1 int);
+sql create table taaa12 (ts timestamp, f1 int);
+sql create table taaa13 (ts timestamp, f1 int);
+sql create table tbbb21 (ts timestamp, f1 int);
+sql create table tbbb22 (ts timestamp, f1 int);
+sql create table tbbb23 (ts timestamp, f1 int);
+sql create table tbbb24 (ts timestamp, f1 int);
+sql create table tccc31 (ts timestamp, f1 int);
+sql create table tccc32 (ts timestamp, f1 int);
+sql create table tccc33 (ts timestamp, f1 int);
+sql create table tddd24 (ts timestamp, f1 int);
+sql create table tddd31 (ts timestamp, f1 int);
+sql create table tddd32 (ts timestamp, f1 int);
+sql create table tddd33 (ts timestamp, f1 int);
+sql show create database db7;
+sql select count(*) a from information_schema.ins_tables where db_name='db7' group by vgroup_id having(count(*) > 0) order by a;
+sql drop database if exists db7;
+
+sql_error create database db8 vgroups 5 TABLE_PREFIX -1 TABLE_SUFFIX 2;
+sql_error create database db8 vgroups 5 TABLE_PREFIX 191 TABLE_SUFFIX 192;
+sql_error create database db8 vgroups 5 TABLE_PREFIX -192 TABLE_SUFFIX -191;
+sql_error create database db8 vgroups 5 TABLE_PREFIX 100 TABLE_SUFFIX 92;
+
+system sh/exec.sh -n dnode1 -s stop -x SIGINT
diff --git a/tests/script/tsim/parser/alter_column.sim b/tests/script/tsim/parser/alter_column.sim
index c70a604c73..d569e47735 100644
--- a/tests/script/tsim/parser/alter_column.sim
+++ b/tests/script/tsim/parser/alter_column.sim
@@ -48,7 +48,7 @@ sql_error alter table tb modify column c2 binary(10);
 sql_error alter table tb modify column c2 binary(9);
 sql_error alter table tb modify column c2 binary(-9);
 sql_error alter table tb modify column c2 binary(0);
-sql alter table tb modify column c2 binary(17000);
+sql_error alter table tb modify column c2 binary(17000);
 sql_error alter table tb modify column c2 nchar(30);
 sql_error alter table tb modify column c3 double;
 sql_error alter table tb modify column c3 nchar(10);
diff --git a/tests/script/tsim/query/sys_tbname.sim b/tests/script/tsim/query/sys_tbname.sim
index c676f2b1e0..849aeb2ac5 100644
--- a/tests/script/tsim/query/sys_tbname.sim
+++ b/tests/script/tsim/query/sys_tbname.sim
@@ -109,5 +109,26 @@ if $rows != 5000 then
         return -1
 endi
 
+sql create database d1;
+sql create stable d1.st1 (ts timestamp, f int) tags(t int);
+sql create stable d1.st2 (ts timestamp, f int) tags(t int);
+sql create table d1.ct1 using d1.st1 tags(1);
+sql create table d1.ct2 using d1.st2 tags(2);
 
+sql create database d2;
+sql create stable d2.st1(ts timestamp, f int) tags(t int);
+sql create stable d2.st2(ts timestamp, f int) tags(t int);
+sql create table d2.ct1 using d2.st1 tags(1);
+sql create table d2.ct2 using d2.st2 tags(2);
+
+sql create database d3;
+sql create stable d3.st1(ts timestamp, f int) tags(t int);
+sql create stable d3.st2(ts timestamp, f int) tags(t int);
+sql create table d3.ct1 using d3.st1 tags(1);
+sql create table d3.ct2 using d3.st2 tags(2);
+sql select count(*), stable_name, db_name from information_schema.ins_tables where db_name != 'd2' group by stable_name,db_name
+print $rows
+if $rows != 9 then
+  return -1
+endi
 #system sh/exec.sh -n dnode1 -s stop -x SIGINT
diff --git a/tests/script/tsim/tag/bigint.sim b/tests/script/tsim/tag/bigint.sim
index 26a5addf6a..34fcc09411 100644
--- a/tests/script/tsim/tag/bigint.sim
+++ b/tests/script/tsim/tag/bigint.sim
@@ -123,6 +123,17 @@ sql select * from $mt where tgcol = 1
 if $rows != 100 then
   return -1
 endi
+
+sql select * from $mt where tgcol = '1'
+if $rows != 100 then
+  return -1
+endi
+
+sql select * from $mt where tgcol = "1"
+if $rows != 100 then
+  return -1
+endi
+
 sql select * from $mt where tgcol <> 1
 if $rows != 100 then
   return -1
diff --git a/tests/script/tsim/tag/double.sim b/tests/script/tsim/tag/double.sim
index fbdf973337..acc026c13d 100644
--- a/tests/script/tsim/tag/double.sim
+++ b/tests/script/tsim/tag/double.sim
@@ -123,6 +123,15 @@ sql select * from $mt where tgcol = 1
 if $rows != 100 then
   return -1
 endi
+
+sql select * from $mt where tgcol = '1';
+if $rows != 100 then
+  return -1
+endi
+sql select * from $mt where tgcol = "1.0"
+if $rows != 100 then
+  return -1
+endi
 sql select * from $mt where tgcol <> 1
 if $rows != 100 then
   return -1
diff --git a/tests/script/tsim/tag/float.sim b/tests/script/tsim/tag/float.sim
index 10fac93d5d..f62feba057 100644
--- a/tests/script/tsim/tag/float.sim
+++ b/tests/script/tsim/tag/float.sim
@@ -123,6 +123,16 @@ sql select * from $mt where tgcol = 1
 if $rows != 100 then
   return -1
 endi
+
+sql select * from $mt where tgcol = "1.0"
+if $rows != 100 then
+  return -1
+endi
+
+sql select * from $mt where tgcol = "1"
+if $rows != 100 then
+  return -1
+endi
 sql select * from $mt where tgcol <> 1
 if $rows != 100 then
   return -1
diff --git a/tests/script/tsim/tag/int.sim b/tests/script/tsim/tag/int.sim
index ac8d31db3b..084b7e74d7 100644
--- a/tests/script/tsim/tag/int.sim
+++ b/tests/script/tsim/tag/int.sim
@@ -123,6 +123,16 @@ sql select * from $mt where tgcol = 1
 if $rows != 100 then
   return -1
 endi
+
+sql select * from $mt where tgcol = '1'
+if $rows != 100 then
+  return -1
+endi
+
+sql select * from $mt where tgcol = "1";
+if $rows != 100 then
+  return -1
+endi
 sql select * from $mt where tgcol <> 1
 if $rows != 100 then
   return -1
diff --git a/tests/script/tsim/tag/int_float.sim b/tests/script/tsim/tag/int_float.sim
index 009629aac9..3034f8b64e 100644
--- a/tests/script/tsim/tag/int_float.sim
+++ b/tests/script/tsim/tag/int_float.sim
@@ -85,10 +85,22 @@ sql select * from $mt where tgcol <> 1
 if $rows != 100 then
   return -1
 endi
+
 sql select * from $mt where tgcol = 1
 if $rows != 100 then
   return -1
 endi
+
+sql select * from $mt where tgcol = '1'
+if $rows != 100 then
+  return -1
+endi
+
+sql select * from $mt where tgcol = "1"
+if $rows != 100 then
+  return -1
+endi
+
 sql select * from $mt where tgcol <> 1
 if $rows != 100 then
   return -1
diff --git a/tests/script/tsim/tag/tinyint.sim b/tests/script/tsim/tag/tinyint.sim
index 8560def34c..89b0134bb3 100644
--- a/tests/script/tsim/tag/tinyint.sim
+++ b/tests/script/tsim/tag/tinyint.sim
@@ -115,14 +115,36 @@ sql select * from $mt where tgcol = 0
 if $rows != 100 then
   return -1
 endi
+
+sql select * from $mt where tgcol = '0'
+if $rows != 100 then
+  return -1
+endi
+
+sql select * from $mt where tgcol = "0"
+if $rows != 100 then
+  return -1
+endi
 sql select * from $mt where tgcol <> 0
 if $rows != 100 then
   return -1
 endi
+
 sql select * from $mt where tgcol = 1
 if $rows != 100 then
   return -1
 endi
+sql select * from $mt where tgcol = "1"
+if $rows != 100 then
+  return -1
+endi
+
+sql select * from $mt where tgcol = '1'
+if $rows != 100 then
+  return -1
+endi
+
+
 sql select * from $mt where tgcol <> 1
 if $rows != 100 then
   return -1
diff --git a/tests/script/tsim/user/privilege_table.sim b/tests/script/tsim/user/privilege_table.sim
new file mode 100644
index 0000000000..05f91ff5b0
--- /dev/null
+++ b/tests/script/tsim/user/privilege_table.sim
@@ -0,0 +1,302 @@
+system sh/stop_dnodes.sh
+system sh/deploy.sh -n dnode1 -i 1
+system sh/exec.sh -n dnode1 -s start
+sql connect
+
+print =============== init env
+sql drop database if exists test;
+sql create database test vgroups 1;
+sql use test;
+sql create stable st1(ts timestamp, i int) tags(id int, loc varchar(20));
+sql create table st1s1 using st1 tags(1, 'beijing');
+sql create table st1s2 using st1 tags(2, 'shanghai');
+sql insert into st1s1 values(now, 1) st1s2 values(now, 2);
+sql create stable st2(ts timestamp, i int) tags(id int, loc varchar(20));
+sql create table st2s1 using st2 tags(1, 'beijing');
+sql create table st2s2 using st2 tags(2, 'shanghai');
+sql insert into st2s1 values(now, 1) st2s2 values(now, 2);
+sql create user wxy pass 'taosdata';
+
+print =============== case 1: database unauthorized and table unauthorized
+sql close
+sql connect wxy
+
+sql reset query cache;
+sql_error select * from test.st1;
+sql_error insert into test.st1s1 values(now, 10) test.st1s2 values(now, 20);
+sql_error select * from test.st2; 
+sql_error insert into test.st2s1 values(now, 10) test.st2s2 values(now, 20);
+
+
+print =============== case 2: database unauthorized and table read privilege
+sql close
+sql connect
+
+sql grant read on test.st1 to wxy;
+
+sql close
+sql connect wxy
+
+sql reset query cache;
+sql select * from test.st1;
+if $rows != 2 then 
+  return -1
+endi
+sql_error insert into test.st1s1 values(now, 10) test.st1s2 values(now, 20);
+sql_error select * from test.st2; 
+sql_error insert into test.st2s1 values(now, 10) test.st2s2 values(now, 20);
+
+print =============== case 3: database unauthorized and table read privilege with condition
+sql close
+sql connect
+
+sql revoke read on test.st1 from wxy;
+sql grant read on test.st1 with id = 1 to wxy;
+
+sql close
+sql connect wxy
+
+sql reset query cache;
+sql select * from test.st1; 
+if $rows != 1 then 
+  return -1
+endi
+sql_error insert into test.st1s1 values(now, 10);
+sql_error insert into test.st1s2 values(now, 20);
+sql_error select * from test.st2; 
+sql_error insert into test.st2s1 values(now, 10) test.st2s2 values(now, 20);
+
+print =============== case 4: database unauthorized and table write privilege
+sql close
+sql connect
+
+sql revoke read on test.st1 with id = 1 from wxy;
+sql grant write on test.st1 to wxy;
+
+sql close
+sql connect wxy
+
+sql reset query cache;
+sql_error select tbname, * from test.st1; 
+sql insert into test.st1s1 values(now, 10);
+sql insert into test.st1s2 values(now, 20);
+sql_error select * from test.st2; 
+sql_error insert into test.st2s1 values(now, 10) test.st2s2 values(now, 20);
+
+print =============== case 5: database unauthorized and table write privilege with condition
+sql close
+sql connect
+
+sql revoke write on test.st1 from wxy;
+sql grant write on test.st1 with id = 1 to wxy;
+
+sql close
+sql connect wxy
+
+sql reset query cache;
+sql_error select tbname, * from test.st1; 
+sql insert into test.st1s1 values(now, 10);
+sql insert into test.st1s3 using test.st1 tags(1, 'dachang') values(now, 100);
+sql_error insert into test.st1s2 values(now, 20);
+sql_error insert into test.st1s4 using test.st1 tags(3, 'dachang') values(now, 300);
+sql_error select * from test.st2; 
+sql_error insert into test.st2s1 values(now, 10) test.st2s2 values(now, 20);
+
+print =============== case 6: database read privilege and table unauthorized
+sql close
+sql connect
+
+sql revoke write on test.st1 with id = 1 from wxy;
+sql grant read on test.* to wxy;
+
+sql close
+sql connect wxy
+
+sql reset query cache;
+sql select * from test.st1;
+if $rows != 6 then 
+  return -1
+endi
+sql_error insert into test.st1s1 values(now, 10) test.st1s2 values(now, 20);
+sql select * from test.st2; 
+if $rows != 2 then 
+  return -1
+endi
+sql_error insert into test.st2s1 values(now, 10) test.st2s2 values(now, 20);
+
+print =============== case 7: database read privilege and table read privilege
+sql close
+sql connect
+
+sql grant read on test.st1 to wxy;
+
+sql close
+sql connect wxy
+
+sql reset query cache;
+sql select * from test.st1; 
+if $rows != 6 then 
+  return -1
+endi
+sql_error insert into test.st1s1 values(now, 10) test.st1s2 values(now, 20);
+sql select * from test.st2; 
+if $rows != 2 then 
+  return -1
+endi
+sql_error insert into test.st2s1 values(now, 10) test.st2s2 values(now, 20);
+
+print =============== case 8: database read privilege and table read privilege with condition
+sql close
+sql connect
+
+sql revoke read on test.st1 from wxy;
+sql grant read on test.st1 with id = 1 to wxy;
+
+sql close
+sql connect wxy
+
+sql reset query cache;
+sql select * from test.st1; 
+if $rows != 4 then 
+  return -1
+endi
+sql_error insert into test.st1s1 values(now, 10) test.st1s2 values(now, 20);
+sql select * from test.st2; 
+if $rows != 2 then 
+  return -1
+endi
+sql_error insert into test.st2s1 values(now, 10) test.st2s2 values(now, 20);
+
+print =============== case 9: database read privilege and table write privilege
+sql close
+sql connect
+
+sql revoke read on test.st1 with id = 1 from wxy;
+sql grant write on test.st1 to wxy;
+
+sql close
+sql connect wxy
+
+sql reset query cache;
+sql select * from test.st1;
+if $rows != 6 then 
+  return -1
+endi
+sql insert into test.st1s1 values(now, 10) test.st1s2 values(now, 20);
+sql select * from test.st2;
+if $rows != 2 then 
+  return -1
+endi
+sql_error insert into test.st2s1 values(now, 10) test.st2s2 values(now, 20);
+
+print =============== case 10: database read privilege and table write privilege with condition
+sql close
+sql connect
+
+sql revoke write on test.st1 from wxy;
+sql grant write on test.st1 with id = 1 to wxy;
+
+sql close
+sql connect wxy
+
+sql reset query cache;
+sql select * from test.st1;
+if $rows != 8 then 
+  return -1
+endi
+sql insert into test.st1s1 values(now, 10);
+sql_error insert into test.st1s2 values(now, 20);
+sql select * from test.st2;
+if $rows != 2 then 
+  return -1
+endi
+sql_error insert into test.st2s1 values(now, 10) test.st2s2 values(now, 20);
+
+print =============== case 11: database write privilege and table unauthorized
+sql close
+sql connect
+
+sql revoke read on test.* from wxy;
+sql revoke write on test.st1 with id = 1 from wxy;
+sql grant write on test.* to wxy;
+
+sql close
+sql connect wxy
+
+sql reset query cache;
+sql_error select * from test.st1; 
+sql insert into test.st1s1 values(now, 10) test.st1s2 values(now, 20);
+sql_error select * from test.st2; 
+sql insert into test.st2s1 values(now, 10) test.st2s2 values(now, 20);
+
+print =============== case 12: database write privilege and table read privilege
+sql close
+sql connect
+
+sql grant read on test.st1 to wxy;
+
+sql close
+sql connect wxy
+
+sql reset query cache;
+sql select * from test.st1; 
+if $rows != 11 then 
+  return -1
+endi
+sql insert into test.st1s1 values(now, 10) test.st1s2 values(now, 20);
+sql_error select * from test.st2; 
+sql insert into test.st2s1 values(now, 10) test.st2s2 values(now, 20);
+
+print =============== case 13: database write privilege and table read privilege with condition
+sql close
+sql connect
+
+sql revoke read on test.st1 from wxy;
+sql grant read on test.st1 with id = 1 to wxy;
+
+sql close
+sql connect wxy
+
+sql reset query cache;
+sql select * from test.st1; 
+if $rows != 8 then 
+  return -1
+endi
+sql insert into test.st1s1 values(now, 10) test.st1s2 values(now, 20);
+sql_error select * from test.st2; 
+sql insert into test.st2s1 values(now, 10) test.st2s2 values(now, 20);
+
+print =============== case 14: database write privilege and table write privilege
+sql close
+sql connect
+
+sql revoke read on test.st1 with id = 1 from wxy;
+sql grant write on test.st1 to wxy;
+
+sql close
+sql connect wxy
+
+sql reset query cache;
+sql_error select * from test.st1; 
+sql insert into test.st1s1 values(now, 10) test.st1s2 values(now, 20);
+sql_error select * from test.st2; 
+sql insert into test.st2s1 values(now, 10) test.st2s2 values(now, 20);
+
+print =============== case 15: database write privilege and table write privilege with condition
+sql close
+sql connect
+
+sql revoke write on test.st1 from wxy;
+sql grant write on test.st1 with id = 1 to wxy;
+
+sql close
+sql connect wxy
+
+sql reset query cache;
+sql_error select * from test.st1; 
+sql insert into test.st1s1 values(now, 10);
+sql_error insert into test.st1s2 values(now, 20);
+sql_error select * from test.st2; 
+sql insert into test.st2s1 values(now, 10) test.st2s2 values(now, 20);
+
+system sh/exec.sh -n dnode1 -s stop -x SIGINT
diff --git a/tests/script/win-test-file b/tests/script/win-test-file
index 2d5a1b3108..3b358993fa 100644
--- a/tests/script/win-test-file
+++ b/tests/script/win-test-file
@@ -3,6 +3,7 @@
 ./test.sh -f tsim/user/privilege_db.sim
 ./test.sh -f tsim/user/privilege_sysinfo.sim
 ./test.sh -f tsim/user/privilege_topic.sim
+./test.sh -f tsim/user/privilege_table.sim
 ./test.sh -f tsim/db/alter_option.sim
 rem ./test.sh -f tsim/db/alter_replica_13.sim
 ./test.sh -f tsim/db/alter_replica_31.sim
diff --git a/tests/system-test/0-others/compatibility.py b/tests/system-test/0-others/compatibility.py
index 33d1dac4b5..22e319fdaf 100644
--- a/tests/system-test/0-others/compatibility.py
+++ b/tests/system-test/0-others/compatibility.py
@@ -17,12 +17,12 @@ from util.dnodes import TDDnode
 from util.cluster import *
 import subprocess
 
-BASEVERSION = "3.0.1.8"
+BASEVERSION = "3.0.2.3"
 class TDTestCase:
     def caseDescription(self):
-        '''
+        f'''
         3.0 data compatibility test 
-        case1: basedata version is 3.0.1.8
+        case1: basedata version is {BASEVERSION}
         '''
         return
 
diff --git a/tests/system-test/0-others/multilevel.py b/tests/system-test/0-others/multilevel.py
new file mode 100644
index 0000000000..7ad4eba645
--- /dev/null
+++ b/tests/system-test/0-others/multilevel.py
@@ -0,0 +1,263 @@
+###################################################################
+#           Copyright (c) 2016 by TAOS Technologies, Inc.
+#                     All rights reserved.
+#
+#  This file is proprietary and confidential to TAOS Technologies.
+#  No part of this file may be reproduced, stored, transmitted,
+#  disclosed or used in any form or by any means other than as
+#  expressly provided by the written permission from Jianhui Tao
+#
+###################################################################
+
+# -*- coding: utf-8 -*-
+
+
+from util.log import *
+from util.cases import *
+from util.sql import *
+from util.common import *
+from util.sqlset import *
+
+class TDTestCase:
+    def init(self, conn, logSql, replicaVar=1):
+
+        self.replicaVar = int(replicaVar)
+        tdLog.debug("start to execute %s" % __file__)
+        tdSql.init(conn.cursor())
+        self.setsql = TDSetSql()
+
+    def basic(self):
+        tdLog.info("============== basic test ===============")
+        cfg={
+            '/mnt/data1' : 'dataDir',
+            '/mnt/data2 0 0' : 'dataDir'
+        }
+        tdSql.createDir('/mnt/data1')
+        tdSql.createDir('/mnt/data2')
+
+        tdLog.info("================= step1")
+        tdDnodes.stop(1)
+        tdDnodes.deploy(1,cfg)
+        tdDnodes.start(1)
+        
+        tdLog.info("================= step2")
+        tdSql.haveFile('/mnt/data1/',1)
+        tdSql.haveFile('/mnt/data2/',0)
+        tdDnodes.stop(1)
+    def dir_not_exist(self):
+        tdLog.info("============== dir_not_exist test ===============")
+        cfg={
+            '/mnt/data1 0 0' : 'dataDir',
+            '/mnt/data2 0 0' : 'dataDir'
+        }
+        tdSql.createDir('/mnt/data1')
+        os.system('rm -rf /mnt/data2')
+        
+
+        tdLog.info("================= step1")
+        tdDnodes.deploy(1,cfg)
+        tdDnodes.startWithoutSleep(1)
+        
+        tdLog.info("================= step2")
+        tdSql.taosdStatus(0)
+
+    def dir_permission_denied(self):
+        tdDnodes.stop(1)
+        tdLog.info("============== dir_permission_denied test ===============")
+        cfg={
+            '/mnt/data1 0 0' : 'dataDir',
+            '/mnt/data2 0 0' : 'dataDir'
+        }
+        tdSql.createDir('/mnt/data1')
+        tdSql.createDir('/mnt/data2')
+        os.system('chmod 111 /mnt/data2')
+
+        tdLog.info("================= step1")
+        tdDnodes.deploy(1,cfg)
+        tdDnodes.startWithoutSleep(1)
+        
+        tdLog.info("================= step2")
+        tdSql.taosdStatus(0)
+    
+    def file_distribution_same_level(self):
+        tdLog.info("============== file_distribution_same_level test ===============")
+        dataDir = ['data00','data01','data02','data03','data04']
+        dataDict = {'data00':0,'data01':0,'data02':0,'data03':0,'data04':0}
+        tdDnodes.stop(1)
+        self.ntables = 1000             
+        self.ts = 1520000010000
+        tdLog.info("================= step1")
+        cfg={
+            '/mnt/data00 0 1' : 'dataDir',
+            '/mnt/data01 0 0' : 'dataDir',
+            '/mnt/data02 0 0' : 'dataDir',
+            '/mnt/data03 0 0' : 'dataDir',
+            '/mnt/data04 0 0' : 'dataDir'
+        }
+        dir_list = ['/mnt/data00','/mnt/data01','/mnt/data02','/mnt/data03','/mnt/data04']
+        for i in dir_list:
+            tdSql.createDir(i)
+        tdDnodes.deploy(1,cfg)
+        tdDnodes.start(1)
+
+        tdSql.execute("create database test duration 1")
+        tdSql.execute("use test")
+
+        tdSql.execute("create table stb(ts timestamp, c int) tags(t int)")
+
+        for i in range(self.ntables):
+            tdSql.execute("create table tb%d using stb tags(%d)" %(i, i))            
+            tdSql.execute("insert into tb%d values(%d, 1)" % (i,self.ts + int (i / 100) * 86400000))
+
+        tdLog.info("================= step2")
+        tdDnodes.stop(1)
+        tdDnodes.start(1)
+        tdSql.query("select * from test.stb")
+        tdSql.checkRows(1000)
+        tdLog.info("================= step3")
+        tdSql.execute('drop database test')
+        for i in range(50):
+            tdSql.execute("create database test%d duration 1" %(i))
+            tdSql.execute("use test%d" %(i))
+            tdSql.execute("create table tb (ts timestamp,i int)") 
+            for j in range(10):           
+                tdSql.execute("insert into tb values(%d, 1)" % (self.ts + int (i / 100) * 86400000))
+        tdDnodes.stop(1)
+        tdDnodes.start(1)
+        flag = True
+        for i in range(4):
+            if dataDict[dataDir[i]] == dataDict[dataDir[i+1]]:
+                flag = flag & True
+            else:
+                flag = flag & False
+                break
+        if not flag : tdLog.exit("%s failed, expect  not occured" % (sys.argv[0]))
+    
+    def three_level_basic(self):
+        tdLog.info("============== three_level_basic test ===============")
+        tdDnodes.stop(1)
+        # Test1 1 dataDir
+        cfg={
+            '/mnt/data000 0 1' : 'dataDir',
+            '/mnt/data001 0 0' : 'dataDir',
+            '/mnt/data002 0 0' : 'dataDir',
+            '/mnt/data010 1 0' : 'dataDir',
+            '/mnt/data011 1 0' : 'dataDir',
+            '/mnt/data012 1 0' : 'dataDir',
+            '/mnt/data020 2 0' : 'dataDir',
+            '/mnt/data021 2 0' : 'dataDir',
+            '/mnt/data022 2 0' : 'dataDir'          
+        }
+        dir_list = ['/mnt/data000','/mnt/data001','/mnt/data002','/mnt/data010','/mnt/data011','/mnt/data012','/mnt/data020','/mnt/data021''/mnt/data022']
+        for i in dir_list:
+            tdSql.createDir(i)
+        
+        tdDnodes.deploy(1,cfg)
+        tdDnodes.start(1)
+        for i in dir_list:
+            if i == '/mnt/data000':
+                tdSql.haveFile(i,1)
+            else:
+                tdSql.haveFile(i,0)
+    
+    def more_than_16_disks(self):
+        tdLog.info("============== more_than_16_disks test ===============")
+        cfg={}
+        for i in range(17):
+            if i == 0 :
+                datadir = '/mnt/data%d 0 1' % (i+1)
+            else:
+                datadir = '/mnt/data%d 0 0' % (i+1)
+            cfg.update({ datadir : 'dataDir' })
+            tdSql.createDir('/mnt/data%d' % (i+1))
+        
+        tdLog.info("================= step1")
+        tdDnodes.stop(1)
+        tdDnodes.deploy(1,cfg)
+        tdDnodes.startWithoutSleep(1)
+        
+        tdLog.info("================= step2")
+        tdSql.taosdStatus(0)
+    
+    def missing_middle_level(self):
+        tdLog.info("============== missing_middle_level test ===============")
+        tdDnodes.stop(1)
+        # Test1 1 dataDir
+        cfg={
+            '/mnt/data1 1 0' : 'dataDir'           
+        }
+        tdSql.createDir('/mnt/data1')
+        
+        tdDnodes.deploy(1,cfg)
+        tdDnodes.startWithoutSleep(1)
+        
+        tdSql.taosdStatus(0)
+        tdDnodes.stop(1)
+        # Test2 2 dataDir
+        cfg = {
+            '/mnt/data1 0 1' : 'dataDir',
+            '/mnt/data1 2 0' : 'dataDir'
+        }
+        tdSql.createDir('/mnt/data1')
+        
+        tdDnodes.deploy(1,cfg)
+        tdDnodes.startWithoutSleep(1)
+        
+        tdSql.taosdStatus(0)
+
+    def trim_database(self):
+        tdLog.info("============== trim_database test ===============")
+        tdDnodes.stop(1)
+        cfg = {
+            '/mnt/data1 0 1' : 'dataDir'
+            
+        }
+        tdSql.createDir('/mnt/data1')
+        tdDnodes.deploy(1,cfg)
+        tdDnodes.start(1)
+
+        tdSql.execute('create database dbtest')
+        tdSql.execute('use dbtest')
+        tdSql.execute('create table stb (ts timestamp,c0 int) tags(t0 int)')
+        tdSql.execute('create table tb1 using stb tags(1)')
+        for i in range(10,30):
+            tdSql.execute(f'insert into tb1 values(now-{i}d,10)')
+        tdSql.execute('flush database dbtest')
+        tdSql.haveFile('/mnt/data1/',1)
+        tdDnodes.stop(1)
+        cfg={
+            '/mnt/data1 0 1' : 'dataDir',
+            '/mnt/data2 1 0' : 'dataDir',
+            '/mnt/data3 2 0' : 'dataDir',        
+        }
+        tdSql.createDir('/mnt/data2')
+        tdSql.createDir('/mnt/data3')
+        tdDnodes.deploy(1,cfg)
+        tdDnodes.start(1)
+        tdSql.haveFile('/mnt/data1/',1)
+        tdSql.haveFile('/mnt/data2/',0)
+        tdSql.haveFile('/mnt/data3/',0)
+        tdSql.execute('alter database dbtest keep 10d,365d,3650d')
+        tdSql.execute('trim database dbtest')
+        time.sleep(3)
+        tdSql.haveFile('/mnt/data1/',1)
+        tdSql.haveFile('/mnt/data2/',1)
+
+    def run(self):
+        self.basic()
+        self.dir_not_exist()
+        self.dir_permission_denied()
+        self.file_distribution_same_level()
+        self.three_level_basic()
+        self.more_than_16_disks()
+        self.trim_database()
+        self.missing_middle_level()
+        
+
+
+    def stop(self):
+        tdSql.close()
+        tdLog.success("%s successfully executed" % __file__)
+
+tdCases.addWindows(__file__, TDTestCase())
+tdCases.addLinux(__file__, TDTestCase())
diff --git a/tests/system-test/0-others/user_privilege.py b/tests/system-test/0-others/user_privilege.py
new file mode 100644
index 0000000000..d1b93f6942
--- /dev/null
+++ b/tests/system-test/0-others/user_privilege.py
@@ -0,0 +1,144 @@
+###################################################################
+#           Copyright (c) 2016 by TAOS Technologies, Inc.
+#                     All rights reserved.
+#
+#  This file is proprietary and confidential to TAOS Technologies.
+#  No part of this file may be reproduced, stored, transmitted,
+#  disclosed or used in any form or by any means other than as
+#  expressly provided by the written permission from Jianhui Tao
+#
+###################################################################
+
+# -*- coding: utf-8 -*-
+
+import taos
+from taos.tmq import *
+from util.cases import *
+from util.common import *
+from util.log import *
+from util.sql import *
+from util.sqlset import *
+
+
+class TDTestCase:
+    def init(self, conn, logSql, replicaVar=1):
+        self.replicaVar = int(replicaVar)
+        tdLog.debug("start to execute %s" % __file__)
+        tdSql.init(conn.cursor())
+        self.setsql = TDSetSql()
+        self.stbname = 'stb'
+        self.binary_length = 20  # the length of binary for column_dict
+        self.nchar_length = 20  # the length of nchar for column_dict
+        self.dbnames = ['db1', 'db2']
+        self.column_dict = {
+            'ts': 'timestamp',
+            'col1': 'float',
+            'col2': 'int',
+            'col3': 'float',
+        }
+        
+        self.tag_dict = {
+            't1': 'int',
+            't2': f'binary({self.binary_length})'
+        }
+        
+        self.tag_list = [
+            f'1, "Beijing"',
+            f'2, "Shanghai"',
+            f'3, "Guangzhou"',
+            f'4, "Shenzhen"'
+        ]
+        
+        self.values_list = [
+            f'now, 9.1, 200, 0.3'            
+        ]
+        
+        self.tbnum = 4
+
+    def create_user(self):
+        user_name = 'test'        
+        tdSql.execute(f'create user {user_name} pass "test"')
+        tdSql.execute(f'grant read on {self.dbnames[0]}.{self.stbname} with t2 = "Beijing" to {user_name}')
+        tdSql.execute(f'grant write on {self.dbnames[1]}.{self.stbname} with t1 = 2 to {user_name}')
+                
+    def prepare_data(self):
+        for db in self.dbnames:
+            tdSql.execute(f"create database {db}")
+            tdSql.execute(f"use {db}")
+            tdSql.execute(self.setsql.set_create_stable_sql(self.stbname, self.column_dict, self.tag_dict))
+            for i in range(self.tbnum):
+                tdSql.execute(f'create table {self.stbname}_{i} using {self.stbname} tags({self.tag_list[i]})')
+                for j in self.values_list:
+                    tdSql.execute(f'insert into {self.stbname}_{i} values({j})')
+    
+    def user_read_privilege_check(self, dbname):
+        testconn = taos.connect(user='test', password='test')        
+        expectErrNotOccured = False
+        
+        try:
+            sql = f"select count(*) from {dbname}.stb where t2 = 'Beijing'"
+            res = testconn.query(sql)
+            data = res.fetch_all()
+            count = data[0][0]            
+        except BaseException:
+            expectErrNotOccured = True
+        
+        if expectErrNotOccured:
+            caller = inspect.getframeinfo(inspect.stack()[1][0])
+            tdLog.exit(f"{caller.filename}({caller.lineno}) failed: sql:{sql}, expect error not occured")
+        elif count != 1:
+            tdLog.exit(f"{sql}, expect result doesn't match")
+        pass
+    
+    def user_write_privilege_check(self, dbname):
+        testconn = taos.connect(user='test', password='test')        
+        expectErrNotOccured = False
+        
+        try:            
+            sql = f"insert into {dbname}.stb_1 values(now, 1.1, 200, 0.3)"
+            testconn.execute(sql)            
+        except BaseException:
+            expectErrNotOccured = True
+        
+        if expectErrNotOccured:
+            caller = inspect.getframeinfo(inspect.stack()[1][0])
+            tdLog.exit(f"{caller.filename}({caller.lineno}) failed: sql:{sql}, expect error not occured")
+        else:
+            pass
+    
+    def user_privilege_error_check(self):
+        testconn = taos.connect(user='test', password='test')        
+        expectErrNotOccured = False
+        
+        sql_list = [f"alter talbe {self.dbnames[0]}.stb_1 set t2 = 'Wuhan'", 
+                    f"insert into {self.dbnames[0]}.stb_1 values(now, 1.1, 200, 0.3)", 
+                    f"drop table {self.dbnames[0]}.stb_1", 
+                    f"select count(*) from {self.dbnames[1]}.stb"]
+        
+        for sql in sql_list:
+            try:
+                res = testconn.execute(sql)                        
+            except BaseException:
+                expectErrNotOccured = True
+            
+            if expectErrNotOccured:
+                pass
+            else:
+                caller = inspect.getframeinfo(inspect.stack()[1][0])
+                tdLog.exit(f"{caller.filename}({caller.lineno}) failed: sql:{sql}, expect error not occured")
+        pass
+
+    def run(self):           
+        self.prepare_data()
+        self.create_user()
+        self.user_read_privilege_check(self.dbnames[0])
+        self.user_write_privilege_check(self.dbnames[1])
+        self.user_privilege_error_check()
+                
+    def stop(self):
+        tdSql.close()
+        tdLog.success("%s successfully executed" % __file__)
+
+
+tdCases.addWindows(__file__, TDTestCase())
+tdCases.addLinux(__file__, TDTestCase())
\ No newline at end of file
diff --git a/tests/system-test/1-insert/alter_replica.py b/tests/system-test/1-insert/alter_replica.py
new file mode 100644
index 0000000000..900b64d943
--- /dev/null
+++ b/tests/system-test/1-insert/alter_replica.py
@@ -0,0 +1,114 @@
+import taos
+import sys
+import time
+import socket
+import os
+import threading
+import datetime
+
+from util.log import *
+from util.sql import *
+from util.cases import *
+from util.dnodes import *
+
+
+class TDTestCase:
+    def init(self, conn, logSql, replicaVar=1):
+        self.replicaVar = int(replicaVar)
+        tdLog.debug("start to execute %s" % __file__)
+        tdSql.init(conn.cursor(), logSql)        
+        
+    def checkVgroups(self, dbName, vgNum):
+        sleepNum = vgNum * 60
+        flag = 0
+        while (sleepNum > 0):
+            sql = f'show {dbName}.vgroups'
+            tdSql.query(sql)
+            flag = 0
+            for vgid in range (vgNum) :
+                v1_status = tdSql.queryResult[vgid][4]
+                v2_status = tdSql.queryResult[vgid][6]
+                v3_status = tdSql.queryResult[vgid][8]
+                if ((v1_status == 'leader') and (v2_status == 'follower') and (v3_status == 'follower')) \
+                or ((v2_status == 'leader') and (v1_status == 'follower') and (v3_status == 'follower')) \
+                or ((v3_status == 'leader') and (v2_status == 'follower') and (v1_status == 'follower')):
+                    continue
+                else: 
+                    sleepNum = sleepNum - 1
+                    time.sleep(1)
+                    flag = 1
+                    break
+            if (0 == flag):
+                return 0
+        tdLog.debug("vgroup[%d] status: %s, %s, %s" %(vgid,v1_status,v2_status,v3_status))
+        return -1
+        
+    def alter_replica(self):        
+        # create db and alter replica
+        tdLog.debug("====alter db repica 1====")
+        vgNum = 3
+        dbName = 'db1'
+        sql = f'create database {dbName} vgroups {vgNum}'
+        tdSql.execute(sql)
+        sql = f'alter database {dbName} replica 3'
+        tdSql.execute(sql)
+        tdLog.debug("start check time: %s"%(str(datetime.datetime.now())))
+        res = self.checkVgroups(dbName, vgNum)       
+        tdLog.debug("end   check time: %s"%(str(datetime.datetime.now())))
+        if (0 != res):
+            tdLog.exit(f'fail: alter database {dbName} replica 3') 
+        
+        # create db, stable, child tables, and insert data, then alter replica
+        tdLog.debug("====alter db repica 2====")
+        dbName = 'db2'
+        sql = f'create database {dbName} vgroups {vgNum}'
+        tdSql.execute(sql)        
+        sql = f'use {dbName}'
+        tdSql.execute(sql)
+        sql = f'create stable stb (ts timestamp, c int) tags (t int)'
+        tdSql.execute(sql)
+        sql = f'create table ctb using stb tags (1)'
+        tdSql.execute(sql)
+        sql = f'insert into ctb values (now, 1) (now+1s, 2) (now+2s, 3)'
+        tdSql.execute(sql)
+        sql = f'alter database {dbName} replica 3'
+        tdSql.execute(sql)
+        tdLog.debug("start check time: %s"%(str(datetime.datetime.now())))
+        res = self.checkVgroups(dbName, vgNum)
+        tdLog.debug("end   check time: %s"%(str(datetime.datetime.now())))
+        if (0 != res):
+            tdLog.exit(f'fail: alter database {dbName} replica 3')        
+        
+        # firstly create db, stable, child tables, and insert data, then drop stable, and then alter replica
+        tdLog.debug("====alter db repica 3====")
+        dbName = 'db3'
+        sql = f'create database {dbName} vgroups {vgNum}'
+        tdSql.execute(sql)
+        sql = f'use {dbName}'
+        tdSql.execute(sql)
+        sql = f'create stable stb (ts timestamp, c int) tags (t int)'
+        tdSql.execute(sql)
+        sql = f'create table ctb using stb tags (1)'
+        tdSql.execute(sql)
+        sql = f'insert into ctb values (now, 1) (now+1s, 2) (now+2s, 3)'
+        tdSql.execute(sql)      
+        sql = f'drop table stb'
+        tdSql.execute(sql)        
+        sql = f'alter database {dbName} replica 3'
+        tdSql.execute(sql)
+        tdLog.debug("start check time: %s"%(str(datetime.datetime.now())))
+        res = self.checkVgroups(dbName, vgNum)
+        tdLog.debug("end   check time: %s"%(str(datetime.datetime.now())))
+        if (0 != res):
+            tdLog.exit(f'fail: alter database {dbName} replica 3')
+
+    def run(self):
+        self.alter_replica()
+
+    def stop(self):
+        tdSql.close()
+        tdLog.success(f"{__file__} successfully executed")
+
+
+tdCases.addLinux(__file__, TDTestCase())
+tdCases.addWindows(__file__, TDTestCase())
diff --git a/tests/system-test/1-insert/database_pre_suf.py b/tests/system-test/1-insert/database_pre_suf.py
index a6ff95ab3f..2e993b9a40 100755
--- a/tests/system-test/1-insert/database_pre_suf.py
+++ b/tests/system-test/1-insert/database_pre_suf.py
@@ -24,9 +24,7 @@ from util.dnodes import tdDnodes
 from util.dnodes import *
 
 class TDTestCase:
-    updatecfgDict = {'maxSQLLength':1048576,'debugFlag': 143 ,"cDebugFlag":143,"uDebugFlag":143 ,"rpcDebugFlag":143 , "tmrDebugFlag":143 , 
-    "jniDebugFlag":143 ,"simDebugFlag":143,"dDebugFlag":143, "dDebugFlag":143,"vDebugFlag":143,"mDebugFlag":143,"qDebugFlag":143,
-    "wDebugFlag":143,"sDebugFlag":143,"tsdbDebugFlag":143,"tqDebugFlag":143 ,"fsDebugFlag":143 ,"fnDebugFlag":143}
+    updatecfgDict = {'maxSQLLength':1048576,'debugFlag': 135}
     
     def init(self, conn, logSql, replicaVar=1):
         self.replicaVar = int(replicaVar)
@@ -39,7 +37,9 @@ class TDTestCase:
         
         self.db = "pre_suf"
 
-    def dropandcreateDB_random(self,database,n,vgroups,table_prefix,table_suffix,check_result):
+    def dropandcreateDB_random(self,database,n,vgroups,table_prefix,table_suffix,check_result_positive,check_result_negative):
+        #check_result_positive 检查前缀后缀是正数的,check_result_negative 检查前缀后缀是负数的(TS-3249)
+        tdLog.info(f"create start:n:{n},vgroups:{vgroups},table_prefix:{table_prefix},table_suffix:{table_suffix},check_result_positive:{check_result_positive},check_result_negative:{check_result_negative}") 
         ts = 1630000000000
         num_random = 100
         fake = Faker('zh_CN')
@@ -56,6 +56,7 @@ class TDTestCase:
                 q_int_null int , q_bigint_null bigint , q_smallint_null smallint , q_tinyint_null tinyint, q_float_null float , q_double_null double , q_bool_null bool , q_binary_null binary(20) , q_nchar_null nchar(20) , q_ts_null timestamp) \
                 tags(loc nchar(100) , t_int int , t_bigint bigint , t_smallint smallint , t_tinyint tinyint, t_bool bool , t_binary binary(100) , t_nchar nchar(100) ,t_float float , t_double double , t_ts timestamp);''')
         
+        #positive
         for i in range(10*n):
             tdSql.execute('''create table bj_%d (ts timestamp , q_int int , q_bigint bigint , q_smallint smallint , q_tinyint tinyint , q_float float , q_double double , q_bool bool , q_binary binary(100) , q_nchar nchar(100) , q_ts timestamp ) ;'''%i)
             tdSql.execute('''create table sh_%d (ts timestamp , q_int int , q_bigint bigint , q_smallint smallint , q_tinyint tinyint , q_float float , q_double double , q_bool bool , q_binary binary(100) , q_nchar nchar(100) , q_ts timestamp ) ;'''%i)
@@ -106,11 +107,60 @@ class TDTestCase:
                         fake.random_int(min=-32767, max=32767, step=1) , fake.random_int(min=-127, max=127, step=1) , 
                         fake.pystr() ,fake.pystr() ,fake.pyfloat(),fake.pyfloat(),fake.random_int(min=-2147483647, max=2147483647, step=1)))
 
-        
+        #negative
+        for i in range(10*n):
+            tdSql.execute('''create table bj_table_%d_r_negative (ts timestamp , q_int int , q_bigint bigint , q_smallint smallint , q_tinyint tinyint , q_float float , q_double double , q_bool bool , q_binary binary(100) , q_nchar nchar(100) , q_ts timestamp ) ;'''%i)
+            tdSql.execute('''create table sh_table_%d_r_negative (ts timestamp , q_int int , q_bigint bigint , q_smallint smallint , q_tinyint tinyint , q_float float , q_double double , q_bool bool , q_binary binary(100) , q_nchar nchar(100) , q_ts timestamp ) ;'''%i)
+            tdSql.execute('''create table hn_table_%d_r_negative \
+                    (ts timestamp , q_int int , q_bigint bigint , q_smallint smallint , q_tinyint tinyint , q_float float , q_double double , q_bool bool , q_binary binary(100) , q_nchar nchar(100) , q_ts timestamp , \
+                    q_binary1 binary(100) , q_nchar1 nchar(100) ,q_binary2 binary(100) , q_nchar2 nchar(100) ,q_binary3 binary(100) , q_nchar3 nchar(100) ,q_binary4 binary(100) , q_nchar4 nchar(100) ,\
+                    q_binary5 binary(100) , q_nchar5 nchar(100) ,q_binary6 binary(100) , q_nchar6 nchar(100) ,q_binary7 binary(100) , q_nchar7 nchar(100) ,q_binary8 binary(100) , q_nchar8 nchar(100) ,\
+                    q_int_null int , q_bigint_null bigint , q_smallint_null smallint , q_tinyint_null tinyint, q_float_null float , q_double_null double , q_bool_null bool , q_binary_null binary(20) , q_nchar_null nchar(20) , q_ts_null timestamp) ;'''%i)
+            
+            tdSql.execute('''create table bj_stable_1_%d_negative using stable_1 tags('bj_stable_1_%d', '%d' , '%d', '%d' , '%d' , 1 , 'binary1.%s' , 'nchar1.%s' , '%f', '%f' ,'%d') ;''' 
+                      %(i,i,fake.random_int(min=-2147483647, max=2147483647, step=1), fake.random_int(min=-9223372036854775807, max=9223372036854775807, step=1), 
+                        fake.random_int(min=-32767, max=32767, step=1) , fake.random_int(min=-127, max=127, step=1) , 
+                        fake.pystr() ,fake.pystr() ,fake.pyfloat(),fake.pyfloat(),fake.random_int(min=-2147483647, max=2147483647, step=1))) 
+            tdSql.execute('''create table sh_table_%d_a_negative using stable_1 tags('sh_a_table_1_%d', '%d' , '%d', '%d' , '%d' , 1 , 'binary1.%s' , 'nchar1.%s' , '%f', '%f' ,'%d') ;''' 
+                      %(i,i,fake.random_int(min=-2147483647, max=2147483647, step=1), fake.random_int(min=-9223372036854775807, max=9223372036854775807, step=1), 
+                        fake.random_int(min=-32767, max=32767, step=1) , fake.random_int(min=-127, max=127, step=1) , 
+                        fake.pystr() ,fake.pystr() ,fake.pyfloat(),fake.pyfloat(),fake.random_int(min=-2147483647, max=2147483647, step=1))) 
+            tdSql.execute('''create table sh_table_%d_b_negative using stable_1 tags('sh_b_table_1_%d', '%d' , '%d', '%d' , '%d' , 1 , 'binary1.%s' , 'nchar1.%s' , '%f', '%f' ,'%d') ;''' 
+                      %(i,i,fake.random_int(min=-2147483647, max=2147483647, step=1), fake.random_int(min=-9223372036854775807, max=9223372036854775807, step=1), 
+                        fake.random_int(min=-32767, max=32767, step=1) , fake.random_int(min=-127, max=127, step=1) , 
+                        fake.pystr() ,fake.pystr() ,fake.pyfloat(),fake.pyfloat(),fake.random_int(min=-2147483647, max=2147483647, step=1)))
+            tdSql.execute('''create table sh_table_%d_c_negative using stable_1 tags('sh_c_table_1_%d', '%d' , '%d', '%d' , '%d' , 1 , 'binary1.%s' , 'nchar1.%s' , '%f', '%f' ,'%d') ;''' 
+                      %(i,i,fake.random_int(min=-2147483647, max=2147483647, step=1), fake.random_int(min=-9223372036854775807, max=9223372036854775807, step=1), 
+                        fake.random_int(min=-32767, max=32767, step=1) , fake.random_int(min=-127, max=127, step=1) , 
+                        fake.pystr() ,fake.pystr() ,fake.pyfloat(),fake.pyfloat(),fake.random_int(min=-2147483647, max=2147483647, step=1)))
+            
+            tdSql.execute('''create table bj_table_%d_a_negative using stable_1 tags('bj_a_table_1_%d', '%d' , '%d', '%d' , '%d' , 1 , 'binary1.%s' , 'nchar1.%s' , '%f', '%f' ,'%d') ;''' 
+                      %(i,i,fake.random_int(min=-2147483647, max=2147483647, step=1), fake.random_int(min=-9223372036854775807, max=9223372036854775807, step=1), 
+                        fake.random_int(min=-32767, max=32767, step=1) , fake.random_int(min=-127, max=127, step=1) , 
+                        fake.pystr() ,fake.pystr() ,fake.pyfloat(),fake.pyfloat(),fake.random_int(min=-2147483647, max=2147483647, step=1))) 
+            tdSql.execute('''create table bj_table_%d_b_negative using stable_1 tags('bj_b_table_1_%d', '%d' , '%d', '%d' , '%d' , 1 , 'binary1.%s' , 'nchar1.%s' , '%f', '%f' ,'%d') ;''' 
+                      %(i,i,fake.random_int(min=-2147483647, max=2147483647, step=1), fake.random_int(min=-9223372036854775807, max=9223372036854775807, step=1), 
+                        fake.random_int(min=-32767, max=32767, step=1) , fake.random_int(min=-127, max=127, step=1) , 
+                        fake.pystr() ,fake.pystr() ,fake.pyfloat(),fake.pyfloat(),fake.random_int(min=-2147483647, max=2147483647, step=1)))
+            tdSql.execute('''create table bj_table_%d_c_negative using stable_1 tags('bj_c_table_1_%d', '%d' , '%d', '%d' , '%d' , 1 , 'binary1.%s' , 'nchar1.%s' , '%f', '%f' ,'%d') ;''' 
+                      %(i,i,fake.random_int(min=-2147483647, max=2147483647, step=1), fake.random_int(min=-9223372036854775807, max=9223372036854775807, step=1), 
+                        fake.random_int(min=-32767, max=32767, step=1) , fake.random_int(min=-127, max=127, step=1) , 
+                        fake.pystr() ,fake.pystr() ,fake.pyfloat(),fake.pyfloat(),fake.random_int(min=-2147483647, max=2147483647, step=1)))
+
+            
+            tdSql.execute('''create table tj_table_%d_a_negative using stable_2 tags('tj_a_table_2_%d', '%d' , '%d', '%d' , '%d' , 1 , 'binary1.%s' , 'nchar1.%s' , '%f', '%f' ,'%d') ;''' 
+                      %(i,i,fake.random_int(min=-2147483647, max=2147483647, step=1), fake.random_int(min=-9223372036854775807, max=9223372036854775807, step=1), 
+                        fake.random_int(min=-32767, max=32767, step=1) , fake.random_int(min=-127, max=127, step=1) , 
+                        fake.pystr() ,fake.pystr() ,fake.pyfloat(),fake.pyfloat(),fake.random_int(min=-2147483647, max=2147483647, step=1))) 
+            tdSql.execute('''create table tj_table_%d_b_negative using stable_2 tags('tj_b_table_2_%d', '%d' , '%d', '%d' , '%d' , 1 , 'binary1.%s' , 'nchar1.%s' , '%f', '%f' ,'%d') ;''' 
+                      %(i,i,fake.random_int(min=-2147483647, max=2147483647, step=1), fake.random_int(min=-9223372036854775807, max=9223372036854775807, step=1), 
+                        fake.random_int(min=-32767, max=32767, step=1) , fake.random_int(min=-127, max=127, step=1) , 
+                        fake.pystr() ,fake.pystr() ,fake.pyfloat(),fake.pyfloat(),fake.random_int(min=-2147483647, max=2147483647, step=1)))
+            
         # create stream
         tdSql.execute('''create stream current_stream trigger at_once IGNORE EXPIRED 0 into stream_max_stable_1 as select _wstart as startts, _wend as wend, max(q_int) as max_int, min(q_bigint) as min_int from stable_1 where ts is not null interval (5s);''')
         
-        # insert data
+        # insert data positive
         for i in range(num_random*n):        
             tdSql.execute('''insert into bj_stable_1_1  (ts , q_int , q_bigint , q_smallint , q_tinyint , q_float , q_double , q_bool , q_binary , q_nchar, q_ts,\
                         q_binary1 , q_nchar1 , q_binary2 , q_nchar2 , q_binary3 , q_nchar3 , q_binary4 , q_nchar4 , q_binary5 , q_nchar5 , q_binary6 , q_nchar6 , q_binary7 , q_nchar7, q_binary8 , q_nchar8) \
@@ -180,8 +230,60 @@ class TDTestCase:
                         fake.pyfloat() , fake.pyfloat() , fake.pystr() , fake.pystr() , ts + i, fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , 
                         fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr()))
 
+        # insert data negative
+        for i in range(num_random*n):        
+            tdSql.execute('''insert into bj_stable_1_1_negative  (ts , q_int , q_bigint , q_smallint , q_tinyint , q_float , q_double , q_bool , q_binary , q_nchar, q_ts,\
+                        q_binary1 , q_nchar1 , q_binary2 , q_nchar2 , q_binary3 , q_nchar3 , q_binary4 , q_nchar4 , q_binary5 , q_nchar5 , q_binary6 , q_nchar6 , q_binary7 , q_nchar7, q_binary8 , q_nchar8) \
+                        values(%d, %d, %d, %d, %d, %f, %f, 0, 'binary.%s', 'nchar.%s', %d, 'binary1.%s', 'nchar1.%s', 'binary2.%s', 'nchar2.%s', 'binary3.%s', 'nchar3.%s', \
+                        'binary4.%s', 'nchar4.%s', 'binary5.%s', 'nchar5.%s', 'binary6.%s', 'nchar6.%s', 'binary7.%s', 'nchar7.%s', 'binary8.%s', 'nchar8.%s') ;''' 
+                        % (ts + i*1000, fake.random_int(min=-2147483647, max=2147483647, step=1), 
+                        fake.random_int(min=-9223372036854775807, max=9223372036854775807, step=1), 
+                        fake.random_int(min=-32767, max=32767, step=1) , fake.random_int(min=-127, max=127, step=1) , 
+                        fake.pyfloat() , fake.pyfloat() , fake.pystr() , fake.pystr() , ts + i , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , 
+                        fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr()))
+
+            tdSql.execute('''insert into bj_stable_1_2_negative (ts , q_int , q_bigint , q_smallint , q_tinyint , q_float , q_double, q_bool , q_binary , q_nchar, q_ts,\
+                        q_binary1 , q_nchar1 , q_binary2 , q_nchar2 , q_binary3 , q_nchar3 , q_binary4 , q_nchar4 , q_binary5 , q_nchar5 , q_binary6 , q_nchar6 , q_binary7 , q_nchar7, q_binary8 , q_nchar8)\
+                        values(%d, %d, %d, %d, %d, %f, %f, 1, 'binary.%s', 'nchar.%s', %d, 'binary1.%s', 'nchar1.%s', 'binary2.%s', 'nchar2.%s', 'binary3.%s', 'nchar3.%s', \
+                        'binary4.%s', 'nchar4.%s', 'binary5.%s', 'nchar5.%s', 'binary6.%s', 'nchar6.%s', 'binary7.%s', 'nchar7.%s', 'binary8.%s', 'nchar8.%s') ;''' 
+                        % (ts + i*1000, fake.random_int(min=0, max=2147483647, step=1), 
+                        fake.random_int(min=0, max=9223372036854775807, step=1), 
+                        fake.random_int(min=0, max=32767, step=1) , fake.random_int(min=0, max=127, step=1) , 
+                        fake.pyfloat() , fake.pyfloat() , fake.pystr() , fake.pystr() , ts + i, fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , 
+                        fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr()))
+
+            tdSql.execute('''insert into bj_stable_1_3_negative (ts , q_int , q_bigint , q_smallint , q_tinyint , q_float , q_double, q_bool , q_binary , q_nchar, q_ts,\
+                        q_binary1 , q_nchar1 , q_binary2 , q_nchar2 , q_binary3 , q_nchar3 , q_binary4 , q_nchar4 , q_binary5 , q_nchar5 , q_binary6 , q_nchar6 , q_binary7 , q_nchar7, q_binary8 , q_nchar8) \
+                        values(%d, %d, %d, %d, %d, %f, %f, 0, 'binary.%s', 'nchar.%s', %d, 'binary1.%s', 'nchar1.%s', 'binary2.%s', 'nchar2.%s', 'binary3.%s', 'nchar3.%s', \
+                        'binary4.%s', 'nchar4.%s', 'binary5.%s', 'nchar5.%s', 'binary6.%s', 'nchar6.%s', 'binary7.%s', 'nchar7.%s', 'binary8.%s', 'nchar8.%s') ;''' 
+                        % (ts + i*1000, fake.random_int(min=-0, max=2147483647, step=1), 
+                        fake.random_int(min=-0, max=9223372036854775807, step=1), 
+                        fake.random_int(min=-0, max=32767, step=1) , fake.random_int(min=-0, max=127, step=1) , 
+                        fake.pyfloat() , fake.pyfloat() , fake.pystr() , fake.pystr() , ts + i, fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , 
+                        fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr()))
+
+            tdSql.execute('''insert into bj_stable_1_4_negative (ts , q_int , q_bigint , q_smallint , q_tinyint , q_float , q_double, q_bool , q_binary , q_nchar, q_ts,\
+                        q_binary1 , q_nchar1 , q_binary2 , q_nchar2 , q_binary3 , q_nchar3 , q_binary4 , q_nchar4 , q_binary5 , q_nchar5 , q_binary6 , q_nchar6 , q_binary7 , q_nchar7, q_binary8 , q_nchar8) \
+                        values(%d, %d, %d, %d, %d, %f, %f, 0, 'binary.%s', 'nchar.%s', %d, 'binary1.%s', 'nchar1.%s', 'binary2.%s', 'nchar2.%s', 'binary3.%s', 'nchar3.%s', \
+                        'binary4.%s', 'nchar4.%s', 'binary5.%s', 'nchar5.%s', 'binary6.%s', 'nchar6.%s', 'binary7.%s', 'nchar7.%s', 'binary8.%s', 'nchar8.%s') ;''' 
+                        % (ts + i*1000 +1, fake.random_int(min=-0, max=2147483647, step=1), 
+                        fake.random_int(min=-0, max=9223372036854775807, step=1), 
+                        fake.random_int(min=-0, max=32767, step=1) , fake.random_int(min=-0, max=127, step=1) , 
+                        fake.pyfloat() , fake.pyfloat() , fake.pystr() , fake.pystr() , ts + i, fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , 
+                        fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr()))
+
+            tdSql.execute('''insert into bj_stable_1_5_negative (ts , q_int , q_bigint , q_smallint , q_tinyint , q_float , q_double, q_bool , q_binary , q_nchar, q_ts,\
+                        q_binary1 , q_nchar1 , q_binary2 , q_nchar2 , q_binary3 , q_nchar3 , q_binary4 , q_nchar4 , q_binary5 , q_nchar5 , q_binary6 , q_nchar6 , q_binary7 , q_nchar7, q_binary8 , q_nchar8) \
+                        values(%d, %d, %d, %d, %d, %f, %f, 0, 'binary.%s', 'nchar.%s', %d, 'binary1.%s', 'nchar1.%s', 'binary2.%s', 'nchar2.%s', 'binary3.%s', 'nchar3.%s', \
+                        'binary4.%s', 'nchar4.%s', 'binary5.%s', 'nchar5.%s', 'binary6.%s', 'nchar6.%s', 'binary7.%s', 'nchar7.%s', 'binary8.%s', 'nchar8.%s') ;''' 
+                        % (ts + i*1000 +10, fake.random_int(min=-0, max=2147483647, step=1), 
+                        fake.random_int(min=-0, max=9223372036854775807, step=1), 
+                        fake.random_int(min=-0, max=32767, step=1) , fake.random_int(min=-0, max=127, step=1) , 
+                        fake.pyfloat() , fake.pyfloat() , fake.pystr() , fake.pystr() , ts + i, fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , 
+                        fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr() , fake.pystr()))
+            
         tdSql.query("select count(*) from stable_1;")
-        tdSql.checkData(0,0,5*num_random*n)
+        tdSql.checkData(0,0,10*num_random*n)
         tdSql.query("select count(*) from hn_table_1_r;")
         tdSql.checkData(0,0,num_random*n)
         
@@ -220,39 +322,28 @@ class TDTestCase:
         
         
         tdSql.query(" select * from information_schema.ins_databases where name = '%s';" %database)
-        print(tdSql.queryResult)
+        tdLog.info(tdSql.queryResult)
         
-        # tdSql.query(" select table_prefix,table_suffix from information_schema.ins_databases where name = '%s';" %database)
-        # print(tdSql.queryResult)
-        #TD-19082
-        
-        #tdSql.query(" select * from information_schema.ins_tables where db_name = '%s';" %database)
-        #print(tdSql.queryResult)
-        
-        tdSql.query(" select table_name,vgroup_id from information_schema.ins_tables where db_name = '%s';" %database)  
+        tdSql.query(" select table_name,vgroup_id from information_schema.ins_tables where db_name = '%s' limit 3;" %database)  
         queryRows = len(tdSql.queryResult)    
         for i in range(queryRows):
-            print("row=%d,  vgroup_id=%s,  tbname=%s " %(i,tdSql.queryResult[i][1],tdSql.queryResult[i][0]))
+            tdLog.info("row=%d,  vgroup_id=%s,  tbname=%s " %(i,tdSql.queryResult[i][1],tdSql.queryResult[i][0]))
         
         tdLog.info("\n=============flush database ====================\n")
         
         tdSql.execute(" flush database %s;" %database)
         
         tdSql.query(" select * from information_schema.ins_databases where name = '%s';" %database)
-        print(tdSql.queryResult)
-        
-        # tdSql.query(" select table_prefix,table_suffix from information_schema.ins_databases where name = '%s';" %database)
-        # print(tdSql.queryResult)
-        #TD-19082
-        
-        tdSql.query(" select table_name,vgroup_id from information_schema.ins_tables where db_name = '%s';" %database)
+        tdLog.info(tdSql.queryResult)
+               
+        tdSql.query(" select table_name,vgroup_id from information_schema.ins_tables where db_name = '%s' limit 3;" %database)
         queryRows = len(tdSql.queryResult)    
         for i in range(queryRows):
-            print("row=%d,  vgroup_id=%s,  tbname=%s " %(i,tdSql.queryResult[i][1],tdSql.queryResult[i][0]))
+            tdLog.info("row=%d,  vgroup_id=%s,  tbname=%s " %(i,tdSql.queryResult[i][1],tdSql.queryResult[i][0]))
 
 
         # check in one vgroup
-        if check_result == 'Y':
+        if check_result_positive == 'Y':
             #base table : sh_table_0_a
             tdSql.query(" select table_name,vgroup_id from information_schema.ins_tables where db_name = '%s' and table_name='sh_table_0_a';" %(database))
             base_value_table_name = tdSql.queryResult[0][0]
@@ -324,8 +415,100 @@ class TDTestCase:
                 tdSql.query(" select table_name,vgroup_id from information_schema.ins_tables where db_name = '%s' and table_name='tj_table_%d_b';" %(database,i))
                 self.value_check(base_value_table_name,base_value_table_vgroup)
                          
+        elif check_result_negative == 'Y':
+            #base table : sh_table_0_a
+            tdSql.query(" select table_name,vgroup_id from information_schema.ins_tables where db_name = '%s' and table_name='sh_table_0_a_negative';" %(database))
+            base_value_table_name = tdSql.queryResult[0][0]
+            base_value_table_vgroup = tdSql.queryResult[0][1]
+            
+            #check table :sh_table_i_a
+            check_rows = tdSql.query(" select table_name,vgroup_id from information_schema.ins_tables where db_name = '%s' and table_name like 'sh_table_%%_a_negative';" %(database))
+            for i in range(check_rows):
+                tdSql.query(" select table_name,vgroup_id from information_schema.ins_tables where db_name = '%s' and table_name='sh_table_%d_a_negative';" %(database,i))
+                self.value_check(base_value_table_name,base_value_table_vgroup)
+                        
+            #check table :sh_table_i_b
+            check_rows = tdSql.query(" select table_name,vgroup_id from information_schema.ins_tables where db_name = '%s' and table_name like 'sh_table_%%_b_negative';" %(database))
+            for i in range(check_rows):
+                tdSql.query(" select table_name,vgroup_id from information_schema.ins_tables where db_name = '%s' and table_name='sh_table_%d_b_negative';" %(database,i))
+                self.value_check(base_value_table_name,base_value_table_vgroup) 
+                       
+            #check table :sh_table_i_c
+            check_rows = tdSql.query(" select table_name,vgroup_id from information_schema.ins_tables where db_name = '%s' and table_name like 'sh_table_%%_c_negative';" %(database))
+            for i in range(check_rows):
+                tdSql.query(" select table_name,vgroup_id from information_schema.ins_tables where db_name = '%s' and table_name='sh_table_%d_c_negative';" %(database,i))
+                self.value_check(base_value_table_name,base_value_table_vgroup)
+                    
+            #check table :sh_table_i_r
+            check_rows = tdSql.query(" select table_name,vgroup_id from information_schema.ins_tables where db_name = '%s' and table_name like 'sh_table_%%_r_negative';" %(database))
+            for i in range(check_rows):
+                tdSql.query(" select table_name,vgroup_id from information_schema.ins_tables where db_name = '%s' and table_name='sh_table_%d_r_negative';" %(database,i))
+                self.value_check(base_value_table_name,base_value_table_vgroup)
+                
+            #base table : bj_table_0_a
+            tdSql.query(" select table_name,vgroup_id from information_schema.ins_tables where db_name = '%s' and table_name='bj_table_0_a_negative';" %(database))
+            base_value_table_name = tdSql.queryResult[0][0]
+            base_value_table_vgroup = tdSql.queryResult[0][1]
+                
+            #check table :bj_table_i_a
+            check_rows = tdSql.query(" select table_name,vgroup_id from information_schema.ins_tables where db_name = '%s' and table_name like 'bj_table_%%_a_negative';" %(database))
+            for i in range(check_rows):
+                tdSql.query(" select table_name,vgroup_id from information_schema.ins_tables where db_name = '%s' and table_name='bj_table_%d_a_negative';" %(database,i))
+                self.value_check(base_value_table_name,base_value_table_vgroup)
+                
+            #check table :bj_table_i_b
+            check_rows = tdSql.query(" select table_name,vgroup_id from information_schema.ins_tables where db_name = '%s' and table_name like 'bj_table_%%_b_negative';" %(database))
+            for i in range(check_rows):
+                tdSql.query(" select table_name,vgroup_id from information_schema.ins_tables where db_name = '%s' and table_name='bj_table_%d_b_negative';" %(database,i))
+                self.value_check(base_value_table_name,base_value_table_vgroup)
+                
+            #check table :bj_table_i_c
+            check_rows = tdSql.query(" select table_name,vgroup_id from information_schema.ins_tables where db_name = '%s' and table_name like 'bj_table_%%_c_negative';" %(database))
+            for i in range(check_rows):
+                tdSql.query(" select table_name,vgroup_id from information_schema.ins_tables where db_name = '%s' and table_name='bj_table_%d_c_negative';" %(database,i))
+                self.value_check(base_value_table_name,base_value_table_vgroup)
+                
+            #check table :bj_table_i_r
+            check_rows = tdSql.query(" select table_name,vgroup_id from information_schema.ins_tables where db_name = '%s' and table_name like 'bj_table_%%_r_negative';" %(database))
+            for i in range(check_rows):
+                tdSql.query(" select table_name,vgroup_id from information_schema.ins_tables where db_name = '%s' and table_name='bj_table_%d_r_negative';" %(database,i))
+                self.value_check(base_value_table_name,base_value_table_vgroup)
+                
+            #base table : hn_table_0_r
+            tdSql.query(" select table_name,vgroup_id from information_schema.ins_tables where db_name = '%s' and table_name='hn_table_0_r_negative';" %(database))
+            base_value_table_name = tdSql.queryResult[0][0]
+            base_value_table_vgroup = tdSql.queryResult[0][1]
+            
+            #check table :hn_table_i_r
+            check_rows = tdSql.query(" select table_name,vgroup_id from information_schema.ins_tables where db_name = '%s' and table_name like 'hn_table_%%_r_negative';" %(database))
+            for i in range(check_rows):
+                tdSql.query(" select table_name,vgroup_id from information_schema.ins_tables where db_name = '%s' and table_name='hn_table_%d_r_negative';" %(database,i))
+                self.value_check(base_value_table_name,base_value_table_vgroup)
+                
+                
+            #base table : tj_table_0_r
+            tdSql.query(" select table_name,vgroup_id from information_schema.ins_tables where db_name = '%s' and table_name='tj_table_0_a_negative';" %(database))
+            base_value_table_name = tdSql.queryResult[0][0]
+            base_value_table_vgroup = tdSql.queryResult[0][1]
+            
+            #check table :tj_table_i_a
+            check_rows = tdSql.query(" select table_name,vgroup_id from information_schema.ins_tables where db_name = '%s' and table_name like 'tj_table_%%_a_negative';" %(database))
+            for i in range(check_rows):
+                tdSql.query(" select table_name,vgroup_id from information_schema.ins_tables where db_name = '%s' and table_name='tj_table_%d_a_negative';" %(database,i))
+                self.value_check(base_value_table_name,base_value_table_vgroup)
+                
+            #check table :tj_table_i_b
+            check_rows = tdSql.query(" select table_name,vgroup_id from information_schema.ins_tables where db_name = '%s' and table_name like 'tj_table_%%_b_negative';" %(database))
+            for i in range(check_rows):
+                tdSql.query(" select table_name,vgroup_id from information_schema.ins_tables where db_name = '%s' and table_name='tj_table_%d_b_negative';" %(database,i))
+                self.value_check(base_value_table_name,base_value_table_vgroup)
+                
+                
         else:
             pass
+        
+        tdLog.info(f"create end:n:{n},vgroups:{vgroups},table_prefix:{table_prefix},table_suffix:{table_suffix},check_result_positive:{check_result_positive},check_result_negative:{check_result_negative}") 
+        
     
     def value_check(self,base_value_table_name,base_value_table_vgroup):
         check_value_table_name = tdSql.queryResult[0][0]
@@ -348,17 +531,28 @@ class TDTestCase:
                   
         os.system("rm -rf %s/%s.sql" % (self.testcasePath,self.testcaseFilename)) 
         
-        #(self,database,n,vgroups,table_prefix,table_suffix)
-        self.dropandcreateDB_random("%s" %self.db, 1,2,0,0,'N')
-        self.dropandcreateDB_random("%s" %self.db, 1,2,0,2,'N')
-        self.dropandcreateDB_random("%s" %self.db, 1,2,2,0,'N')
-        self.dropandcreateDB_random("%s" %self.db, 1,2,3,3,'Y')  
-        self.dropandcreateDB_random("%s" %self.db, 1,3,3,3,'Y')  
-        self.dropandcreateDB_random("%s" %self.db, 1,4,4,4,'Y')
-        self.dropandcreateDB_random("%s" %self.db, 1,5,5,5,'Y')
+        #(self,database,n,vgroups,table_prefix,table_suffix,check_result_positive,check_result_negative):
+        #check_result_positive 检查前缀后缀是正数的,check_result_negative 检查前缀后缀是负数的(TS-3249)
+        # self.dropandcreateDB_random("%s" %self.db, 1,2,0,0,'N','N')
+        # self.dropandcreateDB_random("%s" %self.db, 1,2,0,2,'N','N')
+        # self.dropandcreateDB_random("%s" %self.db, 1,2,2,0,'N','N')        
+        
+        self.dropandcreateDB_random("%s" %self.db, 1,random.randint(1,5),random.randint(0,3),random.randint(0,3),'N','N')
+        self.dropandcreateDB_random("%s" %self.db, 1,random.randint(1,5),random.randint(-10,0),random.randint(-10,0),'N','N')
+        self.dropandcreateDB_random("%s" %self.db, 1,random.randint(1,5),random.randint(-191,0),random.randint(-191,0),'N','N')
+        self.dropandcreateDB_random("%s" %self.db, 1,random.randint(1,5),random.randint(0,100),random.randint(0,91),'N','N')
+        
+        # self.dropandcreateDB_random("%s" %self.db, 1,2,3,3,'Y','N')  
+        # self.dropandcreateDB_random("%s" %self.db, 1,3,3,3,'Y','N')  
+        # self.dropandcreateDB_random("%s" %self.db, 1,4,4,4,'Y','N')
+        # self.dropandcreateDB_random("%s" %self.db, 1,5,5,5,'Y','N')       
+        self.dropandcreateDB_random("%s" %self.db, 1,random.randint(1,5),random.randint(3,5),random.randint(3,5),'Y','N')
+                
+        self.dropandcreateDB_random("%s" %self.db, 1,random.randint(1,5),random.randint(-5,-1),0,'N','Y')        
+        self.dropandcreateDB_random("%s" %self.db, 1,random.randint(1,5),random.randint(-5,-1),random.randint(-9,-0),'N','Y')
         
         
-        #taos -f sql
+        # #taos -f sql
         print("taos -f sql start!")
         taos_cmd1 = "taos -f %s/%s.sql" % (self.testcasePath,self.testcaseFilename)
         _ = subprocess.check_output(taos_cmd1, shell=True)
diff --git a/tests/system-test/1-insert/delete_systable.py b/tests/system-test/1-insert/delete_systable.py
new file mode 100644
index 0000000000..40422a7515
--- /dev/null
+++ b/tests/system-test/1-insert/delete_systable.py
@@ -0,0 +1,111 @@
+
+###################################################################
+#           Copyright (c) 2016 by TAOS Technologies, Inc.
+#                     All rights reserved.
+#
+#  This file is proprietary and confidential to TAOS Technologies.
+#  No part of this file may be reproduced, stored, transmitted,
+#  disclosed or used in any form or by any means other than as
+#  expressly provided by the written permission from Jianhui Tao
+#
+###################################################################
+
+# -*- coding: utf-8 -*-
+
+import random
+import string
+
+from numpy import logspace
+from util import constant
+from util.log import *
+from util.cases import *
+from util.sql import *
+from util.common import *
+from util.sqlset import TDSetSql
+
+info_schema_db = "information_schema"
+perf_schema_db = "performance_schema"
+
+info_schema_tables = [
+    "ins_dnodes",
+    "ins_mnodes",
+    "ins_modules",
+    "ins_qnodes",
+    "ins_snodes",
+    "ins_cluster",
+    "ins_databases",
+    "ins_functions",
+    "ins_indexes",
+    "ins_stables",
+    "ins_tables",
+    "ins_tags",
+    "ins_columns",
+    "ins_users",
+    "ins_grants",
+    "ins_vgroups",
+    "ins_configs",
+    "ins_dnode_variables",
+    "ins_topics",
+    "ins_subscriptions",
+    "ins_streams",
+    "ins_streams_tasks",
+    "ins_vnodes",
+    "ins_user_privileges"
+]
+
+perf_schema_tables = [
+    "perf_connections",
+    "perf_queries",
+    "perf_consumers",
+    "perf_trans",
+    "perf_apps"
+]
+
+class TDTestCase:
+    def init(self, conn, logSql, replicaVar=1):
+        self.replicaVar = int(replicaVar)
+        tdLog.debug("start to execute %s" % __file__)
+        tdSql.init(conn.cursor())
+
+    def delete_systb(self):
+        tdSql.execute(f'use {info_schema_db}')
+        for i in info_schema_tables:
+            tdSql.error(f'delete from {i}')
+            tdSql.error(f'delete from {info_schema_db}.{i}')
+            tdSql.error(f'delete from {i} where ts >= 0')
+            tdSql.error(f'delete from {info_schema_db}.{i} where ts >= 0')
+
+        tdSql.execute(f'use {perf_schema_db}')
+        for i in perf_schema_tables:
+            tdSql.error(f'delete from {i}')
+            tdSql.error(f'delete from {perf_schema_db}.{i}')
+            tdSql.error(f'delete from {i} where ts >= 0')
+            tdSql.error(f'delete from {perf_schema_db}.{i} where ts >= 0')
+
+    def drop_systb(self):
+        tdSql.execute(f'use {info_schema_db}')
+        for i in info_schema_tables:
+            tdSql.error(f'drop table {i}')
+            tdSql.error(f'drop {info_schema_db}.{i}')
+        tdSql.error(f'drop database {info_schema_db}')
+
+        tdSql.execute(f'use {perf_schema_db}')
+        for i in perf_schema_tables:
+            tdSql.error(f'drop table {i}')
+            tdSql.error(f'drop table {perf_schema_db}.{i}')
+        tdSql.error(f'drop database {perf_schema_db}')
+
+    def delete_from_systb(self):
+        self.delete_systb()
+        self.drop_systb()
+    def run(self):
+        self.delete_from_systb()
+        tdDnodes.stoptaosd(1)
+        tdDnodes.starttaosd(1)
+        self.delete_from_systb()
+    def stop(self):
+        tdSql.close()
+        tdLog.success("%s successfully executed" % __file__)
+
+tdCases.addWindows(__file__, TDTestCase())
+tdCases.addLinux(__file__, TDTestCase())
diff --git a/tests/system-test/2-query/select_null.py b/tests/system-test/2-query/select_null.py
new file mode 100755
index 0000000000..68eea8bc67
--- /dev/null
+++ b/tests/system-test/2-query/select_null.py
@@ -0,0 +1,446 @@
+###################################################################
+#           Copyright (c) 2016 by TAOS Technologies, Inc.
+#                     All rights reserved.
+#
+#  This file is proprietary and confidential to TAOS Technologies.
+#  No part of this file may be reproduced, stored, transmitted,
+#  disclosed or used in any form or by any means other than as
+#  expressly provided by the written permission from Jianhui Tao
+#
+###################################################################
+
+# -*- coding: utf-8 -*-
+
+import random
+import os
+import time
+import taos
+import subprocess
+from faker import Faker
+from util.log import tdLog
+from util.cases import tdCases
+from util.sql import tdSql
+from util.dnodes import tdDnodes
+from util.dnodes import *
+
+class TDTestCase:
+    
+    def init(self, conn, logSql, replicaVar):
+        tdLog.debug("start to execute %s" % __file__)
+        tdSql.init(conn.cursor(), logSql)
+
+        self.testcasePath = os.path.split(__file__)[0]
+        self.testcaseFilename = os.path.split(__file__)[-1]
+        os.system("rm -rf %s/%s.sql" % (self.testcasePath,self.testcaseFilename))
+        
+        self.db = "sel_null"
+
+    def insert_data(self,database,vgroups):
+        num_random = 10
+        tdSql.execute('''drop database if exists %s ;''' %database)
+        tdSql.execute('''create database %s keep 36500 vgroups %d PRECISION 'us';'''%(database,vgroups))
+        tdSql.execute('''use %s;'''%database)
+
+        tdSql.execute('''create stable %s.stb0 (ts timestamp , c0 int , c1 double , c0null int , c1null double ) tags( t0 tinyint , t1 varchar(16) , t_int int , t_bigint bigint , t_smallint smallint , t_tinyint tinyint , t_bool bool , t_binary binary(100) , t_nchar nchar(100) ,t_float float , t_double double , t_ts timestamp);'''%database)
+
+        for i in range(5):
+            tdSql.execute('''create table %s.stb0_%d using %s.stb0 tags(%d,'varchar%d',%d,%d, %d, %d,%d,'binary%d','nchar%d',%d,%d,%d ) ;'''%(database,i,database,i,i,i,i,i,i,i,i,i,i,i,i))
+            
+        # insert data
+        for i in range(num_random):   
+            for j in range(50):     
+                tdSql.execute('''insert into %s.stb0_0  (ts , c1 , c0) values(now, %d, %d) ;''' % (database,j,j))
+                tdSql.execute('''insert into %s.stb0_1  (ts , c1 , c0) values(now, %d, %d) ;''' % (database,j,j))
+                tdSql.execute('''insert into %s.stb0_2  (ts , c1 , c0) values(now, %d, %d) ;''' % (database,j,j))
+                tdSql.execute('''insert into %s.stb0_3  (ts , c1 , c0) values(now, %d, %d) ;''' % (database,j,j))
+                tdSql.execute('''insert into %s.stb0_4  (ts , c1 , c0) values(now, %d, %d) ;''' % (database,j,j))
+
+        tdSql.query("select count(*) from %s.stb0;" %database)
+        tdSql.checkData(0,0,5*num_random*50)
+        tdSql.query("select count(*) from %s.stb0_0;"%database)
+        tdSql.checkData(0,0,num_random*50)
+        
+    def ts_3085(self,database):  
+        sql = "select count(c0null) from(select * from %s.stb0 limit 20,4) "%(database)
+        tdSql.query(sql) 
+        tdSql.checkData(0,0,0)
+        
+        offset =  random.randint(10,100)
+        for i in range(offset):
+            sql = "select count(c0null) from(select * from %s.stb0 limit %d,%d) "%(database,offset,i)
+            tdSql.query(sql) 
+            tdSql.checkData(0,0,0)
+            sql = "select count(c1null) from(select * from %s.stb0 limit %d,%d) "%(database,offset,i)
+            tdSql.query(sql) 
+            tdSql.checkData(0,0,0)
+            sql = "select count(c0) from(select * from %s.stb0 limit %d,%d) "%(database,offset,i)
+            tdSql.query(sql) 
+            tdSql.checkData(0,0,i)
+            sql = "select count(c1) from(select * from %s.stb0 limit %d,%d) "%(database,offset,i)
+            tdSql.query(sql) 
+            tdSql.checkData(0,0,i)
+            sql = "select count(t0) from(select * from %s.stb0 limit %d,%d) "%(database,offset,i)
+            tdSql.query(sql) 
+            tdSql.checkData(0,0,i)
+            sql = "select count(t1) from(select * from %s.stb0 limit %d,%d) "%(database,offset,i)
+            tdSql.query(sql) 
+            tdSql.checkData(0,0,i)
+
+
+    def ts_2974_max(self,database):  
+        sql = "select max(c0) from %s.stb0 where ts= 1 or rows <= 4):
+            tdLog.info("sql checkrows success")
+        else:
+            tdLog.exit(f"checkEqual error, sql_rows=={rows}")
+            
+            
+        self.sql_query_time_cost(nest_sql)
+        rows = tdSql.queryRows
+        if (rows >= 1 or rows <= 4):
+            tdLog.info("sql checkrows success")
+        else:
+            tdLog.exit(f"checkEqual error, sql_rows=={rows}")         
+        
+        sql_0 = re.sub(r'\d+',"0",sql)
+        self.sql_query_time_cost(sql_0)
+        tdSql.checkRows(0)
+        
+        nest_sql_0 = re.sub(r'\d\d',"0",nest_sql) # \d是匹配数字字符[0-9],+匹配一个或多个
+        self.sql_query_time_cost(nest_sql_0)
+        tdSql.checkRows(0)
+        
+        sql = sql.replace('limit','slimit')
+        tdSql.error(sql)
+        nest_sql = nest_sql.replace('limit','slimit')
+        tdSql.error(nest_sql)
+        
+        sql_0 = re.sub(r'\d+',"0",sql)
+        tdSql.error(sql_0)
+        nest_sql_0 = re.sub(r'\d\d',"0",nest_sql)
+        tdSql.error(nest_sql_0)
+        
+    def sql_limit_retun_tables_slimit_return_error(self,sql,num,tables,per_table_num,base_fun,replace_fun): 
+        #sql limit n =n;sql limit 0 = 0 ;sql slmit n = error;sql slimit 0  = error  
+        sql = sql.replace('%s'%base_fun,'%s'%replace_fun)
+          
+        nest_sql =" select * from (%s) " %sql         
+        self.sql_query_time_cost(sql)
+        tdSql.checkRows(tables)     
+        self.sql_query_time_cost(nest_sql)
+        tdSql.checkRows(tables)  
+        
+        sql_0 = re.sub(r'\d\d',"0",sql)
+        self.sql_query_time_cost(sql_0)
+        tdSql.checkRows(0)
+        
+        nest_sql_0 = re.sub(r'\d\d',"0",nest_sql) # \d是匹配数字字符[0-9],+匹配一个或多个
+        self.sql_query_time_cost(nest_sql_0)
+        tdSql.checkRows(0)
+        
+        sql = sql.replace('limit','slimit')
+        tdSql.error(sql)
+        nest_sql = nest_sql.replace('limit','slimit')
+        tdSql.error(nest_sql)
+        
+        sql_0 = re.sub(r'\d+',"0",sql)
+        tdSql.error(sql_0)
+        nest_sql_0 = re.sub(r'\d\d',"0",nest_sql)
+        tdSql.error(nest_sql_0)
+
+    def sql_limit_retun_tables_slimit_return_n(self,sql,num,tables,per_table_num,base_fun,replace_fun): 
+        #sql limit n =tables;sql limit 0 = 0 ;sql slmit n = n;sql slimit 0  = 0   
+        sql = sql.replace('%s'%base_fun,'%s'%replace_fun)
+         
+        nest_sql =" select * from (%s) " %sql           
+        self.sql_query_time_cost(sql)
+        tdSql.checkRows(tables)  
+        self.sql_query_time_cost(nest_sql)
+        tdSql.checkRows(tables)  
+        
+        sql_0 = re.sub(r'\d\d',"0",sql)
+        self.sql_query_time_cost(sql_0)
+        tdSql.checkRows(0)
+        
+        nest_sql_0 = re.sub(r'\d\d',"0",nest_sql) # \d是匹配数字字符[0-9],+匹配一个或多个
+        self.sql_query_time_cost(nest_sql_0)
+        tdSql.checkRows(0)
+        
+        sql = sql.replace('limit','slimit')
+        self.sql_query_time_cost(sql)
+        tdSql.checkRows(num)
+        nest_sql = nest_sql.replace('limit','slimit')
+        self.sql_query_time_cost(nest_sql)
+        tdSql.checkRows(num)
+        
+        sql_0 = re.sub(r'\d\d',"0",sql)
+        self.sql_query_time_cost(sql_0)
+        tdSql.checkRows(0)
+        nest_sql_0 = re.sub(r'\d\d',"0",nest_sql)
+        self.sql_query_time_cost(nest_sql_0)
+        tdSql.checkRows(0)
+
+    def sql_data_limit_retun_tables_slimit_return_n(self,sql,num,tables,per_table_num,base_fun,replace_fun): 
+        #sql limit n =tables;sql limit 0 = 0 ;sql slmit n = n;sql slimit 0  = 0   
+        sql = sql.replace('%s'%base_fun,'%s'%replace_fun)
+         
+        nest_sql =" select * from (%s) " %sql           
+        self.sql_query_time_cost(sql)
+        tdSql.checkData(0,0,tables)  
+        self.sql_query_time_cost(nest_sql)
+        tdSql.checkData(0,0,tables)  
+        
+        sql_0 = re.sub(r'\d\d',"0",sql)
+        self.sql_query_time_cost(sql_0)
+        tdSql.checkData(0,0,0)
+        
+        nest_sql_0 = re.sub(r'\d\d',"0",nest_sql) # \d是匹配数字字符[0-9],+匹配一个或多个
+        self.sql_query_time_cost(nest_sql_0)
+        tdSql.checkData(0,0,0)
+        
+        sql = sql.replace('limit','slimit')
+        self.sql_query_time_cost(sql)
+        tdSql.checkData(0,0,num)
+        nest_sql = nest_sql.replace('limit','slimit')
+        self.sql_query_time_cost(nest_sql)
+        tdSql.checkData(0,0,num)
+        
+        sql_0 = re.sub(r'\d\d',"0",sql)
+        self.sql_query_time_cost(sql_0)
+        tdSql.checkData(0,0,0)
+        nest_sql_0 = re.sub(r'\d\d',"0",nest_sql)
+        self.sql_query_time_cost(nest_sql_0)
+        tdSql.checkData(0,0,0)
+
+    def sql_limit_retun_n_slimit_return_tables(self,sql,num,tables,per_table_num,base_fun,replace_fun): 
+        #sql limit n =n;sql limit 0 = 0 ;sql slmit n = 100;sql slimit 0  = 0    
+        sql = sql.replace('%s'%base_fun,'%s'%replace_fun)
+         
+        nest_sql =" select * from (%s) " %sql            
+        self.sql_query_time_cost(sql)
+        tdSql.checkRows(num)
+        self.sql_query_time_cost(nest_sql)
+        tdSql.checkRows(num) 
+        
+        sql_0 = re.sub(r'\d\d',"0",sql)
+        self.sql_query_time_cost(sql_0)
+        tdSql.checkRows(0)
+        
+        nest_sql_0 = re.sub(r'\d\d',"0",nest_sql) # \d是匹配数字字符[0-9],+匹配一个或多个
+        self.sql_query_time_cost(nest_sql_0)
+        tdSql.checkRows(0)
+        
+        sql = sql.replace('limit','slimit')
+        self.sql_query_time_cost(sql)
+        tdSql.checkRows(tables)
+        nest_sql = nest_sql.replace('limit','slimit')
+        self.sql_query_time_cost(nest_sql)
+        tdSql.checkRows(tables)
+        
+        sql_0 = re.sub(r'\d\d',"0",sql)
+        self.sql_query_time_cost(sql_0)
+        tdSql.checkRows(0)
+        nest_sql_0 = re.sub(r'\d\d',"0",nest_sql)
+        self.sql_query_time_cost(nest_sql_0)
+        tdSql.checkRows(0)
+
+    def sql_data_limit_retun_n_slimit_return_tables(self,sql,num,tables,per_table_num,base_fun,replace_fun): 
+        #sql limit n =n;sql limit 0 = 0 ;sql slmit n = 100;sql slimit 0  = 0  
+        sql = sql.replace('%s'%base_fun,'%s'%replace_fun)
+           
+        nest_sql =" select * from (%s) " %sql            
+        self.sql_query_time_cost(sql)
+        tdSql.checkData(0,0,num)
+        self.sql_query_time_cost(nest_sql)
+        tdSql.checkData(0,0,num) 
+        
+        sql_0 = re.sub(r'\d\d',"0",sql)
+        self.sql_query_time_cost(sql_0)
+        tdSql.checkData(0,0,0)
+        
+        nest_sql_0 = re.sub(r'\d\d',"0",nest_sql) # \d是匹配数字字符[0-9],+匹配一个或多个
+        self.sql_query_time_cost(nest_sql_0)
+        tdSql.checkData(0,0,0)
+        
+        sql = sql.replace('limit','slimit')
+        self.sql_query_time_cost(sql)
+        tdSql.checkData(0,0,tables)
+        nest_sql = nest_sql.replace('limit','slimit')
+        self.sql_query_time_cost(nest_sql)
+        tdSql.checkData(0,0,tables)
+        
+        sql_0 = re.sub(r'\d\d',"0",sql)
+        self.sql_query_time_cost(sql_0)
+        tdSql.checkData(0,0,0)
+        nest_sql_0 = re.sub(r'\d\d',"0",nest_sql)
+        self.sql_query_time_cost(nest_sql_0)
+        tdSql.checkData(0,0,0)
+
+    def sql_limit_retun_tables_times_n_slimit_return_error(self,sql,num,tables,per_table_num,base_fun,replace_fun): 
+        #sql limit n =n*tables;sql limit 0 = 0 ;sql slmit n = tables*n;sql slimit 0  = 0   
+        #interval     
+        sql = sql.replace('%s'%base_fun,'%s'%replace_fun)
+         
+        nest_sql =" select * from (%s) " %sql   
+        self.sql_query_time_cost(sql)
+        tdSql.checkRows(num*tables)
+        self.sql_query_time_cost(nest_sql)
+        tdSql.checkRows(num*tables) 
+        
+        sql_0 = re.sub(r'\d\d',"0",sql)
+        self.sql_query_time_cost(sql_0)
+        tdSql.checkRows(0)
+        
+        nest_sql_0 = re.sub(r'\d\d',"0",nest_sql) # \d是匹配数字字符[0-9],+匹配一个或多个
+        self.sql_query_time_cost(nest_sql_0)
+        tdSql.checkRows(0)
+        
+        sql = sql.replace('limit','slimit')
+        tdSql.error(sql)
+        nest_sql = nest_sql.replace('limit','slimit')
+        tdSql.error(nest_sql)
+        
+        sql_0 = re.sub(r'\d\d',"0",sql)
+        tdSql.error(sql_0)
+        nest_sql_0 = re.sub(r'\d\d',"0",nest_sql)
+        tdSql.error(nest_sql_0)
+
+    def sql_limit_retun_tables_times_n_slimit_return_per_table_num_times_n(self,sql,num,tables,per_table_num,base_fun,replace_fun): 
+        #sql limit n =n*tables;sql limit 0 = 0 ;sql slmit n = per_table_num*n;sql slimit 0  = 0   
+        #interval   
+        sql = sql.replace('%s'%base_fun,'%s'%replace_fun)
+         
+        nest_sql =" select * from (%s) " %sql     
+        self.sql_query_time_cost(sql)
+        tdSql.checkRows(num*tables)
+        self.sql_query_time_cost(nest_sql)
+        tdSql.checkRows(num*tables) 
+        
+        sql_0 = re.sub(r'\d\d',"0",sql)
+        self.sql_query_time_cost(sql_0)
+        tdSql.checkRows(0)
+        
+        nest_sql_0 = re.sub(r'\d\d',"0",nest_sql) # \d是匹配数字字符[0-9],+匹配一个或多个
+        self.sql_query_time_cost(nest_sql_0)
+        tdSql.checkRows(0)
+        
+        sql = sql.replace('limit','slimit')
+        self.sql_query_time_cost(sql)
+        tdSql.checkRows(num*per_table_num)
+        nest_sql = nest_sql.replace('limit','slimit')
+        self.sql_query_time_cost(nest_sql)
+        tdSql.checkRows(num*per_table_num)
+        
+        sql_0 = re.sub(r'\d\d',"0",sql)
+        self.sql_query_time_cost(sql_0)
+        tdSql.checkRows(0)
+        nest_sql_0 = re.sub(r'\d\d',"0",nest_sql)
+        self.sql_query_time_cost(nest_sql_0)
+        tdSql.checkRows(0)
+
+    def sql_data_limit_retun_tables_times_n_slimit_return_per_table_num_times_n(self,sql,num,tables,per_table_num,base_fun,replace_fun): 
+        #sql limit n =n*tables;sql limit 0 = 0 ;sql slmit n = per_table_num*n;sql slimit 0  = 0   
+        #interval   
+        sql = sql.replace('%s'%base_fun,'%s'%replace_fun)
+         
+        nest_sql =" select * from (%s) " %sql     
+        self.sql_query_time_cost(sql)
+        tdSql.checkData(0,0,num*tables)
+        self.sql_query_time_cost(nest_sql)
+        tdSql.checkData(0,0,num*tables) 
+        
+        sql_0 = re.sub(r'\d\d',"0",sql)
+        self.sql_query_time_cost(sql_0)
+        tdSql.checkData(0,0,0)
+        
+        nest_sql_0 = re.sub(r'\d\d',"0",nest_sql) # \d是匹配数字字符[0-9],+匹配一个或多个
+        self.sql_query_time_cost(nest_sql_0)
+        tdSql.checkData(0,0,0)
+        
+        sql = sql.replace('limit','slimit')
+        self.sql_query_time_cost(sql)
+        tdSql.checkData(0,0,num*per_table_num)
+        nest_sql = nest_sql.replace('limit','slimit')
+        self.sql_query_time_cost(nest_sql)
+        tdSql.checkData(0,0,num*per_table_num)
+        
+        sql_0 = re.sub(r'\d\d',"0",sql)
+        self.sql_query_time_cost(sql_0)
+        tdSql.checkData(0,0,0)
+        nest_sql_0 = re.sub(r'\d\d',"0",nest_sql)
+        self.sql_query_time_cost(nest_sql_0)
+        tdSql.checkData(0,0,0)
+
+    def sql_limit_retun_n_slimit_return_per_table_num_times_tables(self,sql,num,tables,per_table_num,base_fun,replace_fun): 
+        #sql limit n =n*tables;sql limit 0 = 0 ;sql slmit n = per_table_num*n;sql slimit 0  = 0   
+        #interval  
+        sql = sql.replace('%s'%base_fun,'%s'%replace_fun)
+         
+        nest_sql =" select * from (%s) " %sql     
+        self.sql_query_time_cost(sql)
+        tdSql.checkRows(num)
+        self.sql_query_time_cost(nest_sql)
+        tdSql.checkRows(num) 
+        
+        sql_0 = re.sub(r'\d\d',"0",sql)
+        self.sql_query_time_cost(sql_0)
+        tdSql.checkRows(0)
+        
+        nest_sql_0 = re.sub(r'\d\d',"0",nest_sql) # \d是匹配数字字符[0-9],+匹配一个或多个
+        self.sql_query_time_cost(nest_sql_0)
+        tdSql.checkRows(0)
+        
+        sql = sql.replace('limit','slimit')
+        self.sql_query_time_cost(sql)
+        tdSql.checkRows(tables*per_table_num)
+        nest_sql = nest_sql.replace('limit','slimit')
+        self.sql_query_time_cost(nest_sql)
+        tdSql.checkRows(tables*per_table_num)
+        
+        sql_0 = re.sub(r'\d\d',"0",sql)
+        self.sql_query_time_cost(sql_0)
+        tdSql.checkRows(0)
+        nest_sql_0 = re.sub(r'\d\d',"0",nest_sql)
+        self.sql_query_time_cost(nest_sql_0)
+        tdSql.checkRows(0)
+
+    def sql_data_limit_retun_n_slimit_return_per_table_num_times_tables(self,sql,num,tables,per_table_num,base_fun,replace_fun): 
+        #sql limit n =n*tables;sql limit 0 = 0 ;sql slmit n = per_table_num*n;sql slimit 0  = 0   
+        #interval  
+        sql = sql.replace('%s'%base_fun,'%s'%replace_fun)
+         
+        nest_sql =" select * from (%s) " %sql     
+        self.sql_query_time_cost(sql)
+        tdSql.checkData(0,0,num)
+        self.sql_query_time_cost(nest_sql)
+        tdSql.checkData(0,0,num) 
+        
+        sql_0 = re.sub(r'\d\d',"0",sql)
+        self.sql_query_time_cost(sql_0)
+        tdSql.checkData(0,0,0)
+        
+        nest_sql_0 = re.sub(r'\d\d',"0",nest_sql) # \d是匹配数字字符[0-9],+匹配一个或多个
+        self.sql_query_time_cost(nest_sql_0)
+        tdSql.checkData(0,0,0)
+        
+        sql = sql.replace('limit','slimit')
+        self.sql_query_time_cost(sql)
+        tdSql.checkData(0,0,tables*per_table_num)
+        nest_sql = nest_sql.replace('limit','slimit')
+        self.sql_query_time_cost(nest_sql)
+        tdSql.checkData(0,0,tables*per_table_num)
+        
+        sql_0 = re.sub(r'\d\d',"0",sql)
+        self.sql_query_time_cost(sql_0)
+        tdSql.checkData(0,0,0)
+        nest_sql_0 = re.sub(r'\d\d',"0",nest_sql)
+        self.sql_query_time_cost(nest_sql_0)
+        tdSql.checkData(0,0,0)
+
+    def sql_limit_not_test_slimitkeep_return_per_table_num_times_n(self,sql,num,tables,per_table_num,base_fun,replace_fun): 
+        #sql sql slmit n = per_table_num*n;sql slimit 0  = 0 
+        sql = sql.replace('%s'%base_fun,'%s'%replace_fun)
+         
+        nest_sql =" select * from (%s) " %sql                
+        sql = sql.replace('limit','limit')
+        self.sql_query_time_cost(sql)
+        tdSql.checkRows(num*per_table_num)
+        
+        self.sql_query_time_cost(nest_sql)
+        tdSql.checkRows(num*per_table_num)
+        
+        sql_0 = re.sub(r'\d\d',"0",sql)
+        self.sql_query_time_cost(sql_0)
+        tdSql.checkRows(0)
+        nest_sql_0 = re.sub(r'\d\d',"0",nest_sql)
+        self.sql_query_time_cost(nest_sql_0)
+        tdSql.checkRows(0)
+
+    def sql_data_limit_not_test_slimitkeep_return_per_table_num_times_n(self,sql,num,tables,per_table_num,base_fun,replace_fun): 
+        #sql sql slmit n = per_table_num*n;sql slimit 0  = 0 
+        sql = sql.replace('%s'%base_fun,'%s'%replace_fun)
+         
+        nest_sql =" select * from (%s) " %sql                
+        sql = sql.replace('limit','limit')
+        self.sql_query_time_cost(sql)
+        tdSql.checkData(0,0,num*per_table_num)
+        
+        self.sql_query_time_cost(nest_sql)
+        tdSql.checkData(0,0,num*per_table_num)
+        
+        sql_0 = re.sub(r'\d\d',"0",sql)
+        self.sql_query_time_cost(sql_0)
+        tdSql.checkData(0,0,0)
+        nest_sql_0 = re.sub(r'\d\d',"0",nest_sql)
+        self.sql_query_time_cost(nest_sql_0)
+        tdSql.checkData(0,0,0)
+
+    def sql_limit_not_test_slimitkeep_return_per_table_num_times_tables(self,sql,num,tables,per_table_num,base_fun,replace_fun): 
+        #sql sql slmit n = per_table_num*tables;sql slimit 0  = 0   
+        sql = sql.replace('%s'%base_fun,'%s'%replace_fun)
+         
+        nest_sql =" select * from (%s) " %sql         
+        self.sql_query_time_cost(sql)
+        tdSql.checkRows(tables*per_table_num)
+        
+        self.sql_query_time_cost(nest_sql)
+        tdSql.checkRows(tables*per_table_num)
+        
+        sql_0 = re.sub(r'\d\d',"0",sql)
+        self.sql_query_time_cost(sql_0)
+        tdSql.checkRows(0)
+        nest_sql_0 = re.sub(r'\d\d',"0",nest_sql)
+        self.sql_query_time_cost(nest_sql_0)
+        tdSql.checkRows(0)
+
+    def sql_data_limit_not_test_slimitkeep_return_per_table_num_times_tables(self,sql,num,tables,per_table_num,base_fun,replace_fun): 
+        #sql sql slmit n = per_table_num*tables;sql slimit 0  = 0   
+        sql = sql.replace('%s'%base_fun,'%s'%replace_fun)
+         
+        nest_sql =" select * from (%s) " %sql         
+        self.sql_query_time_cost(sql)
+        tdSql.checkData(0,0,tables*per_table_num)
+        
+        self.sql_query_time_cost(nest_sql)
+        tdSql.checkData(0,0,tables*per_table_num)
+        
+        sql_0 = re.sub(r'\d\d',"0",sql)
+        self.sql_query_time_cost(sql_0)
+        tdSql.checkData(0,0,0)
+        nest_sql_0 = re.sub(r'\d\d',"0",nest_sql)
+        self.sql_query_time_cost(nest_sql_0)
+        tdSql.checkData(0,0,0)
+        
+    def sql_limit_retun_n_times_n2_slimitkeep_return_n_times_n2(self,sql,num,num2,tables,per_table_num,base_fun,replace_fun): 
+        #sql limit n =n*num2;sql limit 0 = 0 ;sql slmit n = num2*n;sql slimit 0  = 0 
+        sql = sql.replace('%s'%base_fun,'%s'%replace_fun)
+         
+        nest_sql =" select * from (%s) " %sql            
+        self.sql_query_time_cost(sql)
+        tdSql.checkRows(num*num2)        
+        self.sql_query_time_cost(nest_sql)
+        tdSql.checkRows(num*num2)
+        
+        sql_0 = re.sub(r'\d\d',"0",sql)
+        self.sql_query_time_cost(sql_0)
+        tdSql.checkRows(0)
+        nest_sql_0 = re.sub(r'\d\d',"0",nest_sql)
+        self.sql_query_time_cost(nest_sql_0)
+        tdSql.checkRows(0)
+        
+        sql = sql.replace('limit','limit')
+        self.sql_query_time_cost(sql)
+        tdSql.checkRows(num*num2)   
+        nest_sql = nest_sql.replace('limit','limit')  
+        self.sql_query_time_cost(nest_sql)
+        tdSql.checkRows(num*num2)
+        
+        sql_0 = re.sub(r'\d\d',"0",sql)
+        self.sql_query_time_cost(sql_0)
+        tdSql.checkRows(0)
+        nest_sql_0 = re.sub(r'\d\d',"0",nest_sql)
+        self.sql_query_time_cost(nest_sql_0)
+        tdSql.checkRows(0)
+        
+    def sql_data_limit_retun_n_times_n2_slimitkeep_return_n_times_n2(self,sql,num,num2,tables,per_table_num,base_fun,replace_fun): 
+        #sql limit n =n*num2;sql limit 0 = 0 ;sql slmit n = num2*n;sql slimit 0  = 0 
+        sql = sql.replace('%s'%base_fun,'%s'%replace_fun)
+         
+        nest_sql =" select * from (%s) " %sql            
+        self.sql_query_time_cost(sql)
+        tdSql.checkData(0,0,num*num2)        
+        self.sql_query_time_cost(nest_sql)
+        tdSql.checkData(0,0,num*num2)
+        
+        sql_0 = re.sub(r'\d\d',"0",sql)
+        self.sql_query_time_cost(sql_0)
+        tdSql.checkData(0,0,0)
+        nest_sql_0 = re.sub(r'\d\d',"0",nest_sql)
+        self.sql_query_time_cost(nest_sql_0)
+        tdSql.checkData(0,0,0)
+        
+        sql = sql.replace('limit','limit')
+        self.sql_query_time_cost(sql)
+        tdSql.checkData(0,0,num*num2)   
+        nest_sql = nest_sql.replace('limit','limit')  
+        self.sql_query_time_cost(nest_sql)
+        tdSql.checkData(0,0,num*num2)
+        
+        sql_0 = re.sub(r'\d\d',"0",sql)
+        self.sql_query_time_cost(sql_0)
+        tdSql.checkData(0,0,0)
+        nest_sql_0 = re.sub(r'\d\d',"0",nest_sql)
+        self.sql_query_time_cost(nest_sql_0)
+        tdSql.checkData(0,0,0)
+        
+    def sql_limit_times_slimitkeep_return_n2(self,sql,num,num2,tables,per_table_num,base_fun,replace_fun): 
+        #sql limit n =n*num2;sql limit 0 = 0 ;sql slmit n = num2*n;sql slimit 0  = 0   
+        sql = sql.replace('%s'%base_fun,'%s'%replace_fun)
+         
+        nest_sql =" select * from (%s) " %sql     
+        self.sql_query_time_cost(sql)
+        tdSql.checkRows(num2)      
+        self.sql_query_time_cost(nest_sql)
+        tdSql.checkRows(num2)
+        
+        sql_0 = re.sub(r'\d\d',"0",sql)
+        self.sql_query_time_cost(sql_0)
+        tdSql.checkRows(0)
+        nest_sql_0 = re.sub(r'\d\d',"0",nest_sql)
+        self.sql_query_time_cost(nest_sql_0)
+        tdSql.checkRows(0)
+        
+    def sql_data_limit_times_slimitkeep_return_n2(self,sql,num,num2,tables,per_table_num,base_fun,replace_fun): 
+        #sql limit n =n*num2;sql limit 0 = 0 ;sql slmit n = num2*n;sql slimit 0  = 0   
+        sql = sql.replace('%s'%base_fun,'%s'%replace_fun)
+         
+        nest_sql =" select * from (%s) " %sql     
+        self.sql_query_time_cost(sql)
+        tdSql.checkData(0,0,num2)      
+        self.sql_query_time_cost(nest_sql)
+        tdSql.checkData(0,0,num2)
+        
+        sql_0 = re.sub(r'\d\d',"0",sql)
+        self.sql_query_time_cost(sql_0)
+        tdSql.checkData(0,0,0)
+        nest_sql_0 = re.sub(r'\d\d',"0",nest_sql)
+        self.sql_query_time_cost(nest_sql_0)
+        tdSql.checkData(0,0,0)
+
+    def sql_retun_error(self,sql,base_fun,replace_fun): 
+        #sql limit n = error;sql limit 0 = error ;sql slmit n = error ;sql slimit 0 = error 
+        sql = sql.replace('%s'%base_fun,'%s'%replace_fun)
+          
+        nest_sql =" select * from (%s) " %sql            
+        tdSql.error(sql)
+        tdSql.error(nest_sql)
+        
+        sql_0 = re.sub(r'\d+',"0",sql)
+        tdSql.error(sql)
+        nest_sql_0 = re.sub(r'\d\d',"0",nest_sql)
+        tdSql.error(nest_sql_0)
+        
+        sql = sql.replace('limit','slimit')
+        tdSql.error(sql)
+        nest_sql = nest_sql.replace('limit','slimit')
+        tdSql.error(nest_sql)
+        
+        sql_0 = re.sub(r'\d+',"0",sql)
+        tdSql.error(sql_0)
+        nest_sql_0 = re.sub(r'\d\d',"0",nest_sql)
+        tdSql.error(nest_sql_0)
+
+    def fun_base(self,dbname,num,num2,tables,per_table_num,dbnamejoin,base_fun,replace_fun):
+        
+        tdLog.info("base query ---------1----------")
+        sql = "select * from %s.meters limit %d" %(dbname,num)
+        self.sql_limit_retun_n_slimit_return_error(sql,num,tables,per_table_num,base_fun,replace_fun)        
+        sql = "select count(*) from (%s)" %sql
+        self.sql_data_limit_retun_n_slimit_return_error(sql,num,tables,per_table_num,base_fun,replace_fun)  
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_data_limit_retun_n_slimit_return_error(sql_union,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_data_limit_retun_n_slimit_return_error(sql_union_all,num,tables,per_table_num,base_fun,replace_fun)
+        
+        sql_join = "select a.* from %s.meters a,%s.meters b where a.ts = b.ts limit %d" %(dbname,dbnamejoin,num)
+        self.sql_limit_retun_n_slimit_return_error(sql_join,num,tables,per_table_num,base_fun,replace_fun)  
+        sql_join = "select count(*) from (%s)" %sql_join
+        self.sql_data_limit_retun_n_slimit_return_error(sql_join,num,tables,per_table_num,base_fun,replace_fun) 
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_data_limit_retun_n_slimit_return_error(sql_union,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_data_limit_retun_n_slimit_return_error(sql_union_all,num,tables,per_table_num,base_fun,replace_fun)
+        
+        
+        
+        tdLog.info("base query ---------2----------")
+        sql = "select * from %s.meters where ts is not null limit %d" %(dbname,num)
+        self.sql_limit_retun_n_slimit_return_error(sql,num,tables,per_table_num,base_fun,replace_fun)
+        sql = "select count(*) from (%s)" %sql
+        self.sql_data_limit_retun_n_slimit_return_error(sql,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_data_limit_retun_n_slimit_return_error(sql_union,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_data_limit_retun_n_slimit_return_error(sql_union_all,num,tables,per_table_num,base_fun,replace_fun)
+        
+        sql_join = "select a.* from %s.meters a,%s.meters b where a.ts is not null and  a.ts = b.ts limit %d" %(dbname,dbnamejoin,num)
+        self.sql_limit_retun_n_slimit_return_error(sql_join,num,tables,per_table_num,base_fun,replace_fun)
+        sql_join = "select count(*) from (%s)" %sql_join
+        self.sql_data_limit_retun_n_slimit_return_error(sql_join,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_data_limit_retun_n_slimit_return_error(sql_union,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_data_limit_retun_n_slimit_return_error(sql_union_all,num,tables,per_table_num,base_fun,replace_fun)
+        
+        
+        
+        tdLog.info("base query ---------3----------")
+        sql = "select * from %s.meters where ts is not null order by ts limit %d" %(dbname,num)
+        self.sql_limit_retun_n_slimit_return_error(sql,num,tables,per_table_num,base_fun,replace_fun)
+        sql = "select count(*) from (%s)" %sql
+        self.sql_data_limit_retun_n_slimit_return_error(sql,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_data_limit_retun_n_slimit_return_error(sql_union,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_data_limit_retun_n_slimit_return_error(sql_union_all,num,tables,per_table_num,base_fun,replace_fun)
+        
+        sql_join = "select a.* from %s.meters a,%s.meters b where a.ts is not null  and  a.ts = b.ts order by b.ts limit %d" %(dbname,dbnamejoin,num)
+        self.sql_limit_retun_n_slimit_return_error(sql_join,num,tables,per_table_num,base_fun,replace_fun)
+        sql_join = "select count(*) from (%s)" %sql_join
+        self.sql_data_limit_retun_n_slimit_return_error(sql_join,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_data_limit_retun_n_slimit_return_error(sql_union,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_data_limit_retun_n_slimit_return_error(sql_union_all,num,tables,per_table_num,base_fun,replace_fun)
+        
+        
+        tdLog.info("base query ---------4----------")
+        sql = "select * from %s.meters where ts is not null order by ts desc limit %d" %(dbname,num)
+        self.sql_limit_retun_n_slimit_return_error(sql,num,tables,per_table_num,base_fun,replace_fun)
+        sql = "select count(*) from (%s)" %sql
+        self.sql_data_limit_retun_n_slimit_return_error(sql,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_data_limit_retun_n_slimit_return_error(sql_union,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_data_limit_retun_n_slimit_return_error(sql_union_all,num,tables,per_table_num,base_fun,replace_fun)
+               
+        sql_join = "select a.* from %s.meters a,%s.meters b where b.ts is not null and  a.ts = b.ts order by a.ts desc limit %d" %(dbname,dbnamejoin,num)
+        self.sql_limit_retun_n_slimit_return_error(sql_join,num,tables,per_table_num,base_fun,replace_fun)
+        sql_join = "select count(*) from (%s)" %sql_join
+        self.sql_data_limit_retun_n_slimit_return_error(sql_join,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_data_limit_retun_n_slimit_return_error(sql_union,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_data_limit_retun_n_slimit_return_error(sql_union_all,num,tables,per_table_num,base_fun,replace_fun)
+    
+    def fun_count(self,dbname,num,num2,tables,per_table_num,dbnamejoin,base_fun,replace_fun):
+        
+        tdLog.info("count query ---------1----------")       
+        sql = "select count(*) from %s.meters limit %d" %(dbname,num)
+        self.sql_limit_retun_1_slimit_return_error(sql,tables,per_table_num,base_fun,replace_fun)
+        sql = "select count(*) from (%s)" %sql
+        self.sql_data_limit_retun_1_slimit_return_error(sql,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_data_limit_retun_1_slimit_return_error(sql_union,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_data_limit_retun_1_slimit_return_error(sql_union_all,tables,per_table_num,base_fun,replace_fun)
+        
+        sql_join = "select count(a.*) from %s.meters a,%s.meters b where a.ts = b.ts limit %d" %(dbname,dbnamejoin,num)
+        self.sql_limit_retun_1_slimit_return_error(sql_join,tables,per_table_num,base_fun,replace_fun)
+        sql_join = "select count(*) from (%s)" %sql_join
+        self.sql_data_limit_retun_1_slimit_return_error(sql_join,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_data_limit_retun_1_slimit_return_error(sql_union,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_data_limit_retun_1_slimit_return_error(sql_union_all,tables,per_table_num,base_fun,replace_fun)
+        
+        
+        
+        
+        tdLog.info("count query ---------2----------")
+        sql = "select count(*) from %s.meters where ts is not null limit %d" %(dbname,num)
+        self.sql_limit_retun_1_slimit_return_error(sql,tables,per_table_num,base_fun,replace_fun)
+        sql = "select count(*) from (%s)" %sql
+        self.sql_data_limit_retun_1_slimit_return_error(sql,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_data_limit_retun_1_slimit_return_error(sql_union,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_data_limit_retun_1_slimit_return_error(sql_union_all,tables,per_table_num,base_fun,replace_fun)
+        
+        sql_join = "select count(a.*) from %s.meters a,%s.meters b where a.ts is not null and  a.ts = b.ts limit %d" %(dbname,dbnamejoin,num)
+        self.sql_limit_retun_1_slimit_return_error(sql_join,tables,per_table_num,base_fun,replace_fun)
+        sql_join = "select count(*) from (%s)" %sql_join
+        self.sql_data_limit_retun_1_slimit_return_error(sql_join,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_data_limit_retun_1_slimit_return_error(sql_union,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_data_limit_retun_1_slimit_return_error(sql_union_all,tables,per_table_num,base_fun,replace_fun)
+        
+        
+        
+        tdLog.info("count query ---------3----------")
+        sql = "select count(*) from %s.meters where ts is not null order by ts limit %d" %(dbname,num)
+        self.sql_retun_error(sql,base_fun,replace_fun)
+        sql = "select count(*) from (%s)" %sql
+        self.sql_retun_error(sql,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_retun_error(sql_union,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_retun_error(sql_union_all,base_fun,replace_fun)
+        
+        sql_join = "select count(a.*) from %s.meters a,%s.meters b where a.ts is not null and  a.ts = b.ts order by b.ts limit %d" %(dbname,dbnamejoin,num)
+        self.sql_retun_error(sql_join,base_fun,replace_fun)
+        sql_join = "select count(*) from (%s)" %sql_join
+        self.sql_retun_error(sql_join,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_retun_error(sql_union,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_retun_error(sql_union_all,base_fun,replace_fun)
+        
+        
+        
+        tdLog.info("count query ---------4----------")
+        sql = "select count(*) from %s.meters where ts is not null order by ts desc limit %d" %(dbname,num)        
+        self.sql_retun_error(sql,base_fun,replace_fun)
+        sql = "select count(*) from (%s)" %sql
+        self.sql_retun_error(sql,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_retun_error(sql_union,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_retun_error(sql_union_all,base_fun,replace_fun)
+        
+        sql_join = "select count(a.*) from %s.meters a,%s.meters b where b.ts is not null and  a.ts = b.ts order by a.ts desc limit %d" %(dbname,dbnamejoin,num)        
+        self.sql_retun_error(sql_join,base_fun,replace_fun)
+        sql_join = "select count(*) from (%s)" %sql_join
+        self.sql_retun_error(sql_join,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_retun_error(sql_union,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_retun_error(sql_union_all,base_fun,replace_fun)
+        
+        
+        
+        tdLog.info("count query ---------5----------")
+        sql = "select count(*) from %s.meters where ts is not null group by tbname limit %d" %(dbname,num)
+        self.sql_limit_retun_tables_slimit_return_n(sql,num,tables,per_table_num,base_fun,replace_fun)        
+        sql = "select count(*) from (%s)" %sql
+        self.sql_data_limit_retun_tables_slimit_return_n(sql,num,tables,per_table_num,base_fun,replace_fun) 
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_data_limit_retun_tables_slimit_return_n(sql_union,num,tables,per_table_num,base_fun,replace_fun) 
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_data_limit_retun_tables_slimit_return_n(sql_union_all,num,tables,per_table_num,base_fun,replace_fun) 
+        
+        sql_join = "select count(*) from %s.meters a,%s.meters b where a.ts is not null and a.ts = b.ts group by b.tbname limit %d" %(dbname,dbnamejoin,num)
+        self.sql_limit_retun_tables_slimit_return_n(sql_join,num,tables,per_table_num,base_fun,replace_fun)        
+        sql_join = "select count(*) from (%s)" %sql_join
+        self.sql_data_limit_retun_tables_slimit_return_n(sql_join,num,tables,per_table_num,base_fun,replace_fun) 
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_data_limit_retun_tables_slimit_return_n(sql_union,num,tables,per_table_num,base_fun,replace_fun) 
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_data_limit_retun_tables_slimit_return_n(sql_union_all,num,tables,per_table_num,base_fun,replace_fun) 
+        
+        
+        
+        
+        tdLog.info("count query ---------6----------")
+        sql = "select count(*) from %s.meters where ts is not null partition by tbname limit %d" %(dbname,num)
+        self.sql_limit_retun_tables_slimit_return_n(sql,num,tables,per_table_num,base_fun,replace_fun) 
+        sql = "select count(*) from (%s)" %sql
+        self.sql_data_limit_retun_tables_slimit_return_n(sql,num,tables,per_table_num,base_fun,replace_fun) 
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_data_limit_retun_tables_slimit_return_n(sql_union,num,tables,per_table_num,base_fun,replace_fun) 
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_data_limit_retun_tables_slimit_return_n(sql_union_all,num,tables,per_table_num,base_fun,replace_fun) 
+        
+        sql_join = "select count(*) from %s.meters a,%s.meters b where a.ts is not null and a.ts = b.ts partition by b.tbname limit %d" %(dbname,dbnamejoin,num)
+        self.sql_limit_retun_tables_slimit_return_n(sql_join,num,tables,per_table_num,base_fun,replace_fun) 
+        sql_join = "select count(*) from (%s)" %sql_join
+        self.sql_data_limit_retun_tables_slimit_return_n(sql_join,num,tables,per_table_num,base_fun,replace_fun) 
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_data_limit_retun_tables_slimit_return_n(sql_union,num,tables,per_table_num,base_fun,replace_fun) 
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_data_limit_retun_tables_slimit_return_n(sql_union_all,num,tables,per_table_num,base_fun,replace_fun) 
+        
+        
+        
+        tdLog.info("count query ---------7----------")
+        sql = "select count(*) cc from %s.meters where ts is not null group by tbname order by cc limit %d" %(dbname,num)
+        self.sql_limit_retun_n_slimit_return_tables(sql,num,tables,per_table_num,base_fun,replace_fun)
+        sql = "select count(*) from (%s)" %sql
+        self.sql_data_limit_retun_n_slimit_return_tables(sql,num,tables,per_table_num,base_fun,replace_fun) 
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_data_limit_retun_n_slimit_return_tables(sql_union,num,tables,per_table_num,base_fun,replace_fun) 
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_data_limit_retun_n_slimit_return_tables(sql_union_all,num,tables,per_table_num,base_fun,replace_fun) 
+        
+        sql_join  = "select count(*) cc from %s.meters a,%s.meters b where a.ts is not null and a.ts = b.ts group by b.tbname order by cc limit %d" %(dbname,dbnamejoin,num)
+        self.sql_limit_retun_n_slimit_return_tables(sql_join,num,tables,per_table_num,base_fun,replace_fun)
+        sql_join = "select count(*) from (%s)" %sql_join
+        self.sql_data_limit_retun_n_slimit_return_tables(sql_join,num,tables,per_table_num,base_fun,replace_fun) 
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_data_limit_retun_n_slimit_return_tables(sql_union,num,tables,per_table_num,base_fun,replace_fun) 
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_data_limit_retun_n_slimit_return_tables(sql_union_all,num,tables,per_table_num,base_fun,replace_fun) 
+        
+        
+        
+        tdLog.info("count query ---------8----------")
+        sql = "select count(*) cc from %s.meters where ts is not null partition by tbname order by cc limit %d" %(dbname,num)
+        self.sql_limit_retun_n_slimit_return_tables(sql,num,tables,per_table_num,base_fun,replace_fun)
+        sql = "select count(*) from (%s)" %sql
+        self.sql_data_limit_retun_n_slimit_return_tables(sql,num,tables,per_table_num,base_fun,replace_fun) 
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_data_limit_retun_n_slimit_return_tables(sql_union,num,tables,per_table_num,base_fun,replace_fun) 
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_data_limit_retun_n_slimit_return_tables(sql_union_all,num,tables,per_table_num,base_fun,replace_fun) 
+        
+        sql_join = "select count(*) cc from %s.meters a,%s.meters b where a.ts is not null and a.ts = b.ts partition by b.tbname order by cc limit %d" %(dbname,dbnamejoin,num)
+        self.sql_limit_retun_n_slimit_return_tables(sql_join,num,tables,per_table_num,base_fun,replace_fun)
+        sql_join = "select count(*) from (%s)" %sql_join
+        self.sql_data_limit_retun_n_slimit_return_tables(sql_join,num,tables,per_table_num,base_fun,replace_fun) 
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_data_limit_retun_n_slimit_return_tables(sql_union,num,tables,per_table_num,base_fun,replace_fun) 
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_data_limit_retun_n_slimit_return_tables(sql_union_all,num,tables,per_table_num,base_fun,replace_fun) 
+        
+        
+        
+        tdLog.info("count query ---------9----------")
+        sql = "select count(*) cc from %s.meters where ts is not null interval(1a) limit %d" %(dbname,num)
+        self.sql_limit_retun_n_slimit_return_error(sql,num,tables,per_table_num,base_fun,replace_fun)
+        sql = "select count(*) from (%s)" %sql
+        self.sql_data_limit_retun_n_slimit_return_error(sql,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_data_limit_retun_n_slimit_return_error(sql_union,num,tables,per_table_num,base_fun,replace_fun) 
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_data_limit_retun_n_slimit_return_error(sql_union_all,num,tables,per_table_num,base_fun,replace_fun) 
+        
+        sql_join  = "select count(*) cc from %s.meters a,%s.meters b where a.ts is not null and a.ts = b.ts interval(1a) limit %d" %(dbname,dbnamejoin,num)
+        self.sql_limit_retun_n_slimit_return_error(sql_join,num,tables,per_table_num,base_fun,replace_fun)
+        sql_join = "select count(*) from (%s)" %sql_join
+        self.sql_data_limit_retun_n_slimit_return_error(sql_join,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_data_limit_retun_n_slimit_return_error(sql_union,num,tables,per_table_num,base_fun,replace_fun) 
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_data_limit_retun_n_slimit_return_error(sql_union_all,num,tables,per_table_num,base_fun,replace_fun) 
+        
+        
+        
+        tdLog.info("count query ---------10----------")
+        sql = "select count(*) cc from %s.meters where ts is not null interval(1a) order by cc asc limit %d" %(dbname,num)
+        self.sql_limit_retun_n_slimit_return_error(sql,num,tables,per_table_num,base_fun,replace_fun)
+        sql = "select count(*) from (%s)" %sql
+        self.sql_data_limit_retun_n_slimit_return_error(sql,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_data_limit_retun_n_slimit_return_error(sql_union,num,tables,per_table_num,base_fun,replace_fun) 
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_data_limit_retun_n_slimit_return_error(sql_union_all,num,tables,per_table_num,base_fun,replace_fun) 
+        
+        sql_join = "select count(*) cc from %s.meters a,%s.meters b where a.ts is not null and a.ts = b.ts interval(1a) order by cc asc limit %d" %(dbname,dbnamejoin,num)
+        self.sql_limit_retun_n_slimit_return_error(sql_join,num,tables,per_table_num,base_fun,replace_fun)
+        sql_join = "select count(*) from (%s)" %sql_join
+        self.sql_data_limit_retun_n_slimit_return_error(sql_join,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_data_limit_retun_n_slimit_return_error(sql_union,num,tables,per_table_num,base_fun,replace_fun) 
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_data_limit_retun_n_slimit_return_error(sql_union_all,num,tables,per_table_num,base_fun,replace_fun) 
+        
+        
+        
+        tdLog.info("count query ---------11----------")
+        sql = "select count(*) cc from %s.meters where ts is not null interval(1a) order by cc desc limit %d" %(dbname,num)
+        self.sql_limit_retun_n_slimit_return_error(sql,num,tables,per_table_num,base_fun,replace_fun)
+        sql = "select count(*) from (%s)" %sql
+        self.sql_data_limit_retun_n_slimit_return_error(sql,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_data_limit_retun_n_slimit_return_error(sql_union,num,tables,per_table_num,base_fun,replace_fun) 
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_data_limit_retun_n_slimit_return_error(sql_union_all,num,tables,per_table_num,base_fun,replace_fun) 
+        
+        sql_join = "select count(*) cc from %s.meters a,%s.meters b where a.ts is not null and a.ts = b.ts interval(1a) order by cc desc limit %d" %(dbname,dbnamejoin,num)
+        self.sql_limit_retun_n_slimit_return_error(sql_join,num,tables,per_table_num,base_fun,replace_fun)
+        sql_join = "select count(*) from (%s)" %sql_join
+        self.sql_data_limit_retun_n_slimit_return_error(sql_join,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_data_limit_retun_n_slimit_return_error(sql_union,num,tables,per_table_num,base_fun,replace_fun) 
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_data_limit_retun_n_slimit_return_error(sql_union_all,num,tables,per_table_num,base_fun,replace_fun) 
+        
+        
+        
+        tdLog.info("count query ---------12----------")
+        sql = "select tbname,count(*) cc from %s.meters where ts is not null interval(1a) group by tbname limit %d" %(dbname,num)
+        self.sql_retun_error(sql,base_fun,replace_fun)
+        sql = "select count(*) from (%s)" %sql
+        self.sql_retun_error(sql,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_retun_error(sql_union,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_retun_error(sql_union_all,base_fun,replace_fun)
+        
+        sql_join = "select a.tbname,count(*) cc from %s.meters a,%s.meters b where a.ts is not null and a.ts = b.ts interval(1a) group by b.tbname limit %d" %(dbname,dbnamejoin,num)
+        self.sql_retun_error(sql_join,base_fun,replace_fun)
+        sql_join = "select count(*) from (%s)" %sql_join
+        self.sql_retun_error(sql_join,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_retun_error(sql_union,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_retun_error(sql_union_all,base_fun,replace_fun)
+        
+        
+        
+        tdLog.info("count query ---------13----------")
+        sql = "select tbname,count(*) cc from %s.meters where ts is not null interval(1a) partition by tbname limit %d" %(dbname,num)
+        self.sql_retun_error(sql,base_fun,replace_fun)
+        sql = "select count(*) from (%s)" %sql
+        self.sql_retun_error(sql,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_retun_error(sql_union,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_retun_error(sql_union_all,base_fun,replace_fun)
+        
+        sql_join = "select a.tbname,count(*) cc from %s.meters a,%s.meters b where a.ts is not null and a.ts = b.ts interval(1a) partition by b.tbname limit %d" %(dbname,dbnamejoin,num)
+        self.sql_retun_error(sql_join,base_fun,replace_fun)
+        sql_join = "select count(*) from (%s)" %sql_join
+        self.sql_retun_error(sql_join,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_retun_error(sql_union,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_retun_error(sql_union_all,base_fun,replace_fun)
+        
+        
+        
+        tdLog.info("count query ---------14----------")
+        sql = "select tbname,count(*) cc from %s.meters where ts is not null partition by tbname interval(1a) limit %d" %(dbname,num)
+        self.sql_limit_retun_tables_times_n_slimit_return_per_table_num_times_n(sql,num,tables,per_table_num,base_fun,replace_fun)
+        sql = "select count(*) from (%s)" %sql
+        self.sql_data_limit_retun_tables_times_n_slimit_return_per_table_num_times_n(sql,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_data_limit_retun_tables_times_n_slimit_return_per_table_num_times_n(sql_union,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_data_limit_retun_tables_times_n_slimit_return_per_table_num_times_n(sql_union_all,num,tables,per_table_num,base_fun,replace_fun)
+        
+        sql_join = "select a.tbname,count(*) cc from %s.meters a,%s.meters b where a.ts is not null and a.ts = b.ts partition by a.tbname interval(1a) limit %d" %(dbname,dbnamejoin,num)
+        self.sql_limit_retun_tables_times_n_slimit_return_per_table_num_times_n(sql_join,num,tables,per_table_num,base_fun,replace_fun)
+        sql_join = "select count(*) from (%s)" %sql_join
+        self.sql_data_limit_retun_tables_times_n_slimit_return_per_table_num_times_n(sql_join,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_data_limit_retun_tables_times_n_slimit_return_per_table_num_times_n(sql_union,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_data_limit_retun_tables_times_n_slimit_return_per_table_num_times_n(sql_union_all,num,tables,per_table_num,base_fun,replace_fun)
+        
+        
+        
+        tdLog.info("count query ---------15----------")
+        sql = "select tbname,count(*) cc from %s.meters where ts is not null partition by tbname interval(1a) order by cc asc limit %d" %(dbname,num)
+        self.sql_limit_retun_n_slimit_return_per_table_num_times_tables(sql,num,tables,per_table_num,base_fun,replace_fun)
+        sql = "select count(*) from (%s)" %sql
+        self.sql_data_limit_retun_n_slimit_return_per_table_num_times_tables(sql,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_data_limit_retun_n_slimit_return_per_table_num_times_tables(sql_union,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_data_limit_retun_n_slimit_return_per_table_num_times_tables(sql_union_all,num,tables,per_table_num,base_fun,replace_fun)
+        
+        sql_join = "select a.tbname,count(*) cc from %s.meters a,%s.meters b where a.ts is not null and a.ts = b.ts partition by a.tbname interval(1a) order by cc asc limit %d" %(dbname,dbnamejoin,num)
+        self.sql_limit_retun_n_slimit_return_per_table_num_times_tables(sql_join,num,tables,per_table_num,base_fun,replace_fun)
+        sql_join = "select count(*) from (%s)" %sql_join
+        self.sql_data_limit_retun_n_slimit_return_per_table_num_times_tables(sql_join,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_data_limit_retun_n_slimit_return_per_table_num_times_tables(sql_union,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_data_limit_retun_n_slimit_return_per_table_num_times_tables(sql_union_all,num,tables,per_table_num,base_fun,replace_fun)
+        
+        
+        
+        tdLog.info("count query ---------16----------")
+        sql = "select tbname,count(*) cc from %s.meters where ts is not null partition by tbname interval(1a) order by cc desc limit %d" %(dbname,num)
+        self.sql_limit_retun_n_slimit_return_per_table_num_times_tables(sql,num,tables,per_table_num,base_fun,replace_fun)
+        sql = "select count(*) from (%s)" %sql
+        self.sql_data_limit_retun_n_slimit_return_per_table_num_times_tables(sql,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_data_limit_retun_n_slimit_return_per_table_num_times_tables(sql_union,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_data_limit_retun_n_slimit_return_per_table_num_times_tables(sql_union_all,num,tables,per_table_num,base_fun,replace_fun)
+        
+        sql_join = "select a.tbname,count(*) cc from %s.meters a,%s.meters b where a.ts is not null and a.ts = b.ts partition by a.tbname interval(1a) order by cc desc limit %d" %(dbname,dbnamejoin,num)
+        self.sql_limit_retun_n_slimit_return_per_table_num_times_tables(sql_join,num,tables,per_table_num,base_fun,replace_fun)
+        sql_join = "select count(*) from (%s)" %sql_join
+        self.sql_data_limit_retun_n_slimit_return_per_table_num_times_tables(sql_join,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_data_limit_retun_n_slimit_return_per_table_num_times_tables(sql_union,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_data_limit_retun_n_slimit_return_per_table_num_times_tables(sql_union_all,num,tables,per_table_num,base_fun,replace_fun)
+        
+        
+        
+        tdLog.info("count query ---------17----------")
+        sql = "select tbname,count(*) cc from %s.meters where ts is not null partition by tbname interval(1a) slimit %d" %(dbname,num)
+        self.sql_limit_not_test_slimitkeep_return_per_table_num_times_n(sql,num,tables,per_table_num,base_fun,replace_fun)
+        sql = "select count(*) from (%s)" %sql
+        self.sql_data_limit_not_test_slimitkeep_return_per_table_num_times_n(sql,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_data_limit_not_test_slimitkeep_return_per_table_num_times_n(sql_union,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_data_limit_not_test_slimitkeep_return_per_table_num_times_n(sql_union_all,num,tables,per_table_num,base_fun,replace_fun)
+        
+        sql_join = "select a.tbname,count(*) cc from %s.meters a,%s.meters b where a.ts is not null and a.ts = b.ts partition by a.tbname interval(1a) slimit %d" %(dbname,dbnamejoin,num)
+        self.sql_limit_not_test_slimitkeep_return_per_table_num_times_n(sql_join,num,tables,per_table_num,base_fun,replace_fun)
+        sql_join = "select count(*) from (%s)" %sql_join
+        self.sql_data_limit_not_test_slimitkeep_return_per_table_num_times_n(sql_join,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_data_limit_not_test_slimitkeep_return_per_table_num_times_n(sql_union,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_data_limit_not_test_slimitkeep_return_per_table_num_times_n(sql_union_all,num,tables,per_table_num,base_fun,replace_fun)
+        
+        
+        
+        tdLog.info("count query ---------18----------")
+        sql = "select tbname,count(*) cc from %s.meters where ts is not null partition by tbname interval(1a) order by cc asc slimit %d" %(dbname,num)
+        self.sql_limit_not_test_slimitkeep_return_per_table_num_times_tables(sql,num,tables,per_table_num,base_fun,replace_fun)
+        sql = "select count(*) from (%s)" %sql
+        self.sql_data_limit_not_test_slimitkeep_return_per_table_num_times_tables(sql,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_data_limit_not_test_slimitkeep_return_per_table_num_times_tables(sql_union,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_data_limit_not_test_slimitkeep_return_per_table_num_times_tables(sql_union_all,num,tables,per_table_num,base_fun,replace_fun)
+        
+        sql_join = "select a.tbname,count(*) cc from %s.meters a,%s.meters b where a.ts is not null and a.ts = b.ts partition by a.tbname interval(1a) order by cc asc slimit %d" %(dbname,dbnamejoin,num)
+        self.sql_limit_not_test_slimitkeep_return_per_table_num_times_tables(sql_join,num,tables,per_table_num,base_fun,replace_fun)
+        sql_join = "select count(*) from (%s)" %sql_join
+        self.sql_data_limit_not_test_slimitkeep_return_per_table_num_times_tables(sql_join,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_data_limit_not_test_slimitkeep_return_per_table_num_times_tables(sql_union,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_data_limit_not_test_slimitkeep_return_per_table_num_times_tables(sql_union_all,num,tables,per_table_num,base_fun,replace_fun)
+        
+        
+        tdLog.info("count query ---------19----------")
+        sql = "select tbname,count(*) cc from %s.meters where ts is not null partition by tbname interval(1a) order by cc desc slimit %d" %(dbname,num)
+        self.sql_limit_not_test_slimitkeep_return_per_table_num_times_tables(sql,num,tables,per_table_num,base_fun,replace_fun)
+        sql = "select count(*) from (%s)" %sql
+        self.sql_data_limit_not_test_slimitkeep_return_per_table_num_times_tables(sql,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_data_limit_not_test_slimitkeep_return_per_table_num_times_tables(sql_union,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_data_limit_not_test_slimitkeep_return_per_table_num_times_tables(sql_union_all,num,tables,per_table_num,base_fun,replace_fun)
+        
+        sql_join = "select a.tbname,count(*) cc from %s.meters a,%s.meters b where a.ts is not null and a.ts = b.ts partition by a.tbname interval(1a) order by cc desc slimit %d" %(dbname,dbnamejoin,num)
+        self.sql_limit_not_test_slimitkeep_return_per_table_num_times_tables(sql_join,num,tables,per_table_num,base_fun,replace_fun)
+        sql_join = "select count(*) from (%s)" %sql_join
+        self.sql_data_limit_not_test_slimitkeep_return_per_table_num_times_tables(sql_join,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_data_limit_not_test_slimitkeep_return_per_table_num_times_tables(sql_union,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_data_limit_not_test_slimitkeep_return_per_table_num_times_tables(sql_union_all,num,tables,per_table_num,base_fun,replace_fun)
+        
+        
+        
+        tdLog.info("count query ---------20----------")
+        sql = "select tbname,count(*) cc from %s.meters where ts is not null partition by tbname interval(1a) slimit %d limit %d" %(dbname,num,num2)
+        self.sql_limit_retun_n_times_n2_slimitkeep_return_n_times_n2(sql,num,num2,tables,per_table_num,base_fun,replace_fun)
+        sql = "select count(*) from (%s)" %sql
+        self.sql_data_limit_retun_n_times_n2_slimitkeep_return_n_times_n2(sql,num,num2,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_data_limit_retun_n_times_n2_slimitkeep_return_n_times_n2(sql_union,num,num2,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_data_limit_retun_n_times_n2_slimitkeep_return_n_times_n2(sql_union_all,num,num2,tables,per_table_num,base_fun,replace_fun)
+        
+        sql_join = "select a.tbname,count(*) cc from %s.meters a,%s.meters b where a.ts is not null and a.ts = b.ts partition by a.tbname interval(1a) slimit %d limit %d" %(dbname,dbnamejoin,num,num2)
+        self.sql_limit_retun_n_times_n2_slimitkeep_return_n_times_n2(sql_join,num,num2,tables,per_table_num,base_fun,replace_fun)
+        sql_join = "select count(*) from (%s)" %sql_join
+        self.sql_data_limit_retun_n_times_n2_slimitkeep_return_n_times_n2(sql_join,num,num2,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_data_limit_retun_n_times_n2_slimitkeep_return_n_times_n2(sql_union,num,num2,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_data_limit_retun_n_times_n2_slimitkeep_return_n_times_n2(sql_union_all,num,num2,tables,per_table_num,base_fun,replace_fun)
+        
+        
+        tdLog.info("count query ---------21----------")
+        sql = "select tbname,count(*) cc from %s.meters where ts is not null partition by tbname interval(1a) order by cc asc slimit %d limit %d" %(dbname,num,num2)
+        self.sql_limit_times_slimitkeep_return_n2(sql,num,num2,tables,per_table_num,base_fun,replace_fun)
+        sql = "select count(*) from (%s)" %sql
+        self.sql_data_limit_times_slimitkeep_return_n2(sql,num,num2,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_data_limit_times_slimitkeep_return_n2(sql_union,num,num2,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_data_limit_times_slimitkeep_return_n2(sql_union_all,num,num2,tables,per_table_num,base_fun,replace_fun)       
+        
+        sql_join = "select a.tbname,count(*) cc from %s.meters a,%s.meters b where a.ts is not null and a.ts = b.ts partition by a.tbname interval(1a) order by cc asc slimit %d limit %d" %(dbname,dbnamejoin,num,num2)
+        self.sql_limit_times_slimitkeep_return_n2(sql_join,num,num2,tables,per_table_num,base_fun,replace_fun)
+        sql_join = "select count(*) from (%s)" %sql_join
+        self.sql_data_limit_times_slimitkeep_return_n2(sql_join,num,num2,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_data_limit_times_slimitkeep_return_n2(sql_union,num,num2,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_data_limit_times_slimitkeep_return_n2(sql_union_all,num,num2,tables,per_table_num,base_fun,replace_fun)
+        
+        
+        tdLog.info("count query ---------22----------")
+        sql = "select tbname,count(*) cc from %s.meters where ts is not null partition by tbname interval(1a) order by cc desc slimit %d limit %d" %(dbname,num,num2)
+        self.sql_limit_times_slimitkeep_return_n2(sql,num,num2,tables,per_table_num,base_fun,replace_fun)
+        sql = "select count(*) from (%s)" %sql
+        self.sql_data_limit_times_slimitkeep_return_n2(sql,num,num2,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_data_limit_times_slimitkeep_return_n2(sql_union,num,num2,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_data_limit_times_slimitkeep_return_n2(sql_union_all,num,num2,tables,per_table_num,base_fun,replace_fun)
+        
+        sql_join = "select a.tbname,count(*) cc from %s.meters a,%s.meters b where a.ts is not null and a.ts = b.ts partition by a.tbname interval(1a) order by cc desc slimit %d limit %d" %(dbname,dbnamejoin,num,num2)
+        self.sql_limit_times_slimitkeep_return_n2(sql_join,num,num2,tables,per_table_num,base_fun,replace_fun)
+        sql_join = "select count(*) from (%s)" %sql_join
+        self.sql_data_limit_times_slimitkeep_return_n2(sql_join,num,num2,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_data_limit_times_slimitkeep_return_n2(sql_union,num,num2,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_data_limit_times_slimitkeep_return_n2(sql_union_all,num,num2,tables,per_table_num,base_fun,replace_fun)
+        
+         
+    def fun_last(self,dbname,num,num2,tables,per_table_num,dbnamejoin,base_fun,replace_fun):
+        
+        tdLog.info("last query ---------1----------")       
+        sql = "select last(*) from %s.meters limit %d" %(dbname,num)
+        self.sql_limit_retun_1_slimit_return_error(sql,tables,per_table_num,base_fun,replace_fun)
+        sql = "select last(*) from (%s)" %sql
+        self.sql_limit_retun_1_slimit_return_error(sql,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_last_limit_retun_1_slimit_return_error(sql_union,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_last_limit_retun_1_slimit_return_error(sql_union_all,tables,per_table_num,base_fun,replace_fun)
+        
+        sql_join = "select last(a.*) from %s.meters a,%s.meters b where a.ts = b.ts limit %d" %(dbname,dbnamejoin,num)
+        self.sql_limit_retun_1_slimit_return_error(sql_join,tables,per_table_num,base_fun,replace_fun)
+        sql_join = "select last(*) from (%s)" %sql_join
+        self.sql_limit_retun_1_slimit_return_error(sql_join,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_last_limit_retun_1_slimit_return_error(sql_union,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_last_limit_retun_1_slimit_return_error(sql_union_all,tables,per_table_num,base_fun,replace_fun)
+        
+        
+        
+        
+        tdLog.info("last query ---------2----------")
+        sql = "select last(*) from %s.meters where ts is not null limit %d" %(dbname,num)
+        self.sql_limit_retun_1_slimit_return_error(sql,tables,per_table_num,base_fun,replace_fun)
+        sql = "select last(*) from (%s)" %sql
+        self.sql_limit_retun_1_slimit_return_error(sql,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_last_limit_retun_1_slimit_return_error(sql_union,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_last_limit_retun_1_slimit_return_error(sql_union_all,tables,per_table_num,base_fun,replace_fun)
+        
+        sql_join = "select last(a.*) from %s.meters a,%s.meters b where a.ts is not null and  a.ts = b.ts limit %d" %(dbname,dbnamejoin,num)
+        self.sql_limit_retun_1_slimit_return_error(sql_join,tables,per_table_num,base_fun,replace_fun)
+        sql_join = "select last(*) from (%s)" %sql_join
+        self.sql_limit_retun_1_slimit_return_error(sql_join,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_last_limit_retun_1_slimit_return_error(sql_union,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_last_limit_retun_1_slimit_return_error(sql_union_all,tables,per_table_num,base_fun,replace_fun)
+        
+        
+        
+        tdLog.info("last query ---------3----------")
+        sql = "select last(*) from %s.meters where ts is not null order by ts limit %d" %(dbname,num)
+        self.sql_retun_error(sql,base_fun,replace_fun)
+        sql = "select last(*) from (%s)" %sql
+        self.sql_retun_error(sql,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_retun_error(sql_union,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_retun_error(sql_union_all,base_fun,replace_fun)
+        
+        sql_join = "select last(a.*) from %s.meters a,%s.meters b where a.ts is not null and  a.ts = b.ts order by b.ts limit %d" %(dbname,dbnamejoin,num)
+        self.sql_retun_error(sql_join,base_fun,replace_fun)
+        sql_join = "select last(*) from (%s)" %sql_join
+        self.sql_retun_error(sql_join,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_retun_error(sql_union,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_retun_error(sql_union_all,base_fun,replace_fun)
+        
+        
+        
+        tdLog.info("last query ---------4----------")
+        sql = "select last(*) from %s.meters where ts is not null order by ts desc limit %d" %(dbname,num)        
+        self.sql_retun_error(sql,base_fun,replace_fun)
+        sql = "select last(*) from (%s)" %sql
+        self.sql_retun_error(sql,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_retun_error(sql_union,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_retun_error(sql_union_all,base_fun,replace_fun)
+        
+        sql_join = "select last(a.*) from %s.meters a,%s.meters b where b.ts is not null and  a.ts = b.ts order by a.ts desc limit %d" %(dbname,dbnamejoin,num)        
+        self.sql_retun_error(sql_join,base_fun,replace_fun)
+        sql_join = "select last(*) from (%s)" %sql_join
+        self.sql_retun_error(sql_join,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_retun_error(sql_union,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_retun_error(sql_union_all,base_fun,replace_fun)
+        
+        
+        
+        tdLog.info("last query ---------5----------")
+        sql = "select last(*) from %s.meters where ts is not null group by tbname limit %d" %(dbname,num)
+        self.sql_limit_retun_tables_slimit_return_n(sql,num,tables,per_table_num,base_fun,replace_fun)        
+        sql = "select count(*) from (%s)" %sql
+        self.sql_data_limit_retun_tables_slimit_return_n(sql,num,tables,per_table_num,base_fun,replace_fun) 
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_data_limit_retun_tables_slimit_return_n(sql_union,num,tables,per_table_num,base_fun,replace_fun) 
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_data_limit_retun_tables_slimit_return_n(sql_union_all,num,tables,per_table_num,base_fun,replace_fun) 
+        
+        sql_join = "select last(a.*) from %s.meters a,%s.meters b where a.ts is not null and a.ts = b.ts group by b.tbname limit %d" %(dbname,dbnamejoin,num)
+        self.sql_limit_retun_tables_slimit_return_n(sql_join,num,tables,per_table_num,base_fun,replace_fun)        
+        sql_join = "select count(*) from (%s)" %sql_join
+        self.sql_data_limit_retun_tables_slimit_return_n(sql_join,num,tables,per_table_num,base_fun,replace_fun) 
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_data_limit_retun_tables_slimit_return_n(sql_union,num,tables,per_table_num,base_fun,replace_fun) 
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_data_limit_retun_tables_slimit_return_n(sql_union_all,num,tables,per_table_num,base_fun,replace_fun) 
+        
+        
+        
+        
+        tdLog.info("last query ---------6----------")
+        sql = "select last(*) from %s.meters where ts is not null partition by tbname limit %d" %(dbname,num)
+        self.sql_limit_retun_tables_slimit_return_n(sql,num,tables,per_table_num,base_fun,replace_fun) 
+        sql = "select count(*) from (%s)" %sql
+        self.sql_data_limit_retun_tables_slimit_return_n(sql,num,tables,per_table_num,base_fun,replace_fun) 
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_data_limit_retun_tables_slimit_return_n(sql_union,num,tables,per_table_num,base_fun,replace_fun) 
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_data_limit_retun_tables_slimit_return_n(sql_union_all,num,tables,per_table_num,base_fun,replace_fun) 
+        
+        sql_join = "select last(a.*) from %s.meters a,%s.meters b where a.ts is not null and a.ts = b.ts partition by b.tbname limit %d" %(dbname,dbnamejoin,num)
+        self.sql_limit_retun_tables_slimit_return_n(sql_join,num,tables,per_table_num,base_fun,replace_fun) 
+        sql_join = "select count(*) from (%s)" %sql_join
+        self.sql_data_limit_retun_tables_slimit_return_n(sql_join,num,tables,per_table_num,base_fun,replace_fun) 
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_data_limit_retun_tables_slimit_return_n(sql_union,num,tables,per_table_num,base_fun,replace_fun) 
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_data_limit_retun_tables_slimit_return_n(sql_union_all,num,tables,per_table_num,base_fun,replace_fun) 
+        
+        
+        
+        tdLog.info("last query ---------7----------")
+        sql = "select last(ts) cc from %s.meters where ts is not null group by tbname order by cc limit %d" %(dbname,num)
+        self.sql_limit_retun_n_slimit_return_tables(sql,num,tables,per_table_num,base_fun,replace_fun)
+        sql = "select count(*) from (%s)" %sql
+        self.sql_data_limit_retun_n_slimit_return_tables(sql,num,tables,per_table_num,base_fun,replace_fun) 
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_data_limit_retun_n_slimit_return_tables(sql_union,num,tables,per_table_num,base_fun,replace_fun) 
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_data_limit_retun_n_slimit_return_tables(sql_union_all,num,tables,per_table_num,base_fun,replace_fun) 
+        
+        sql_join  = "select last(a.ts) cc from %s.meters a,%s.meters b where a.ts is not null and a.ts = b.ts group by b.tbname order by cc limit %d" %(dbname,dbnamejoin,num)
+        self.sql_limit_retun_n_slimit_return_tables(sql_join,num,tables,per_table_num,base_fun,replace_fun)
+        sql_join = "select count(*) from (%s)" %sql_join
+        self.sql_data_limit_retun_n_slimit_return_tables(sql_join,num,tables,per_table_num,base_fun,replace_fun) 
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_data_limit_retun_n_slimit_return_tables(sql_union,num,tables,per_table_num,base_fun,replace_fun) 
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_data_limit_retun_n_slimit_return_tables(sql_union_all,num,tables,per_table_num,base_fun,replace_fun) 
+        
+        
+        
+        tdLog.info("last query ---------8----------")
+        sql = "select last(ts) cc from %s.meters where ts is not null partition by tbname order by cc limit %d" %(dbname,num)
+        self.sql_limit_retun_n_slimit_return_tables(sql,num,tables,per_table_num,base_fun,replace_fun)
+        sql = "select count(*) from (%s)" %sql
+        self.sql_data_limit_retun_n_slimit_return_tables(sql,num,tables,per_table_num,base_fun,replace_fun) 
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_data_limit_retun_n_slimit_return_tables(sql_union,num,tables,per_table_num,base_fun,replace_fun) 
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_data_limit_retun_n_slimit_return_tables(sql_union_all,num,tables,per_table_num,base_fun,replace_fun) 
+        
+        sql_join = "select last(a.ts) cc from %s.meters a,%s.meters b where a.ts is not null and a.ts = b.ts partition by b.tbname order by cc limit %d" %(dbname,dbnamejoin,num)
+        self.sql_limit_retun_n_slimit_return_tables(sql_join,num,tables,per_table_num,base_fun,replace_fun)
+        sql_join = "select count(*) from (%s)" %sql_join
+        self.sql_data_limit_retun_n_slimit_return_tables(sql_join,num,tables,per_table_num,base_fun,replace_fun) 
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_data_limit_retun_n_slimit_return_tables(sql_union,num,tables,per_table_num,base_fun,replace_fun) 
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_data_limit_retun_n_slimit_return_tables(sql_union_all,num,tables,per_table_num,base_fun,replace_fun) 
+        
+        
+        
+        tdLog.info("last query ---------9----------")
+        sql = "select last(*) from %s.meters where ts is not null interval(1a) limit %d" %(dbname,num)
+        self.sql_limit_retun_n_slimit_return_error(sql,num,tables,per_table_num,base_fun,replace_fun)
+        sql = "select count(*) from (%s)" %sql
+        self.sql_data_limit_retun_n_slimit_return_error(sql,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_data_limit_retun_n_slimit_return_error(sql_union,num,tables,per_table_num,base_fun,replace_fun) 
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_data_limit_retun_n_slimit_return_error(sql_union_all,num,tables,per_table_num,base_fun,replace_fun) 
+        
+        sql_join  = "select last(a.ts) cc from %s.meters a,%s.meters b where a.ts is not null and a.ts = b.ts interval(1a) limit %d" %(dbname,dbnamejoin,num)
+        self.sql_limit_retun_n_slimit_return_error(sql_join,num,tables,per_table_num,base_fun,replace_fun)
+        sql_join = "select count(*) from (%s)" %sql_join
+        self.sql_data_limit_retun_n_slimit_return_error(sql_join,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_data_limit_retun_n_slimit_return_error(sql_union,num,tables,per_table_num,base_fun,replace_fun) 
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_data_limit_retun_n_slimit_return_error(sql_union_all,num,tables,per_table_num,base_fun,replace_fun) 
+        
+        
+        
+        tdLog.info("last query ---------10----------")
+        sql = "select last(ts) cc from %s.meters where ts is not null interval(1a) order by cc asc limit %d" %(dbname,num)
+        self.sql_limit_retun_n_slimit_return_error(sql,num,tables,per_table_num,base_fun,replace_fun)
+        sql = "select count(*) from (%s)" %sql
+        self.sql_data_limit_retun_n_slimit_return_error(sql,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_data_limit_retun_n_slimit_return_error(sql_union,num,tables,per_table_num,base_fun,replace_fun) 
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_data_limit_retun_n_slimit_return_error(sql_union_all,num,tables,per_table_num,base_fun,replace_fun) 
+        
+        sql_join = "select last(a.ts) cc from %s.meters a,%s.meters b where a.ts is not null and a.ts = b.ts interval(1a) order by cc asc limit %d" %(dbname,dbnamejoin,num)
+        self.sql_limit_retun_n_slimit_return_error(sql_join,num,tables,per_table_num,base_fun,replace_fun)
+        sql_join = "select count(*) from (%s)" %sql_join
+        self.sql_data_limit_retun_n_slimit_return_error(sql_join,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_data_limit_retun_n_slimit_return_error(sql_union,num,tables,per_table_num,base_fun,replace_fun) 
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_data_limit_retun_n_slimit_return_error(sql_union_all,num,tables,per_table_num,base_fun,replace_fun) 
+        
+        
+        
+        tdLog.info("last query ---------11----------")
+        sql = "select last(ts) cc from %s.meters where ts is not null interval(1a) order by cc desc limit %d" %(dbname,num)
+        self.sql_limit_retun_n_slimit_return_error(sql,num,tables,per_table_num,base_fun,replace_fun)
+        sql = "select count(*) from (%s)" %sql
+        self.sql_data_limit_retun_n_slimit_return_error(sql,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_data_limit_retun_n_slimit_return_error(sql_union,num,tables,per_table_num,base_fun,replace_fun) 
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_data_limit_retun_n_slimit_return_error(sql_union_all,num,tables,per_table_num,base_fun,replace_fun) 
+        
+        sql_join = "select last(a.ts) cc from %s.meters a,%s.meters b where a.ts is not null and a.ts = b.ts interval(1a) order by cc desc limit %d" %(dbname,dbnamejoin,num)
+        self.sql_limit_retun_n_slimit_return_error(sql_join,num,tables,per_table_num,base_fun,replace_fun)
+        sql_join = "select count(*) from (%s)" %sql_join
+        self.sql_data_limit_retun_n_slimit_return_error(sql_join,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_data_limit_retun_n_slimit_return_error(sql_union,num,tables,per_table_num,base_fun,replace_fun) 
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_data_limit_retun_n_slimit_return_error(sql_union_all,num,tables,per_table_num,base_fun,replace_fun) 
+        
+        
+        
+        tdLog.info("last query ---------12----------")
+        sql = "select tbname,last(ts) cc from %s.meters where ts is not null interval(1a) group by tbname limit %d" %(dbname,num)
+        self.sql_retun_error(sql,base_fun,replace_fun)
+        sql = "select last(*) from (%s)" %sql
+        self.sql_retun_error(sql,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_retun_error(sql_union,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_retun_error(sql_union_all,base_fun,replace_fun)
+        
+        sql_join = "select a.tbname,last(a.ts) cc from %s.meters a,%s.meters b where a.ts is not null and a.ts = b.ts interval(1a) group by b.tbname limit %d" %(dbname,dbnamejoin,num)
+        self.sql_retun_error(sql_join,base_fun,replace_fun)
+        sql_join = "select last(*) from (%s)" %sql_join
+        self.sql_retun_error(sql_join,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_retun_error(sql_union,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_retun_error(sql_union_all,base_fun,replace_fun)
+        
+        
+        
+        tdLog.info("last query ---------13----------")
+        sql = "select tbname,last(ts) cc from %s.meters where ts is not null interval(1a) partition by tbname limit %d" %(dbname,num)
+        self.sql_retun_error(sql,base_fun,replace_fun)
+        sql = "select last(*) from (%s)" %sql
+        self.sql_retun_error(sql,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_retun_error(sql_union,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_retun_error(sql_union_all,base_fun,replace_fun)
+        
+        sql_join = "select a.tbname,last(a.ts) cc from %s.meters a,%s.meters b where a.ts is not null and a.ts = b.ts interval(1a) partition by b.tbname limit %d" %(dbname,dbnamejoin,num)
+        self.sql_retun_error(sql_join,base_fun,replace_fun)
+        sql_join = "select last(*) from (%s)" %sql_join
+        self.sql_retun_error(sql_join,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_retun_error(sql_union,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_retun_error(sql_union_all,base_fun,replace_fun)
+        
+        
+        
+        tdLog.info("last query ---------14----------") 
+        sql = "select tbname,last(*) cc from %s.meters where ts is not null partition by tbname interval(1a) limit %d" %(dbname,num)
+        self.sql_limit_retun_tables_times_n_slimit_return_per_table_num_times_n(sql,num,tables,per_table_num,base_fun,replace_fun)
+        sql = "select count(*) from (%s)" %sql
+        self.sql_data_limit_retun_tables_times_n_slimit_return_per_table_num_times_n(sql,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_data_limit_retun_tables_times_n_slimit_return_per_table_num_times_n(sql_union,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_data_limit_retun_tables_times_n_slimit_return_per_table_num_times_n(sql_union_all,num,tables,per_table_num,base_fun,replace_fun)
+        
+        sql_join = "select a.tbname,last(a.ts) cc from %s.meters a,%s.meters b where a.ts is not null and a.ts = b.ts partition by a.tbname interval(1a) limit %d" %(dbname,dbnamejoin,num)
+        self.sql_limit_retun_tables_times_n_slimit_return_per_table_num_times_n(sql_join,num,tables,per_table_num,base_fun,replace_fun)
+        sql_join = "select count(*) from (%s)" %sql_join
+        self.sql_data_limit_retun_tables_times_n_slimit_return_per_table_num_times_n(sql_join,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_data_limit_retun_tables_times_n_slimit_return_per_table_num_times_n(sql_union,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_data_limit_retun_tables_times_n_slimit_return_per_table_num_times_n(sql_union_all,num,tables,per_table_num,base_fun,replace_fun)
+        
+        
+        
+        tdLog.info("last query ---------15----------")
+        sql = "select tbname,last(ts) cc from %s.meters where ts is not null partition by tbname interval(1a) order by cc asc limit %d" %(dbname,num)
+        self.sql_limit_retun_n_slimit_return_per_table_num_times_tables(sql,num,tables,per_table_num,base_fun,replace_fun)
+        sql = "select count(*) from (%s)" %sql
+        self.sql_data_limit_retun_n_slimit_return_per_table_num_times_tables(sql,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_data_limit_retun_n_slimit_return_per_table_num_times_tables(sql_union,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_data_limit_retun_n_slimit_return_per_table_num_times_tables(sql_union_all,num,tables,per_table_num,base_fun,replace_fun)
+        
+        sql_join = "select a.tbname,last(a.ts) cc from %s.meters a,%s.meters b where a.ts is not null and a.ts = b.ts partition by a.tbname interval(1a) order by cc asc limit %d" %(dbname,dbnamejoin,num)
+        self.sql_limit_retun_n_slimit_return_per_table_num_times_tables(sql_join,num,tables,per_table_num,base_fun,replace_fun)
+        sql_join = "select count(*) from (%s)" %sql_join
+        self.sql_data_limit_retun_n_slimit_return_per_table_num_times_tables(sql_join,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_data_limit_retun_n_slimit_return_per_table_num_times_tables(sql_union,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_data_limit_retun_n_slimit_return_per_table_num_times_tables(sql_union_all,num,tables,per_table_num,base_fun,replace_fun)
+        
+        
+        
+        tdLog.info("last query ---------16----------")
+        sql = "select tbname,last(ts) cc from %s.meters where ts is not null partition by tbname interval(1a) order by cc desc limit %d" %(dbname,num)
+        self.sql_limit_retun_n_slimit_return_per_table_num_times_tables(sql,num,tables,per_table_num,base_fun,replace_fun)
+        sql = "select count(*) from (%s)" %sql
+        self.sql_data_limit_retun_n_slimit_return_per_table_num_times_tables(sql,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_data_limit_retun_n_slimit_return_per_table_num_times_tables(sql_union,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_data_limit_retun_n_slimit_return_per_table_num_times_tables(sql_union_all,num,tables,per_table_num,base_fun,replace_fun)
+        
+        sql_join = "select a.tbname,last(a.ts) cc from %s.meters a,%s.meters b where a.ts is not null and a.ts = b.ts partition by a.tbname interval(1a) order by cc desc limit %d" %(dbname,dbnamejoin,num)
+        self.sql_limit_retun_n_slimit_return_per_table_num_times_tables(sql_join,num,tables,per_table_num,base_fun,replace_fun)
+        sql_join = "select count(*) from (%s)" %sql_join
+        self.sql_data_limit_retun_n_slimit_return_per_table_num_times_tables(sql_join,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_data_limit_retun_n_slimit_return_per_table_num_times_tables(sql_union,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_data_limit_retun_n_slimit_return_per_table_num_times_tables(sql_union_all,num,tables,per_table_num,base_fun,replace_fun)
+        
+        
+        
+        tdLog.info("last query ---------17----------")
+        sql = "select tbname,last(*) cc from %s.meters where ts is not null partition by tbname interval(1a) slimit %d" %(dbname,num)
+        self.sql_limit_not_test_slimitkeep_return_per_table_num_times_n(sql,num,tables,per_table_num,base_fun,replace_fun)
+        sql = "select count(*) from (%s)" %sql
+        self.sql_data_limit_not_test_slimitkeep_return_per_table_num_times_n(sql,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_data_limit_not_test_slimitkeep_return_per_table_num_times_n(sql_union,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_data_limit_not_test_slimitkeep_return_per_table_num_times_n(sql_union_all,num,tables,per_table_num,base_fun,replace_fun)
+        
+        sql_join = "select a.tbname,last(a.ts) cc from %s.meters a,%s.meters b where a.ts is not null and a.ts = b.ts partition by a.tbname interval(1a) slimit %d" %(dbname,dbnamejoin,num)
+        self.sql_limit_not_test_slimitkeep_return_per_table_num_times_n(sql_join,num,tables,per_table_num,base_fun,replace_fun)
+        sql_join = "select count(*) from (%s)" %sql_join
+        self.sql_data_limit_not_test_slimitkeep_return_per_table_num_times_n(sql_join,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_data_limit_not_test_slimitkeep_return_per_table_num_times_n(sql_union,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_data_limit_not_test_slimitkeep_return_per_table_num_times_n(sql_union_all,num,tables,per_table_num,base_fun,replace_fun)
+        
+        
+        
+        tdLog.info("last query ---------18----------")
+        sql = "select tbname,last(ts) cc from %s.meters where ts is not null partition by tbname interval(1a) order by cc asc slimit %d" %(dbname,num)
+        self.sql_limit_not_test_slimitkeep_return_per_table_num_times_tables(sql,num,tables,per_table_num,base_fun,replace_fun)
+        sql = "select count(*) from (%s)" %sql
+        self.sql_data_limit_not_test_slimitkeep_return_per_table_num_times_tables(sql,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_data_limit_not_test_slimitkeep_return_per_table_num_times_tables(sql_union,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_data_limit_not_test_slimitkeep_return_per_table_num_times_tables(sql_union_all,num,tables,per_table_num,base_fun,replace_fun)
+        
+        sql_join = "select a.tbname,last(a.ts) cc from %s.meters a,%s.meters b where a.ts is not null and a.ts = b.ts partition by a.tbname interval(1a) order by cc asc slimit %d" %(dbname,dbnamejoin,num)
+        self.sql_limit_not_test_slimitkeep_return_per_table_num_times_tables(sql_join,num,tables,per_table_num,base_fun,replace_fun)
+        sql_join = "select count(*) from (%s)" %sql_join
+        self.sql_data_limit_not_test_slimitkeep_return_per_table_num_times_tables(sql_join,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_data_limit_not_test_slimitkeep_return_per_table_num_times_tables(sql_union,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_data_limit_not_test_slimitkeep_return_per_table_num_times_tables(sql_union_all,num,tables,per_table_num,base_fun,replace_fun)
+        
+        
+        tdLog.info("last query ---------19----------")
+        sql = "select tbname,last(ts) cc from %s.meters where ts is not null partition by tbname interval(1a) order by cc desc slimit %d" %(dbname,num)
+        self.sql_limit_not_test_slimitkeep_return_per_table_num_times_tables(sql,num,tables,per_table_num,base_fun,replace_fun)
+        sql = "select count(*) from (%s)" %sql
+        self.sql_data_limit_not_test_slimitkeep_return_per_table_num_times_tables(sql,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_data_limit_not_test_slimitkeep_return_per_table_num_times_tables(sql_union,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_data_limit_not_test_slimitkeep_return_per_table_num_times_tables(sql_union_all,num,tables,per_table_num,base_fun,replace_fun)
+        
+        sql_join = "select a.tbname,last(a.ts) cc from %s.meters a,%s.meters b where a.ts is not null and a.ts = b.ts partition by a.tbname interval(1a) order by cc desc slimit %d" %(dbname,dbnamejoin,num)
+        self.sql_limit_not_test_slimitkeep_return_per_table_num_times_tables(sql_join,num,tables,per_table_num,base_fun,replace_fun)
+        sql_join = "select count(*) from (%s)" %sql_join
+        self.sql_data_limit_not_test_slimitkeep_return_per_table_num_times_tables(sql_join,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_data_limit_not_test_slimitkeep_return_per_table_num_times_tables(sql_union,num,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_data_limit_not_test_slimitkeep_return_per_table_num_times_tables(sql_union_all,num,tables,per_table_num,base_fun,replace_fun)
+        
+        
+        
+        tdLog.info("last query ---------20----------") 
+        sql = "select tbname,last(*) cc from %s.meters where ts is not null partition by tbname interval(1a) slimit %d limit %d" %(dbname,num,num2)
+        self.sql_limit_retun_n_times_n2_slimitkeep_return_n_times_n2(sql,num,num2,tables,per_table_num,base_fun,replace_fun)
+        sql = "select count(*) from (%s)" %sql
+        self.sql_data_limit_retun_n_times_n2_slimitkeep_return_n_times_n2(sql,num,num2,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_data_limit_retun_n_times_n2_slimitkeep_return_n_times_n2(sql_union,num,num2,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_data_limit_retun_n_times_n2_slimitkeep_return_n_times_n2(sql_union_all,num,num2,tables,per_table_num,base_fun,replace_fun)
+        
+        sql_join = "select a.tbname,last(a.*) cc from %s.meters a,%s.meters b where a.ts is not null and a.ts = b.ts partition by a.tbname interval(1a) slimit %d limit %d" %(dbname,dbnamejoin,num,num2)
+        self.sql_limit_retun_n_times_n2_slimitkeep_return_n_times_n2(sql_join,num,num2,tables,per_table_num,base_fun,replace_fun)
+        sql_join = "select count(*) from (%s)" %sql_join
+        self.sql_data_limit_retun_n_times_n2_slimitkeep_return_n_times_n2(sql_join,num,num2,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_data_limit_retun_n_times_n2_slimitkeep_return_n_times_n2(sql_union,num,num2,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_data_limit_retun_n_times_n2_slimitkeep_return_n_times_n2(sql_union_all,num,num2,tables,per_table_num,base_fun,replace_fun)
+        
+        
+        tdLog.info("last query ---------21----------")
+        sql = "select tbname,last(ts) cc from %s.meters where ts is not null partition by tbname interval(1a) order by cc asc slimit %d limit %d" %(dbname,num,num2)
+        self.sql_limit_times_slimitkeep_return_n2(sql,num,num2,tables,per_table_num,base_fun,replace_fun)
+        sql = "select count(*) from (%s)" %sql
+        self.sql_data_limit_times_slimitkeep_return_n2(sql,num,num2,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_data_limit_times_slimitkeep_return_n2(sql_union,num,num2,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_data_limit_times_slimitkeep_return_n2(sql_union_all,num,num2,tables,per_table_num,base_fun,replace_fun)       
+        
+        sql_join = "select a.tbname,last(a.ts) cc from %s.meters a,%s.meters b where a.ts is not null and a.ts = b.ts partition by a.tbname interval(1a) order by cc asc slimit %d limit %d" %(dbname,dbnamejoin,num,num2)
+        self.sql_limit_times_slimitkeep_return_n2(sql_join,num,num2,tables,per_table_num,base_fun,replace_fun)
+        sql_join = "select count(*) from (%s)" %sql_join
+        self.sql_data_limit_times_slimitkeep_return_n2(sql_join,num,num2,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_data_limit_times_slimitkeep_return_n2(sql_union,num,num2,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_data_limit_times_slimitkeep_return_n2(sql_union_all,num,num2,tables,per_table_num,base_fun,replace_fun)
+        
+        
+        tdLog.info("last query ---------22----------")
+        sql = "select tbname,last(ts) cc from %s.meters where ts is not null partition by tbname interval(1a) order by cc desc slimit %d limit %d" %(dbname,num,num2)
+        self.sql_limit_times_slimitkeep_return_n2(sql,num,num2,tables,per_table_num,base_fun,replace_fun)
+        sql = "select count(*) from (%s)" %sql
+        self.sql_data_limit_times_slimitkeep_return_n2(sql,num,num2,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql,sql)
+        self.sql_data_limit_times_slimitkeep_return_n2(sql_union,num,num2,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql,sql_union)
+        self.sql_data_limit_times_slimitkeep_return_n2(sql_union_all,num,num2,tables,per_table_num,base_fun,replace_fun)
+        
+        sql_join = "select a.tbname,last(a.ts) cc from %s.meters a,%s.meters b where a.ts is not null and a.ts = b.ts partition by a.tbname interval(1a) order by cc desc slimit %d limit %d" %(dbname,dbnamejoin,num,num2)
+        self.sql_limit_times_slimitkeep_return_n2(sql_join,num,num2,tables,per_table_num,base_fun,replace_fun)
+        sql_join = "select count(*) from (%s)" %sql_join
+        self.sql_data_limit_times_slimitkeep_return_n2(sql_join,num,num2,tables,per_table_num,base_fun,replace_fun)
+        sql_union = "(%s) union (%s)" %(sql_join,sql_join)
+        self.sql_data_limit_times_slimitkeep_return_n2(sql_union,num,num2,tables,per_table_num,base_fun,replace_fun)
+        sql_union_all = "(%s) union all (%s)" %(sql_join,sql_union)
+        self.sql_data_limit_times_slimitkeep_return_n2(sql_union_all,num,num2,tables,per_table_num,base_fun,replace_fun)
+        
+        
+            
+   
+
+    def sql_base_check(self,sql1,sql2):
+        tdSql.query(sql1)
+        sql1_result = tdSql.getData(0,0)
+        tdLog.info("sql:%s , result: %s" %(sql1,sql1_result))
+
+        tdSql.query(sql2)
+        sql2_result = tdSql.getData(0,0)
+        tdLog.info("sql:%s , result: %s" %(sql2,sql2_result))
+
+        if sql1_result==sql2_result:
+            tdLog.info(f"checkEqual success, sql1_result={sql1_result},sql2_result={sql2_result}")
+        else :
+            tdLog.exit(f"checkEqual error, sql1_result=={sql1_result},sql2_result={sql2_result}")
+
+    def run_limit_slimit_sql(self,dbname,tables,per_table_num,dbnamejoin):
+        
+        num,num2 = random.randint(10,100),random.randint(10,100)
+        self.sql_base(dbname,num,num2,tables,per_table_num,dbnamejoin)
+
+        tdSql.execute(" flush database %s;" %dbname)
+
+        self.sql_base(dbname,num,num2,tables,per_table_num,dbnamejoin)
+
+    def check_sub(self,dbname):
+
+        sql = "select count(*) from (select distinct(tbname) from %s.meters)" %dbname
+        self.sql_query_time_cost(sql)
+        num = tdSql.getData(0,0)
+
+        for i in range(0,num):
+            sql1 = "select count(*) from %s.d%d" %(dbname,i)
+            self.sql_query_time_cost(sql1)
+            sql1_result = tdSql.getData(0,0)
+            tdLog.info("sql:%s , result: %s" %(sql1,sql1_result))
+    
+                
+    def sql_base(self,dbname,num,num2,tables,per_table_num,dbnamejoin):
+        
+        sql = "select count(*) from %s.meters" %dbname
+        self.sql_query_time_cost(sql)
+        tdSql.checkData(0,0,tables*per_table_num)
+        sql = "select count(*) from %s.meters" %dbnamejoin
+        self.sql_query_time_cost(sql)
+        
+        self.fun_base(dbname,num,num2,tables,per_table_num,dbnamejoin,'*','*')
+        # self.fun_count(dbname,num,num2,tables,per_table_num,dbnamejoin,'count','count')
+        # self.fun_last(dbname,num,num2,tables,per_table_num,dbnamejoin,'last','last')
+        # #self.fun_last(dbname,num,num2,tables,per_table_num,dbnamejoin,'last','last_row')
+        # self.fun_last(dbname,num,num2,tables,per_table_num,dbnamejoin,'last','first')
+            
+    def test(self,dbname,tables,per_table_num,vgroups,replica,dbnamejoin):
+        self.run_benchmark(dbname,tables,per_table_num,vgroups,replica)
+        self.run_benchmark(dbnamejoin,tables,per_table_num,vgroups,replica)
+        self.run_limit_slimit_sql(dbname,tables,per_table_num,dbnamejoin)
+
+    def run(self):
+        startTime = time.time()
+
+        dbname = 'test'
+        dbnamejoin = 'testjoin'
+        vgroups = random.randint(1,8)
+        tables = random.randint(100,300)
+        per_table_num = random.randint(100,500)
+        replica = 1
+        #self.test('test',tables,per_table_num,vgroup,1) 
+        #self.test('test',10000,150,vgroup,1)     
+        
+        self.test('test',100,150,vgroups,1,'testjoin')    #方便调试,调试时不执行下面3个 
+        
+        # self.run_benchmark(dbname,tables,per_table_num,vgroups,replica)
+        # self.run_benchmark(dbnamejoin,tables*vgroups,per_table_num*vgroups,vgroups*2,replica) #方便测试不同数据量
+        # self.run_limit_slimit_sql(dbname,tables,per_table_num,dbnamejoin)  
+
+        endTime = time.time()
+        print("total time %ds" % (endTime - startTime))
+
+
+    def stop(self):
+        tdSql.close()
+        tdLog.success("%s successfully executed" % __file__)
+
+
+tdCases.addWindows(__file__, TDTestCase())
+tdCases.addLinux(__file__, TDTestCase())
diff --git a/tests/system-test/2-query/sml.py b/tests/system-test/2-query/sml.py
index f96ed8a3ff..2f97118fbf 100644
--- a/tests/system-test/2-query/sml.py
+++ b/tests/system-test/2-query/sml.py
@@ -34,6 +34,9 @@ class TDTestCase:
         if ret != 0:
             tdLog.info("sml_test ret != 0")
 
+        tdSql.query(f"select * from ts3303.stb2")
+        tdSql.query(f"select * from ts3303.meters")
+
         # tdSql.execute('use sml_db')
         tdSql.query(f"select * from {dbname}.t_b7d815c9222ca64cdf2614c61de8f211")
         tdSql.checkRows(1)
diff --git a/tests/system-test/6-cluster/clusterCommonCheck.py b/tests/system-test/6-cluster/clusterCommonCheck.py
index 149c6d8ded..f5926321da 100644
--- a/tests/system-test/6-cluster/clusterCommonCheck.py
+++ b/tests/system-test/6-cluster/clusterCommonCheck.py
@@ -207,7 +207,7 @@ class ClusterComCheck:
                 count+=1
         else:
             tdLog.debug(tdSql.queryResult)
-            tdLog.exit("stop mnodes  on dnode %d  failed in 10s ")
+            tdLog.exit(f"stop mnodes  on dnode {offlineDnodeNo}  failed in 10s ")
 
     def check3mnode2off(self,mnodeNums=3):
         count=0
@@ -226,7 +226,45 @@ class ClusterComCheck:
             count+=1
         else:
             tdLog.debug(tdSql.queryResult)
-            tdLog.exit("stop mnodes  on dnode %d  failed in 10s ")
+            tdLog.exit("stop mnodes  on dnode 2 or 3 failed in 10s")
+
+    def check_vgroups_status(self,vgroup_numbers=2,db_replica=3,count_number=10,db_name="db"):
+        """ check vgroups status in 10s after db vgroups status is changed """
+        vgroup_numbers = int(vgroup_numbers)
+        self.db_replica = int(db_replica)
+        tdLog.debug("start to check status of vgroups")
+        count=0
+        last_number=vgroup_numbers-1
+        while count < count_number:
+            time.sleep(1)
+            tdSql.query(f"show  {db_name}.vgroups;")
+            if  count == 0 :
+                if tdSql.checkRows(vgroup_numbers) :
+                    tdLog.success(f"{db_name} has {vgroup_numbers} vgroups" )
+                else:
+                    tdLog.exit(f"vgroup number of {db_name} is not correct")
+            if self.db_replica == 1 :
+                if  tdSql.queryResult[0][4] == 'leader' and tdSql.queryResult[1][4] == 'leader' and tdSql.queryResult[last_number][4] == 'leader':
+                    ready_time= (count + 1)
+                    tdLog.success(f"all vgroups of {db_name} are leaders in {count + 1} s")
+                    return True
+                count+=1
+            elif self.db_replica == 3 :
+                vgroup_status_first=[tdSql.queryResult[0][4],tdSql.queryResult[0][6],tdSql.queryResult[0][8]]
+                
+                vgroup_status_last=[tdSql.queryResult[last_number][4],tdSql.queryResult[last_number][6],tdSql.queryResult[last_number][8]]
+                if  vgroup_status_first.count('leader') == 1 and vgroup_status_first.count('follower') == 2:
+                    if vgroup_status_last.count('leader') == 1 and vgroup_status_last.count('follower') == 2:
+                        ready_time= (count + 1)
+                        tdLog.success(f"all vgroups of {db_name} are ready in {ready_time} s")
+                        return True
+                count+=1
+        else:
+            tdLog.debug(tdSql.queryResult)
+            tdLog.notice(f"all vgroups  leader of {db_name} is selected {count}s ")
+            caller = inspect.getframeinfo(inspect.stack()[1][0])
+            args = (caller.filename, caller.lineno)
+            tdLog.exit("%s(%d) failed " % args)
 
 
 
diff --git a/tests/system-test/6-cluster/clusterCommonCreate.py b/tests/system-test/6-cluster/clusterCommonCreate.py
index 6e699e2396..a06c1233d8 100644
--- a/tests/system-test/6-cluster/clusterCommonCreate.py
+++ b/tests/system-test/6-cluster/clusterCommonCreate.py
@@ -94,26 +94,26 @@ class ClusterComCreate:
         tdLog.info(shellCmd)
         os.system(shellCmd)
 
-    def getStartConsumeNotifyFromTmqsim(self,cdbName='cdb'):
-        while 1:
-            tdSql.query("select * from %s.notifyinfo"%cdbName)
-            #tdLog.info("row: %d, %l64d, %l64d"%(tdSql.getData(0, 1),tdSql.getData(0, 2),tdSql.getData(0, 3))
-            if (tdSql.getRows() == 1) and (tdSql.getData(0, 1) == 0):
-                break
-            else:
-                time.sleep(0.1)
-        return
-
-    def getStartCommitNotifyFromTmqsim(self,cdbName='cdb'):
-        while 1:
-            tdSql.query("select * from %s.notifyinfo"%cdbName)
-            #tdLog.info("row: %d, %l64d, %l64d"%(tdSql.getData(0, 1),tdSql.getData(0, 2),tdSql.getData(0, 3))
-            if tdSql.getRows() == 2 :
-                print(tdSql.getData(0, 1), tdSql.getData(1, 1))
-                if tdSql.getData(1, 1) == 1:
-                    break
-            time.sleep(0.1)
-        return
+    # def getStartConsumeNotifyFromTmqsim(self,cdbName='cdb'):
+    #     while 1:
+    #         tdSql.query("select * from %s.notifyinfo"%cdbName)
+    #         #tdLog.info("row: %d, %l64d, %l64d"%(tdSql.getData(0, 1),tdSql.getData(0, 2),tdSql.getData(0, 3))
+    #         if (tdSql.getRows() == 1) and (tdSql.getData(0, 1) == 0):
+    #             break
+    #         else:
+    #             time.sleep(0.1)
+    #     return
+    #
+    # def getStartCommitNotifyFromTmqsim(self,cdbName='cdb'):
+    #     while 1:
+    #         tdSql.query("select * from %s.notifyinfo"%cdbName)
+    #         #tdLog.info("row: %d, %l64d, %l64d"%(tdSql.getData(0, 1),tdSql.getData(0, 2),tdSql.getData(0, 3))
+    #         if tdSql.getRows() == 2 :
+    #             print(tdSql.getData(0, 1), tdSql.getData(1, 1))
+    #             if tdSql.getData(1, 1) == 1:
+    #                 break
+    #         time.sleep(0.1)
+    #     return
 
     def create_database(self,tsql, dbName,dropFlag=1,vgroups=4,replica=1):
         if dropFlag == 1:
diff --git a/tests/system-test/6-cluster/manually-test/6dnode3mnodeInsertDataRebootModifyMetaAlterRep1to3.py b/tests/system-test/6-cluster/manually-test/6dnode3mnodeInsertDataRebootModifyMetaAlterRep1to3.py
new file mode 100644
index 0000000000..7d46b3143d
--- /dev/null
+++ b/tests/system-test/6-cluster/manually-test/6dnode3mnodeInsertDataRebootModifyMetaAlterRep1to3.py
@@ -0,0 +1,206 @@
+import taos
+import sys
+import time
+import os
+
+from util.log import *
+from util.sql import *
+from util.cases import *
+from util.dnodes import TDDnodes
+from util.dnodes import TDDnode
+from util.cluster import *
+sys.path.append("./6-cluster")
+from clusterCommonCreate import *
+from clusterCommonCheck import clusterComCheck
+
+import time
+import socket
+import subprocess
+from multiprocessing import Process
+import threading
+import time
+import inspect
+import ctypes
+
+class TDTestCase:
+
+    def init(self, conn, logSql, replicaVar=1):
+        tdLog.debug(f"start to excute {__file__}")
+        self.TDDnodes = None
+        tdSql.init(conn.cursor())
+        self.host = socket.gethostname()
+
+
+    def getBuildPath(self):
+        selfPath = os.path.dirname(os.path.realpath(__file__))
+
+        if ("community" in selfPath):
+            projPath = selfPath[:selfPath.find("community")]
+        else:
+            projPath = selfPath[:selfPath.find("tests")]
+
+        for root, dirs, files in os.walk(projPath):
+            if ("taosd" in files):
+                rootRealPath = os.path.dirname(os.path.realpath(root))
+                if ("packaging" not in rootRealPath):
+                    buildPath = root[:len(root) - len("/build/bin")]
+                    break
+        return buildPath
+
+    def _async_raise(self, tid, exctype):
+        """raises the exception, performs cleanup if needed"""
+        if not inspect.isclass(exctype):
+            exctype = type(exctype)
+        res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))
+        if res == 0:
+            raise ValueError("invalid thread id")
+        elif res != 1:
+            # """if it returns a number greater than one, you're in trouble,
+            # and you should call it again with exc=NULL to revert the effect"""
+            ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)
+            raise SystemError("PyThreadState_SetAsyncExc failed")
+
+    def stopThread(self,thread):
+        self._async_raise(thread.ident, SystemExit)
+
+
+    def fiveDnodeThreeMnode(self,dnodeNumbers,mnodeNums,restartNumbers,stopRole):
+        tdLog.printNoPrefix("======== test case 1: ")
+        paraDict = {'dbName':     'db0_0',
+                    'dropFlag':   1,
+                    'event':      '',
+                    'vgroups':    4,
+                    'replica':    1,
+                    'stbName':    'stb',
+                    'stbNumbers': 2,
+                    'colPrefix':  'c',
+                    'tagPrefix':  't',
+                    'colSchema':   [{'type': 'INT', 'count':1}, {'type': 'binary', 'len':20, 'count':1}],
+                    'tagSchema':   [{'type': 'INT', 'count':1}, {'type': 'binary', 'len':20, 'count':1}],
+                    'ctbPrefix':  'ctb',
+                    'ctbNum':     200,
+                    'startTs':    1640966400000,  # 2022-01-01 00:00:00.000
+                    "rowsPerTbl": 1000,
+                    "batchNum": 5000
+                    }
+
+        dnodeNumbers=int(dnodeNumbers)
+        mnodeNums=int(mnodeNums)
+        vnodeNumbers = int(dnodeNumbers-mnodeNums)
+        allctbNumbers=(paraDict['stbNumbers']*paraDict["ctbNum"])
+        rowsPerStb=paraDict["ctbNum"]*paraDict["rowsPerTbl"]
+        rowsall=rowsPerStb*paraDict['stbNumbers']
+        dbNumbers = 1
+
+        tdLog.info("first check dnode and mnode")
+        tdSql.query("select * from information_schema.ins_dnodes;")
+        tdSql.checkData(0,1,'%s:6030'%self.host)
+        tdSql.checkData(4,1,'%s:6430'%self.host)
+        clusterComCheck.checkDnodes(dnodeNumbers)
+        
+        #check mnode status
+        tdLog.info("check mnode status")
+        clusterComCheck.checkMnodeStatus(mnodeNums)
+
+        # add some error operations and
+        tdLog.info("Confirm the status of the dnode again")
+        tdSql.error("create mnode on dnode 2")
+        tdSql.query("select * from information_schema.ins_dnodes;")
+        print(tdSql.queryResult)
+        clusterComCheck.checkDnodes(dnodeNumbers)
+
+        # create database and stable
+        clusterComCreate.create_database(tdSql, paraDict["dbName"],paraDict["dropFlag"], paraDict["vgroups"],paraDict['replica'])
+        tdLog.info("Take turns stopping Mnodes ")
+
+        tdDnodes=cluster.dnodes
+        stopcount =0
+        threads=[]
+
+        # create stable:stb_0
+        stableName= paraDict['stbName']
+        newTdSql=tdCom.newTdSql()
+        clusterComCreate.create_stables(newTdSql, paraDict["dbName"],stableName,paraDict['stbNumbers'])
+        #create child table:ctb_0
+        for i in range(paraDict['stbNumbers']):
+            stableName= '%s_%d'%(paraDict['stbName'],i)
+            newTdSql=tdCom.newTdSql()
+            clusterComCreate.create_ctable(newTdSql, paraDict["dbName"],stableName,stableName, paraDict['ctbNum'])
+        #insert date
+        for i in range(paraDict['stbNumbers']):
+            stableName= '%s_%d'%(paraDict['stbName'],i)
+            newTdSql=tdCom.newTdSql()
+            threads.append(threading.Thread(target=clusterComCreate.insert_data, args=(newTdSql, paraDict["dbName"],stableName,paraDict["ctbNum"],paraDict["rowsPerTbl"],paraDict["batchNum"],paraDict["startTs"])))
+        for tr in threads:
+            tr.start()
+        for tr in threads:
+            tr.join()
+
+        while stopcount < restartNumbers:
+            tdLog.info(" restart loop: %d"%stopcount )
+            if stopRole == "mnode":
+                for i in range(mnodeNums):
+                    tdDnodes[i].stoptaosd()
+                    # sleep(10)
+                    tdDnodes[i].starttaosd()
+                    # sleep(10)
+            elif stopRole == "vnode":
+                for i in range(vnodeNumbers):
+                    tdDnodes[i+mnodeNums].stoptaosd()
+                    # sleep(10)
+                    tdDnodes[i+mnodeNums].starttaosd()
+                    # sleep(10)
+            elif stopRole == "dnode":
+                for i in range(dnodeNumbers):
+                    if i == 0 :
+                        stableName= '%s_%d'%(paraDict['stbName'],0)
+                        newTdSql=tdCom.newTdSql()
+                        # newTdSql.execute('alter database db0_0 replica 3')
+                        clusterComCreate.alterStbMetaData(newTdSql, paraDict["dbName"],stableName,paraDict["ctbNum"],paraDict["rowsPerTbl"],paraDict["batchNum"])
+                    tdDnodes[i].stoptaosd()
+                    clusterComCheck.checkDbRows(dbNumbers)
+                    # sleep(10)
+                    tdDnodes[i].starttaosd()
+                    if i == 3 :
+                        TdSqlEx=tdCom.newTdSql()
+                        tdLog.info("alter database db0_0 replica 3")
+                        TdSqlEx.execute('alter database db0_0 replica 3')
+ 
+
+            # dnodeNumbers don't include database of schema
+            if clusterComCheck.checkDnodes(dnodeNumbers):
+                tdLog.info("123")
+            else:
+                print("456")
+
+                self.stopThread(threads)
+                tdLog.exit("one or more of dnodes failed to start ")
+                # self.check3mnode()
+            stopcount+=1
+
+
+        clusterComCheck.checkDnodes(dnodeNumbers)
+        clusterComCheck.checkDbRows(dbNumbers)
+        # clusterComCheck.checkDb(dbNumbers,1,paraDict["dbName"])
+
+        # tdSql.execute("use %s" %(paraDict["dbName"]))
+        tdSql.query("show %s.stables"%(paraDict["dbName"]))
+        tdSql.checkRows(paraDict["stbNumbers"])
+        for i in range(paraDict['stbNumbers']):
+            stableName= '%s.%s_%d'%(paraDict["dbName"],paraDict['stbName'],i)
+            tdSql.query("select count(*) from %s"%stableName)
+            if i == 0 :
+                tdSql.checkData(0,0,rowsPerStb*2)
+            else:
+                tdSql.checkData(0,0,rowsPerStb)   
+        clusterComCheck.check_vgroups_status(vgroup_numbers=paraDict["vgroups"],db_replica=3,db_name=paraDict["dbName"],count_number=150)     
+    def run(self):
+        # print(self.master_dnode.cfgDict)
+        self.fiveDnodeThreeMnode(dnodeNumbers=6,mnodeNums=3,restartNumbers=1,stopRole='dnode')
+
+    def stop(self):
+        tdSql.close()
+        tdLog.success(f"{__file__} successfully executed")
+
+tdCases.addLinux(__file__, TDTestCase())
+tdCases.addWindows(__file__, TDTestCase())
diff --git a/tests/system-test/6-cluster/manually-test/6dnode3mnodeInsertDataRebootModifyMetaAlterRep3to1.py b/tests/system-test/6-cluster/manually-test/6dnode3mnodeInsertDataRebootModifyMetaAlterRep3to1.py
new file mode 100644
index 0000000000..5b5fb04969
--- /dev/null
+++ b/tests/system-test/6-cluster/manually-test/6dnode3mnodeInsertDataRebootModifyMetaAlterRep3to1.py
@@ -0,0 +1,206 @@
+import taos
+import sys
+import time
+import os
+
+from util.log import *
+from util.sql import *
+from util.cases import *
+from util.dnodes import TDDnodes
+from util.dnodes import TDDnode
+from util.cluster import *
+sys.path.append("./6-cluster")
+from clusterCommonCreate import *
+from clusterCommonCheck import clusterComCheck
+
+import time
+import socket
+import subprocess
+from multiprocessing import Process
+import threading
+import time
+import inspect
+import ctypes
+
+class TDTestCase:
+
+    def init(self, conn, logSql, replicaVar=1):
+        tdLog.debug(f"start to excute {__file__}")
+        self.TDDnodes = None
+        tdSql.init(conn.cursor())
+        self.host = socket.gethostname()
+
+
+    def getBuildPath(self):
+        selfPath = os.path.dirname(os.path.realpath(__file__))
+
+        if ("community" in selfPath):
+            projPath = selfPath[:selfPath.find("community")]
+        else:
+            projPath = selfPath[:selfPath.find("tests")]
+
+        for root, dirs, files in os.walk(projPath):
+            if ("taosd" in files):
+                rootRealPath = os.path.dirname(os.path.realpath(root))
+                if ("packaging" not in rootRealPath):
+                    buildPath = root[:len(root) - len("/build/bin")]
+                    break
+        return buildPath
+
+    def _async_raise(self, tid, exctype):
+        """raises the exception, performs cleanup if needed"""
+        if not inspect.isclass(exctype):
+            exctype = type(exctype)
+        res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))
+        if res == 0:
+            raise ValueError("invalid thread id")
+        elif res != 1:
+            # """if it returns a number greater than one, you're in trouble,
+            # and you should call it again with exc=NULL to revert the effect"""
+            ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)
+            raise SystemError("PyThreadState_SetAsyncExc failed")
+
+    def stopThread(self,thread):
+        self._async_raise(thread.ident, SystemExit)
+
+
+    def fiveDnodeThreeMnode(self,dnodeNumbers,mnodeNums,restartNumbers,stopRole):
+        tdLog.printNoPrefix("======== test case 1: ")
+        paraDict = {'dbName':     'db0_0',
+                    'dropFlag':   1,
+                    'event':      '',
+                    'vgroups':    4,
+                    'replica':    3,
+                    'stbName':    'stb',
+                    'stbNumbers': 2,
+                    'colPrefix':  'c',
+                    'tagPrefix':  't',
+                    'colSchema':   [{'type': 'INT', 'count':1}, {'type': 'binary', 'len':20, 'count':1}],
+                    'tagSchema':   [{'type': 'INT', 'count':1}, {'type': 'binary', 'len':20, 'count':1}],
+                    'ctbPrefix':  'ctb',
+                    'ctbNum':     200,
+                    'startTs':    1640966400000,  # 2022-01-01 00:00:00.000
+                    "rowsPerTbl": 1000,
+                    "batchNum": 5000
+                    }
+
+        dnodeNumbers=int(dnodeNumbers)
+        mnodeNums=int(mnodeNums)
+        vnodeNumbers = int(dnodeNumbers-mnodeNums)
+        allctbNumbers=(paraDict['stbNumbers']*paraDict["ctbNum"])
+        rowsPerStb=paraDict["ctbNum"]*paraDict["rowsPerTbl"]
+        rowsall=rowsPerStb*paraDict['stbNumbers']
+        dbNumbers = 1
+
+        tdLog.info("first check dnode and mnode")
+        tdSql.query("select * from information_schema.ins_dnodes;")
+        tdSql.checkData(0,1,'%s:6030'%self.host)
+        tdSql.checkData(4,1,'%s:6430'%self.host)
+        clusterComCheck.checkDnodes(dnodeNumbers)
+        
+        #check mnode status
+        tdLog.info("check mnode status")
+        clusterComCheck.checkMnodeStatus(mnodeNums)
+
+        # add some error operations and
+        tdLog.info("Confirm the status of the dnode again")
+        tdSql.error("create mnode on dnode 2")
+        tdSql.query("select * from information_schema.ins_dnodes;")
+        print(tdSql.queryResult)
+        clusterComCheck.checkDnodes(dnodeNumbers)
+
+        # create database and stable
+        clusterComCreate.create_database(tdSql, paraDict["dbName"],paraDict["dropFlag"], paraDict["vgroups"],paraDict['replica'])
+        tdLog.info("Take turns stopping Mnodes ")
+
+        tdDnodes=cluster.dnodes
+        stopcount =0
+        threads=[]
+
+        # create stable:stb_0
+        stableName= paraDict['stbName']
+        newTdSql=tdCom.newTdSql()
+        clusterComCreate.create_stables(newTdSql, paraDict["dbName"],stableName,paraDict['stbNumbers'])
+        #create child table:ctb_0
+        for i in range(paraDict['stbNumbers']):
+            stableName= '%s_%d'%(paraDict['stbName'],i)
+            newTdSql=tdCom.newTdSql()
+            clusterComCreate.create_ctable(newTdSql, paraDict["dbName"],stableName,stableName, paraDict['ctbNum'])
+        #insert date
+        for i in range(paraDict['stbNumbers']):
+            stableName= '%s_%d'%(paraDict['stbName'],i)
+            newTdSql=tdCom.newTdSql()
+            threads.append(threading.Thread(target=clusterComCreate.insert_data, args=(newTdSql, paraDict["dbName"],stableName,paraDict["ctbNum"],paraDict["rowsPerTbl"],paraDict["batchNum"],paraDict["startTs"])))
+        for tr in threads:
+            tr.start()
+        for tr in threads:
+            tr.join()
+
+        while stopcount < restartNumbers:
+            tdLog.info(" restart loop: %d"%stopcount )
+            if stopRole == "mnode":
+                for i in range(mnodeNums):
+                    tdDnodes[i].stoptaosd()
+                    # sleep(10)
+                    tdDnodes[i].starttaosd()
+                    # sleep(10)
+            elif stopRole == "vnode":
+                for i in range(vnodeNumbers):
+                    tdDnodes[i+mnodeNums].stoptaosd()
+                    # sleep(10)
+                    tdDnodes[i+mnodeNums].starttaosd()
+                    # sleep(10)
+            elif stopRole == "dnode":
+                for i in range(dnodeNumbers):
+                    tdDnodes[i].stoptaosd()
+                    clusterComCheck.checkDbRows(dbNumbers)
+                    if i == 0 :
+                        stableName= '%s_%d'%(paraDict['stbName'],0)
+                        newTdSql=tdCom.newTdSql()
+                        # newTdSql.execute('alter database db0_0 replica 3')
+                        clusterComCreate.alterStbMetaData(newTdSql, paraDict["dbName"],stableName,paraDict["ctbNum"],paraDict["rowsPerTbl"],paraDict["batchNum"])
+                    # sleep(10)
+                    tdDnodes[i].starttaosd()
+                    if i == 3 :
+                        TdSqlEx=tdCom.newTdSql()
+                        tdLog.info("alter database db0_0 replica 1")
+                        TdSqlEx.execute('alter database db0_0 replica 1')
+ 
+
+            # dnodeNumbers don't include database of schema
+            if clusterComCheck.checkDnodes(dnodeNumbers):
+                tdLog.info("123")
+            else:
+                print("456")
+
+                self.stopThread(threads)
+                tdLog.exit("one or more of dnodes failed to start ")
+                # self.check3mnode()
+            stopcount+=1
+
+
+        clusterComCheck.checkDnodes(dnodeNumbers)
+        clusterComCheck.checkDbRows(dbNumbers)
+        # clusterComCheck.checkDb(dbNumbers,1,paraDict["dbName"])
+
+        # tdSql.execute("use %s" %(paraDict["dbName"]))
+        tdSql.query("show %s.stables"%(paraDict["dbName"]))
+        tdSql.checkRows(paraDict["stbNumbers"])
+        for i in range(paraDict['stbNumbers']):
+            stableName= '%s.%s_%d'%(paraDict["dbName"],paraDict['stbName'],i)
+            tdSql.query("select count(*) from %s"%stableName)
+            if i == 0 :
+                tdSql.checkData(0,0,rowsPerStb*2)
+            else:
+                tdSql.checkData(0,0,rowsPerStb)   
+        clusterComCheck.check_vgroups_status(vgroup_numbers=paraDict["vgroups"],db_replica=1,db_name=paraDict["dbName"],count_number=150)    
+    def run(self):
+        # print(self.master_dnode.cfgDict)
+        self.fiveDnodeThreeMnode(dnodeNumbers=6,mnodeNums=3,restartNumbers=1,stopRole='dnode')
+
+    def stop(self):
+        tdSql.close()
+        tdLog.success(f"{__file__} successfully executed")
+
+tdCases.addLinux(__file__, TDTestCase())
+tdCases.addWindows(__file__, TDTestCase())
diff --git a/tests/system-test/6-cluster/manually-test/6dnode3mnodeInsertDatarRebootAlterRep1-3.py b/tests/system-test/6-cluster/manually-test/6dnode3mnodeInsertDatarRebootAlterRep1-3.py
new file mode 100644
index 0000000000..aa3ed8e3fd
--- /dev/null
+++ b/tests/system-test/6-cluster/manually-test/6dnode3mnodeInsertDatarRebootAlterRep1-3.py
@@ -0,0 +1,222 @@
+import taos
+import sys
+import time
+import os
+
+from util.log import *
+from util.sql import *
+from util.cases import *
+from util.dnodes import TDDnodes
+from util.dnodes import TDDnode
+from util.cluster import *
+sys.path.append("./6-cluster")
+from clusterCommonCreate import *
+from clusterCommonCheck import clusterComCheck
+
+import time
+import socket
+import subprocess
+from multiprocessing import Process
+import threading
+import time
+import inspect
+import ctypes
+
+class TDTestCase:
+
+    def init(self, conn, logSql, replicaVar=1):
+        tdLog.debug(f"start to excute {__file__}")
+        self.TDDnodes = None
+        tdSql.init(conn.cursor())
+        self.host = socket.gethostname()
+
+
+    def getBuildPath(self):
+        selfPath = os.path.dirname(os.path.realpath(__file__))
+
+        if ("community" in selfPath):
+            projPath = selfPath[:selfPath.find("community")]
+        else:
+            projPath = selfPath[:selfPath.find("tests")]
+
+        for root, dirs, files in os.walk(projPath):
+            if ("taosd" in files):
+                rootRealPath = os.path.dirname(os.path.realpath(root))
+                if ("packaging" not in rootRealPath):
+                    buildPath = root[:len(root) - len("/build/bin")]
+                    break
+        return buildPath
+
+    def _async_raise(self, tid, exctype):
+        """raises the exception, performs cleanup if needed"""
+        if not inspect.isclass(exctype):
+            exctype = type(exctype)
+        res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))
+        if res == 0:
+            raise ValueError("invalid thread id")
+        elif res != 1:
+            # """if it returns a number greater than one, you're in trouble,
+            # and you should call it again with exc=NULL to revert the effect"""
+            ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)
+            raise SystemError("PyThreadState_SetAsyncExc failed")
+
+    def stopThread(self,thread):
+        self._async_raise(thread.ident, SystemExit)
+
+
+    def insertData(self,countstart,countstop):
+        # fisrt add data : db\stable\childtable\general table
+
+        for couti in range(countstart,countstop):
+            tdLog.debug("drop database if exists db%d" %couti)
+            tdSql.execute("drop database if exists db%d" %couti)
+            print("create database if not exists db%d replica 1 duration 300" %couti)
+            tdSql.execute("create database if not exists db%d replica 1 duration 300" %couti)
+            tdSql.execute("use db%d" %couti)
+            tdSql.execute(
+            '''create table stb1
+            (ts timestamp, c1 int, c2 bigint, c3 smallint, c4 tinyint, c5 float, c6 double, c7 bool, c8 binary(16),c9 nchar(32), c10 timestamp)
+            tags (t1 int)
+            '''
+            )
+            tdSql.execute(
+                '''
+                create table t1
+                (ts timestamp, c1 int, c2 bigint, c3 smallint, c4 tinyint, c5 float, c6 double, c7 bool, c8 binary(16),c9 nchar(32), c10 timestamp)
+                '''
+            )
+            for i in range(4):
+                tdSql.execute(f'create table ct{i+1} using stb1 tags ( {i+1} )')
+
+
+    def fiveDnodeThreeMnode(self,dnodeNumbers,mnodeNums,restartNumbers,stopRole):
+        tdLog.printNoPrefix("======== test case 1: ")
+        paraDict = {'dbName':     'db0_0',
+                    'dropFlag':   1,
+                    'event':      '',
+                    'vgroups':    4,
+                    'replica':    1,
+                    'stbName':    'stb',
+                    'stbNumbers': 2,
+                    'colPrefix':  'c',
+                    'tagPrefix':  't',
+                    'colSchema':   [{'type': 'INT', 'count':1}, {'type': 'binary', 'len':20, 'count':1}],
+                    'tagSchema':   [{'type': 'INT', 'count':1}, {'type': 'binary', 'len':20, 'count':1}],
+                    'ctbPrefix':  'ctb',
+                    'ctbNum':     1000,
+                    'startTs':    1640966400000,  # 2022-01-01 00:00:00.000
+                    "rowsPerTbl": 100,
+                    "batchNum": 5000
+                    }
+
+        dnodeNumbers = int(dnodeNumbers)
+        mnodeNums = int(mnodeNums)
+        vnodeNumbers = int(dnodeNumbers-mnodeNums)
+        allctbNumbers = (paraDict['stbNumbers']*paraDict["ctbNum"])
+        rowsPerStb = paraDict["ctbNum"]*paraDict["rowsPerTbl"]
+        rowsall = rowsPerStb*paraDict['stbNumbers']
+        dbNumbers = 1
+        replica3 = 3
+        tdLog.info("first check dnode and mnode")
+        tdSql.query("select * from information_schema.ins_dnodes;")
+        tdSql.checkData(0,1,'%s:6030'%self.host)
+        tdSql.checkData(4,1,'%s:6430'%self.host)
+        clusterComCheck.checkDnodes(dnodeNumbers)
+        
+        #check mnode status
+        tdLog.info("check mnode status")
+        clusterComCheck.checkMnodeStatus(mnodeNums)
+
+        # add some error operations and
+        tdLog.info("Confirm the status of the dnode again")
+        tdSql.error("create mnode on dnode 2")
+        tdSql.query("select * from information_schema.ins_dnodes;")
+        print(tdSql.queryResult)
+        clusterComCheck.checkDnodes(dnodeNumbers)
+
+        # create database and stable
+        clusterComCreate.create_database(tdSql, paraDict["dbName"],paraDict["dropFlag"], paraDict["vgroups"],paraDict['replica'])
+        tdLog.info("Take turns stopping Mnodes ")
+
+        tdDnodes=cluster.dnodes
+        stopcount =0
+        threads=[]
+
+        # create stable:stb_0
+        stableName= paraDict['stbName']
+        newTdSql=tdCom.newTdSql()
+        clusterComCreate.create_stables(newTdSql, paraDict["dbName"],stableName,paraDict['stbNumbers'])
+        #create child table:ctb_0
+        for i in range(paraDict['stbNumbers']):
+            stableName= '%s_%d'%(paraDict['stbName'],i)
+            newTdSql=tdCom.newTdSql()
+            clusterComCreate.create_ctable(newTdSql, paraDict["dbName"],stableName,stableName, paraDict['ctbNum'])
+        #insert date
+        for i in range(paraDict['stbNumbers']):
+            stableName= '%s_%d'%(paraDict['stbName'],i)
+            newTdSql=tdCom.newTdSql()
+            threads.append(threading.Thread(target=clusterComCreate.insert_data, args=(newTdSql, paraDict["dbName"],stableName,paraDict["ctbNum"],paraDict["rowsPerTbl"],paraDict["batchNum"],paraDict["startTs"])))
+        for tr in threads:
+            tr.start()
+        TdSqlEx=tdCom.newTdSql()
+        tdLog.info("alter database db0_0 replica 3")
+        TdSqlEx.execute('alter database db0_0 replica 3')
+        while stopcount < restartNumbers:
+            tdLog.info(" restart loop: %d"%stopcount )
+            if stopRole == "mnode":
+                for i in range(mnodeNums):
+                    tdDnodes[i].stoptaosd()
+                    # sleep(10)
+                    tdDnodes[i].starttaosd()
+                    # sleep(10)
+            elif stopRole == "vnode":
+                for i in range(vnodeNumbers):
+                    tdDnodes[i+mnodeNums].stoptaosd()
+                    # sleep(10)
+                    tdDnodes[i+mnodeNums].starttaosd()
+                    # sleep(10)
+            elif stopRole == "dnode":
+                for i in range(dnodeNumbers):
+                    tdDnodes[i].stoptaosd()
+                    # tdLog.info('select  cast(c2 as nchar(10)) from db0_0.stb_1;')
+                    # TdSqlEx.execute('select  cast(c2 as nchar(10)) from db0_0.stb_1;')
+                    # tdLog.info('select  avg(c1)  from db0_0.stb_0 interval(10s);')
+                    # TdSqlEx.execute('select  avg(c1)  from db0_0.stb_0 interval(10s);')
+                    # sleep(10)
+                    tdDnodes[i].starttaosd()
+                    # sleep(10)
+            # dnodeNumbers don't include database of schema
+            if clusterComCheck.checkDnodes(dnodeNumbers):
+                tdLog.info("123")
+            else:
+                print("456")
+
+                self.stopThread(threads)
+                tdLog.exit("one or more of dnodes failed to start ")
+                # self.check3mnode()
+            stopcount+=1
+
+        for tr in threads:
+            tr.join()
+        clusterComCheck.checkDnodes(dnodeNumbers)
+        clusterComCheck.checkDbRows(dbNumbers)
+        # clusterComCheck.checkDb(dbNumbers,1,paraDict["dbName"])
+
+        # tdSql.execute("use %s" %(paraDict["dbName"]))
+        tdSql.query("show %s.stables"%(paraDict["dbName"]))
+        tdSql.checkRows(paraDict["stbNumbers"])
+        # for i in range(paraDict['stbNumbers']):
+        #     stableName= '%s.%s_%d'%(paraDict["dbName"],paraDict['stbName'],i)
+        #     tdSql.query("select count(*) from %s"%stableName)
+        #     tdSql.checkData(0,0,rowsPerStb)
+        clusterComCheck.check_vgroups_status(vgroup_numbers=paraDict["vgroups"],db_replica=replica3,db_name=paraDict["dbName"],count_number=240)        
+    def run(self):
+        # print(self.master_dnode.cfgDict)
+        self.fiveDnodeThreeMnode(dnodeNumbers=6,mnodeNums=3,restartNumbers=4,stopRole='dnode')
+
+    def stop(self):
+        tdSql.close()
+        tdLog.success(f"{__file__} successfully executed")
+
+tdCases.addLinux(__file__, TDTestCase())
+tdCases.addWindows(__file__, TDTestCase())
diff --git a/tests/system-test/6-cluster/manually-test/6dnode3mnodeInsertLessDataAlterRep3to1to3.py b/tests/system-test/6-cluster/manually-test/6dnode3mnodeInsertLessDataAlterRep3to1to3.py
new file mode 100644
index 0000000000..ed7b99a880
--- /dev/null
+++ b/tests/system-test/6-cluster/manually-test/6dnode3mnodeInsertLessDataAlterRep3to1to3.py
@@ -0,0 +1,196 @@
+import taos
+import sys
+import time
+import os
+
+from util.log import *
+from util.sql import *
+from util.cases import *
+from util.dnodes import TDDnodes
+from util.dnodes import TDDnode
+from util.cluster import *
+sys.path.append("./6-cluster")
+from clusterCommonCreate import *
+from clusterCommonCheck import clusterComCheck
+
+import time
+import socket
+import subprocess
+from multiprocessing import Process
+import threading
+import time
+import inspect
+import ctypes
+
+class TDTestCase:
+
+    def init(self, conn, logSql, replicaVar=1):
+        tdLog.debug(f"start to excute {__file__}")
+        self.TDDnodes = None
+        tdSql.init(conn.cursor())
+        self.host = socket.gethostname()
+
+
+    def getBuildPath(self):
+        selfPath = os.path.dirname(os.path.realpath(__file__))
+
+        if ("community" in selfPath):
+            projPath = selfPath[:selfPath.find("community")]
+        else:
+            projPath = selfPath[:selfPath.find("tests")]
+
+        for root, dirs, files in os.walk(projPath):
+            if ("taosd" in files):
+                rootRealPath = os.path.dirname(os.path.realpath(root))
+                if ("packaging" not in rootRealPath):
+                    buildPath = root[:len(root) - len("/build/bin")]
+                    break
+        return buildPath
+
+    def _async_raise(self, tid, exctype):
+        """raises the exception, performs cleanup if needed"""
+        if not inspect.isclass(exctype):
+            exctype = type(exctype)
+        res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))
+        if res == 0:
+            raise ValueError("invalid thread id")
+        elif res != 1:
+            # """if it returns a number greater than one, you're in trouble,
+            # and you should call it again with exc=NULL to revert the effect"""
+            ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)
+            raise SystemError("PyThreadState_SetAsyncExc failed")
+
+    def stopThread(self,thread):
+        self._async_raise(thread.ident, SystemExit)
+
+
+    def insertData(self,countstart,countstop):
+        # fisrt add data : db\stable\childtable\general table
+
+        for couti in range(countstart,countstop):
+            tdLog.debug("drop database if exists db%d" %couti)
+            tdSql.execute("drop database if exists db%d" %couti)
+            print("create database if not exists db%d replica 1 duration 300" %couti)
+            tdSql.execute("create database if not exists db%d replica 1 duration 300" %couti)
+            tdSql.execute("use db%d" %couti)
+            tdSql.execute(
+            '''create table stb1
+            (ts timestamp, c1 int, c2 bigint, c3 smallint, c4 tinyint, c5 float, c6 double, c7 bool, c8 binary(16),c9 nchar(32), c10 timestamp)
+            tags (t1 int)
+            '''
+            )
+            tdSql.execute(
+                '''
+                create table t1
+                (ts timestamp, c1 int, c2 bigint, c3 smallint, c4 tinyint, c5 float, c6 double, c7 bool, c8 binary(16),c9 nchar(32), c10 timestamp)
+                '''
+            )
+            for i in range(4):
+                tdSql.execute(f'create table ct{i+1} using stb1 tags ( {i+1} )')
+
+
+    def fiveDnodeThreeMnode(self,dnodeNumbers,mnodeNums,restartNumbers,stopRole):
+        tdLog.printNoPrefix("======== test case 1: ")
+        paraDict = {'dbName':     'db0_0',
+                    'dropFlag':   1,
+                    'event':      '',
+                    'vgroups':    4,
+                    'replica':    3,
+                    'stbName':    'stb',
+                    'stbNumbers': 2,
+                    'colPrefix':  'c',
+                    'tagPrefix':  't',
+                    'colSchema':   [{'type': 'INT', 'count':1}, {'type': 'binary', 'len':20, 'count':1}],
+                    'tagSchema':   [{'type': 'INT', 'count':1}, {'type': 'binary', 'len':20, 'count':1}],
+                    'ctbPrefix':  'ctb',
+                    'ctbNum':     1,
+                    'startTs':    1640966400000,  # 2022-01-01 00:00:00.000
+                    "rowsPerTbl": 1,
+                    "batchNum": 5000
+                    }
+
+        dnodeNumbers=int(dnodeNumbers)
+        mnodeNums=int(mnodeNums)
+        vnodeNumbers = int(dnodeNumbers-mnodeNums)
+        replica1 = 1
+        replica3 = 3
+        allctbNumbers=(paraDict['stbNumbers']*paraDict["ctbNum"])
+        rowsPerStb=paraDict["ctbNum"]*paraDict["rowsPerTbl"]
+        rowsall=rowsPerStb*paraDict['stbNumbers']
+        dbNumbers = 1
+
+        tdLog.info("first check dnode and mnode")
+        tdSql.query("select * from information_schema.ins_dnodes;")
+        tdSql.checkData(0,1,'%s:6030'%self.host)
+        tdSql.checkData(4,1,'%s:6430'%self.host)
+        clusterComCheck.checkDnodes(dnodeNumbers)
+        
+        #check mnode status
+        tdLog.info("check mnode status")
+        clusterComCheck.checkMnodeStatus(mnodeNums)
+
+        # add some error operations and
+        tdLog.info("Confirm the status of the dnode again")
+        tdSql.error("create mnode on dnode 2")
+        tdSql.query("select * from information_schema.ins_dnodes;")
+        print(tdSql.queryResult)
+        clusterComCheck.checkDnodes(dnodeNumbers)
+
+        # create database and stable
+        clusterComCreate.create_database(tdSql, paraDict["dbName"],paraDict["dropFlag"], paraDict["vgroups"],paraDict['replica'])
+        tdLog.info("Take turns stopping Mnodes ")
+
+        tdDnodes=cluster.dnodes
+        stopcount =0
+        threads=[]
+
+        # create stable:stb_0
+        stableName= paraDict['stbName']
+        newTdSql=tdCom.newTdSql()
+        clusterComCreate.create_stables(newTdSql, paraDict["dbName"],stableName,paraDict['stbNumbers'])
+        #create child table:ctb_0
+        for i in range(paraDict['stbNumbers']):
+            stableName= '%s_%d'%(paraDict['stbName'],i)
+            newTdSql=tdCom.newTdSql()
+            clusterComCreate.create_ctable(newTdSql, paraDict["dbName"],stableName,stableName, paraDict['ctbNum'])
+        #insert date
+        for i in range(paraDict['stbNumbers']):
+            stableName= '%s_%d'%(paraDict['stbName'],i)
+            newTdSql=tdCom.newTdSql()
+            threads.append(threading.Thread(target=clusterComCreate.insert_data, args=(newTdSql, paraDict["dbName"],stableName,paraDict["ctbNum"],paraDict["rowsPerTbl"],paraDict["batchNum"],paraDict["startTs"])))
+        for tr in threads:
+            tr.start()
+        TdSqlEx=tdCom.newTdSql()
+        tdLog.info(f"alter database db0_0 replica {replica1}")
+        TdSqlEx.execute(f'alter database db0_0 replica {replica1}')
+        for tr in threads:
+            tr.join()
+        clusterComCheck.checkDnodes(dnodeNumbers)
+        clusterComCheck.checkDbRows(dbNumbers)
+        # clusterComCheck.checkDb(dbNumbers,1,paraDict["dbName"])
+
+        # tdSql.execute("use %s" %(paraDict["dbName"]))
+        tdSql.query("show %s.stables"%(paraDict["dbName"]))
+        tdSql.checkRows(paraDict["stbNumbers"])
+        for i in range(paraDict['stbNumbers']):
+            stableName= '%s.%s_%d'%(paraDict["dbName"],paraDict['stbName'],i)
+            tdSql.query("select count(*) from %s"%stableName)
+            tdSql.checkData(0,0,rowsPerStb)
+        
+        clusterComCheck.check_vgroups_status(vgroup_numbers=paraDict["vgroups"],db_replica=replica1,db_name=paraDict["dbName"],count_number=20)
+        sleep(5)
+        tdLog.info(f"show transactions;alter database db0_0 replica {replica3};")
+        TdSqlEx.execute(f'show transactions;')
+        TdSqlEx.execute(f'alter database db0_0 replica {replica3};')
+        clusterComCheck.check_vgroups_status(vgroup_numbers=paraDict["vgroups"],db_replica=replica3,db_name=paraDict["dbName"],count_number=120)
+
+    def run(self):
+        # print(self.master_dnode.cfgDict)
+        self.fiveDnodeThreeMnode(dnodeNumbers=6,mnodeNums=3,restartNumbers=4,stopRole='dnode')
+
+    def stop(self):
+        tdSql.close()
+        tdLog.success(f"{__file__} successfully executed")
+
+tdCases.addLinux(__file__, TDTestCase())
+tdCases.addWindows(__file__, TDTestCase())
diff --git a/tests/system-test/6-cluster/manually-test/6dnode3mnodeStopDnodeInsertDatatb.py b/tests/system-test/6-cluster/manually-test/6dnode3mnodeStopDnodeInsertDatatb.py
new file mode 100644
index 0000000000..e02af29a05
--- /dev/null
+++ b/tests/system-test/6-cluster/manually-test/6dnode3mnodeStopDnodeInsertDatatb.py
@@ -0,0 +1,191 @@
+import taos
+import sys
+import time
+import os
+
+from util.log import *
+from util.sql import *
+from util.cases import *
+from util.dnodes import TDDnodes
+from util.dnodes import TDDnode
+from util.cluster import *
+sys.path.append("./6-cluster")
+from clusterCommonCreate import *
+from clusterCommonCheck import clusterComCheck
+
+import time
+import socket
+import subprocess
+from multiprocessing import Process
+import threading
+import time
+import inspect
+import ctypes
+
+class TDTestCase:
+
+    def init(self, conn, logSql, replicaVar=1):
+        tdLog.debug(f"start to excute {__file__}")
+        self.TDDnodes = None
+        tdSql.init(conn.cursor())
+        self.host = socket.gethostname()
+
+
+    def getBuildPath(self):
+        selfPath = os.path.dirname(os.path.realpath(__file__))
+
+        if ("community" in selfPath):
+            projPath = selfPath[:selfPath.find("community")]
+        else:
+            projPath = selfPath[:selfPath.find("tests")]
+
+        for root, dirs, files in os.walk(projPath):
+            if ("taosd" in files):
+                rootRealPath = os.path.dirname(os.path.realpath(root))
+                if ("packaging" not in rootRealPath):
+                    buildPath = root[:len(root) - len("/build/bin")]
+                    break
+        return buildPath
+
+    def _async_raise(self, tid, exctype):
+        """raises the exception, performs cleanup if needed"""
+        if not inspect.isclass(exctype):
+            exctype = type(exctype)
+        res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))
+        if res == 0:
+            raise ValueError("invalid thread id")
+        elif res != 1:
+            # """if it returns a number greater than one, you're in trouble,
+            # and you should call it again with exc=NULL to revert the effect"""
+            ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)
+            raise SystemError("PyThreadState_SetAsyncExc failed")
+
+    def stopThread(self,thread):
+        self._async_raise(thread.ident, SystemExit)
+
+
+    def insertData(self,dbname,tableCount,rowsPerCount):
+        # tableCount : create table number
+        # rowsPerCount :  rows per table
+        # fisrt add data : db\stable\childtable\general table
+        os.system(f"taosBenchmark  -d {dbname} -n {tableCount} -t {rowsPerCount}  -z 1 -k 10000 -y ")
+
+
+    def fiveDnodeThreeMnode(self,dnodeNumbers,mnodeNums,restartNumbers,stopRole):
+        tdLog.printNoPrefix("======== test case 1: ")
+        paraDict = {'dbName':     'db0_0',
+                    'dropFlag':   1,
+                    'event':      '',
+                    'vgroups':    4,
+                    'replica':    1,
+                    'stbName':    'stb',
+                    'stbNumbers': 2,
+                    'colPrefix':  'c',
+                    'tagPrefix':  't',
+                    'colSchema':   [{'type': 'INT', 'count':1}, {'type': 'binary', 'len':20, 'count':1}],
+                    'tagSchema':   [{'type': 'INT', 'count':1}, {'type': 'binary', 'len':20, 'count':1}],
+                    'ctbPrefix':  'ctb',
+                    'ctbNum':     10000,
+                    'startTs':    1640966400000,  # 2022-01-01 00:00:00.000
+                    "rowsPerTbl": 10000,
+                    "batchNum": 5000
+                    }
+
+        dnodeNumbers=int(dnodeNumbers)
+        mnodeNums=int(mnodeNums)
+        vnodeNumbers = int(dnodeNumbers-mnodeNums)
+        allctbNumbers=(paraDict['stbNumbers']*paraDict["ctbNum"])
+        rowsPerStb=paraDict["ctbNum"]*paraDict["rowsPerTbl"]
+        rowsall=rowsPerStb*paraDict['stbNumbers']
+        dbNumbers = 1
+
+        tdLog.info("first check dnode and mnode")
+        tdSql.query("select * from information_schema.ins_dnodes;")
+        tdSql.checkData(0,1,'%s:6030'%self.host)
+        tdSql.checkData(4,1,'%s:6430'%self.host)
+        clusterComCheck.checkDnodes(dnodeNumbers)
+        
+        #check mnode status
+        tdLog.info("check mnode status")
+        clusterComCheck.checkMnodeStatus(mnodeNums)
+
+        # add some error operations and
+        tdLog.info("Confirm the status of the dnode again")
+        tdSql.error("create mnode on dnode 2")
+        tdSql.query("select * from information_schema.ins_dnodes;")
+        print(tdSql.queryResult)
+        clusterComCheck.checkDnodes(dnodeNumbers)
+
+        # create database and stable
+        tdLog.info("Take turns stopping Mnodes ")
+
+        tdDnodes=cluster.dnodes
+        stopcount =0
+        threads=[]
+
+        # create stable:stb_0
+        threads.append(threading.Thread(target=self.insertData, args=(paraDict["dbName"],paraDict["ctbNum"],paraDict["rowsPerTbl"])))
+        for tr in threads:
+            tr.start()
+        TdSqlEx=tdCom.newTdSql()
+        tdLog.info("alter database db0_0 replica 3")
+        TdSqlEx.execute('alter database db0_0 replica 3')
+        while stopcount < restartNumbers:
+            tdLog.info(" restart loop: %d"%stopcount )
+            if stopRole == "mnode":
+                for i in range(mnodeNums):
+                    tdDnodes[i].stoptaosd()
+                    # sleep(10)
+                    tdDnodes[i].starttaosd()
+                    # sleep(10)
+            elif stopRole == "vnode":
+                for i in range(vnodeNumbers):
+                    tdDnodes[i+mnodeNums].stoptaosd()
+                    # sleep(10)
+                    tdDnodes[i+mnodeNums].starttaosd()
+                    # sleep(10)
+            elif stopRole == "dnode":
+                for i in range(dnodeNumbers):
+                    tdDnodes[i].stoptaosd()
+                    # tdLog.info('select  cast(c2 as nchar(10)) from db0_0.stb_1;')
+                    # TdSqlEx.execute('select  cast(c2 as nchar(10)) from db0_0.stb_1;')
+                    # tdLog.info('select  avg(c1)  from db0_0.stb_0 interval(10s);')
+                    # TdSqlEx.execute('select  avg(c1)  from db0_0.stb_0 interval(10s);')
+                    # sleep(10)
+                    tdDnodes[i].starttaosd()
+                    # sleep(10)
+            # dnodeNumbers don't include database of schema
+            if clusterComCheck.checkDnodes(dnodeNumbers):
+                tdLog.info("123")
+            else:
+                print("456")
+
+                self.stopThread(threads)
+                tdLog.exit("one or more of dnodes failed to start ")
+                # self.check3mnode()
+            stopcount+=1
+
+        for tr in threads:
+            tr.join()
+        clusterComCheck.checkDnodes(dnodeNumbers)
+        clusterComCheck.checkDbRows(dbNumbers)
+        # clusterComCheck.checkDb(dbNumbers,1,paraDict["dbName"])
+
+        # tdSql.execute("use %s" %(paraDict["dbName"]))
+        tdSql.query("show %s.stables"%(paraDict["dbName"]))
+        tdSql.checkRows(paraDict["stbNumbers"])
+        for i in range(paraDict['stbNumbers']):
+            stableName= '%s.%s_%d'%(paraDict["dbName"],paraDict['stbName'],i)
+            tdSql.query("select count(*) from %s"%stableName)
+            tdSql.checkData(0,0,rowsPerStb)
+        clusterComCheck.check_vgroups_status(vgroup_numbers=paraDict["vgroups"],db_replica=3,db_name=paraDict["dbName"],count_number=240)             
+    def run(self):
+        # print(self.master_dnode.cfgDict)
+        self.fiveDnodeThreeMnode(dnodeNumbers=6,mnodeNums=3,restartNumbers=4,stopRole='dnode')
+
+    def stop(self):
+        tdSql.close()
+        tdLog.success(f"{__file__} successfully executed")
+
+tdCases.addLinux(__file__, TDTestCase())
+tdCases.addWindows(__file__, TDTestCase())
diff --git a/tests/system-test/7-tmq/stbTagFilter-1ctb.py b/tests/system-test/7-tmq/stbTagFilter-1ctb.py
index 7ee5fce5a8..1867dc54cb 100644
--- a/tests/system-test/7-tmq/stbTagFilter-1ctb.py
+++ b/tests/system-test/7-tmq/stbTagFilter-1ctb.py
@@ -111,7 +111,7 @@ class TDTestCase:
         topicFromStb1 = 'topic_UpperCase_stb1'
         # queryString = "select ts, c1, c2 from %s.%s where t4 == 'shanghai' or t4 == 'changsha'"%(paraDict['dbName'], paraDict['stbName'])
         queryString = "select ts, c1, c2, t4 from %s.%s where t4 == 'shanghai' or t4 == 'changsha'"%(paraDict['dbName'], paraDict['stbName'])
-        sqlString = "create topic %s as %s" %(topicFromStb1, queryString)
+        sqlString = "create topic `%s` as %s" %(topicFromStb1, queryString)
         tdLog.info("create topic sql: %s"%sqlString)
         tdSql.execute(sqlString)
 
@@ -148,7 +148,7 @@ class TDTestCase:
 
         tmqCom.checkFileContent(consumerId, queryString)
 
-        tdSql.query("drop topic %s"%topicFromStb1)
+        tdSql.query("drop topic `%s`"%topicFromStb1)
         tdLog.printNoPrefix("======== test case 1 end ...... ")
 
     def tmqCase2(self):
@@ -196,7 +196,7 @@ class TDTestCase:
         topicFromStb1 = 'topic_UpperCase_stb1'
         queryString = "select ts, c1, c2 from %s.%s where t4 == 'shanghai' or t4 == 'changsha'"%(paraDict['dbName'], paraDict['stbName'])
         # queryString = "select ts, c1, c2, t4 from %s.%s where t4 == 'shanghai' or t4 == 'changsha'"%(paraDict['dbName'], paraDict['stbName'])
-        sqlString = "create topic %s as %s" %(topicFromStb1, queryString)
+        sqlString = "create topic `%s` as %s" %(topicFromStb1, queryString)
         tdLog.info("create topic sql: %s"%sqlString)
         tdSql.execute(sqlString)
 
@@ -242,7 +242,7 @@ class TDTestCase:
 
         # tmqCom.checkFileContent(consumerId, queryString)
 
-        tdSql.query("drop topic %s"%topicFromStb1)
+        tdSql.query("drop topic `%s`"%topicFromStb1)
 
         tdLog.printNoPrefix("======== test case 2 end ...... ")
 
diff --git a/tests/system-test/7-tmq/stbTagFilter-multiCtb.py b/tests/system-test/7-tmq/stbTagFilter-multiCtb.py
index 71b7fdef5d..67cc60d196 100644
--- a/tests/system-test/7-tmq/stbTagFilter-multiCtb.py
+++ b/tests/system-test/7-tmq/stbTagFilter-multiCtb.py
@@ -111,7 +111,7 @@ class TDTestCase:
         topicFromStb1 = 'topic_UpperCase_stb1'
         queryString = "select ts, c1, c2 from %s.%s where t4 == 'beijing' or t4 == 'changsha'"%(paraDict['dbName'], paraDict['stbName'])
         # queryString = "select ts, c1, c2, t4 from %s.%s where t4 == 'beijing' or t4 == 'changsha'"%(paraDict['dbName'], paraDict['stbName'])
-        sqlString = "create topic %s as %s" %(topicFromStb1, queryString)
+        sqlString = "create topic `%s` as %s" %(topicFromStb1, queryString)
         tdLog.info("create topic sql: %s"%sqlString)
         tdSql.execute(sqlString)
 
@@ -148,7 +148,7 @@ class TDTestCase:
 
         # tmqCom.checkFileContent(consumerId, queryString)
 
-        tdSql.query("drop topic %s"%topicFromStb1)
+        tdSql.query("drop topic `%s`"%topicFromStb1)
         tdLog.printNoPrefix("======== test case 1 end ...... ")
 
     def tmqCase2(self):
@@ -196,7 +196,7 @@ class TDTestCase:
         topicFromStb1 = 'topic_UpperCase_stb1'
         # queryString = "select ts, c1, c2 from %s.%s where t4 == 'beijing' or t4 == 'changsha'"%(paraDict['dbName'], paraDict['stbName'])
         queryString = "select ts, c1, c2, t4 from %s.%s where t4 == 'beijing' or t4 == 'changsha'"%(paraDict['dbName'], paraDict['stbName'])
-        sqlString = "create topic %s as %s" %(topicFromStb1, queryString)
+        sqlString = "create topic `%s` as %s" %(topicFromStb1, queryString)
         tdLog.info("create topic sql: %s"%sqlString)
         tdSql.execute(sqlString)
 
@@ -244,7 +244,7 @@ class TDTestCase:
 
         # tmqCom.checkFileContent(consumerId, queryString)
 
-        tdSql.query("drop topic %s"%topicFromStb1)
+        tdSql.query("drop topic `%s`"%topicFromStb1)
 
         tdLog.printNoPrefix("======== test case 2 end ...... ")
 
diff --git a/tests/system-test/7-tmq/subscribeDb3.py b/tests/system-test/7-tmq/subscribeDb3.py
index 1de9b62bcd..b66334a6a6 100644
--- a/tests/system-test/7-tmq/subscribeDb3.py
+++ b/tests/system-test/7-tmq/subscribeDb3.py
@@ -10,6 +10,8 @@ from util.log import *
 from util.sql import *
 from util.cases import *
 from util.dnodes import *
+sys.path.append("./7-tmq")
+from tmqCommon import *
 
 class TDTestCase:
     hostname = socket.gethostname()
@@ -67,26 +69,26 @@ class TDTestCase:
         tdLog.info("consume info sql: %s"%sql)
         tdSql.query(sql)
 
-    def getStartConsumeNotifyFromTmqsim(self,cdbName='cdb'):
-        while 1:
-            tdSql.query("select * from %s.notifyinfo"%cdbName)
-            #tdLog.info("row: %d, %l64d, %l64d"%(tdSql.getData(0, 1),tdSql.getData(0, 2),tdSql.getData(0, 3))
-            if (tdSql.getRows() == 1) and (tdSql.getData(0, 1) == 0):
-                break
-            else:
-                time.sleep(0.1)
-        return
-
-    def getStartCommitNotifyFromTmqsim(self,cdbName='cdb'):
-        while 1:
-            tdSql.query("select * from %s.notifyinfo"%cdbName)
-            #tdLog.info("row: %d, %l64d, %l64d"%(tdSql.getData(0, 1),tdSql.getData(0, 2),tdSql.getData(0, 3))
-            if tdSql.getRows() == 2 :
-                tdLog.info("row[0][1]: %d, row[1][1]: %d"%(tdSql.getData(0, 1), tdSql.getData(1, 1)))
-                if tdSql.getData(1, 1) == 1:
-                    break
-            time.sleep(0.1)
-        return
+    # def getStartConsumeNotifyFromTmqsim(self,cdbName='cdb'):
+    #     while 1:
+    #         tdSql.query("select * from %s.notifyinfo"%cdbName)
+    #         #tdLog.info("row: %d, %l64d, %l64d"%(tdSql.getData(0, 1),tdSql.getData(0, 2),tdSql.getData(0, 3))
+    #         if (tdSql.getRows() == 1) and (tdSql.getData(0, 1) == 0):
+    #             break
+    #         else:
+    #             time.sleep(0.1)
+    #     return
+    #
+    # def getStartCommitNotifyFromTmqsim(self,cdbName='cdb'):
+    #     while 1:
+    #         tdSql.query("select * from %s.notifyinfo"%cdbName)
+    #         #tdLog.info("row: %d, %l64d, %l64d"%(tdSql.getData(0, 1),tdSql.getData(0, 2),tdSql.getData(0, 3))
+    #         if tdSql.getRows() == 2 :
+    #             tdLog.info("row[0][1]: %d, row[1][1]: %d"%(tdSql.getData(0, 1), tdSql.getData(1, 1)))
+    #             if tdSql.getData(1, 1) == 1:
+    #                 break
+    #         time.sleep(0.1)
+    #     return
 
     def selectConsumeResult(self,expectRows,cdbName='cdb'):
         resultList=[]
@@ -233,7 +235,7 @@ class TDTestCase:
         self.startTmqSimProcess(buildPath,cfgPath,pollDelay,parameterDict["dbName"],showMsg, showRow)
 
         tdLog.info("wait the notify info of start consume")
-        self.getStartConsumeNotifyFromTmqsim()
+        tmqCom.getStartConsumeNotifyFromTmqsim()
 
         tdLog.info("pkill consume processor")
         if (platform.system().lower() == 'windows'):
@@ -311,7 +313,7 @@ class TDTestCase:
 
         # time.sleep(6)
         tdLog.info("start to wait commit notify")
-        self.getStartCommitNotifyFromTmqsim()
+        tmqCom.getStartCommitNotifyFromTmqsim()
 
         tdLog.info("pkill consume processor")
         if (platform.system().lower() == 'windows'):
@@ -334,7 +336,7 @@ class TDTestCase:
         for i in range(expectRows):
             totalConsumeRows += resultList[i]
 
-        if totalConsumeRows >= expectrowcnt or totalConsumeRows <= 0:
+        if totalConsumeRows > expectrowcnt or totalConsumeRows <= 0:
             tdLog.info("act consume rows: %d, expect consume rows between %d and 0"%(totalConsumeRows, expectrowcnt))
             tdLog.exit("tmq consume rows error!")
 
diff --git a/tests/system-test/7-tmq/subscribeStb.py b/tests/system-test/7-tmq/subscribeStb.py
index 9dcbf5b351..53f1a34d58 100644
--- a/tests/system-test/7-tmq/subscribeStb.py
+++ b/tests/system-test/7-tmq/subscribeStb.py
@@ -226,12 +226,11 @@ class TDTestCase:
         self.insertConsumerInfo(consumerId, expectrowcnt,topicList,keyList,ifcheckdata,ifManualCommit)
 
         tdLog.info("start consume processor")
-        pollDelay = 5
+        pollDelay = 10
         showMsg   = 1
         showRow   = 1
         self.startTmqSimProcess(buildPath,cfgPath,pollDelay,parameterDict["dbName"],showMsg, showRow)
 
-        time.sleep(5)
         self.create_ctables(tdSql, parameterDict["dbName"], parameterDict["stbName"], parameterDict["ctbNum"])
         self.insert_data(tdSql,\
                          parameterDict["dbName"],\
@@ -307,7 +306,7 @@ class TDTestCase:
         self.insertConsumerInfo(consumerId, expectrowcnt,topicList,keyList,ifcheckdata,ifManualCommit)
 
         tdLog.info("start consume processor")
-        pollDelay = 5
+        pollDelay = 10
         showMsg   = 1
         showRow   = 1
         self.startTmqSimProcess(buildPath,cfgPath,pollDelay,parameterDict["dbName"],showMsg, showRow)
diff --git a/tests/system-test/7-tmq/tmqCommon.py b/tests/system-test/7-tmq/tmqCommon.py
index f63c70a4c6..44eef8bf24 100644
--- a/tests/system-test/7-tmq/tmqCommon.py
+++ b/tests/system-test/7-tmq/tmqCommon.py
@@ -145,31 +145,29 @@ class TMQCom:
             processID = subprocess.check_output(psCmd, shell=True).decode("utf-8")
         tdLog.debug("%s is stopped by kill -INT" % (processorName))
 
-    def getStartConsumeNotifyFromTmqsim(self,cdbName='cdb',rows=1):
+    def getStartConsumeNotifyFromTmqsim(self,cdbName='cdb'):
         loopFlag = 1
         while loopFlag:
             tdSql.query("select * from %s.notifyinfo"%cdbName)
             #tdLog.info("row: %d, %l64d, %l64d"%(tdSql.getData(0, 1),tdSql.getData(0, 2),tdSql.getData(0, 3))
             actRows = tdSql.getRows()
-            if (actRows >= rows):
-                for i in range(actRows):
-                    if tdSql.getData(i, 1) == 0:
-                        loopFlag = 0
-                        break
+            for i in range(actRows):
+                if tdSql.getData(i, 1) == 0:
+                    loopFlag = 0
+                    break
             time.sleep(0.02)
         return
 
-    def getStartCommitNotifyFromTmqsim(self,cdbName='cdb',rows=2):
+    def getStartCommitNotifyFromTmqsim(self,cdbName='cdb'):
         loopFlag = 1
         while loopFlag:
             tdSql.query("select * from %s.notifyinfo"%cdbName)
             #tdLog.info("row: %d, %l64d, %l64d"%(tdSql.getData(0, 1),tdSql.getData(0, 2),tdSql.getData(0, 3))
             actRows = tdSql.getRows()
-            if (actRows >= rows):
-                for i in range(actRows):
-                    if tdSql.getData(i, 1) == 1:
-                        loopFlag = 0
-                        break
+            for i in range(actRows):
+                if tdSql.getData(i, 1) == 1:
+                    loopFlag = 0
+                    break
             time.sleep(0.02)
         return
 
diff --git a/tests/system-test/7-tmq/tmqConsumerGroup.py b/tests/system-test/7-tmq/tmqConsumerGroup.py
index f05f600f27..ae9671bcf4 100644
--- a/tests/system-test/7-tmq/tmqConsumerGroup.py
+++ b/tests/system-test/7-tmq/tmqConsumerGroup.py
@@ -100,7 +100,7 @@ class TDTestCase:
 
         tdLog.info("wait consumer commit notify")
         # tmqCom.getStartCommitNotifyFromTmqsim(rows=4)
-        tmqCom.getStartConsumeNotifyFromTmqsim(rows=2)
+        tmqCom.getStartConsumeNotifyFromTmqsim()
 
         tdLog.info("pkill one consume processor")
         tmqCom.stopTmqSimProcess('tmq_sim_new')
diff --git a/tests/system-test/7-tmq/tmqDnodeRestart1.py b/tests/system-test/7-tmq/tmqDnodeRestart1.py
index cff55a1239..2bde32800b 100644
--- a/tests/system-test/7-tmq/tmqDnodeRestart1.py
+++ b/tests/system-test/7-tmq/tmqDnodeRestart1.py
@@ -121,7 +121,7 @@ class TDTestCase:
         tmqCom.startTmqSimProcess(pollDelay=paraDict['pollDelay'],dbName=paraDict["dbName"],showMsg=paraDict['showMsg'], showRow=paraDict['showRow'],snapshot=paraDict['snapshot'])
 
         # time.sleep(3)
-        tmqCom.getStartCommitNotifyFromTmqsim('cdb',1)
+        tmqCom.getStartCommitNotifyFromTmqsim()
 
         tdLog.info("create some new child table and insert data for latest mode")
         paraDict["batchNum"] = 100
@@ -205,7 +205,7 @@ class TDTestCase:
         tdLog.info("start consume processor")
         tmqCom.startTmqSimProcess(pollDelay=paraDict['pollDelay'],dbName=paraDict["dbName"],showMsg=paraDict['showMsg'], showRow=paraDict['showRow'],snapshot=paraDict['snapshot'])
 
-        tmqCom.getStartCommitNotifyFromTmqsim('cdb',1)
+        tmqCom.getStartCommitNotifyFromTmqsim()
 
         tdLog.info("create some new child table and insert data for latest mode")
         paraDict["batchNum"] = 10
diff --git a/tests/system-test/7-tmq/tmqDropStb.py b/tests/system-test/7-tmq/tmqDropStb.py
index a94747e574..0b252a7334 100644
--- a/tests/system-test/7-tmq/tmqDropStb.py
+++ b/tests/system-test/7-tmq/tmqDropStb.py
@@ -82,7 +82,7 @@ class TDTestCase:
 
         tdLog.info("create topics from db")
         topicName1 = 'UpperCasetopic_%s'%(self.paraDict['dbName'])
-        tdSql.execute("create topic %s as database %s" %(topicName1, self.paraDict['dbName']))
+        tdSql.execute("create topic `%s` as database %s" %(topicName1, self.paraDict['dbName']))
 
         topicList = topicName1 + ',' +topicName1
         keyList = '%s,%s,%s,%s'%(self.groupId,self.autoCommit,self.autoCommitInterval,self.autoOffset)
@@ -113,7 +113,7 @@ class TDTestCase:
             tdLog.exit("tmq consume rows error!")
 
         time.sleep(10)
-        tdSql.query("drop topic %s"%topicName1)
+        tdSql.query("drop topic `%s`"%topicName1)
 
         tdLog.printNoPrefix("======== test case 1 end ...... ")
 
diff --git a/tools/shell/src/shellEngine.c b/tools/shell/src/shellEngine.c
index 5ac32eaad9..0f91bdeeda 100644
--- a/tools/shell/src/shellEngine.c
+++ b/tools/shell/src/shellEngine.c
@@ -554,7 +554,12 @@ void shellPrintField(const char *val, TAOS_FIELD *field, int32_t width, int32_t
       if (tsEnableScience) {
         printf("%*e", width, GET_FLOAT_VAL(val));
       } else {
-        printf("%*.5f", width, GET_FLOAT_VAL(val));
+        n = snprintf(buf, TSDB_MAX_BYTES_PER_ROW, "%*.5f", width, GET_FLOAT_VAL(val));
+        if (n > TMAX(20, width)) {
+            printf("%*e", width, GET_FLOAT_VAL(val));
+        } else {
+            printf("%s", buf);
+        }
       }
       break;
     case TSDB_DATA_TYPE_DOUBLE:
diff --git a/utils/test/c/sml_test.c b/utils/test/c/sml_test.c
index 755ab55625..f1dc8ebe79 100644
--- a/utils/test/c/sml_test.c
+++ b/utils/test/c/sml_test.c
@@ -895,6 +895,63 @@ int smlProcess_18784_Test() {
   return code;
 }
 
+int sml_escape_Test() {
+  TAOS *taos = taos_connect("localhost", "root", "taosdata", NULL, 0);
+
+  TAOS_RES *pRes = taos_query(taos, "create database if not exists db_escape");
+  taos_free_result(pRes);
+
+  pRes = taos_query(taos, "use db_escape");
+  taos_free_result(pRes);
+
+  const char *sql[] = {
+      "d\\,i=\\ s\\k\",dev\"i\\,\\=\\ ce=s\"i\\,\\=\\ dc inode\"i\\,\\=\\ s_used=176059i,total=1076048383523889174i 1661943960000000000",
+      "d\\,i=\\ s\\k\",dev\"i\\,\\=\\ ce=s\"i\\,\\=\\ dc inode\"i\\,\\=\\ s_f\\\\ree=\"\\\"id,= ei\\\\\\f\" 1661943960000000000",
+  };
+  pRes = taos_schemaless_insert(taos, (char **)sql, sizeof(sql) / sizeof(sql[0]), TSDB_SML_LINE_PROTOCOL, 0);
+  printf("%s result:%s, rows:%d\n", __FUNCTION__, taos_errstr(pRes), taos_affected_rows(pRes));
+  int code = taos_errno(pRes);
+  ASSERT(!code);
+  ASSERT(taos_affected_rows(pRes) == 1);
+  taos_free_result(pRes);
+
+  pRes = taos_query(taos, "select * from `d,i= s\\k\"`");     //check stable name
+  ASSERT(pRes);
+  int fieldNum = taos_field_count(pRes);
+  ASSERT(fieldNum == 5);
+  printf("fieldNum:%d\n", fieldNum);
+
+  int         numFields = taos_num_fields(pRes);
+  TAOS_FIELD *fields = taos_fetch_fields(pRes);
+  ASSERT(numFields == 5);
+  ASSERT(strncmp(fields[1].name, "inode\"i,= s_used", sizeof("inode\"i,= s_used") - 1) == 0);
+  ASSERT(strncmp(fields[2].name, "total", sizeof("total") - 1) == 0);
+  ASSERT(strncmp(fields[3].name, "inode\"i,= s_f\\\\ree", sizeof("inode\"i,= s_f\\\\ree") - 1) == 0);
+  ASSERT(strncmp(fields[4].name, "dev\"i,= ce", sizeof("dev\"i,= ce") - 1) == 0);
+
+  TAOS_ROW row = NULL;
+  int32_t  rowIndex = 0;
+  while ((row = taos_fetch_row(pRes)) != NULL) {
+    int64_t ts = *(int64_t *)row[0];
+    int64_t used = *(int64_t *)row[1];
+    int64_t total = *(int64_t *)row[2];
+
+    if (rowIndex == 0) {
+      ASSERT(ts == 1661943960000);
+      ASSERT(used == 176059);
+      ASSERT(total == 1076048383523889174);
+      ASSERT(strncmp(row[3], "\"id,= ei\\\\f", sizeof("\"id,= ei\\\\f") - 1) == 0);
+      ASSERT(strncmp(row[4], "s\"i,= dc", sizeof("s\"i,= dc") - 1) == 0);
+
+    }
+    rowIndex++;
+  }
+  taos_free_result(pRes);
+  taos_close(taos);
+
+  return code;
+}
+
 int sml_19221_Test() {
   TAOS *taos = taos_connect("localhost", "root", "taosdata", NULL, 0);
 
@@ -961,6 +1018,55 @@ int sml_ts2164_Test() {
   return code;
 }
 
+
+int sml_ts3116_Test() {
+  TAOS *taos = taos_connect("localhost", "root", "taosdata", NULL, 0);
+
+  TAOS_RES *pRes =
+      taos_query(taos, "DROP DATABASE IF EXISTS ts3116");
+  taos_free_result(pRes);
+
+  pRes = taos_query(taos, "CREATE DATABASE IF NOT EXISTS ts3116  BUFFER 384  MINROWS 1000  PAGES 256 PRECISION 'ns'");
+  taos_free_result(pRes);
+
+  char *sql = {
+      "meters,location=la,groupid=ca current=11.8,voltage=221",
+  };
+
+  pRes = taos_query(taos, "use ts3116");
+  taos_free_result(pRes);
+  int32_t totalRows = 0;
+  char *tmp = (char *)taosMemoryCalloc(1024, 1);
+  memcpy(tmp, sql, strlen(sql));
+  totalRows = 0;
+  pRes = taos_schemaless_insert_raw(taos, tmp, strlen(tmp), &totalRows, TSDB_SML_LINE_PROTOCOL,
+                                    TSDB_SML_TIMESTAMP_MILLI_SECONDS);
+  taosMemoryFree(tmp);
+  printf("%s result:%s\n", __FUNCTION__, taos_errstr(pRes));
+  int code = taos_errno(pRes);
+  taos_free_result(pRes);
+
+  char *sql1 = {
+      "meters,location=la,groupid=ca\\=3 current=11.8,voltage=221\nmeters,location=la,groupid=ca current=11.8,voltage=221,phase=0.27",
+  };
+
+  pRes = taos_query(taos, "use ts3116");
+  taos_free_result(pRes);
+
+  tmp = (char *)taosMemoryCalloc(1024, 1);
+  memcpy(tmp, sql1, strlen(sql1));
+  totalRows = 0;
+  pRes = taos_schemaless_insert_raw(taos, tmp, strlen(tmp), &totalRows, TSDB_SML_LINE_PROTOCOL,
+                                TSDB_SML_TIMESTAMP_MILLI_SECONDS);
+  taosMemoryFree(tmp);
+  printf("%s result:%s\n", __FUNCTION__, taos_errstr(pRes));
+  code = taos_errno(pRes);
+  taos_free_result(pRes);
+  taos_close(taos);
+
+  return code;
+}
+
 int sml_td22898_Test() {
   TAOS *taos = taos_connect("localhost", "root", "taosdata", NULL, 0);
 
@@ -1026,6 +1132,84 @@ int sml_td22900_Test() {
   return code;
 }
 
+int sml_td23881_Test() {
+  TAOS *taos = taos_connect("localhost", "root", "taosdata", NULL, 0);
+
+  TAOS_RES *pRes =
+      taos_query(taos, "CREATE DATABASE IF NOT EXISTS line_23881 PRECISION 'ns'");
+  taos_free_result(pRes);
+
+  char tmp[16375] = {0};
+  memset(tmp, 'a', 16374);
+  char sql[102400] = {0};
+  sprintf(sql,"lujixfvqor,t0=t c0=f,c1=\"%s\",c2=\"%s\",c3=\"%s\",c4=\"wthvqxcsrlps\" 1626006833639000000", tmp, tmp, tmp);
+
+  pRes = taos_query(taos, "use line_23881");
+  taos_free_result(pRes);
+
+  int totalRows = 0;
+  pRes = taos_schemaless_insert_raw(taos, sql, strlen(sql), &totalRows, TSDB_SML_LINE_PROTOCOL,
+                                    TSDB_SML_TIMESTAMP_NANO_SECONDS);
+
+  printf("%s result:%s\n", __FUNCTION__, taos_errstr(pRes));
+  int code = taos_errno(pRes);
+  taos_free_result(pRes);
+  taos_close(taos);
+
+  return code;
+}
+
+int sml_ts3303_Test() {
+  TAOS *taos = taos_connect("localhost", "root", "taosdata", NULL, 0);
+
+  TAOS_RES *pRes = taos_query(taos, "drop database if exists ts3303");
+  taos_free_result(pRes);
+
+  pRes = taos_query(taos, "create database if not exists ts3303");
+  taos_free_result(pRes);
+
+  const char *sql[] = {
+      "stb2,t1=1,dataModelName=t0 f1=283i32 1632299372000",
+      "stb2,t1=1,dataModelName=t0 f1=106i32 1632299378000",
+      "stb2,t1=4,dataModelName=t0 f1=144i32 1629716944000",
+      "stb2,t1=4,dataModelName=t0 f1=125i32 1629717012000",
+      "stb2,t1=4,dataModelName=t0 f1=144i32 1629717012000",
+      "stb2,t1=4,dataModelName=t0 f1=107i32 1629717013000",
+      "stb2,t1=6,dataModelName=t0 f1=154i32 1629717140000",
+      "stb2,t1=6,dataModelName=t0 f1=93i32 1629717140000",
+      "stb2,t1=6,dataModelName=t0 f1=134i32 1629717140000",
+      "stb2,t1=4,dataModelName=t0 f1=73i32 1629717140000",
+      "stb2,t1=4,dataModelName=t0 f1=83i32 1629717140000",
+      "stb2,t1=4,dataModelName=t0 f1=72i32 1629717140000",
+  };
+
+  const char *sql1[] = {
+      "meters,location=California.LosAngeles,groupid=2 current=11.8,voltage=221,phase=\"2022-02-0210:22:22\" 1626006833339000000",
+      "meters,groupid=2,location=California.LosAngeles current=11.8,voltage=221,phase=\"2022-02-0210:22:22\" 1626006833339000000",
+  };
+
+  pRes = taos_query(taos, "use ts3303");
+  taos_free_result(pRes);
+
+  pRes = taos_schemaless_insert_ttl(taos, (char **)sql, sizeof(sql) / sizeof(sql[0]), TSDB_SML_LINE_PROTOCOL,
+                                    TSDB_SML_TIMESTAMP_MILLI_SECONDS, 20);
+
+  int code = taos_errno(pRes);
+  printf("%s result0:%s\n", __FUNCTION__, taos_errstr(pRes));
+  taos_free_result(pRes);
+  ASSERT(code == 0);
+
+  pRes = taos_schemaless_insert_ttl(taos, (char **)sql1, sizeof(sql1) / sizeof(sql1[0]), TSDB_SML_LINE_PROTOCOL,
+                                    TSDB_SML_TIMESTAMP_NANO_SECONDS, 20);
+
+  printf("%s result1:%s\n", __FUNCTION__, taos_errstr(pRes));
+  taos_free_result(pRes);
+
+  taos_close(taos);
+
+  return code;
+}
+
 int sml_ttl_Test() {
   TAOS *taos = taos_connect("localhost", "root", "taosdata", NULL, 0);
 
@@ -1195,8 +1379,17 @@ int main(int argc, char *argv[]) {
   }
 
   int ret = 0;
+  ret = sml_td23881_Test();
+  ASSERT(ret);
+  ret = sml_escape_Test();
+  ASSERT(!ret);
+  ret = sml_ts3116_Test();
+  ASSERT(!ret);
   ret = sml_ts2385_Test();    // this test case need config sml table name using ./sml_test config_file
   ASSERT(!ret);
+  ret = sml_ts3303_Test();    // this test case need config sml table name using ./sml_test config_file
+  ASSERT(!ret);
+
   //  for(int i = 0; i < sizeof(str)/sizeof(str[0]); i++){
   //    printf("str:%s \t %d\n", str[i], smlCalTypeSum(str[i], strlen(str[i])));
   //  }
diff --git a/utils/test/c/tmqSim.c b/utils/test/c/tmqSim.c
index f2de219f4e..d98a45f0d3 100644
--- a/utils/test/c/tmqSim.c
+++ b/utils/test/c/tmqSim.c
@@ -232,7 +232,7 @@ void saveConfigToLogFile() {
       taosFprintfFile(g_fp, "%s:%s, ", g_stConfInfo.stThreads[i].key[k], g_stConfInfo.stThreads[i].value[k]);
     }
     taosFprintfFile(g_fp, "\n");
-    taosFprintfFile(g_fp, "  expect rows: %" PRIx64 "\n", g_stConfInfo.stThreads[i].expectMsgCnt);
+    taosFprintfFile(g_fp, "  expect rows: %" PRId64 "\n", g_stConfInfo.stThreads[i].expectMsgCnt);
   }
 
   char tmpString[128];