feat:[TS-4897] virtual table (#30098)

* feat: [TS-4897] Support create/drop/alter/show/describe vtable

* feat: [TS-4897] Support vtable's query

* feat: [TS-4897] Support create virtual supertable

* feat: [TS-4897] Support explain analyze / where / count(*) and only select ts of vtable.

* feat: [TS-4897] Add create test and fix bugs

* feat: [TS-4897] Add alter/drop test and fix bugs

* feat: [TS-4897] Add describe/show test and fix bugs

* feat: [TS-4897] Add auth test and fix bugs

* feat: [TS-4897] Fix meta/catalog/cache bugs

* feat: [TS-4897] Support select tag from virtual child table

* feat: [TS-4897] Add select test and fix plenty of bugs

* feat: [TS-4897] Add optimize rule for vtable scan / support create vtable cross database / remove enterprise constraint / fix bugs.

* feat: [TS-4897] Fix 'schema is old'

* feat: [TS-4897] Support virtual stable query

* feat: [TS-4897] Add tests and Fix bugs

* feat: [TS-4897] resolve conflict.
This commit is contained in:
Jing Sima 2025-03-15 14:10:46 +08:00 committed by GitHub
parent 49f8f5ce0f
commit 410324746b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
198 changed files with 317511 additions and 783 deletions

View File

@ -373,7 +373,7 @@ This document details the server error codes that may be encountered when using
## parser ## parser
| Error Code | Description | Possible Error Scenarios or Reasons | Suggested Actions for Users | | Error Code | Description | Possible Error Scenarios or Reasons | Suggested Actions for Users |
| ---------- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | |------------| ------------------------------------------------------------ |----------------------------------------------------------------------------| ------------------------------------------------------------ |
| 0x80002600 | syntax error near | SQL syntax error | Check and correct the SQL statement | | 0x80002600 | syntax error near | SQL syntax error | Check and correct the SQL statement |
| 0x80002601 | Incomplete SQL statement | Incomplete SQL statement | Check and correct the SQL statement | | 0x80002601 | Incomplete SQL statement | Incomplete SQL statement | Check and correct the SQL statement |
| 0x80002602 | Invalid column name | Illegal or non-existent column name | Check and correct the SQL statement | | 0x80002602 | Invalid column name | Illegal or non-existent column name | Check and correct the SQL statement |
@ -466,10 +466,17 @@ This document details the server error codes that may be encountered when using
| 0x8000268A | Cols function's first param must be a select function that output a single row | The first parameter of the cols function should be a selection function | Check and correct the SQL statement | | 0x8000268A | Cols function's first param must be a select function that output a single row | The first parameter of the cols function should be a selection function | Check and correct the SQL statement |
| 0x8000268B | Invalid using alias for cols function | Illegal cols function alias | Check and correct the SQL statement | | 0x8000268B | Invalid using alias for cols function | Illegal cols function alias | Check and correct the SQL statement |
| 0x8000268C | Join primary key col must be timestmap type | Join primary key data type error | Check and correct the SQL statement | | 0x8000268C | Join primary key col must be timestmap type | Join primary key data type error | Check and correct the SQL statement |
| 0x8000268D | Invalid virtual table's ref column | Create/Update Virtual table using incorrect data source column | Check and correct the SQL statement |
| 0x8000268E | Invalid table type | Incorrect Table type | Check and correct the SQL statement |
| 0x8000268F | Invalid ref column type | Virtual table's column type and data source column's type are different | Check and correct the SQL statement |
| 0x80002690 | Create child table using virtual super table | Create non-virtual child table using virtual super table | Check and correct the SQL statement |
| 0x800026FF | Parser internal error | Internal error in parser | Preserve the scene and logs, report issue on GitHub | | 0x800026FF | Parser internal error | Internal error in parser | Preserve the scene and logs, report issue on GitHub |
| 0x80002700 | Planner internal error | Internal error in planner | Preserve the scene and logs, report issue on GitHub | | 0x80002700 | Planner internal error | Internal error in planner | Preserve the scene and logs, report issue on GitHub |
| 0x80002701 | Expect ts equal | JOIN condition validation failed | Preserve the scene and logs, report issue on GitHub | | 0x80002701 | Expect ts equal | JOIN condition validation failed | Preserve the scene and logs, report issue on GitHub |
| 0x80002702 | Cross join not support | CROSS JOIN not supported | Check and correct the SQL statement | | 0x80002702 | Cross join not support | CROSS JOIN not supported | Check and correct the SQL statement |
| 0x80002704 | Planner slot key not found | Planner cannot find slotId during making physic plan | Preserve the scene and logs, report issue on GitHub |
| 0x80002705 | Planner invalid table type | Planner get invalid table type | Preserve the scene and logs, report issue on GitHub |
| 0x80002706 | Planner invalid query control plan type | Planner get invalid query control plan type during making physic plan | Preserve the scene and logs, report issue on GitHub |
## function ## function
@ -547,3 +554,12 @@ This document details the server error codes that may be encountered when using
| 0x80004017 | Invalid status, please subscribe topic first | tmq status invalidate | Without calling subscribe, directly poll data | | 0x80004017 | Invalid status, please subscribe topic first | tmq status invalidate | Without calling subscribe, directly poll data |
| 0x80004100 | Stream task not exist | The stream computing task does not exist | Check the server-side error logs | | 0x80004100 | Stream task not exist | The stream computing task does not exist | Check the server-side error logs |
## virtual table
| Error Code | Description | Possible Error Scenarios or Reasons | Recommended Actions for Users |
|-------------|---------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------|
| 0x80006200 | Virtual table scan internal error | virtual table scan operator internal error, generally does not occur | Check error logs, contact development for handling |
| 0x80006201 | Virtual table scan invalid downstream operator type | The incorrect execution plan generated causes the downstream operator type of the virtual table scan operator to be incorrect. | Check error logs, contact development for handling |
| 0x80006202 | Virtual table prim timestamp column should not has ref | The timestamp primary key column of a virtual table should not have a data source. If it does, this error will occur during subsequent queries on the virtual table. | Check error logs, contact development for handling |
| 0x80006203 | Create virtual child table must use virtual super table | Create virtual child table using non-virtual super table | create virtual child table using virtual super table |

View File

@ -390,7 +390,7 @@ description: TDengine 服务端的错误码列表和详细说明
## parser ## parser
| 错误码 | 错误描述 | 可能的出错场景或者可能的原因 | 建议用户采取的措施 | | 错误码 | 错误描述 | 可能的出错场景或者可能的原因 | 建议用户采取的措施 |
| ---------- | ------------------------------------------------------------------------------------------------------ | --------------------------------------------- | ------------------------------------- | |------------| ------------------------------------------------------------------------------------------------------ |---------------------------------------------| ------------------------------------- |
| 0x80002600 | syntax error near | SQL 语法错误 | 检查并修正 SQL 语句 | | 0x80002600 | syntax error near | SQL 语法错误 | 检查并修正 SQL 语句 |
| 0x80002601 | Incomplete SQL statement | 不完整的 SQL 语句 | 检查并修正 SQL 语句 | | 0x80002601 | Incomplete SQL statement | 不完整的 SQL 语句 | 检查并修正 SQL 语句 |
| 0x80002602 | Invalid column name | 不合法或不存在的列名 | 检查并修正 SQL 语句 | | 0x80002602 | Invalid column name | 不合法或不存在的列名 | 检查并修正 SQL 语句 |
@ -483,11 +483,17 @@ description: TDengine 服务端的错误码列表和详细说明
| 0x8000268A | Cols function's first param must be a select function that output a single row | cols 函数第一个参数应该为选择函数 | 检查并修正 SQL 语句 | | 0x8000268A | Cols function's first param must be a select function that output a single row | cols 函数第一个参数应该为选择函数 | 检查并修正 SQL 语句 |
| 0x8000268B | Invalid using alias for cols function | cols 函数输出列重命名错误 | 检查并修正 SQL 语句 | | 0x8000268B | Invalid using alias for cols function | cols 函数输出列重命名错误 | 检查并修正 SQL 语句 |
| 0x8000268C | Join primary key col must be timestmap type | 关联查询主键列等值条件类型错误 | 检查并修正 SQL 语句 | | 0x8000268C | Join primary key col must be timestmap type | 关联查询主键列等值条件类型错误 | 检查并修正 SQL 语句 |
| 0x8000268D | Invalid virtual table's ref column | 创建/更新虚拟表时数据源列不正确 | 检查并修正SQL语句 |
| 0x8000268E | Invalid table type | 表类型不正确 | 检查并修正SQL语句 |
| 0x8000268F | Invalid ref column type | 虚拟表列的数据类型与数据源的数据类型不同 | 检查并修正SQL语句 |
| 0x80002690 | Create child table using virtual super table | 创建非虚拟子表 USING 了虚拟超级表 | 检查并修正SQL语句 |
| 0x800026FF | Parser internal error | 解析器内部错误 | 保留现场和日志github上报issue | | 0x800026FF | Parser internal error | 解析器内部错误 | 保留现场和日志github上报issue |
| 0x80002700 | Planner internal error | 计划期内部错误 | 保留现场和日志github上报issue | | 0x80002700 | Planner internal error | 计划期内部错误 | 保留现场和日志github上报issue |
| 0x80002701 | Expect ts equal | JOIN 条件校验失败 | 保留现场和日志github上报issue | | 0x80002701 | Expect ts equal | JOIN 条件校验失败 | 保留现场和日志github上报issue |
| 0x80002702 | Cross join not support | 不支持 CROSS JOIN | 检查并修正 SQL 语句 | | 0x80002702 | Cross join not support | 不支持 CROSS JOIN | 检查并修正 SQL 语句 |
| 0x80002704 | Planner slot key not found | 生成物理计划时查找不到 slotId | 保留现场和日志github上报issue |
| 0x80002705 | Planner invalid table type | 计划器生成计划时得到了错误的表类型 | 保留现场和日志github上报issue |
| 0x80002706 | Planner invalid query control plan type | 计划器生成 dynamic query control 计划时得到的类型不正确 | 保留现场和日志github上报issue |
## function ## function
@ -567,3 +573,13 @@ description: TDengine 服务端的错误码列表和详细说明
| 0x80004017 | Invalid status, please subscribe topic first | 数据订阅状态不对 | 没有调用 subscribe直接 poll 数据 | | 0x80004017 | Invalid status, please subscribe topic first | 数据订阅状态不对 | 没有调用 subscribe直接 poll 数据 |
| 0x80004100 | Stream task not exist | 流计算任务不存在 | 具体查看 server 端的错误日志 | | 0x80004100 | Stream task not exist | 流计算任务不存在 | 具体查看 server 端的错误日志 |
## virtual table
| 错误码 | 错误描述 | 可能的出错场景或者可能的原因 | 建议用户采取的措施 |
|------------|---------------------------------------------------------|------------------------------------------------|------------------------|
| 0x80006200 | Virtual table scan 算子内部错误 | virtual table scan 算子内部逻辑错误,一般不会出现 | 具体查看client端的错误日志提示 |
| 0x80006201 | Virtual table scan invalid downstream operator type | 由于生成的执行计划不对,导致 virtual table scan 算子的下游算子类型不正确 | 保留 explain 执行计划,联系开发处理 |
| 0x80006202 | Virtual table prim timestamp column should not has ref | 虚拟表的时间戳主键列不应该有数据源,如果有,后续查询虚拟表的时候就会出现该错误 | 检查错误日志,联系开发处理 |
| 0x80006203 | Create virtual child table must use virtual super table | 虚拟子表必须建在虚拟超级表下,否则就会出现该错误 | 创建虚拟子表的时候USING 虚拟超级表 |

View File

@ -39,7 +39,9 @@ typedef enum {
TSDB_SYSTEM_TABLE = 5, TSDB_SYSTEM_TABLE = 5,
TSDB_TSMA_TABLE = 6, // time-range-wise sma TSDB_TSMA_TABLE = 6, // time-range-wise sma
TSDB_VIEW_TABLE = 7, TSDB_VIEW_TABLE = 7,
TSDB_TABLE_MAX = 8 TSDB_VIRTUAL_NORMAL_TABLE = 8,
TSDB_VIRTUAL_CHILD_TABLE = 9,
TSDB_TABLE_MAX = 10
} ETableType; } ETableType;
typedef enum { typedef enum {

View File

@ -80,6 +80,7 @@ uint8_t columnEncodeVal(const char* encode);
uint16_t columnCompressVal(const char* compress); uint16_t columnCompressVal(const char* compress);
bool withExtSchema(uint8_t tableType); bool withExtSchema(uint8_t tableType);
bool hasRefCol(uint8_t tableType);
bool checkColumnEncode(char encode[TSDB_CL_COMPRESS_OPTION_LEN]); bool checkColumnEncode(char encode[TSDB_CL_COMPRESS_OPTION_LEN]);
bool checkColumnEncodeOrSetDefault(uint8_t type, char encode[TSDB_CL_COMPRESS_OPTION_LEN]); bool checkColumnEncodeOrSetDefault(uint8_t type, char encode[TSDB_CL_COMPRESS_OPTION_LEN]);
bool checkColumnCompress(char compress[TSDB_CL_COMPRESS_OPTION_LEN]); bool checkColumnCompress(char compress[TSDB_CL_COMPRESS_OPTION_LEN]);

View File

@ -267,6 +267,8 @@ int32_t createDataBlock(SSDataBlock** pResBlock);
void blockDataDestroy(SSDataBlock* pBlock); void blockDataDestroy(SSDataBlock* pBlock);
void blockDataFreeRes(SSDataBlock* pBlock); void blockDataFreeRes(SSDataBlock* pBlock);
int32_t createOneDataBlock(const SSDataBlock* pDataBlock, bool copyData, SSDataBlock** pResBlock); int32_t createOneDataBlock(const SSDataBlock* pDataBlock, bool copyData, SSDataBlock** pResBlock);
int32_t createOneDataBlockWithColArray(const SSDataBlock* pDataBlock, SArray* pColArray, SSDataBlock** pResBlock);
int32_t createOneDataBlockWithTwoBlock(const SSDataBlock* pDataBlock, const SSDataBlock* pOrgBlock, SSDataBlock** pResBlock);
int32_t createSpecialDataBlock(EStreamType type, SSDataBlock** pBlock); int32_t createSpecialDataBlock(EStreamType type, SSDataBlock** pBlock);
int32_t blockCopyOneRow(const SSDataBlock* pDataBlock, int32_t rowIdx, SSDataBlock** pResBlock); int32_t blockCopyOneRow(const SSDataBlock* pDataBlock, int32_t rowIdx, SSDataBlock** pResBlock);

View File

@ -182,6 +182,9 @@ typedef enum _mgmt_table {
#define TSDB_ALTER_TABLE_UPDATE_COLUMN_COMPRESS 13 #define TSDB_ALTER_TABLE_UPDATE_COLUMN_COMPRESS 13
#define TSDB_ALTER_TABLE_ADD_COLUMN_WITH_COMPRESS_OPTION 14 #define TSDB_ALTER_TABLE_ADD_COLUMN_WITH_COMPRESS_OPTION 14
#define TSDB_ALTER_TABLE_UPDATE_MULTI_TAG_VAL 15 #define TSDB_ALTER_TABLE_UPDATE_MULTI_TAG_VAL 15
#define TSDB_ALTER_TABLE_ALTER_COLUMN_REF 16
#define TSDB_ALTER_TABLE_REMOVE_COLUMN_REF 17
#define TSDB_ALTER_TABLE_ADD_COLUMN_WITH_COLUMN_REF 18
#define TSDB_FILL_NONE 0 #define TSDB_FILL_NONE 0
#define TSDB_FILL_NULL 1 #define TSDB_FILL_NULL 1
@ -225,6 +228,8 @@ typedef enum _mgmt_table {
#define TD_SUPER_TABLE TSDB_SUPER_TABLE #define TD_SUPER_TABLE TSDB_SUPER_TABLE
#define TD_CHILD_TABLE TSDB_CHILD_TABLE #define TD_CHILD_TABLE TSDB_CHILD_TABLE
#define TD_NORMAL_TABLE TSDB_NORMAL_TABLE #define TD_NORMAL_TABLE TSDB_NORMAL_TABLE
#define TD_VIRTUAL_NORMAL_TABLE TSDB_VIRTUAL_NORMAL_TABLE
#define TD_VIRTUAL_CHILD_TABLE TSDB_VIRTUAL_CHILD_TABLE
typedef enum ENodeType { typedef enum ENodeType {
// Syntax nodes are used in parser and planner module, and some are also used in executor module, such as COLUMN, // Syntax nodes are used in parser and planner module, and some are also used in executor module, such as COLUMN,
@ -270,6 +275,7 @@ typedef enum ENodeType {
QUERY_NODE_ANOMALY_WINDOW, QUERY_NODE_ANOMALY_WINDOW,
QUERY_NODE_RANGE_AROUND, QUERY_NODE_RANGE_AROUND,
QUERY_NODE_STREAM_NOTIFY_OPTIONS, QUERY_NODE_STREAM_NOTIFY_OPTIONS,
QUERY_NODE_VIRTUAL_TABLE,
// Statement nodes are used in parser and planner module. // Statement nodes are used in parser and planner module.
QUERY_NODE_SET_OPERATOR = 100, QUERY_NODE_SET_OPERATOR = 100,
@ -327,6 +333,13 @@ typedef enum ENodeType {
QUERY_NODE_REVOKE_STMT, QUERY_NODE_REVOKE_STMT,
QUERY_NODE_ALTER_CLUSTER_STMT, QUERY_NODE_ALTER_CLUSTER_STMT,
QUERY_NODE_S3MIGRATE_DATABASE_STMT, QUERY_NODE_S3MIGRATE_DATABASE_STMT,
QUERY_NODE_CREATE_TSMA_STMT,
QUERY_NODE_DROP_TSMA_STMT,
QUERY_NODE_CREATE_VIRTUAL_TABLE_STMT,
QUERY_NODE_CREATE_VIRTUAL_SUBTABLE_STMT,
QUERY_NODE_DROP_VIRTUAL_TABLE_STMT,
QUERY_NODE_ALTER_VIRTUAL_TABLE_STMT,
// placeholder for [154, 180] // placeholder for [154, 180]
QUERY_NODE_SHOW_CREATE_VIEW_STMT = 181, QUERY_NODE_SHOW_CREATE_VIEW_STMT = 181,
QUERY_NODE_SHOW_CREATE_DATABASE_STMT, QUERY_NODE_SHOW_CREATE_DATABASE_STMT,
@ -360,6 +373,8 @@ typedef enum ENodeType {
QUERY_NODE_DROP_ANODE_STMT, QUERY_NODE_DROP_ANODE_STMT,
QUERY_NODE_UPDATE_ANODE_STMT, QUERY_NODE_UPDATE_ANODE_STMT,
QUERY_NODE_ASSIGN_LEADER_STMT, QUERY_NODE_ASSIGN_LEADER_STMT,
QUERY_NODE_SHOW_CREATE_TSMA_STMT,
QUERY_NODE_SHOW_CREATE_VTABLE_STMT,
// show statement nodes // show statement nodes
// see 'sysTableShowAdapter', 'SYSTABLE_SHOW_TYPE_OFFSET' // see 'sysTableShowAdapter', 'SYSTABLE_SHOW_TYPE_OFFSET'
@ -404,11 +419,9 @@ typedef enum ENodeType {
QUERY_NODE_SHOW_ANODES_STMT, QUERY_NODE_SHOW_ANODES_STMT,
QUERY_NODE_SHOW_ANODES_FULL_STMT, QUERY_NODE_SHOW_ANODES_FULL_STMT,
QUERY_NODE_SHOW_USAGE_STMT, QUERY_NODE_SHOW_USAGE_STMT,
QUERY_NODE_CREATE_TSMA_STMT,
QUERY_NODE_SHOW_CREATE_TSMA_STMT,
QUERY_NODE_DROP_TSMA_STMT,
QUERY_NODE_SHOW_FILESETS_STMT, QUERY_NODE_SHOW_FILESETS_STMT,
QUERY_NODE_SHOW_TRANSACTION_DETAILS_STMT, QUERY_NODE_SHOW_TRANSACTION_DETAILS_STMT,
QUERY_NODE_SHOW_VTABLES_STMT,
// logic plan node // logic plan node
QUERY_NODE_LOGIC_PLAN_SCAN = 1000, QUERY_NODE_LOGIC_PLAN_SCAN = 1000,
@ -429,6 +442,7 @@ typedef enum ENodeType {
QUERY_NODE_LOGIC_PLAN_GROUP_CACHE, QUERY_NODE_LOGIC_PLAN_GROUP_CACHE,
QUERY_NODE_LOGIC_PLAN_DYN_QUERY_CTRL, QUERY_NODE_LOGIC_PLAN_DYN_QUERY_CTRL,
QUERY_NODE_LOGIC_PLAN_FORECAST_FUNC, QUERY_NODE_LOGIC_PLAN_FORECAST_FUNC,
QUERY_NODE_LOGIC_PLAN_VIRTUAL_TABLE_SCAN,
// physical plan node // physical plan node
QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN = 1100, QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN = 1100,
@ -493,6 +507,7 @@ typedef enum ENodeType {
QUERY_NODE_PHYSICAL_PLAN_STREAM_CONTINUE_STATE, QUERY_NODE_PHYSICAL_PLAN_STREAM_CONTINUE_STATE,
QUERY_NODE_PHYSICAL_PLAN_STREAM_CONTINUE_EVENT, QUERY_NODE_PHYSICAL_PLAN_STREAM_CONTINUE_EVENT,
QUERY_NODE_PHYSICAL_PLAN_STREAM_CONTINUE_COUNT, QUERY_NODE_PHYSICAL_PLAN_STREAM_CONTINUE_COUNT,
QUERY_NODE_PHYSICAL_PLAN_VIRTUAL_TABLE_SCAN,
} ENodeType; } ENodeType;
typedef struct { typedef struct {
@ -595,6 +610,20 @@ STSRow* tGetSubmitBlkNext(SSubmitBlkIter* pIter);
// for debug // for debug
int32_t tPrintFixedSchemaSubmitReq(SSubmitReq* pReq, STSchema* pSchema); int32_t tPrintFixedSchemaSubmitReq(SSubmitReq* pReq, STSchema* pSchema);
typedef struct {
bool hasRef;
col_id_t id;
char refDbName[TSDB_DB_NAME_LEN];
char refTableName[TSDB_TABLE_NAME_LEN];
char refColName[TSDB_COL_NAME_LEN];
} SColRef;
typedef struct {
int32_t nCols;
int32_t version;
SColRef* pColRef;
} SColRefWrapper;
struct SSchema { struct SSchema {
int8_t type; int8_t type;
int8_t flags; int8_t flags;
@ -636,6 +665,9 @@ typedef struct {
int8_t sysInfo; int8_t sysInfo;
SSchema* pSchemas; SSchema* pSchemas;
SSchemaExt* pSchemaExt; SSchemaExt* pSchemaExt;
int8_t virtualStb;
int32_t numOfColRefs;
SColRef* pColRefs;
} STableMetaRsp; } STableMetaRsp;
typedef struct { typedef struct {
@ -734,6 +766,23 @@ typedef struct {
SColCmpr* pColCmpr; SColCmpr* pColCmpr;
} SColCmprWrapper; } SColCmprWrapper;
static FORCE_INLINE int32_t tInitDefaultSColRefWrapperByCols(SColRefWrapper* pRef, int32_t nCols) {
if (pRef->pColRef) {
return TSDB_CODE_INVALID_PARA;
}
pRef->pColRef = (SColRef*)taosMemoryCalloc(nCols, sizeof(SColRef));
if (pRef->pColRef == NULL) {
return terrno;
}
pRef->nCols = nCols;
for (int32_t i = 0; i < nCols; i++) {
pRef->pColRef[i].hasRef = false;
pRef->pColRef[i].id = (col_id_t)(i + 1);
}
return 0;
}
static FORCE_INLINE SColCmprWrapper* tCloneSColCmprWrapper(const SColCmprWrapper* pSrcWrapper) { static FORCE_INLINE SColCmprWrapper* tCloneSColCmprWrapper(const SColCmprWrapper* pSrcWrapper) {
if (pSrcWrapper->pColCmpr == NULL || pSrcWrapper->nCols == 0) { if (pSrcWrapper->pColCmpr == NULL || pSrcWrapper->nCols == 0) {
terrno = TSDB_CODE_INVALID_PARA; terrno = TSDB_CODE_INVALID_PARA;
@ -878,6 +927,29 @@ static FORCE_INLINE int32_t tDecodeSSchemaExt(SDecoder* pDecoder, SSchemaExt* pS
return 0; return 0;
} }
static FORCE_INLINE int32_t tEncodeSColRef(SEncoder* pEncoder, const SColRef* pColRef) {
TAOS_CHECK_RETURN(tEncodeI8(pEncoder, pColRef->hasRef));
TAOS_CHECK_RETURN(tEncodeI16(pEncoder, pColRef->id));
if (pColRef->hasRef) {
TAOS_CHECK_RETURN(tEncodeCStr(pEncoder, pColRef->refDbName));
TAOS_CHECK_RETURN(tEncodeCStr(pEncoder, pColRef->refTableName));
TAOS_CHECK_RETURN(tEncodeCStr(pEncoder, pColRef->refColName));
}
return 0;
}
static FORCE_INLINE int32_t tDecodeSColRef(SDecoder* pDecoder, SColRef* pColRef) {
TAOS_CHECK_RETURN(tDecodeI8(pDecoder, (int8_t*)&pColRef->hasRef));
TAOS_CHECK_RETURN(tDecodeI16(pDecoder, &pColRef->id));
if (pColRef->hasRef) {
TAOS_CHECK_RETURN(tDecodeCStrTo(pDecoder, pColRef->refDbName));
TAOS_CHECK_RETURN(tDecodeCStrTo(pDecoder, pColRef->refTableName));
TAOS_CHECK_RETURN(tDecodeCStrTo(pDecoder, pColRef->refColName));
}
return 0;
}
static FORCE_INLINE int32_t taosEncodeSSchemaWrapper(void** buf, const SSchemaWrapper* pSW) { static FORCE_INLINE int32_t taosEncodeSSchemaWrapper(void** buf, const SSchemaWrapper* pSW) {
int32_t tlen = 0; int32_t tlen = 0;
tlen += taosEncodeVariantI32(buf, pSW->nCols); tlen += taosEncodeVariantI32(buf, pSW->nCols);
@ -977,6 +1049,7 @@ typedef struct {
int32_t sqlLen; int32_t sqlLen;
char* sql; char* sql;
int64_t keep; int64_t keep;
int8_t virtualStb;
} SMCreateStbReq; } SMCreateStbReq;
int32_t tSerializeSMCreateStbReq(void* buf, int32_t bufLen, SMCreateStbReq* pReq); int32_t tSerializeSMCreateStbReq(void* buf, int32_t bufLen, SMCreateStbReq* pReq);
@ -1335,6 +1408,8 @@ typedef struct {
int32_t tagsLen; int32_t tagsLen;
char* pTags; char* pTags;
SSchemaExt* pSchemaExt; SSchemaExt* pSchemaExt;
int8_t virtualStb;
SColRef* pColRefs;
} STableCfg; } STableCfg;
typedef STableCfg STableCfgRsp; typedef STableCfg STableCfgRsp;
@ -2843,13 +2918,37 @@ typedef struct SOperatorParam {
int32_t downstreamIdx; int32_t downstreamIdx;
void* value; void* value;
SArray* pChildren; // SArray<SOperatorParam*> SArray* pChildren; // SArray<SOperatorParam*>
bool reUse;
} SOperatorParam; } SOperatorParam;
typedef struct SColIdNameKV {
col_id_t colId;
char colName[TSDB_COL_NAME_LEN];
} SColIdNameKV;
typedef struct SColIdPair {
col_id_t vtbColId;
col_id_t orgColId;
} SColIdPair;
typedef struct SOrgTbInfo {
int32_t vgId;
char tbName[TSDB_TABLE_FNAME_LEN];
SArray* colMap; // SArray<SColIdNameKV>
} SOrgTbInfo;
typedef struct STableScanOperatorParam { typedef struct STableScanOperatorParam {
bool tableSeq; bool tableSeq;
SArray* pUidList; SArray* pUidList;
SOrgTbInfo* pOrgTbInfo;
STimeWindow window;
} STableScanOperatorParam; } STableScanOperatorParam;
typedef struct SVTableScanOperatorParam {
uint64_t uid;
SArray* pOpParamArray; // SArray<SOperatorParam>
} SVTableScanOperatorParam;
typedef struct { typedef struct {
SMsgHead header; SMsgHead header;
uint64_t sId; uint64_t sId;
@ -3279,6 +3378,7 @@ typedef struct SVCreateStbReq {
SColCmprWrapper colCmpr; SColCmprWrapper colCmpr;
int64_t keep; int64_t keep;
SExtSchema* pExtSchemas; SExtSchema* pExtSchemas;
int8_t virtualStb;
} SVCreateStbReq; } SVCreateStbReq;
int tEncodeSVCreateStbReq(SEncoder* pCoder, const SVCreateStbReq* pReq); int tEncodeSVCreateStbReq(SEncoder* pCoder, const SVCreateStbReq* pReq);
@ -3320,6 +3420,7 @@ typedef struct SVCreateTbReq {
char* sql; char* sql;
SColCmprWrapper colCmpr; SColCmprWrapper colCmpr;
SExtSchema* pExtSchemas; SExtSchema* pExtSchemas;
SColRefWrapper colRef; // col reference for virtual table
} SVCreateTbReq; } SVCreateTbReq;
int tEncodeSVCreateTbReq(SEncoder* pCoder, const SVCreateTbReq* pReq); int tEncodeSVCreateTbReq(SEncoder* pCoder, const SVCreateTbReq* pReq);
@ -3334,16 +3435,17 @@ static FORCE_INLINE void tdDestroySVCreateTbReq(SVCreateTbReq* req) {
taosMemoryFreeClear(req->sql); taosMemoryFreeClear(req->sql);
taosMemoryFreeClear(req->name); taosMemoryFreeClear(req->name);
taosMemoryFreeClear(req->comment); taosMemoryFreeClear(req->comment);
if (req->type == TSDB_CHILD_TABLE) { if (req->type == TSDB_CHILD_TABLE || req->type == TSDB_VIRTUAL_CHILD_TABLE) {
taosMemoryFreeClear(req->ctb.pTag); taosMemoryFreeClear(req->ctb.pTag);
taosMemoryFreeClear(req->ctb.stbName); taosMemoryFreeClear(req->ctb.stbName);
taosArrayDestroy(req->ctb.tagName); taosArrayDestroy(req->ctb.tagName);
req->ctb.tagName = NULL; req->ctb.tagName = NULL;
} else if (req->type == TSDB_NORMAL_TABLE) { } else if (req->type == TSDB_NORMAL_TABLE || req->type == TSDB_VIRTUAL_NORMAL_TABLE) {
taosMemoryFreeClear(req->ntb.schemaRow.pSchema); taosMemoryFreeClear(req->ntb.schemaRow.pSchema);
} }
taosMemoryFreeClear(req->colCmpr.pColCmpr); taosMemoryFreeClear(req->colCmpr.pColCmpr);
taosMemoryFreeClear(req->pExtSchemas); taosMemoryFreeClear(req->pExtSchemas);
taosMemoryFreeClear(req->colRef.pColRef);
} }
typedef struct { typedef struct {
@ -3391,6 +3493,7 @@ typedef struct {
uint64_t suid; // for tmq in wal format uint64_t suid; // for tmq in wal format
int64_t uid; int64_t uid;
int8_t igNotExists; int8_t igNotExists;
int8_t isVirtual;
} SVDropTbReq; } SVDropTbReq;
typedef struct { typedef struct {
@ -3430,7 +3533,7 @@ typedef struct SMultiTagUpateVal {
int8_t isNull; int8_t isNull;
SArray* pTagArray; SArray* pTagArray;
} SMultiTagUpateVal; } SMultiTagUpateVal;
typedef struct { typedef struct SVAlterTbReq{
char* tbName; char* tbName;
int8_t action; int8_t action;
char* colName; char* colName;
@ -3462,6 +3565,11 @@ typedef struct {
SArray* pMultiTag; // TSDB_ALTER_TABLE_ADD_MULTI_TAGS SArray* pMultiTag; // TSDB_ALTER_TABLE_ADD_MULTI_TAGS
// for Add column // for Add column
STypeMod typeMod; STypeMod typeMod;
// TSDB_ALTER_TABLE_ALTER_COLUMN_REF
char* refDbName;
char* refTbName;
char* refColName;
// TSDB_ALTER_TABLE_REMOVE_COLUMN_REF
} SVAlterTbReq; } SVAlterTbReq;
int32_t tEncodeSVAlterTbReq(SEncoder* pEncoder, const SVAlterTbReq* pReq); int32_t tEncodeSVAlterTbReq(SEncoder* pEncoder, const SVAlterTbReq* pReq);

View File

@ -132,6 +132,7 @@
TD_DEF_MSG_TYPE(TDMT_MND_RETRIEVE_ANAL_ALGO, "retrieve-anal-algo", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_MND_RETRIEVE_ANAL_ALGO, "retrieve-anal-algo", NULL, NULL)
TD_DEF_MSG_TYPE(TDMT_MND_FAILED_STREAM, "create-stream-failed", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_MND_FAILED_STREAM, "create-stream-failed", NULL, NULL)
TD_DEF_MSG_TYPE(TDMT_MND_CHECK_STREAM_TIMER, "check-stream-status", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_MND_CHECK_STREAM_TIMER, "check-stream-status", NULL, NULL)
TD_DEF_MSG_TYPE(TDMT_MND_GET_DB_INFO, "get-db-info", NULL, NULL)
TD_CLOSE_MSG_SEG(TDMT_DND_MSG) TD_CLOSE_MSG_SEG(TDMT_DND_MSG)
TD_NEW_MSG_SEG(TDMT_MND_MSG) // 1<<8 TD_NEW_MSG_SEG(TDMT_MND_MSG) // 1<<8
@ -265,6 +266,7 @@
TD_DEF_MSG_TYPE(TDMT_MND_CONFIG, "init-config", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_MND_CONFIG, "init-config", NULL, NULL)
TD_DEF_MSG_TYPE(TDMT_MND_CONFIG_SDB, "config-sdb", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_MND_CONFIG_SDB, "config-sdb", NULL, NULL)
TD_DEF_MSG_TYPE(TDMT_MND_RESET_STREAM, "reset-stream", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_MND_RESET_STREAM, "reset-stream", NULL, NULL)
// do not add new message type here, since mnode msg overload. you can add new message type after dnode msg
TD_CLOSE_MSG_SEG(TDMT_END_MND_MSG) TD_CLOSE_MSG_SEG(TDMT_END_MND_MSG)
TD_NEW_MSG_SEG(TDMT_VND_MSG) // 2<<8 TD_NEW_MSG_SEG(TDMT_VND_MSG) // 2<<8

View File

@ -30,6 +30,7 @@ extern "C" {
#define DS_BUF_EMPTY 3 #define DS_BUF_EMPTY 3
#define DS_FLAG_USE_MEMPOOL (1 << 0) #define DS_FLAG_USE_MEMPOOL (1 << 0)
#define DS_FLAG_PROCESS_ONE_BLOCK (1 << 1)
struct SSDataBlock; struct SSDataBlock;
@ -87,7 +88,7 @@ typedef struct SOutputData {
* @param pHandle output * @param pHandle output
* @return error code * @return error code
*/ */
int32_t dsCreateDataSinker(void* pSinkManager, SDataSinkNode** ppDataSink, DataSinkHandle* pHandle, void* pParam, const char* id); int32_t dsCreateDataSinker(void* pSinkManager, SDataSinkNode** ppDataSink, DataSinkHandle* pHandle, void* pParam, const char* id, bool processOneBlock);
int32_t dsDataSinkGetCacheSize(SDataSinkStat* pStat); int32_t dsDataSinkGetCacheSize(SDataSinkStat* pStat);

View File

@ -168,7 +168,7 @@ int32_t qGetQueryTableSchemaVersion(qTaskInfo_t tinfo, char* dbName, int32_t dbN
* @param handle * @param handle
* @return * @return
*/ */
int32_t qExecTaskOpt(qTaskInfo_t tinfo, SArray* pResList, uint64_t* useconds, bool* hasMore, SLocalFetch* pLocal); int32_t qExecTaskOpt(qTaskInfo_t tinfo, SArray* pResList, uint64_t* useconds, bool* hasMore, SLocalFetch* pLocal, bool processOneBlock);
int32_t qExecTask(qTaskInfo_t tinfo, SSDataBlock** pBlock, uint64_t* useconds); int32_t qExecTask(qTaskInfo_t tinfo, SSDataBlock** pBlock, uint64_t* useconds);

View File

@ -85,6 +85,7 @@ typedef struct SMetaEntry {
SColCmprWrapper colCmpr; // col compress alg SColCmprWrapper colCmpr; // col compress alg
SExtSchema* pExtSchemas; SExtSchema* pExtSchemas;
SColRefWrapper colRef; // col reference for virtual table
} SMetaEntry; } SMetaEntry;
typedef struct SMetaReader { typedef struct SMetaReader {

View File

@ -279,6 +279,7 @@ bool fmIsForbidSysTableFunc(int32_t funcId);
bool fmIsIntervalInterpoFunc(int32_t funcId); bool fmIsIntervalInterpoFunc(int32_t funcId);
bool fmIsInterpFunc(int32_t funcId); bool fmIsInterpFunc(int32_t funcId);
bool fmIsLastRowFunc(int32_t funcId); bool fmIsLastRowFunc(int32_t funcId);
bool fmIsLastFunc(int32_t funcId);
bool fmIsForecastFunc(int32_t funcId); bool fmIsForecastFunc(int32_t funcId);
bool fmIsNotNullOutputFunc(int32_t funcId); bool fmIsNotNullOutputFunc(int32_t funcId);
bool fmIsSelectValueFunc(int32_t funcId); bool fmIsSelectValueFunc(int32_t funcId);

View File

@ -25,10 +25,12 @@ extern "C" {
#define DESCRIBE_RESULT_COLS 4 #define DESCRIBE_RESULT_COLS 4
#define DESCRIBE_RESULT_COLS_COMPRESS 7 #define DESCRIBE_RESULT_COLS_COMPRESS 7
#define DESCRIBE_RESULT_COLS_REF 5
#define DESCRIBE_RESULT_FIELD_LEN (TSDB_COL_NAME_LEN - 1 + VARSTR_HEADER_SIZE) #define DESCRIBE_RESULT_FIELD_LEN (TSDB_COL_NAME_LEN - 1 + VARSTR_HEADER_SIZE)
#define DESCRIBE_RESULT_TYPE_LEN (20 + VARSTR_HEADER_SIZE) #define DESCRIBE_RESULT_TYPE_LEN (20 + VARSTR_HEADER_SIZE)
#define DESCRIBE_RESULT_NOTE_LEN (16 + VARSTR_HEADER_SIZE) #define DESCRIBE_RESULT_NOTE_LEN (16 + VARSTR_HEADER_SIZE)
#define DESCRIBE_RESULT_COPRESS_OPTION_LEN (TSDB_CL_COMPRESS_OPTION_LEN + VARSTR_HEADER_SIZE) #define DESCRIBE_RESULT_COPRESS_OPTION_LEN (TSDB_CL_COMPRESS_OPTION_LEN + VARSTR_HEADER_SIZE)
#define DESCRIBE_RESULT_COL_REF_LEN (TSDB_COL_FNAME_LEN + VARSTR_HEADER_SIZE)
#define SHOW_CREATE_DB_RESULT_COLS 2 #define SHOW_CREATE_DB_RESULT_COLS 2
#define SHOW_CREATE_DB_RESULT_FIELD1_LEN (TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE) #define SHOW_CREATE_DB_RESULT_FIELD1_LEN (TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE)
@ -184,6 +186,7 @@ typedef struct SCompactVgroupsStmt {
typedef struct STableOptions { typedef struct STableOptions {
ENodeType type; ENodeType type;
bool virtualStb;
bool commentNull; bool commentNull;
char comment[TSDB_TB_COMMENT_LEN]; char comment[TSDB_TB_COMMENT_LEN];
SNodeList* pMaxDelay; SNodeList* pMaxDelay;
@ -210,7 +213,12 @@ typedef struct SColumnOptions {
char compress[TSDB_CL_COMPRESS_OPTION_LEN]; char compress[TSDB_CL_COMPRESS_OPTION_LEN];
char compressLevel[TSDB_CL_COMPRESS_OPTION_LEN]; char compressLevel[TSDB_CL_COMPRESS_OPTION_LEN];
bool bPrimaryKey; bool bPrimaryKey;
bool hasRef;
char refDb[TSDB_DB_NAME_LEN];
char refTable[TSDB_TABLE_NAME_LEN];
char refColumn[TSDB_COL_NAME_LEN];
} SColumnOptions; } SColumnOptions;
typedef struct SColumnDefNode { typedef struct SColumnDefNode {
ENodeType type; ENodeType type;
char colName[TSDB_COL_NAME_LEN]; char colName[TSDB_COL_NAME_LEN];
@ -229,6 +237,27 @@ typedef struct SCreateTableStmt {
STableOptions* pOptions; STableOptions* pOptions;
} SCreateTableStmt; } SCreateTableStmt;
typedef struct SCreateVTableStmt {
ENodeType type;
char dbName[TSDB_DB_NAME_LEN];
char tableName[TSDB_TABLE_NAME_LEN];
bool ignoreExists;
SNodeList* pCols;
} SCreateVTableStmt;
typedef struct SCreateVSubTableStmt {
ENodeType type;
char dbName[TSDB_DB_NAME_LEN];
char tableName[TSDB_TABLE_NAME_LEN];
char useDbName[TSDB_DB_NAME_LEN];
char useTableName[TSDB_TABLE_NAME_LEN];
bool ignoreExists;
SNodeList* pSpecificTags;
SNodeList* pValsOfTags;
SNodeList* pSpecificColRefs;
SNodeList* pColRefs;
} SCreateVSubTableStmt;
typedef struct SCreateSubTableClause { typedef struct SCreateSubTableClause {
ENodeType type; ENodeType type;
char dbName[TSDB_DB_NAME_LEN]; char dbName[TSDB_DB_NAME_LEN];
@ -278,6 +307,14 @@ typedef struct SDropSuperTableStmt {
bool withOpt; bool withOpt;
} SDropSuperTableStmt; } SDropSuperTableStmt;
typedef struct SDropVirtualTableStmt {
ENodeType type;
char dbName[TSDB_DB_NAME_LEN];
char tableName[TSDB_TABLE_NAME_LEN];
bool ignoreNotExists;
bool withOpt;
} SDropVirtualTableStmt;
typedef struct SAlterTableStmt { typedef struct SAlterTableStmt {
ENodeType type; ENodeType type;
char dbName[TSDB_DB_NAME_LEN]; char dbName[TSDB_DB_NAME_LEN];
@ -290,6 +327,9 @@ typedef struct SAlterTableStmt {
SValueNode* pVal; SValueNode* pVal;
SColumnOptions* pColOptions; SColumnOptions* pColOptions;
SNodeList* pNodeListTagValue; SNodeList* pNodeListTagValue;
char refDbName[TSDB_DB_NAME_LEN];
char refTableName[TSDB_TABLE_NAME_LEN];
char refColName[TSDB_COL_NAME_LEN];
} SAlterTableStmt; } SAlterTableStmt;
typedef struct SAlterTableMultiStmt { typedef struct SAlterTableMultiStmt {

View File

@ -129,6 +129,7 @@ typedef struct SScanLogicNode {
bool smallDataTsSort; // disable row id sort for table merge scan bool smallDataTsSort; // disable row id sort for table merge scan
bool needSplit; bool needSplit;
bool noPseudoRefAfterGrp; // no pseudo columns referenced ater group/partition clause bool noPseudoRefAfterGrp; // no pseudo columns referenced ater group/partition clause
bool virtualStableScan;
} SScanLogicNode; } SScanLogicNode;
typedef struct SJoinLogicNode { typedef struct SJoinLogicNode {
@ -170,6 +171,19 @@ typedef struct SJoinLogicNode {
SNode* pRightOnCond; // table onCond filter SNode* pRightOnCond; // table onCond filter
} SJoinLogicNode; } SJoinLogicNode;
typedef struct SVirtualScanLogicNode {
SLogicNode node;
bool scanAllCols;
SNodeList* pScanCols;
SNodeList* pScanPseudoCols;
int8_t tableType;
uint64_t tableId;
uint64_t stableId;
SVgroupsInfo* pVgroupList;
EScanType scanType;
SName tableName;
} SVirtualScanLogicNode;
typedef struct SAggLogicNode { typedef struct SAggLogicNode {
SLogicNode node; SLogicNode node;
SNodeList* pGroupKeys; SNodeList* pGroupKeys;
@ -247,10 +261,17 @@ typedef struct SDynQueryCtrlStbJoin {
bool srcScan[2]; bool srcScan[2];
} SDynQueryCtrlStbJoin; } SDynQueryCtrlStbJoin;
typedef struct SDynQueryCtrlVtbScan {
bool scanAllCols;
uint64_t suid;
SVgroupsInfo* pVgroupList;
} SDynQueryCtrlVtbScan;
typedef struct SDynQueryCtrlLogicNode { typedef struct SDynQueryCtrlLogicNode {
SLogicNode node; SLogicNode node;
EDynQueryType qType; EDynQueryType qType;
SDynQueryCtrlStbJoin stbJoin; SDynQueryCtrlStbJoin stbJoin;
SDynQueryCtrlVtbScan vtbScan;
} SDynQueryCtrlLogicNode; } SDynQueryCtrlLogicNode;
typedef enum EModifyTableType { MODIFY_TABLE_TYPE_INSERT = 1, MODIFY_TABLE_TYPE_DELETE } EModifyTableType; typedef enum EModifyTableType { MODIFY_TABLE_TYPE_INSERT = 1, MODIFY_TABLE_TYPE_DELETE } EModifyTableType;
@ -413,6 +434,7 @@ typedef struct SLogicSubplan {
int32_t level; int32_t level;
int32_t splitFlag; int32_t splitFlag;
int32_t numOfComputeNodes; int32_t numOfComputeNodes;
bool processOneBlock;
} SLogicSubplan; } SLogicSubplan;
typedef struct SQueryLogicPlan { typedef struct SQueryLogicPlan {
@ -462,6 +484,7 @@ typedef struct SScanPhysiNode {
int8_t tableType; int8_t tableType;
SName tableName; SName tableName;
bool groupOrderScan; bool groupOrderScan;
bool virtualStableScan;
} SScanPhysiNode; } SScanPhysiNode;
typedef struct STagScanPhysiNode { typedef struct STagScanPhysiNode {
@ -471,6 +494,14 @@ typedef struct STagScanPhysiNode {
typedef SScanPhysiNode SBlockDistScanPhysiNode; typedef SScanPhysiNode SBlockDistScanPhysiNode;
typedef struct SVirtualScanPhysiNode {
SScanPhysiNode scan;
SNodeList* pGroupTags;
bool groupSort;
bool scanAllCols;
SNodeList* pTargets;
}SVirtualScanPhysiNode;
typedef struct SLastRowScanPhysiNode { typedef struct SLastRowScanPhysiNode {
SScanPhysiNode scan; SScanPhysiNode scan;
SNodeList* pGroupTags; SNodeList* pGroupTags;
@ -629,11 +660,20 @@ typedef struct SStbJoinDynCtrlBasic {
bool srcScan[2]; bool srcScan[2];
} SStbJoinDynCtrlBasic; } SStbJoinDynCtrlBasic;
typedef struct SVtbScanDynCtrlBasic {
bool scanAllCols;
uint64_t suid;
int32_t accountId;
SEpSet mgmtEpSet;
SNodeList *pScanCols;
} SVtbScanDynCtrlBasic;
typedef struct SDynQueryCtrlPhysiNode { typedef struct SDynQueryCtrlPhysiNode {
SPhysiNode node; SPhysiNode node;
EDynQueryType qType; EDynQueryType qType;
union { union {
SStbJoinDynCtrlBasic stbJoin; SStbJoinDynCtrlBasic stbJoin;
SVtbScanDynCtrlBasic vtbScan;
}; };
} SDynQueryCtrlPhysiNode; } SDynQueryCtrlPhysiNode;
@ -861,6 +901,7 @@ typedef struct SSubplan {
bool isAudit; bool isAudit;
bool dynamicRowThreshold; bool dynamicRowThreshold;
int32_t rowsThreshold; int32_t rowsThreshold;
bool processOneBlock;
} SSubplan; } SSubplan;
typedef enum EExplainMode { EXPLAIN_MODE_DISABLE = 1, EXPLAIN_MODE_STATIC, EXPLAIN_MODE_ANALYZE } EExplainMode; typedef enum EExplainMode { EXPLAIN_MODE_DISABLE = 1, EXPLAIN_MODE_STATIC, EXPLAIN_MODE_ANALYZE } EExplainMode;

View File

@ -94,12 +94,19 @@ typedef struct SColumnNode {
bool isPk; bool isPk;
int32_t projRefIdx; int32_t projRefIdx;
int32_t resIdx; int32_t resIdx;
bool hasDep;
bool hasRef;
char refDbName[TSDB_DB_NAME_LEN];
char refTableName[TSDB_TABLE_NAME_LEN];
char refColName[TSDB_COL_NAME_LEN];
} SColumnNode; } SColumnNode;
typedef struct SColumnRefNode { typedef struct SColumnRefNode {
ENodeType type; ENodeType type;
SDataType resType;
char colName[TSDB_COL_NAME_LEN]; char colName[TSDB_COL_NAME_LEN];
char refDbName[TSDB_DB_NAME_LEN];
char refTableName[TSDB_TABLE_NAME_LEN];
char refColName[TSDB_COL_NAME_LEN];
} SColumnRefNode; } SColumnRefNode;
typedef struct STargetNode { typedef struct STargetNode {
@ -238,6 +245,13 @@ typedef struct STempTableNode {
SNode* pSubquery; SNode* pSubquery;
} STempTableNode; } STempTableNode;
typedef struct SVirtualTableNode {
STableNode table; // QUERY_NODE_VIRTUAL_TABLE
struct STableMeta* pMeta;
SVgroupsInfo* pVgroupList;
SNodeList* refTables;
} SVirtualTableNode;
typedef struct SViewNode { typedef struct SViewNode {
STableNode table; // QUERY_NODE_REAL_TABLE STableNode table; // QUERY_NODE_REAL_TABLE
struct STableMeta* pMeta; struct STableMeta* pMeta;
@ -281,6 +295,7 @@ typedef enum EJoinAlgorithm {
typedef enum EDynQueryType { typedef enum EDynQueryType {
DYN_QTYPE_STB_HASH = 1, DYN_QTYPE_STB_HASH = 1,
DYN_QTYPE_VTB_SCAN,
} EDynQueryType; } EDynQueryType;
typedef struct SJoinTableNode { typedef struct SJoinTableNode {
@ -395,6 +410,7 @@ typedef enum EShowKind {
SHOW_KIND_ALL = 1, SHOW_KIND_ALL = 1,
SHOW_KIND_TABLES_NORMAL, SHOW_KIND_TABLES_NORMAL,
SHOW_KIND_TABLES_CHILD, SHOW_KIND_TABLES_CHILD,
SHOW_KIND_TABLES_VIRTUAL,
SHOW_KIND_DATABASES_USER, SHOW_KIND_DATABASES_USER,
SHOW_KIND_DATABASES_SYSTEM SHOW_KIND_DATABASES_SYSTEM
} EShowKind; } EShowKind;

View File

@ -24,6 +24,31 @@ extern "C" {
#include "query.h" #include "query.h"
#include "querynodes.h" #include "querynodes.h"
#define PAR_ERR_RET(c) \
do { \
int32_t _code = c; \
if (_code != TSDB_CODE_SUCCESS) { \
terrno = _code; \
return _code; \
} \
} while (0)
#define PAR_RET(c) \
do { \
int32_t _code = c; \
if (_code != TSDB_CODE_SUCCESS) { \
terrno = _code; \
} \
return _code; \
} while (0)
#define PAR_ERR_JRET(c) \
do { \
code = c; \
if (code != TSDB_CODE_SUCCESS) { \
terrno = code; \
goto _return; \
} \
} while (0)
typedef struct SStmtCallback { typedef struct SStmtCallback {
TAOS_STMT* pStmt; TAOS_STMT* pStmt;
int32_t (*getTbNameFn)(TAOS_STMT*, char**); int32_t (*getTbNameFn)(TAOS_STMT*, char**);

View File

@ -53,6 +53,7 @@ typedef struct SPlanContext {
char pWendName[TSDB_COL_NAME_LEN]; char pWendName[TSDB_COL_NAME_LEN];
char pGroupIdName[TSDB_COL_NAME_LEN]; char pGroupIdName[TSDB_COL_NAME_LEN];
char pIsWindowFilledName[TSDB_COL_NAME_LEN]; char pIsWindowFilledName[TSDB_COL_NAME_LEN];
bool virtualStableQuery;
} SPlanContext; } SPlanContext;
// Create the physical plan for the query, according to the AST. // Create the physical plan for the query, according to the AST.

View File

@ -105,8 +105,20 @@ typedef struct SCTableMeta {
} SCTableMeta; } SCTableMeta;
#pragma pack(pop) #pragma pack(pop)
#pragma pack(push, 1)
typedef struct SVCTableMeta {
uint64_t uid;
uint64_t suid;
int32_t vgId;
int8_t tableType;
int32_t numOfColRefs;
SColRef* colRef;
} SVCTableMeta;
#pragma pack(pop)
#pragma pack(push, 1) #pragma pack(push, 1)
typedef struct STableMeta { typedef struct STableMeta {
// BEGIN: KEEP THIS PART SAME WITH SVCTableMeta
// BEGIN: KEEP THIS PART SAME WITH SCTableMeta // BEGIN: KEEP THIS PART SAME WITH SCTableMeta
uint64_t uid; uint64_t uid;
uint64_t suid; uint64_t suid;
@ -114,6 +126,10 @@ typedef struct STableMeta {
int8_t tableType; int8_t tableType;
// END: KEEP THIS PART SAME WITH SCTableMeta // END: KEEP THIS PART SAME WITH SCTableMeta
int32_t numOfColRefs;
SColRef* colRef;
// END: KEEP THIS PART SAME WITH SVCTableMeta
// if the table is TSDB_CHILD_TABLE, the following information is acquired from the corresponding super table meta // if the table is TSDB_CHILD_TABLE, the following information is acquired from the corresponding super table meta
// info // info
int32_t sversion; int32_t sversion;
@ -121,6 +137,7 @@ typedef struct STableMeta {
STableComInfo tableInfo; STableComInfo tableInfo;
SSchemaExt* schemaExt; // There is no additional memory allocation, and the pointer is fixed to the next address of SSchemaExt* schemaExt; // There is no additional memory allocation, and the pointer is fixed to the next address of
// the schema content. // the schema content.
int8_t virtualStb;
SSchema schema[]; SSchema schema[];
} STableMeta; } STableMeta;
#pragma pack(pop) #pragma pack(pop)
@ -153,7 +170,12 @@ typedef struct SUseDbOutput {
SDBVgInfo* dbVgroup; SDBVgInfo* dbVgroup;
} SUseDbOutput; } SUseDbOutput;
enum { META_TYPE_NULL_TABLE = 1, META_TYPE_CTABLE, META_TYPE_TABLE, META_TYPE_BOTH_TABLE }; enum { META_TYPE_NULL_TABLE = 1,
META_TYPE_CTABLE,
META_TYPE_VCTABLE,
META_TYPE_TABLE,
META_TYPE_BOTH_TABLE,
META_TYPE_BOTH_VTABLE};
typedef struct STableMetaOutput { typedef struct STableMetaOutput {
int32_t metaType; int32_t metaType;
@ -162,6 +184,7 @@ typedef struct STableMetaOutput {
char ctbName[TSDB_TABLE_NAME_LEN]; char ctbName[TSDB_TABLE_NAME_LEN];
char tbName[TSDB_TABLE_NAME_LEN]; char tbName[TSDB_TABLE_NAME_LEN];
SCTableMeta ctbMeta; SCTableMeta ctbMeta;
SVCTableMeta* vctbMeta;
STableMeta* tbMeta; STableMeta* tbMeta;
} STableMetaOutput; } STableMetaOutput;
@ -331,6 +354,7 @@ bool tIsValidSchema(struct SSchema* pSchema, int32_t numOfCols, int32_
int32_t getAsofJoinReverseOp(EOperatorType op); int32_t getAsofJoinReverseOp(EOperatorType op);
int32_t queryCreateCTableMetaFromMsg(STableMetaRsp* msg, SCTableMeta* pMeta); int32_t queryCreateCTableMetaFromMsg(STableMetaRsp* msg, SCTableMeta* pMeta);
int32_t queryCreateVCTableMetaFromMsg(STableMetaRsp *msg, SVCTableMeta **pMeta);
int32_t queryCreateTableMetaFromMsg(STableMetaRsp* msg, bool isSuperTable, STableMeta** pMeta); int32_t queryCreateTableMetaFromMsg(STableMetaRsp* msg, bool isSuperTable, STableMeta** pMeta);
int32_t queryCreateTableMetaExFromMsg(STableMetaRsp* msg, bool isSuperTable, STableMeta** pMeta); int32_t queryCreateTableMetaExFromMsg(STableMetaRsp* msg, bool isSuperTable, STableMeta** pMeta);
char* jobTaskStatusStr(int32_t status); char* jobTaskStatusStr(int32_t status);
@ -340,6 +364,7 @@ SSchema createSchema(int8_t type, int32_t bytes, col_id_t colId, const char* nam
void destroyQueryExecRes(SExecResult* pRes); void destroyQueryExecRes(SExecResult* pRes);
int32_t dataConverToStr(char* str, int64_t capacity, int type, void* buf, int32_t bufSize, int32_t* len); int32_t dataConverToStr(char* str, int64_t capacity, int type, void* buf, int32_t bufSize, int32_t* len);
void parseTagDatatoJson(void* p, char** jsonStr, void *charsetCxt); void parseTagDatatoJson(void* p, char** jsonStr, void *charsetCxt);
int32_t setColRef(SColRef* colRef, col_id_t colId, char* refColName, char* refTableName, char* refDbName);
int32_t cloneTableMeta(STableMeta* pSrc, STableMeta** pDst); int32_t cloneTableMeta(STableMeta* pSrc, STableMeta** pDst);
void getColumnTypeFromMeta(STableMeta* pMeta, char* pName, ETableColumnType* pType); void getColumnTypeFromMeta(STableMeta* pMeta, char* pName, ETableColumnType* pType);
int32_t cloneDbVgInfo(SDBVgInfo* pSrc, SDBVgInfo** pDst); int32_t cloneDbVgInfo(SDBVgInfo* pSrc, SDBVgInfo** pDst);
@ -355,8 +380,10 @@ void* getTaskPoolWorkerCb();
#define SET_META_TYPE_NULL(t) (t) = META_TYPE_NULL_TABLE #define SET_META_TYPE_NULL(t) (t) = META_TYPE_NULL_TABLE
#define SET_META_TYPE_CTABLE(t) (t) = META_TYPE_CTABLE #define SET_META_TYPE_CTABLE(t) (t) = META_TYPE_CTABLE
#define SET_META_TYPE_VCTABLE(t) (t) = META_TYPE_VCTABLE
#define SET_META_TYPE_TABLE(t) (t) = META_TYPE_TABLE #define SET_META_TYPE_TABLE(t) (t) = META_TYPE_TABLE
#define SET_META_TYPE_BOTH_TABLE(t) (t) = META_TYPE_BOTH_TABLE #define SET_META_TYPE_BOTH_TABLE(t) (t) = META_TYPE_BOTH_TABLE
#define SET_META_TYPE_BOTH_VTABLE(t) (t) = META_TYPE_BOTH_VTABLE
#define NEED_CLIENT_RM_TBLMETA_ERROR(_code) \ #define NEED_CLIENT_RM_TBLMETA_ERROR(_code) \
((_code) == TSDB_CODE_PAR_TABLE_NOT_EXIST || (_code) == TSDB_CODE_TDB_TABLE_NOT_EXIST || \ ((_code) == TSDB_CODE_PAR_TABLE_NOT_EXIST || (_code) == TSDB_CODE_TDB_TABLE_NOT_EXIST || \

View File

@ -922,6 +922,10 @@ int32_t taosGetErrSize();
#define TSDB_CODE_PAR_INVALID_COLS_SELECTFUNC TAOS_DEF_ERROR_CODE(0, 0x268A) #define TSDB_CODE_PAR_INVALID_COLS_SELECTFUNC TAOS_DEF_ERROR_CODE(0, 0x268A)
#define TSDB_CODE_PAR_INVALID_COLS_ALIAS TAOS_DEF_ERROR_CODE(0, 0x268B) #define TSDB_CODE_PAR_INVALID_COLS_ALIAS TAOS_DEF_ERROR_CODE(0, 0x268B)
#define TSDB_CODE_PAR_PRIM_KEY_MUST_BE_TS TAOS_DEF_ERROR_CODE(0, 0x268C) #define TSDB_CODE_PAR_PRIM_KEY_MUST_BE_TS TAOS_DEF_ERROR_CODE(0, 0x268C)
#define TSDB_CODE_PAR_INVALID_REF_COLUMN TAOS_DEF_ERROR_CODE(0, 0x268D)
#define TSDB_CODE_PAR_INVALID_TABLE_TYPE TAOS_DEF_ERROR_CODE(0, 0x268E)
#define TSDB_CODE_PAR_INVALID_REF_COLUMN_TYPE TAOS_DEF_ERROR_CODE(0, 0x268F)
#define TSDB_CODE_PAR_MISMATCH_STABLE_TYPE TAOS_DEF_ERROR_CODE(0, 0x2690)
#define TSDB_CODE_PAR_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x26FF) #define TSDB_CODE_PAR_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x26FF)
//planner //planner
@ -929,6 +933,9 @@ int32_t taosGetErrSize();
#define TSDB_CODE_PLAN_EXPECTED_TS_EQUAL TAOS_DEF_ERROR_CODE(0, 0x2701) #define TSDB_CODE_PLAN_EXPECTED_TS_EQUAL TAOS_DEF_ERROR_CODE(0, 0x2701)
#define TSDB_CODE_PLAN_NOT_SUPPORT_CROSS_JOIN TAOS_DEF_ERROR_CODE(0, 0x2702) #define TSDB_CODE_PLAN_NOT_SUPPORT_CROSS_JOIN TAOS_DEF_ERROR_CODE(0, 0x2702)
#define TSDB_CODE_PLAN_NOT_SUPPORT_JOIN_COND TAOS_DEF_ERROR_CODE(0, 0x2703) #define TSDB_CODE_PLAN_NOT_SUPPORT_JOIN_COND TAOS_DEF_ERROR_CODE(0, 0x2703)
#define TSDB_CODE_PLAN_SLOT_NOT_FOUND TAOS_DEF_ERROR_CODE(0, 0x2704)
#define TSDB_CODE_PLAN_INVALID_TABLE_TYPE TAOS_DEF_ERROR_CODE(0, 0x2705)
#define TSDB_CODE_PLAN_INVALID_DYN_CTRL_TYPE TAOS_DEF_ERROR_CODE(0, 0x2706)
//function //function
#define TSDB_CODE_FUNC_FUNTION_ERROR TAOS_DEF_ERROR_CODE(0, 0x2800) #define TSDB_CODE_FUNC_FUNTION_ERROR TAOS_DEF_ERROR_CODE(0, 0x2800)
@ -1056,6 +1063,11 @@ int32_t taosGetErrSize();
#define TSDB_CODE_AUDIT_FAIL_SEND_AUDIT_RECORD TAOS_DEF_ERROR_CODE(0, 0x6101) #define TSDB_CODE_AUDIT_FAIL_SEND_AUDIT_RECORD TAOS_DEF_ERROR_CODE(0, 0x6101)
#define TSDB_CODE_AUDIT_FAIL_GENERATE_JSON TAOS_DEF_ERROR_CODE(0, 0x6102) #define TSDB_CODE_AUDIT_FAIL_GENERATE_JSON TAOS_DEF_ERROR_CODE(0, 0x6102)
// VTABLE
#define TSDB_CODE_VTABLE_SCAN_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x6200)
#define TSDB_CODE_VTABLE_SCAN_INVALID_DOWNSTREAM TAOS_DEF_ERROR_CODE(0, 0x6201)
#define TSDB_CODE_VTABLE_PRIMTS_HAS_REF TAOS_DEF_ERROR_CODE(0, 0x6202)
#define TSDB_CODE_VTABLE_NOT_VIRTUAL_SUPER_TABLE TAOS_DEF_ERROR_CODE(0, 0x6203)
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -285,6 +285,7 @@ typedef enum ELogicConditionType {
#define TSDB_COL_NAME_LEN 65 #define TSDB_COL_NAME_LEN 65
#define TSDB_COL_NAME_EXLEN 8 #define TSDB_COL_NAME_EXLEN 8
#define TSDB_COL_FNAME_LEN (TSDB_TABLE_NAME_LEN + TSDB_COL_NAME_LEN + TSDB_NAME_DELIMITER_LEN) #define TSDB_COL_FNAME_LEN (TSDB_TABLE_NAME_LEN + TSDB_COL_NAME_LEN + TSDB_NAME_DELIMITER_LEN)
#define TSDB_COL_FNAME_EX_LEN (TSDB_DB_NAME_LEN + TSDB_NAME_DELIMITER_LEN + TSDB_TABLE_NAME_LEN + TSDB_NAME_DELIMITER_LEN + TSDB_COL_NAME_LEN)
#define TSDB_MAX_SAVED_SQL_LEN TSDB_MAX_COLUMNS * 64 #define TSDB_MAX_SAVED_SQL_LEN TSDB_MAX_COLUMNS * 64
#define TSDB_MAX_SQL_LEN TSDB_PAYLOAD_SIZE #define TSDB_MAX_SQL_LEN TSDB_PAYLOAD_SIZE
#define TSDB_MAX_SQL_SHOW_LEN 1024 #define TSDB_MAX_SQL_SHOW_LEN 1024

View File

@ -704,6 +704,8 @@ int32_t tSerializeSMCreateStbReq(void *buf, int32_t bufLen, SMCreateStbReq *pReq
ENCODESQL(); ENCODESQL();
TAOS_CHECK_EXIT(tEncodeI8(&encoder, pReq->virtualStb));
tEndEncode(&encoder); tEndEncode(&encoder);
_exit: _exit:
@ -818,6 +820,12 @@ int32_t tDeserializeSMCreateStbReq(void *buf, int32_t bufLen, SMCreateStbReq *pR
DECODESQL(); DECODESQL();
if (!tDecodeIsEnd(&decoder)) {
TAOS_CHECK_EXIT(tDecodeI8(&decoder, &pReq->virtualStb));
} else {
pReq->virtualStb = 0;
}
tEndDecode(&decoder); tEndDecode(&decoder);
_exit: _exit:
@ -3954,6 +3962,14 @@ int32_t tSerializeSTableCfgRsp(void *buf, int32_t bufLen, STableCfgRsp *pRsp) {
} }
} }
TAOS_CHECK_EXIT(tEncodeI8(&encoder, pRsp->virtualStb));
if (hasRefCol(pRsp->tableType)) {
for (int32_t i = 0; i < pRsp->numOfColumns; ++i) {
SColRef *pColRef = &pRsp->pColRefs[i];
TAOS_CHECK_EXIT(tEncodeSColRef(&encoder, pColRef));
}
}
tEndEncode(&encoder); tEndEncode(&encoder);
_exit: _exit:
@ -4037,6 +4053,23 @@ int32_t tDeserializeSTableCfgRsp(void *buf, int32_t bufLen, STableCfgRsp *pRsp)
pRsp->pSchemaExt = NULL; pRsp->pSchemaExt = NULL;
} }
} }
if (!tDecodeIsEnd(&decoder)) {
TAOS_CHECK_EXIT(tDecodeI8(&decoder, &pRsp->virtualStb));
if (hasRefCol(pRsp->tableType) && pRsp->numOfColumns > 0) {
pRsp->pColRefs = taosMemoryMalloc(sizeof(SColRef) * pRsp->numOfColumns);
if (pRsp->pColRefs == NULL) {
TAOS_CHECK_EXIT(terrno);
}
for (int32_t i = 0; i < pRsp->numOfColumns; ++i) {
SColRef *pColRef = &pRsp->pColRefs[i];
TAOS_CHECK_EXIT(tDecodeSColRef(&decoder, pColRef));
}
} else {
pRsp->pColRefs = NULL;
}
}
tEndDecode(&decoder); tEndDecode(&decoder);
_exit: _exit:
@ -4052,6 +4085,7 @@ void tFreeSTableCfgRsp(STableCfgRsp *pRsp) {
taosMemoryFreeClear(pRsp->pComment); taosMemoryFreeClear(pRsp->pComment);
taosMemoryFreeClear(pRsp->pSchemas); taosMemoryFreeClear(pRsp->pSchemas);
taosMemoryFreeClear(pRsp->pSchemaExt); taosMemoryFreeClear(pRsp->pSchemaExt);
taosMemoryFreeClear(pRsp->pColRefs);
taosMemoryFreeClear(pRsp->pTags); taosMemoryFreeClear(pRsp->pTags);
taosArrayDestroy(pRsp->pFuncs); taosArrayDestroy(pRsp->pFuncs);
@ -6125,6 +6159,15 @@ static int32_t tEncodeSTableMetaRsp(SEncoder *pEncoder, STableMetaRsp *pRsp) {
} }
} }
TAOS_CHECK_RETURN(tEncodeI8(pEncoder, pRsp->virtualStb));
TAOS_CHECK_RETURN(tEncodeI32(pEncoder, pRsp->numOfColRefs));
if (hasRefCol(pRsp->tableType)) {
for (int32_t i = 0; i < pRsp->numOfColRefs; ++i) {
SColRef *pColRef = &pRsp->pColRefs[i];
TAOS_CHECK_RETURN(tEncodeSColRef(pEncoder, pColRef));
}
}
return 0; return 0;
} }
@ -6173,6 +6216,23 @@ static int32_t tDecodeSTableMetaRsp(SDecoder *pDecoder, STableMetaRsp *pRsp) {
pRsp->pSchemaExt = NULL; pRsp->pSchemaExt = NULL;
} }
} }
if (!tDecodeIsEnd(pDecoder)) {
TAOS_CHECK_RETURN(tDecodeI8(pDecoder, &pRsp->virtualStb));
TAOS_CHECK_RETURN(tDecodeI32(pDecoder, &pRsp->numOfColRefs));
if (hasRefCol(pRsp->tableType) && pRsp->numOfColRefs > 0) {
pRsp->pColRefs = taosMemoryMalloc(sizeof(SColRef) * pRsp->numOfColRefs);
if (pRsp->pColRefs == NULL) {
TAOS_CHECK_RETURN(terrno);
}
for (int32_t i = 0; i < pRsp->numOfColRefs; ++i) {
SColRef *pColRef = &pRsp->pColRefs[i];
TAOS_CHECK_RETURN(tDecodeSColRef(pDecoder, pColRef));
}
} else {
pRsp->pColRefs = NULL;
}
}
return 0; return 0;
} }
@ -6282,6 +6342,7 @@ int32_t tDeserializeSSTbHbRsp(void *buf, int32_t bufLen, SSTbHbRsp *pRsp) {
if (taosArrayPush(pRsp->pMetaRsp, &tableMetaRsp) == NULL) { if (taosArrayPush(pRsp->pMetaRsp, &tableMetaRsp) == NULL) {
taosMemoryFree(tableMetaRsp.pSchemas); taosMemoryFree(tableMetaRsp.pSchemas);
taosMemoryFree(tableMetaRsp.pSchemaExt); taosMemoryFree(tableMetaRsp.pSchemaExt);
taosMemoryFree(tableMetaRsp.pColRefs);
TAOS_CHECK_EXIT(terrno); TAOS_CHECK_EXIT(terrno);
} }
} }
@ -6337,6 +6398,7 @@ void tFreeSTableMetaRsp(void *pRsp) {
taosMemoryFreeClear(((STableMetaRsp *)pRsp)->pSchemas); taosMemoryFreeClear(((STableMetaRsp *)pRsp)->pSchemas);
taosMemoryFreeClear(((STableMetaRsp *)pRsp)->pSchemaExt); taosMemoryFreeClear(((STableMetaRsp *)pRsp)->pSchemaExt);
taosMemoryFreeClear(((STableMetaRsp *)pRsp)->pColRefs);
} }
void tFreeSTableIndexRsp(void *info) { void tFreeSTableIndexRsp(void *info) {
@ -8463,9 +8525,9 @@ int32_t tSerializeSMArbUpdateGroupBatchReq(void *buf, int32_t bufLen, SMArbUpdat
SMArbUpdateGroup *pGroup = taosArrayGet(pReq->updateArray, i); SMArbUpdateGroup *pGroup = taosArrayGet(pReq->updateArray, i);
TAOS_CHECK_EXIT(tEncodeI32(&encoder, pGroup->vgId)); TAOS_CHECK_EXIT(tEncodeI32(&encoder, pGroup->vgId));
TAOS_CHECK_EXIT(tEncodeI64(&encoder, pGroup->dbUid)); TAOS_CHECK_EXIT(tEncodeI64(&encoder, pGroup->dbUid));
for (int i = 0; i < TSDB_ARB_GROUP_MEMBER_NUM; i++) { for (int j = 0; j < TSDB_ARB_GROUP_MEMBER_NUM; j++) {
TAOS_CHECK_EXIT(tEncodeI32(&encoder, pGroup->members[i].dnodeId)); TAOS_CHECK_EXIT(tEncodeI32(&encoder, pGroup->members[j].dnodeId));
TAOS_CHECK_EXIT(tEncodeCStr(&encoder, pGroup->members[i].token)); TAOS_CHECK_EXIT(tEncodeCStr(&encoder, pGroup->members[j].token));
} }
TAOS_CHECK_EXIT(tEncodeI8(&encoder, pGroup->isSync)); TAOS_CHECK_EXIT(tEncodeI8(&encoder, pGroup->isSync));
TAOS_CHECK_EXIT(tEncodeI32(&encoder, pGroup->assignedLeader.dnodeId)); TAOS_CHECK_EXIT(tEncodeI32(&encoder, pGroup->assignedLeader.dnodeId));
@ -8515,12 +8577,12 @@ int32_t tDeserializeSMArbUpdateGroupBatchReq(void *buf, int32_t bufLen, SMArbUpd
SMArbUpdateGroup group = {0}; SMArbUpdateGroup group = {0};
TAOS_CHECK_EXIT(tDecodeI32(&decoder, &group.vgId)); TAOS_CHECK_EXIT(tDecodeI32(&decoder, &group.vgId));
TAOS_CHECK_EXIT(tDecodeI64(&decoder, &group.dbUid)); TAOS_CHECK_EXIT(tDecodeI64(&decoder, &group.dbUid));
for (int i = 0; i < TSDB_ARB_GROUP_MEMBER_NUM; i++) { for (int j = 0; j < TSDB_ARB_GROUP_MEMBER_NUM; j++) {
TAOS_CHECK_EXIT(tDecodeI32(&decoder, &group.members[i].dnodeId)); TAOS_CHECK_EXIT(tDecodeI32(&decoder, &group.members[j].dnodeId));
if ((group.members[i].token = taosMemoryMalloc(TSDB_ARB_TOKEN_SIZE)) == NULL) { if ((group.members[j].token = taosMemoryMalloc(TSDB_ARB_TOKEN_SIZE)) == NULL) {
TAOS_CHECK_EXIT(terrno); TAOS_CHECK_EXIT(terrno);
} }
TAOS_CHECK_EXIT(tDecodeCStrTo(&decoder, group.members[i].token)); TAOS_CHECK_EXIT(tDecodeCStrTo(&decoder, group.members[j].token));
} }
TAOS_CHECK_EXIT(tDecodeI8(&decoder, &group.isSync)); TAOS_CHECK_EXIT(tDecodeI8(&decoder, &group.isSync));
TAOS_CHECK_EXIT(tDecodeI32(&decoder, &group.assignedLeader.dnodeId)); TAOS_CHECK_EXIT(tDecodeI32(&decoder, &group.assignedLeader.dnodeId));
@ -8568,8 +8630,8 @@ void tFreeSMArbUpdateGroupBatchReq(SMArbUpdateGroupBatchReq *pReq) {
int32_t sz = taosArrayGetSize(pReq->updateArray); int32_t sz = taosArrayGetSize(pReq->updateArray);
for (int32_t i = 0; i < sz; i++) { for (int32_t i = 0; i < sz; i++) {
SMArbUpdateGroup *pGroup = taosArrayGet(pReq->updateArray, i); SMArbUpdateGroup *pGroup = taosArrayGet(pReq->updateArray, i);
for (int i = 0; i < TSDB_ARB_GROUP_MEMBER_NUM; i++) { for (int j = 0; j < TSDB_ARB_GROUP_MEMBER_NUM; j++) {
taosMemoryFreeClear(pGroup->members[i].token); taosMemoryFreeClear(pGroup->members[j].token);
} }
taosMemoryFreeClear(pGroup->assignedLeader.token); taosMemoryFreeClear(pGroup->assignedLeader.token);
} }
@ -9209,6 +9271,22 @@ int32_t tSerializeSOperatorParam(SEncoder *pEncoder, SOperatorParam *pOpParam) {
int64_t *pUid = taosArrayGet(pScan->pUidList, m); int64_t *pUid = taosArrayGet(pScan->pUidList, m);
TAOS_CHECK_RETURN(tEncodeI64(pEncoder, *pUid)); TAOS_CHECK_RETURN(tEncodeI64(pEncoder, *pUid));
} }
if (pScan->pOrgTbInfo) {
TAOS_CHECK_RETURN(tEncodeBool(pEncoder, true));
TAOS_CHECK_RETURN(tEncodeI32(pEncoder, pScan->pOrgTbInfo->vgId));
TAOS_CHECK_RETURN(tEncodeCStr(pEncoder, pScan->pOrgTbInfo->tbName));
int32_t num = taosArrayGetSize(pScan->pOrgTbInfo->colMap);
TAOS_CHECK_RETURN(tEncodeI32(pEncoder, num));
for (int32_t i = 0; i < num; ++i) {
SColIdNameKV *pColKV = taosArrayGet(pScan->pOrgTbInfo->colMap, i);
TAOS_CHECK_RETURN(tEncodeI16(pEncoder, pColKV->colId));
TAOS_CHECK_RETURN(tEncodeCStr(pEncoder, pColKV->colName));
}
} else {
TAOS_CHECK_RETURN(tEncodeBool(pEncoder, false));
}
TAOS_CHECK_RETURN(tEncodeI64(pEncoder, pScan->window.skey));
TAOS_CHECK_RETURN(tEncodeI64(pEncoder, pScan->window.ekey));
break; break;
} }
default: default:
@ -9222,6 +9300,7 @@ int32_t tSerializeSOperatorParam(SEncoder *pEncoder, SOperatorParam *pOpParam) {
TAOS_CHECK_RETURN(tSerializeSOperatorParam(pEncoder, pChild)); TAOS_CHECK_RETURN(tSerializeSOperatorParam(pEncoder, pChild));
} }
TAOS_CHECK_RETURN(tEncodeBool(pEncoder, pOpParam->reUse));
return 0; return 0;
} }
@ -9253,6 +9332,33 @@ int32_t tDeserializeSOperatorParam(SDecoder *pDecoder, SOperatorParam *pOpParam)
} else { } else {
pScan->pUidList = NULL; pScan->pUidList = NULL;
} }
bool hasTbInfo = false;
TAOS_CHECK_RETURN(tDecodeBool(pDecoder, &hasTbInfo));
if (hasTbInfo) {
pScan->pOrgTbInfo = taosMemoryMalloc(sizeof(SOrgTbInfo));
if (NULL == pScan->pOrgTbInfo) {
TAOS_CHECK_RETURN(terrno);
}
TAOS_CHECK_RETURN(tDecodeI32(pDecoder, &pScan->pOrgTbInfo->vgId));
TAOS_CHECK_RETURN(tDecodeCStrTo(pDecoder, pScan->pOrgTbInfo->tbName));
int32_t num = 0;
TAOS_CHECK_RETURN(tDecodeI32(pDecoder, &num));
pScan->pOrgTbInfo->colMap = taosArrayInit(num, sizeof(SColIdNameKV));
for (int32_t i = 0; i < num; ++i) {
SColIdNameKV pColKV;
TAOS_CHECK_RETURN(tDecodeI16(pDecoder, (int16_t *)&(pColKV.colId)));
TAOS_CHECK_RETURN(tDecodeCStrTo(pDecoder, pColKV.colName));
if (taosArrayPush(pScan->pOrgTbInfo->colMap, &pColKV) == NULL) {
TAOS_CHECK_RETURN(terrno);
}
}
} else {
pScan->pOrgTbInfo = NULL;
}
TAOS_CHECK_RETURN(tDecodeI64(pDecoder, &pScan->window.skey));
TAOS_CHECK_RETURN(tDecodeI64(pDecoder, &pScan->window.ekey));
pOpParam->value = pScan; pOpParam->value = pScan;
break; break;
} }
@ -9282,6 +9388,12 @@ int32_t tDeserializeSOperatorParam(SDecoder *pDecoder, SOperatorParam *pOpParam)
pOpParam->pChildren = NULL; pOpParam->pChildren = NULL;
} }
if (!tDecodeIsEnd(pDecoder)) {
TAOS_CHECK_RETURN(tDecodeBool(pDecoder, &pOpParam->reUse));
} else {
pOpParam->reUse = false;
}
return 0; return 0;
} }
@ -10449,6 +10561,57 @@ _exit:
return code; return code;
} }
int32_t tEncodeSColRefWrapper(SEncoder *pCoder, const SColRefWrapper *pWrapper) {
int32_t code = 0;
int32_t lino;
TAOS_CHECK_EXIT(tEncodeI32v(pCoder, pWrapper->nCols));
TAOS_CHECK_EXIT(tEncodeI32v(pCoder, pWrapper->version));
for (int32_t i = 0; i < pWrapper->nCols; i++) {
SColRef *p = &pWrapper->pColRef[i];
TAOS_CHECK_EXIT(tEncodeI8(pCoder, p->hasRef));
TAOS_CHECK_EXIT(tEncodeI16v(pCoder, p->id));
if (p->hasRef) {
TAOS_CHECK_EXIT(tEncodeCStr(pCoder, p->refDbName));
TAOS_CHECK_EXIT(tEncodeCStr(pCoder, p->refTableName));
TAOS_CHECK_EXIT(tEncodeCStr(pCoder, p->refColName));
}
}
_exit:
return code;
}
int32_t tDecodeSColRefWrapperEx(SDecoder *pDecoder, SColRefWrapper *pWrapper) {
int32_t code = 0;
int32_t lino;
TAOS_CHECK_EXIT(tDecodeI32v(pDecoder, &pWrapper->nCols));
TAOS_CHECK_EXIT(tDecodeI32v(pDecoder, &pWrapper->version));
pWrapper->pColRef = (SColRef *)tDecoderMalloc(pDecoder, pWrapper->nCols * sizeof(SColRef));
if (pWrapper->pColRef == NULL) {
TAOS_CHECK_EXIT(terrno);
}
for (int i = 0; i < pWrapper->nCols; i++) {
SColRef *p = &pWrapper->pColRef[i];
TAOS_CHECK_EXIT(tDecodeI8(pDecoder, (int8_t *)&p->hasRef));
TAOS_CHECK_EXIT(tDecodeI16v(pDecoder, &p->id));
if (p->hasRef) {
TAOS_CHECK_EXIT(tDecodeCStrTo(pDecoder, p->refDbName));
TAOS_CHECK_EXIT(tDecodeCStrTo(pDecoder, p->refTableName));
TAOS_CHECK_EXIT(tDecodeCStrTo(pDecoder, p->refColName));
}
}
_exit:
if (code) {
taosMemoryFree(pWrapper->pColRef);
}
return code;
}
int32_t tEncodeSColCmprWrapper(SEncoder *pCoder, const SColCmprWrapper *pWrapper) { int32_t tEncodeSColCmprWrapper(SEncoder *pCoder, const SColCmprWrapper *pWrapper) {
int32_t code = 0; int32_t code = 0;
int32_t lino; int32_t lino;
@ -10558,6 +10721,7 @@ int tEncodeSVCreateStbReq(SEncoder *pCoder, const SVCreateStbReq *pReq) {
} else { } else {
TAOS_CHECK_EXIT(tEncodeI8(pCoder, 0)); TAOS_CHECK_EXIT(tEncodeI8(pCoder, 0));
} }
TAOS_CHECK_EXIT(tEncodeI8(pCoder, pReq->virtualStb));
tEndEncode(pCoder); tEndEncode(pCoder);
_exit: _exit:
@ -10603,6 +10767,9 @@ int tDecodeSVCreateStbReq(SDecoder *pCoder, SVCreateStbReq *pReq) {
} }
} }
} }
if (!tDecodeIsEnd(pCoder)) {
TAOS_CHECK_EXIT(tDecodeI8(pCoder, &pReq->virtualStb));
}
tEndDecode(pCoder); tEndDecode(pCoder);
_exit: _exit:
@ -10626,7 +10793,7 @@ int tEncodeSVCreateTbReq(SEncoder *pCoder, const SVCreateTbReq *pReq) {
TAOS_CHECK_EXIT(tEncodeCStr(pCoder, pReq->comment)); TAOS_CHECK_EXIT(tEncodeCStr(pCoder, pReq->comment));
} }
if (pReq->type == TSDB_CHILD_TABLE) { if (pReq->type == TSDB_CHILD_TABLE || pReq->type == TSDB_VIRTUAL_CHILD_TABLE) {
TAOS_CHECK_EXIT(tEncodeCStr(pCoder, pReq->ctb.stbName)); TAOS_CHECK_EXIT(tEncodeCStr(pCoder, pReq->ctb.stbName));
TAOS_CHECK_EXIT(tEncodeU8(pCoder, pReq->ctb.tagNum)); TAOS_CHECK_EXIT(tEncodeU8(pCoder, pReq->ctb.tagNum));
TAOS_CHECK_EXIT(tEncodeI64(pCoder, pReq->ctb.suid)); TAOS_CHECK_EXIT(tEncodeI64(pCoder, pReq->ctb.suid));
@ -10637,7 +10804,7 @@ int tEncodeSVCreateTbReq(SEncoder *pCoder, const SVCreateTbReq *pReq) {
char *name = taosArrayGet(pReq->ctb.tagName, i); char *name = taosArrayGet(pReq->ctb.tagName, i);
TAOS_CHECK_EXIT(tEncodeCStr(pCoder, name)); TAOS_CHECK_EXIT(tEncodeCStr(pCoder, name));
} }
} else if (pReq->type == TSDB_NORMAL_TABLE) { } else if (pReq->type == TSDB_NORMAL_TABLE || pReq->type == TSDB_VIRTUAL_NORMAL_TABLE) {
TAOS_CHECK_EXIT(tEncodeSSchemaWrapper(pCoder, &pReq->ntb.schemaRow)); TAOS_CHECK_EXIT(tEncodeSSchemaWrapper(pCoder, &pReq->ntb.schemaRow));
} else { } else {
return TSDB_CODE_INVALID_MSG; return TSDB_CODE_INVALID_MSG;
@ -10651,13 +10818,16 @@ int tEncodeSVCreateTbReq(SEncoder *pCoder, const SVCreateTbReq *pReq) {
// Encode Column Options: encode compress level // Encode Column Options: encode compress level
if (pReq->type == TSDB_SUPER_TABLE || pReq->type == TSDB_NORMAL_TABLE) { if (pReq->type == TSDB_SUPER_TABLE || pReq->type == TSDB_NORMAL_TABLE) {
TAOS_CHECK_EXIT(tEncodeSColCmprWrapper(pCoder, &pReq->colCmpr)); TAOS_CHECK_EXIT(tEncodeSColCmprWrapper(pCoder, &pReq->colCmpr));
}
if (pReq->type == TSDB_VIRTUAL_NORMAL_TABLE || pReq->type == TSDB_VIRTUAL_CHILD_TABLE) {
TAOS_CHECK_EXIT(tEncodeSColRefWrapper(pCoder, &pReq->colRef));
}
if (pReq->pExtSchemas) { if (pReq->pExtSchemas) {
TAOS_CHECK_EXIT(tEncodeI8(pCoder, 1)); TAOS_CHECK_EXIT(tEncodeI8(pCoder, 1));
TAOS_CHECK_EXIT(tEncodeSExtSchemas(pCoder, pReq->pExtSchemas, pReq->ntb.schemaRow.nCols)); TAOS_CHECK_EXIT(tEncodeSExtSchemas(pCoder, pReq->pExtSchemas, pReq->ntb.schemaRow.nCols));
} else { } else {
TAOS_CHECK_EXIT(tEncodeI8(pCoder, 0)); TAOS_CHECK_EXIT(tEncodeI8(pCoder, 0));
} }
}
tEndEncode(pCoder); tEndEncode(pCoder);
_exit: _exit:
@ -10685,7 +10855,7 @@ int tDecodeSVCreateTbReq(SDecoder *pCoder, SVCreateTbReq *pReq) {
TAOS_CHECK_EXIT(tDecodeCStrTo(pCoder, pReq->comment)); TAOS_CHECK_EXIT(tDecodeCStrTo(pCoder, pReq->comment));
} }
if (pReq->type == TSDB_CHILD_TABLE) { if (pReq->type == TSDB_CHILD_TABLE || pReq->type == TSDB_VIRTUAL_CHILD_TABLE) {
TAOS_CHECK_EXIT(tDecodeCStr(pCoder, &pReq->ctb.stbName)); TAOS_CHECK_EXIT(tDecodeCStr(pCoder, &pReq->ctb.stbName));
TAOS_CHECK_EXIT(tDecodeU8(pCoder, &pReq->ctb.tagNum)); TAOS_CHECK_EXIT(tDecodeU8(pCoder, &pReq->ctb.tagNum));
TAOS_CHECK_EXIT(tDecodeI64(pCoder, &pReq->ctb.suid)); TAOS_CHECK_EXIT(tDecodeI64(pCoder, &pReq->ctb.suid));
@ -10705,7 +10875,7 @@ int tDecodeSVCreateTbReq(SDecoder *pCoder, SVCreateTbReq *pReq) {
TAOS_CHECK_EXIT(terrno); TAOS_CHECK_EXIT(terrno);
} }
} }
} else if (pReq->type == TSDB_NORMAL_TABLE) { } else if (pReq->type == TSDB_NORMAL_TABLE || pReq->type == TSDB_VIRTUAL_NORMAL_TABLE) {
TAOS_CHECK_EXIT(tDecodeSSchemaWrapperEx(pCoder, &pReq->ntb.schemaRow)); TAOS_CHECK_EXIT(tDecodeSSchemaWrapperEx(pCoder, &pReq->ntb.schemaRow));
} else { } else {
return TSDB_CODE_INVALID_MSG; return TSDB_CODE_INVALID_MSG;
@ -10717,10 +10887,15 @@ int tDecodeSVCreateTbReq(SDecoder *pCoder, SVCreateTbReq *pReq) {
if (pReq->sqlLen > 0) { if (pReq->sqlLen > 0) {
TAOS_CHECK_EXIT(tDecodeBinaryAlloc(pCoder, (void **)&pReq->sql, NULL)); TAOS_CHECK_EXIT(tDecodeBinaryAlloc(pCoder, (void **)&pReq->sql, NULL));
} }
if (pReq->type == TSDB_NORMAL_TABLE || pReq->type == TSDB_SUPER_TABLE) if (pReq->type == TSDB_NORMAL_TABLE || pReq->type == TSDB_SUPER_TABLE) {
if (!tDecodeIsEnd(pCoder)) { if (!tDecodeIsEnd(pCoder)) {
TAOS_CHECK_EXIT(tDecodeSColCmprWrapperEx(pCoder, &pReq->colCmpr)); TAOS_CHECK_EXIT(tDecodeSColCmprWrapperEx(pCoder, &pReq->colCmpr));
} }
} else if (pReq->type == TSDB_VIRTUAL_NORMAL_TABLE || pReq->type == TSDB_VIRTUAL_CHILD_TABLE) {
if (!tDecodeIsEnd(pCoder)) {
TAOS_CHECK_EXIT(tDecodeSColRefWrapperEx(pCoder, &pReq->colRef));
}
}
if (!tDecodeIsEnd(pCoder)) { if (!tDecodeIsEnd(pCoder)) {
int8_t hasExtSchema = 0; int8_t hasExtSchema = 0;
@ -10742,25 +10917,18 @@ void tDestroySVCreateTbReq(SVCreateTbReq *pReq, int32_t flags) {
if (flags & TSDB_MSG_FLG_ENCODE) { if (flags & TSDB_MSG_FLG_ENCODE) {
// TODO // TODO
} else if (flags & TSDB_MSG_FLG_DECODE) { } else if (flags & TSDB_MSG_FLG_DECODE) {
if (pReq->comment) { taosMemoryFreeClear(pReq->comment);
pReq->comment = NULL;
taosMemoryFree(pReq->comment);
}
if (pReq->type == TSDB_CHILD_TABLE) { if (pReq->type == TSDB_CHILD_TABLE || pReq->type == TSDB_VIRTUAL_CHILD_TABLE) {
if (pReq->ctb.tagName) taosArrayDestroy(pReq->ctb.tagName); taosArrayDestroy(pReq->ctb.tagName);
} else if (pReq->type == TSDB_NORMAL_TABLE) { } else if (pReq->type == TSDB_NORMAL_TABLE || pReq->type == TSDB_VIRTUAL_NORMAL_TABLE) {
if (pReq->ntb.schemaRow.pSchema) taosMemoryFree(pReq->ntb.schemaRow.pSchema); taosMemoryFreeClear(pReq->ntb.schemaRow.pSchema);
} }
} }
if (pReq->colCmpr.pColCmpr) taosMemoryFree(pReq->colCmpr.pColCmpr); taosMemoryFreeClear(pReq->colCmpr.pColCmpr);
pReq->colCmpr.pColCmpr = NULL; taosMemoryFreeClear(pReq->colRef.pColRef);
taosMemoryFreeClear(pReq->sql);
if (pReq->sql != NULL) {
taosMemoryFree(pReq->sql);
}
pReq->sql = NULL;
} }
int tEncodeSVCreateTbBatchReq(SEncoder *pCoder, const SVCreateTbBatchReq *pReq) { int tEncodeSVCreateTbBatchReq(SEncoder *pCoder, const SVCreateTbBatchReq *pReq) {
@ -10803,7 +10971,7 @@ void tDeleteSVCreateTbBatchReq(SVCreateTbBatchReq *pReq) {
SVCreateTbReq *pCreateReq = pReq->pReqs + iReq; SVCreateTbReq *pCreateReq = pReq->pReqs + iReq;
taosMemoryFreeClear(pCreateReq->sql); taosMemoryFreeClear(pCreateReq->sql);
taosMemoryFreeClear(pCreateReq->comment); taosMemoryFreeClear(pCreateReq->comment);
if (pCreateReq->type == TSDB_CHILD_TABLE) { if (pCreateReq->type == TSDB_CHILD_TABLE || pCreateReq->type == TSDB_VIRTUAL_CHILD_TABLE) {
taosArrayDestroy(pCreateReq->ctb.tagName); taosArrayDestroy(pCreateReq->ctb.tagName);
pCreateReq->ctb.tagName = NULL; pCreateReq->ctb.tagName = NULL;
} }
@ -10853,6 +11021,7 @@ void tFreeSVCreateTbRsp(void *param) {
if (pRsp->pMeta) { if (pRsp->pMeta) {
taosMemoryFree(pRsp->pMeta->pSchemas); taosMemoryFree(pRsp->pMeta->pSchemas);
taosMemoryFree(pRsp->pMeta->pSchemaExt); taosMemoryFree(pRsp->pMeta->pSchemaExt);
taosMemoryFree(pRsp->pMeta->pColRefs);
taosMemoryFree(pRsp->pMeta); taosMemoryFree(pRsp->pMeta);
} }
} }
@ -10864,6 +11033,7 @@ static int32_t tEncodeSVDropTbReq(SEncoder *pCoder, const SVDropTbReq *pReq) {
TAOS_CHECK_RETURN(tEncodeU64(pCoder, pReq->suid)); TAOS_CHECK_RETURN(tEncodeU64(pCoder, pReq->suid));
TAOS_CHECK_RETURN(tEncodeI64(pCoder, pReq->uid)); TAOS_CHECK_RETURN(tEncodeI64(pCoder, pReq->uid));
TAOS_CHECK_RETURN(tEncodeI8(pCoder, pReq->igNotExists)); TAOS_CHECK_RETURN(tEncodeI8(pCoder, pReq->igNotExists));
TAOS_CHECK_RETURN(tEncodeI8(pCoder, pReq->isVirtual));
tEndEncode(pCoder); tEndEncode(pCoder);
return 0; return 0;
@ -10875,6 +11045,9 @@ static int32_t tDecodeSVDropTbReq(SDecoder *pCoder, SVDropTbReq *pReq) {
TAOS_CHECK_RETURN(tDecodeU64(pCoder, &pReq->suid)); TAOS_CHECK_RETURN(tDecodeU64(pCoder, &pReq->suid));
TAOS_CHECK_RETURN(tDecodeI64(pCoder, &pReq->uid)); TAOS_CHECK_RETURN(tDecodeI64(pCoder, &pReq->uid));
TAOS_CHECK_RETURN(tDecodeI8(pCoder, &pReq->igNotExists)); TAOS_CHECK_RETURN(tDecodeI8(pCoder, &pReq->igNotExists));
if (!tDecodeIsEnd(pCoder)) {
TAOS_CHECK_RETURN(tDecodeI8(pCoder, &pReq->isVirtual));
}
tEndDecode(pCoder); tEndDecode(pCoder);
return 0; return 0;
@ -11081,6 +11254,24 @@ int32_t tEncodeSVAlterTbReq(SEncoder *pEncoder, const SVAlterTbReq *pReq) {
TAOS_CHECK_EXIT(tEncodeI32v(pEncoder, pReq->bytes)); TAOS_CHECK_EXIT(tEncodeI32v(pEncoder, pReq->bytes));
TAOS_CHECK_EXIT(tEncodeU32(pEncoder, pReq->compress)); TAOS_CHECK_EXIT(tEncodeU32(pEncoder, pReq->compress));
break; break;
case TSDB_ALTER_TABLE_ALTER_COLUMN_REF:
TAOS_CHECK_EXIT(tEncodeCStr(pEncoder, pReq->colName));
TAOS_CHECK_EXIT(tEncodeCStr(pEncoder, pReq->refDbName));
TAOS_CHECK_EXIT(tEncodeCStr(pEncoder, pReq->refTbName));
TAOS_CHECK_EXIT(tEncodeCStr(pEncoder, pReq->refColName));
break;
case TSDB_ALTER_TABLE_REMOVE_COLUMN_REF:
TAOS_CHECK_EXIT(tEncodeCStr(pEncoder, pReq->colName));
break;
case TSDB_ALTER_TABLE_ADD_COLUMN_WITH_COLUMN_REF:
TAOS_CHECK_EXIT(tEncodeCStr(pEncoder, pReq->colName));
TAOS_CHECK_EXIT(tEncodeI8(pEncoder, pReq->type));
TAOS_CHECK_EXIT(tEncodeI8(pEncoder, pReq->flags));
TAOS_CHECK_EXIT(tEncodeI32v(pEncoder, pReq->bytes));
TAOS_CHECK_EXIT(tEncodeCStr(pEncoder, pReq->refDbName));
TAOS_CHECK_EXIT(tEncodeCStr(pEncoder, pReq->refTbName));
TAOS_CHECK_EXIT(tEncodeCStr(pEncoder, pReq->refColName));
break;
default: default:
break; break;
} }
@ -11171,6 +11362,25 @@ static int32_t tDecodeSVAlterTbReqCommon(SDecoder *pDecoder, SVAlterTbReq *pReq)
TAOS_CHECK_EXIT(tDecodeI8(pDecoder, &pReq->flags)); TAOS_CHECK_EXIT(tDecodeI8(pDecoder, &pReq->flags));
TAOS_CHECK_EXIT(tDecodeI32v(pDecoder, &pReq->bytes)); TAOS_CHECK_EXIT(tDecodeI32v(pDecoder, &pReq->bytes));
TAOS_CHECK_EXIT(tDecodeU32(pDecoder, &pReq->compress)); TAOS_CHECK_EXIT(tDecodeU32(pDecoder, &pReq->compress));
break;
case TSDB_ALTER_TABLE_ALTER_COLUMN_REF:
TAOS_CHECK_EXIT(tDecodeCStr(pDecoder, &pReq->colName));
TAOS_CHECK_EXIT(tDecodeCStr(pDecoder, &pReq->refDbName));
TAOS_CHECK_EXIT(tDecodeCStr(pDecoder, &pReq->refTbName));
TAOS_CHECK_EXIT(tDecodeCStr(pDecoder, &pReq->refColName));
break;
case TSDB_ALTER_TABLE_REMOVE_COLUMN_REF:
TAOS_CHECK_EXIT(tDecodeCStr(pDecoder, &pReq->colName));
break;
case TSDB_ALTER_TABLE_ADD_COLUMN_WITH_COLUMN_REF:
TAOS_CHECK_EXIT(tDecodeCStr(pDecoder, &pReq->colName));
TAOS_CHECK_EXIT(tDecodeI8(pDecoder, &pReq->type));
TAOS_CHECK_EXIT(tDecodeI8(pDecoder, &pReq->flags));
TAOS_CHECK_EXIT(tDecodeI32v(pDecoder, &pReq->bytes));
TAOS_CHECK_EXIT(tDecodeCStr(pDecoder, &pReq->refDbName));
TAOS_CHECK_EXIT(tDecodeCStr(pDecoder, &pReq->refTbName));
TAOS_CHECK_EXIT(tDecodeCStr(pDecoder, &pReq->refColName));
break;
default: default:
break; break;
} }
@ -11308,6 +11518,7 @@ void tFreeSMAlterStbRsp(SMAlterStbRsp *pRsp) {
if (pRsp->pMeta) { if (pRsp->pMeta) {
taosMemoryFree(pRsp->pMeta->pSchemas); taosMemoryFree(pRsp->pMeta->pSchemas);
taosMemoryFree(pRsp->pMeta->pSchemaExt); taosMemoryFree(pRsp->pMeta->pSchemaExt);
taosMemoryFree(pRsp->pMeta->pColRefs);
taosMemoryFree(pRsp->pMeta); taosMemoryFree(pRsp->pMeta);
} }
} }
@ -11359,6 +11570,7 @@ void tFreeSMCreateStbRsp(SMCreateStbRsp *pRsp) {
if (pRsp->pMeta) { if (pRsp->pMeta) {
taosMemoryFree(pRsp->pMeta->pSchemas); taosMemoryFree(pRsp->pMeta->pSchemas);
taosMemoryFree(pRsp->pMeta->pSchemaExt); taosMemoryFree(pRsp->pMeta->pSchemaExt);
taosMemoryFree(pRsp->pMeta->pColRefs);
taosMemoryFree(pRsp->pMeta); taosMemoryFree(pRsp->pMeta);
} }
} }

View File

@ -164,6 +164,7 @@ static const SSysDbTableSchema userStbsSchema[] = {
{.name = "max_delay", .bytes = 64 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false}, {.name = "max_delay", .bytes = 64 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false},
{.name = "rollup", .bytes = 128 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false}, {.name = "rollup", .bytes = 128 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false},
{.name = "uid", .bytes = 8, .type = TSDB_DATA_TYPE_BIGINT, .sysInfo = false}, {.name = "uid", .bytes = 8, .type = TSDB_DATA_TYPE_BIGINT, .sysInfo = false},
{.name = "isvirtual", .bytes = 1, .type = TSDB_DATA_TYPE_BOOL, .sysInfo = false},
}; };
static const SSysDbTableSchema streamSchema[] = { static const SSysDbTableSchema streamSchema[] = {
@ -247,7 +248,8 @@ static const SSysDbTableSchema userColsSchema[] = {
{.name = "col_length", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = false}, {.name = "col_length", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = false},
{.name = "col_precision", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = false}, {.name = "col_precision", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = false},
{.name = "col_scale", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = false}, {.name = "col_scale", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = false},
{.name = "col_nullable", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = false} {.name = "col_nullable", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = false},
{.name = "col_source", .bytes = TSDB_COL_FNAME_LEN - 1 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false}
}; };
static const SSysDbTableSchema userTblDistSchema[] = { static const SSysDbTableSchema userTblDistSchema[] = {

View File

@ -354,6 +354,10 @@ bool withExtSchema(uint8_t tableType) {
return TSDB_SUPER_TABLE == tableType || TSDB_NORMAL_TABLE == tableType || TSDB_CHILD_TABLE == tableType; return TSDB_SUPER_TABLE == tableType || TSDB_NORMAL_TABLE == tableType || TSDB_CHILD_TABLE == tableType;
} }
bool hasRefCol(uint8_t tableType) {
return TSDB_VIRTUAL_NORMAL_TABLE == tableType || TSDB_VIRTUAL_CHILD_TABLE == tableType;
}
int8_t validColCompressLevel(uint8_t type, uint8_t level) { int8_t validColCompressLevel(uint8_t type, uint8_t level) {
if (level == TSDB_COLVAL_LEVEL_DISABLED) return 1; if (level == TSDB_COLVAL_LEVEL_DISABLED) return 1;
if (level < TSDB_COLVAL_LEVEL_NOCHANGE || level > TSDB_COLVAL_LEVEL_HIGH) { if (level < TSDB_COLVAL_LEVEL_NOCHANGE || level > TSDB_COLVAL_LEVEL_HIGH) {

View File

@ -1224,7 +1224,7 @@ size_t blockDataGetRowSize(SSDataBlock* pBlock) {
*/ */
size_t blockDataGetSerialMetaSize(uint32_t numOfCols) { size_t blockDataGetSerialMetaSize(uint32_t numOfCols) {
// | version | total length | total rows | blankFull | total columns | flag seg| block group id | column schema // | version | total length | total rows | blankFull | total columns | flag seg| block group id | column schema
// | each column length | // | each column length
return sizeof(int32_t) + sizeof(int32_t) + sizeof(int32_t) + sizeof(bool) + sizeof(int32_t) + sizeof(int32_t) + return sizeof(int32_t) + sizeof(int32_t) + sizeof(int32_t) + sizeof(bool) + sizeof(int32_t) + sizeof(int32_t) +
sizeof(uint64_t) + numOfCols * (sizeof(int8_t) + sizeof(int32_t)) + numOfCols * sizeof(int32_t); sizeof(uint64_t) + numOfCols * (sizeof(int8_t) + sizeof(int32_t)) + numOfCols * sizeof(int32_t);
} }
@ -2112,6 +2112,97 @@ int32_t createOneDataBlock(const SSDataBlock* pDataBlock, bool copyData, SSDataB
return code; return code;
} }
int32_t createOneDataBlockWithColArray(const SSDataBlock* pDataBlock, SArray* pColArray, SSDataBlock** pResBlock) {
int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
SSDataBlock* pDstBlock = NULL;
QRY_PARAM_CHECK(pResBlock);
QUERY_CHECK_NULL(pDataBlock, code, lino, _return, TSDB_CODE_INVALID_PARA);
QUERY_CHECK_CODE(createDataBlock(&pDstBlock), lino, _return);
pDstBlock->info = pDataBlock->info;
pDstBlock->info.pks[0].pData = NULL;
pDstBlock->info.pks[1].pData = NULL;
pDstBlock->info.rows = 0;
pDstBlock->info.capacity = 0;
pDstBlock->info.rowSize = 0;
pDstBlock->info.id = pDataBlock->info.id;
pDstBlock->info.blankFill = pDataBlock->info.blankFill;
for (int32_t i = 0; i < taosArrayGetSize(pColArray); ++i) {
SColIdPair *pColPair = taosArrayGet(pColArray, i);
QUERY_CHECK_NULL(pColPair, code, lino, _return, terrno);
for (int32_t j = 0; j < taosArrayGetSize(pDataBlock->pDataBlock); ++j) {
SColumnInfoData* p = taosArrayGet(pDataBlock->pDataBlock, j);
if (p == NULL) {
continue;
}
if (p->info.colId == pColPair->vtbColId) {
QUERY_CHECK_CODE(blockDataAppendColInfo(pDstBlock, p), lino, _return);
break;
}
}
}
*pResBlock = pDstBlock;
return code;
_return:
uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
blockDataDestroy(pDstBlock);
return code;
}
int32_t createOneDataBlockWithTwoBlock(const SSDataBlock* pDataBlock, const SSDataBlock* pOrgBlock, SSDataBlock** pResBlock) {
int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
SSDataBlock *pDstBlock = NULL;
QRY_PARAM_CHECK(pResBlock);
QUERY_CHECK_NULL(pDataBlock, code, lino, _return, TSDB_CODE_INVALID_PARA);
QUERY_CHECK_NULL(pOrgBlock, code, lino, _return, TSDB_CODE_INVALID_PARA);
QUERY_CHECK_CODE(createOneDataBlock(pOrgBlock, false, &pDstBlock), lino, _return);
QUERY_CHECK_CODE(blockDataEnsureCapacity(pDstBlock, pDataBlock->info.rows), lino, _return);
for (int32_t i = 0; i < taosArrayGetSize(pOrgBlock->pDataBlock); ++i) {
SColumnInfoData* pDst = taosArrayGet(pDstBlock->pDataBlock, i);
SColumnInfoData* pSrc = taosArrayGet(pOrgBlock->pDataBlock, i);
QUERY_CHECK_NULL(pDst, code, lino, _return, terrno);
QUERY_CHECK_NULL(pSrc, code, lino, _return, terrno);
bool found = false;
for (int32_t j = 0; j < taosArrayGetSize(pDataBlock->pDataBlock); j++) {
SColumnInfoData *p = taosArrayGet(pDataBlock->pDataBlock, j);
if (p->info.slotId == pSrc->info.slotId) {
QUERY_CHECK_CODE(colDataAssign(pDst, p, (int32_t)pDataBlock->info.rows, &pDataBlock->info), lino, _return);
found = true;
break;
}
}
if (!found) {
colDataSetNNULL(pDst, 0, pDataBlock->info.rows);
}
}
pDstBlock->info.rows = pDataBlock->info.rows;
pDstBlock->info.capacity = pDataBlock->info.rows;
pDstBlock->info.window = pDataBlock->info.window;
*pResBlock = pDstBlock;
return code;
_return:
uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
blockDataDestroy(pDstBlock);
return code;
}
int32_t createDataBlock(SSDataBlock** pResBlock) { int32_t createDataBlock(SSDataBlock** pResBlock) {
QRY_PARAM_CHECK(pResBlock); QRY_PARAM_CHECK(pResBlock);
SSDataBlock* pBlock = taosMemoryCalloc(1, sizeof(SSDataBlock)); SSDataBlock* pBlock = taosMemoryCalloc(1, sizeof(SSDataBlock));

View File

@ -188,6 +188,7 @@ SArray *mmGetMsgHandles() {
if (dmSetMgmtHandle(pArray, TDMT_VND_FETCH_TTL_EXPIRED_TBS_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_VND_FETCH_TTL_EXPIRED_TBS_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_VND_DROP_TABLE_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_VND_DROP_TABLE_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_MND_RESET_STREAM, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_MND_RESET_STREAM, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_MND_GET_DB_INFO, mmPutMsgToReadQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_MND_RETRIEVE_ANAL_ALGO, mmPutMsgToReadQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_MND_RETRIEVE_ANAL_ALGO, mmPutMsgToReadQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_MND_RETRIEVE_IP_WHITE, mmPutMsgToReadQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_MND_RETRIEVE_IP_WHITE, mmPutMsgToReadQueue, 0) == NULL) goto _OVER;

View File

@ -164,6 +164,7 @@ static void dmProcessRpcMsg(SDnode *pDnode, SRpcMsg *pRpc, SEpSet *pEpSet) {
case TDMT_SCH_FETCH_RSP: case TDMT_SCH_FETCH_RSP:
case TDMT_SCH_MERGE_FETCH_RSP: case TDMT_SCH_MERGE_FETCH_RSP:
case TDMT_VND_SUBMIT_RSP: case TDMT_VND_SUBMIT_RSP:
case TDMT_MND_GET_DB_INFO_RSP:
code = qWorkerProcessRspMsg(NULL, NULL, pRpc, 0); code = qWorkerProcessRspMsg(NULL, NULL, pRpc, 0);
return; return;
case TDMT_MND_STATUS_RSP: case TDMT_MND_STATUS_RSP:

View File

@ -593,6 +593,7 @@ typedef struct {
SColCmpr* pCmpr; SColCmpr* pCmpr;
int64_t keep; int64_t keep;
SExtSchema* pExtSchemas; SExtSchema* pExtSchemas;
int8_t virtualStb;
} SStbObj; } SStbObj;
typedef struct { typedef struct {

View File

@ -80,6 +80,7 @@ int32_t mndInitDb(SMnode *pMnode) {
mndSetMsgHandle(pMnode, TDMT_MND_TRIM_DB, mndProcessTrimDbReq); mndSetMsgHandle(pMnode, TDMT_MND_TRIM_DB, mndProcessTrimDbReq);
mndSetMsgHandle(pMnode, TDMT_MND_GET_DB_CFG, mndProcessGetDbCfgReq); mndSetMsgHandle(pMnode, TDMT_MND_GET_DB_CFG, mndProcessGetDbCfgReq);
mndSetMsgHandle(pMnode, TDMT_MND_S3MIGRATE_DB, mndProcessS3MigrateDbReq); mndSetMsgHandle(pMnode, TDMT_MND_S3MIGRATE_DB, mndProcessS3MigrateDbReq);
mndSetMsgHandle(pMnode, TDMT_MND_GET_DB_INFO, mndProcessUseDbReq);
mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_DB, mndRetrieveDbs); mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_DB, mndRetrieveDbs);
mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_DB, mndCancelGetNextDb); mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_DB, mndCancelGetNextDb);

View File

@ -198,6 +198,7 @@ void dumpStb(SSdb *pSdb, SJson *json) {
RETRIEVE_CHECK_GOTO(tjsonAddStringToObject(item, "commentLen", i642str(pObj->commentLen)), pObj, &lino, _OVER); RETRIEVE_CHECK_GOTO(tjsonAddStringToObject(item, "commentLen", i642str(pObj->commentLen)), pObj, &lino, _OVER);
RETRIEVE_CHECK_GOTO(tjsonAddStringToObject(item, "ast1Len", i642str(pObj->ast1Len)), pObj, &lino, _OVER); RETRIEVE_CHECK_GOTO(tjsonAddStringToObject(item, "ast1Len", i642str(pObj->ast1Len)), pObj, &lino, _OVER);
RETRIEVE_CHECK_GOTO(tjsonAddStringToObject(item, "ast2Len", i642str(pObj->ast2Len)), pObj, &lino, _OVER); RETRIEVE_CHECK_GOTO(tjsonAddStringToObject(item, "ast2Len", i642str(pObj->ast2Len)), pObj, &lino, _OVER);
RETRIEVE_CHECK_GOTO(tjsonAddStringToObject(item, "virtual", i642str(pObj->virtualStb)), pObj, &lino, _OVER);
RETRIEVE_CHECK_GOTO(tjsonAddStringToObject(item, "numOfColumns", i642str(pObj->numOfColumns)), pObj, &lino, _OVER); RETRIEVE_CHECK_GOTO(tjsonAddStringToObject(item, "numOfColumns", i642str(pObj->numOfColumns)), pObj, &lino, _OVER);
SJson *columns = tjsonAddArrayToObject(item, "columns"); SJson *columns = tjsonAddArrayToObject(item, "columns");

View File

@ -47,6 +47,7 @@ static int32_t mndInsInitMeta(SHashObj *hash) {
meta.tableType = TSDB_SYSTEM_TABLE; meta.tableType = TSDB_SYSTEM_TABLE;
meta.sversion = 1; meta.sversion = 1;
meta.tversion = 1; meta.tversion = 1;
meta.virtualStb = false;
size_t size = 0; size_t size = 0;
const SSysTableMeta *pInfosTableMeta = NULL; const SSysTableMeta *pInfosTableMeta = NULL;
@ -128,6 +129,7 @@ int32_t mndBuildInsTableCfg(SMnode *pMnode, const char *dbFName, const char *tbN
pRsp->numOfTags = pMeta->numOfTags; pRsp->numOfTags = pMeta->numOfTags;
pRsp->numOfColumns = pMeta->numOfColumns; pRsp->numOfColumns = pMeta->numOfColumns;
pRsp->tableType = pMeta->tableType; pRsp->tableType = pMeta->tableType;
pRsp->virtualStb = pMeta->virtualStb;
pRsp->pSchemas = taosMemoryCalloc(pMeta->numOfColumns, sizeof(SSchema)); pRsp->pSchemas = taosMemoryCalloc(pMeta->numOfColumns, sizeof(SSchema));
if (pRsp->pSchemas == NULL) { if (pRsp->pSchemas == NULL) {
@ -139,6 +141,7 @@ int32_t mndBuildInsTableCfg(SMnode *pMnode, const char *dbFName, const char *tbN
memcpy(pRsp->pSchemas, pMeta->pSchemas, pMeta->numOfColumns * sizeof(SSchema)); memcpy(pRsp->pSchemas, pMeta->pSchemas, pMeta->numOfColumns * sizeof(SSchema));
pRsp->pSchemaExt = taosMemoryCalloc(pMeta->numOfColumns, sizeof(SSchemaExt)); pRsp->pSchemaExt = taosMemoryCalloc(pMeta->numOfColumns, sizeof(SSchemaExt));
pRsp->pColRefs = taosMemCalloc(pMeta->numOfColumns, sizeof(SColRef));
TAOS_RETURN(code); TAOS_RETURN(code);
} }

View File

@ -46,6 +46,7 @@ int32_t mndPerfsInitMeta(SHashObj *hash) {
meta.tableType = TSDB_SYSTEM_TABLE; meta.tableType = TSDB_SYSTEM_TABLE;
meta.sversion = 1; meta.sversion = 1;
meta.tversion = 1; meta.tversion = 1;
meta.virtualStb = false;
size_t size = 0; size_t size = 0;
const SSysTableMeta *pSysDbTableMeta = NULL; const SSysTableMeta *pSysDbTableMeta = NULL;
@ -113,6 +114,7 @@ int32_t mndBuildPerfsTableCfg(SMnode *pMnode, const char *dbFName, const char *t
pRsp->numOfTags = pMeta->numOfTags; pRsp->numOfTags = pMeta->numOfTags;
pRsp->numOfColumns = pMeta->numOfColumns; pRsp->numOfColumns = pMeta->numOfColumns;
pRsp->tableType = pMeta->tableType; pRsp->tableType = pMeta->tableType;
pRsp->virtualStb = pMeta->virtualStb;
pRsp->pSchemas = taosMemoryCalloc(pMeta->numOfColumns, sizeof(SSchema)); pRsp->pSchemas = taosMemoryCalloc(pMeta->numOfColumns, sizeof(SSchema));
if (pRsp->pSchemas == NULL) { if (pRsp->pSchemas == NULL) {

View File

@ -33,7 +33,7 @@
#include "mndVgroup.h" #include "mndVgroup.h"
#include "tname.h" #include "tname.h"
#define STB_VER_NUMBER 2 #define STB_VER_NUMBER 3
#define STB_RESERVE_SIZE 56 #define STB_RESERVE_SIZE 56
static SSdbRow *mndStbActionDecode(SSdbRaw *pRaw); static SSdbRow *mndStbActionDecode(SSdbRaw *pRaw);
@ -194,13 +194,13 @@ SSdbRaw *mndStbActionEncode(SStbObj *pStb) {
} }
SDB_SET_INT64(pRaw, dataPos, pStb->keep, _OVER) SDB_SET_INT64(pRaw, dataPos, pStb->keep, _OVER)
if (hasTypeMod) { if (hasTypeMod) {
for (int32_t i = 0; i < pStb->numOfColumns; ++i) { for (int32_t i = 0; i < pStb->numOfColumns; ++i) {
SDB_SET_INT32(pRaw, dataPos, pStb->pExtSchemas[i].typeMod, _OVER); SDB_SET_INT32(pRaw, dataPos, pStb->pExtSchemas[i].typeMod, _OVER);
} }
} }
SDB_SET_INT8(pRaw, dataPos, pStb->virtualStb, _OVER)
SDB_SET_RESERVE(pRaw, dataPos, STB_RESERVE_SIZE, _OVER) SDB_SET_RESERVE(pRaw, dataPos, STB_RESERVE_SIZE, _OVER)
SDB_SET_DATALEN(pRaw, dataPos, _OVER) SDB_SET_DATALEN(pRaw, dataPos, _OVER)
@ -313,7 +313,7 @@ static SSdbRow *mndStbActionDecode(SSdbRaw *pRaw) {
} }
pStb->pCmpr = taosMemoryCalloc(pStb->numOfColumns, sizeof(SColCmpr)); pStb->pCmpr = taosMemoryCalloc(pStb->numOfColumns, sizeof(SColCmpr));
if (sver < STB_VER_NUMBER) { if (sver < STB_VER_NUMBER - 1) {
// compatible with old data, setup default compress value // compatible with old data, setup default compress value
// impl later // impl later
for (int i = 0; i < pStb->numOfColumns; i++) { for (int i = 0; i < pStb->numOfColumns; i++) {
@ -341,6 +341,12 @@ static SSdbRow *mndStbActionDecode(SSdbRaw *pRaw) {
} }
} }
if (sver < STB_VER_NUMBER) {
pStb->virtualStb = 0;
} else {
SDB_GET_INT8(pRaw, dataPos, &pStb->virtualStb, _OVER)
}
SDB_GET_RESERVE(pRaw, dataPos, STB_RESERVE_SIZE, _OVER) SDB_GET_RESERVE(pRaw, dataPos, STB_RESERVE_SIZE, _OVER)
terrno = 0; terrno = 0;
@ -544,6 +550,7 @@ void *mndBuildVCreateStbReq(SMnode *pMnode, SVgObj *pVgroup, SStbObj *pStb, int3
req.alterOriData = alterOriData; req.alterOriData = alterOriData;
req.alterOriDataLen = alterOriDataLen; req.alterOriDataLen = alterOriDataLen;
req.source = pStb->source; req.source = pStb->source;
req.virtualStb = pStb->virtualStb;
// todo // todo
req.schemaRow.nCols = pStb->numOfColumns; req.schemaRow.nCols = pStb->numOfColumns;
req.schemaRow.version = pStb->colVer; req.schemaRow.version = pStb->colVer;
@ -674,6 +681,11 @@ int32_t mndCheckCreateStbReq(SMCreateStbReq *pCreate) {
TAOS_RETURN(code); TAOS_RETURN(code);
} }
if (pCreate->virtualStb != 0 && pCreate->virtualStb != 1) {
code = TSDB_CODE_MND_INVALID_STB_OPTION;
TAOS_RETURN(code);
}
if (pCreate->numOfColumns < TSDB_MIN_COLUMNS || pCreate->numOfTags + pCreate->numOfColumns > TSDB_MAX_COLUMNS) { if (pCreate->numOfColumns < TSDB_MIN_COLUMNS || pCreate->numOfTags + pCreate->numOfColumns > TSDB_MAX_COLUMNS) {
code = TSDB_CODE_PAR_INVALID_COLUMNS_NUM; code = TSDB_CODE_PAR_INVALID_COLUMNS_NUM;
TAOS_RETURN(code); TAOS_RETURN(code);
@ -909,6 +921,7 @@ int32_t mndBuildStbFromReq(SMnode *pMnode, SStbObj *pDst, SMCreateStbReq *pCreat
pDst->pFuncs = pCreate->pFuncs; pDst->pFuncs = pCreate->pFuncs;
pDst->source = pCreate->source; pDst->source = pCreate->source;
pDst->keep = pCreate->keep; pDst->keep = pCreate->keep;
pDst->virtualStb = pCreate->virtualStb;
pCreate->pFuncs = NULL; pCreate->pFuncs = NULL;
if (pDst->commentLen > 0) { if (pDst->commentLen > 0) {
@ -2223,6 +2236,7 @@ static int32_t mndSetAlterStbRedoActions2(SMnode *pMnode, STrans *pTrans, SDbObj
TAOS_RETURN(code); TAOS_RETURN(code);
} }
static int32_t mndBuildStbSchemaImp(SDbObj *pDb, SStbObj *pStb, const char *tbName, STableMetaRsp *pRsp) { static int32_t mndBuildStbSchemaImp(SDbObj *pDb, SStbObj *pStb, const char *tbName, STableMetaRsp *pRsp) {
int32_t code = 0; int32_t code = 0;
taosRLockLatch(&pStb->lock); taosRLockLatch(&pStb->lock);
@ -2240,7 +2254,8 @@ static int32_t mndBuildStbSchemaImp(SDbObj *pDb, SStbObj *pStb, const char *tbNa
code = terrno; code = terrno;
TAOS_RETURN(code); TAOS_RETURN(code);
} }
pRsp->numOfColRefs = 0;
pRsp->pColRefs = NULL;
tstrncpy(pRsp->dbFName, pStb->db, sizeof(pRsp->dbFName)); tstrncpy(pRsp->dbFName, pStb->db, sizeof(pRsp->dbFName));
tstrncpy(pRsp->tbName, tbName, sizeof(pRsp->tbName)); tstrncpy(pRsp->tbName, tbName, sizeof(pRsp->tbName));
tstrncpy(pRsp->stbName, tbName, sizeof(pRsp->stbName)); tstrncpy(pRsp->stbName, tbName, sizeof(pRsp->stbName));
@ -2253,6 +2268,7 @@ static int32_t mndBuildStbSchemaImp(SDbObj *pDb, SStbObj *pStb, const char *tbNa
pRsp->tversion = pStb->tagVer; pRsp->tversion = pStb->tagVer;
pRsp->suid = pStb->uid; pRsp->suid = pStb->uid;
pRsp->tuid = pStb->uid; pRsp->tuid = pStb->uid;
pRsp->virtualStb = pStb->virtualStb;
for (int32_t i = 0; i < pStb->numOfColumns; ++i) { for (int32_t i = 0; i < pStb->numOfColumns; ++i) {
SSchema *pSchema = &pRsp->pSchemas[i]; SSchema *pSchema = &pRsp->pSchemas[i];
@ -2350,6 +2366,8 @@ static int32_t mndBuildStbCfgImp(SDbObj *pDb, SStbObj *pStb, const char *tbName,
pSchExt->typeMod = pStb->pExtSchemas[i].typeMod; pSchExt->typeMod = pStb->pExtSchemas[i].typeMod;
} }
} }
pRsp->virtualStb = pStb->virtualStb;
pRsp->pColRefs = NULL;
taosRUnLockLatch(&pStb->lock); taosRUnLockLatch(&pStb->lock);
TAOS_RETURN(code); TAOS_RETURN(code);
@ -3493,6 +3511,10 @@ static int32_t mndRetrieveStb(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBloc
RETRIEVE_CHECK_GOTO(colDataSetVal(pColInfo, numOfRows, (const char *)(&pStb->uid), false), pStb, &lino, _ERROR); RETRIEVE_CHECK_GOTO(colDataSetVal(pColInfo, numOfRows, (const char *)(&pStb->uid), false), pStb, &lino, _ERROR);
} }
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
if (pColInfo) {
RETRIEVE_CHECK_GOTO(colDataSetVal(pColInfo, numOfRows, (const char *)(&pStb->virtualStb), false), pStb, &lino, _ERROR);
}
numOfRows++; numOfRows++;
sdbRelease(pSdb, pStb); sdbRelease(pSdb, pStb);
} }
@ -3573,7 +3595,7 @@ static int32_t buildDbColsInfoBlock(const SSDataBlock *p, const SSysTableMeta *p
pColInfoData = taosArrayGet(p->pDataBlock, 5); pColInfoData = taosArrayGet(p->pDataBlock, 5);
TAOS_CHECK_GOTO(colDataSetVal(pColInfoData, numOfRows, (const char *)&pm->schema[j].bytes, false), &lino, _OVER); TAOS_CHECK_GOTO(colDataSetVal(pColInfoData, numOfRows, (const char *)&pm->schema[j].bytes, false), &lino, _OVER);
for (int32_t k = 6; k <= 8; ++k) { for (int32_t k = 6; k <= 9; ++k) {
pColInfoData = taosArrayGet(p->pDataBlock, k); pColInfoData = taosArrayGet(p->pDataBlock, k);
colDataSetNULL(pColInfoData, numOfRows); colDataSetNULL(pColInfoData, numOfRows);
} }
@ -3581,6 +3603,7 @@ static int32_t buildDbColsInfoBlock(const SSDataBlock *p, const SSysTableMeta *p
numOfRows += 1; numOfRows += 1;
} }
} }
return numOfRows;
_OVER: _OVER:
mError("failed at %s:%d since %s", __FUNCTION__, lino, tstrerror(code)); mError("failed at %s:%d since %s", __FUNCTION__, lino, tstrerror(code));
return numOfRows; return numOfRows;

View File

@ -298,6 +298,8 @@ typedef struct {
int64_t numOfSTables; int64_t numOfSTables;
int64_t numOfCTables; int64_t numOfCTables;
int64_t numOfNTables; int64_t numOfNTables;
int64_t numOfVTables;
int64_t numOfVCTables;
int64_t numOfReportedTimeSeries; int64_t numOfReportedTimeSeries;
int64_t numOfNTimeSeries; int64_t numOfNTimeSeries;
int64_t numOfTimeSeries; int64_t numOfTimeSeries;
@ -348,6 +350,10 @@ struct SVnodeCfg {
#define TABLE_IS_COL_COMPRESSED(FLG) (((FLG) & (TABLE_COL_COMPRESSED)) != 0) #define TABLE_IS_COL_COMPRESSED(FLG) (((FLG) & (TABLE_COL_COMPRESSED)) != 0)
#define TABLE_SET_COL_COMPRESSED(FLG) ((FLG) |= TABLE_COL_COMPRESSED) #define TABLE_SET_COL_COMPRESSED(FLG) ((FLG) |= TABLE_COL_COMPRESSED)
#define TABLE_VIRTUAL ((int8_t)0x4)
#define TABLE_IS_VIRTUAL(FLG) (((FLG) & (TABLE_VIRTUAL)) != 0)
#define TABLE_SET_VIRTUAL(FLG) ((FLG) |= TABLE_VIRTUAL)
struct SFileSetReader; struct SFileSetReader;
int32_t tsdbFileSetReaderOpen(void *pVnode, struct SFileSetReader **ppReader); int32_t tsdbFileSetReaderOpen(void *pVnode, struct SFileSetReader **ppReader);
int32_t tsdbFileSetReaderNext(struct SFileSetReader *pReader); int32_t tsdbFileSetReaderNext(struct SFileSetReader *pReader);

View File

@ -165,6 +165,7 @@ int32_t metaFilterTableName(void* pVnode, SMetaFltParam* param, SArray* pUids);
int32_t metaFilterTtl(void* pVnode, SMetaFltParam* param, SArray* pUids); int32_t metaFilterTtl(void* pVnode, SMetaFltParam* param, SArray* pUids);
int32_t metaGetColCmpr(SMeta* pMeta, tb_uid_t uid, SHashObj** colCmprObj); int32_t metaGetColCmpr(SMeta* pMeta, tb_uid_t uid, SHashObj** colCmprObj);
int32_t updataTableColRef(SColRefWrapper *pWp, const SSchema *pSchema, int8_t add, SColRef *pColRef);
#if !defined(META_REFACT) && !defined(TD_ASTRA) #if !defined(META_REFACT) && !defined(TD_ASTRA)
// SMetaDB // SMetaDB
int metaOpenDB(SMeta* pMeta); int metaOpenDB(SMeta* pMeta);

View File

@ -44,6 +44,25 @@ static int32_t metaEncodeExtSchema(SEncoder* pCoder, const SMetaEntry* pME) {
return 0; return 0;
} }
int meteEncodeColRefEntry(SEncoder *pCoder, const SMetaEntry *pME) {
const SColRefWrapper *pw = &pME->colRef;
TAOS_CHECK_RETURN(tEncodeI32v(pCoder, pw->nCols));
TAOS_CHECK_RETURN(tEncodeI32v(pCoder, pw->version));
uDebug("encode cols:%d", pw->nCols);
for (int32_t i = 0; i < pw->nCols; i++) {
SColRef *p = &pw->pColRef[i];
TAOS_CHECK_RETURN(tEncodeI8(pCoder, p->hasRef));
TAOS_CHECK_RETURN(tEncodeI16v(pCoder, p->id));
if (p->hasRef) {
TAOS_CHECK_RETURN(tEncodeCStr(pCoder, p->refDbName));
TAOS_CHECK_RETURN(tEncodeCStr(pCoder, p->refTableName));
TAOS_CHECK_RETURN(tEncodeCStr(pCoder, p->refColName));
}
}
return 0;
}
static int32_t metaDecodeExtSchemas(SDecoder* pDecoder, SMetaEntry* pME) { static int32_t metaDecodeExtSchemas(SDecoder* pDecoder, SMetaEntry* pME) {
bool hasExtSchema = false; bool hasExtSchema = false;
SSchemaWrapper* pSchWrapper = NULL; SSchemaWrapper* pSchWrapper = NULL;
@ -92,6 +111,62 @@ SExtSchema* metaGetSExtSchema(const SMetaEntry *pME) {
return NULL; return NULL;
} }
int meteDecodeColRefEntry(SDecoder *pDecoder, SMetaEntry *pME) {
SColRefWrapper *pWrapper = &pME->colRef;
TAOS_CHECK_RETURN(tDecodeI32v(pDecoder, &pWrapper->nCols));
if (pWrapper->nCols == 0) {
return 0;
}
TAOS_CHECK_RETURN(tDecodeI32v(pDecoder, &pWrapper->version));
uDebug("decode cols:%d", pWrapper->nCols);
pWrapper->pColRef = (SColRef *)tDecoderMalloc(pDecoder, pWrapper->nCols * sizeof(SColRef));
if (pWrapper->pColRef == NULL) {
return terrno;
}
for (int i = 0; i < pWrapper->nCols; i++) {
SColRef *p = &pWrapper->pColRef[i];
TAOS_CHECK_RETURN(tDecodeI8(pDecoder, (int8_t *)&p->hasRef));
TAOS_CHECK_RETURN(tDecodeI16v(pDecoder, &p->id));
if (p->hasRef) {
TAOS_CHECK_RETURN(tDecodeCStrTo(pDecoder, p->refDbName));
TAOS_CHECK_RETURN(tDecodeCStrTo(pDecoder, p->refTableName));
TAOS_CHECK_RETURN(tDecodeCStrTo(pDecoder, p->refColName));
}
}
return 0;
}
static FORCE_INLINE int32_t metatInitDefaultSColRefWrapper(SDecoder *pDecoder, SColRefWrapper *pRef,
SSchemaWrapper *pSchema) {
pRef->nCols = pSchema->nCols;
if ((pRef->pColRef = (SColRef *)tDecoderMalloc(pDecoder, pRef->nCols * sizeof(SColRef))) == NULL) {
return terrno;
}
for (int32_t i = 0; i < pRef->nCols; i++) {
SColRef *pColRef = &pRef->pColRef[i];
SSchema *pColSchema = &pSchema->pSchema[i];
pColRef->id = pColSchema->colId;
pColRef->hasRef = false;
}
return 0;
}
static int32_t metaCloneColRef(const SColRefWrapper*pSrc, SColRefWrapper *pDst) {
if (pSrc->nCols > 0) {
pDst->nCols = pSrc->nCols;
pDst->version = pSrc->version;
pDst->pColRef = (SColRef*)taosMemoryCalloc(pSrc->nCols, sizeof(SColRef));
if (NULL == pDst->pColRef) {
return terrno;
}
memcpy(pDst->pColRef, pSrc->pColRef, pSrc->nCols * sizeof(SColRef));
}
return 0;
}
int meteEncodeColCmprEntry(SEncoder *pCoder, const SMetaEntry *pME) { int meteEncodeColCmprEntry(SEncoder *pCoder, const SMetaEntry *pME) {
const SColCmprWrapper *pw = &pME->colCmpr; const SColCmprWrapper *pw = &pME->colCmpr;
TAOS_CHECK_RETURN(tEncodeI32v(pCoder, pw->nCols)); TAOS_CHECK_RETURN(tEncodeI32v(pCoder, pw->nCols));
@ -155,6 +230,12 @@ static int32_t metaCloneColCmpr(const SColCmprWrapper *pSrc, SColCmprWrapper *pD
return 0; return 0;
} }
static void metaCloneColRefFree(SColRefWrapper *pColRef) {
if (pColRef) {
taosMemoryFreeClear(pColRef->pColRef);
}
}
static void metaCloneColCmprFree(SColCmprWrapper *pCmpr) { static void metaCloneColCmprFree(SColCmprWrapper *pCmpr) {
if (pCmpr) { if (pCmpr) {
taosMemoryFreeClear(pCmpr->pColCmpr); taosMemoryFreeClear(pCmpr->pColCmpr);
@ -181,7 +262,7 @@ int metaEncodeEntry(SEncoder *pCoder, const SMetaEntry *pME) {
if (TABLE_IS_ROLLUP(pME->flags)) { if (TABLE_IS_ROLLUP(pME->flags)) {
TAOS_CHECK_RETURN(tEncodeSRSmaParam(pCoder, &pME->stbEntry.rsmaParam)); TAOS_CHECK_RETURN(tEncodeSRSmaParam(pCoder, &pME->stbEntry.rsmaParam));
} }
} else if (pME->type == TSDB_CHILD_TABLE) { } else if (pME->type == TSDB_CHILD_TABLE || pME->type == TSDB_VIRTUAL_CHILD_TABLE) {
TAOS_CHECK_RETURN(tEncodeI64(pCoder, pME->ctbEntry.btime)); TAOS_CHECK_RETURN(tEncodeI64(pCoder, pME->ctbEntry.btime));
TAOS_CHECK_RETURN(tEncodeI32(pCoder, pME->ctbEntry.ttlDays)); TAOS_CHECK_RETURN(tEncodeI32(pCoder, pME->ctbEntry.ttlDays));
TAOS_CHECK_RETURN(tEncodeI32v(pCoder, pME->ctbEntry.commentLen)); TAOS_CHECK_RETURN(tEncodeI32v(pCoder, pME->ctbEntry.commentLen));
@ -190,7 +271,7 @@ int metaEncodeEntry(SEncoder *pCoder, const SMetaEntry *pME) {
} }
TAOS_CHECK_RETURN(tEncodeI64(pCoder, pME->ctbEntry.suid)); TAOS_CHECK_RETURN(tEncodeI64(pCoder, pME->ctbEntry.suid));
TAOS_CHECK_RETURN(tEncodeTag(pCoder, (const STag *)pME->ctbEntry.pTags)); TAOS_CHECK_RETURN(tEncodeTag(pCoder, (const STag *)pME->ctbEntry.pTags));
} else if (pME->type == TSDB_NORMAL_TABLE) { } else if (pME->type == TSDB_NORMAL_TABLE || pME->type == TSDB_VIRTUAL_NORMAL_TABLE) {
TAOS_CHECK_RETURN(tEncodeI64(pCoder, pME->ntbEntry.btime)); TAOS_CHECK_RETURN(tEncodeI64(pCoder, pME->ntbEntry.btime));
TAOS_CHECK_RETURN(tEncodeI32(pCoder, pME->ntbEntry.ttlDays)); TAOS_CHECK_RETURN(tEncodeI32(pCoder, pME->ntbEntry.ttlDays));
TAOS_CHECK_RETURN(tEncodeI32v(pCoder, pME->ntbEntry.commentLen)); TAOS_CHECK_RETURN(tEncodeI32v(pCoder, pME->ntbEntry.commentLen));
@ -205,7 +286,11 @@ int metaEncodeEntry(SEncoder *pCoder, const SMetaEntry *pME) {
metaError("meta/entry: invalide table type: %" PRId8 " encode failed.", pME->type); metaError("meta/entry: invalide table type: %" PRId8 " encode failed.", pME->type);
return TSDB_CODE_INVALID_PARA; return TSDB_CODE_INVALID_PARA;
} }
if (pME->type == TSDB_VIRTUAL_NORMAL_TABLE || pME->type == TSDB_VIRTUAL_CHILD_TABLE) {
TAOS_CHECK_RETURN(meteEncodeColRefEntry(pCoder, pME));
} else {
TAOS_CHECK_RETURN(meteEncodeColCmprEntry(pCoder, pME)); TAOS_CHECK_RETURN(meteEncodeColCmprEntry(pCoder, pME));
}
TAOS_CHECK_RETURN(metaEncodeExtSchema(pCoder, pME)); TAOS_CHECK_RETURN(metaEncodeExtSchema(pCoder, pME));
} }
if (pME->type == TSDB_SUPER_TABLE) { if (pME->type == TSDB_SUPER_TABLE) {
@ -237,7 +322,7 @@ int metaDecodeEntryImpl(SDecoder *pCoder, SMetaEntry *pME, bool headerOnly) {
if (TABLE_IS_ROLLUP(pME->flags)) { if (TABLE_IS_ROLLUP(pME->flags)) {
TAOS_CHECK_RETURN(tDecodeSRSmaParam(pCoder, &pME->stbEntry.rsmaParam)); TAOS_CHECK_RETURN(tDecodeSRSmaParam(pCoder, &pME->stbEntry.rsmaParam));
} }
} else if (pME->type == TSDB_CHILD_TABLE) { } else if (pME->type == TSDB_CHILD_TABLE || pME->type == TSDB_VIRTUAL_CHILD_TABLE) {
TAOS_CHECK_RETURN(tDecodeI64(pCoder, &pME->ctbEntry.btime)); TAOS_CHECK_RETURN(tDecodeI64(pCoder, &pME->ctbEntry.btime));
TAOS_CHECK_RETURN(tDecodeI32(pCoder, &pME->ctbEntry.ttlDays)); TAOS_CHECK_RETURN(tDecodeI32(pCoder, &pME->ctbEntry.ttlDays));
TAOS_CHECK_RETURN(tDecodeI32v(pCoder, &pME->ctbEntry.commentLen)); TAOS_CHECK_RETURN(tDecodeI32v(pCoder, &pME->ctbEntry.commentLen));
@ -246,7 +331,7 @@ int metaDecodeEntryImpl(SDecoder *pCoder, SMetaEntry *pME, bool headerOnly) {
} }
TAOS_CHECK_RETURN(tDecodeI64(pCoder, &pME->ctbEntry.suid)); TAOS_CHECK_RETURN(tDecodeI64(pCoder, &pME->ctbEntry.suid));
TAOS_CHECK_RETURN(tDecodeTag(pCoder, (STag **)&pME->ctbEntry.pTags)); TAOS_CHECK_RETURN(tDecodeTag(pCoder, (STag **)&pME->ctbEntry.pTags));
} else if (pME->type == TSDB_NORMAL_TABLE) { } else if (pME->type == TSDB_NORMAL_TABLE || pME->type == TSDB_VIRTUAL_NORMAL_TABLE) {
TAOS_CHECK_RETURN(tDecodeI64(pCoder, &pME->ntbEntry.btime)); TAOS_CHECK_RETURN(tDecodeI64(pCoder, &pME->ntbEntry.btime));
TAOS_CHECK_RETURN(tDecodeI32(pCoder, &pME->ntbEntry.ttlDays)); TAOS_CHECK_RETURN(tDecodeI32(pCoder, &pME->ntbEntry.ttlDays));
TAOS_CHECK_RETURN(tDecodeI32v(pCoder, &pME->ntbEntry.commentLen)); TAOS_CHECK_RETURN(tDecodeI32v(pCoder, &pME->ntbEntry.commentLen));
@ -288,6 +373,16 @@ int metaDecodeEntryImpl(SDecoder *pCoder, SMetaEntry *pME, bool headerOnly) {
TAOS_CHECK_RETURN(metatInitDefaultSColCmprWrapper(pCoder, &pME->colCmpr, &pME->ntbEntry.schemaRow)); TAOS_CHECK_RETURN(metatInitDefaultSColCmprWrapper(pCoder, &pME->colCmpr, &pME->ntbEntry.schemaRow));
} }
TABLE_SET_COL_COMPRESSED(pME->flags); TABLE_SET_COL_COMPRESSED(pME->flags);
} else if (pME->type == TSDB_VIRTUAL_NORMAL_TABLE || pME->type == TSDB_VIRTUAL_CHILD_TABLE) {
if (!tDecodeIsEnd(pCoder)) {
uDebug("set type: %d, tableName:%s", pME->type, pME->name);
TAOS_CHECK_RETURN(meteDecodeColRefEntry(pCoder, pME));
} else {
uDebug("set default type: %d, tableName:%s", pME->type, pME->name);
if (pME->type == TSDB_VIRTUAL_NORMAL_TABLE) {
TAOS_CHECK_RETURN(metatInitDefaultSColRefWrapper(pCoder, &pME->colRef, &pME->ntbEntry.schemaRow));
}
}
} }
if (!tDecodeIsEnd(pCoder)) { if (!tDecodeIsEnd(pCoder)) {
TAOS_CHECK_RETURN(metaDecodeExtSchemas(pCoder, pME)); TAOS_CHECK_RETURN(metaDecodeExtSchemas(pCoder, pME));
@ -342,10 +437,10 @@ void metaCloneEntryFree(SMetaEntry **ppEntry) {
if (TSDB_SUPER_TABLE == (*ppEntry)->type) { if (TSDB_SUPER_TABLE == (*ppEntry)->type) {
metaCloneSchemaFree(&(*ppEntry)->stbEntry.schemaRow); metaCloneSchemaFree(&(*ppEntry)->stbEntry.schemaRow);
metaCloneSchemaFree(&(*ppEntry)->stbEntry.schemaTag); metaCloneSchemaFree(&(*ppEntry)->stbEntry.schemaTag);
} else if (TSDB_CHILD_TABLE == (*ppEntry)->type) { } else if (TSDB_CHILD_TABLE == (*ppEntry)->type || TSDB_VIRTUAL_CHILD_TABLE == (*ppEntry)->type) {
taosMemoryFreeClear((*ppEntry)->ctbEntry.comment); taosMemoryFreeClear((*ppEntry)->ctbEntry.comment);
taosMemoryFreeClear((*ppEntry)->ctbEntry.pTags); taosMemoryFreeClear((*ppEntry)->ctbEntry.pTags);
} else if (TSDB_NORMAL_TABLE == (*ppEntry)->type) { } else if (TSDB_NORMAL_TABLE == (*ppEntry)->type || TSDB_VIRTUAL_NORMAL_TABLE == (*ppEntry)->type) {
metaCloneSchemaFree(&(*ppEntry)->ntbEntry.schemaRow); metaCloneSchemaFree(&(*ppEntry)->ntbEntry.schemaRow);
taosMemoryFreeClear((*ppEntry)->ntbEntry.comment); taosMemoryFreeClear((*ppEntry)->ntbEntry.comment);
} else { } else {
@ -353,6 +448,7 @@ void metaCloneEntryFree(SMetaEntry **ppEntry) {
} }
metaCloneColCmprFree(&(*ppEntry)->colCmpr); metaCloneColCmprFree(&(*ppEntry)->colCmpr);
taosMemoryFreeClear((*ppEntry)->pExtSchemas); taosMemoryFreeClear((*ppEntry)->pExtSchemas);
metaCloneColRefFree(&(*ppEntry)->colRef);
taosMemoryFreeClear(*ppEntry); taosMemoryFreeClear(*ppEntry);
return; return;
@ -402,7 +498,7 @@ int32_t metaCloneEntry(const SMetaEntry *pEntry, SMetaEntry **ppEntry) {
return code; return code;
} }
(*ppEntry)->stbEntry.keep = pEntry->stbEntry.keep; (*ppEntry)->stbEntry.keep = pEntry->stbEntry.keep;
} else if (pEntry->type == TSDB_CHILD_TABLE) { } else if (pEntry->type == TSDB_CHILD_TABLE || pEntry->type == TSDB_VIRTUAL_CHILD_TABLE) {
(*ppEntry)->ctbEntry.btime = pEntry->ctbEntry.btime; (*ppEntry)->ctbEntry.btime = pEntry->ctbEntry.btime;
(*ppEntry)->ctbEntry.ttlDays = pEntry->ctbEntry.ttlDays; (*ppEntry)->ctbEntry.ttlDays = pEntry->ctbEntry.ttlDays;
(*ppEntry)->ctbEntry.suid = pEntry->ctbEntry.suid; (*ppEntry)->ctbEntry.suid = pEntry->ctbEntry.suid;
@ -428,7 +524,7 @@ int32_t metaCloneEntry(const SMetaEntry *pEntry, SMetaEntry **ppEntry) {
return code; return code;
} }
memcpy((*ppEntry)->ctbEntry.pTags, pEntry->ctbEntry.pTags, pTags->len); memcpy((*ppEntry)->ctbEntry.pTags, pEntry->ctbEntry.pTags, pTags->len);
} else if (pEntry->type == TSDB_NORMAL_TABLE) { } else if (pEntry->type == TSDB_NORMAL_TABLE || pEntry->type == TSDB_VIRTUAL_NORMAL_TABLE) {
(*ppEntry)->ntbEntry.btime = pEntry->ntbEntry.btime; (*ppEntry)->ntbEntry.btime = pEntry->ntbEntry.btime;
(*ppEntry)->ntbEntry.ttlDays = pEntry->ntbEntry.ttlDays; (*ppEntry)->ntbEntry.ttlDays = pEntry->ntbEntry.ttlDays;
(*ppEntry)->ntbEntry.ncid = pEntry->ntbEntry.ncid; (*ppEntry)->ntbEntry.ncid = pEntry->ntbEntry.ncid;
@ -455,11 +551,19 @@ int32_t metaCloneEntry(const SMetaEntry *pEntry, SMetaEntry **ppEntry) {
return TSDB_CODE_INVALID_PARA; return TSDB_CODE_INVALID_PARA;
} }
if (pEntry->type == TSDB_VIRTUAL_NORMAL_TABLE || pEntry->type == TSDB_VIRTUAL_CHILD_TABLE) {
code = metaCloneColRef(&pEntry->colRef, &(*ppEntry)->colRef);
if (code) {
metaCloneEntryFree(ppEntry);
return code;
}
} else {
code = metaCloneColCmpr(&pEntry->colCmpr, &(*ppEntry)->colCmpr); code = metaCloneColCmpr(&pEntry->colCmpr, &(*ppEntry)->colCmpr);
if (code) { if (code) {
metaCloneEntryFree(ppEntry); metaCloneEntryFree(ppEntry);
return code; return code;
} }
}
if (pEntry->pExtSchemas && pEntry->colCmpr.nCols > 0) { if (pEntry->pExtSchemas && pEntry->colCmpr.nCols > 0) {
(*ppEntry)->pExtSchemas = taosMemoryCalloc(pEntry->colCmpr.nCols, sizeof(SExtSchema)); (*ppEntry)->pExtSchemas = taosMemoryCalloc(pEntry->colCmpr.nCols, sizeof(SExtSchema));
if (!(*ppEntry)->pExtSchemas) { if (!(*ppEntry)->pExtSchemas) {

View File

@ -218,7 +218,7 @@ static int32_t metaSchemaTableUpsert(SMeta *pMeta, const SMetaHandleParam *pPara
const SSchemaWrapper *pSchema = NULL; const SSchemaWrapper *pSchema = NULL;
if (pEntry->type == TSDB_SUPER_TABLE) { if (pEntry->type == TSDB_SUPER_TABLE) {
pSchema = &pEntry->stbEntry.schemaRow; pSchema = &pEntry->stbEntry.schemaRow;
} else if (pEntry->type == TSDB_NORMAL_TABLE) { } else if (pEntry->type == TSDB_NORMAL_TABLE || pEntry->type == TSDB_VIRTUAL_NORMAL_TABLE) {
pSchema = &pEntry->ntbEntry.schemaRow; pSchema = &pEntry->ntbEntry.schemaRow;
} else { } else {
return TSDB_CODE_INVALID_PARA; return TSDB_CODE_INVALID_PARA;
@ -370,6 +370,88 @@ static int32_t metaAddOrDropTagIndexOfSuperTable(SMeta *pMeta, const SMetaHandle
return code; return code;
} }
static int32_t metaAddOrDropColumnIndexOfVirtualSuperTable(SMeta *pMeta, const SMetaHandleParam *pParam,
const SSchema *pOldColumn, const SSchema *pNewColumn) {
int32_t code = TSDB_CODE_SUCCESS;
const SMetaEntry *pEntry = pParam->pEntry;
const SMetaEntry *pOldEntry = pParam->pOldEntry;
enum { ADD_COLUMN, DROP_COLUMN } action;
if (pOldColumn && pNewColumn) {
return TSDB_CODE_SUCCESS;
} else if (pOldColumn) {
action = DROP_COLUMN;
} else {
action = ADD_COLUMN;
}
// fetch all child tables
SArray *childTables = 0;
code = metaGetChildUidsOfSuperTable(pMeta, pEntry->uid, &childTables);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
return code;
}
// do drop or add index
for (int32_t i = 0; i < taosArrayGetSize(childTables); i++) {
int64_t uid = *(int64_t *)taosArrayGet(childTables, i);
// fetch child entry
SMetaEntry *pChildEntry = NULL;
code = metaFetchEntryByUid(pMeta, uid, &pChildEntry);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
taosArrayDestroy(childTables);
return code;
}
SMetaHandleParam param = {
.pEntry = pChildEntry
};
if (action == ADD_COLUMN) {
code = updataTableColRef(&pChildEntry->colRef, pNewColumn, 1, NULL);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
taosArrayDestroy(childTables);
metaFetchEntryFree(&pChildEntry);
return code;
}
code = metaEntryTableUpdate(pMeta, &param);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
taosArrayDestroy(childTables);
metaFetchEntryFree(&pChildEntry);
return code;
}
} else {
code = updataTableColRef(&pChildEntry->colRef, pOldColumn, 0, NULL);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
taosArrayDestroy(childTables);
metaFetchEntryFree(&pChildEntry);
return code;
}
code = metaEntryTableUpdate(pMeta, &param);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
taosArrayDestroy(childTables);
metaFetchEntryFree(&pChildEntry);
return code;
}
}
metaFetchEntryFree(&pChildEntry);
}
taosArrayDestroy(childTables);
return code;
}
static int32_t metaUpdateSuperTableTagSchema(SMeta *pMeta, const SMetaHandleParam *pParam) { static int32_t metaUpdateSuperTableTagSchema(SMeta *pMeta, const SMetaHandleParam *pParam) {
int32_t code = TSDB_CODE_SUCCESS; int32_t code = TSDB_CODE_SUCCESS;
const SMetaEntry *pEntry = pParam->pEntry; const SMetaEntry *pEntry = pParam->pEntry;
@ -431,6 +513,67 @@ static int32_t metaUpdateSuperTableTagSchema(SMeta *pMeta, const SMetaHandlePara
return code; return code;
} }
static int32_t metaUpdateSuperTableRowSchema(SMeta *pMeta, const SMetaHandleParam *pParam) {
int32_t code = TSDB_CODE_SUCCESS;
const SMetaEntry *pEntry = pParam->pEntry;
const SMetaEntry *pOldEntry = pParam->pOldEntry;
const SSchemaWrapper *pNewRowSchema = &pEntry->stbEntry.schemaRow;
const SSchemaWrapper *pOldRowSchema = &pOldEntry->stbEntry.schemaRow;
int32_t iOld = 0, iNew = 0;
for (; iOld < pOldRowSchema->nCols && iNew < pNewRowSchema->nCols;) {
SSchema *pOldColumn = pOldRowSchema->pSchema + iOld;
SSchema *pNewColumn = pNewRowSchema->pSchema + iNew;
if (pOldColumn->colId == pNewColumn->colId) {
code = metaAddOrDropColumnIndexOfVirtualSuperTable(pMeta, pParam, pOldColumn, pNewColumn);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
return code;
}
iOld++;
iNew++;
} else if (pOldColumn->colId < pNewColumn->colId) {
code = metaAddOrDropColumnIndexOfVirtualSuperTable(pMeta, pParam, pOldColumn, NULL);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
return code;
}
iOld++;
} else {
code = metaAddOrDropColumnIndexOfVirtualSuperTable(pMeta, pParam, NULL, pNewColumn);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
return code;
}
iNew++;
}
}
for (; iOld < pOldRowSchema->nCols; iOld++) {
SSchema *pOldColumn = pOldRowSchema->pSchema + iOld;
code = metaAddOrDropColumnIndexOfVirtualSuperTable(pMeta, pParam, pOldColumn, NULL);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
return code;
}
}
for (; iNew < pNewRowSchema->nCols; iNew++) {
SSchema *pNewColumn = pNewRowSchema->pSchema + iNew;
code = metaAddOrDropColumnIndexOfVirtualSuperTable(pMeta, pParam, NULL, pNewColumn);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
return code;
}
}
return code;
}
static int32_t metaSchemaTableUpdate(SMeta *pMeta, const SMetaHandleParam *pParam) { static int32_t metaSchemaTableUpdate(SMeta *pMeta, const SMetaHandleParam *pParam) {
int32_t code = TSDB_CODE_SUCCESS; int32_t code = TSDB_CODE_SUCCESS;
@ -441,7 +584,7 @@ static int32_t metaSchemaTableUpdate(SMeta *pMeta, const SMetaHandleParam *pPara
return metaSchemaTableUpsert(pMeta, pParam, META_TABLE_OP_UPDATA); return metaSchemaTableUpsert(pMeta, pParam, META_TABLE_OP_UPDATA);
} }
if (pEntry->type == TSDB_NORMAL_TABLE) { if (pEntry->type == TSDB_NORMAL_TABLE || pEntry->type == TSDB_VIRTUAL_NORMAL_TABLE) {
// check row schema // check row schema
if (pOldEntry->ntbEntry.schemaRow.version != pEntry->ntbEntry.schemaRow.version) { if (pOldEntry->ntbEntry.schemaRow.version != pEntry->ntbEntry.schemaRow.version) {
return metaSchemaTableUpsert(pMeta, pParam, META_TABLE_OP_UPDATA); return metaSchemaTableUpsert(pMeta, pParam, META_TABLE_OP_UPDATA);
@ -449,9 +592,14 @@ static int32_t metaSchemaTableUpdate(SMeta *pMeta, const SMetaHandleParam *pPara
} else if (pEntry->type == TSDB_SUPER_TABLE) { } else if (pEntry->type == TSDB_SUPER_TABLE) {
// check row schema // check row schema
if (pOldEntry->stbEntry.schemaRow.version != pEntry->stbEntry.schemaRow.version) { if (pOldEntry->stbEntry.schemaRow.version != pEntry->stbEntry.schemaRow.version) {
if (TABLE_IS_VIRTUAL(pEntry->flags)) {
return metaUpdateSuperTableRowSchema(pMeta, pParam);
} else {
return metaSchemaTableUpsert(pMeta, pParam, META_TABLE_OP_UPDATA); return metaSchemaTableUpsert(pMeta, pParam, META_TABLE_OP_UPDATA);
} }
}
// check tag schema // check tag schema
code = metaUpdateSuperTableTagSchema(pMeta, pParam); code = metaUpdateSuperTableTagSchema(pMeta, pParam);
if (code) { if (code) {
@ -478,10 +626,10 @@ static void metaBuildEntryInfo(const SMetaEntry *pEntry, SMetaInfo *pInfo) {
if (pEntry->type == TSDB_SUPER_TABLE) { if (pEntry->type == TSDB_SUPER_TABLE) {
pInfo->suid = pEntry->uid; pInfo->suid = pEntry->uid;
pInfo->skmVer = pEntry->stbEntry.schemaRow.version; pInfo->skmVer = pEntry->stbEntry.schemaRow.version;
} else if (pEntry->type == TSDB_CHILD_TABLE) { } else if (pEntry->type == TSDB_CHILD_TABLE || pEntry->type == TSDB_VIRTUAL_CHILD_TABLE) {
pInfo->suid = pEntry->ctbEntry.suid; pInfo->suid = pEntry->ctbEntry.suid;
pInfo->skmVer = 0; pInfo->skmVer = 0;
} else if (pEntry->type == TSDB_NORMAL_TABLE) { } else if (pEntry->type == TSDB_NORMAL_TABLE || pEntry->type == TSDB_VIRTUAL_NORMAL_TABLE) {
pInfo->suid = 0; pInfo->suid = 0;
pInfo->skmVer = pEntry->ntbEntry.schemaRow.version; pInfo->skmVer = pEntry->ntbEntry.schemaRow.version;
} }
@ -877,9 +1025,9 @@ static int32_t metaBtimeIdxUpsert(SMeta *pMeta, const SMetaHandleParam *pParam,
.uid = pEntry->uid, .uid = pEntry->uid,
}; };
if (TSDB_CHILD_TABLE == pEntry->type) { if (TSDB_CHILD_TABLE == pEntry->type || TSDB_VIRTUAL_CHILD_TABLE == pEntry->type) {
key.btime = pEntry->ctbEntry.btime; key.btime = pEntry->ctbEntry.btime;
} else if (TSDB_NORMAL_TABLE == pEntry->type) { } else if (TSDB_NORMAL_TABLE == pEntry->type || TSDB_VIRTUAL_NORMAL_TABLE == pEntry->type) {
key.btime = pEntry->ntbEntry.btime; key.btime = pEntry->ntbEntry.btime;
} else { } else {
return TSDB_CODE_INVALID_PARA; return TSDB_CODE_INVALID_PARA;
@ -1249,6 +1397,121 @@ static int32_t metaHandleChildTableCreate(SMeta *pMeta, const SMetaEntry *pEntry
return code; return code;
} }
static int32_t metaHandleVirtualNormalTableCreateImpl(SMeta *pMeta, const SMetaEntry *pEntry) {
int32_t code = TSDB_CODE_SUCCESS;
SMetaTableOp ops[] = {
{META_ENTRY_TABLE, META_TABLE_OP_INSERT}, //
{META_SCHEMA_TABLE, META_TABLE_OP_UPDATA}, // TODO: need to be insert
{META_UID_IDX, META_TABLE_OP_INSERT}, //
{META_NAME_IDX, META_TABLE_OP_INSERT}, //
{META_BTIME_IDX, META_TABLE_OP_INSERT}, //
};
for (int i = 0; i < sizeof(ops) / sizeof(ops[0]); i++) {
SMetaTableOp *op = &ops[i];
SMetaHandleParam param = {
.pEntry = pEntry,
};
code = metaTableOpFn[op->table][op->op](pMeta, &param);
if (TSDB_CODE_SUCCESS != code) {
metaErr(TD_VID(pMeta->pVnode), code);
return code;
}
}
return code;
}
static int32_t metaHandleVirtualNormalTableCreate(SMeta *pMeta, const SMetaEntry *pEntry) {
int32_t code = TSDB_CODE_SUCCESS;
// update TDB
metaWLock(pMeta);
code = metaHandleVirtualNormalTableCreateImpl(pMeta, pEntry);
metaULock(pMeta);
// update other stuff
if (TSDB_CODE_SUCCESS == code) {
pMeta->pVnode->config.vndStats.numOfVTables++;
} else {
metaErr(TD_VID(pMeta->pVnode), code);
}
return code;
}
static int32_t metaHandleVirtualChildTableCreateImpl(SMeta *pMeta, const SMetaEntry *pEntry, const SMetaEntry *pSuperEntry) {
int32_t code = TSDB_CODE_SUCCESS;
SMetaTableOp ops[] = {
{META_ENTRY_TABLE, META_TABLE_OP_INSERT}, //
{META_UID_IDX, META_TABLE_OP_INSERT}, //
{META_NAME_IDX, META_TABLE_OP_INSERT}, //
{META_CHILD_IDX, META_TABLE_OP_INSERT}, //
{META_TAG_IDX, META_TABLE_OP_INSERT}, //
{META_BTIME_IDX, META_TABLE_OP_INSERT}, //
};
for (int i = 0; i < sizeof(ops) / sizeof(ops[0]); i++) {
SMetaTableOp *op = &ops[i];
SMetaHandleParam param = {
.pEntry = pEntry,
.pSuperEntry = pSuperEntry,
};
code = metaTableOpFn[op->table][op->op](pMeta, &param);
if (TSDB_CODE_SUCCESS != code) {
metaErr(TD_VID(pMeta->pVnode), code);
return code;
}
}
if (TSDB_CODE_SUCCESS == code) {
metaUpdateStbStats(pMeta, pSuperEntry->uid, 1, 0, -1);
int32_t ret = metaUidCacheClear(pMeta, pSuperEntry->uid);
if (ret < 0) {
metaErr(TD_VID(pMeta->pVnode), ret);
}
ret = metaTbGroupCacheClear(pMeta, pSuperEntry->uid);
if (ret < 0) {
metaErr(TD_VID(pMeta->pVnode), ret);
}
}
return code;
}
static int32_t metaHandleVirtualChildTableCreate(SMeta *pMeta, const SMetaEntry *pEntry) {
int32_t code = TSDB_CODE_SUCCESS;
SMetaEntry *pSuperEntry = NULL;
// get the super table entry
code = metaFetchEntryByUid(pMeta, pEntry->ctbEntry.suid, &pSuperEntry);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
return code;
}
// update TDB
metaWLock(pMeta);
code = metaHandleVirtualChildTableCreateImpl(pMeta, pEntry, pSuperEntry);
metaULock(pMeta);
// update other stuff
if (TSDB_CODE_SUCCESS == code) {
pMeta->pVnode->config.vndStats.numOfVCTables++;
} else {
metaErr(TD_VID(pMeta->pVnode), code);
}
metaFetchEntryFree(&pSuperEntry);
return code;
}
static int32_t metaHandleNormalTableDropImpl(SMeta *pMeta, SMetaHandleParam *pParam) { static int32_t metaHandleNormalTableDropImpl(SMeta *pMeta, SMetaHandleParam *pParam) {
int32_t code = TSDB_CODE_SUCCESS; int32_t code = TSDB_CODE_SUCCESS;
@ -1439,6 +1702,165 @@ static int32_t metaHandleChildTableDrop(SMeta *pMeta, const SMetaEntry *pEntry,
return code; return code;
} }
static int32_t metaHandleVirtualNormalTableDropImpl(SMeta *pMeta, SMetaHandleParam *pParam) {
int32_t code = TSDB_CODE_SUCCESS;
SMetaTableOp ops[] = {
{META_ENTRY_TABLE, META_TABLE_OP_DELETE}, //
{META_UID_IDX, META_TABLE_OP_DELETE}, //
{META_NAME_IDX, META_TABLE_OP_DELETE}, //
{META_BTIME_IDX, META_TABLE_OP_DELETE}, //
// {META_SCHEMA_TABLE, META_TABLE_OP_DELETE}, //
};
for (int32_t i = 0; i < sizeof(ops) / sizeof(ops[0]); i++) {
SMetaTableOp *op = &ops[i];
code = metaTableOpFn[op->table][op->op](pMeta, pParam);
if (code) {
const SMetaEntry *pEntry = pParam->pEntry;
metaErr(TD_VID(pMeta->pVnode), code);
}
}
return code;
}
static int32_t metaHandleVirtualNormalTableDrop(SMeta *pMeta, const SMetaEntry *pEntry) {
int32_t code = TSDB_CODE_SUCCESS;
SMetaEntry *pOldEntry = NULL;
// fetch the entry
code = metaFetchEntryByUid(pMeta, pEntry->uid, &pOldEntry);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
return code;
}
SMetaHandleParam param = {
.pEntry = pEntry,
.pOldEntry = pOldEntry,
};
// do the drop
metaWLock(pMeta);
code = metaHandleVirtualNormalTableDropImpl(pMeta, &param);
metaULock(pMeta);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
metaFetchEntryFree(&pOldEntry);
return code;
}
// update other stuff
pMeta->pVnode->config.vndStats.numOfVTables--;
#if 0
if (tbUids) {
if (taosArrayPush(tbUids, &uid) == NULL) {
rc = terrno;
goto _exit;
}
}
#endif
if (!TSDB_CACHE_NO(pMeta->pVnode->config)) {
int32_t ret = tsdbCacheDropTable(pMeta->pVnode->pTsdb, pOldEntry->uid, 0, NULL);
if (ret < 0) {
metaErr(TD_VID(pMeta->pVnode), ret);
}
}
metaFetchEntryFree(&pOldEntry);
return code;
}
static int32_t metaHandleVirtualChildTableDropImpl(SMeta *pMeta, const SMetaHandleParam *pParam, bool superDropped) {
int32_t code = TSDB_CODE_SUCCESS;
const SMetaEntry *pEntry = pParam->pEntry;
const SMetaEntry *pChild = pParam->pOldEntry;
const SMetaEntry *pSuper = pParam->pSuperEntry;
SMetaTableOp ops[] = {
{META_ENTRY_TABLE, META_TABLE_OP_DELETE}, //
{META_UID_IDX, META_TABLE_OP_DELETE}, //
{META_NAME_IDX, META_TABLE_OP_DELETE}, //
{META_CHILD_IDX, META_TABLE_OP_DELETE}, //
{META_TAG_IDX, META_TABLE_OP_DELETE}, //
{META_BTIME_IDX, META_TABLE_OP_DELETE}, //
};
for (int i = 0; i < sizeof(ops) / sizeof(ops[0]); i++) {
SMetaTableOp *op = &ops[i];
if (op->table == META_ENTRY_TABLE && superDropped) {
continue;
}
code = metaTableOpFn[op->table][op->op](pMeta, pParam);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
return code;
}
}
--pMeta->pVnode->config.vndStats.numOfVCTables;
metaUpdateStbStats(pMeta, pParam->pSuperEntry->uid, -1, 0, -1);
int32_t ret = metaUidCacheClear(pMeta, pSuper->uid);
if (ret < 0) {
metaErr(TD_VID(pMeta->pVnode), ret);
}
ret = metaTbGroupCacheClear(pMeta, pSuper->uid);
if (ret < 0) {
metaErr(TD_VID(pMeta->pVnode), ret);
}
return code;
}
static int32_t metaHandleVirtualChildTableDrop(SMeta *pMeta, const SMetaEntry *pEntry, bool superDropped) {
int32_t code = TSDB_CODE_SUCCESS;
SMetaEntry *pChild = NULL;
SMetaEntry *pSuper = NULL;
// fetch old entry
code = metaFetchEntryByUid(pMeta, pEntry->uid, &pChild);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
return code;
}
// fetch super entry
code = metaFetchEntryByUid(pMeta, pChild->ctbEntry.suid, &pSuper);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
metaFetchEntryFree(&pChild);
return code;
}
SMetaHandleParam param = {
.pEntry = pEntry,
.pOldEntry = pChild,
.pSuperEntry = pSuper,
};
// do the drop
metaWLock(pMeta);
code = metaHandleVirtualChildTableDropImpl(pMeta, &param, superDropped);
metaULock(pMeta);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
metaFetchEntryFree(&pChild);
metaFetchEntryFree(&pSuper);
return code;
}
metaFetchEntryFree(&pChild);
metaFetchEntryFree(&pSuper);
return code;
}
static int32_t metaGetChildUidsOfSuperTable(SMeta *pMeta, tb_uid_t suid, SArray **childList) { static int32_t metaGetChildUidsOfSuperTable(SMeta *pMeta, tb_uid_t suid, SArray **childList) {
int32_t code = TSDB_CODE_SUCCESS; int32_t code = TSDB_CODE_SUCCESS;
void *key = NULL; void *key = NULL;
@ -1551,6 +1973,65 @@ static int32_t metaHandleNormalTableUpdateImpl(SMeta *pMeta, const SMetaHandlePa
return code; return code;
} }
static int32_t metaHandleVirtualNormalTableUpdateImpl(SMeta *pMeta, const SMetaHandleParam *pParam) {
int32_t code = TSDB_CODE_SUCCESS;
const SMetaEntry *pEntry = pParam->pEntry;
SMetaTableOp ops[] = {
{META_ENTRY_TABLE, META_TABLE_OP_UPDATA}, //
{META_SCHEMA_TABLE, META_TABLE_OP_UPDATA}, //
{META_UID_IDX, META_TABLE_OP_UPDATA}, //
};
for (int32_t i = 0; i < sizeof(ops) / sizeof(ops[0]); i++) {
SMetaTableOp *op = &ops[i];
code = metaTableOpFn[op->table][op->op](pMeta, pParam);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
return code;
}
}
#if 0
if (metaUpdateChangeTime(pMeta, entry.uid, pAlterTbReq->ctimeMs) < 0) {
metaError("vgId:%d, failed to update change time:%s uid:%" PRId64, TD_VID(pMeta->pVnode), entry.name, entry.uid);
}
#endif
return code;
}
static int32_t metaHandleVirtualChildTableUpdateImpl(SMeta *pMeta, const SMetaHandleParam *pParam) {
int32_t code = TSDB_CODE_SUCCESS;
const SMetaEntry *pEntry = pParam->pEntry;
const SMetaEntry *pOldEntry = pParam->pOldEntry;
const SMetaEntry *pSuperEntry = pParam->pSuperEntry;
SMetaTableOp ops[] = {
{META_ENTRY_TABLE, META_TABLE_OP_UPDATA}, //
{META_UID_IDX, META_TABLE_OP_UPDATA}, //
{META_TAG_IDX, META_TABLE_OP_UPDATA}, //
{META_CHILD_IDX, META_TABLE_OP_UPDATA}, //
};
for (int i = 0; i < sizeof(ops) / sizeof(ops[0]); i++) {
SMetaTableOp *op = &ops[i];
code = metaTableOpFn[op->table][op->op](pMeta, pParam);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
return code;
}
}
if (metaUidCacheClear(pMeta, pSuperEntry->uid) < 0) {
metaErr(TD_VID(pMeta->pVnode), code);
}
if (metaTbGroupCacheClear(pMeta, pSuperEntry->uid) < 0) {
metaErr(TD_VID(pMeta->pVnode), code);
}
return code;
}
static int32_t metaHandleChildTableUpdateImpl(SMeta *pMeta, const SMetaHandleParam *pParam) { static int32_t metaHandleChildTableUpdateImpl(SMeta *pMeta, const SMetaHandleParam *pParam) {
int32_t code = TSDB_CODE_SUCCESS; int32_t code = TSDB_CODE_SUCCESS;
@ -1809,6 +2290,76 @@ static int32_t metaHandleNormalTableUpdate(SMeta *pMeta, const SMetaEntry *pEntr
return code; return code;
} }
static int32_t metaHandleVirtualNormalTableUpdate(SMeta *pMeta, const SMetaEntry *pEntry) {
int32_t code = TSDB_CODE_SUCCESS;
SMetaEntry *pOldEntry = NULL;
// fetch old entry
code = metaFetchEntryByUid(pMeta, pEntry->uid, &pOldEntry);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
return code;
}
// handle update
SMetaHandleParam param = {
.pEntry = pEntry,
.pOldEntry = pOldEntry,
};
metaWLock(pMeta);
code = metaHandleVirtualNormalTableUpdateImpl(pMeta, &param);
metaULock(pMeta);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
metaFetchEntryFree(&pOldEntry);
return code;
}
metaTimeSeriesNotifyCheck(pMeta);
metaFetchEntryFree(&pOldEntry);
return code;
}
static int32_t metaHandleVirtualChildTableUpdate(SMeta *pMeta, const SMetaEntry *pEntry) {
int32_t code = TSDB_CODE_SUCCESS;
SMetaEntry *pOldEntry = NULL;
SMetaEntry *pSuperEntry = NULL;
code = metaFetchEntryByUid(pMeta, pEntry->uid, &pOldEntry);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
return code;
}
code = metaFetchEntryByUid(pMeta, pEntry->ctbEntry.suid, &pSuperEntry);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
metaFetchEntryFree(&pOldEntry);
return code;
}
SMetaHandleParam param = {
.pEntry = pEntry,
.pOldEntry = pOldEntry,
.pSuperEntry = pSuperEntry,
};
metaWLock(pMeta);
code = metaHandleVirtualChildTableUpdateImpl(pMeta, &param);
metaULock(pMeta);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
metaFetchEntryFree(&pOldEntry);
metaFetchEntryFree(&pSuperEntry);
return code;
}
metaFetchEntryFree(&pOldEntry);
metaFetchEntryFree(&pSuperEntry);
return code;
}
static int32_t metaHandleSuperTableDrop(SMeta *pMeta, const SMetaEntry *pEntry) { static int32_t metaHandleSuperTableDrop(SMeta *pMeta, const SMetaEntry *pEntry) {
int32_t code = TSDB_CODE_SUCCESS; int32_t code = TSDB_CODE_SUCCESS;
SArray *childList = NULL; SArray *childList = NULL;
@ -1912,6 +2463,22 @@ int32_t metaHandleEntry2(SMeta *pMeta, const SMetaEntry *pEntry) {
} }
break; break;
} }
case TSDB_VIRTUAL_NORMAL_TABLE: {
if (isExist) {
code = metaHandleVirtualNormalTableUpdate(pMeta, pEntry);
} else {
code = metaHandleVirtualNormalTableCreate(pMeta, pEntry);
}
break;
}
case TSDB_VIRTUAL_CHILD_TABLE: {
if (isExist) {
code = metaHandleVirtualChildTableUpdate(pMeta, pEntry);
} else {
code = metaHandleVirtualChildTableCreate(pMeta, pEntry);
}
break;
}
default: { default: {
code = TSDB_CODE_INVALID_PARA; code = TSDB_CODE_INVALID_PARA;
break; break;
@ -1931,6 +2498,14 @@ int32_t metaHandleEntry2(SMeta *pMeta, const SMetaEntry *pEntry) {
code = metaHandleNormalTableDrop(pMeta, pEntry); code = metaHandleNormalTableDrop(pMeta, pEntry);
break; break;
} }
case TSDB_VIRTUAL_NORMAL_TABLE: {
code = metaHandleVirtualNormalTableDrop(pMeta, pEntry);
break;
}
case TSDB_VIRTUAL_CHILD_TABLE: {
code = metaHandleVirtualChildTableDrop(pMeta, pEntry, false);
break;
}
default: { default: {
code = TSDB_CODE_INVALID_PARA; code = TSDB_CODE_INVALID_PARA;
break; break;

View File

@ -25,7 +25,8 @@ int32_t metaUpdateTableTagValue(SMeta *pMeta, int64_t version, SVAlterTbReq *pRe
int32_t metaUpdateTableMultiTagValue(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq); int32_t metaUpdateTableMultiTagValue(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq);
int32_t metaUpdateTableOptions2(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq); int32_t metaUpdateTableOptions2(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq);
int32_t metaUpdateTableColCompress2(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq); int32_t metaUpdateTableColCompress2(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq);
int32_t metaAlterTableColumnRef(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq, STableMetaRsp *pRsp);
int32_t metaRemoveTableColumnRef(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq, STableMetaRsp *pRsp);
int32_t metaSaveJsonVarToIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry, const SSchema *pSchema); int32_t metaSaveJsonVarToIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry, const SSchema *pSchema);
int32_t metaDelJsonVarFromIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry, const SSchema *pSchema); int32_t metaDelJsonVarFromIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry, const SSchema *pSchema);
@ -103,6 +104,49 @@ int32_t dropTableExtSchema(SMetaEntry *pEntry, int32_t dropColId, int32_t newCol
return 0; return 0;
} }
int32_t updataTableColRef(SColRefWrapper *pWp, const SSchema *pSchema, int8_t add, SColRef *pColRef) {
int32_t nCols = pWp->nCols;
int32_t ver = pWp->version;
if (add) {
SColRef *p = taosMemoryRealloc(pWp->pColRef, sizeof(SColRef) * (nCols + 1));
if (p == NULL) {
return terrno;
}
pWp->pColRef = p;
SColRef *pCol = p + nCols;
if (NULL == pColRef) {
pCol->hasRef = false;
pCol->id = pSchema->colId;
} else {
pCol->hasRef = pColRef->hasRef;
pCol->id = pSchema->colId;
if (pCol->hasRef) {
tstrncpy(pCol->refDbName, pColRef->refDbName, TSDB_DB_NAME_LEN);
tstrncpy(pCol->refTableName, pColRef->refTableName, TSDB_TABLE_NAME_LEN);
tstrncpy(pCol->refColName, pColRef->refColName, TSDB_COL_NAME_LEN);
}
}
pWp->nCols = nCols + 1;
pWp->version = ver;
} else {
for (int32_t i = 0; i < nCols; i++) {
SColRef *pOColRef = &pWp->pColRef[i];
if (pOColRef->id == pSchema->colId) {
int32_t left = (nCols - i - 1) * sizeof(SColRef);
if (left) {
memmove(pWp->pColRef + i, pWp->pColRef + i + 1, left);
}
nCols--;
break;
}
}
pWp->nCols = nCols;
pWp->version = ver;
}
return 0;
}
int metaUpdateMetaRsp(tb_uid_t uid, char *tbName, SSchemaWrapper *pSchema, STableMetaRsp *pMetaRsp) { int metaUpdateMetaRsp(tb_uid_t uid, char *tbName, SSchemaWrapper *pSchema, STableMetaRsp *pMetaRsp) {
pMetaRsp->pSchemas = taosMemoryMalloc(pSchema->nCols * sizeof(SSchema)); pMetaRsp->pSchemas = taosMemoryMalloc(pSchema->nCols * sizeof(SSchema));
if (NULL == pMetaRsp->pSchemas) { if (NULL == pMetaRsp->pSchemas) {
@ -120,12 +164,56 @@ int metaUpdateMetaRsp(tb_uid_t uid, char *tbName, SSchemaWrapper *pSchema, STabl
pMetaRsp->tableType = TSDB_NORMAL_TABLE; pMetaRsp->tableType = TSDB_NORMAL_TABLE;
pMetaRsp->sversion = pSchema->version; pMetaRsp->sversion = pSchema->version;
pMetaRsp->tuid = uid; pMetaRsp->tuid = uid;
pMetaRsp->virtualStb = false; // super table will never be processed here
memcpy(pMetaRsp->pSchemas, pSchema->pSchema, pSchema->nCols * sizeof(SSchema)); memcpy(pMetaRsp->pSchemas, pSchema->pSchema, pSchema->nCols * sizeof(SSchema));
return 0; return 0;
} }
int32_t metaUpdateVtbMetaRsp(tb_uid_t uid, char *tbName, SSchemaWrapper *pSchema, SColRefWrapper *pRef,
STableMetaRsp *pMetaRsp, int8_t tableType) {
int32_t code = TSDB_CODE_SUCCESS;
if (!pRef) {
return TSDB_CODE_INVALID_PARA;
}
if (pSchema) {
pMetaRsp->pSchemas = taosMemoryMalloc(pSchema->nCols * sizeof(SSchema));
if (NULL == pMetaRsp->pSchemas) {
code = terrno;
goto _return;
}
pMetaRsp->pSchemaExt = taosMemoryMalloc(pSchema->nCols * sizeof(SSchemaExt));
if (pMetaRsp->pSchemaExt == NULL) {
code = terrno;
goto _return;
}
pMetaRsp->numOfColumns = pSchema->nCols;
pMetaRsp->sversion = pSchema->version;
memcpy(pMetaRsp->pSchemas, pSchema->pSchema, pSchema->nCols * sizeof(SSchema));
}
pMetaRsp->pColRefs = taosMemoryMalloc(pRef->nCols * sizeof(SColRef));
if (NULL == pMetaRsp->pColRefs) {
code = terrno;
goto _return;
}
memcpy(pMetaRsp->pColRefs, pRef->pColRef, pRef->nCols * sizeof(SColRef));
tstrncpy(pMetaRsp->tbName, tbName, TSDB_TABLE_NAME_LEN);
pMetaRsp->tuid = uid;
pMetaRsp->tableType = tableType;
pMetaRsp->virtualStb = false; // super table will never be processed here
pMetaRsp->numOfColRefs = pRef->nCols;
return code;
_return:
taosMemoryFreeClear(pMetaRsp->pSchemaExt);
taosMemoryFreeClear(pMetaRsp->pSchemas);
taosMemoryFreeClear(pMetaRsp->pColRefs);
return code;
}
int metaSaveJsonVarToIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry, const SSchema *pSchema) { int metaSaveJsonVarToIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry, const SSchema *pSchema) {
int32_t code = 0; int32_t code = 0;
@ -390,7 +478,7 @@ static int32_t metaFilterTableByHash(SMeta *pMeta, SArray *uidList) {
char tbFName[TSDB_TABLE_FNAME_LEN + 1]; char tbFName[TSDB_TABLE_FNAME_LEN + 1];
snprintf(tbFName, sizeof(tbFName), "%s.%s", pMeta->pVnode->config.dbname, me.name); snprintf(tbFName, sizeof(tbFName), "%s.%s", pMeta->pVnode->config.dbname, me.name);
tbFName[TSDB_TABLE_FNAME_LEN] = '\0'; tbFName[TSDB_TABLE_FNAME_LEN] = '\0';
int32_t ret = vnodeValidateTableHash(pMeta->pVnode, tbFName); ret = vnodeValidateTableHash(pMeta->pVnode, tbFName);
if (ret < 0 && terrno == TSDB_CODE_VND_HASH_MISMATCH) { if (ret < 0 && terrno == TSDB_CODE_VND_HASH_MISMATCH) {
if (taosArrayPush(uidList, &me.uid) == NULL) { if (taosArrayPush(uidList, &me.uid) == NULL) {
code = terrno; code = terrno;
@ -531,7 +619,7 @@ static int metaDropTableByUid(SMeta *pMeta, tb_uid_t uid, int *type, tb_uid_t *p
SMetaEntry stbEntry = {0}; SMetaEntry stbEntry = {0};
tDecoderInit(&tdc, tData, tLen); tDecoderInit(&tdc, tData, tLen);
int32_t ret = metaDecodeEntry(&tdc, &stbEntry); ret = metaDecodeEntry(&tdc, &stbEntry);
if (ret < 0) { if (ret < 0) {
tDecoderClear(&tdc); tDecoderClear(&tdc);
metaError("vgId:%d, failed to decode child table:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), e.name, metaError("vgId:%d, failed to decode child table:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), e.name,
@ -709,6 +797,7 @@ int metaAlterTable(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq, STableMeta
switch (pReq->action) { switch (pReq->action) {
case TSDB_ALTER_TABLE_ADD_COLUMN: case TSDB_ALTER_TABLE_ADD_COLUMN:
case TSDB_ALTER_TABLE_ADD_COLUMN_WITH_COMPRESS_OPTION: case TSDB_ALTER_TABLE_ADD_COLUMN_WITH_COMPRESS_OPTION:
case TSDB_ALTER_TABLE_ADD_COLUMN_WITH_COLUMN_REF:
return metaAddTableColumn(pMeta, version, pReq, pMetaRsp); return metaAddTableColumn(pMeta, version, pReq, pMetaRsp);
case TSDB_ALTER_TABLE_DROP_COLUMN: case TSDB_ALTER_TABLE_DROP_COLUMN:
return metaDropTableColumn(pMeta, version, pReq, pMetaRsp); return metaDropTableColumn(pMeta, version, pReq, pMetaRsp);
@ -724,6 +813,10 @@ int metaAlterTable(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq, STableMeta
return metaUpdateTableOptions2(pMeta, version, pReq); return metaUpdateTableOptions2(pMeta, version, pReq);
case TSDB_ALTER_TABLE_UPDATE_COLUMN_COMPRESS: case TSDB_ALTER_TABLE_UPDATE_COLUMN_COMPRESS:
return metaUpdateTableColCompress2(pMeta, version, pReq); return metaUpdateTableColCompress2(pMeta, version, pReq);
case TSDB_ALTER_TABLE_ALTER_COLUMN_REF:
return metaAlterTableColumnRef(pMeta, version, pReq, pMetaRsp);
case TSDB_ALTER_TABLE_REMOVE_COLUMN_REF:
return metaRemoveTableColumnRef(pMeta, version, pReq, pMetaRsp);
default: default:
return terrno = TSDB_CODE_VND_INVALID_TABLE_ACTION; return terrno = TSDB_CODE_VND_INVALID_TABLE_ACTION;
break; break;

View File

@ -17,6 +17,8 @@
extern int32_t metaHandleEntry2(SMeta *pMeta, const SMetaEntry *pEntry); extern int32_t metaHandleEntry2(SMeta *pMeta, const SMetaEntry *pEntry);
extern int32_t metaUpdateMetaRsp(tb_uid_t uid, char *tbName, SSchemaWrapper *pSchema, STableMetaRsp *pMetaRsp); extern int32_t metaUpdateMetaRsp(tb_uid_t uid, char *tbName, SSchemaWrapper *pSchema, STableMetaRsp *pMetaRsp);
extern int32_t metaUpdateVtbMetaRsp(tb_uid_t uid, char *tbName, SSchemaWrapper *pSchema, SColRefWrapper *pRef,
STableMetaRsp *pMetaRsp, int8_t tableType);
extern int32_t metaFetchEntryByUid(SMeta *pMeta, int64_t uid, SMetaEntry **ppEntry); extern int32_t metaFetchEntryByUid(SMeta *pMeta, int64_t uid, SMetaEntry **ppEntry);
extern int32_t metaFetchEntryByName(SMeta *pMeta, const char *name, SMetaEntry **ppEntry); extern int32_t metaFetchEntryByName(SMeta *pMeta, const char *name, SMetaEntry **ppEntry);
extern void metaFetchEntryFree(SMetaEntry **ppEntry); extern void metaFetchEntryFree(SMetaEntry **ppEntry);
@ -192,8 +194,13 @@ int32_t metaCreateSuperTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq
TABLE_SET_COL_COMPRESSED(entry.flags); TABLE_SET_COL_COMPRESSED(entry.flags);
entry.colCmpr = pReq->colCmpr; entry.colCmpr = pReq->colCmpr;
} }
entry.pExtSchemas = pReq->pExtSchemas; entry.pExtSchemas = pReq->pExtSchemas;
if (pReq->virtualStb) {
TABLE_SET_VIRTUAL(entry.flags);
}
code = metaHandleEntry2(pMeta, &entry); code = metaHandleEntry2(pMeta, &entry);
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
metaInfo("vgId:%d, super table %s suid:%" PRId64 " is created, version:%" PRId64, TD_VID(pMeta->pVnode), pReq->name, metaInfo("vgId:%d, super table %s suid:%" PRId64 " is created, version:%" PRId64, TD_VID(pMeta->pVnode), pReq->name,
@ -495,6 +502,141 @@ static int32_t metaCreateNormalTable(SMeta *pMeta, int64_t version, SVCreateTbRe
TAOS_RETURN(code); TAOS_RETURN(code);
} }
static int32_t metaBuildCreateVirtualNormalTableRsp(SMeta *pMeta, SMetaEntry *pEntry, STableMetaRsp **ppRsp) {
int32_t code = TSDB_CODE_SUCCESS;
if (NULL == ppRsp) {
return code;
}
*ppRsp = taosMemoryCalloc(1, sizeof(STableMetaRsp));
if (NULL == *ppRsp) {
return terrno;
}
code = metaUpdateVtbMetaRsp(pEntry->uid, pEntry->name, &pEntry->ntbEntry.schemaRow, &pEntry->colRef, *ppRsp, TSDB_VIRTUAL_NORMAL_TABLE);
if (code) {
taosMemoryFreeClear(*ppRsp);
return code;
}
return code;
}
static int32_t metaCreateVirtualNormalTable(SMeta *pMeta, int64_t version, SVCreateTbReq *pReq, STableMetaRsp **ppRsp) {
// check request
int32_t code = metaCheckCreateNormalTableReq(pMeta, version, pReq);
if (code) {
if (TSDB_CODE_TDB_TABLE_ALREADY_EXIST != code) {
metaError("vgId:%d, %s failed at %s:%d since %s, version:%" PRId64 " name:%s", TD_VID(pMeta->pVnode), __func__,
__FILE__, __LINE__, tstrerror(code), version, pReq->name);
}
TAOS_RETURN(code);
}
SMetaEntry entry = {
.version = version,
.type = TSDB_VIRTUAL_NORMAL_TABLE,
.uid = pReq->uid,
.name = pReq->name,
.ntbEntry.btime = pReq->btime,
.ntbEntry.ttlDays = pReq->ttl,
.ntbEntry.commentLen = pReq->commentLen,
.ntbEntry.comment = pReq->comment,
.ntbEntry.schemaRow = pReq->ntb.schemaRow,
.ntbEntry.ncid = pReq->ntb.schemaRow.pSchema[pReq->ntb.schemaRow.nCols - 1].colId + 1,
.colRef = pReq->colRef
};
code = metaBuildCreateVirtualNormalTableRsp(pMeta, &entry, ppRsp);
if (code) {
metaError("vgId:%d, %s failed at %s:%d since %s", TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__,
tstrerror(code));
}
// handle entry
code = metaHandleEntry2(pMeta, &entry);
if (TSDB_CODE_SUCCESS == code) {
metaInfo("vgId:%d, normal table:%s uid %" PRId64 " is created, version:%" PRId64, TD_VID(pMeta->pVnode), pReq->name,
pReq->uid, version);
} else {
metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
__func__, __FILE__, __LINE__, tstrerror(code), pReq->uid, pReq->name, version);
}
TAOS_RETURN(code);
#if 0
metaTimeSeriesNotifyCheck(pMeta);
#endif
}
static int32_t metaBuildCreateVirtualChildTableRsp(SMeta *pMeta, SMetaEntry *pEntry, STableMetaRsp **ppRsp) {
int32_t code = TSDB_CODE_SUCCESS;
if (NULL == ppRsp) {
return code;
}
*ppRsp = taosMemoryCalloc(1, sizeof(STableMetaRsp));
if (NULL == *ppRsp) {
return terrno;
}
code = metaUpdateVtbMetaRsp(pEntry->uid, pEntry->name, NULL, &pEntry->colRef, *ppRsp, TSDB_VIRTUAL_CHILD_TABLE);
if (code) {
taosMemoryFreeClear(*ppRsp);
return code;
}
(*ppRsp)->suid = pEntry->ctbEntry.suid;
return code;
}
static int32_t metaCreateVirtualChildTable(SMeta *pMeta, int64_t version, SVCreateTbReq *pReq, STableMetaRsp **ppRsp) {
// check request
int32_t code = metaCheckCreateChildTableReq(pMeta, version, pReq);
if (code) {
if (TSDB_CODE_TDB_TABLE_ALREADY_EXIST != code) {
metaError("vgId:%d, %s failed at %s:%d since %s, version:%" PRId64 " name:%s", TD_VID(pMeta->pVnode), __func__,
__FILE__, __LINE__, tstrerror(code), version, pReq->name);
}
TAOS_RETURN(code);
}
SMetaEntry entry = {
.version = version,
.type = TSDB_VIRTUAL_CHILD_TABLE,
.uid = pReq->uid,
.name = pReq->name,
.ctbEntry.btime = pReq->btime,
.ctbEntry.ttlDays = pReq->ttl,
.ctbEntry.commentLen = pReq->commentLen,
.ctbEntry.comment = pReq->comment,
.ctbEntry.suid = pReq->ctb.suid,
.ctbEntry.pTags = pReq->ctb.pTag,
.colRef = pReq->colRef
};
code = metaBuildCreateVirtualChildTableRsp(pMeta, &entry, ppRsp);
if (code) {
metaError("vgId:%d, %s failed at %s:%d since %s", TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__,
tstrerror(code));
}
// handle entry
code = metaHandleEntry2(pMeta, &entry);
if (TSDB_CODE_SUCCESS == code) {
metaInfo("vgId:%d, normal table:%s uid %" PRId64 " is created, version:%" PRId64, TD_VID(pMeta->pVnode), pReq->name,
pReq->uid, version);
} else {
metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
__func__, __FILE__, __LINE__, tstrerror(code), pReq->uid, pReq->name, version);
}
TAOS_RETURN(code);
#if 0
metaTimeSeriesNotifyCheck(pMeta);
#endif
}
// Drop Normal Table // Drop Normal Table
// Alter Normal Table // Alter Normal Table
@ -505,6 +647,10 @@ int32_t metaCreateTable2(SMeta *pMeta, int64_t version, SVCreateTbReq *pReq, STa
code = metaCreateChildTable(pMeta, version, pReq, ppRsp); code = metaCreateChildTable(pMeta, version, pReq, ppRsp);
} else if (TSDB_NORMAL_TABLE == pReq->type) { } else if (TSDB_NORMAL_TABLE == pReq->type) {
code = metaCreateNormalTable(pMeta, version, pReq, ppRsp); code = metaCreateNormalTable(pMeta, version, pReq, ppRsp);
} else if (TSDB_VIRTUAL_NORMAL_TABLE == pReq->type) {
code = metaCreateVirtualNormalTable(pMeta, version, pReq, ppRsp);
} else if (TSDB_VIRTUAL_CHILD_TABLE == pReq->type) {
code = metaCreateVirtualChildTable(pMeta, version, pReq, ppRsp);
} else { } else {
code = TSDB_CODE_INVALID_MSG; code = TSDB_CODE_INVALID_MSG;
} }
@ -536,11 +682,19 @@ int32_t metaDropTable2(SMeta *pMeta, int64_t version, SVDropTbReq *pReq) {
.uid = pReq->uid, .uid = pReq->uid,
}; };
if (pReq->isVirtual) {
if (pReq->suid == 0) {
entry.type = -TSDB_VIRTUAL_NORMAL_TABLE;
} else {
entry.type = -TSDB_VIRTUAL_CHILD_TABLE;
}
} else {
if (pReq->suid == 0) { if (pReq->suid == 0) {
entry.type = -TSDB_NORMAL_TABLE; entry.type = -TSDB_NORMAL_TABLE;
} else { } else {
entry.type = -TSDB_CHILD_TABLE; entry.type = -TSDB_CHILD_TABLE;
} }
}
code = metaHandleEntry2(pMeta, &entry); code = metaHandleEntry2(pMeta, &entry);
if (code) { if (code) {
metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode), metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
@ -583,7 +737,7 @@ static int32_t metaCheckAlterTableColumnReq(SMeta *pMeta, int64_t version, SVAlt
code = TSDB_CODE_INTERNAL_ERROR; code = TSDB_CODE_INTERNAL_ERROR;
TAOS_RETURN(code); TAOS_RETURN(code);
} }
if (info.suid != 0) { if (info.suid != 0 && pReq->action != TSDB_ALTER_TABLE_ALTER_COLUMN_REF && pReq->action != TSDB_ALTER_TABLE_REMOVE_COLUMN_REF) {
metaError("vgId:%d, %s failed at %s:%d since table %s uid %" PRId64 " is not a normal table, version:%" PRId64, metaError("vgId:%d, %s failed at %s:%d since table %s uid %" PRId64 " is not a normal table, version:%" PRId64,
TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->tbName, uid, version); TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->tbName, uid, version);
code = TSDB_CODE_VND_INVALID_TABLE_ACTION; code = TSDB_CODE_VND_INVALID_TABLE_ACTION;
@ -665,6 +819,26 @@ int32_t metaAddTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq, ST
pColumn->colId = pEntry->ntbEntry.ncid++; pColumn->colId = pEntry->ntbEntry.ncid++;
extSchema.typeMod = pReq->typeMod; extSchema.typeMod = pReq->typeMod;
tstrncpy(pColumn->name, pReq->colName, TSDB_COL_NAME_LEN); tstrncpy(pColumn->name, pReq->colName, TSDB_COL_NAME_LEN);
if (pEntry->type == TSDB_VIRTUAL_NORMAL_TABLE) {
SColRef tmpRef;
if (TSDB_ALTER_TABLE_ADD_COLUMN == pReq->action) {
tmpRef.hasRef = false;
tmpRef.id = pColumn->colId;
} else {
tmpRef.hasRef = true;
tmpRef.id = pColumn->colId;
tstrncpy(tmpRef.refDbName, pReq->refDbName, TSDB_DB_NAME_LEN);
tstrncpy(tmpRef.refTableName, pReq->refTbName, TSDB_TABLE_NAME_LEN);
tstrncpy(tmpRef.refColName, pReq->refColName, TSDB_COL_NAME_LEN);
}
code = updataTableColRef(&pEntry->colRef, pColumn, 1, &tmpRef);
if (code) {
metaError("vgId:%d, %s failed at %s:%d since %s, version:%" PRId64, TD_VID(pMeta->pVnode), __func__, __FILE__,
__LINE__, tstrerror(code), version);
metaFetchEntryFree(&pEntry);
TAOS_RETURN(code);
}
} else {
uint32_t compress; uint32_t compress;
if (TSDB_ALTER_TABLE_ADD_COLUMN == pReq->action) { if (TSDB_ALTER_TABLE_ADD_COLUMN == pReq->action) {
compress = createDefaultColCmprByType(pColumn->type); compress = createDefaultColCmprByType(pColumn->type);
@ -678,6 +852,7 @@ int32_t metaAddTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq, ST
metaFetchEntryFree(&pEntry); metaFetchEntryFree(&pEntry);
TAOS_RETURN(code); TAOS_RETURN(code);
} }
}
code = addTableExtSchema(pEntry, pColumn, pSchema->nCols, &extSchema); code = addTableExtSchema(pEntry, pColumn, pSchema->nCols, &extSchema);
if (code) { if (code) {
metaError("vgId:%d, %s failed to add ext schema at %s:%d since %s, version:%" PRId64, TD_VID(pMeta->pVnode), metaError("vgId:%d, %s failed to add ext schema at %s:%d since %s, version:%" PRId64, TD_VID(pMeta->pVnode),
@ -698,6 +873,23 @@ int32_t metaAddTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq, ST
pEntry->uid, version); pEntry->uid, version);
} }
if (pEntry->type == TSDB_VIRTUAL_NORMAL_TABLE) {
if (metaUpdateVtbMetaRsp(pEntry->uid, pReq->tbName, pSchema, &pEntry->colRef, pRsp, pEntry->type) < 0) {
metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
__func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version);
} else {
for (int32_t i = 0; i < pEntry->colRef.nCols; i++) {
SColRef *p = &pEntry->colRef.pColRef[i];
pRsp->pColRefs[i].hasRef = p->hasRef;
pRsp->pColRefs[i].id = p->id;
if (p->hasRef) {
tstrncpy(pRsp->pColRefs[i].refDbName, p->refDbName, TSDB_DB_NAME_LEN);
tstrncpy(pRsp->pColRefs[i].refTableName, p->refTableName, TSDB_TABLE_NAME_LEN);
tstrncpy(pRsp->pColRefs[i].refColName, p->refColName, TSDB_COL_NAME_LEN);
}
}
}
} else {
if (metaUpdateMetaRsp(pEntry->uid, pReq->tbName, pSchema, pRsp) < 0) { if (metaUpdateMetaRsp(pEntry->uid, pReq->tbName, pSchema, pRsp) < 0) {
metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode), metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
__func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version); __func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version);
@ -708,6 +900,7 @@ int32_t metaAddTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq, ST
pRsp->pSchemaExt[i].compress = p->alg; pRsp->pSchemaExt[i].compress = p->alg;
} }
} }
}
metaFetchEntryFree(&pEntry); metaFetchEntryFree(&pEntry);
TAOS_RETURN(code); TAOS_RETURN(code);
@ -779,6 +972,21 @@ int32_t metaDropTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq, S
} }
pSchema->nCols--; pSchema->nCols--;
pSchema->version++; pSchema->version++;
if (pEntry->type == TSDB_VIRTUAL_NORMAL_TABLE) {
code = updataTableColRef(&pEntry->colRef, &tColumn, 0, NULL);
if (code) {
metaError("vgId:%d, %s failed at %s:%d since %s, version:%" PRId64, TD_VID(pMeta->pVnode), __func__, __FILE__,
__LINE__, tstrerror(code), version);
metaFetchEntryFree(&pEntry);
TAOS_RETURN(code);
}
if (pEntry->colRef.nCols != pSchema->nCols) {
metaError("vgId:%d, %s failed at %s:%d since column count mismatch, version:%" PRId64, TD_VID(pMeta->pVnode),
__func__, __FILE__, __LINE__, version);
metaFetchEntryFree(&pEntry);
TAOS_RETURN(TSDB_CODE_VND_INVALID_TABLE_ACTION);
}
} else {
code = updataTableColCmpr(&pEntry->colCmpr, &tColumn, 0, 0); code = updataTableColCmpr(&pEntry->colCmpr, &tColumn, 0, 0);
if (code) { if (code) {
metaError("vgId:%d, %s failed at %s:%d since %s, version:%" PRId64, TD_VID(pMeta->pVnode), __func__, __FILE__, metaError("vgId:%d, %s failed at %s:%d since %s, version:%" PRId64, TD_VID(pMeta->pVnode), __func__, __FILE__,
@ -792,6 +1000,7 @@ int32_t metaDropTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq, S
metaFetchEntryFree(&pEntry); metaFetchEntryFree(&pEntry);
TAOS_RETURN(TSDB_CODE_VND_INVALID_TABLE_ACTION); TAOS_RETURN(TSDB_CODE_VND_INVALID_TABLE_ACTION);
} }
}
// update column extschema // update column extschema
code = dropTableExtSchema(pEntry, iColumn, pSchema->nCols); code = dropTableExtSchema(pEntry, iColumn, pSchema->nCols);
@ -814,6 +1023,23 @@ int32_t metaDropTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq, S
} }
// build response // build response
if (pEntry->type == TSDB_VIRTUAL_NORMAL_TABLE) {
if (metaUpdateVtbMetaRsp(pEntry->uid, pReq->tbName, pSchema, &pEntry->colRef, pRsp, pEntry->type) < 0) {
metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
__func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version);
} else {
for (int32_t i = 0; i < pEntry->colRef.nCols; i++) {
SColRef *p = &pEntry->colRef.pColRef[i];
pRsp->pColRefs[i].hasRef = p->hasRef;
pRsp->pColRefs[i].id = p->id;
if (p->hasRef) {
tstrncpy(pRsp->pColRefs[i].refDbName, p->refDbName, TSDB_DB_NAME_LEN);
tstrncpy(pRsp->pColRefs[i].refTableName, p->refTableName, TSDB_TABLE_NAME_LEN);
tstrncpy(pRsp->pColRefs[i].refColName, p->refColName, TSDB_COL_NAME_LEN);
}
}
}
} else {
if (metaUpdateMetaRsp(pEntry->uid, pReq->tbName, pSchema, pRsp) < 0) { if (metaUpdateMetaRsp(pEntry->uid, pReq->tbName, pSchema, pRsp) < 0) {
metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode), metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
__func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version); __func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version);
@ -824,6 +1050,7 @@ int32_t metaDropTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq, S
pRsp->pSchemaExt[i].compress = p->alg; pRsp->pSchemaExt[i].compress = p->alg;
} }
} }
}
metaFetchEntryFree(&pEntry); metaFetchEntryFree(&pEntry);
TAOS_RETURN(code); TAOS_RETURN(code);
@ -904,6 +1131,23 @@ int32_t metaAlterTableColumnName(SMeta *pMeta, int64_t version, SVAlterTbReq *pR
} }
// build response // build response
if (pEntry->type == TSDB_VIRTUAL_NORMAL_TABLE) {
if (metaUpdateVtbMetaRsp(pEntry->uid, pReq->tbName, pSchema, &pEntry->colRef, pRsp, pEntry->type) < 0) {
metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
__func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version);
} else {
for (int32_t i = 0; i < pEntry->colRef.nCols; i++) {
SColRef *p = &pEntry->colRef.pColRef[i];
pRsp->pColRefs[i].hasRef = p->hasRef;
pRsp->pColRefs[i].id = p->id;
if (p->hasRef) {
tstrncpy(pRsp->pColRefs[i].refDbName, p->refDbName, TSDB_DB_NAME_LEN);
tstrncpy(pRsp->pColRefs[i].refTableName, p->refTableName, TSDB_TABLE_NAME_LEN);
tstrncpy(pRsp->pColRefs[i].refColName, p->refColName, TSDB_COL_NAME_LEN);
}
}
}
} else {
if (metaUpdateMetaRsp(pEntry->uid, pReq->tbName, pSchema, pRsp) < 0) { if (metaUpdateMetaRsp(pEntry->uid, pReq->tbName, pSchema, pRsp) < 0) {
metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode), metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
__func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version); __func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version);
@ -914,6 +1158,7 @@ int32_t metaAlterTableColumnName(SMeta *pMeta, int64_t version, SVAlterTbReq *pR
pRsp->pSchemaExt[i].compress = p->alg; pRsp->pSchemaExt[i].compress = p->alg;
} }
} }
}
metaFetchEntryFree(&pEntry); metaFetchEntryFree(&pEntry);
TAOS_RETURN(code); TAOS_RETURN(code);
@ -1005,6 +1250,23 @@ int32_t metaAlterTableColumnBytes(SMeta *pMeta, int64_t version, SVAlterTbReq *p
} }
// build response // build response
if (pEntry->type == TSDB_VIRTUAL_NORMAL_TABLE) {
if (metaUpdateVtbMetaRsp(pEntry->uid, pReq->tbName, pSchema, &pEntry->colRef, pRsp, pEntry->type) < 0) {
metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
__func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version);
} else {
for (int32_t i = 0; i < pEntry->colRef.nCols; i++) {
SColRef *p = &pEntry->colRef.pColRef[i];
pRsp->pColRefs[i].hasRef = p->hasRef;
pRsp->pColRefs[i].id = p->id;
if (p->hasRef) {
tstrncpy(pRsp->pColRefs[i].refDbName, p->refDbName, TSDB_DB_NAME_LEN);
tstrncpy(pRsp->pColRefs[i].refTableName, p->refTableName, TSDB_TABLE_NAME_LEN);
tstrncpy(pRsp->pColRefs[i].refColName, p->refColName, TSDB_COL_NAME_LEN);
}
}
}
} else {
if (metaUpdateMetaRsp(pEntry->uid, pReq->tbName, pSchema, pRsp) < 0) { if (metaUpdateMetaRsp(pEntry->uid, pReq->tbName, pSchema, pRsp) < 0) {
metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode), metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
__func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version); __func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version);
@ -1015,6 +1277,7 @@ int32_t metaAlterTableColumnBytes(SMeta *pMeta, int64_t version, SVAlterTbReq *p
pRsp->pSchemaExt[i].compress = p->alg; pRsp->pSchemaExt[i].compress = p->alg;
} }
} }
}
metaFetchEntryFree(&pEntry); metaFetchEntryFree(&pEntry);
TAOS_RETURN(code); TAOS_RETURN(code);
@ -1063,7 +1326,7 @@ int32_t metaUpdateTableTagValue(SMeta *pMeta, int64_t version, SVAlterTbReq *pRe
TAOS_RETURN(code); TAOS_RETURN(code);
} }
if (pChild->type != TSDB_CHILD_TABLE) { if (pChild->type != TSDB_CHILD_TABLE && pChild->type != TSDB_VIRTUAL_CHILD_TABLE) {
metaError("vgId:%d, %s failed at %s:%d since table %s is not a child table, version:%" PRId64, metaError("vgId:%d, %s failed at %s:%d since table %s is not a child table, version:%" PRId64,
TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->tbName, version); TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->tbName, version);
metaFetchEntryFree(&pChild); metaFetchEntryFree(&pChild);
@ -1561,6 +1824,224 @@ int32_t metaUpdateTableColCompress2(SMeta *pMeta, int64_t version, SVAlterTbReq
TAOS_RETURN(code); TAOS_RETURN(code);
} }
int32_t metaAlterTableColumnRef(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq, STableMetaRsp *pRsp) {
int32_t code = TSDB_CODE_SUCCESS;
// check request
code = metaCheckAlterTableColumnReq(pMeta, version, pReq);
if (code) {
TAOS_RETURN(code);
}
if (NULL == pReq->refDbName) {
metaError("vgId:%d, %s failed at %s:%d since invalid ref db name, version:%" PRId64, TD_VID(pMeta->pVnode),
__func__, __FILE__, __LINE__, version);
TAOS_RETURN(TSDB_CODE_INVALID_MSG);
}
if (NULL == pReq->refTbName) {
metaError("vgId:%d, %s failed at %s:%d since invalid ref table name, version:%" PRId64, TD_VID(pMeta->pVnode),
__func__, __FILE__, __LINE__, version);
TAOS_RETURN(TSDB_CODE_INVALID_MSG);
}
if (NULL == pReq->refColName) {
metaError("vgId:%d, %s failed at %s:%d since invalid ref Col name, version:%" PRId64, TD_VID(pMeta->pVnode),
__func__, __FILE__, __LINE__, version);
TAOS_RETURN(TSDB_CODE_INVALID_MSG);
}
// fetch old entry
SMetaEntry *pEntry = NULL;
code = metaFetchEntryByName(pMeta, pReq->tbName, &pEntry);
if (code) {
metaError("vgId:%d, %s failed at %s:%d since table %s not found, version:%" PRId64, TD_VID(pMeta->pVnode), __func__,
__FILE__, __LINE__, pReq->tbName, version);
TAOS_RETURN(code);
}
if (pEntry->version >= version) {
metaError("vgId:%d, %s failed at %s:%d since table %s version %" PRId64 " is not less than %" PRId64,
TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->tbName, pEntry->version, version);
metaFetchEntryFree(&pEntry);
TAOS_RETURN(TSDB_CODE_INVALID_PARA);
}
// fetch super entry
SMetaEntry *pSuper = NULL;
if (pEntry->type == TSDB_VIRTUAL_CHILD_TABLE) {
code = metaFetchEntryByUid(pMeta, pEntry->ctbEntry.suid, &pSuper);
if (code) {
metaError("vgId:%d, %s failed at %s:%d since super table uid %" PRId64 " not found, version:%" PRId64,
TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pEntry->ctbEntry.suid, version);
metaFetchEntryFree(&pEntry);
TAOS_RETURN(TSDB_CODE_INTERNAL_ERROR);
}
}
// search the column to update
SSchemaWrapper *pSchema = pEntry->type == TSDB_VIRTUAL_CHILD_TABLE ? &pSuper->stbEntry.schemaRow : &pEntry->ntbEntry.schemaRow;
SColRef *pColRef = NULL;
int32_t iColumn = 0;
for (int32_t i = 0; i < pSchema->nCols; i++) {
if (strncmp(pSchema->pSchema[i].name, pReq->colName, TSDB_COL_NAME_LEN) == 0) {
pColRef = &pEntry->colRef.pColRef[i];
iColumn = i;
break;
}
}
if (NULL == pColRef) {
metaError("vgId:%d, %s failed at %s:%d since column id %d not found in table %s, version:%" PRId64,
TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->colId, pReq->tbName, version);
metaFetchEntryFree(&pEntry);
metaFetchEntryFree(&pSuper);
TAOS_RETURN(TSDB_CODE_VND_COL_NOT_EXISTS);
}
// do update column name
pEntry->version = version;
pColRef->hasRef = true;
pColRef->id = pSchema->pSchema[iColumn].colId;
tstrncpy(pColRef->refDbName, pReq->refDbName, TSDB_DB_NAME_LEN);
tstrncpy(pColRef->refTableName, pReq->refTbName, TSDB_TABLE_NAME_LEN);
tstrncpy(pColRef->refColName, pReq->refColName, TSDB_COL_NAME_LEN);
pSchema->version++;
// do handle entry
code = metaHandleEntry2(pMeta, pEntry);
if (code) {
metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
__func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version);
metaFetchEntryFree(&pEntry);
metaFetchEntryFree(&pSuper);
TAOS_RETURN(code);
} else {
metaInfo("vgId:%d, table %s uid %" PRId64 " is updated, version:%" PRId64, TD_VID(pMeta->pVnode), pReq->tbName,
pEntry->uid, version);
}
// build response
if (metaUpdateVtbMetaRsp(pEntry->uid, pReq->tbName, pSchema, &pEntry->colRef, pRsp, pEntry->type) < 0) {
metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
__func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version);
} else {
for (int32_t i = 0; i < pEntry->colRef.nCols; i++) {
SColRef *p = &pEntry->colRef.pColRef[i];
pRsp->pColRefs[i].hasRef = p->hasRef;
pRsp->pColRefs[i].id = p->id;
if (p->hasRef) {
tstrncpy(pRsp->pColRefs[i].refDbName, p->refDbName, TSDB_DB_NAME_LEN);
tstrncpy(pRsp->pColRefs[i].refTableName, p->refTableName, TSDB_TABLE_NAME_LEN);
tstrncpy(pRsp->pColRefs[i].refColName, p->refColName, TSDB_COL_NAME_LEN);
}
}
}
metaFetchEntryFree(&pEntry);
metaFetchEntryFree(&pSuper);
TAOS_RETURN(code);
}
int32_t metaRemoveTableColumnRef(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq, STableMetaRsp *pRsp) {
int32_t code = TSDB_CODE_SUCCESS;
// check request
code = metaCheckAlterTableColumnReq(pMeta, version, pReq);
if (code) {
TAOS_RETURN(code);
}
// fetch old entry
SMetaEntry *pEntry = NULL;
code = metaFetchEntryByName(pMeta, pReq->tbName, &pEntry);
if (code) {
metaError("vgId:%d, %s failed at %s:%d since table %s not found, version:%" PRId64, TD_VID(pMeta->pVnode), __func__,
__FILE__, __LINE__, pReq->tbName, version);
TAOS_RETURN(code);
}
if (pEntry->version >= version) {
metaError("vgId:%d, %s failed at %s:%d since table %s version %" PRId64 " is not less than %" PRId64,
TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->tbName, pEntry->version, version);
metaFetchEntryFree(&pEntry);
TAOS_RETURN(TSDB_CODE_INVALID_PARA);
}
// fetch super entry
SMetaEntry *pSuper = NULL;
if (pEntry->type == TSDB_VIRTUAL_CHILD_TABLE) {
code = metaFetchEntryByUid(pMeta, pEntry->ctbEntry.suid, &pSuper);
if (code) {
metaError("vgId:%d, %s failed at %s:%d since super table uid %" PRId64 " not found, version:%" PRId64,
TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pEntry->ctbEntry.suid, version);
metaFetchEntryFree(&pEntry);
TAOS_RETURN(TSDB_CODE_INTERNAL_ERROR);
}
}
// search the column to update
SSchemaWrapper *pSchema = pEntry->type == TSDB_VIRTUAL_CHILD_TABLE ? &pSuper->stbEntry.schemaRow : &pEntry->ntbEntry.schemaRow;
SColRef *pColRef = NULL;
int32_t iColumn = 0;
for (int32_t i = 0; i < pSchema->nCols; i++) {
if (strncmp(pSchema->pSchema[i].name, pReq->colName, TSDB_COL_NAME_LEN) == 0) {
pColRef = &pEntry->colRef.pColRef[i];
iColumn = i;
break;
}
}
if (NULL == pColRef) {
metaError("vgId:%d, %s failed at %s:%d since column id %d not found in table %s, version:%" PRId64,
TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, iColumn + 1, pReq->tbName, version);
metaFetchEntryFree(&pEntry);
metaFetchEntryFree(&pSuper);
TAOS_RETURN(TSDB_CODE_VND_COL_NOT_EXISTS);
}
// do update column name
pEntry->version = version;
pColRef->hasRef = false;
pColRef->id = pSchema->pSchema[iColumn].colId;
pSchema->version++;
// do handle entry
code = metaHandleEntry2(pMeta, pEntry);
if (code) {
metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
__func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version);
metaFetchEntryFree(&pEntry);
metaFetchEntryFree(&pSuper);
TAOS_RETURN(code);
} else {
metaInfo("vgId:%d, table %s uid %" PRId64 " is updated, version:%" PRId64, TD_VID(pMeta->pVnode), pReq->tbName,
pEntry->uid, version);
}
// build response
if (metaUpdateVtbMetaRsp(pEntry->uid, pReq->tbName, pSchema, &pEntry->colRef, pRsp, pEntry->type) < 0) {
metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
__func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version);
} else {
for (int32_t i = 0; i < pEntry->colRef.nCols; i++) {
SColRef *p = &pEntry->colRef.pColRef[i];
pRsp->pColRefs[i].hasRef = p->hasRef;
pRsp->pColRefs[i].id = p->id;
if (p->hasRef) {
tstrncpy(pRsp->pColRefs[i].refDbName, p->refDbName, TSDB_DB_NAME_LEN);
tstrncpy(pRsp->pColRefs[i].refTableName, p->refTableName, TSDB_TABLE_NAME_LEN);
tstrncpy(pRsp->pColRefs[i].refColName, p->refColName, TSDB_COL_NAME_LEN);
}
}
}
metaFetchEntryFree(&pEntry);
metaFetchEntryFree(&pSuper);
TAOS_RETURN(code);
}
int32_t metaAddIndexToSuperTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq) { int32_t metaAddIndexToSuperTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq) {
int32_t code = TSDB_CODE_SUCCESS; int32_t code = TSDB_CODE_SUCCESS;
@ -1791,6 +2272,9 @@ int32_t metaAlterSuperTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq)
.pExtSchemas = pReq->pExtSchemas, .pExtSchemas = pReq->pExtSchemas,
}; };
TABLE_SET_COL_COMPRESSED(entry.flags); TABLE_SET_COL_COMPRESSED(entry.flags);
if (pReq->virtualStb) {
TABLE_SET_VIRTUAL(entry.flags);
}
// do handle the entry // do handle the entry
code = metaHandleEntry2(pMeta, &entry); code = metaHandleEntry2(pMeta, &entry);

View File

@ -692,7 +692,7 @@ static int32_t tdRSmaExecAndSubmitResult(SSma *pSma, qTaskInfo_t taskInfo, SRSma
while (1) { while (1) {
uint64_t ts; uint64_t ts;
bool hasMore = false; bool hasMore = false;
code = qExecTaskOpt(taskInfo, pResList, &ts, &hasMore, NULL); code = qExecTaskOpt(taskInfo, pResList, &ts, &hasMore, NULL, false);
if (code == TSDB_CODE_QRY_IN_EXEC) { if (code == TSDB_CODE_QRY_IN_EXEC) {
code = 0; code = 0;
break; break;

View File

@ -77,6 +77,28 @@ void vnodePrintTableMeta(STableMetaRsp *pMeta) {
} }
} }
int32_t fillTableColRef(SMetaReader *reader, SColRef *pRef, int32_t numOfCol) {
int8_t tblType = reader->me.type;
if (hasRefCol(tblType)) {
SColRefWrapper *p = &(reader->me.colRef);
if (numOfCol != p->nCols) {
vError("fillTableColRef table type:%d, col num:%d, col cmpr num:%d mismatch", tblType, numOfCol, p->nCols);
return TSDB_CODE_APP_ERROR;
}
for (int i = 0; i < p->nCols; i++) {
SColRef *pColRef = &p->pColRef[i];
pRef[i].hasRef = pColRef->hasRef;
pRef[i].id = pColRef->id;
if(pRef[i].hasRef) {
tstrncpy(pRef[i].refDbName, pColRef->refDbName, TSDB_DB_NAME_LEN);
tstrncpy(pRef[i].refTableName, pColRef->refTableName, TSDB_TABLE_NAME_LEN);
tstrncpy(pRef[i].refColName, pColRef->refColName, TSDB_COL_NAME_LEN);
}
}
}
return 0;
}
int32_t vnodeGetTableMeta(SVnode *pVnode, SRpcMsg *pMsg, bool direct) { int32_t vnodeGetTableMeta(SVnode *pVnode, SRpcMsg *pMsg, bool direct) {
STableInfoReq infoReq = {0}; STableInfoReq infoReq = {0};
STableMetaRsp metaRsp = {0}; STableMetaRsp metaRsp = {0};
@ -139,25 +161,35 @@ int32_t vnodeGetTableMeta(SVnode *pVnode, SRpcMsg *pMsg, bool direct) {
metaRsp.vgId = TD_VID(pVnode); metaRsp.vgId = TD_VID(pVnode);
metaRsp.tuid = mer1.me.uid; metaRsp.tuid = mer1.me.uid;
if (mer1.me.type == TSDB_SUPER_TABLE) { switch (mer1.me.type) {
tstrncpy(metaRsp.stbName, mer1.me.name, TSDB_TABLE_NAME_LEN); case TSDB_SUPER_TABLE: {
(void)strcpy(metaRsp.stbName, mer1.me.name);
schema = mer1.me.stbEntry.schemaRow; schema = mer1.me.stbEntry.schemaRow;
schemaTag = mer1.me.stbEntry.schemaTag; schemaTag = mer1.me.stbEntry.schemaTag;
metaRsp.suid = mer1.me.uid; metaRsp.suid = mer1.me.uid;
} else if (mer1.me.type == TSDB_CHILD_TABLE) { break;
}
case TSDB_CHILD_TABLE:
case TSDB_VIRTUAL_CHILD_TABLE:{
metaReaderDoInit(&mer2, pVnode->pMeta, META_READER_NOLOCK); metaReaderDoInit(&mer2, pVnode->pMeta, META_READER_NOLOCK);
if (metaReaderGetTableEntryByUid(&mer2, mer1.me.ctbEntry.suid) < 0) goto _exit2; if (metaReaderGetTableEntryByUid(&mer2, mer1.me.ctbEntry.suid) < 0) goto _exit2;
tstrncpy(metaRsp.stbName, mer2.me.name, TSDB_TABLE_NAME_LEN); (void)strcpy(metaRsp.stbName, mer2.me.name);
metaRsp.suid = mer2.me.uid; metaRsp.suid = mer2.me.uid;
schema = mer2.me.stbEntry.schemaRow; schema = mer2.me.stbEntry.schemaRow;
schemaTag = mer2.me.stbEntry.schemaTag; schemaTag = mer2.me.stbEntry.schemaTag;
} else if (mer1.me.type == TSDB_NORMAL_TABLE) { break;
}
case TSDB_NORMAL_TABLE:
case TSDB_VIRTUAL_NORMAL_TABLE: {
schema = mer1.me.ntbEntry.schemaRow; schema = mer1.me.ntbEntry.schemaRow;
} else { break;
}
default: {
vError("vnodeGetTableMeta get invalid table type:%d", mer1.me.type); vError("vnodeGetTableMeta get invalid table type:%d", mer1.me.type);
goto _exit3; goto _exit3;
} }
}
metaRsp.numOfTags = schemaTag.nCols; metaRsp.numOfTags = schemaTag.nCols;
metaRsp.numOfColumns = schema.nCols; metaRsp.numOfColumns = schema.nCols;
@ -187,6 +219,19 @@ int32_t vnodeGetTableMeta(SVnode *pVnode, SRpcMsg *pMsg, bool direct) {
code = TSDB_CODE_OUT_OF_MEMORY; code = TSDB_CODE_OUT_OF_MEMORY;
goto _exit; goto _exit;
} }
if (hasRefCol(mer1.me.type)) {
metaRsp.pColRefs = (SColRef*)taosMemoryMalloc(sizeof(SColRef) * metaRsp.numOfColumns);
if (metaRsp.pColRefs) {
code = fillTableColRef(&mer1, metaRsp.pColRefs, metaRsp.numOfColumns);
if (code < 0) {
goto _exit;
}
}
metaRsp.numOfColRefs = metaRsp.numOfColumns;
} else {
metaRsp.pColRefs = NULL;
metaRsp.numOfColRefs = 0;
}
vnodePrintTableMeta(&metaRsp); vnodePrintTableMeta(&metaRsp);
@ -215,6 +260,7 @@ int32_t vnodeGetTableMeta(SVnode *pVnode, SRpcMsg *pMsg, bool direct) {
} }
_exit: _exit:
taosMemoryFree(metaRsp.pColRefs);
taosMemoryFree(metaRsp.pSchemas); taosMemoryFree(metaRsp.pSchemas);
taosMemoryFree(metaRsp.pSchemaExt); taosMemoryFree(metaRsp.pSchemaExt);
_exit2: _exit2:
@ -286,7 +332,7 @@ int32_t vnodeGetTableCfg(SVnode *pVnode, SRpcMsg *pMsg, bool direct) {
if (mer1.me.type == TSDB_SUPER_TABLE) { if (mer1.me.type == TSDB_SUPER_TABLE) {
code = TSDB_CODE_VND_HASH_MISMATCH; code = TSDB_CODE_VND_HASH_MISMATCH;
goto _exit; goto _exit;
} else if (mer1.me.type == TSDB_CHILD_TABLE) { } else if (mer1.me.type == TSDB_CHILD_TABLE || mer1.me.type == TSDB_VIRTUAL_CHILD_TABLE) {
metaReaderDoInit(&mer2, pVnode->pMeta, META_READER_NOLOCK); metaReaderDoInit(&mer2, pVnode->pMeta, META_READER_NOLOCK);
if (metaReaderGetTableEntryByUid(&mer2, mer1.me.ctbEntry.suid) < 0) goto _exit; if (metaReaderGetTableEntryByUid(&mer2, mer1.me.ctbEntry.suid) < 0) goto _exit;
@ -310,7 +356,7 @@ int32_t vnodeGetTableCfg(SVnode *pVnode, SRpcMsg *pMsg, bool direct) {
goto _exit; goto _exit;
} }
(void)memcpy(cfgRsp.pTags, pTag, cfgRsp.tagsLen); (void)memcpy(cfgRsp.pTags, pTag, cfgRsp.tagsLen);
} else if (mer1.me.type == TSDB_NORMAL_TABLE) { } else if (mer1.me.type == TSDB_NORMAL_TABLE || mer1.me.type == TSDB_VIRTUAL_NORMAL_TABLE) {
schema = mer1.me.ntbEntry.schemaRow; schema = mer1.me.ntbEntry.schemaRow;
cfgRsp.ttl = mer1.me.ntbEntry.ttlDays; cfgRsp.ttl = mer1.me.ntbEntry.ttlDays;
cfgRsp.commentLen = mer1.me.ntbEntry.commentLen; cfgRsp.commentLen = mer1.me.ntbEntry.commentLen;
@ -329,10 +375,12 @@ int32_t vnodeGetTableCfg(SVnode *pVnode, SRpcMsg *pMsg, bool direct) {
cfgRsp.numOfTags = schemaTag.nCols; cfgRsp.numOfTags = schemaTag.nCols;
cfgRsp.numOfColumns = schema.nCols; cfgRsp.numOfColumns = schema.nCols;
cfgRsp.virtualStb = false; // vnode don't have super table, so it's always false
cfgRsp.pSchemas = (SSchema *)taosMemoryMalloc(sizeof(SSchema) * (cfgRsp.numOfColumns + cfgRsp.numOfTags)); cfgRsp.pSchemas = (SSchema *)taosMemoryMalloc(sizeof(SSchema) * (cfgRsp.numOfColumns + cfgRsp.numOfTags));
cfgRsp.pSchemaExt = (SSchemaExt *)taosMemoryMalloc(cfgRsp.numOfColumns * sizeof(SSchemaExt)); cfgRsp.pSchemaExt = (SSchemaExt *)taosMemoryMalloc(cfgRsp.numOfColumns * sizeof(SSchemaExt));
cfgRsp.pColRefs = (SColRef *)taosMemoryMalloc(sizeof(SColRef) * cfgRsp.numOfColumns);
if (NULL == cfgRsp.pSchemas || NULL == cfgRsp.pSchemaExt) { if (NULL == cfgRsp.pSchemas || NULL == cfgRsp.pSchemaExt || NULL == cfgRsp.pColRefs) {
code = terrno; code = terrno;
goto _exit; goto _exit;
} }
@ -341,11 +389,11 @@ int32_t vnodeGetTableCfg(SVnode *pVnode, SRpcMsg *pMsg, bool direct) {
(void)memcpy(cfgRsp.pSchemas + schema.nCols, schemaTag.pSchema, sizeof(SSchema) * schemaTag.nCols); (void)memcpy(cfgRsp.pSchemas + schema.nCols, schemaTag.pSchema, sizeof(SSchema) * schemaTag.nCols);
} }
// if (useCompress(cfgRsp.tableType)) { SMetaReader *pReader = (mer1.me.type == TSDB_CHILD_TABLE || mer1.me.type == TSDB_VIRTUAL_CHILD_TABLE) ? &mer2 : &mer1;
SMetaReader *pReader = mer1.me.type == TSDB_CHILD_TABLE ? &mer2 : &mer1;
SColCmprWrapper *pColCmpr = &pReader->me.colCmpr; SColCmprWrapper *pColCmpr = &pReader->me.colCmpr;
SColRefWrapper *pColRef = &mer1.me.colRef;
if (withExtSchema(cfgRsp.tableType)) {
for (int32_t i = 0; i < cfgRsp.numOfColumns; i++) { for (int32_t i = 0; i < cfgRsp.numOfColumns; i++) {
SColCmpr *pCmpr = &pColCmpr->pColCmpr[i]; SColCmpr *pCmpr = &pColCmpr->pColCmpr[i];
SSchemaExt *pSchExt = cfgRsp.pSchemaExt + i; SSchemaExt *pSchExt = cfgRsp.pSchemaExt + i;
@ -356,7 +404,21 @@ int32_t vnodeGetTableCfg(SVnode *pVnode, SRpcMsg *pMsg, bool direct) {
else else
pSchExt->typeMod = 0; pSchExt->typeMod = 0;
} }
//} }
cfgRsp.virtualStb = false;
if (hasRefCol(cfgRsp.tableType)) {
for (int32_t i = 0; i < cfgRsp.numOfColumns; i++) {
SColRef *pRef = &pColRef->pColRef[i];
cfgRsp.pColRefs[i].hasRef = pRef->hasRef;
cfgRsp.pColRefs[i].id = pRef->id;
if (cfgRsp.pColRefs[i].hasRef) {
tstrncpy(cfgRsp.pColRefs[i].refDbName, pRef->refDbName, TSDB_DB_NAME_LEN);
tstrncpy(cfgRsp.pColRefs[i].refTableName, pRef->refTableName, TSDB_TABLE_NAME_LEN);
tstrncpy(cfgRsp.pColRefs[i].refColName, pRef->refColName, TSDB_COL_NAME_LEN);
}
}
}
// encode and send response // encode and send response
rspLen = tSerializeSTableCfgRsp(NULL, 0, &cfgRsp); rspLen = tSerializeSTableCfgRsp(NULL, 0, &cfgRsp);

View File

@ -1563,6 +1563,9 @@ _exit:
taosMemoryFree(vMetaRsp.pSchemas); taosMemoryFree(vMetaRsp.pSchemas);
taosMemoryFree(vMetaRsp.pSchemaExt); taosMemoryFree(vMetaRsp.pSchemaExt);
} }
if (vMetaRsp.pColRefs) {
taosMemoryFree(vMetaRsp.pColRefs);
}
return 0; return 0;
} }

View File

@ -779,8 +779,10 @@ typedef struct SCtgCacheItemInfo {
#define CTG_IS_META_NULL(type) ((type) == META_TYPE_NULL_TABLE) #define CTG_IS_META_NULL(type) ((type) == META_TYPE_NULL_TABLE)
#define CTG_IS_META_CTABLE(type) ((type) == META_TYPE_CTABLE) #define CTG_IS_META_CTABLE(type) ((type) == META_TYPE_CTABLE)
#define CTG_IS_META_VCTABLE(type) ((type) == META_TYPE_VCTABLE)
#define CTG_IS_META_TABLE(type) ((type) == META_TYPE_TABLE) #define CTG_IS_META_TABLE(type) ((type) == META_TYPE_TABLE)
#define CTG_IS_META_BOTH(type) ((type) == META_TYPE_BOTH_TABLE) #define CTG_IS_META_BOTH(type) ((type) == META_TYPE_BOTH_TABLE)
#define CTG_IS_META_VBOTH(type) ((type) == META_TYPE_BOTH_VTABLE)
#define CTG_FLAG_STB 0x1 #define CTG_FLAG_STB 0x1
#define CTG_FLAG_NOT_STB 0x2 #define CTG_FLAG_NOT_STB 0x2

View File

@ -138,7 +138,7 @@ int32_t ctgRefreshTbMeta(SCatalog* pCtg, SRequestConnInfo* pConn, SCtgTbMetaCtx*
taosMemoryFreeClear(output->tbMeta); taosMemoryFreeClear(output->tbMeta);
CTG_ERR_JRET(ctgGetTbMetaFromMnodeImpl(pCtg, pConn, output->dbFName, output->tbName, output, NULL)); CTG_ERR_JRET(ctgGetTbMetaFromMnodeImpl(pCtg, pConn, output->dbFName, output->tbName, output, NULL));
} else if (CTG_IS_META_BOTH(output->metaType)) { } else if (CTG_IS_META_BOTH(output->metaType) || CTG_IS_META_VBOTH(output->metaType)) {
int32_t exist = 0; int32_t exist = 0;
if (!CTG_FLAG_IS_FORCE_UPDATE(ctx->flag)) { if (!CTG_FLAG_IS_FORCE_UPDATE(ctx->flag)) {
CTG_ERR_JRET(ctgTbMetaExistInCache(pCtg, output->dbFName, output->tbName, &exist)); CTG_ERR_JRET(ctgTbMetaExistInCache(pCtg, output->dbFName, output->tbName, &exist));
@ -157,7 +157,11 @@ int32_t ctgRefreshTbMeta(SCatalog* pCtg, SRequestConnInfo* pConn, SCtgTbMetaCtx*
} else { } else {
taosMemoryFreeClear(output->tbMeta); taosMemoryFreeClear(output->tbMeta);
if (CTG_IS_META_BOTH(output->metaType)) {
SET_META_TYPE_CTABLE(output->metaType); SET_META_TYPE_CTABLE(output->metaType);
} else {
SET_META_TYPE_VCTABLE(output->metaType);
}
} }
} }
} }
@ -189,6 +193,7 @@ _return:
if (output) { if (output) {
taosMemoryFreeClear(output->tbMeta); taosMemoryFreeClear(output->tbMeta);
taosMemoryFreeClear(output->vctbMeta);
taosMemoryFreeClear(output); taosMemoryFreeClear(output);
} }
@ -219,8 +224,30 @@ int32_t ctgGetTbMeta(SCatalog* pCtg, SRequestConnInfo* pConn, SCtgTbMetaCtx* ctx
goto _return; goto _return;
} }
if (CTG_IS_META_VBOTH(output->metaType) || CTG_IS_META_VCTABLE(output->metaType)) {
int32_t colRefSize = output->vctbMeta->numOfColRefs * sizeof(SColRef);
if (output->tbMeta) {
int32_t metaSize = CTG_META_SIZE(output->tbMeta);
int32_t schemaExtSize = 0;
if (withExtSchema(output->tbMeta->tableType) && output->tbMeta->schemaExt) {
schemaExtSize = output->tbMeta->tableInfo.numOfColumns * sizeof(SSchemaExt);
}
TAOS_MEMCPY(output->tbMeta, output->vctbMeta, sizeof(SVCTableMeta));
output->tbMeta->colRef = (SColRef *)((char *)output->tbMeta + metaSize + schemaExtSize);
TAOS_MEMCPY(output->tbMeta->colRef, output->vctbMeta->colRef, colRefSize);
} else {
TAOS_MEMCPY(output->tbMeta, output->vctbMeta, sizeof(SVCTableMeta) + colRefSize);
output->tbMeta->colRef = (SColRef *)((char *)output->tbMeta + sizeof(SVCTableMeta));
}
output->tbMeta->numOfColRefs = output->vctbMeta->numOfColRefs;
taosMemoryFreeClear(output->vctbMeta);
*pTableMeta = output->tbMeta;
goto _return;
}
if ((!CTG_IS_META_CTABLE(output->metaType)) || output->tbMeta) { if ((!CTG_IS_META_CTABLE(output->metaType)) || output->tbMeta) {
ctgError("invalid metaType:%d", output->metaType); ctgError("invalid metaType:%d", output->metaType);
taosMemoryFreeClear(output->vctbMeta);
taosMemoryFreeClear(output->tbMeta); taosMemoryFreeClear(output->tbMeta);
CTG_ERR_JRET(TSDB_CODE_CTG_INTERNAL_ERROR); CTG_ERR_JRET(TSDB_CODE_CTG_INTERNAL_ERROR);
} }
@ -228,6 +255,7 @@ int32_t ctgGetTbMeta(SCatalog* pCtg, SRequestConnInfo* pConn, SCtgTbMetaCtx* ctx
// HANDLE ONLY CHILD TABLE META // HANDLE ONLY CHILD TABLE META
taosMemoryFreeClear(output->tbMeta); taosMemoryFreeClear(output->tbMeta);
taosMemoryFreeClear(output->vctbMeta);
SName stbName = *ctx->pName; SName stbName = *ctx->pName;
TAOS_STRCPY(stbName.tname, output->tbName); TAOS_STRCPY(stbName.tname, output->tbName);
@ -292,6 +320,12 @@ int32_t ctgUpdateTbMeta(SCatalog* pCtg, STableMetaRsp* rspMsg, bool syncOp) {
SET_META_TYPE_CTABLE(output->metaType); SET_META_TYPE_CTABLE(output->metaType);
CTG_ERR_JRET(queryCreateCTableMetaFromMsg(rspMsg, &output->ctbMeta)); CTG_ERR_JRET(queryCreateCTableMetaFromMsg(rspMsg, &output->ctbMeta));
} else if (TSDB_VIRTUAL_CHILD_TABLE == rspMsg->tableType && NULL == rspMsg->pSchemas) {
TAOS_STRCPY(output->ctbName, rspMsg->tbName);
SET_META_TYPE_VCTABLE(output->metaType);
CTG_ERR_JRET(queryCreateVCTableMetaFromMsg(rspMsg, &output->vctbMeta));
} else { } else {
TAOS_STRCPY(output->tbName, rspMsg->tbName); TAOS_STRCPY(output->tbName, rspMsg->tbName);
@ -310,6 +344,7 @@ _return:
if (output) { if (output) {
taosMemoryFreeClear(output->tbMeta); taosMemoryFreeClear(output->tbMeta);
taosMemoryFreeClear(output->vctbMeta);
taosMemoryFreeClear(output); taosMemoryFreeClear(output);
} }

View File

@ -1638,7 +1638,7 @@ int32_t ctgHandleGetTbMetaRsp(SCtgTaskReq* tReq, int32_t reqType, const SDataBuf
taosMemoryFreeClear(pOut->tbMeta); taosMemoryFreeClear(pOut->tbMeta);
CTG_RET(ctgGetTbMetaFromMnode(pCtg, pConn, pName, NULL, tReq)); CTG_RET(ctgGetTbMetaFromMnode(pCtg, pConn, pName, NULL, tReq));
} else if (CTG_IS_META_BOTH(pOut->metaType)) { } else if (CTG_IS_META_BOTH(pOut->metaType) || CTG_IS_META_VBOTH(pOut->metaType)) {
int32_t exist = 0; int32_t exist = 0;
if (!CTG_FLAG_IS_FORCE_UPDATE(flag)) { if (!CTG_FLAG_IS_FORCE_UPDATE(flag)) {
SName stbName = *pName; SName stbName = *pName;
@ -1674,6 +1674,28 @@ int32_t ctgHandleGetTbMetaRsp(SCtgTaskReq* tReq, int32_t reqType, const SDataBuf
TAOS_MEMCPY(pOut->tbMeta, &pOut->ctbMeta, sizeof(pOut->ctbMeta)); TAOS_MEMCPY(pOut->tbMeta, &pOut->ctbMeta, sizeof(pOut->ctbMeta));
} }
if (CTG_IS_META_VBOTH(pOut->metaType)) {
int32_t colRefSize = pOut->vctbMeta->numOfColRefs * sizeof(SColRef);
if (pOut->tbMeta) {
int32_t metaSize = CTG_META_SIZE(pOut->tbMeta);
int32_t schemaExtSize = 0;
if (withExtSchema(pOut->tbMeta->tableType) && pOut->tbMeta->schemaExt) {
schemaExtSize = pOut->tbMeta->tableInfo.numOfColumns * sizeof(SSchemaExt);
}
pOut->tbMeta = taosMemoryRealloc(pOut->tbMeta, metaSize + schemaExtSize + colRefSize);
TAOS_MEMCPY(pOut->tbMeta, pOut->vctbMeta, sizeof(SVCTableMeta));
pOut->tbMeta->colRef = (SColRef *)((char *)pOut->tbMeta + metaSize + schemaExtSize);
TAOS_MEMCPY(pOut->tbMeta->colRef, pOut->vctbMeta->colRef, colRefSize);
} else {
pOut->tbMeta = taosMemoryRealloc(pOut->tbMeta, sizeof(STableMeta) + colRefSize);
TAOS_MEMCPY(pOut->tbMeta, pOut->vctbMeta, sizeof(SVCTableMeta));
TAOS_MEMCPY(pOut->tbMeta + sizeof(STableMeta), pOut->vctbMeta + sizeof(SVCTableMeta), colRefSize);
pOut->tbMeta->colRef = (SColRef *)((char *)pOut->tbMeta + sizeof(STableMeta));
}
pOut->tbMeta->numOfColRefs = pOut->vctbMeta->numOfColRefs;
taosMemoryFreeClear(pOut->vctbMeta);
}
/* /*
else if (CTG_IS_META_CTABLE(pOut->metaType)) { else if (CTG_IS_META_CTABLE(pOut->metaType)) {
SName stbName = *pName; SName stbName = *pName;
@ -1823,7 +1845,7 @@ int32_t ctgHandleGetTbMetasRsp(SCtgTaskReq* tReq, int32_t reqType, const SDataBu
taosMemoryFreeClear(pOut->tbMeta); taosMemoryFreeClear(pOut->tbMeta);
CTG_RET(ctgGetTbMetaFromMnode(pCtg, pConn, pName, NULL, tReq)); CTG_RET(ctgGetTbMetaFromMnode(pCtg, pConn, pName, NULL, tReq));
} else if (CTG_IS_META_BOTH(pOut->metaType)) { } else if (CTG_IS_META_BOTH(pOut->metaType) || CTG_IS_META_VBOTH(pOut->metaType)) {
int32_t exist = 0; int32_t exist = 0;
if (!CTG_FLAG_IS_FORCE_UPDATE(flag)) { if (!CTG_FLAG_IS_FORCE_UPDATE(flag)) {
SName stbName = *pName; SName stbName = *pName;
@ -1865,6 +1887,27 @@ int32_t ctgHandleGetTbMetasRsp(SCtgTaskReq* tReq, int32_t reqType, const SDataBu
TAOS_MEMCPY(pOut->tbMeta, &pOut->ctbMeta, sizeof(pOut->ctbMeta)); TAOS_MEMCPY(pOut->tbMeta, &pOut->ctbMeta, sizeof(pOut->ctbMeta));
} }
if (CTG_IS_META_VBOTH(pOut->metaType)) {
int32_t colRefSize = pOut->vctbMeta->numOfColRefs * sizeof(SColRef);
if (pOut->tbMeta) {
int32_t metaSize = CTG_META_SIZE(pOut->tbMeta);
int32_t schemaExtSize = 0;
if (withExtSchema(pOut->tbMeta->tableType) && pOut->tbMeta->schemaExt) {
schemaExtSize = pOut->tbMeta->tableInfo.numOfColumns * sizeof(SSchemaExt);
}
pOut->tbMeta = taosMemoryRealloc(pOut->tbMeta, metaSize + schemaExtSize + colRefSize);
TAOS_MEMCPY(pOut->tbMeta, pOut->vctbMeta, sizeof(SVCTableMeta));
pOut->tbMeta->colRef = (SColRef *)((char *)pOut->tbMeta + metaSize + schemaExtSize);
TAOS_MEMCPY(pOut->tbMeta->colRef, pOut->vctbMeta->colRef, colRefSize);
} else {
pOut->tbMeta = taosMemoryRealloc(pOut->tbMeta, sizeof(STableMeta) + colRefSize);
TAOS_MEMCPY(pOut->tbMeta, pOut->vctbMeta, sizeof(SVCTableMeta));
TAOS_MEMCPY(pOut->tbMeta + sizeof(STableMeta), pOut->vctbMeta + sizeof(SVCTableMeta), colRefSize);
pOut->tbMeta->colRef = (SColRef *)((char *)pOut->tbMeta + sizeof(STableMeta));
}
pOut->tbMeta->numOfColRefs = pOut->vctbMeta->numOfColRefs;
taosMemoryFreeClear(pOut->vctbMeta);
}
/* /*
else if (CTG_IS_META_CTABLE(pOut->metaType)) { else if (CTG_IS_META_CTABLE(pOut->metaType)) {
SName stbName = *pName; SName stbName = *pName;
@ -1895,6 +1938,7 @@ int32_t ctgHandleGetTbMetasRsp(SCtgTaskReq* tReq, int32_t reqType, const SDataBu
pRes->code = 0; pRes->code = 0;
pRes->pRes = pOut->tbMeta; pRes->pRes = pOut->tbMeta;
pOut->tbMeta = NULL; pOut->tbMeta = NULL;
pOut->vctbMeta = NULL;
if (0 == atomic_sub_fetch_32(&ctx->fetchNum, 1)) { if (0 == atomic_sub_fetch_32(&ctx->fetchNum, 1)) {
TSWAP(pTask->res, ctx->pResList); TSWAP(pTask->res, ctx->pResList);
taskDone = true; taskDone = true;
@ -2066,6 +2110,28 @@ static int32_t ctgHandleGetTbNamesRsp(SCtgTaskReq* tReq, int32_t reqType, const
TAOS_MEMCPY(pOut->tbMeta, &pOut->ctbMeta, sizeof(pOut->ctbMeta)); TAOS_MEMCPY(pOut->tbMeta, &pOut->ctbMeta, sizeof(pOut->ctbMeta));
} }
if (CTG_IS_META_VBOTH(pOut->metaType)) {
int32_t colRefSize = pOut->vctbMeta->numOfColRefs * sizeof(SColRef);
if (pOut->tbMeta) {
int32_t metaSize = CTG_META_SIZE(pOut->tbMeta);
int32_t schemaExtSize = 0;
if (withExtSchema(pOut->tbMeta->tableType) && pOut->tbMeta->schemaExt) {
schemaExtSize = pOut->tbMeta->tableInfo.numOfColumns * sizeof(SSchemaExt);
}
pOut->tbMeta = taosMemoryRealloc(pOut->tbMeta, metaSize + schemaExtSize + colRefSize);
TAOS_MEMCPY(pOut->tbMeta, pOut->vctbMeta, sizeof(SVCTableMeta));
pOut->tbMeta->colRef = (SColRef *)((char *)pOut->tbMeta + metaSize + schemaExtSize);
TAOS_MEMCPY(pOut->tbMeta->colRef, pOut->vctbMeta->colRef, colRefSize);
} else {
pOut->tbMeta = taosMemoryRealloc(pOut->tbMeta, sizeof(STableMeta) + colRefSize);
TAOS_MEMCPY(pOut->tbMeta, pOut->vctbMeta, sizeof(SVCTableMeta));
TAOS_MEMCPY(pOut->tbMeta + sizeof(STableMeta), pOut->vctbMeta + sizeof(SVCTableMeta), colRefSize);
pOut->tbMeta->colRef = (SColRef *)((char *)pOut->tbMeta + sizeof(STableMeta));
}
pOut->tbMeta->numOfColRefs = pOut->vctbMeta->numOfColRefs;
taosMemoryFreeClear(pOut->vctbMeta);
}
SMetaRes* pRes = taosArrayGet(ctx->pResList, pFetch->resIdx); SMetaRes* pRes = taosArrayGet(ctx->pResList, pFetch->resIdx);
if (NULL == pRes) { if (NULL == pRes) {
ctgTaskError("fail to get the %dth res in pResList, resNum:%d", pFetch->resIdx, ctgTaskError("fail to get the %dth res in pResList, resNum:%d", pFetch->resIdx,
@ -2076,8 +2142,10 @@ static int32_t ctgHandleGetTbNamesRsp(SCtgTaskReq* tReq, int32_t reqType, const
if (!pRes->pRes) { if (!pRes->pRes) {
pRes->code = 0; pRes->code = 0;
pRes->pRes = pOut->tbMeta; pRes->pRes = pOut->tbMeta;
taosMemoryFreeClear(pOut->vctbMeta);
pOut->tbMeta = NULL; pOut->tbMeta = NULL;
} else { } else {
taosMemoryFreeClear(pOut->vctbMeta);
taosMemoryFreeClear(pOut->tbMeta); taosMemoryFreeClear(pOut->tbMeta);
} }

View File

@ -538,34 +538,55 @@ int32_t ctgCopyTbMeta(SCatalog *pCtg, SCtgTbMetaCtx *ctx, SCtgDBCache **pDb, SCt
ctx->tbInfo.suid = tbMeta->suid; ctx->tbInfo.suid = tbMeta->suid;
ctx->tbInfo.tbType = tbMeta->tableType; ctx->tbInfo.tbType = tbMeta->tableType;
if (tbMeta->tableType != TSDB_CHILD_TABLE) { if (tbMeta->tableType != TSDB_CHILD_TABLE && tbMeta->tableType != TSDB_VIRTUAL_CHILD_TABLE) {
int32_t schemaExtSize = 0; int32_t schemaExtSize = 0;
int32_t colRefSize = 0;
int32_t metaSize = CTG_META_SIZE(tbMeta); int32_t metaSize = CTG_META_SIZE(tbMeta);
if (tbMeta->schemaExt != NULL) { if (withExtSchema(tbMeta->tableType) && tbMeta->schemaExt != NULL) {
schemaExtSize = tbMeta->tableInfo.numOfColumns * sizeof(SSchemaExt); schemaExtSize = tbMeta->tableInfo.numOfColumns * sizeof(SSchemaExt);
} }
*pTableMeta = taosMemoryCalloc(1, metaSize + schemaExtSize); if (hasRefCol(tbMeta->tableType) && tbMeta->colRef != NULL) {
colRefSize += tbMeta->tableInfo.numOfColumns * sizeof(SColRef);
}
*pTableMeta = taosMemoryCalloc(1, metaSize + schemaExtSize + colRefSize);
if (NULL == *pTableMeta) { if (NULL == *pTableMeta) {
CTG_ERR_RET(terrno); CTG_ERR_RET(terrno);
} }
TAOS_MEMCPY(*pTableMeta, tbMeta, metaSize); TAOS_MEMCPY(*pTableMeta, tbMeta, metaSize);
if (tbMeta->schemaExt != NULL) { if (withExtSchema(tbMeta->tableType) && tbMeta->schemaExt != NULL) {
(*pTableMeta)->schemaExt = (SSchemaExt *)((char *)*pTableMeta + metaSize); (*pTableMeta)->schemaExt = (SSchemaExt *)((char *)*pTableMeta + metaSize);
TAOS_MEMCPY((*pTableMeta)->schemaExt, tbMeta->schemaExt, schemaExtSize); TAOS_MEMCPY((*pTableMeta)->schemaExt, tbMeta->schemaExt, schemaExtSize);
} else { } else {
(*pTableMeta)->schemaExt = NULL; (*pTableMeta)->schemaExt = NULL;
} }
if (hasRefCol(tbMeta->tableType) && tbMeta->colRef) {
(*pTableMeta)->colRef = (SColRef *)((char *)*pTableMeta + metaSize + schemaExtSize);
TAOS_MEMCPY((*pTableMeta)->colRef, tbMeta->colRef, colRefSize);
(*pTableMeta)->numOfColRefs = tbMeta->numOfColRefs;
} else {
(*pTableMeta)->colRef = NULL;
}
ctgDebug("tb:%s, get meta from cache, type:%d, db:%s", ctx->pName->tname, tbMeta->tableType, dbFName); ctgDebug("tb:%s, get meta from cache, type:%d, db:%s", ctx->pName->tname, tbMeta->tableType, dbFName);
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
// PROCESS FOR CHILD TABLE // PROCESS FOR CHILD TABLE
int32_t metaSize = sizeof(SCTableMeta); int32_t metaSize = sizeof(SCTableMeta);
*pTableMeta = taosMemoryCalloc(1, metaSize); int32_t colRefSize = 0;
int32_t numOfColRefs = 0;
SColRef *tmpRef = NULL;
if (hasRefCol(tbMeta->tableType) && tbMeta->colRef != NULL) {
colRefSize += tbMeta->numOfColRefs * sizeof(SColRef);
numOfColRefs = tbMeta->numOfColRefs;
tmpRef = taosMemoryMalloc(colRefSize);
TAOS_MEMCPY(tmpRef, tbMeta->colRef, colRefSize);
}
*pTableMeta = taosMemoryCalloc(1, metaSize + colRefSize);
if (NULL == *pTableMeta) { if (NULL == *pTableMeta) {
taosMemoryFreeClear(tmpRef);
CTG_ERR_RET(terrno); CTG_ERR_RET(terrno);
} }
@ -582,6 +603,7 @@ int32_t ctgCopyTbMeta(SCatalog *pCtg, SCtgTbMetaCtx *ctx, SCtgDBCache **pDb, SCt
CTG_ERR_RET(ctgAcquireStbMetaFromCache(dbCache, pCtg, dbFName, ctx->tbInfo.suid, &tbCache)); CTG_ERR_RET(ctgAcquireStbMetaFromCache(dbCache, pCtg, dbFName, ctx->tbInfo.suid, &tbCache));
if (NULL == tbCache) { if (NULL == tbCache) {
taosMemoryFreeClear(tmpRef);
taosMemoryFreeClear(*pTableMeta); taosMemoryFreeClear(*pTableMeta);
*pDb = NULL; *pDb = NULL;
ctgDebug("stb:0x%" PRIx64 ", meta not in cache", ctx->tbInfo.suid); ctgDebug("stb:0x%" PRIx64 ", meta not in cache", ctx->tbInfo.suid);
@ -594,6 +616,7 @@ int32_t ctgCopyTbMeta(SCatalog *pCtg, SCtgTbMetaCtx *ctx, SCtgDBCache **pDb, SCt
if (stbMeta->suid != ctx->tbInfo.suid) { if (stbMeta->suid != ctx->tbInfo.suid) {
ctgError("stb:0x%" PRIx64 ", suid in stbCache mis-match, expected suid:0x%" PRIx64, stbMeta->suid, ctx->tbInfo.suid); ctgError("stb:0x%" PRIx64 ", suid in stbCache mis-match, expected suid:0x%" PRIx64, stbMeta->suid, ctx->tbInfo.suid);
taosMemoryFreeClear(*pTableMeta); taosMemoryFreeClear(*pTableMeta);
taosMemoryFreeClear(tmpRef);
CTG_ERR_RET(TSDB_CODE_CTG_INTERNAL_ERROR); CTG_ERR_RET(TSDB_CODE_CTG_INTERNAL_ERROR);
} }
@ -602,12 +625,13 @@ int32_t ctgCopyTbMeta(SCatalog *pCtg, SCtgTbMetaCtx *ctx, SCtgDBCache **pDb, SCt
if (stbMeta->schemaExt) { if (stbMeta->schemaExt) {
schemaExtSize = stbMeta->tableInfo.numOfColumns * sizeof(SSchemaExt); schemaExtSize = stbMeta->tableInfo.numOfColumns * sizeof(SSchemaExt);
} }
*pTableMeta = taosMemoryRealloc(*pTableMeta, metaSize + schemaExtSize); *pTableMeta = taosMemoryRealloc(*pTableMeta, metaSize + schemaExtSize + colRefSize);
if (NULL == *pTableMeta) { if (NULL == *pTableMeta) {
taosMemoryFreeClear(tmpRef);
CTG_ERR_RET(terrno); CTG_ERR_RET(terrno);
} }
TAOS_MEMCPY(&(*pTableMeta)->sversion, &stbMeta->sversion, metaSize - sizeof(SCTableMeta)); TAOS_MEMCPY(&(*pTableMeta)->numOfColRefs, &stbMeta->numOfColRefs, metaSize - sizeof(SCTableMeta));
if (stbMeta->schemaExt) { if (stbMeta->schemaExt) {
(*pTableMeta)->schemaExt = (SSchemaExt*)((char*)*pTableMeta + metaSize); (*pTableMeta)->schemaExt = (SSchemaExt*)((char*)*pTableMeta + metaSize);
TAOS_MEMCPY((*pTableMeta)->schemaExt, stbMeta->schemaExt, schemaExtSize); TAOS_MEMCPY((*pTableMeta)->schemaExt, stbMeta->schemaExt, schemaExtSize);
@ -615,6 +639,15 @@ int32_t ctgCopyTbMeta(SCatalog *pCtg, SCtgTbMetaCtx *ctx, SCtgDBCache **pDb, SCt
(*pTableMeta)->schemaExt = NULL; (*pTableMeta)->schemaExt = NULL;
} }
if (colRefSize != 0) {
(*pTableMeta)->colRef = (SColRef *)((char *)*pTableMeta + metaSize + schemaExtSize);
(*pTableMeta)->numOfColRefs = numOfColRefs;
TAOS_MEMCPY((*pTableMeta)->colRef, tmpRef, colRefSize);
} else {
(*pTableMeta)->colRef = NULL;
}
taosMemoryFreeClear(tmpRef);
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
@ -1230,6 +1263,7 @@ _return:
if (output) { if (output) {
taosMemoryFree(output->tbMeta); taosMemoryFree(output->tbMeta);
taosMemoryFree(output->vctbMeta);
taosMemoryFree(output); taosMemoryFree(output);
} }
@ -2433,12 +2467,14 @@ int32_t ctgOpUpdateTbMeta(SCtgCacheOperation *operation) {
goto _return; goto _return;
} }
if ((!CTG_IS_META_CTABLE(pMeta->metaType)) && NULL == pMeta->tbMeta) { if ((!CTG_IS_META_CTABLE(pMeta->metaType) && !CTG_IS_META_VCTABLE(pMeta->metaType)) && NULL == pMeta->tbMeta) {
ctgError("no valid tbmeta got from meta rsp, db:%s, tbName:%s", pMeta->dbFName, pMeta->tbName); ctgError("no valid tbmeta got from meta rsp, db:%s, tbName:%s", pMeta->dbFName, pMeta->tbName);
CTG_ERR_JRET(TSDB_CODE_CTG_INTERNAL_ERROR); CTG_ERR_JRET(TSDB_CODE_CTG_INTERNAL_ERROR);
} }
if (CTG_IS_META_BOTH(pMeta->metaType) && TSDB_SUPER_TABLE != pMeta->tbMeta->tableType) { if ((CTG_IS_META_BOTH(pMeta->metaType) ||
CTG_IS_META_VBOTH(pMeta->metaType)) &&
TSDB_SUPER_TABLE != pMeta->tbMeta->tableType) {
ctgError("table type error, expected:%d, actual:%d", TSDB_SUPER_TABLE, pMeta->tbMeta->tableType); ctgError("table type error, expected:%d, actual:%d", TSDB_SUPER_TABLE, pMeta->tbMeta->tableType);
CTG_ERR_JRET(TSDB_CODE_CTG_INTERNAL_ERROR); CTG_ERR_JRET(TSDB_CODE_CTG_INTERNAL_ERROR);
} }
@ -2449,7 +2485,7 @@ int32_t ctgOpUpdateTbMeta(SCtgCacheOperation *operation) {
CTG_ERR_JRET(TSDB_CODE_CTG_INTERNAL_ERROR); CTG_ERR_JRET(TSDB_CODE_CTG_INTERNAL_ERROR);
} }
if (CTG_IS_META_TABLE(pMeta->metaType) || CTG_IS_META_BOTH(pMeta->metaType)) { if (CTG_IS_META_TABLE(pMeta->metaType) || CTG_IS_META_BOTH(pMeta->metaType) || CTG_IS_META_VBOTH(pMeta->metaType)) {
code = ctgWriteTbMetaToCache(pCtg, dbCache, pMeta->dbFName, pMeta->dbId, pMeta->tbName, pMeta->tbMeta); code = ctgWriteTbMetaToCache(pCtg, dbCache, pMeta->dbFName, pMeta->dbId, pMeta->tbName, pMeta->tbMeta);
pMeta->tbMeta = NULL; pMeta->tbMeta = NULL;
CTG_ERR_JRET(code); CTG_ERR_JRET(code);
@ -2465,9 +2501,16 @@ int32_t ctgOpUpdateTbMeta(SCtgCacheOperation *operation) {
(STableMeta *)ctbMeta)); (STableMeta *)ctbMeta));
} }
if (CTG_IS_META_VCTABLE(pMeta->metaType) || CTG_IS_META_VBOTH(pMeta->metaType)) {
code = ctgWriteTbMetaToCache(pCtg, dbCache, pMeta->dbFName, pMeta->dbId, pMeta->ctbName, (STableMeta *)pMeta->vctbMeta);
pMeta->vctbMeta = NULL;
CTG_ERR_JRET(code);
}
_return: _return:
taosMemoryFreeClear(pMeta->tbMeta); taosMemoryFreeClear(pMeta->tbMeta);
taosMemoryFreeClear(pMeta->vctbMeta);
taosMemoryFreeClear(pMeta); taosMemoryFreeClear(pMeta);
taosMemoryFreeClear(msg); taosMemoryFreeClear(msg);
@ -3162,6 +3205,7 @@ void ctgFreeCacheOperationData(SCtgCacheOperation *op) {
case CTG_OP_UPDATE_TB_META: { case CTG_OP_UPDATE_TB_META: {
SCtgUpdateTbMetaMsg *msg = op->data; SCtgUpdateTbMetaMsg *msg = op->data;
taosMemoryFreeClear(msg->pMeta->tbMeta); taosMemoryFreeClear(msg->pMeta->tbMeta);
taosMemoryFreeClear(msg->pMeta->vctbMeta);
taosMemoryFreeClear(msg->pMeta); taosMemoryFreeClear(msg->pMeta);
taosMemoryFreeClear(op->data); taosMemoryFreeClear(op->data);
break; break;
@ -3426,6 +3470,7 @@ int32_t ctgGetTbMetasFromCache(SCatalog *pCtg, SRequestConnInfo *pConn, SCtgTbMe
int32_t code = TSDB_CODE_SUCCESS; int32_t code = TSDB_CODE_SUCCESS;
uint64_t lastSuid = 0; uint64_t lastSuid = 0;
STableMeta *lastTableMeta = NULL; STableMeta *lastTableMeta = NULL;
SColRef *tmpRef = NULL;
SName *pName = taosArrayGet(pList, 0); SName *pName = taosArrayGet(pList, 0);
if (NULL == pName) { if (NULL == pName) {
ctgError("fail to get the 0th SName from tableList, tableNum:%d", (int32_t)taosArrayGetSize(pList)); ctgError("fail to get the 0th SName from tableList, tableNum:%d", (int32_t)taosArrayGetSize(pList));
@ -3505,26 +3550,37 @@ int32_t ctgGetTbMetasFromCache(SCatalog *pCtg, SRequestConnInfo *pConn, SCtgTbMe
SMetaRes res = {0}; SMetaRes res = {0};
STableMeta *pTableMeta = NULL; STableMeta *pTableMeta = NULL;
if (tbMeta->tableType != TSDB_CHILD_TABLE) { if (tbMeta->tableType != TSDB_CHILD_TABLE && tbMeta->tableType != TSDB_VIRTUAL_CHILD_TABLE) {
int32_t schemaExtSize = 0; int32_t schemaExtSize = 0;
int32_t colRefSize = 0;
int32_t metaSize = CTG_META_SIZE(tbMeta); int32_t metaSize = CTG_META_SIZE(tbMeta);
if (tbMeta->schemaExt != NULL) { if (withExtSchema(tbMeta->tableType) && tbMeta->schemaExt != NULL) {
schemaExtSize = tbMeta->tableInfo.numOfColumns * sizeof(SSchemaExt); schemaExtSize = tbMeta->tableInfo.numOfColumns * sizeof(SSchemaExt);
} }
if (hasRefCol(tbMeta->tableType) && tbMeta->colRef) {
colRefSize = tbMeta->tableInfo.numOfColumns * sizeof(SColRef);
}
pTableMeta = taosMemoryCalloc(1, metaSize + schemaExtSize); pTableMeta = taosMemoryCalloc(1, metaSize + schemaExtSize + colRefSize);
if (NULL == pTableMeta) { if (NULL == pTableMeta) {
ctgReleaseTbMetaToCache(pCtg, dbCache, pCache); ctgReleaseTbMetaToCache(pCtg, dbCache, pCache);
CTG_ERR_RET(terrno); CTG_ERR_RET(terrno);
} }
TAOS_MEMCPY(pTableMeta, tbMeta, metaSize); TAOS_MEMCPY(pTableMeta, tbMeta, metaSize);
if (tbMeta->schemaExt != NULL) { if (withExtSchema(tbMeta->tableType) && tbMeta->schemaExt != NULL) {
pTableMeta->schemaExt = (SSchemaExt *)((char *)pTableMeta + metaSize); pTableMeta->schemaExt = (SSchemaExt *)((char *)pTableMeta + metaSize);
TAOS_MEMCPY(pTableMeta->schemaExt, tbMeta->schemaExt, schemaExtSize); TAOS_MEMCPY(pTableMeta->schemaExt, tbMeta->schemaExt, schemaExtSize);
} else { } else {
pTableMeta->schemaExt = NULL; pTableMeta->schemaExt = NULL;
} }
if (hasRefCol(tbMeta->tableType) && tbMeta->colRef) {
pTableMeta->colRef = (SColRef *)((char *)pTableMeta + metaSize + schemaExtSize);
pTableMeta->numOfColRefs = tbMeta->tableInfo.numOfColumns;
TAOS_MEMCPY(pTableMeta->colRef, tbMeta->colRef, colRefSize);
} else {
pTableMeta->colRef = NULL;
}
CTG_UNLOCK(CTG_READ, &pCache->metaLock); CTG_UNLOCK(CTG_READ, &pCache->metaLock);
taosHashRelease(dbCache->tbCache, pCache); taosHashRelease(dbCache->tbCache, pCache);
@ -3541,7 +3597,7 @@ int32_t ctgGetTbMetasFromCache(SCatalog *pCtg, SRequestConnInfo *pConn, SCtgTbMe
// PROCESS FOR CHILD TABLE // PROCESS FOR CHILD TABLE
if (lastSuid && tbMeta->suid == lastSuid && lastTableMeta) { if (lastSuid && tbMeta->suid == lastSuid && lastTableMeta && tbMeta->tableType != TSDB_VIRTUAL_CHILD_TABLE) {
code = cloneTableMeta(lastTableMeta, &pTableMeta); code = cloneTableMeta(lastTableMeta, &pTableMeta);
if (code) { if (code) {
CTG_UNLOCK(CTG_READ, &pCache->metaLock); CTG_UNLOCK(CTG_READ, &pCache->metaLock);
@ -3565,12 +3621,23 @@ int32_t ctgGetTbMetasFromCache(SCatalog *pCtg, SRequestConnInfo *pConn, SCtgTbMe
} }
int32_t metaSize = sizeof(SCTableMeta); int32_t metaSize = sizeof(SCTableMeta);
int32_t colRefSize = 0;
int32_t colRefNum = 0;
pTableMeta = taosMemoryCalloc(1, metaSize); pTableMeta = taosMemoryCalloc(1, metaSize);
if (NULL == pTableMeta) { if (NULL == pTableMeta) {
ctgReleaseTbMetaToCache(pCtg, dbCache, pCache); ctgReleaseTbMetaToCache(pCtg, dbCache, pCache);
CTG_ERR_RET(terrno); CTG_ERR_RET(terrno);
} }
if (hasRefCol(tbMeta->tableType) && tbMeta->colRef != NULL) {
colRefSize = tbMeta->numOfColRefs * sizeof(SColRef);
colRefNum = tbMeta->numOfColRefs;
taosMemoryFreeClear(tmpRef);
tmpRef = taosMemoryMalloc(colRefSize);
TAOS_MEMCPY(tmpRef, tbMeta->colRef, colRefSize);
}
TAOS_MEMCPY(pTableMeta, tbMeta, metaSize); TAOS_MEMCPY(pTableMeta, tbMeta, metaSize);
CTG_UNLOCK(CTG_READ, &pCache->metaLock); CTG_UNLOCK(CTG_READ, &pCache->metaLock);
@ -3651,19 +3718,29 @@ int32_t ctgGetTbMetasFromCache(SCatalog *pCtg, SRequestConnInfo *pConn, SCtgTbMe
schemaExtSize = stbMeta->tableInfo.numOfColumns * sizeof(SSchemaExt); schemaExtSize = stbMeta->tableInfo.numOfColumns * sizeof(SSchemaExt);
} }
metaSize = CTG_META_SIZE(stbMeta); metaSize = CTG_META_SIZE(stbMeta);
pTableMeta = taosMemoryRealloc(pTableMeta, metaSize + schemaExtSize); pTableMeta = taosMemoryRealloc(pTableMeta, metaSize + schemaExtSize + colRefSize);
if (NULL == pTableMeta) { if (NULL == pTableMeta) {
ctgReleaseTbMetaToCache(pCtg, dbCache, pCache); ctgReleaseTbMetaToCache(pCtg, dbCache, pCache);
taosMemoryFreeClear(tmpRef);
CTG_ERR_RET(terrno); CTG_ERR_RET(terrno);
} }
TAOS_MEMCPY(&pTableMeta->sversion, &stbMeta->sversion, metaSize + schemaExtSize - sizeof(SCTableMeta)); TAOS_MEMCPY(&pTableMeta->numOfColRefs, &stbMeta->numOfColRefs, metaSize + schemaExtSize - sizeof(SCTableMeta));
if (stbMeta->schemaExt != NULL) { if (withExtSchema(stbMeta->tableType) && stbMeta->schemaExt != NULL) {
pTableMeta->schemaExt = (SSchemaExt *)((char *)pTableMeta + metaSize); pTableMeta->schemaExt = (SSchemaExt *)((char *)pTableMeta + metaSize);
} else { } else {
pTableMeta->schemaExt = NULL; pTableMeta->schemaExt = NULL;
} }
if (colRefSize != 0) {
pTableMeta->numOfColRefs = colRefNum;
pTableMeta->colRef = (SColRef *)((char *)pTableMeta + metaSize + schemaExtSize);
TAOS_MEMCPY(pTableMeta->colRef, tmpRef, colRefSize);
} else {
pTableMeta->colRef = NULL;
}
taosMemoryFreeClear(tmpRef);
CTG_UNLOCK(CTG_READ, &pCache->metaLock); CTG_UNLOCK(CTG_READ, &pCache->metaLock);
taosHashRelease(dbCache->tbCache, pCache); taosHashRelease(dbCache->tbCache, pCache);
@ -3679,7 +3756,7 @@ int32_t ctgGetTbMetasFromCache(SCatalog *pCtg, SRequestConnInfo *pConn, SCtgTbMe
} }
_return: _return:
taosMemoryFreeClear(tmpRef);
ctgReleaseDBCache(pCtg, dbCache); ctgReleaseDBCache(pCtg, dbCache);
return code; return code;

View File

@ -591,6 +591,7 @@ void ctgFreeMsgCtx(SCtgMsgCtx* pCtx) {
case TDMT_VND_TABLE_NAME: { case TDMT_VND_TABLE_NAME: {
STableMetaOutput* pOut = (STableMetaOutput*)pCtx->out; STableMetaOutput* pOut = (STableMetaOutput*)pCtx->out;
taosMemoryFree(pOut->tbMeta); taosMemoryFree(pOut->tbMeta);
taosMemoryFree(pOut->vctbMeta);
taosMemoryFreeClear(pCtx->out); taosMemoryFreeClear(pCtx->out);
break; break;
} }
@ -676,6 +677,7 @@ void ctgFreeSTableMetaOutput(STableMetaOutput* pOutput) {
} }
taosMemoryFree(pOutput->tbMeta); taosMemoryFree(pOutput->tbMeta);
taosMemoryFree(pOutput->vctbMeta);
taosMemoryFree(pOutput); taosMemoryFree(pOutput);
} }
@ -1681,15 +1683,42 @@ int32_t ctgCloneMetaOutput(STableMetaOutput* output, STableMetaOutput** pOutput)
TAOS_MEMCPY(*pOutput, output, sizeof(STableMetaOutput)); TAOS_MEMCPY(*pOutput, output, sizeof(STableMetaOutput));
if (output->vctbMeta) {
int32_t metaSize = sizeof(SVCTableMeta);
int32_t colRefSize = 0;
if (hasRefCol(output->vctbMeta->tableType) && (*pOutput)->vctbMeta->colRef) {
colRefSize = output->vctbMeta->numOfColRefs * sizeof(SColRef);
}
(*pOutput)->vctbMeta = taosMemoryMalloc(metaSize + colRefSize);
if (NULL == (*pOutput)->vctbMeta) {
qError("malloc %d failed", (int32_t)sizeof(STableMetaOutput));
taosMemoryFreeClear(*pOutput);
CTG_ERR_RET(terrno);
}
TAOS_MEMCPY((*pOutput)->vctbMeta, output->vctbMeta, metaSize);
if (hasRefCol(output->vctbMeta->tableType) && (*pOutput)->vctbMeta->colRef) {
(*pOutput)->vctbMeta->colRef = (SColRef*)((char*)(*pOutput)->vctbMeta + metaSize);
TAOS_MEMCPY((*pOutput)->vctbMeta->colRef, output->vctbMeta->colRef, colRefSize);
} else {
(*pOutput)->vctbMeta->colRef = NULL;
}
}
if (output->tbMeta) { if (output->tbMeta) {
int32_t metaSize = CTG_META_SIZE(output->tbMeta); int32_t metaSize = CTG_META_SIZE(output->tbMeta);
int32_t schemaExtSize = 0; int32_t schemaExtSize = 0;
int32_t colRefSize = 0;
if (withExtSchema(output->tbMeta->tableType) && (*pOutput)->tbMeta->schemaExt) { if (withExtSchema(output->tbMeta->tableType) && (*pOutput)->tbMeta->schemaExt) {
schemaExtSize = output->tbMeta->tableInfo.numOfColumns * sizeof(SSchemaExt); schemaExtSize = output->tbMeta->tableInfo.numOfColumns * sizeof(SSchemaExt);
} }
if (hasRefCol(output->tbMeta->tableType) && (*pOutput)->tbMeta->colRef) {
colRefSize = output->tbMeta->tableInfo.numOfColumns * sizeof(SColRef);
}
(*pOutput)->tbMeta = taosMemoryMalloc(metaSize + schemaExtSize); (*pOutput)->tbMeta = taosMemoryMalloc(metaSize + schemaExtSize + colRefSize);
qTrace("tbmeta cloned, size:%d, p:%p", metaSize, (*pOutput)->tbMeta); qTrace("tbmeta cloned, size:%d, p:%p", metaSize, (*pOutput)->tbMeta);
if (NULL == (*pOutput)->tbMeta) { if (NULL == (*pOutput)->tbMeta) {
qError("malloc %d failed", (int32_t)sizeof(STableMetaOutput)); qError("malloc %d failed", (int32_t)sizeof(STableMetaOutput));
taosMemoryFreeClear(*pOutput); taosMemoryFreeClear(*pOutput);
@ -1703,6 +1732,12 @@ int32_t ctgCloneMetaOutput(STableMetaOutput* output, STableMetaOutput** pOutput)
} else { } else {
(*pOutput)->tbMeta->schemaExt = NULL; (*pOutput)->tbMeta->schemaExt = NULL;
} }
if (hasRefCol(output->tbMeta->tableType) && (*pOutput)->tbMeta->colRef) {
(*pOutput)->tbMeta->colRef = (SColRef*)((char*)(*pOutput)->tbMeta + metaSize + schemaExtSize);
TAOS_MEMCPY((*pOutput)->tbMeta->colRef, output->tbMeta->colRef, colRefSize);
} else {
(*pOutput)->tbMeta->colRef = NULL;
}
} }
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
@ -2087,12 +2122,12 @@ int32_t ctgChkSetTbAuthRes(SCatalog* pCtg, SCtgAuthReq* req, SCtgAuthRsp* res) {
CTG_ERR_JRET(ctgGetTbMeta(pCtg, req->pConn, &ctx, &pMeta)); CTG_ERR_JRET(ctgGetTbMeta(pCtg, req->pConn, &ctx, &pMeta));
} }
if (TSDB_SUPER_TABLE == pMeta->tableType || TSDB_NORMAL_TABLE == pMeta->tableType) { if (TSDB_SUPER_TABLE == pMeta->tableType || TSDB_NORMAL_TABLE == pMeta->tableType || TSDB_VIRTUAL_NORMAL_TABLE == pMeta->tableType) {
res->pRawRes->pass[AUTH_RES_BASIC] = false; res->pRawRes->pass[AUTH_RES_BASIC] = false;
goto _return; goto _return;
} }
if (TSDB_CHILD_TABLE == pMeta->tableType) { if (TSDB_CHILD_TABLE == pMeta->tableType || TSDB_VIRTUAL_CHILD_TABLE == pMeta->tableType) {
CTG_ERR_JRET(ctgGetCachedStbNameFromSuid(pCtg, dbFName, pMeta->suid, &stbName)); CTG_ERR_JRET(ctgGetCachedStbNameFromSuid(pCtg, dbFName, pMeta->suid, &stbName));
if (NULL == stbName) { if (NULL == stbName) {
if (req->onlyCache) { if (req->onlyCache) {
@ -2410,6 +2445,8 @@ FORCE_INLINE uint64_t ctgGetTbMetaCacheSize(STableMeta* pMeta) {
return sizeof(*pMeta) + (pMeta->tableInfo.numOfColumns + pMeta->tableInfo.numOfTags) * sizeof(SSchema); return sizeof(*pMeta) + (pMeta->tableInfo.numOfColumns + pMeta->tableInfo.numOfTags) * sizeof(SSchema);
case TSDB_CHILD_TABLE: case TSDB_CHILD_TABLE:
return sizeof(SCTableMeta); return sizeof(SCTableMeta);
case TSDB_VIRTUAL_CHILD_TABLE:
return sizeof(SVCTableMeta);
default: default:
return sizeof(*pMeta) + pMeta->tableInfo.numOfColumns * sizeof(SSchema); return sizeof(*pMeta) + pMeta->tableInfo.numOfColumns * sizeof(SSchema);
} }

View File

@ -210,6 +210,8 @@ void ctgTestBuildCTableMetaOutput(STableMetaOutput *output) {
output->tbMeta->sversion = ctgTestSVersion; output->tbMeta->sversion = ctgTestSVersion;
output->tbMeta->tversion = ctgTestTVersion; output->tbMeta->tversion = ctgTestTVersion;
output->vctbMeta = NULL;
SSchema *s = NULL; SSchema *s = NULL;
s = &output->tbMeta->schema[0]; s = &output->tbMeta->schema[0];
s->type = TSDB_DATA_TYPE_TIMESTAMP; s->type = TSDB_DATA_TYPE_TIMESTAMP;

View File

@ -29,6 +29,7 @@ extern "C" {
//newline area //newline area
#define EXPLAIN_TAG_SCAN_FORMAT "Tag Scan on %s" #define EXPLAIN_TAG_SCAN_FORMAT "Tag Scan on %s"
#define EXPLAIN_VIRTUAL_TABLE_SCAN_FORMAT "Virtual Table Scan on %s"
#define EXPLAIN_TBL_SCAN_FORMAT "Table Scan on %s" #define EXPLAIN_TBL_SCAN_FORMAT "Table Scan on %s"
#define EXPLAIN_TBL_MERGE_SCAN_FORMAT "Table Merge Scan on %s" #define EXPLAIN_TBL_MERGE_SCAN_FORMAT "Table Merge Scan on %s"
#define EXPLAIN_SYSTBL_SCAN_FORMAT "System Table Scan on %s" #define EXPLAIN_SYSTBL_SCAN_FORMAT "System Table Scan on %s"

View File

@ -122,7 +122,10 @@ static int32_t buildDescResultDataBlock(SSDataBlock** pOutput) {
infoData = createColumnInfoData(TSDB_DATA_TYPE_VARCHAR, DESCRIBE_RESULT_COPRESS_OPTION_LEN, 7); infoData = createColumnInfoData(TSDB_DATA_TYPE_VARCHAR, DESCRIBE_RESULT_COPRESS_OPTION_LEN, 7);
code = blockDataAppendColInfo(pBlock, &infoData); code = blockDataAppendColInfo(pBlock, &infoData);
} }
if (TSDB_CODE_SUCCESS == code) {
infoData = createColumnInfoData(TSDB_DATA_TYPE_VARCHAR, DESCRIBE_RESULT_COL_REF_LEN, 8);
code = blockDataAppendColInfo(pBlock, &infoData);
}
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
*pOutput = pBlock; *pOutput = pBlock;
} else { } else {
@ -151,12 +154,18 @@ static int32_t setDescResultIntoDataBlock(bool sysInfoUser, SSDataBlock* pBlock,
SColumnInfoData* pCol6 = NULL; SColumnInfoData* pCol6 = NULL;
// level // level
SColumnInfoData* pCol7 = NULL; SColumnInfoData* pCol7 = NULL;
// colref
SColumnInfoData* pCol8 = NULL;
if (withExtSchema(pMeta->tableType)) { if (withExtSchema(pMeta->tableType)) {
pCol5 = taosArrayGet(pBlock->pDataBlock, 4); pCol5 = taosArrayGet(pBlock->pDataBlock, 4);
pCol6 = taosArrayGet(pBlock->pDataBlock, 5); pCol6 = taosArrayGet(pBlock->pDataBlock, 5);
pCol7 = taosArrayGet(pBlock->pDataBlock, 6); pCol7 = taosArrayGet(pBlock->pDataBlock, 6);
} }
if (hasRefCol(pMeta->tableType)) {
pCol5 = taosArrayGet(pBlock->pDataBlock, 4);
}
int32_t fillTagCol = 0; int32_t fillTagCol = 0;
char buf[DESCRIBE_RESULT_FIELD_LEN] = {0}; char buf[DESCRIBE_RESULT_FIELD_LEN] = {0};
for (int32_t i = 0; i < numOfRows; ++i) { for (int32_t i = 0; i < numOfRows; ++i) {
@ -207,6 +216,24 @@ static int32_t setDescResultIntoDataBlock(bool sysInfoUser, SSDataBlock* pBlock,
STR_TO_VARSTR(buf, fillTagCol == 0 ? "" : "disabled"); STR_TO_VARSTR(buf, fillTagCol == 0 ? "" : "disabled");
COL_DATA_SET_VAL_AND_CHECK(pCol7, pBlock->info.rows, buf, false); COL_DATA_SET_VAL_AND_CHECK(pCol7, pBlock->info.rows, buf, false);
} }
} else if (hasRefCol(pMeta->tableType) && pMeta->colRef) {
if (i < pMeta->numOfColRefs) {
if (pMeta->colRef[i].hasRef) {
char refColName[TSDB_DB_NAME_LEN + TSDB_NAME_DELIMITER_LEN + TSDB_COL_FNAME_LEN] = {0};
strcat(refColName, pMeta->colRef[i].refDbName);
strcat(refColName, ".");
strcat(refColName, pMeta->colRef[i].refTableName);
strcat(refColName, ".");
strcat(refColName, pMeta->colRef[i].refColName);
STR_TO_VARSTR(buf, refColName);
} else {
STR_TO_VARSTR(buf, "");
}
COL_DATA_SET_VAL_AND_CHECK(pCol5, pBlock->info.rows, buf, false);
} else {
STR_TO_VARSTR(buf, "");
COL_DATA_SET_VAL_AND_CHECK(pCol5, pBlock->info.rows, buf, false);
}
} }
fillTagCol = 0; fillTagCol = 0;
@ -244,8 +271,14 @@ static int32_t execDescribe(bool sysInfoUser, SNode* pStmt, SRetrieveTableRsp**
code = setDescResultIntoDataBlock(sysInfoUser, pBlock, numOfRows, pDesc->pMeta, biMode); code = setDescResultIntoDataBlock(sysInfoUser, pBlock, numOfRows, pDesc->pMeta, biMode);
} }
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
if (pDesc->pMeta && withExtSchema(pDesc->pMeta->tableType) && pDesc->pMeta->schemaExt) { if (pDesc->pMeta) {
if (withExtSchema(pDesc->pMeta->tableType) && pDesc->pMeta->schemaExt) {
code = buildRetrieveTableRsp(pBlock, DESCRIBE_RESULT_COLS_COMPRESS, pRsp); code = buildRetrieveTableRsp(pBlock, DESCRIBE_RESULT_COLS_COMPRESS, pRsp);
} else if (hasRefCol(pDesc->pMeta->tableType) && pDesc->pMeta->colRef) {
code = buildRetrieveTableRsp(pBlock, DESCRIBE_RESULT_COLS_REF, pRsp);
} else {
code = buildRetrieveTableRsp(pBlock, DESCRIBE_RESULT_COLS, pRsp);
}
} else { } else {
code = buildRetrieveTableRsp(pBlock, DESCRIBE_RESULT_COLS, pRsp); code = buildRetrieveTableRsp(pBlock, DESCRIBE_RESULT_COLS, pRsp);
} }
@ -536,7 +569,8 @@ static int32_t buildCreateViewResultDataBlock(SSDataBlock** pOutput) {
static void appendColumnFields(char* buf, int32_t* len, STableCfg* pCfg) { static void appendColumnFields(char* buf, int32_t* len, STableCfg* pCfg) {
for (int32_t i = 0; i < pCfg->numOfColumns; ++i) { for (int32_t i = 0; i < pCfg->numOfColumns; ++i) {
SSchema* pSchema = pCfg->pSchemas + i; SSchema* pSchema = pCfg->pSchemas + i;
#define LTYPE_LEN (32 + 60) // 60 byte for compress info SColRef* pRef = pCfg->pColRefs + i;
#define LTYPE_LEN (32 + 60 + TSDB_COL_FNAME_LEN + TSDB_DB_NAME_LEN + 10) // 60 byte for compress info, TSDB_COL_FNAME_LEN + TSDB_DB_NAME_LEN for column ref
char type[LTYPE_LEN]; char type[LTYPE_LEN];
snprintf(type, LTYPE_LEN, "%s", tDataTypes[pSchema->type].name); snprintf(type, LTYPE_LEN, "%s", tDataTypes[pSchema->type].name);
int typeLen = strlen(type); int typeLen = strlen(type);
@ -560,6 +594,15 @@ static void appendColumnFields(char* buf, int32_t* len, STableCfg* pCfg) {
typeLen += tsnprintf(type + typeLen, LTYPE_LEN - typeLen, " LEVEL \'%s\'", typeLen += tsnprintf(type + typeLen, LTYPE_LEN - typeLen, " LEVEL \'%s\'",
columnLevelStr(COMPRESS_L2_TYPE_LEVEL_U32(pCfg->pSchemaExt[i].compress))); columnLevelStr(COMPRESS_L2_TYPE_LEVEL_U32(pCfg->pSchemaExt[i].compress)));
} }
if (hasRefCol(pCfg->tableType) && pCfg->pColRefs && pRef->hasRef) {
typeLen += tsnprintf(type + typeLen, LTYPE_LEN - typeLen, " FROM `%s`", pRef->refDbName);
typeLen += tsnprintf(type + typeLen, LTYPE_LEN - typeLen, ".");
typeLen += tsnprintf(type + typeLen, LTYPE_LEN - typeLen, "`%s`", pRef->refTableName);
typeLen += tsnprintf(type + typeLen, LTYPE_LEN - typeLen, ".");
typeLen += tsnprintf(type + typeLen, LTYPE_LEN - typeLen, "`%s`", pRef->refColName);
}
if (!(pSchema->flags & COL_IS_KEY)) { if (!(pSchema->flags & COL_IS_KEY)) {
*len += tsnprintf(buf + VARSTR_HEADER_SIZE + *len, SHOW_CREATE_TB_RESULT_FIELD2_LEN - (VARSTR_HEADER_SIZE + *len), *len += tsnprintf(buf + VARSTR_HEADER_SIZE + *len, SHOW_CREATE_TB_RESULT_FIELD2_LEN - (VARSTR_HEADER_SIZE + *len),
"%s`%s` %s", ((i > 0) ? ", " : ""), pSchema->name, type); "%s`%s` %s", ((i > 0) ? ", " : ""), pSchema->name, type);
@ -571,6 +614,29 @@ static void appendColumnFields(char* buf, int32_t* len, STableCfg* pCfg) {
} }
} }
static void appendColRefFields(char* buf, int32_t* len, STableCfg* pCfg) {
for (int32_t i = 1; i < pCfg->numOfColumns; ++i) {
SSchema* pSchema = pCfg->pSchemas + i;
SColRef* pRef = pCfg->pColRefs + i;
char type[TSDB_COL_NAME_LEN + 10 + TSDB_COL_FNAME_LEN + TSDB_DB_NAME_LEN];
int typeLen = 0;
if (hasRefCol(pCfg->tableType) && pCfg->pColRefs && pRef->hasRef) {
typeLen += tsnprintf(type + typeLen, sizeof(type) - typeLen, "FROM `%s`", pRef->refDbName);
typeLen += tsnprintf(type + typeLen, sizeof(type) - typeLen, ".");
typeLen += tsnprintf(type + typeLen, sizeof(type) - typeLen, "`%s`", pRef->refTableName);
typeLen += tsnprintf(type + typeLen, sizeof(type) - typeLen, ".");
typeLen += tsnprintf(type + typeLen, sizeof(type) - typeLen, "`%s`", pRef->refColName);
} else {
continue;
}
*len += tsnprintf(buf + VARSTR_HEADER_SIZE + *len, SHOW_CREATE_TB_RESULT_FIELD2_LEN - (VARSTR_HEADER_SIZE + *len),
"%s`%s` %s", ((i > 1) ? ", " : ""), pSchema->name, type);
}
}
static void appendTagFields(char* buf, int32_t* len, STableCfg* pCfg) { static void appendTagFields(char* buf, int32_t* len, STableCfg* pCfg) {
for (int32_t i = 0; i < pCfg->numOfTags; ++i) { for (int32_t i = 0; i < pCfg->numOfTags; ++i) {
SSchema* pSchema = pCfg->pSchemas + pCfg->numOfColumns + i; SSchema* pSchema = pCfg->pSchemas + pCfg->numOfColumns + i;
@ -749,6 +815,11 @@ static void appendTableOptions(char* buf, int32_t* len, SDbCfgInfo* pDbCfg, STab
*len += tsnprintf(buf + VARSTR_HEADER_SIZE + *len, SHOW_CREATE_TB_RESULT_FIELD2_LEN - VARSTR_HEADER_SIZE, ")"); *len += tsnprintf(buf + VARSTR_HEADER_SIZE + *len, SHOW_CREATE_TB_RESULT_FIELD2_LEN - VARSTR_HEADER_SIZE, ")");
} }
} }
if (pCfg->virtualStb) {
*len += tsnprintf(buf + VARSTR_HEADER_SIZE + *len, SHOW_CREATE_TB_RESULT_FIELD2_LEN - (VARSTR_HEADER_SIZE + *len),
" VIRTUAL %d", pCfg->virtualStb);
}
} }
static int32_t setCreateTBResultIntoDataBlock(SSDataBlock* pBlock, SDbCfgInfo* pDbCfg, char* tbName, STableCfg* pCfg, static int32_t setCreateTBResultIntoDataBlock(SSDataBlock* pBlock, SDbCfgInfo* pDbCfg, char* tbName, STableCfg* pCfg,
@ -791,13 +862,33 @@ static int32_t setCreateTBResultIntoDataBlock(SSDataBlock* pBlock, SDbCfgInfo* p
len += len +=
snprintf(buf2 + VARSTR_HEADER_SIZE + len, SHOW_CREATE_TB_RESULT_FIELD2_LEN - (VARSTR_HEADER_SIZE + len), ")"); snprintf(buf2 + VARSTR_HEADER_SIZE + len, SHOW_CREATE_TB_RESULT_FIELD2_LEN - (VARSTR_HEADER_SIZE + len), ")");
appendTableOptions(buf2, &len, pDbCfg, pCfg); appendTableOptions(buf2, &len, pDbCfg, pCfg);
} else { } else if (TSDB_NORMAL_TABLE == pCfg->tableType){
len += tsnprintf(buf2 + VARSTR_HEADER_SIZE, SHOW_CREATE_TB_RESULT_FIELD2_LEN - VARSTR_HEADER_SIZE, len += tsnprintf(buf2 + VARSTR_HEADER_SIZE, SHOW_CREATE_TB_RESULT_FIELD2_LEN - VARSTR_HEADER_SIZE,
"CREATE TABLE `%s` (", tbName); "CREATE TABLE `%s` (", tbName);
appendColumnFields(buf2, &len, pCfg); appendColumnFields(buf2, &len, pCfg);
len += len +=
snprintf(buf2 + VARSTR_HEADER_SIZE + len, SHOW_CREATE_TB_RESULT_FIELD2_LEN - (VARSTR_HEADER_SIZE + len), ")"); snprintf(buf2 + VARSTR_HEADER_SIZE + len, SHOW_CREATE_TB_RESULT_FIELD2_LEN - (VARSTR_HEADER_SIZE + len), ")");
appendTableOptions(buf2, &len, pDbCfg, pCfg); appendTableOptions(buf2, &len, pDbCfg, pCfg);
} else if (TSDB_VIRTUAL_NORMAL_TABLE == pCfg->tableType) {
len += tsnprintf(buf2 + VARSTR_HEADER_SIZE, SHOW_CREATE_TB_RESULT_FIELD2_LEN - VARSTR_HEADER_SIZE,
"CREATE VTABLE `%s` (", tbName);
appendColumnFields(buf2, &len, pCfg);
len +=
snprintf(buf2 + VARSTR_HEADER_SIZE + len, SHOW_CREATE_TB_RESULT_FIELD2_LEN - (VARSTR_HEADER_SIZE + len), ")");
} else if (TSDB_VIRTUAL_CHILD_TABLE == pCfg->tableType) {
len += tsnprintf(buf2 + VARSTR_HEADER_SIZE, SHOW_CREATE_TB_RESULT_FIELD2_LEN - VARSTR_HEADER_SIZE,
"CREATE VTABLE `%s` (", tbName);
appendColRefFields(buf2, &len, pCfg);
len +=
snprintf(buf2 + VARSTR_HEADER_SIZE + len, SHOW_CREATE_TB_RESULT_FIELD2_LEN - (VARSTR_HEADER_SIZE + len),
") USING `%s` (", pCfg->stbName);
appendTagNameFields(buf2, &len, pCfg);
len += tsnprintf(buf2 + VARSTR_HEADER_SIZE + len, SHOW_CREATE_TB_RESULT_FIELD2_LEN - (VARSTR_HEADER_SIZE + len),
") TAGS (");
code = appendTagValues(buf2, &len, pCfg, charsetCxt);
TAOS_CHECK_ERRNO(code);
len +=
snprintf(buf2 + VARSTR_HEADER_SIZE + len, SHOW_CREATE_TB_RESULT_FIELD2_LEN - (VARSTR_HEADER_SIZE + len), ")");
} }
varDataLen(buf2) = (len > 65535) ? 65535 : len; varDataLen(buf2) = (len > 65535) ? 65535 : len;
@ -856,6 +947,19 @@ static int32_t execShowCreateTable(SShowCreateTableStmt* pStmt, SRetrieveTableRs
return code; return code;
} }
static int32_t execShowCreateVTable(SShowCreateTableStmt* pStmt, SRetrieveTableRsp** pRsp, void* charsetCxt) {
SSDataBlock* pBlock = NULL;
int32_t code = buildCreateTbResultDataBlock(&pBlock);
if (TSDB_CODE_SUCCESS == code) {
code = setCreateTBResultIntoDataBlock(pBlock, pStmt->pDbCfg, pStmt->tableName, pStmt->pTableCfg, charsetCxt);
}
if (TSDB_CODE_SUCCESS == code) {
code = buildRetrieveTableRsp(pBlock, SHOW_CREATE_TB_RESULT_COLS, pRsp);
}
(void)blockDataDestroy(pBlock);
return code;
}
static int32_t execShowCreateSTable(SShowCreateTableStmt* pStmt, SRetrieveTableRsp** pRsp, void* charsetCxt) { static int32_t execShowCreateSTable(SShowCreateTableStmt* pStmt, SRetrieveTableRsp** pRsp, void* charsetCxt) {
STableCfg* pCfg = (STableCfg*)pStmt->pTableCfg; STableCfg* pCfg = (STableCfg*)pStmt->pTableCfg;
if (TSDB_SUPER_TABLE != pCfg->tableType) { if (TSDB_SUPER_TABLE != pCfg->tableType) {
@ -1109,6 +1213,8 @@ int32_t qExecCommand(int64_t* pConnId, bool sysInfoUser, SNode* pStmt, SRetrieve
return execShowCreateDatabase((SShowCreateDatabaseStmt*)pStmt, pRsp); return execShowCreateDatabase((SShowCreateDatabaseStmt*)pStmt, pRsp);
case QUERY_NODE_SHOW_CREATE_TABLE_STMT: case QUERY_NODE_SHOW_CREATE_TABLE_STMT:
return execShowCreateTable((SShowCreateTableStmt*)pStmt, pRsp, charsetCxt); return execShowCreateTable((SShowCreateTableStmt*)pStmt, pRsp, charsetCxt);
case QUERY_NODE_SHOW_CREATE_VTABLE_STMT:
return execShowCreateVTable((SShowCreateTableStmt*)pStmt, pRsp, charsetCxt);
case QUERY_NODE_SHOW_CREATE_STABLE_STMT: case QUERY_NODE_SHOW_CREATE_STABLE_STMT:
return execShowCreateSTable((SShowCreateTableStmt*)pStmt, pRsp, charsetCxt); return execShowCreateSTable((SShowCreateTableStmt*)pStmt, pRsp, charsetCxt);
case QUERY_NODE_SHOW_CREATE_VIEW_STMT: case QUERY_NODE_SHOW_CREATE_VIEW_STMT:

View File

@ -420,6 +420,52 @@ static int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx
} }
break; break;
} }
case QUERY_NODE_PHYSICAL_PLAN_VIRTUAL_TABLE_SCAN: {
SVirtualScanPhysiNode *pVirtualTableScanNode = (SVirtualScanPhysiNode *)pNode;
EXPLAIN_ROW_NEW(level, EXPLAIN_VIRTUAL_TABLE_SCAN_FORMAT, pVirtualTableScanNode->scan.tableName.tname);
EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
if (pResNode->pExecInfo) {
QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
}
if (pVirtualTableScanNode->scan.pScanPseudoCols) {
EXPLAIN_ROW_APPEND(EXPLAIN_PSEUDO_COLUMNS_FORMAT, pVirtualTableScanNode->scan.pScanPseudoCols->length);
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
}
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pVirtualTableScanNode->scan.node.pOutputDataBlockDesc->totalRowSize);
EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
EXPLAIN_ROW_END();
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
if (verbose) {
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
nodesGetOutputNumFromSlotList(pVirtualTableScanNode->scan.node.pOutputDataBlockDesc->pSlots));
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pVirtualTableScanNode->scan.node.pOutputDataBlockDesc->outputRowSize);
EXPLAIN_ROW_APPEND_LIMIT(pVirtualTableScanNode->scan.node.pLimit);
EXPLAIN_ROW_APPEND_SLIMIT(pVirtualTableScanNode->scan.node.pSlimit);
EXPLAIN_ROW_END();
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
if (pResNode->pExecInfo) {
QRY_ERR_RET(qExplainBufAppendVerboseExecInfo(pResNode->pExecInfo, tbuf, &tlen));
if (tlen) {
EXPLAIN_ROW_END();
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
}
}
if (pVirtualTableScanNode->scan.node.pConditions) {
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
QRY_ERR_RET(nodesNodeToSQL(pVirtualTableScanNode->scan.node.pConditions, tbuf + VARSTR_HEADER_SIZE,
TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
EXPLAIN_ROW_END();
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
}
}
break;
}
case QUERY_NODE_PHYSICAL_PLAN_TABLE_SEQ_SCAN: case QUERY_NODE_PHYSICAL_PLAN_TABLE_SEQ_SCAN:
case QUERY_NODE_PHYSICAL_PLAN_TABLE_MERGE_SCAN: case QUERY_NODE_PHYSICAL_PLAN_TABLE_MERGE_SCAN:
case QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN: { case QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN: {

View File

@ -52,7 +52,7 @@ typedef struct SDataSinkHandle {
FGetSinkFlags fGetFlags; FGetSinkFlags fGetFlags;
} SDataSinkHandle; } SDataSinkHandle;
int32_t createDataDispatcher(SDataSinkManager* pManager, SDataSinkNode** ppDataSink, DataSinkHandle* pHandle); int32_t createDataDispatcher(SDataSinkManager* pManager, SDataSinkNode** ppDataSink, DataSinkHandle* pHandle, bool processOneBlock);
int32_t createDataDeleter(SDataSinkManager* pManager, SDataSinkNode** ppDataSink, DataSinkHandle* pHandle, int32_t createDataDeleter(SDataSinkManager* pManager, SDataSinkNode** ppDataSink, DataSinkHandle* pHandle,
void* pParam); void* pParam);
int32_t createDataInserter(SDataSinkManager* pManager, SDataSinkNode** ppDataSink, DataSinkHandle* pHandle, int32_t createDataInserter(SDataSinkManager* pManager, SDataSinkNode** ppDataSink, DataSinkHandle* pHandle,

View File

@ -74,10 +74,28 @@ typedef struct SStbJoinDynCtrlInfo {
SDataBlockDescNode* pOutputDataBlockDesc; SDataBlockDescNode* pOutputDataBlockDesc;
} SStbJoinDynCtrlInfo; } SStbJoinDynCtrlInfo;
typedef struct SVtbScanDynCtrlInfo {
int32_t acctId;
SUseDbRsp* pRsp;
SUseDbReq req;
tsem_t ready;
SEpSet epSet;
uint64_t suid;
SReadHandle readHandle;
SArray* childTableList;
int32_t lastTableIdx;
SOperatorParam* vtbScanParam;
int32_t readTableIdx;
SHashObj* dbVgInfoMap;
SArray* readColList;
bool scanAllCols;
} SVtbScanDynCtrlInfo;
typedef struct SDynQueryCtrlOperatorInfo { typedef struct SDynQueryCtrlOperatorInfo {
EDynQueryType qType; EDynQueryType qType;
union { union {
SStbJoinDynCtrlInfo stbJoin; SStbJoinDynCtrlInfo stbJoin;
SVtbScanDynCtrlInfo vtbScan;
}; };
} SDynQueryCtrlOperatorInfo; } SDynQueryCtrlOperatorInfo;

View File

@ -192,6 +192,8 @@ SColumn extractColumnFromColumnNode(SColumnNode* pColNode);
int32_t initQueryTableDataCond(SQueryTableDataCond* pCond, const STableScanPhysiNode* pTableScanNode, int32_t initQueryTableDataCond(SQueryTableDataCond* pCond, const STableScanPhysiNode* pTableScanNode,
const SReadHandle* readHandle); const SReadHandle* readHandle);
int32_t initQueryTableDataCondWithColArray(SQueryTableDataCond* pCond, SQueryTableDataCond* pOrgCond,
const SReadHandle* readHandle, SArray* colArray);
void cleanupQueryTableDataCond(SQueryTableDataCond* pCond); void cleanupQueryTableDataCond(SQueryTableDataCond* pCond);
int32_t convertFillType(int32_t mode); int32_t convertFillType(int32_t mode);

View File

@ -165,6 +165,9 @@ typedef struct SExchangeOperatorBasicParam {
int32_t srcOpType; int32_t srcOpType;
bool tableSeq; bool tableSeq;
SArray* uidList; SArray* uidList;
bool isVtbRefScan;
SOrgTbInfo* colMap;
STimeWindow window;
} SExchangeOperatorBasicParam; } SExchangeOperatorBasicParam;
typedef struct SExchangeOperatorBatchParam { typedef struct SExchangeOperatorBatchParam {
@ -253,6 +256,7 @@ typedef struct STableScanBase {
STsdbReader* dataReader; STsdbReader* dataReader;
SFileBlockLoadRecorder readRecorder; SFileBlockLoadRecorder readRecorder;
SQueryTableDataCond cond; SQueryTableDataCond cond;
SQueryTableDataCond orgCond; // use for virtual super table scan
SAggOptrPushDownInfo pdInfo; SAggOptrPushDownInfo pdInfo;
SColMatchInfo matchInfo; SColMatchInfo matchInfo;
SReadHandle readHandle; SReadHandle readHandle;
@ -283,6 +287,9 @@ typedef struct STableScanInfo {
bool hasGroupByTag; bool hasGroupByTag;
bool filesetDelimited; bool filesetDelimited;
bool needCountEmptyTable; bool needCountEmptyTable;
SSDataBlock* pOrgBlock;
bool ignoreTag;
bool virtualStableScan;
} STableScanInfo; } STableScanInfo;
typedef enum ESubTableInputType { typedef enum ESubTableInputType {
@ -1190,6 +1197,7 @@ void* decodeSTimeWindowAggSupp(void* buf, STimeWindowAggSupp* pTwAggSup);
void destroyOperatorParamValue(void* pValues); void destroyOperatorParamValue(void* pValues);
int32_t mergeOperatorParams(SOperatorParam* pDst, SOperatorParam* pSrc); int32_t mergeOperatorParams(SOperatorParam* pDst, SOperatorParam* pSrc);
int32_t buildTableScanOperatorParam(SOperatorParam** ppRes, SArray* pUidList, int32_t srcOpType, bool tableSeq); int32_t buildTableScanOperatorParam(SOperatorParam** ppRes, SArray* pUidList, int32_t srcOpType, bool tableSeq);
int32_t buildTableScanOperatorParamEx(SOperatorParam** ppRes, SArray* pUidList, int32_t srcOpType, SOrgTbInfo *pMap, bool tableSeq, STimeWindow *window);
void freeExchangeGetBasicOperatorParam(void* pParam); void freeExchangeGetBasicOperatorParam(void* pParam);
void freeOperatorParam(SOperatorParam* pParam, SOperatorParamType type); void freeOperatorParam(SOperatorParam* pParam, SOperatorParamType type);
void freeResetOperatorParams(struct SOperatorInfo* pOperator, SOperatorParamType type, bool allFree); void freeResetOperatorParams(struct SOperatorInfo* pOperator, SOperatorParamType type, bool allFree);

View File

@ -172,7 +172,7 @@ int32_t createGroupCacheOperatorInfo(SOperatorInfo** pDownstream, int32_t numOfD
int32_t createAnomalywindowOperatorInfo(SOperatorInfo* downstream, SPhysiNode* physiNode, SExecTaskInfo* pTaskInfo, SOperatorInfo** pInfo); int32_t createAnomalywindowOperatorInfo(SOperatorInfo* downstream, SPhysiNode* physiNode, SExecTaskInfo* pTaskInfo, SOperatorInfo** pInfo);
int32_t createDynQueryCtrlOperatorInfo(SOperatorInfo** pDownstream, int32_t numOfDownstream, SDynQueryCtrlPhysiNode* pPhyciNode, SExecTaskInfo* pTaskInfo, SOperatorInfo** pInfo); int32_t createDynQueryCtrlOperatorInfo(SOperatorInfo** pDownstream, int32_t numOfDownstream, SDynQueryCtrlPhysiNode* pPhyciNode, SExecTaskInfo* pTaskInfo, SReadHandle* pHandle, SOperatorInfo** pInfo);
int32_t createStreamTimeSliceOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, SReadHandle* pHandle, SOperatorInfo** ppOptInfo); int32_t createStreamTimeSliceOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, SReadHandle* pHandle, SOperatorInfo** ppOptInfo);
@ -186,6 +186,8 @@ int32_t createStateNonblockOperatorInfo(SOperatorInfo* downstream, SPhysiNode* p
int32_t createEventNonblockOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, SReadHandle* pHandle, SOperatorInfo** ppOptInfo); int32_t createEventNonblockOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, SReadHandle* pHandle, SOperatorInfo** ppOptInfo);
int32_t createVirtualTableMergeOperatorInfo(SOperatorInfo** pDownstream, SReadHandle* readHandle, STableListInfo* pTableListInfo, int32_t numOfDownstream, SVirtualScanPhysiNode * pJoinNode, SExecTaskInfo* pTaskInfo, SOperatorInfo** pOptrInfo);
// clang-format on // clang-format on
SOperatorFpSet createOperatorFpSet(__optr_open_fn_t openFn, __optr_fn_t nextFn, __optr_fn_t cleanup, SOperatorFpSet createOperatorFpSet(__optr_open_fn_t openFn, __optr_fn_t nextFn, __optr_fn_t cleanup,

View File

@ -166,6 +166,22 @@ void tsortGetValue(STupleHandle* pVHandle, int32_t colId, void** pVal);
*/ */
uint64_t tsortGetGroupId(STupleHandle* pVHandle); uint64_t tsortGetGroupId(STupleHandle* pVHandle);
void tsortGetBlockInfo(STupleHandle* pVHandle, SDataBlockInfo* pInfo); void tsortGetBlockInfo(STupleHandle* pVHandle, SDataBlockInfo* pInfo);
/**
* return the SColumnInfoData of columns in the tuple
* @param pVHandle
* @param colId
* @return
*/
void tsortGetColumnInfo(STupleHandle* pVHandle, int32_t colIndex, SColumnInfoData** pColInfo);
/**
* return the number of columns in the tuple
* @param pVHandle
* @return
*/
size_t tsortGetColNum(STupleHandle* pVHandle);
/** /**
* *
* @param pSortHandle * @param pSortHandle

View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef TDENGINE_VIRTUALTABLESCAN_H
#define TDENGINE_VIRTUALTABLESCAN_H
#ifdef __cplusplus
extern "C" {
#endif
#include "executorInt.h"
#include "operator.h"
#define VTS_ERR_RET(c) \
do { \
int32_t _code = (c); \
if (_code != TSDB_CODE_SUCCESS) { \
terrno = _code; \
return _code; \
} \
} while (0)
#define VTS_ERR_JRET(c) \
do { \
code = (c); \
if (code != TSDB_CODE_SUCCESS) { \
terrno = code; \
goto _return; \
} \
} while (0)
#ifdef __cplusplus
}
#endif
#endif // TDENGINE_VIRTUALTABLESCAN_H

View File

@ -268,7 +268,7 @@ static int32_t putDataBlock(SDataSinkHandle* pHandle, const SInputData* pInput,
QRY_ERR_JRET(taosWriteQitem(pDispatcher->pDataBlocks, pBuf)); QRY_ERR_JRET(taosWriteQitem(pDispatcher->pDataBlocks, pBuf));
int32_t status = updateStatus(pDispatcher); int32_t status = updateStatus(pDispatcher);
*pContinue = (status == DS_BUF_LOW || status == DS_BUF_EMPTY); *pContinue = (status == DS_BUF_LOW || status == DS_BUF_EMPTY) && !(pDispatcher->flags & DS_FLAG_PROCESS_ONE_BLOCK);
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
_return: _return:
@ -438,7 +438,7 @@ int32_t getOutputColCounts(SDataBlockDescNode* pInputDataBlockDesc) {
return numOfCols; return numOfCols;
} }
int32_t createDataDispatcher(SDataSinkManager* pManager, SDataSinkNode** ppDataSink, DataSinkHandle* pHandle) { int32_t createDataDispatcher(SDataSinkManager* pManager, SDataSinkNode** ppDataSink, DataSinkHandle* pHandle, bool processOneBlock) {
int32_t code; int32_t code;
SDataSinkNode* pDataSink = *ppDataSink; SDataSinkNode* pDataSink = *ppDataSink;
code = blockDescNodeCheck(pDataSink->pInputDataBlockDesc); code = blockDescNodeCheck(pDataSink->pInputDataBlockDesc);
@ -480,6 +480,9 @@ int32_t createDataDispatcher(SDataSinkManager* pManager, SDataSinkNode** ppDataS
} }
dispatcher->flags = DS_FLAG_USE_MEMPOOL; dispatcher->flags = DS_FLAG_USE_MEMPOOL;
if (processOneBlock) {
dispatcher->flags |= DS_FLAG_PROCESS_ONE_BLOCK;
}
*pHandle = dispatcher; *pHandle = dispatcher;
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;

View File

@ -39,11 +39,11 @@ int32_t dsDataSinkGetCacheSize(SDataSinkStat* pStat) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
int32_t dsCreateDataSinker(void* pSinkManager, SDataSinkNode** ppDataSink, DataSinkHandle* pHandle, void* pParam, const char* id) { int32_t dsCreateDataSinker(void* pSinkManager, SDataSinkNode** ppDataSink, DataSinkHandle* pHandle, void* pParam, const char* id, bool processOneBlock) {
SDataSinkManager* pManager = pSinkManager; SDataSinkManager* pManager = pSinkManager;
switch ((int)nodeType(*ppDataSink)) { switch ((int)nodeType(*ppDataSink)) {
case QUERY_NODE_PHYSICAL_PLAN_DISPATCH: case QUERY_NODE_PHYSICAL_PLAN_DISPATCH:
return createDataDispatcher(pManager, ppDataSink, pHandle); return createDataDispatcher(pManager, ppDataSink, pHandle, processOneBlock);
case QUERY_NODE_PHYSICAL_PLAN_DELETE: { case QUERY_NODE_PHYSICAL_PLAN_DELETE: {
return createDataDeleter(pManager, ppDataSink, pHandle, pParam); return createDataDeleter(pManager, ppDataSink, pHandle, pParam);
} }

View File

@ -15,7 +15,6 @@
#include "executorInt.h" #include "executorInt.h"
#include "filter.h" #include "filter.h"
#include "function.h"
#include "nodes.h" #include "nodes.h"
#include "operator.h" #include "operator.h"
#include "os.h" #include "os.h"
@ -28,6 +27,7 @@
#include "tdatablock.h" #include "tdatablock.h"
#include "thash.h" #include "thash.h"
#include "tmsg.h" #include "tmsg.h"
#include "trpc.h"
#include "ttypes.h" #include "ttypes.h"
#include "dynqueryctrl.h" #include "dynqueryctrl.h"
@ -80,6 +80,35 @@ static void destroyStbJoinDynCtrlInfo(SStbJoinDynCtrlInfo* pStbJoin) {
destroyStbJoinTableList(pStbJoin->ctx.prev.pListHead); destroyStbJoinTableList(pStbJoin->ctx.prev.pListHead);
} }
void freeUseDbOutput(void* pOutput) {
SUseDbOutput *pOut = *(SUseDbOutput**)pOutput;
if (NULL == pOutput) {
return;
}
if (pOut->dbVgroup) {
freeVgInfo(pOut->dbVgroup);
}
taosMemFree(pOut);
}
static void destroyVtbScanDynCtrlInfo(SVtbScanDynCtrlInfo* pVtbScan) {
if (pVtbScan->childTableList) {
taosArrayDestroy(pVtbScan->childTableList);
}
if (pVtbScan->readColList) {
taosArrayDestroy(pVtbScan->readColList);
}
if (pVtbScan->dbVgInfoMap) {
taosHashSetFreeFp(pVtbScan->dbVgInfoMap, freeUseDbOutput);
taosHashCleanup(pVtbScan->dbVgInfoMap);
}
if (pVtbScan->pRsp) {
tFreeSUsedbRsp(pVtbScan->pRsp);
taosMemoryFreeClear(pVtbScan->pRsp);
}
}
static void destroyDynQueryCtrlOperator(void* param) { static void destroyDynQueryCtrlOperator(void* param) {
SDynQueryCtrlOperatorInfo* pDyn = (SDynQueryCtrlOperatorInfo*)param; SDynQueryCtrlOperatorInfo* pDyn = (SDynQueryCtrlOperatorInfo*)param;
@ -87,6 +116,9 @@ static void destroyDynQueryCtrlOperator(void* param) {
case DYN_QTYPE_STB_HASH: case DYN_QTYPE_STB_HASH:
destroyStbJoinDynCtrlInfo(&pDyn->stbJoin); destroyStbJoinDynCtrlInfo(&pDyn->stbJoin);
break; break;
case DYN_QTYPE_VTB_SCAN:
destroyVtbScanDynCtrlInfo(&pDyn->vtbScan);
break;
default: default:
qError("unsupported dynamic query ctrl type: %d", pDyn->qType); qError("unsupported dynamic query ctrl type: %d", pDyn->qType);
break; break;
@ -199,6 +231,7 @@ static int32_t buildGroupCacheOperatorParam(SOperatorParam** ppRes, int32_t down
(*ppRes)->opType = QUERY_NODE_PHYSICAL_PLAN_GROUP_CACHE; (*ppRes)->opType = QUERY_NODE_PHYSICAL_PLAN_GROUP_CACHE;
(*ppRes)->downstreamIdx = downstreamIdx; (*ppRes)->downstreamIdx = downstreamIdx;
(*ppRes)->value = pGc; (*ppRes)->value = pGc;
(*ppRes)->reUse = false;
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
@ -226,12 +259,13 @@ static int32_t buildGroupCacheNotifyOperatorParam(SOperatorParam** ppRes, int32_
(*ppRes)->opType = QUERY_NODE_PHYSICAL_PLAN_GROUP_CACHE; (*ppRes)->opType = QUERY_NODE_PHYSICAL_PLAN_GROUP_CACHE;
(*ppRes)->downstreamIdx = downstreamIdx; (*ppRes)->downstreamIdx = downstreamIdx;
(*ppRes)->value = pGc; (*ppRes)->value = pGc;
(*ppRes)->reUse = false;
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
static int32_t buildExchangeOperatorParam(SOperatorParam** ppRes, int32_t downstreamIdx, int32_t* pVgId, int64_t* pUid) { static int32_t buildExchangeOperatorParam(SOperatorParam** ppRes, int32_t downstreamIdx, const int32_t* pVgId, int64_t* pUid) {
*ppRes = taosMemoryMalloc(sizeof(SOperatorParam)); *ppRes = taosMemoryMalloc(sizeof(SOperatorParam));
if (NULL == *ppRes) { if (NULL == *ppRes) {
return terrno; return terrno;
@ -246,7 +280,9 @@ static int32_t buildExchangeOperatorParam(SOperatorParam** ppRes, int32_t downst
pExc->multiParams = false; pExc->multiParams = false;
pExc->basic.vgId = *pVgId; pExc->basic.vgId = *pVgId;
pExc->basic.tableSeq = true; pExc->basic.tableSeq = true;
pExc->basic.isVtbRefScan = false;
pExc->basic.srcOpType = QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN; pExc->basic.srcOpType = QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN;
pExc->basic.colMap = NULL;
pExc->basic.uidList = taosArrayInit(1, sizeof(int64_t)); pExc->basic.uidList = taosArrayInit(1, sizeof(int64_t));
if (NULL == pExc->basic.uidList) { if (NULL == pExc->basic.uidList) {
taosMemoryFree(pExc); taosMemoryFree(pExc);
@ -261,11 +297,11 @@ static int32_t buildExchangeOperatorParam(SOperatorParam** ppRes, int32_t downst
(*ppRes)->opType = QUERY_NODE_PHYSICAL_PLAN_EXCHANGE; (*ppRes)->opType = QUERY_NODE_PHYSICAL_PLAN_EXCHANGE;
(*ppRes)->downstreamIdx = downstreamIdx; (*ppRes)->downstreamIdx = downstreamIdx;
(*ppRes)->value = pExc; (*ppRes)->value = pExc;
(*ppRes)->reUse = false;
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
static int32_t buildBatchExchangeOperatorParam(SOperatorParam** ppRes, int32_t downstreamIdx, SSHashObj* pVg) { static int32_t buildBatchExchangeOperatorParam(SOperatorParam** ppRes, int32_t downstreamIdx, SSHashObj* pVg) {
*ppRes = taosMemoryMalloc(sizeof(SOperatorParam)); *ppRes = taosMemoryMalloc(sizeof(SOperatorParam));
if (NULL == *ppRes) { if (NULL == *ppRes) {
@ -298,7 +334,9 @@ static int32_t buildBatchExchangeOperatorParam(SOperatorParam** ppRes, int32_t d
SArray* pUidList = *(SArray**)p; SArray* pUidList = *(SArray**)p;
basic.vgId = *pVgId; basic.vgId = *pVgId;
basic.uidList = pUidList; basic.uidList = pUidList;
basic.colMap = NULL;
basic.tableSeq = false; basic.tableSeq = false;
basic.isVtbRefScan = false;
QRY_ERR_RET(tSimpleHashPut(pExc->pBatchs, pVgId, sizeof(*pVgId), &basic, sizeof(basic))); QRY_ERR_RET(tSimpleHashPut(pExc->pBatchs, pVgId, sizeof(*pVgId), &basic, sizeof(basic)));
@ -309,10 +347,65 @@ static int32_t buildBatchExchangeOperatorParam(SOperatorParam** ppRes, int32_t d
(*ppRes)->opType = QUERY_NODE_PHYSICAL_PLAN_EXCHANGE; (*ppRes)->opType = QUERY_NODE_PHYSICAL_PLAN_EXCHANGE;
(*ppRes)->downstreamIdx = downstreamIdx; (*ppRes)->downstreamIdx = downstreamIdx;
(*ppRes)->value = pExc; (*ppRes)->value = pExc;
(*ppRes)->reUse = false;
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
static int32_t buildExchangeOperatorParamForVScan(SOperatorParam** ppRes, int32_t downstreamIdx, SOrgTbInfo* pMap) {
int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
SExchangeOperatorParam* pExc = NULL;
SExchangeOperatorBasicParam* basic = NULL;
*ppRes = taosMemoryMalloc(sizeof(SOperatorParam));
QUERY_CHECK_NULL(*ppRes, code, lino, _return, terrno);
(*ppRes)->pChildren = NULL;
pExc = taosMemoryMalloc(sizeof(SExchangeOperatorParam));
QUERY_CHECK_NULL(pExc, code, lino, _return, terrno);
pExc->multiParams = false;
basic = &pExc->basic;
basic->srcOpType = QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN;
basic->vgId = pMap->vgId;
basic->tableSeq = false;
basic->isVtbRefScan = true;
basic->colMap = taosMemoryMalloc(sizeof(SOrgTbInfo));
QUERY_CHECK_NULL(basic->colMap, code, lino, _return, terrno);
basic->colMap->vgId = pMap->vgId;
tstrncpy(basic->colMap->tbName, pMap->tbName, TSDB_TABLE_FNAME_LEN);
basic->colMap->colMap = taosArrayDup(pMap->colMap, NULL);
QUERY_CHECK_NULL(basic->colMap->colMap, code, lino, _return, terrno);
basic->uidList = taosArrayInit(1, sizeof(int64_t));
QUERY_CHECK_NULL(basic->uidList, code, lino, _return, terrno);
(*ppRes)->opType = QUERY_NODE_PHYSICAL_PLAN_EXCHANGE;
(*ppRes)->downstreamIdx = downstreamIdx;
(*ppRes)->value = pExc;
(*ppRes)->reUse = true;
return TSDB_CODE_SUCCESS;
_return:
qError("failed to build exchange operator param for vscan, code:%d", code);
taosMemoryFreeClear(*ppRes);
if (basic) {
if (basic->colMap) {
taosArrayDestroy(basic->colMap->colMap);
taosMemoryFreeClear(basic->colMap);
}
if (basic->uidList) {
taosArrayDestroy(basic->uidList);
}
taosMemoryFreeClear(basic);
}
taosMemoryFreeClear(pExc);
return code;
}
static int32_t buildMergeJoinOperatorParam(SOperatorParam** ppRes, bool initParam, SOperatorParam** ppChild0, SOperatorParam** ppChild1) { static int32_t buildMergeJoinOperatorParam(SOperatorParam** ppRes, bool initParam, SOperatorParam** ppChild0, SOperatorParam** ppChild1) {
int32_t code = TSDB_CODE_SUCCESS; int32_t code = TSDB_CODE_SUCCESS;
@ -355,11 +448,11 @@ static int32_t buildMergeJoinOperatorParam(SOperatorParam** ppRes, bool initPara
(*ppRes)->opType = QUERY_NODE_PHYSICAL_PLAN_MERGE_JOIN; (*ppRes)->opType = QUERY_NODE_PHYSICAL_PLAN_MERGE_JOIN;
(*ppRes)->value = pJoin; (*ppRes)->value = pJoin;
(*ppRes)->reUse = false;
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
static int32_t buildMergeJoinNotifyOperatorParam(SOperatorParam** ppRes, SOperatorParam* pChild0, SOperatorParam* pChild1) { static int32_t buildMergeJoinNotifyOperatorParam(SOperatorParam** ppRes, SOperatorParam* pChild0, SOperatorParam* pChild1) {
int32_t code = TSDB_CODE_SUCCESS; int32_t code = TSDB_CODE_SUCCESS;
*ppRes = taosMemoryMalloc(sizeof(SOperatorParam)); *ppRes = taosMemoryMalloc(sizeof(SOperatorParam));
@ -395,12 +488,11 @@ static int32_t buildMergeJoinNotifyOperatorParam(SOperatorParam** ppRes, SOperat
(*ppRes)->opType = QUERY_NODE_PHYSICAL_PLAN_MERGE_JOIN; (*ppRes)->opType = QUERY_NODE_PHYSICAL_PLAN_MERGE_JOIN;
(*ppRes)->value = NULL; (*ppRes)->value = NULL;
(*ppRes)->reUse = false;
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
static int32_t buildBatchTableScanOperatorParam(SOperatorParam** ppRes, int32_t downstreamIdx, SSHashObj* pVg) { static int32_t buildBatchTableScanOperatorParam(SOperatorParam** ppRes, int32_t downstreamIdx, SSHashObj* pVg) {
int32_t code = TSDB_CODE_SUCCESS; int32_t code = TSDB_CODE_SUCCESS;
int32_t vgNum = tSimpleHashGetSize(pVg); int32_t vgNum = tSimpleHashGetSize(pVg);
@ -516,7 +608,6 @@ static int32_t buildSeqStbJoinOperatorParam(SDynQueryCtrlOperatorInfo* pInfo, SS
return code; return code;
} }
static void seqJoinLaunchNewRetrieveImpl(SOperatorInfo* pOperator, SSDataBlock** ppRes) { static void seqJoinLaunchNewRetrieveImpl(SOperatorInfo* pOperator, SSDataBlock** ppRes) {
SDynQueryCtrlOperatorInfo* pInfo = pOperator->info; SDynQueryCtrlOperatorInfo* pInfo = pOperator->info;
SStbJoinDynCtrlInfo* pStbJoin = (SStbJoinDynCtrlInfo*)&pInfo->stbJoin; SStbJoinDynCtrlInfo* pStbJoin = (SStbJoinDynCtrlInfo*)&pInfo->stbJoin;
@ -918,8 +1009,11 @@ static int32_t seqStableJoinComposeRes(SStbJoinDynCtrlInfo* pStbJoin, SSDataBloc
return TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR; return TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
} }
SColumnInfoData colInfo = createColumnInfoData(pSlot->dataType.type, pSlot->dataType.bytes, pSlot->slotId); SColumnInfoData colInfo = createColumnInfoData(pSlot->dataType.type, pSlot->dataType.bytes, pSlot->slotId);
colInfoDataEnsureCapacity(&colInfo, pBlock->info.rows, true); int32_t code = colInfoDataEnsureCapacity(&colInfo, pBlock->info.rows, true);
int32_t code = blockDataAppendColInfo(pBlock, &colInfo); if (code != TSDB_CODE_SUCCESS) {
return code;
}
code = blockDataAppendColInfo(pBlock, &colInfo);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
return code; return code;
} }
@ -964,7 +1058,7 @@ int32_t seqStableJoin(SOperatorInfo* pOperator, SSDataBlock** pRes) {
_return: _return:
if (pOperator->cost.openCost == 0) { if (pOperator->cost.openCost == 0) {
pOperator->cost.openCost = (taosGetTimestampUs() - st) / 1000.0; pOperator->cost.openCost = (double)(taosGetTimestampUs() - st) / 1000.0;
} }
if (code) { if (code) {
@ -977,6 +1071,354 @@ _return:
return code; return code;
} }
static int32_t buildVtbScanOperatorParam(SDynQueryCtrlOperatorInfo* pInfo, SOperatorParam** ppRes) {
int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
SVTableScanOperatorParam* pVScan = NULL;
*ppRes = taosMemoryMalloc(sizeof(SOperatorParam));
QUERY_CHECK_NULL(*ppRes, code, lino, _return, terrno);
(*ppRes)->pChildren = taosArrayInit(1, POINTER_BYTES);
QUERY_CHECK_NULL((*ppRes)->pChildren, code, lino, _return, terrno);
pVScan = taosMemoryMalloc(sizeof(SVTableScanOperatorParam));
QUERY_CHECK_NULL(pVScan, code, lino, _return, terrno);
pVScan->pOpParamArray = taosArrayInit(1, POINTER_BYTES);
QUERY_CHECK_NULL(pVScan->pOpParamArray, code, lino, _return, terrno);
(*ppRes)->opType = QUERY_NODE_PHYSICAL_PLAN_VIRTUAL_TABLE_SCAN;
(*ppRes)->downstreamIdx = 0;
(*ppRes)->value = pVScan;
(*ppRes)->reUse = false;
return TSDB_CODE_SUCCESS;
_return:
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
if (pVScan) {
taosArrayDestroy(pVScan->pOpParamArray);
taosMemoryFreeClear(pVScan);
}
if (*ppRes) {
taosArrayDestroy((*ppRes)->pChildren);
taosMemoryFreeClear(*ppRes);
}
return code;
}
int32_t dynProcessUseDbRsp(void* param, SDataBuf* pMsg, int32_t code) {
int32_t lino = 0;
SOperatorInfo* operator=(SOperatorInfo*) param;
SDynQueryCtrlOperatorInfo* pScanResInfo = (SDynQueryCtrlOperatorInfo*)operator->info;
if (TSDB_CODE_SUCCESS != code) {
operator->pTaskInfo->code = rpcCvtErrCode(code);
if (operator->pTaskInfo->code != code) {
qError("load systable rsp received, error:%s, cvted error:%s", tstrerror(code),
tstrerror(operator->pTaskInfo->code));
} else {
qError("load systable rsp received, error:%s", tstrerror(code));
}
goto _return;
}
pScanResInfo->vtbScan.pRsp = taosMemoryMalloc(sizeof(SUseDbRsp));
QUERY_CHECK_NULL(pScanResInfo->vtbScan.pRsp, code, lino, _return, terrno);
QUERY_CHECK_CODE(tDeserializeSUseDbRsp(pMsg->pData, (int32_t)pMsg->len, pScanResInfo->vtbScan.pRsp), lino, _return);
taosMemoryFreeClear(pMsg->pData);
QUERY_CHECK_CODE(tsem_post(&pScanResInfo->vtbScan.ready), lino, _return);
return TSDB_CODE_SUCCESS;
_return:
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
return code;
}
static int32_t buildDbVgInfoMap(SOperatorInfo* pOperator, SReadHandle* pHandle, SName* name, SExecTaskInfo* pTaskInfo, SUseDbOutput* output) {
int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
char* buf1 = NULL;
SUseDbReq* pReq = NULL;
SDynQueryCtrlOperatorInfo* pScanResInfo = (SDynQueryCtrlOperatorInfo*)pOperator->info;
pReq = taosMemoryMalloc(sizeof(SUseDbReq));
QUERY_CHECK_NULL(pReq, code, lino, _return, terrno);
QUERY_CHECK_CODE(tNameGetFullDbName(name, pReq->db), lino, _return);
int32_t contLen = tSerializeSUseDbReq(NULL, 0, pReq);
buf1 = taosMemoryCalloc(1, contLen);
QUERY_CHECK_NULL(buf1, code, lino, _return, terrno);
int32_t tempRes = tSerializeSUseDbReq(buf1, contLen, pReq);
if (tempRes < 0) {
QUERY_CHECK_CODE(terrno, lino, _return);
}
// send the fetch remote task result request
SMsgSendInfo* pMsgSendInfo = taosMemoryCalloc(1, sizeof(SMsgSendInfo));
QUERY_CHECK_NULL(pMsgSendInfo, code, lino, _return, terrno);
pMsgSendInfo->param = pOperator;
pMsgSendInfo->msgInfo.pData = buf1;
pMsgSendInfo->msgInfo.len = contLen;
pMsgSendInfo->msgType = TDMT_MND_GET_DB_INFO;
pMsgSendInfo->fp = dynProcessUseDbRsp;
pMsgSendInfo->requestId = pTaskInfo->id.queryId;
QUERY_CHECK_CODE(asyncSendMsgToServer(pHandle->pMsgCb->clientRpc, &pScanResInfo->vtbScan.epSet, NULL, pMsgSendInfo), lino, _return);
QUERY_CHECK_CODE(tsem_wait(&pScanResInfo->vtbScan.ready), lino, _return);
QUERY_CHECK_CODE(queryBuildUseDbOutput(output, pScanResInfo->vtbScan.pRsp), lino, _return);
_return:
if (code) {
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
taosMemoryFree(buf1);
}
taosMemoryFree(pReq);
tFreeSUsedbRsp(pScanResInfo->vtbScan.pRsp);
taosMemoryFreeClear(pScanResInfo->vtbScan.pRsp);
return code;
}
int dynVgInfoComp(const void* lp, const void* rp) {
SVgroupInfo* pLeft = (SVgroupInfo*)lp;
SVgroupInfo* pRight = (SVgroupInfo*)rp;
if (pLeft->hashBegin < pRight->hashBegin) {
return -1;
} else if (pLeft->hashBegin > pRight->hashBegin) {
return 1;
}
return 0;
}
int32_t dynMakeVgArraySortBy(SDBVgInfo* dbInfo, __compar_fn_t sort_func) {
if (NULL == dbInfo) {
return TSDB_CODE_SUCCESS;
}
if (dbInfo->vgHash && NULL == dbInfo->vgArray) {
int32_t vgSize = taosHashGetSize(dbInfo->vgHash);
dbInfo->vgArray = taosArrayInit(vgSize, sizeof(SVgroupInfo));
if (NULL == dbInfo->vgArray) {
return terrno;
}
void* pIter = taosHashIterate(dbInfo->vgHash, NULL);
while (pIter) {
if (NULL == taosArrayPush(dbInfo->vgArray, pIter)) {
taosHashCancelIterate(dbInfo->vgHash, pIter);
return terrno;
}
pIter = taosHashIterate(dbInfo->vgHash, pIter);
}
taosArraySort(dbInfo->vgArray, sort_func);
}
return TSDB_CODE_SUCCESS;
}
int32_t dynHashValueComp(void const* lp, void const* rp) {
uint32_t* key = (uint32_t*)lp;
SVgroupInfo* pVg = (SVgroupInfo*)rp;
if (*key < pVg->hashBegin) {
return -1;
} else if (*key > pVg->hashEnd) {
return 1;
}
return 0;
}
int32_t getVgId(SDBVgInfo* dbInfo, char* dbFName, int32_t* vgId, char *tbName) {
int32_t code = 0;
int32_t lino = 0;
QUERY_CHECK_CODE(dynMakeVgArraySortBy(dbInfo, dynVgInfoComp), lino, _return);
int32_t vgNum = (int32_t)taosArrayGetSize(dbInfo->vgArray);
if (vgNum <= 0) {
qError("db vgroup cache invalid, db:%s, vgroup number:%d", dbFName, vgNum);
QUERY_CHECK_CODE(TSDB_CODE_TSC_DB_NOT_SELECTED, lino, _return);
}
SVgroupInfo* vgInfo = NULL;
char tbFullName[TSDB_TABLE_FNAME_LEN];
(void)snprintf(tbFullName, sizeof(tbFullName), "%s.", dbFName);
int32_t offset = (int32_t)strlen(tbFullName);
(void)snprintf(tbFullName + offset, sizeof(tbFullName) - offset, "%s", tbName);
uint32_t hashValue = taosGetTbHashVal(tbFullName, (int32_t)strlen(tbFullName), dbInfo->hashMethod,
dbInfo->hashPrefix, dbInfo->hashSuffix);
vgInfo = taosArraySearch(dbInfo->vgArray, &hashValue, dynHashValueComp, TD_EQ);
if (NULL == vgInfo) {
qError("no hash range found for hash value [%u], db:%s, numOfVgId:%d", hashValue, dbFName,
(int32_t)taosArrayGetSize(dbInfo->vgArray));
return TSDB_CODE_CTG_INTERNAL_ERROR;
}
*vgId = vgInfo->vgId;
_return:
return code;
}
bool colNeedScan(SOperatorInfo* pOperator, col_id_t colId) {
SDynQueryCtrlOperatorInfo* pInfo = pOperator->info;
SVtbScanDynCtrlInfo* pVtbScan = (SVtbScanDynCtrlInfo*)&pInfo->vtbScan;
SArray * pColList = pVtbScan->readColList;
if (pVtbScan->scanAllCols) {
return true;
}
for (int32_t i = 0; i < taosArrayGetSize(pColList); i++) {
if (colId == *(col_id_t*)taosArrayGet(pColList, i)) {
return true;
}
}
return false;
}
void destroyOrgTbInfo(void *info) {
SOrgTbInfo *pOrgTbInfo = (SOrgTbInfo *)info;
if (pOrgTbInfo) {
taosArrayDestroy(pOrgTbInfo->colMap);
}
}
int32_t vtbScan(SOperatorInfo* pOperator, SSDataBlock** pRes) {
int32_t code = TSDB_CODE_SUCCESS;
int32_t line = 0;
SDynQueryCtrlOperatorInfo* pInfo = pOperator->info;
SVtbScanDynCtrlInfo* pVtbScan = (SVtbScanDynCtrlInfo*)&pInfo->vtbScan;
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
SReadHandle* pHandle = &pVtbScan->readHandle;
SMetaReader mr = {0};
SHashObj* orgTbVgColMap = NULL;
QRY_PARAM_CHECK(pRes);
if (pOperator->status == OP_EXEC_DONE) {
return code;
}
int64_t st = 0;
if (pOperator->cost.openCost == 0) {
st = taosGetTimestampUs();
}
size_t num = taosArrayGetSize(pVtbScan->childTableList);
if (num == 0) {
setOperatorCompleted(pOperator);
return code;
}
// TODO(smj) : proper hash size
orgTbVgColMap = taosHashInit(num * 64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_ENTRY_LOCK);
QUERY_CHECK_NULL(orgTbVgColMap, code, line, _return, terrno);
taosHashSetFreeFp(orgTbVgColMap, destroyOrgTbInfo);
while (true) {
if (pVtbScan->readTableIdx == pVtbScan->lastTableIdx) {
QUERY_CHECK_CODE(pOperator->pDownstream[0]->fpSet.getNextFn(pOperator->pDownstream[0], pRes), line, _return);
} else {
uint64_t* id = taosArrayGet(pVtbScan->childTableList, pVtbScan->readTableIdx);
QUERY_CHECK_NULL(id, code, line, _return, terrno);
pHandle->api.metaReaderFn.initReader(&mr, pHandle->vnode, META_READER_LOCK, &pHandle->api.metaFn);
QUERY_CHECK_CODE(pHandle->api.metaReaderFn.getTableEntryByUid(&mr, *id), line, _return);
for (int32_t j = 0; j < mr.me.colRef.nCols; j++) {
if (mr.me.colRef.pColRef[j].hasRef && colNeedScan(pOperator, mr.me.colRef.pColRef[j].id)) {
SName name = {0};
toName(pInfo->vtbScan.acctId, mr.me.colRef.pColRef[j].refDbName, "", &name);
SUseDbOutput* output = NULL;
SUseDbOutput** find = (SUseDbOutput**)taosHashGet(pInfo->vtbScan.dbVgInfoMap, name.dbname, strlen(name.dbname));
if (find == NULL) {
output = taosMemoryMalloc(sizeof(SUseDbOutput));
QUERY_CHECK_CODE(buildDbVgInfoMap(pOperator, pHandle, &name, pTaskInfo, output), line, _return);
QUERY_CHECK_CODE(taosHashPut(pInfo->vtbScan.dbVgInfoMap, name.dbname, strlen(name.dbname), &output, sizeof(output)), line, _return);
} else {
output = *find;
}
int32_t vgId = 0;
char dbFname[TSDB_DB_FNAME_LEN] = {0};
QUERY_CHECK_CODE(tNameGetFullDbName(&name, dbFname), line, _return);
QUERY_CHECK_CODE(getVgId(output->dbVgroup, dbFname, &vgId, mr.me.colRef.pColRef[j].refTableName), line, _return);
char orgTbFName[TSDB_TABLE_FNAME_LEN] = {0};
TAOS_STRNCAT(orgTbFName, mr.me.colRef.pColRef[j].refDbName, TSDB_DB_NAME_LEN);
TAOS_STRNCAT(orgTbFName, ".", 2);
TAOS_STRNCAT(orgTbFName, mr.me.colRef.pColRef[j].refTableName, TSDB_TABLE_NAME_LEN);
void *tbVgCol = taosHashGet(orgTbVgColMap, orgTbFName, sizeof(orgTbFName));
if (!tbVgCol) {
SOrgTbInfo map = {0};
map.vgId = vgId;
tstrncpy(map.tbName, orgTbFName, sizeof(map.tbName));
map.colMap = taosArrayInit(10, sizeof(SColIdNameKV));
QUERY_CHECK_NULL(map.colMap, code, line, _return, terrno);
SColIdNameKV colIdNameKV = {0};
colIdNameKV.colId = mr.me.colRef.pColRef[j].id;
tstrncpy(colIdNameKV.colName, mr.me.colRef.pColRef[j].refColName, sizeof(colIdNameKV.colName));
QUERY_CHECK_NULL(taosArrayPush(map.colMap, &colIdNameKV), code, line, _return, terrno);
QUERY_CHECK_CODE(taosHashPut(orgTbVgColMap, orgTbFName, sizeof(orgTbFName), &map, sizeof(map)), line, _return);
} else {
SOrgTbInfo *map = (SOrgTbInfo *)tbVgCol;
SColIdNameKV colIdNameKV = {0};
colIdNameKV.colId = mr.me.colRef.pColRef[j].id;
tstrncpy(colIdNameKV.colName, mr.me.colRef.pColRef[j].refColName, sizeof(colIdNameKV.colName));
QUERY_CHECK_NULL(taosArrayPush(map->colMap, &colIdNameKV), code, line, _return, terrno);
}
}
}
pVtbScan->vtbScanParam = NULL;
QUERY_CHECK_CODE(buildVtbScanOperatorParam(pInfo, &pVtbScan->vtbScanParam), line, _return);
((SVTableScanOperatorParam*)pVtbScan->vtbScanParam->value)->uid = *id;
void* pIter = taosHashIterate(orgTbVgColMap, NULL);
while (pIter != NULL) {
SOrgTbInfo* pMap = (SOrgTbInfo*)pIter;
SOperatorParam* pExchangeParam = NULL;
QUERY_CHECK_CODE(buildExchangeOperatorParamForVScan(&pExchangeParam, 0, pMap), line, _return);
QUERY_CHECK_NULL(taosArrayPush(((SVTableScanOperatorParam*)pVtbScan->vtbScanParam->value)->pOpParamArray, &pExchangeParam), code, line, _return, terrno);
pIter = taosHashIterate(orgTbVgColMap, pIter);
}
pHandle->api.metaReaderFn.clearReader(&mr);
pOperator->pDownstream[0]->status = OP_NOT_OPENED;
QUERY_CHECK_CODE(pOperator->pDownstream[0]->fpSet.getNextExtFn(pOperator->pDownstream[0], pVtbScan->vtbScanParam, pRes), line, _return);
}
if (*pRes) {
pVtbScan->lastTableIdx = pVtbScan->readTableIdx;
break;
} else {
pVtbScan->readTableIdx++;
if (pVtbScan->readTableIdx >= taosArrayGetSize(pVtbScan->childTableList)) {
setOperatorCompleted(pOperator);
break;
}
}
}
_return:
taosHashCleanup(orgTbVgColMap);
if (pOperator->cost.openCost == 0) {
pOperator->cost.openCost = (double)(taosGetTimestampUs() - st) / 1000.0;
}
if (code) {
qError("%s failed since %s", __func__, tstrerror(code));
pOperator->pTaskInfo->code = code;
T_LONG_JMP(pOperator->pTaskInfo->env, code);
}
return code;
}
int32_t initSeqStbJoinTableHash(SStbJoinPrevJoinCtx* pPrev, bool batchFetch) { int32_t initSeqStbJoinTableHash(SStbJoinPrevJoinCtx* pPrev, bool batchFetch) {
if (batchFetch) { if (batchFetch) {
pPrev->leftHash = tSimpleHashInit(20, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT)); pPrev->leftHash = tSimpleHashInit(20, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT));
@ -1005,9 +1447,43 @@ int32_t initSeqStbJoinTableHash(SStbJoinPrevJoinCtx* pPrev, bool batchFetch) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
static int32_t initVtbScanInfo(SOperatorInfo* pOperator, SDynQueryCtrlOperatorInfo* pInfo, SReadHandle* pHandle,
SDynQueryCtrlPhysiNode* pPhyciNode, SExecTaskInfo* pTaskInfo) {
int32_t code = TSDB_CODE_SUCCESS;
int32_t line = 0;
QUERY_CHECK_CODE(tsem_init(&pInfo->vtbScan.ready, 0, 0), line, _return);
pInfo->vtbScan.scanAllCols = pPhyciNode->vtbScan.scanAllCols;
pInfo->vtbScan.suid = pPhyciNode->vtbScan.suid;
pInfo->vtbScan.epSet = pPhyciNode->vtbScan.mgmtEpSet;
pInfo->vtbScan.acctId = pPhyciNode->vtbScan.accountId;
pInfo->vtbScan.readHandle = *pHandle;
pInfo->vtbScan.readTableIdx = 0;
pInfo->vtbScan.lastTableIdx = -1;
pInfo->vtbScan.readColList = taosArrayInit(LIST_LENGTH(pPhyciNode->vtbScan.pScanCols), sizeof(col_id_t));
QUERY_CHECK_NULL(pInfo->vtbScan.readColList, code, line, _return, terrno);
for (int32_t i = 0; i < LIST_LENGTH(pPhyciNode->vtbScan.pScanCols); ++i) {
SColumnNode* pNode = (SColumnNode*)nodesListGetNode(pPhyciNode->vtbScan.pScanCols, i);
QUERY_CHECK_NULL(pNode, code, line, _return, terrno);
QUERY_CHECK_NULL(taosArrayPush(pInfo->vtbScan.readColList, &pNode->colId), code, line, _return, terrno);
}
pInfo->vtbScan.childTableList = taosArrayInit(10, sizeof(uint64_t));
QUERY_CHECK_CODE(pHandle->api.metaFn.getChildTableList(pHandle->vnode, pInfo->vtbScan.suid, pInfo->vtbScan.childTableList), line, _return);
pInfo->vtbScan.dbVgInfoMap = taosHashInit(taosArrayGetSize(pInfo->vtbScan.childTableList), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_ENTRY_LOCK);
QUERY_CHECK_NULL(pInfo->vtbScan.dbVgInfoMap, code, line, _return, terrno);
_return:
return code;
}
int32_t createDynQueryCtrlOperatorInfo(SOperatorInfo** pDownstream, int32_t numOfDownstream, int32_t createDynQueryCtrlOperatorInfo(SOperatorInfo** pDownstream, int32_t numOfDownstream,
SDynQueryCtrlPhysiNode* pPhyciNode, SExecTaskInfo* pTaskInfo, SDynQueryCtrlPhysiNode* pPhyciNode, SExecTaskInfo* pTaskInfo,
SOperatorInfo** pOptrInfo) { SReadHandle* pHandle, SOperatorInfo** pOptrInfo) {
QRY_PARAM_CHECK(pOptrInfo); QRY_PARAM_CHECK(pOptrInfo);
int32_t code = TSDB_CODE_SUCCESS; int32_t code = TSDB_CODE_SUCCESS;
@ -1025,13 +1501,16 @@ int32_t createDynQueryCtrlOperatorInfo(SOperatorInfo** pDownstream, int32_t numO
goto _error; goto _error;
} }
pTaskInfo->dynamicTask = pPhyciNode->node.dynamicOp; pTaskInfo->dynamicTask = (int8_t)pPhyciNode->node.dynamicOp;
code = appendDownstream(pOperator, pDownstream, numOfDownstream); code = appendDownstream(pOperator, pDownstream, numOfDownstream);
if (TSDB_CODE_SUCCESS != code) { if (TSDB_CODE_SUCCESS != code) {
goto _error; goto _error;
} }
setOperatorInfo(pOperator, "DynQueryCtrlOperator", QUERY_NODE_PHYSICAL_PLAN_DYN_QUERY_CTRL, false, OP_NOT_OPENED,
pInfo, pTaskInfo);
pInfo->qType = pPhyciNode->qType; pInfo->qType = pPhyciNode->qType;
switch (pInfo->qType) { switch (pInfo->qType) {
case DYN_QTYPE_STB_HASH: case DYN_QTYPE_STB_HASH:
@ -1043,15 +1522,16 @@ int32_t createDynQueryCtrlOperatorInfo(SOperatorInfo** pDownstream, int32_t numO
} }
nextFp = seqStableJoin; nextFp = seqStableJoin;
break; break;
case DYN_QTYPE_VTB_SCAN:
QUERY_CHECK_CODE(initVtbScanInfo(pOperator, pInfo, pHandle, pPhyciNode, pTaskInfo), code, _error);
nextFp = vtbScan;
break;
default: default:
qError("unsupported dynamic query ctrl type: %d", pInfo->qType); qError("unsupported dynamic query ctrl type: %d", pInfo->qType);
code = TSDB_CODE_INVALID_PARA; code = TSDB_CODE_INVALID_PARA;
goto _error; goto _error;
} }
setOperatorInfo(pOperator, "DynQueryCtrlOperator", QUERY_NODE_PHYSICAL_PLAN_DYN_QUERY_CTRL, false, OP_NOT_OPENED,
pInfo, pTaskInfo);
pOperator->fpSet = createOperatorFpSet(optrDummyOpenFn, nextFp, NULL, destroyDynQueryCtrlOperator, optrDefaultBufFn, pOperator->fpSet = createOperatorFpSet(optrDummyOpenFn, nextFp, NULL, destroyDynQueryCtrlOperator, optrDefaultBufFn,
NULL, optrDefaultGetNextExtFn, NULL); NULL, optrDefaultGetNextExtFn, NULL);

View File

@ -43,6 +43,9 @@ typedef struct SSourceDataInfo {
bool tableSeq; bool tableSeq;
char* decompBuf; char* decompBuf;
int32_t decompBufSize; int32_t decompBufSize;
SOrgTbInfo* colMap;
bool isVtbRefScan;
STimeWindow window;
} SSourceDataInfo; } SSourceDataInfo;
static void destroyExchangeOperatorInfo(void* param); static void destroyExchangeOperatorInfo(void* param);
@ -112,7 +115,7 @@ static void concurrentlyLoadRemoteDataImpl(SOperatorInfo* pOperator, SExchangeIn
// todo // todo
SLoadRemoteDataInfo* pLoadInfo = &pExchangeInfo->loadInfo; SLoadRemoteDataInfo* pLoadInfo = &pExchangeInfo->loadInfo;
if (pRsp->numOfRows == 0) { if (pRsp->numOfRows == 0) {
if (NULL != pDataInfo->pSrcUidList) { if (NULL != pDataInfo->pSrcUidList && (!pDataInfo->isVtbRefScan)) {
pDataInfo->status = EX_SOURCE_DATA_NOT_READY; pDataInfo->status = EX_SOURCE_DATA_NOT_READY;
code = doSendFetchDataRequest(pExchangeInfo, pTaskInfo, i); code = doSendFetchDataRequest(pExchangeInfo, pTaskInfo, i);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
@ -156,7 +159,7 @@ static void concurrentlyLoadRemoteDataImpl(SOperatorInfo* pOperator, SExchangeIn
taosMemoryFreeClear(pDataInfo->pRsp); taosMemoryFreeClear(pDataInfo->pRsp);
if (pDataInfo->status != EX_SOURCE_DATA_EXHAUSTED || NULL != pDataInfo->pSrcUidList) { if ((pDataInfo->status != EX_SOURCE_DATA_EXHAUSTED || NULL != pDataInfo->pSrcUidList) && !pDataInfo->isVtbRefScan) {
pDataInfo->status = EX_SOURCE_DATA_NOT_READY; pDataInfo->status = EX_SOURCE_DATA_NOT_READY;
code = doSendFetchDataRequest(pExchangeInfo, pTaskInfo, i); code = doSendFetchDataRequest(pExchangeInfo, pTaskInfo, i);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
@ -603,15 +606,67 @@ int32_t buildTableScanOperatorParam(SOperatorParam** ppRes, SArray* pUidList, in
return terrno; return terrno;
} }
pScan->tableSeq = tableSeq; pScan->tableSeq = tableSeq;
pScan->pOrgTbInfo = NULL;
pScan->window.skey = INT64_MAX;
pScan->window.ekey = INT64_MIN;
(*ppRes)->opType = srcOpType; (*ppRes)->opType = srcOpType;
(*ppRes)->downstreamIdx = 0; (*ppRes)->downstreamIdx = 0;
(*ppRes)->value = pScan; (*ppRes)->value = pScan;
(*ppRes)->pChildren = NULL; (*ppRes)->pChildren = NULL;
(*ppRes)->reUse = false;
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
int32_t buildTableScanOperatorParamEx(SOperatorParam** ppRes, SArray* pUidList, int32_t srcOpType, SOrgTbInfo *pMap, bool tableSeq, STimeWindow *window) {
int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
STableScanOperatorParam* pScan = NULL;
*ppRes = taosMemoryMalloc(sizeof(SOperatorParam));
QUERY_CHECK_NULL(*ppRes, code, lino, _return, terrno);
pScan = taosMemoryMalloc(sizeof(STableScanOperatorParam));
QUERY_CHECK_NULL(pScan, code, lino, _return, terrno);
pScan->pUidList = taosArrayDup(pUidList, NULL);
QUERY_CHECK_NULL(pScan->pUidList, code, lino, _return, terrno);
pScan->pOrgTbInfo = taosMemoryMalloc(sizeof(SOrgTbInfo));
QUERY_CHECK_NULL(pScan->pOrgTbInfo, code, lino, _return, terrno);
pScan->pOrgTbInfo->vgId = pMap->vgId;
tstrncpy(pScan->pOrgTbInfo->tbName, pMap->tbName, TSDB_TABLE_FNAME_LEN);
pScan->pOrgTbInfo->colMap = taosArrayDup(pMap->colMap, NULL);
QUERY_CHECK_NULL(pScan->pOrgTbInfo->colMap, code, lino, _return, terrno);
pScan->tableSeq = tableSeq;
pScan->window.skey = window->skey;
pScan->window.ekey = window->ekey;
(*ppRes)->opType = srcOpType;
(*ppRes)->downstreamIdx = 0;
(*ppRes)->value = pScan;
(*ppRes)->pChildren = NULL;
(*ppRes)->reUse = false;
return code;
_return:
qError("%s failed at %d, failed to build scan operator msg:%s", __FUNCTION__, lino, tstrerror(code));
taosMemoryFreeClear(*ppRes);
if (pScan) {
taosArrayDestroy(pScan->pUidList);
if (pScan->pOrgTbInfo) {
taosArrayDestroy(pScan->pOrgTbInfo->colMap);
taosMemoryFreeClear(pScan->pOrgTbInfo);
}
taosMemoryFree(pScan);
}
return code;
}
int32_t doSendFetchDataRequest(SExchangeInfo* pExchangeInfo, SExecTaskInfo* pTaskInfo, int32_t sourceIndex) { int32_t doSendFetchDataRequest(SExchangeInfo* pExchangeInfo, SExecTaskInfo* pTaskInfo, int32_t sourceIndex) {
int32_t code = TSDB_CODE_SUCCESS; int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0; int32_t lino = 0;
@ -654,9 +709,10 @@ int32_t doSendFetchDataRequest(SExchangeInfo* pExchangeInfo, SExecTaskInfo* pTas
req.taskId = pSource->taskId; req.taskId = pSource->taskId;
req.queryId = pTaskInfo->id.queryId; req.queryId = pTaskInfo->id.queryId;
req.execId = pSource->execId; req.execId = pSource->execId;
if (pDataInfo->pSrcUidList) { if (pDataInfo->isVtbRefScan) {
int32_t code = code = buildTableScanOperatorParamEx(&req.pOpParam, pDataInfo->pSrcUidList, pDataInfo->srcOpType, pDataInfo->colMap, pDataInfo->tableSeq, &pDataInfo->window);
buildTableScanOperatorParam(&req.pOpParam, pDataInfo->pSrcUidList, pDataInfo->srcOpType, pDataInfo->tableSeq); taosArrayDestroy(pDataInfo->colMap->colMap);
taosMemoryFreeClear(pDataInfo->colMap);
taosArrayDestroy(pDataInfo->pSrcUidList); taosArrayDestroy(pDataInfo->pSrcUidList);
pDataInfo->pSrcUidList = NULL; pDataInfo->pSrcUidList = NULL;
if (TSDB_CODE_SUCCESS != code) { if (TSDB_CODE_SUCCESS != code) {
@ -664,6 +720,17 @@ int32_t doSendFetchDataRequest(SExchangeInfo* pExchangeInfo, SExecTaskInfo* pTas
taosMemoryFree(pWrapper); taosMemoryFree(pWrapper);
return pTaskInfo->code; return pTaskInfo->code;
} }
} else {
if (pDataInfo->pSrcUidList) {
code = buildTableScanOperatorParam(&req.pOpParam, pDataInfo->pSrcUidList, pDataInfo->srcOpType, pDataInfo->tableSeq);
taosArrayDestroy(pDataInfo->pSrcUidList);
pDataInfo->pSrcUidList = NULL;
if (TSDB_CODE_SUCCESS != code) {
pTaskInfo->code = code;
taosMemoryFree(pWrapper);
return pTaskInfo->code;
}
}
} }
int32_t msgSize = tSerializeSResFetchReq(NULL, 0, &req); int32_t msgSize = tSerializeSResFetchReq(NULL, 0, &req);
@ -995,7 +1062,11 @@ int32_t seqLoadRemoteData(SOperatorInfo* pOperator) {
pExchangeInfo->current + 1, pDataInfo->totalRows, pLoadInfo->totalRows); pExchangeInfo->current + 1, pDataInfo->totalRows, pLoadInfo->totalRows);
pDataInfo->status = EX_SOURCE_DATA_EXHAUSTED; pDataInfo->status = EX_SOURCE_DATA_EXHAUSTED;
if (pDataInfo->isVtbRefScan) {
pExchangeInfo->current = totalSources;
} else {
pExchangeInfo->current += 1; pExchangeInfo->current += 1;
}
taosMemoryFreeClear(pDataInfo->pRsp); taosMemoryFreeClear(pDataInfo->pRsp);
continue; continue;
} }
@ -1014,14 +1085,20 @@ int32_t seqLoadRemoteData(SOperatorInfo* pOperator) {
pExchangeInfo->current + 1, totalSources); pExchangeInfo->current + 1, totalSources);
pDataInfo->status = EX_SOURCE_DATA_EXHAUSTED; pDataInfo->status = EX_SOURCE_DATA_EXHAUSTED;
if (pDataInfo->isVtbRefScan) {
pExchangeInfo->current = totalSources;
} else {
pExchangeInfo->current += 1; pExchangeInfo->current += 1;
}
} else { } else {
qDebug("%s fetch msg rsp from vgId:%d, clientId:0x%" PRIx64 " taskId:0x%" PRIx64 " execId:%d numOfRows:%" PRId64 qDebug("%s fetch msg rsp from vgId:%d, clientId:0x%" PRIx64 " taskId:0x%" PRIx64 " execId:%d numOfRows:%" PRId64
", totalRows:%" PRIu64 ", totalBytes:%" PRIu64, ", totalRows:%" PRIu64 ", totalBytes:%" PRIu64,
GET_TASKID(pTaskInfo), pSource->addr.nodeId, pSource->clientId, pSource->taskId, pSource->execId, GET_TASKID(pTaskInfo), pSource->addr.nodeId, pSource->clientId, pSource->taskId, pSource->execId,
pRetrieveRsp->numOfRows, pLoadInfo->totalRows, pLoadInfo->totalSize); pRetrieveRsp->numOfRows, pLoadInfo->totalRows, pLoadInfo->totalSize);
} }
if (pExchangeInfo->dynamicOp && pExchangeInfo->seqLoadData) {
taosArrayClear(pExchangeInfo->pSourceDataInfo);
}
updateLoadRemoteInfo(pLoadInfo, pRetrieveRsp->numOfRows, pRetrieveRsp->compLen, startTs, pOperator); updateLoadRemoteInfo(pLoadInfo, pRetrieveRsp->numOfRows, pRetrieveRsp->compLen, startTs, pOperator);
pDataInfo->totalRows += pRetrieveRsp->numOfRows; pDataInfo->totalRows += pRetrieveRsp->numOfRows;
@ -1034,6 +1111,15 @@ _error:
return code; return code;
} }
void clearVtbScanDataInfo(void* pItem) {
SSourceDataInfo *pInfo = (SSourceDataInfo *)pItem;
if (pInfo->colMap) {
taosArrayDestroy(pInfo->colMap->colMap);
taosMemoryFreeClear(pInfo->colMap);
}
taosArrayDestroy(pInfo->pSrcUidList);
}
int32_t addSingleExchangeSource(SOperatorInfo* pOperator, SExchangeOperatorBasicParam* pBasicParam) { int32_t addSingleExchangeSource(SOperatorInfo* pOperator, SExchangeOperatorBasicParam* pBasicParam) {
SExchangeInfo* pExchangeInfo = pOperator->info; SExchangeInfo* pExchangeInfo = pOperator->info;
SExchangeSrcIndex* pIdx = tSimpleHashGet(pExchangeInfo->pHashSources, &pBasicParam->vgId, sizeof(pBasicParam->vgId)); SExchangeSrcIndex* pIdx = tSimpleHashGet(pExchangeInfo->pHashSources, &pBasicParam->vgId, sizeof(pBasicParam->vgId));
@ -1042,16 +1128,52 @@ int32_t addSingleExchangeSource(SOperatorInfo* pOperator, SExchangeOperatorBasic
return TSDB_CODE_INVALID_PARA; return TSDB_CODE_INVALID_PARA;
} }
if (pIdx->inUseIdx < 0) { if (pBasicParam->isVtbRefScan) {
SSourceDataInfo dataInfo = {0}; SSourceDataInfo dataInfo = {0};
dataInfo.status = EX_SOURCE_DATA_NOT_READY; dataInfo.status = EX_SOURCE_DATA_NOT_READY;
dataInfo.taskId = pExchangeInfo->pTaskId; dataInfo.taskId = pExchangeInfo->pTaskId;
dataInfo.index = pIdx->srcIdx; dataInfo.index = pIdx->srcIdx;
dataInfo.window = pBasicParam->window;
dataInfo.colMap = taosMemoryMalloc(sizeof(SOrgTbInfo));
dataInfo.colMap->vgId = pBasicParam->colMap->vgId;
tstrncpy(dataInfo.colMap->tbName, pBasicParam->colMap->tbName, TSDB_TABLE_FNAME_LEN);
dataInfo.colMap->colMap = taosArrayDup(pBasicParam->colMap->colMap, NULL);
dataInfo.pSrcUidList = taosArrayDup(pBasicParam->uidList, NULL); dataInfo.pSrcUidList = taosArrayDup(pBasicParam->uidList, NULL);
if (dataInfo.pSrcUidList == NULL) { if (dataInfo.pSrcUidList == NULL) {
return terrno; return terrno;
} }
dataInfo.isVtbRefScan = pBasicParam->isVtbRefScan;
dataInfo.srcOpType = pBasicParam->srcOpType;
dataInfo.tableSeq = pBasicParam->tableSeq;
taosArrayClearEx(pExchangeInfo->pSourceDataInfo, clearVtbScanDataInfo);
void* tmp = taosArrayPush(pExchangeInfo->pSourceDataInfo, &dataInfo);
if (!tmp) {
qError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(terrno));
return terrno;
}
} else {
if (pIdx->inUseIdx < 0) {
SSourceDataInfo dataInfo = {0};
dataInfo.status = EX_SOURCE_DATA_NOT_READY;
dataInfo.taskId = pExchangeInfo->pTaskId;
dataInfo.index = pIdx->srcIdx;
if (pBasicParam->isVtbRefScan) {
dataInfo.window = pBasicParam->window;
dataInfo.colMap = taosMemoryMalloc(sizeof(SOrgTbInfo));
dataInfo.colMap->vgId = pBasicParam->colMap->vgId;
tstrncpy(dataInfo.colMap->tbName, pBasicParam->colMap->tbName, TSDB_TABLE_FNAME_LEN);
dataInfo.colMap->colMap = taosArrayDup(pBasicParam->colMap->colMap, NULL);
}
dataInfo.pSrcUidList = taosArrayDup(pBasicParam->uidList, NULL);
if (dataInfo.pSrcUidList == NULL) {
return terrno;
}
dataInfo.isVtbRefScan = pBasicParam->isVtbRefScan;
dataInfo.srcOpType = pBasicParam->srcOpType; dataInfo.srcOpType = pBasicParam->srcOpType;
dataInfo.tableSeq = pBasicParam->tableSeq; dataInfo.tableSeq = pBasicParam->tableSeq;
@ -1069,14 +1191,28 @@ int32_t addSingleExchangeSource(SOperatorInfo* pOperator, SExchangeOperatorBasic
if (pDataInfo->status == EX_SOURCE_DATA_EXHAUSTED) { if (pDataInfo->status == EX_SOURCE_DATA_EXHAUSTED) {
pDataInfo->status = EX_SOURCE_DATA_NOT_READY; pDataInfo->status = EX_SOURCE_DATA_NOT_READY;
} }
if (pBasicParam->isVtbRefScan) {
pDataInfo->window = pBasicParam->window;
if (!pDataInfo->colMap) {
pDataInfo->colMap = taosMemoryMalloc(sizeof(SOrgTbInfo));
}
pDataInfo->colMap->vgId = pBasicParam->colMap->vgId;
tstrncpy(pDataInfo->colMap->tbName, pBasicParam->colMap->tbName, TSDB_TABLE_FNAME_LEN);
pDataInfo->colMap->colMap = taosArrayDup(pBasicParam->colMap->colMap, NULL);
}
pDataInfo->pSrcUidList = taosArrayDup(pBasicParam->uidList, NULL); pDataInfo->pSrcUidList = taosArrayDup(pBasicParam->uidList, NULL);
if (pDataInfo->pSrcUidList == NULL) { if (pDataInfo->pSrcUidList == NULL) {
return terrno; return terrno;
} }
pDataInfo->isVtbRefScan = pBasicParam->isVtbRefScan;
pDataInfo->srcOpType = pBasicParam->srcOpType; pDataInfo->srcOpType = pBasicParam->srcOpType;
pDataInfo->tableSeq = pBasicParam->tableSeq; pDataInfo->tableSeq = pBasicParam->tableSeq;
} }
}
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
@ -1120,6 +1256,10 @@ int32_t prepareLoadRemoteData(SOperatorInfo* pOperator) {
QUERY_CHECK_CODE(code, lino, _end); QUERY_CHECK_CODE(code, lino, _end);
} }
if (pOperator->status == OP_NOT_OPENED && pExchangeInfo->dynamicOp && pExchangeInfo->seqLoadData) {
pExchangeInfo->current = 0;
}
int64_t st = taosGetTimestampUs(); int64_t st = taosGetTimestampUs();
if (!pExchangeInfo->seqLoadData) { if (!pExchangeInfo->seqLoadData) {

View File

@ -2403,6 +2403,54 @@ int32_t initQueryTableDataCond(SQueryTableDataCond* pCond, const STableScanPhysi
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
int32_t initQueryTableDataCondWithColArray(SQueryTableDataCond* pCond, SQueryTableDataCond* pOrgCond,
const SReadHandle* readHandle, SArray* colArray) {
int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
pCond->order = TSDB_ORDER_ASC;
pCond->numOfCols = (int32_t)taosArrayGetSize(colArray);
pCond->colList = taosMemoryCalloc(pCond->numOfCols, sizeof(SColumnInfo));
QUERY_CHECK_NULL(pCond->colList, code, lino, _return, terrno);
pCond->pSlotList = taosMemoryMalloc(sizeof(int32_t) * pCond->numOfCols);
QUERY_CHECK_NULL(pCond->pSlotList, code, lino, _return, terrno);
pCond->twindows = pOrgCond->twindows;
pCond->type = pOrgCond->type;
pCond->startVersion = -1;
pCond->endVersion = -1;
pCond->skipRollup = true;
pCond->notLoadData = false;
for (int32_t i = 0; i < pCond->numOfCols; ++i) {
SColIdPair* pColPair = taosArrayGet(colArray, i);
QUERY_CHECK_NULL(pColPair, code, lino, _return, terrno);
bool find = false;
for (int32_t j = 0; j < pOrgCond->numOfCols; ++j) {
if (pOrgCond->colList[j].colId == pColPair->vtbColId) {
pCond->colList[i].type = pOrgCond->colList[j].type;
pCond->colList[i].bytes = pOrgCond->colList[j].bytes;
pCond->colList[i].colId = pColPair->orgColId;
pCond->colList[i].pk = pOrgCond->colList[j].pk;
pCond->pSlotList[i] = i;
find = true;
break;
}
}
QUERY_CHECK_CONDITION(find, code, lino, _return, TSDB_CODE_NOT_FOUND);
}
return code;
_return:
qError("%s failed at line %d since %s", __func__, lino, tstrerror(terrno));
taosMemoryFreeClear(pCond->colList);
taosMemoryFreeClear(pCond->pSlotList);
return code;
}
void cleanupQueryTableDataCond(SQueryTableDataCond* pCond) { void cleanupQueryTableDataCond(SQueryTableDataCond* pCond) {
taosMemoryFreeClear(pCond->colList); taosMemoryFreeClear(pCond->colList);
taosMemoryFreeClear(pCond->pSlotList); taosMemoryFreeClear(pCond->pSlotList);
@ -2995,17 +3043,17 @@ char* getStreamOpName(uint16_t opType) {
void printDataBlock(SSDataBlock* pBlock, const char* flag, const char* taskIdStr) { void printDataBlock(SSDataBlock* pBlock, const char* flag, const char* taskIdStr) {
if (!pBlock) { if (!pBlock) {
qDebug("%s===stream===%s: Block is Null", taskIdStr, flag); qInfo("%s===stream===%s: Block is Null", taskIdStr, flag);
return; return;
} else if (pBlock->info.rows == 0) { } else if (pBlock->info.rows == 0) {
qDebug("%s===stream===%s: Block is Empty. block type %d", taskIdStr, flag, pBlock->info.type); qInfo("%s===stream===%s: Block is Empty. block type %d", taskIdStr, flag, pBlock->info.type);
return; return;
} }
if (qDebugFlag & DEBUG_DEBUG) { if (qDebugFlag & DEBUG_DEBUG) {
char* pBuf = NULL; char* pBuf = NULL;
int32_t code = dumpBlockData(pBlock, flag, &pBuf, taskIdStr); int32_t code = dumpBlockData(pBlock, flag, &pBuf, taskIdStr);
if (code == 0) { if (code == 0) {
qDebug("%s", pBuf); qInfo("%s", pBuf);
taosMemoryFree(pBuf); taosMemoryFree(pBuf);
} }
} }

View File

@ -678,7 +678,7 @@ int32_t qCreateExecTask(SReadHandle* readHandle, int32_t vgId, uint64_t taskId,
} }
// pSinkParam has been freed during create sinker. // pSinkParam has been freed during create sinker.
code = dsCreateDataSinker(pSinkManager, readHandle->localExec ? &pSink : &pSubplan->pDataSink, handle, pSinkParam, (*pTask)->id.str); code = dsCreateDataSinker(pSinkManager, readHandle->localExec ? &pSink : &pSubplan->pDataSink, handle, pSinkParam, (*pTask)->id.str, pSubplan->processOneBlock);
if (code) { if (code) {
qError("s-task:%s failed to create data sinker, code:%s", (*pTask)->id.str, tstrerror(code)); qError("s-task:%s failed to create data sinker, code:%s", (*pTask)->id.str, tstrerror(code));
} }
@ -697,7 +697,7 @@ static void freeBlock(void* param) {
blockDataDestroy(pBlock); blockDataDestroy(pBlock);
} }
int32_t qExecTaskOpt(qTaskInfo_t tinfo, SArray* pResList, uint64_t* useconds, bool* hasMore, SLocalFetch* pLocal) { int32_t qExecTaskOpt(qTaskInfo_t tinfo, SArray* pResList, uint64_t* useconds, bool* hasMore, SLocalFetch* pLocal, bool processOneBlock) {
int32_t code = TSDB_CODE_SUCCESS; int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0; int32_t lino = 0;
SExecTaskInfo* pTaskInfo = (SExecTaskInfo*)tinfo; SExecTaskInfo* pTaskInfo = (SExecTaskInfo*)tinfo;
@ -792,7 +792,7 @@ int32_t qExecTaskOpt(qTaskInfo_t tinfo, SArray* pResList, uint64_t* useconds, bo
void* tmp = taosArrayPush(pResList, &p); void* tmp = taosArrayPush(pResList, &p);
QUERY_CHECK_NULL(tmp, code, lino, _end, terrno); QUERY_CHECK_NULL(tmp, code, lino, _end, terrno);
if (current >= rowsThreshold) { if (current >= rowsThreshold || processOneBlock) {
break; break;
} }

View File

@ -1202,6 +1202,10 @@ void freeOperatorParamImpl(SOperatorParam* pParam, SOperatorParamType type) {
void freeExchangeGetBasicOperatorParam(void* pParam) { void freeExchangeGetBasicOperatorParam(void* pParam) {
SExchangeOperatorBasicParam* pBasic = (SExchangeOperatorBasicParam*)pParam; SExchangeOperatorBasicParam* pBasic = (SExchangeOperatorBasicParam*)pParam;
taosArrayDestroy(pBasic->uidList); taosArrayDestroy(pBasic->uidList);
if (pBasic->colMap) {
taosArrayDestroy(pBasic->colMap->colMap);
taosMemoryFreeClear(pBasic->colMap);
}
} }
void freeExchangeGetOperatorParam(SOperatorParam* pParam) { void freeExchangeGetOperatorParam(SOperatorParam* pParam) {
@ -1229,13 +1233,31 @@ void freeMergeJoinNotifyOperatorParam(SOperatorParam* pParam) { freeOperatorPara
void freeTableScanGetOperatorParam(SOperatorParam* pParam) { void freeTableScanGetOperatorParam(SOperatorParam* pParam) {
STableScanOperatorParam* pTableScanParam = (STableScanOperatorParam*)pParam->value; STableScanOperatorParam* pTableScanParam = (STableScanOperatorParam*)pParam->value;
taosArrayDestroy(pTableScanParam->pUidList); taosArrayDestroy(pTableScanParam->pUidList);
if (pTableScanParam->pOrgTbInfo) {
taosArrayDestroy(pTableScanParam->pOrgTbInfo->colMap);
taosMemoryFreeClear(pTableScanParam->pOrgTbInfo);
}
freeOperatorParamImpl(pParam, OP_GET_PARAM); freeOperatorParamImpl(pParam, OP_GET_PARAM);
} }
void freeTableScanNotifyOperatorParam(SOperatorParam* pParam) { freeOperatorParamImpl(pParam, OP_NOTIFY_PARAM); } void freeTableScanNotifyOperatorParam(SOperatorParam* pParam) { freeOperatorParamImpl(pParam, OP_NOTIFY_PARAM); }
void freeOpParamItem(void* pItem) {
SOperatorParam* pParam = *(SOperatorParam**)pItem;
pParam->reUse = false;
freeOperatorParam(pParam, OP_GET_PARAM);
}
void freeVirtualTableScanGetOperatorParam(SOperatorParam* pParam) {
SVTableScanOperatorParam* pVTableScanParam = (SVTableScanOperatorParam*)pParam->value;
taosArrayDestroyEx(pVTableScanParam->pOpParamArray, freeOpParamItem);
freeOperatorParamImpl(pParam, OP_GET_PARAM);
}
void freeVTableScanNotifyOperatorParam(SOperatorParam* pParam) { freeOperatorParamImpl(pParam, OP_NOTIFY_PARAM); }
void freeOperatorParam(SOperatorParam* pParam, SOperatorParamType type) { void freeOperatorParam(SOperatorParam* pParam, SOperatorParamType type) {
if (NULL == pParam) { if (NULL == pParam || pParam->reUse) {
return; return;
} }
@ -1252,6 +1274,9 @@ void freeOperatorParam(SOperatorParam* pParam, SOperatorParamType type) {
case QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN: case QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN:
type == OP_GET_PARAM ? freeTableScanGetOperatorParam(pParam) : freeTableScanNotifyOperatorParam(pParam); type == OP_GET_PARAM ? freeTableScanGetOperatorParam(pParam) : freeTableScanNotifyOperatorParam(pParam);
break; break;
case QUERY_NODE_PHYSICAL_PLAN_VIRTUAL_TABLE_SCAN:
type == OP_GET_PARAM ? freeVirtualTableScanGetOperatorParam(pParam) : freeVTableScanNotifyOperatorParam(pParam);
break;
default: default:
qError("unsupported op %d param, type %d", pParam->opType, type); qError("unsupported op %d param, type %d", pParam->opType, type);
break; break;

View File

@ -962,6 +962,7 @@ static int32_t handleGroupCacheRetrievedBlk(struct SOperatorInfo* pOperator, SSD
fakeGcParam.needCache = true; fakeGcParam.needCache = true;
fakeParam.downstreamIdx = pSession->downstreamIdx; fakeParam.downstreamIdx = pSession->downstreamIdx;
fakeParam.value = &fakeGcParam; fakeParam.value = &fakeGcParam;
fakeParam.reUse = false;
code = addNewGroupData(pOperator, &fakeParam, &pGroup, GROUP_CACHE_DEFAULT_VGID, pBlock->info.id.groupId); code = addNewGroupData(pOperator, &fakeParam, &pGroup, GROUP_CACHE_DEFAULT_VGID, pBlock->info.id.groupId);
if (TSDB_CODE_SUCCESS != code) { if (TSDB_CODE_SUCCESS != code) {
return code; return code;

View File

@ -39,7 +39,8 @@ typedef struct SNonSortMergeInfo {
typedef struct SColsMergeInfo { typedef struct SColsMergeInfo {
SNodeList* pTargets; SNodeList* pTargets;
uint64_t srcBlkIds[2]; size_t sourceNum;
uint64_t* srcBlkIds;
} SColsMergeInfo; } SColsMergeInfo;
typedef struct SMultiwayMergeOperatorInfo { typedef struct SMultiwayMergeOperatorInfo {
@ -437,7 +438,7 @@ int32_t doColsMerge(SOperatorInfo* pOperator, SSDataBlock** pResBlock) {
qDebug("start to merge columns, %s", GET_TASKID(pTaskInfo)); qDebug("start to merge columns, %s", GET_TASKID(pTaskInfo));
for (int32_t i = 0; i < 2; ++i) { for (int32_t i = 0; i < pColsMerge->sourceNum; ++i) {
pBlock = getNextBlockFromDownstream(pOperator, i); pBlock = getNextBlockFromDownstream(pOperator, i);
if (pBlock && pBlock->info.rows > 1) { if (pBlock && pBlock->info.rows > 1) {
qError("more than 1 row returned from downstream, rows:%" PRId64, pBlock->info.rows); qError("more than 1 row returned from downstream, rows:%" PRId64, pBlock->info.rows);
@ -453,7 +454,7 @@ int32_t doColsMerge(SOperatorInfo* pOperator, SSDataBlock** pResBlock) {
} }
setOperatorCompleted(pOperator); setOperatorCompleted(pOperator);
if (2 == nullBlkNum) { if (pColsMerge->sourceNum == nullBlkNum) {
return code; return code;
} }
@ -464,6 +465,8 @@ int32_t doColsMerge(SOperatorInfo* pOperator, SSDataBlock** pResBlock) {
} }
void destroyColsMergeOperatorInfo(void* param) { void destroyColsMergeOperatorInfo(void* param) {
SColsMergeInfo* pColsMergeInfo = param;
taosMemoryFreeClear(pColsMergeInfo->srcBlkIds);
} }
int32_t getColsMergeExplainExecInfo(SOperatorInfo* pOptr, void** pOptrExplain, uint32_t* len) { int32_t getColsMergeExplainExecInfo(SOperatorInfo* pOptr, void** pOptrExplain, uint32_t* len) {
@ -640,8 +643,11 @@ int32_t createMultiwayMergeOperatorInfo(SOperatorInfo** downStreams, size_t numS
TSDB_CHECK_CODE(code, lino, _error); TSDB_CHECK_CODE(code, lino, _error);
pColsMerge->pTargets = pMergePhyNode->pTargets; pColsMerge->pTargets = pMergePhyNode->pTargets;
pColsMerge->srcBlkIds[0] = getOperatorResultBlockId(downStreams[0], 0); pColsMerge->sourceNum = numStreams;
pColsMerge->srcBlkIds[1] = getOperatorResultBlockId(downStreams[1], 0); pColsMerge->srcBlkIds = taosMemoryCalloc(numStreams, sizeof(uint64_t));
for (size_t i = 0; i < numStreams; ++i) {
pColsMerge->srcBlkIds[i] = getOperatorResultBlockId(downStreams[i], 0);
}
break; break;
} }
default: default:

View File

@ -512,6 +512,8 @@ int32_t createOperator(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, SReadHand
} }
} else if (QUERY_NODE_PHYSICAL_PLAN_PROJECT == type) { } else if (QUERY_NODE_PHYSICAL_PLAN_PROJECT == type) {
code = createProjectOperatorInfo(NULL, (SProjectPhysiNode*)pPhyNode, pTaskInfo, &pOperator); code = createProjectOperatorInfo(NULL, (SProjectPhysiNode*)pPhyNode, pTaskInfo, &pOperator);
} else if (QUERY_NODE_PHYSICAL_PLAN_VIRTUAL_TABLE_SCAN == type) {
code = createVirtualTableMergeOperatorInfo(NULL, pHandle, NULL, 0, (SVirtualScanPhysiNode*)pPhyNode, pTaskInfo, &pOperator);
} else { } else {
code = TSDB_CODE_INVALID_PARA; code = TSDB_CODE_INVALID_PARA;
pTaskInfo->code = code; pTaskInfo->code = code;
@ -630,7 +632,7 @@ int32_t createOperator(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, SReadHand
} else if (QUERY_NODE_PHYSICAL_PLAN_GROUP_CACHE == type) { } else if (QUERY_NODE_PHYSICAL_PLAN_GROUP_CACHE == type) {
code = createGroupCacheOperatorInfo(ops, size, (SGroupCachePhysiNode*)pPhyNode, pTaskInfo, &pOptr); code = createGroupCacheOperatorInfo(ops, size, (SGroupCachePhysiNode*)pPhyNode, pTaskInfo, &pOptr);
} else if (QUERY_NODE_PHYSICAL_PLAN_DYN_QUERY_CTRL == type) { } else if (QUERY_NODE_PHYSICAL_PLAN_DYN_QUERY_CTRL == type) {
code = createDynQueryCtrlOperatorInfo(ops, size, (SDynQueryCtrlPhysiNode*)pPhyNode, pTaskInfo, &pOptr); code = createDynQueryCtrlOperatorInfo(ops, size, (SDynQueryCtrlPhysiNode*)pPhyNode, pTaskInfo, pHandle, &pOptr);
} else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_COUNT == type) { } else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_COUNT == type) {
code = createStreamCountAggOperatorInfo(ops[0], pPhyNode, pTaskInfo, pHandle, &pOptr); code = createStreamCountAggOperatorInfo(ops[0], pPhyNode, pTaskInfo, pHandle, &pOptr);
} else if (QUERY_NODE_PHYSICAL_PLAN_MERGE_COUNT == type) { } else if (QUERY_NODE_PHYSICAL_PLAN_MERGE_COUNT == type) {
@ -651,6 +653,39 @@ int32_t createOperator(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, SReadHand
code = createEventNonblockOperatorInfo(ops[0], pPhyNode, pTaskInfo, pHandle, &pOptr); code = createEventNonblockOperatorInfo(ops[0], pPhyNode, pTaskInfo, pHandle, &pOptr);
} else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_CONTINUE_COUNT == type) { } else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_CONTINUE_COUNT == type) {
//todo (liuyao) add //todo (liuyao) add
} else if (QUERY_NODE_PHYSICAL_PLAN_VIRTUAL_TABLE_SCAN == type) {
SVirtualScanPhysiNode* pVirtualTableScanNode = (SVirtualScanPhysiNode*)pPhyNode;
// NOTE: this is an patch to fix the physical plan
if (pVirtualTableScanNode->scan.node.pLimit != NULL) {
pVirtualTableScanNode->groupSort = true;
}
STableListInfo* pTableListInfo = tableListCreate();
if (!pTableListInfo) {
pTaskInfo->code = terrno;
qError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(terrno));
return terrno;
}
code = initQueriedTableSchemaInfo(pHandle, &pVirtualTableScanNode->scan, dbname, pTaskInfo);
if (code) {
pTaskInfo->code = code;
tableListDestroy(pTableListInfo);
return code;
}
code = createScanTableListInfo(&pVirtualTableScanNode->scan, pVirtualTableScanNode->pGroupTags, pVirtualTableScanNode->groupSort,
pHandle, pTableListInfo, pTagCond, pTagIndexCond, pTaskInfo);
if (code) {
pTaskInfo->code = code;
tableListDestroy(pTableListInfo);
qError("failed to createScanTableListInfo, code:%s, %s", tstrerror(code), idstr);
return code;
}
code = createVirtualTableMergeOperatorInfo(ops, pHandle, pTableListInfo, size, (SVirtualScanPhysiNode*)pPhyNode, pTaskInfo, &pOptr);
} else { } else {
code = TSDB_CODE_INVALID_PARA; code = TSDB_CODE_INVALID_PARA;
pTaskInfo->code = code; pTaskInfo->code = code;

View File

@ -176,7 +176,7 @@ int32_t initQueriedTableSchemaInfo(SReadHandle* pHandle, SScanPhysiNode* pScanNo
if (mr.me.type == TSDB_SUPER_TABLE) { if (mr.me.type == TSDB_SUPER_TABLE) {
schemaInfo.sw = tCloneSSchemaWrapper(&mr.me.stbEntry.schemaRow); schemaInfo.sw = tCloneSSchemaWrapper(&mr.me.stbEntry.schemaRow);
schemaInfo.tversion = mr.me.stbEntry.schemaTag.version; schemaInfo.tversion = mr.me.stbEntry.schemaTag.version;
} else if (mr.me.type == TSDB_CHILD_TABLE) { } else if (mr.me.type == TSDB_CHILD_TABLE || mr.me.type == TSDB_VIRTUAL_CHILD_TABLE) {
tDecoderClear(&mr.coder); tDecoderClear(&mr.coder);
tb_uid_t suid = mr.me.ctbEntry.suid; tb_uid_t suid = mr.me.ctbEntry.suid;

View File

@ -332,6 +332,10 @@ bool applyLimitOffset(SLimitInfo* pLimitInfo, SSDataBlock* pBlock, SExecTaskInfo
return false; return false;
} }
static bool isDynVtbScan(SOperatorInfo* pOperator) {
return pOperator->dynamicTask && ((STableScanInfo*)(pOperator->info))->virtualStableScan;
}
static int32_t loadDataBlock(SOperatorInfo* pOperator, STableScanBase* pTableScanInfo, SSDataBlock* pBlock, static int32_t loadDataBlock(SOperatorInfo* pOperator, STableScanBase* pTableScanInfo, SSDataBlock* pBlock,
uint32_t* status) { uint32_t* status) {
int32_t code = TSDB_CODE_SUCCESS; int32_t code = TSDB_CODE_SUCCESS;
@ -474,10 +478,15 @@ static int32_t loadDataBlock(SOperatorInfo* pOperator, STableScanBase* pTableSca
return code; return code;
} }
if ((pOperator->operatorType == QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN) && ((STableScanInfo *)pOperator->info)->ignoreTag) {
// do nothing
} else {
// dyn vtb scan do not read tag from origin tables.
code = doSetTagColumnData(pTableScanInfo, pBlock, pTaskInfo, pBlock->info.rows); code = doSetTagColumnData(pTableScanInfo, pBlock, pTaskInfo, pBlock->info.rows);
if (code) { if (code) {
return code; return code;
} }
}
// restore the previous value // restore the previous value
pCost->totalRows -= pBlock->info.rows; pCost->totalRows -= pBlock->info.rows;
@ -549,7 +558,7 @@ static int32_t createTableCacheVal(const SMetaReader* pMetaReader, STableCachedV
QUERY_CHECK_NULL(pVal->pName, code, lino, _end, terrno); QUERY_CHECK_NULL(pVal->pName, code, lino, _end, terrno);
// only child table has tag value // only child table has tag value
if (pMetaReader->me.type == TSDB_CHILD_TABLE) { if (pMetaReader->me.type == TSDB_CHILD_TABLE || pMetaReader->me.type == TSDB_VIRTUAL_CHILD_TABLE) {
STag* pTag = (STag*)pMetaReader->me.ctbEntry.pTags; STag* pTag = (STag*)pMetaReader->me.ctbEntry.pTags;
pVal->pTags = taosMemoryMalloc(pTag->len); pVal->pTags = taosMemoryMalloc(pTag->len);
QUERY_CHECK_NULL(pVal->pTags, code, lino, _end, terrno); QUERY_CHECK_NULL(pVal->pTags, code, lino, _end, terrno);
@ -1183,6 +1192,145 @@ static int32_t createTableListInfoFromParam(SOperatorInfo* pOperator) {
return code; return code;
} }
static int32_t doInitReader(STableScanInfo* pInfo, SExecTaskInfo* pTaskInfo, SStorageAPI* pAPI, int32_t* pNum,
STableKeyInfo** pList) {
const char* idStr = GET_TASKID(pTaskInfo);
int32_t code = initNextGroupScan(pInfo, pList, pNum);
if (code) {
qError("%s failed to init groupScan Info, code:%s at line:%d", idStr, tstrerror(code), __LINE__);
return code;
}
if (pInfo->base.dataReader != NULL) {
qError("%s tsdb reader should be null", idStr);
return TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
}
code = pAPI->tsdReader.tsdReaderOpen(pInfo->base.readHandle.vnode, &pInfo->base.cond, *pList, *pNum, pInfo->pResBlock,
(void**)&pInfo->base.dataReader, idStr, &pInfo->pIgnoreTables);
if (code) {
qError("%s failed to open tsdbReader, code:%s at line:%d", idStr, tstrerror(code), __LINE__);
}
return code;
}
static int32_t createVTableScanInfoFromParam(SOperatorInfo* pOperator) {
int32_t code = 0;
int32_t lino = 0;
STableScanInfo* pInfo = pOperator->info;
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
SStorageAPI* pAPI = &pTaskInfo->storageAPI;
STableListInfo* pListInfo = pInfo->base.pTableListInfo;
STableScanOperatorParam* pParam = (STableScanOperatorParam*)pOperator->pOperatorGetParam->value;
SMetaReader orgTable = {0};
SMetaReader superTable = {0};
SSchemaWrapper* schema = NULL;
SArray* pColArray = NULL;
SArray* pBlockColArray = NULL;
int32_t num = 0;
STableKeyInfo* pList = NULL;
cleanupQueryTableDataCond(&pInfo->base.cond);
if (pAPI->tsdReader.tsdReaderClose) {
pAPI->tsdReader.tsdReaderClose(pInfo->base.dataReader);
}
pAPI->metaReaderFn.initReader(&orgTable, pInfo->base.readHandle.vnode, META_READER_LOCK, &pAPI->metaFn);
QUERY_CHECK_CODE(pAPI->metaReaderFn.getTableEntryByName(&orgTable, strstr(pParam->pOrgTbInfo->tbName, ".") + 1), lino, _return);
switch (orgTable.me.type) {
case TSDB_CHILD_TABLE:
pAPI->metaReaderFn.initReader(&superTable, pInfo->base.readHandle.vnode, META_READER_LOCK, &pAPI->metaFn);
QUERY_CHECK_CODE(pAPI->metaReaderFn.getTableEntryByUid(&superTable, orgTable.me.ctbEntry.suid), lino, _return);
schema = &superTable.me.stbEntry.schemaRow;
break;
case TSDB_NORMAL_TABLE:
schema = &orgTable.me.ntbEntry.schemaRow;
break;
default:
qError("invalid table type:%d", orgTable.me.type);
return TSDB_CODE_INVALID_PARA;
break;
}
pColArray = taosArrayInit(schema->nCols, sizeof(SColIdPair));
QUERY_CHECK_NULL(pColArray, code, lino, _return, terrno);
pBlockColArray = taosArrayInit(schema->nCols, sizeof(int32_t));
QUERY_CHECK_NULL(pBlockColArray, code, lino, _return, terrno);
// virtual table's origin table scan do not has ts column.
SColIdPair tsPair = {.vtbColId = PRIMARYKEY_TIMESTAMP_COL_ID, .orgColId = PRIMARYKEY_TIMESTAMP_COL_ID};
QUERY_CHECK_NULL(taosArrayPush(pColArray, &tsPair), code, lino, _return, terrno);
for (int32_t i = 0; i < taosArrayGetSize(pParam->pOrgTbInfo->colMap); ++i) {
SColIdNameKV *kv = taosArrayGet(pParam->pOrgTbInfo->colMap, i);
for (int32_t j = 0; j < schema->nCols; j++) {
if (strncmp(kv->colName, schema->pSchema[j].name, strlen(schema->pSchema[j].name)) == 0) {
SColIdPair pPair = {.vtbColId = kv->colId, .orgColId = (col_id_t)(j + 1)};
QUERY_CHECK_NULL(taosArrayPush(pColArray, &pPair), code, lino, _return, terrno);
break;
}
}
}
for (int32_t i = 0; i < taosArrayGetSize(pColArray); i++) {
SColIdPair *pPair = (SColIdPair*)taosArrayGet(pColArray, i);
for (int32_t j = 0; j < taosArrayGetSize(pInfo->base.matchInfo.pList); j++) {
SColMatchItem *pItem = taosArrayGet(pInfo->base.matchInfo.pList, j);
if (pItem->colId == pPair->vtbColId) {
SColIdPair tmpPair = {.orgColId = pPair->orgColId, .vtbColId = pItem->dstSlotId};
QUERY_CHECK_NULL(taosArrayPush(pBlockColArray, &tmpPair), code, lino, _return, terrno);
break;
}
}
}
if (pInfo->pResBlock) {
blockDataDestroy(pInfo->pResBlock);
pInfo->pResBlock = NULL;
}
QUERY_CHECK_CODE(createOneDataBlockWithColArray(pInfo->pOrgBlock, pBlockColArray, &pInfo->pResBlock), lino, _return);
QUERY_CHECK_CODE(initQueryTableDataCondWithColArray(&pInfo->base.cond, &pInfo->base.orgCond, &pInfo->base.readHandle, pColArray), lino, _return);
pInfo->base.cond.twindows.skey = pParam->window.ekey + 1;
pInfo->base.cond.suid = orgTable.me.type == TSDB_CHILD_TABLE ? superTable.me.uid : 0;
pInfo->currentGroupId = 0;
pInfo->base.dataReader = NULL;
pInfo->ignoreTag = true;
pListInfo->oneTableForEachGroup = true;
taosHashClear(pListInfo->map);
taosArrayClear(pListInfo->pTableList);
uint64_t pUid = orgTable.me.uid;
STableKeyInfo info = {.groupId = 0, .uid = pUid};
int32_t tableIdx = 0;
QUERY_CHECK_CODE(taosHashPut(pListInfo->map, &pUid, sizeof(uint64_t), &tableIdx, sizeof(int32_t)), lino, _return);
QUERY_CHECK_NULL(taosArrayPush(pListInfo->pTableList, &info), code, lino, _return, terrno);
qDebug("add dynamic table scan uid:%" PRIu64 ", %s", info.uid, GET_TASKID(pTaskInfo));
pOperator->status = OP_OPENED;
taosRLockLatch(&pTaskInfo->lock);
code = doInitReader(pInfo, pTaskInfo, pAPI, &num, &pList);
taosRUnLockLatch(&pTaskInfo->lock);
QUERY_CHECK_CODE(code, lino, _return);
if (pInfo->pResBlock->info.capacity > pOperator->resultInfo.capacity) {
pOperator->resultInfo.capacity = pInfo->pResBlock->info.capacity;
}
pInfo->currentGroupId = -1;
_return:
if (code) {
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
}
taosArrayDestroy(pColArray);
taosArrayDestroy(pBlockColArray);
pAPI->metaReaderFn.clearReader(&superTable);
pAPI->metaReaderFn.clearReader(&orgTable);
return code;
}
static int32_t startNextGroupScan(SOperatorInfo* pOperator, SSDataBlock** pResult) { static int32_t startNextGroupScan(SOperatorInfo* pOperator, SSDataBlock** pResult) {
int32_t code = TSDB_CODE_SUCCESS; int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0; int32_t lino = 0;
@ -1239,29 +1387,6 @@ _end:
return code; return code;
} }
static int32_t doInitReader(STableScanInfo* pInfo, SExecTaskInfo* pTaskInfo, SStorageAPI* pAPI, int32_t* pNum,
STableKeyInfo** pList) {
const char* idStr = GET_TASKID(pTaskInfo);
int32_t code = initNextGroupScan(pInfo, pList, pNum);
if (code) {
qError("%s failed to init groupScan Info, code:%s at line:%d", idStr, tstrerror(code), __LINE__);
return code;
}
if (pInfo->base.dataReader != NULL) {
qError("%s tsdb reader should be null", idStr);
return TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
}
code = pAPI->tsdReader.tsdReaderOpen(pInfo->base.readHandle.vnode, &pInfo->base.cond, *pList, *pNum, pInfo->pResBlock,
(void**)&pInfo->base.dataReader, idStr, &pInfo->pIgnoreTables);
if (code) {
qError("%s failed to open tsdbReader, code:%s at line:%d", idStr, tstrerror(code), __LINE__);
}
return code;
}
static int32_t groupSeqTableScan(SOperatorInfo* pOperator, SSDataBlock** pResBlock) { static int32_t groupSeqTableScan(SOperatorInfo* pOperator, SSDataBlock** pResBlock) {
int32_t code = TSDB_CODE_SUCCESS; int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0; int32_t lino = 0;
@ -1336,6 +1461,29 @@ int32_t doTableScanNext(SOperatorInfo* pOperator, SSDataBlock** ppRes) {
if (pOperator->pOperatorGetParam) { if (pOperator->pOperatorGetParam) {
pOperator->dynamicTask = true; pOperator->dynamicTask = true;
if (isDynVtbScan(pOperator)) {
code = createVTableScanInfoFromParam(pOperator);
freeOperatorParam(pOperator->pOperatorGetParam, OP_GET_PARAM);
pOperator->pOperatorGetParam = NULL;
QUERY_CHECK_CODE(code, lino, _end);
SSDataBlock* result = NULL;
while (true) {
QUERY_CHECK_CODE(startNextGroupScan(pOperator, &result), lino, _end);
if (result || pOperator->status == OP_EXEC_DONE) {
SSDataBlock* res = NULL;
if (result) {
QUERY_CHECK_CODE(createOneDataBlockWithTwoBlock(result, pInfo->pOrgBlock, &res), lino, _end);
pInfo->pResBlock = res;
blockDataDestroy(result);
}
(*ppRes) = res;
return code;
}
}
} else {
code = createTableListInfoFromParam(pOperator); code = createTableListInfoFromParam(pOperator);
freeOperatorParam(pOperator->pOperatorGetParam, OP_GET_PARAM); freeOperatorParam(pOperator->pOperatorGetParam, OP_GET_PARAM);
pOperator->pOperatorGetParam = NULL; pOperator->pOperatorGetParam = NULL;
@ -1357,6 +1505,7 @@ int32_t doTableScanNext(SOperatorInfo* pOperator, SSDataBlock** ppRes) {
} }
} }
} }
}
// scan table one by one sequentially // scan table one by one sequentially
if (pInfo->scanMode == TABLE_SCAN__TABLE_ORDER) { if (pInfo->scanMode == TABLE_SCAN__TABLE_ORDER) {
@ -1440,6 +1589,7 @@ static int32_t getTableScannerExecInfo(struct SOperatorInfo* pOptr, void** pOptr
static void destroyTableScanBase(STableScanBase* pBase, TsdReader* pAPI) { static void destroyTableScanBase(STableScanBase* pBase, TsdReader* pAPI) {
cleanupQueryTableDataCond(&pBase->cond); cleanupQueryTableDataCond(&pBase->cond);
cleanupQueryTableDataCond(&pBase->orgCond);
if (pAPI->tsdReaderClose) { if (pAPI->tsdReaderClose) {
pAPI->tsdReaderClose(pBase->dataReader); pAPI->tsdReaderClose(pBase->dataReader);
@ -1458,6 +1608,7 @@ static void destroyTableScanBase(STableScanBase* pBase, TsdReader* pAPI) {
static void destroyTableScanOperatorInfo(void* param) { static void destroyTableScanOperatorInfo(void* param) {
STableScanInfo* pTableScanInfo = (STableScanInfo*)param; STableScanInfo* pTableScanInfo = (STableScanInfo*)param;
blockDataDestroy(pTableScanInfo->pResBlock); blockDataDestroy(pTableScanInfo->pResBlock);
blockDataDestroy(pTableScanInfo->pOrgBlock);
taosHashCleanup(pTableScanInfo->pIgnoreTables); taosHashCleanup(pTableScanInfo->pIgnoreTables);
destroyTableScanBase(&pTableScanInfo->base, &pTableScanInfo->base.readerAPI); destroyTableScanBase(&pTableScanInfo->base, &pTableScanInfo->base.readerAPI);
taosMemoryFreeClear(param); taosMemoryFreeClear(param);
@ -1531,6 +1682,14 @@ int32_t createTableScanOperatorInfo(STableScanPhysiNode* pTableScanNode, SReadHa
code = prepareDataBlockBuf(pInfo->pResBlock, &pInfo->base.matchInfo); code = prepareDataBlockBuf(pInfo->pResBlock, &pInfo->base.matchInfo);
QUERY_CHECK_CODE(code, lino, _error); QUERY_CHECK_CODE(code, lino, _error);
pInfo->virtualStableScan = pScanNode->virtualStableScan;
if (pScanNode->node.dynamicOp && pScanNode->virtualStableScan) {
TSWAP(pInfo->pOrgBlock, pInfo->pResBlock);
pInfo->pResBlock = NULL;
memcpy(&pInfo->base.orgCond, &pInfo->base.cond, sizeof(SQueryTableDataCond));
memset(&pInfo->base.cond, 0, sizeof(SQueryTableDataCond));
}
code = filterInitFromNode((SNode*)pTableScanNode->scan.node.pConditions, &pOperator->exprSupp.pFilterInfo, 0); code = filterInitFromNode((SNode*)pTableScanNode->scan.node.pConditions, &pOperator->exprSupp.pFilterInfo, 0);
QUERY_CHECK_CODE(code, lino, _error); QUERY_CHECK_CODE(code, lino, _error);
@ -1545,6 +1704,7 @@ int32_t createTableScanOperatorInfo(STableScanPhysiNode* pTableScanNode, SReadHa
pOperator->exprSupp.numOfExprs = numOfCols; pOperator->exprSupp.numOfExprs = numOfCols;
pInfo->needCountEmptyTable = tsCountAlwaysReturnValue && pTableScanNode->needCountEmptyTable; pInfo->needCountEmptyTable = tsCountAlwaysReturnValue && pTableScanNode->needCountEmptyTable;
pInfo->ignoreTag = false;
pInfo->base.pTableListInfo = pTableListInfo; pInfo->base.pTableListInfo = pTableListInfo;
pInfo->base.metaCache.pTableMetaEntryCache = taosLRUCacheInit(1024 * 128, -1, .5); pInfo->base.metaCache.pTableMetaEntryCache = taosLRUCacheInit(1024 * 128, -1, .5);

View File

@ -156,7 +156,7 @@ static int32_t sysTableUserTagsFillOneTableTags(const SSysTableScanInfo* pInfo,
static int32_t sysTableUserColsFillOneTableCols(const SSysTableScanInfo* pInfo, const char* dbname, int32_t* pNumOfRows, static int32_t sysTableUserColsFillOneTableCols(const SSysTableScanInfo* pInfo, const char* dbname, int32_t* pNumOfRows,
const SSDataBlock* dataBlock, char* tName, SSchemaWrapper* schemaRow, const SSDataBlock* dataBlock, char* tName, SSchemaWrapper* schemaRow,
char* tableType); char* tableType, SColRefWrapper *colRef);
static void relocateAndFilterSysTagsScanResult(SSysTableScanInfo* pInfo, int32_t numOfRows, SSDataBlock* dataBlock, static void relocateAndFilterSysTagsScanResult(SSysTableScanInfo* pInfo, int32_t numOfRows, SSDataBlock* dataBlock,
SFilterInfo* pFilterInfo, SExecTaskInfo* pTaskInfo); SFilterInfo* pFilterInfo, SExecTaskInfo* pTaskInfo);
@ -509,15 +509,23 @@ static SSDataBlock* doOptimizeTableNameFilter(SOperatorInfo* pOperator, SSDataBl
char typeName[TSDB_TABLE_FNAME_LEN + VARSTR_HEADER_SIZE] = {0}; char typeName[TSDB_TABLE_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
SSchemaWrapper* schemaRow = NULL; SSchemaWrapper* schemaRow = NULL;
SColRefWrapper* colRef = NULL;
if (smrTable.me.type == TSDB_SUPER_TABLE) { if (smrTable.me.type == TSDB_SUPER_TABLE) {
schemaRow = &smrTable.me.stbEntry.schemaRow; schemaRow = &smrTable.me.stbEntry.schemaRow;
STR_TO_VARSTR(typeName, "CHILD_TABLE"); STR_TO_VARSTR(typeName, "CHILD_TABLE");
} else if (smrTable.me.type == TSDB_NORMAL_TABLE) { } else if (smrTable.me.type == TSDB_NORMAL_TABLE) {
schemaRow = &smrTable.me.ntbEntry.schemaRow; schemaRow = &smrTable.me.ntbEntry.schemaRow;
STR_TO_VARSTR(typeName, "NORMAL_TABLE"); STR_TO_VARSTR(typeName, "NORMAL_TABLE");
} else if (smrTable.me.type == TSDB_VIRTUAL_NORMAL_TABLE) {
schemaRow = &smrTable.me.ntbEntry.schemaRow;
colRef = &smrTable.me.colRef;
STR_TO_VARSTR(typeName, "VIRTUAL_NORMAL_TABLE");
} else if (smrTable.me.type == TSDB_VIRTUAL_CHILD_TABLE) {
colRef = &smrTable.me.colRef;
STR_TO_VARSTR(typeName, "VIRTUAL_CHILD_TABLE");
} }
code = sysTableUserColsFillOneTableCols(pInfo, dbname, &numOfRows, dataBlock, tableName, schemaRow, typeName); code = sysTableUserColsFillOneTableCols(pInfo, dbname, &numOfRows, dataBlock, tableName, schemaRow, typeName, colRef);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
pAPI->metaReaderFn.clearReader(&smrTable); pAPI->metaReaderFn.clearReader(&smrTable);
pInfo->loadInfo.totalRows = 0; pInfo->loadInfo.totalRows = 0;
@ -623,6 +631,7 @@ static SSDataBlock* sysTableScanUserCols(SOperatorInfo* pOperator) {
char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0}; char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
SSchemaWrapper* schemaRow = NULL; SSchemaWrapper* schemaRow = NULL;
SColRefWrapper* colRef = NULL;
if (pInfo->pCur->mr.me.type == TSDB_SUPER_TABLE) { if (pInfo->pCur->mr.me.type == TSDB_SUPER_TABLE) {
qDebug("sysTableScanUserCols cursor get super table, %s", GET_TASKID(pTaskInfo)); qDebug("sysTableScanUserCols cursor get super table, %s", GET_TASKID(pTaskInfo));
@ -684,6 +693,53 @@ static SSDataBlock* sysTableScanUserCols(SOperatorInfo* pOperator) {
schemaRow = &pInfo->pCur->mr.me.ntbEntry.schemaRow; schemaRow = &pInfo->pCur->mr.me.ntbEntry.schemaRow;
STR_TO_VARSTR(typeName, "NORMAL_TABLE"); STR_TO_VARSTR(typeName, "NORMAL_TABLE");
STR_TO_VARSTR(tableName, pInfo->pCur->mr.me.name); STR_TO_VARSTR(tableName, pInfo->pCur->mr.me.name);
} else if (pInfo->pCur->mr.me.type == TSDB_VIRTUAL_NORMAL_TABLE) {
qDebug("sysTableScanUserCols cursor get virtual normal table, %s", GET_TASKID(pTaskInfo));
schemaRow = &pInfo->pCur->mr.me.ntbEntry.schemaRow;
STR_TO_VARSTR(typeName, "VIRTUAL_NORMAL_TABLE");
STR_TO_VARSTR(tableName, pInfo->pCur->mr.me.name);
colRef = &pInfo->pCur->mr.me.colRef;
} else if (pInfo->pCur->mr.me.type == TSDB_VIRTUAL_CHILD_TABLE) {
qDebug("sysTableScanUserCols cursor get virtual child table, %s", GET_TASKID(pTaskInfo));
STR_TO_VARSTR(typeName, "VIRTUAL_CHILD_TABLE");
STR_TO_VARSTR(tableName, pInfo->pCur->mr.me.name);
colRef = &pInfo->pCur->mr.me.colRef;
int64_t suid = pInfo->pCur->mr.me.ctbEntry.suid;
void* schema = taosHashGet(pInfo->pSchema, &pInfo->pCur->mr.me.ctbEntry.suid, sizeof(int64_t));
if (schema != NULL) {
schemaRow = *(SSchemaWrapper**)schema;
} else {
SMetaReader smrSuperTable = {0};
pAPI->metaReaderFn.initReader(&smrSuperTable, pInfo->readHandle.vnode, META_READER_NOLOCK, &pAPI->metaFn);
code = pAPI->metaReaderFn.getTableEntryByUid(&smrSuperTable, suid);
if (code != TSDB_CODE_SUCCESS) {
// terrno has been set by pAPI->metaReaderFn.getTableEntryByName, therefore, return directly
qError("sysTableScanUserCols get meta by suid:%" PRId64 " error, code:%d, %s", suid, code,
GET_TASKID(pTaskInfo));
pAPI->metaReaderFn.clearReader(&smrSuperTable);
blockDataDestroy(pDataBlock);
pInfo->loadInfo.totalRows = 0;
return NULL;
}
SSchemaWrapper* schemaWrapper = tCloneSSchemaWrapper(&smrSuperTable.me.stbEntry.schemaRow);
if (smrSuperTable.me.stbEntry.schemaRow.pSchema) {
if (schemaWrapper == NULL) {
code = terrno;
lino = __LINE__;
pAPI->metaReaderFn.clearReader(&smrSuperTable);
goto _end;
}
}
code = taosHashPut(pInfo->pSchema, &suid, sizeof(int64_t), &schemaWrapper, POINTER_BYTES);
if (code == TSDB_CODE_DUP_KEY) {
code = TSDB_CODE_SUCCESS;
}
schemaRow = schemaWrapper;
pAPI->metaReaderFn.clearReader(&smrSuperTable);
QUERY_CHECK_CODE(code, lino, _end);
}
} else { } else {
qDebug("sysTableScanUserCols cursor get invalid table, %s", GET_TASKID(pTaskInfo)); qDebug("sysTableScanUserCols cursor get invalid table, %s", GET_TASKID(pTaskInfo));
continue; continue;
@ -699,7 +755,7 @@ static SSDataBlock* sysTableScanUserCols(SOperatorInfo* pOperator) {
} }
} }
// if pInfo->pRes->info.rows == 0, also need to add the meta to pDataBlock // if pInfo->pRes->info.rows == 0, also need to add the meta to pDataBlock
code = sysTableUserColsFillOneTableCols(pInfo, dbname, &numOfRows, pDataBlock, tableName, schemaRow, typeName); code = sysTableUserColsFillOneTableCols(pInfo, dbname, &numOfRows, pDataBlock, tableName, schemaRow, typeName, colRef);
QUERY_CHECK_CODE(code, lino, _end); QUERY_CHECK_CODE(code, lino, _end);
} }
@ -782,7 +838,7 @@ static SSDataBlock* sysTableScanUserTags(SOperatorInfo* pOperator) {
return NULL; return NULL;
} }
if (smrChildTable.me.type != TSDB_CHILD_TABLE) { if (smrChildTable.me.type != TSDB_CHILD_TABLE && smrChildTable.me.type != TSDB_VIRTUAL_CHILD_TABLE) {
pAPI->metaReaderFn.clearReader(&smrChildTable); pAPI->metaReaderFn.clearReader(&smrChildTable);
blockDataDestroy(dataBlock); blockDataDestroy(dataBlock);
pInfo->loadInfo.totalRows = 0; pInfo->loadInfo.totalRows = 0;
@ -828,7 +884,7 @@ static SSDataBlock* sysTableScanUserTags(SOperatorInfo* pOperator) {
} }
while ((ret = pAPI->metaFn.cursorNext(pInfo->pCur, TSDB_SUPER_TABLE)) == 0) { while ((ret = pAPI->metaFn.cursorNext(pInfo->pCur, TSDB_SUPER_TABLE)) == 0) {
if (pInfo->pCur->mr.me.type != TSDB_CHILD_TABLE) { if (pInfo->pCur->mr.me.type != TSDB_CHILD_TABLE && pInfo->pCur->mr.me.type != TSDB_VIRTUAL_CHILD_TABLE) {
continue; continue;
} }
@ -1181,7 +1237,7 @@ _end:
static int32_t sysTableUserColsFillOneTableCols(const SSysTableScanInfo* pInfo, const char* dbname, int32_t* pNumOfRows, static int32_t sysTableUserColsFillOneTableCols(const SSysTableScanInfo* pInfo, const char* dbname, int32_t* pNumOfRows,
const SSDataBlock* dataBlock, char* tName, SSchemaWrapper* schemaRow, const SSDataBlock* dataBlock, char* tName, SSchemaWrapper* schemaRow,
char* tableType) { char* tableType, SColRefWrapper *colRef) {
int32_t code = TSDB_CODE_SUCCESS; int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0; int32_t lino = 0;
if (schemaRow == NULL) { if (schemaRow == NULL) {
@ -1252,6 +1308,25 @@ static int32_t sysTableUserColsFillOneTableCols(const SSysTableScanInfo* pInfo,
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno); QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
colDataSetNULL(pColInfoData, numOfRows); colDataSetNULL(pColInfoData, numOfRows);
} }
// col data source
pColInfoData = taosArrayGet(dataBlock->pDataBlock, 9);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
if (!colRef || !colRef->pColRef[i].hasRef) {
colDataSetNULL(pColInfoData, numOfRows);
} else {
char refColName[TSDB_DB_NAME_LEN + TSDB_NAME_DELIMITER_LEN + TSDB_COL_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
char tmpColName[TSDB_DB_NAME_LEN + TSDB_NAME_DELIMITER_LEN + TSDB_COL_FNAME_LEN] = {0};
strcat(tmpColName, colRef->pColRef[i].refDbName);
strcat(tmpColName, ".");
strcat(tmpColName, colRef->pColRef[i].refTableName);
strcat(tmpColName, ".");
strcat(tmpColName, colRef->pColRef[i].refColName);
STR_TO_VARSTR(refColName, tmpColName);
code = colDataSetVal(pColInfoData, numOfRows, (char *)refColName, false);
QUERY_CHECK_CODE(code, lino, _end);
}
++numOfRows; ++numOfRows;
} }
@ -1560,6 +1635,104 @@ static int32_t doSetUserTableMetaInfo(SStoreMetaReader* pMetaReaderFn, SStoreMet
STR_TO_VARSTR(n, "NORMAL_TABLE"); STR_TO_VARSTR(n, "NORMAL_TABLE");
// impl later // impl later
} else if (tableType == TSDB_VIRTUAL_NORMAL_TABLE) {
// create time
pColInfoData = taosArrayGet(p->pDataBlock, 2);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
code = colDataSetVal(pColInfoData, rowIndex, (char*)&pMReader->me.ntbEntry.btime, false);
QUERY_CHECK_CODE(code, lino, _end);
// number of columns
pColInfoData = taosArrayGet(p->pDataBlock, 3);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
code = colDataSetVal(pColInfoData, rowIndex, (char*)&pMReader->me.ntbEntry.schemaRow.nCols, false);
QUERY_CHECK_CODE(code, lino, _end);
// super table name
pColInfoData = taosArrayGet(p->pDataBlock, 4);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
colDataSetNULL(pColInfoData, rowIndex);
// table comment
pColInfoData = taosArrayGet(p->pDataBlock, 8);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
colDataSetNULL(pColInfoData, rowIndex);
// uid
pColInfoData = taosArrayGet(p->pDataBlock, 5);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
code = colDataSetVal(pColInfoData, rowIndex, (char*)&pMReader->me.uid, false);
QUERY_CHECK_CODE(code, lino, _end);
// ttl
pColInfoData = taosArrayGet(p->pDataBlock, 7);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
colDataSetNULL(pColInfoData, rowIndex);
STR_TO_VARSTR(n, "VIRTUAL_NORMAL_TABLE");
// impl later
} else if (tableType == TSDB_VIRTUAL_CHILD_TABLE) {
// create time
int64_t ts = pMReader->me.ctbEntry.btime;
pColInfoData = taosArrayGet(p->pDataBlock, 2);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
code = colDataSetVal(pColInfoData, rowIndex, (char*)&ts, false);
QUERY_CHECK_CODE(code, lino, _end);
SMetaReader mr1 = {0};
pMetaReaderFn->initReader(&mr1, pVnode, META_READER_NOLOCK, pMetaFn);
int64_t suid = pMReader->me.ctbEntry.suid;
code = pMetaReaderFn->getTableEntryByUid(&mr1, suid);
if (code != TSDB_CODE_SUCCESS) {
qError("failed to get super table meta, cname:%s, suid:0x%" PRIx64 ", code:%s, %s", pMReader->me.name, suid,
tstrerror(code), idStr);
pMetaReaderFn->clearReader(&mr1);
QUERY_CHECK_CODE(code, lino, _end);
}
pColInfoData = taosArrayGet(p->pDataBlock, 3);
if (pColInfoData == NULL) {
pMetaReaderFn->clearReader(&mr1);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
}
code = colDataSetVal(pColInfoData, rowIndex, (char*)&mr1.me.stbEntry.schemaRow.nCols, false);
if (code != 0) {
pMetaReaderFn->clearReader(&mr1);
QUERY_CHECK_CODE(code, lino, _end);
}
// super table name
STR_TO_VARSTR(n, mr1.me.name);
pColInfoData = taosArrayGet(p->pDataBlock, 4);
if (pColInfoData == NULL) {
pMetaReaderFn->clearReader(&mr1);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
}
code = colDataSetVal(pColInfoData, rowIndex, n, false);
pMetaReaderFn->clearReader(&mr1);
QUERY_CHECK_CODE(code, lino, _end);
// table comment
pColInfoData = taosArrayGet(p->pDataBlock, 8);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
colDataSetNULL(pColInfoData, rowIndex);
// uid
pColInfoData = taosArrayGet(p->pDataBlock, 5);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
code = colDataSetVal(pColInfoData, rowIndex, (char*)&pMReader->me.uid, false);
QUERY_CHECK_CODE(code, lino, _end);
// ttl
pColInfoData = taosArrayGet(p->pDataBlock, 7);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
colDataSetNULL(pColInfoData, rowIndex);
STR_TO_VARSTR(n, "VIRTUAL_CHILD_TABLE");
} }
_end: _end:
@ -1866,6 +2039,100 @@ static SSDataBlock* sysTableBuildUserTables(SOperatorInfo* pOperator) {
QUERY_CHECK_CODE(code, lino, _end); QUERY_CHECK_CODE(code, lino, _end);
STR_TO_VARSTR(n, "NORMAL_TABLE"); STR_TO_VARSTR(n, "NORMAL_TABLE");
} else if (tableType == TSDB_VIRTUAL_NORMAL_TABLE) {
// create time
pColInfoData = taosArrayGet(p->pDataBlock, 2);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
code = colDataSetVal(pColInfoData, numOfRows, (char*)&pInfo->pCur->mr.me.ntbEntry.btime, false);
QUERY_CHECK_CODE(code, lino, _end);
// number of columns
pColInfoData = taosArrayGet(p->pDataBlock, 3);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
code = colDataSetVal(pColInfoData, numOfRows, (char*)&pInfo->pCur->mr.me.ntbEntry.schemaRow.nCols, false);
QUERY_CHECK_CODE(code, lino, _end);
// super table name
pColInfoData = taosArrayGet(p->pDataBlock, 4);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
colDataSetNULL(pColInfoData, numOfRows);
// table comment
pColInfoData = taosArrayGet(p->pDataBlock, 8);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
colDataSetNULL(pColInfoData, numOfRows);
// uid
pColInfoData = taosArrayGet(p->pDataBlock, 5);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
code = colDataSetVal(pColInfoData, numOfRows, (char*)&pInfo->pCur->mr.me.uid, false);
QUERY_CHECK_CODE(code, lino, _end);
// ttl
pColInfoData = taosArrayGet(p->pDataBlock, 7);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
colDataSetNULL(pColInfoData, numOfRows);
STR_TO_VARSTR(n, "VIRTUAL_NORMAL_TABLE");
} else if (tableType == TSDB_VIRTUAL_CHILD_TABLE) {
// create time
int64_t ts = pInfo->pCur->mr.me.ctbEntry.btime;
pColInfoData = taosArrayGet(p->pDataBlock, 2);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
code = colDataSetVal(pColInfoData, numOfRows, (char*)&ts, false);
QUERY_CHECK_CODE(code, lino, _end);
SMetaReader mr = {0};
pAPI->metaReaderFn.initReader(&mr, pInfo->readHandle.vnode, META_READER_NOLOCK, &pAPI->metaFn);
uint64_t suid = pInfo->pCur->mr.me.ctbEntry.suid;
code = pAPI->metaReaderFn.getTableEntryByUid(&mr, suid);
if (code != TSDB_CODE_SUCCESS) {
qError("failed to get super table meta, cname:%s, suid:0x%" PRIx64 ", code:%s, %s", pInfo->pCur->mr.me.name,
suid, tstrerror(terrno), GET_TASKID(pTaskInfo));
pAPI->metaReaderFn.clearReader(&mr);
pAPI->metaFn.closeTableMetaCursor(pInfo->pCur);
pInfo->pCur = NULL;
blockDataDestroy(p);
T_LONG_JMP(pTaskInfo->env, terrno);
}
if (isTsmaResSTb(mr.me.name)) {
pAPI->metaReaderFn.clearReader(&mr);
continue;
}
// number of columns
pColInfoData = taosArrayGet(p->pDataBlock, 3);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
code = colDataSetVal(pColInfoData, numOfRows, (char*)&mr.me.stbEntry.schemaRow.nCols, false);
QUERY_CHECK_CODE(code, lino, _end);
// super table name
STR_TO_VARSTR(n, mr.me.name);
pColInfoData = taosArrayGet(p->pDataBlock, 4);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
code = colDataSetVal(pColInfoData, numOfRows, n, false);
QUERY_CHECK_CODE(code, lino, _end);
pAPI->metaReaderFn.clearReader(&mr);
// table comment
pColInfoData = taosArrayGet(p->pDataBlock, 8);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
colDataSetNULL(pColInfoData, numOfRows);
// uid
pColInfoData = taosArrayGet(p->pDataBlock, 5);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
code = colDataSetVal(pColInfoData, numOfRows, (char*)&pInfo->pCur->mr.me.uid, false);
QUERY_CHECK_CODE(code, lino, _end);
// ttl
pColInfoData = taosArrayGet(p->pDataBlock, 7);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
colDataSetNULL(pColInfoData, numOfRows);
STR_TO_VARSTR(n, "VIRTUAL_CHILD_TABLE");
} }
pColInfoData = taosArrayGet(p->pDataBlock, 9); pColInfoData = taosArrayGet(p->pDataBlock, 9);

View File

@ -2929,6 +2929,11 @@ void tsortGetValue(STupleHandle* pVHandle, int32_t colIndex, void** pVal) {
} }
} }
void tsortGetColumnInfo(STupleHandle* pVHandle, int32_t colIndex, SColumnInfoData** pColInfo) {
*pColInfo = TARRAY_GET_ELEM(pVHandle->pBlock->pDataBlock, colIndex);
}
size_t tsortGetColNum(STupleHandle* pVHandle) { return blockDataGetNumOfCols(pVHandle->pBlock); }
uint64_t tsortGetGroupId(STupleHandle* pVHandle) { return pVHandle->pBlock->info.id.groupId; } uint64_t tsortGetGroupId(STupleHandle* pVHandle) { return pVHandle->pBlock->info.id.groupId; }
void tsortGetBlockInfo(STupleHandle* pVHandle, SDataBlockInfo* pBlockInfo) { *pBlockInfo = pVHandle->pBlock->info; } void tsortGetBlockInfo(STupleHandle* pVHandle, SDataBlockInfo* pBlockInfo) { *pBlockInfo = pVHandle->pBlock->info; }

View File

@ -0,0 +1,761 @@
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "executorInt.h"
#include "filter.h"
#include "operator.h"
#include "querytask.h"
#include "tdatablock.h"
#include "virtualtablescan.h"
#include "tsort.h"
typedef struct SVirtualTableScanInfo {
STableScanBase base;
SArray* pSortInfo;
SSortHandle* pSortHandle;
int32_t bufPageSize;
uint32_t sortBufSize; // max buffer size for in-memory sort
SSDataBlock* pIntermediateBlock; // to hold the intermediate result
SSDataBlock* pInputBlock;
SHashObj* dataSlotMap;
int32_t tsSlotId;
bool scanAllCols;
SArray* pSortCtxList;
} SVirtualTableScanInfo;
typedef struct SVirtualScanMergeOperatorInfo {
SOptrBasicInfo binfo;
EMergeType type;
SVirtualTableScanInfo virtualScanInfo;
SLimitInfo limitInfo;
bool ignoreGroupId;
uint64_t groupId;
STupleHandle* pSavedTuple;
} SVirtualScanMergeOperatorInfo;
typedef struct SLoadNextCtx {
SOperatorInfo* pOperator;
SOperatorParam* pOperatorGetParam;
int32_t blockId;
STimeWindow window;
SSDataBlock* pIntermediateBlock;
col_id_t tsSlotId;
} SLoadNextCtx;
int32_t virtualScanloadNextDataBlock(void* param, SSDataBlock** ppBlock) {
SOperatorInfo* pOperator = (SOperatorInfo*)param;
int32_t code = TSDB_CODE_SUCCESS;
VTS_ERR_JRET(pOperator->fpSet.getNextFn(pOperator, ppBlock));
VTS_ERR_JRET(blockDataCheck(*ppBlock));
return code;
_return:
qError("failed to load data block from downstream, %s code:%s", __func__, tstrerror(code));
return code;
}
int32_t getTimeWindowOfBlock(SSDataBlock *pBlock, col_id_t tsSlotId, int64_t *startTs, int64_t *endTs) {
int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
int32_t tsIndex = -1;
for (int32_t i = 0; i < taosArrayGetSize(pBlock->pDataBlock); i++) {
if (((SColumnInfoData*)taosArrayGet(pBlock->pDataBlock, i))->info.colId == tsSlotId) {
tsIndex = i;
break;
}
}
if (tsIndex == -1) {
tsIndex = (int32_t)taosArrayGetSize(pBlock->pDataBlock) - 1;
}
SColumnInfoData *pColData = (SColumnInfoData*)taosArrayGet(pBlock->pDataBlock, tsIndex);
QUERY_CHECK_NULL(pColData, code, lino, _return, terrno);
GET_TYPED_DATA(*startTs, int64_t, TSDB_DATA_TYPE_TIMESTAMP, colDataGetNumData(pColData, 0), 0);
GET_TYPED_DATA(*endTs, int64_t, TSDB_DATA_TYPE_TIMESTAMP, colDataGetNumData(pColData, pBlock->info.rows - 1), 0);
return code;
_return:
qError("failed to get time window of block, %s code:%s", __func__, tstrerror(code));
return code;
}
int32_t virtualScanloadNextDataBlockFromParam(void* param, SSDataBlock** ppBlock) {
SLoadNextCtx* pCtx = (SLoadNextCtx*)param;
SOperatorInfo* pOperator = pCtx->pOperator;
SOperatorParam* pOperatorGetParam = pCtx->pOperatorGetParam;
int32_t code = TSDB_CODE_SUCCESS;
SSDataBlock* pRes = NULL;
SExchangeOperatorParam* pParam = (SExchangeOperatorParam*)pOperatorGetParam->value;
pParam->basic.window = pCtx->window;
pOperator->status = OP_NOT_OPENED;
if (pCtx->pIntermediateBlock) {
blockDataDestroy(pCtx->pIntermediateBlock);
pCtx->pIntermediateBlock = NULL;
}
VTS_ERR_JRET(pOperator->fpSet.getNextExtFn(pOperator, pOperatorGetParam, &pRes));
VTS_ERR_JRET(blockDataCheck(pRes));
if ((pRes)) {
qInfo("load from downstream, blockId:%d", pCtx->blockId);
//printDataBlock(pRes, "load from downstream", "task");
(pRes)->info.id.blockId = pCtx->blockId;
getTimeWindowOfBlock(pRes, pCtx->tsSlotId, &pCtx->window.skey, &pCtx->window.ekey);
VTS_ERR_JRET(createOneDataBlock(pRes, true, &pCtx->pIntermediateBlock));
*ppBlock = pCtx->pIntermediateBlock;
} else {
pCtx->window.ekey = INT64_MAX;
*ppBlock = NULL;
}
return code;
_return:
qError("failed to load data block from downstream, %s code:%s", __func__, tstrerror(code));
return code;
}
int32_t makeTSMergeKey(SNodeList** pMergeKeys, col_id_t tsSlotId) {
int32_t code = TSDB_CODE_SUCCESS;
SNodeList *pNodeList = NULL;
SColumnNode *pColumnNode = NULL;
SOrderByExprNode *pOrderByExprNode = NULL;
VTS_ERR_JRET(nodesMakeList(&pNodeList));
VTS_ERR_JRET(nodesMakeNode(QUERY_NODE_COLUMN, (SNode**)&pColumnNode));
pColumnNode->slotId = tsSlotId;
VTS_ERR_JRET(nodesMakeNode(QUERY_NODE_ORDER_BY_EXPR, (SNode**)&pOrderByExprNode));
pOrderByExprNode->pExpr = (SNode*)pColumnNode;
pOrderByExprNode->order = ORDER_ASC;
pOrderByExprNode->nullOrder = NULL_ORDER_FIRST;
VTS_ERR_JRET(nodesListAppend(pNodeList, (SNode*)pOrderByExprNode));
*pMergeKeys = pNodeList;
return code;
_return:
nodesDestroyNode((SNode*)pColumnNode);
nodesDestroyNode((SNode*)pOrderByExprNode);
nodesDestroyList(pNodeList);
return code;
}
void cleanUpVirtualScanInfo(SVirtualTableScanInfo* pVirtualScanInfo) {
if (pVirtualScanInfo->pSortInfo) {
taosArrayDestroy(pVirtualScanInfo->pSortInfo);
pVirtualScanInfo->pSortInfo = NULL;
}
if (pVirtualScanInfo->pSortHandle) {
tsortDestroySortHandle(pVirtualScanInfo->pSortHandle);
pVirtualScanInfo->pSortHandle = NULL;
}
if (pVirtualScanInfo->pSortCtxList) {
for (int32_t i = 0; i < taosArrayGetSize(pVirtualScanInfo->pSortCtxList); i++) {
SLoadNextCtx* pCtx = *(SLoadNextCtx**)taosArrayGet(pVirtualScanInfo->pSortCtxList, i);
blockDataDestroy(pCtx->pIntermediateBlock);
taosMemoryFree(pCtx);
}
taosArrayDestroy(pVirtualScanInfo->pSortCtxList);
}
}
int32_t createSortHandleFromParam(SOperatorInfo* pOperator) {
int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
SVirtualScanMergeOperatorInfo* pInfo = pOperator->info;
SVirtualTableScanInfo* pVirtualScanInfo = &pInfo->virtualScanInfo;
SVTableScanOperatorParam * pParam = (SVTableScanOperatorParam*)pOperator->pOperatorGetParam->value;
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
pVirtualScanInfo->sortBufSize = pVirtualScanInfo->bufPageSize * (taosArrayGetSize((pParam)->pOpParamArray) + 1);
int32_t numOfBufPage = (int32_t)pVirtualScanInfo->sortBufSize / pVirtualScanInfo->bufPageSize;
SNodeList* pMergeKeys = NULL;
SSortSource* ps = NULL;
cleanUpVirtualScanInfo(pVirtualScanInfo);
VTS_ERR_JRET(makeTSMergeKey(&pMergeKeys, pVirtualScanInfo->tsSlotId));
pVirtualScanInfo->pSortInfo = createSortInfo(pMergeKeys);
TSDB_CHECK_NULL(pVirtualScanInfo->pSortInfo, code, lino, _return, terrno);
nodesDestroyList(pMergeKeys);
VTS_ERR_JRET(tsortCreateSortHandle(pVirtualScanInfo->pSortInfo, SORT_MULTISOURCE_MERGE, pVirtualScanInfo->bufPageSize,
numOfBufPage, pVirtualScanInfo->pInputBlock, pTaskInfo->id.str, 0, 0, 0, &pVirtualScanInfo->pSortHandle));
tsortSetForceUsePQSort(pVirtualScanInfo->pSortHandle);
tsortSetFetchRawDataFp(pVirtualScanInfo->pSortHandle, virtualScanloadNextDataBlockFromParam, NULL, NULL);
pOperator->pDownstream[0]->status = OP_NOT_OPENED;
pVirtualScanInfo->pSortCtxList = taosArrayInit(taosArrayGetSize((pParam)->pOpParamArray), POINTER_BYTES);
TSDB_CHECK_NULL(pVirtualScanInfo->pSortCtxList, code, lino, _return, terrno);
for (int32_t i = 0; i < taosArrayGetSize((pParam)->pOpParamArray); i++) {
SOperatorParam* pOpParam = *(SOperatorParam**)taosArrayGet((pParam)->pOpParamArray, i);
SLoadNextCtx* pCtx = NULL;
ps = NULL;
pCtx = taosMemoryMalloc(sizeof(SLoadNextCtx));
QUERY_CHECK_NULL(pCtx, code, lino, _return, terrno);
pCtx->blockId = i;
pCtx->pOperator = pOperator->pDownstream[0];
pCtx->pOperatorGetParam = pOpParam;
pCtx->window = (STimeWindow){.skey = INT64_MAX, .ekey = INT64_MIN};
pCtx->pIntermediateBlock = NULL;
pCtx->tsSlotId = (col_id_t)pVirtualScanInfo->tsSlotId;
ps = taosMemoryCalloc(1, sizeof(SSortSource));
QUERY_CHECK_NULL(ps, code, lino, _return, terrno);
ps->param = pCtx;
ps->onlyRef = true;
VTS_ERR_JRET(tsortAddSource(pVirtualScanInfo->pSortHandle, ps));
QUERY_CHECK_NULL(taosArrayPush(pVirtualScanInfo->pSortCtxList, &pCtx), code, lino, _return, terrno);
}
VTS_ERR_JRET(tsortOpen(pVirtualScanInfo->pSortHandle));
return code;
_return:
if (code != 0){
qError("%s failed at line %d with msg:%s", __func__, lino, tstrerror(code));
}
nodesDestroyList(pMergeKeys);
if (ps != NULL) {
taosMemoryFree(ps);
}
return code;
}
int32_t createSortHandle(SOperatorInfo* pOperator) {
SVirtualScanMergeOperatorInfo * pInfo = pOperator->info;
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
SVirtualTableScanInfo* pVirtualScanInfo = &pInfo->virtualScanInfo;
int32_t numOfBufPage = (int32_t)pVirtualScanInfo->sortBufSize / pVirtualScanInfo->bufPageSize;
SSortSource* ps = NULL;
int32_t code = 0;
int32_t lino = 0;
VTS_ERR_JRET(tsortCreateSortHandle(pVirtualScanInfo->pSortInfo, SORT_MULTISOURCE_MERGE, pVirtualScanInfo->bufPageSize,
numOfBufPage, pVirtualScanInfo->pInputBlock, pTaskInfo->id.str, 0, 0, 0, &pVirtualScanInfo->pSortHandle));
tsortSetForceUsePQSort(pVirtualScanInfo->pSortHandle);
tsortSetFetchRawDataFp(pVirtualScanInfo->pSortHandle, virtualScanloadNextDataBlock, NULL, NULL);
for (int32_t i = 0; i < pOperator->numOfDownstream; ++i) {
SOperatorInfo* pDownstream = pOperator->pDownstream[i];
if (pDownstream->operatorType == QUERY_NODE_PHYSICAL_PLAN_EXCHANGE) {
VTS_ERR_JRET(pDownstream->fpSet._openFn(pDownstream));
} else {
VTS_ERR_JRET(TSDB_CODE_VTABLE_SCAN_INVALID_DOWNSTREAM);
}
ps = taosMemoryCalloc(1, sizeof(SSortSource));
TSDB_CHECK_NULL(ps, code, lino, _return, terrno);
ps->param = pDownstream;
ps->onlyRef = true;
VTS_ERR_JRET(tsortAddSource(pVirtualScanInfo->pSortHandle, ps));
ps = NULL;
}
VTS_ERR_JRET(tsortOpen(pVirtualScanInfo->pSortHandle));
_return:
if (code != 0){
qError("%s failed at line %d with msg:%s", __func__, lino, tstrerror(code));
}
if (ps != NULL) {
taosMemoryFree(ps);
}
return code;
}
int32_t openVirtualTableScanOperatorImpl(SOperatorInfo* pOperator) {
SVirtualScanMergeOperatorInfo * pInfo = pOperator->info;
int32_t code = 0;
int32_t lino = 0;
if (pOperator->numOfDownstream == 0) {
return code;
}
if (pOperator->pOperatorGetParam) {
VTS_ERR_JRET(createSortHandleFromParam(pOperator));
} else {
VTS_ERR_JRET(createSortHandle(pOperator));
}
return code;
_return:
qError("%s failed at line %d with msg:%s", __func__, lino, tstrerror(code));
return code;
}
int32_t openVirtualTableScanOperator(SOperatorInfo* pOperator) {
int32_t code = 0;
if (OPTR_IS_OPENED(pOperator)) {
return TSDB_CODE_SUCCESS;
}
int64_t startTs = taosGetTimestampUs();
code = openVirtualTableScanOperatorImpl(pOperator);
pOperator->cost.openCost = (double)(taosGetTimestampUs() - startTs) / 1000.0;
pOperator->status = OP_RES_TO_RETURN;
VTS_ERR_RET(code);
OPTR_SET_OPENED(pOperator);
return code;
}
static int32_t doGetVtableMergedBlockData(SVirtualScanMergeOperatorInfo* pInfo, SSortHandle* pHandle, int32_t capacity,
SSDataBlock* p) {
int32_t code = 0;
int64_t lastTs = 0;
int64_t rowNums = -1;
blockDataEmpty(p);
while (1) {
STupleHandle* pTupleHandle = NULL;
if (!pInfo->pSavedTuple) {
code = tsortNextTuple(pHandle, &pTupleHandle);
if (pTupleHandle == NULL || (code != 0)) {
break;
}
} else {
pTupleHandle = pInfo->pSavedTuple;
pInfo->pSavedTuple = NULL;
}
SDataBlockInfo info = {0};
tsortGetBlockInfo(pTupleHandle, &info);
int32_t blockId = (int32_t)info.id.blockId;
for (int32_t i = 0; i < (pInfo->virtualScanInfo.scanAllCols ? 1 : tsortGetColNum(pTupleHandle)); i++) {
bool isNull = tsortIsNullVal(pTupleHandle, i);
if (isNull) {
colDataSetNULL(taosArrayGet(p->pDataBlock, i), rowNums);
} else {
char* pData = NULL;
tsortGetValue(pTupleHandle, i, (void**)&pData);
if (pData != NULL) {
if (i == 0) {
if (lastTs != *(int64_t*)pData) {
if (rowNums >= capacity - 1) {
pInfo->pSavedTuple = pTupleHandle;
goto _return;
}
rowNums++;
for (int32_t j = 0; j < taosArrayGetSize(p->pDataBlock); j++) {
colDataSetNULL(taosArrayGet(p->pDataBlock, j), rowNums);
}
if (pInfo->virtualScanInfo.tsSlotId != -1) {
VTS_ERR_RET(colDataSetVal(taosArrayGet(p->pDataBlock, pInfo->virtualScanInfo.tsSlotId), rowNums, pData, false));
}
lastTs = *(int64_t*)pData;
}
continue;
}
int32_t slotKey = blockId << 16 | i;
void *slotId = taosHashGet(pInfo->virtualScanInfo.dataSlotMap, &slotKey, sizeof(slotKey));
if (slotId == NULL) {
qError("failed to get slotId from dataSlotMap, blockId:%d, slotId:%d", blockId, i);
VTS_ERR_RET(TSDB_CODE_VTABLE_SCAN_INTERNAL_ERROR);
}
VTS_ERR_RET(colDataSetVal(taosArrayGet(p->pDataBlock, *(int32_t *)slotId), rowNums, pData, false));
}
}
}
}
_return:
p->info.rows = rowNums + 1;
p->info.dataLoad = 1;
p->info.scanFlag = MAIN_SCAN;
return code;
}
static int32_t doGetVStableMergedBlockData(SVirtualScanMergeOperatorInfo* pInfo, SSortHandle* pHandle, int32_t capacity,
SSDataBlock* p) {
int32_t code = 0;
int64_t lastTs = 0;
int64_t rowNums = -1;
blockDataEmpty(p);
while (1) {
STupleHandle* pTupleHandle = NULL;
if (!pInfo->pSavedTuple) {
code = tsortNextTuple(pHandle, &pTupleHandle);
if (pTupleHandle == NULL || (code != 0)) {
break;
}
} else {
pTupleHandle = pInfo->pSavedTuple;
pInfo->pSavedTuple = NULL;
}
int32_t tsIndex = -1;
for (int32_t i = 0; i < tsortGetColNum(pTupleHandle); i++) {
if (tsortIsNullVal(pTupleHandle, i)) {
continue;
} else {
SColumnInfoData *pColInfo = NULL;
tsortGetColumnInfo(pTupleHandle, i, &pColInfo);
if (pColInfo->info.slotId == pInfo->virtualScanInfo.tsSlotId) {
tsIndex = i;
break;
}
}
}
if (tsIndex == -1) {
tsIndex = (int32_t)tsortGetColNum(pTupleHandle) - 1;
}
char* pData = NULL;
// first, set ts slot's data
// then, set other slots' data
tsortGetValue(pTupleHandle, tsIndex, (void**)&pData);
if (pData != NULL) {
if (lastTs != *(int64_t*)pData) {
if (rowNums >= capacity - 1) {
pInfo->pSavedTuple = pTupleHandle;
goto _return;
}
rowNums++;
for (int32_t j = 0; j < taosArrayGetSize(p->pDataBlock); j++) {
colDataSetNULL(taosArrayGet(p->pDataBlock, j), rowNums);
}
if (pInfo->virtualScanInfo.tsSlotId != -1) {
VTS_ERR_RET(colDataSetVal(taosArrayGet(p->pDataBlock, pInfo->virtualScanInfo.tsSlotId), rowNums, pData, false));
}
lastTs = *(int64_t*)pData;
}
}
if (pInfo->virtualScanInfo.scanAllCols) {
continue;
}
for (int32_t i = 0; i < tsortGetColNum(pTupleHandle); i++) {
if (i == tsIndex || tsortIsNullVal(pTupleHandle, i)) {
continue;
}
SColumnInfoData *pColInfo = NULL;
tsortGetColumnInfo(pTupleHandle, i, &pColInfo);
tsortGetValue(pTupleHandle, i, (void**)&pData);
if (pData != NULL) {
VTS_ERR_RET(colDataSetVal(taosArrayGet(p->pDataBlock, i), rowNums, pData, false));
}
}
}
_return:
p->info.rows = rowNums + 1;
p->info.dataLoad = 1;
p->info.scanFlag = MAIN_SCAN;
return code;
}
int32_t doVirtualTableMerge(SOperatorInfo* pOperator, SSDataBlock** pResBlock) {
int32_t code = 0;
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
SVirtualScanMergeOperatorInfo* pInfo = pOperator->info;
SVirtualTableScanInfo* pVirtualScanInfo = &pInfo->virtualScanInfo;
SSortHandle* pHandle = pVirtualScanInfo->pSortHandle;
SSDataBlock* pDataBlock = pInfo->binfo.pRes;
int32_t capacity = pOperator->resultInfo.capacity;
qDebug("start to merge final sorted rows, %s", GET_TASKID(pTaskInfo));
blockDataCleanup(pDataBlock);
if (pHandle == NULL) {
return TSDB_CODE_SUCCESS;
}
if (pVirtualScanInfo->pIntermediateBlock == NULL) {
VTS_ERR_RET(tsortGetSortedDataBlock(pHandle, &pVirtualScanInfo->pIntermediateBlock));
if (pVirtualScanInfo->pIntermediateBlock == NULL) {
return TSDB_CODE_SUCCESS;
}
VTS_ERR_RET(blockDataEnsureCapacity(pVirtualScanInfo->pIntermediateBlock, capacity));
} else {
blockDataCleanup(pVirtualScanInfo->pIntermediateBlock);
}
SSDataBlock* p = pVirtualScanInfo->pIntermediateBlock;
if (pOperator->pOperatorGetParam) {
VTS_ERR_RET(doGetVStableMergedBlockData(pInfo, pHandle, capacity, p));
} else {
VTS_ERR_RET(doGetVtableMergedBlockData(pInfo, pHandle, capacity, p));
}
VTS_ERR_RET(copyDataBlock(pDataBlock, p));
qDebug("%s get sorted block, groupId:0x%" PRIx64 " rows:%" PRId64 , GET_TASKID(pTaskInfo), pDataBlock->info.id.groupId,
pDataBlock->info.rows);
*pResBlock = (pDataBlock->info.rows > 0) ? pDataBlock : NULL;
return code;
}
static int32_t doSetTagColumnData(STableScanBase * pTableScanInfo, SSDataBlock* pBlock, SExecTaskInfo* pTaskInfo,
int32_t rows) {
int32_t code = 0;
SExprSupp* pSup = &pTableScanInfo->pseudoSup;
if (pSup->numOfExprs > 0) {
code = addTagPseudoColumnData(&pTableScanInfo->readHandle, pSup->pExprInfo, pSup->numOfExprs, pBlock, rows,
pTaskInfo, &pTableScanInfo->metaCache);
// ignore the table not exists error, since this table may have been dropped during the scan procedure.
if (code == TSDB_CODE_PAR_TABLE_NOT_EXIST) {
if (pTaskInfo->streamInfo.pState) blockDataCleanup(pBlock);
code = 0;
}
}
return code;
}
int32_t virtualTableGetNext(SOperatorInfo* pOperator, SSDataBlock** pResBlock) {
int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
SVirtualScanMergeOperatorInfo* pInfo = pOperator->info;
SVirtualTableScanInfo* pVirtualScanInfo = &pInfo->virtualScanInfo;
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
if (pOperator->status == OP_EXEC_DONE && !pOperator->pOperatorGetParam) {
pResBlock = NULL;
return code;
}
VTS_ERR_JRET(pOperator->fpSet._openFn(pOperator));
while(1) {
VTS_ERR_JRET(doVirtualTableMerge(pOperator, pResBlock));
if (*pResBlock == NULL) {
setOperatorCompleted(pOperator);
break;
}
if (pOperator->pOperatorGetParam) {
uint64_t uid = ((SVTableScanOperatorParam*)pOperator->pOperatorGetParam->value)->uid;
STableKeyInfo* tbInfo = tableListGetInfo(pVirtualScanInfo->base.pTableListInfo, tableListFind(pVirtualScanInfo->base.pTableListInfo, uid, 0));
QUERY_CHECK_NULL(tbInfo, code, lino, _return, terrno);
(*pResBlock)->info.id.uid = tbInfo->uid;
} else {
STableKeyInfo* tbInfo = tableListGetInfo(pVirtualScanInfo->base.pTableListInfo, 0);
QUERY_CHECK_NULL(tbInfo, code, lino, _return, terrno);
(*pResBlock)->info.id.uid = tbInfo->uid;
}
VTS_ERR_JRET(doSetTagColumnData(&pVirtualScanInfo->base, (*pResBlock), pTaskInfo, (*pResBlock)->info.rows));
VTS_ERR_JRET(doFilter(*pResBlock, pOperator->exprSupp.pFilterInfo, NULL));
if ((*pResBlock)->info.rows > 0) {
break;
}
}
return code;
_return:
if (code != TSDB_CODE_SUCCESS) {
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
pTaskInfo->code = code;
T_LONG_JMP(pTaskInfo->env, code);
}
return code;
}
static void destroyTableScanBase(STableScanBase* pBase, TsdReader* pAPI) {
cleanupQueryTableDataCond(&pBase->cond);
if (pAPI->tsdReaderClose) {
pAPI->tsdReaderClose(pBase->dataReader);
}
pBase->dataReader = NULL;
if (pBase->matchInfo.pList != NULL) {
taosArrayDestroy(pBase->matchInfo.pList);
}
tableListDestroy(pBase->pTableListInfo);
taosLRUCacheCleanup(pBase->metaCache.pTableMetaEntryCache);
cleanupExprSupp(&pBase->pseudoSup);
}
void destroyVirtualTableScanOperatorInfo(void* param) {
if (!param) {
return;
}
SVirtualScanMergeOperatorInfo* pOperatorInfo = (SVirtualScanMergeOperatorInfo*)param;
SVirtualTableScanInfo* pInfo = &pOperatorInfo->virtualScanInfo;
blockDataDestroy(pOperatorInfo->binfo.pRes);
pOperatorInfo->binfo.pRes = NULL;
tsortDestroySortHandle(pInfo->pSortHandle);
pInfo->pSortHandle = NULL;
taosArrayDestroy(pInfo->pSortInfo);
pInfo->pSortHandle = NULL;
blockDataDestroy(pInfo->pIntermediateBlock);
pInfo->pIntermediateBlock = NULL;
blockDataDestroy(pInfo->pInputBlock);
pInfo->pInputBlock = NULL;
destroyTableScanBase(&pInfo->base, &pInfo->base.readerAPI);
taosHashCleanup(pInfo->dataSlotMap);
if (pInfo->pSortCtxList) {
for (int32_t i = 0; i < taosArrayGetSize(pInfo->pSortCtxList); i++) {
SLoadNextCtx* pCtx = *(SLoadNextCtx**)taosArrayGet(pInfo->pSortCtxList, i);
blockDataDestroy(pCtx->pIntermediateBlock);
taosMemoryFree(pCtx);
}
taosArrayDestroy(pInfo->pSortCtxList);
}
taosMemoryFreeClear(param);
}
int32_t extractColMap(SNodeList* pNodeList, SHashObj** pSlotMap, int32_t *tsSlotId) {
size_t numOfCols = LIST_LENGTH(pNodeList);
int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
if (numOfCols == 0) {
return code;
}
*tsSlotId = -1;
*pSlotMap = taosHashInit(numOfCols, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_NO_LOCK);
TSDB_CHECK_NULL(*pSlotMap, code, lino, _return, terrno);
for (int32_t i = 0; i < numOfCols; ++i) {
SColumnNode* pColNode = (SColumnNode*)nodesListGetNode(pNodeList, i);
TSDB_CHECK_NULL(pColNode, code, lino, _return, terrno);
if (pColNode->isPrimTs) {
*tsSlotId = i;
} else if (pColNode->hasRef) {
int32_t slotKey = pColNode->dataBlockId << 16 | pColNode->slotId;
VTS_ERR_JRET(taosHashPut(*pSlotMap, &slotKey, sizeof(slotKey), &i, sizeof(i)));
}
}
return code;
_return:
taosHashCleanup(*pSlotMap);
*pSlotMap = NULL;
if (code != TSDB_CODE_SUCCESS) {
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
}
return code;
}
int32_t createVirtualTableMergeOperatorInfo(SOperatorInfo** pDownstream, SReadHandle* readHandle,
STableListInfo* pTableListInfo, int32_t numOfDownstream,
SVirtualScanPhysiNode* pVirtualScanPhyNode, SExecTaskInfo* pTaskInfo,
SOperatorInfo** pOptrInfo) {
SPhysiNode* pPhyNode = (SPhysiNode*)pVirtualScanPhyNode;
int32_t lino = 0;
int32_t code = TSDB_CODE_SUCCESS;
SVirtualScanMergeOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SVirtualScanMergeOperatorInfo));
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
SDataBlockDescNode* pDescNode = pPhyNode->pOutputDataBlockDesc;
SNodeList* pMergeKeys = NULL;
QUERY_CHECK_NULL(pInfo, code, lino, _return, terrno);
QUERY_CHECK_NULL(pOperator, code, lino, _return, terrno);
pInfo->binfo.inputTsOrder = pVirtualScanPhyNode->scan.node.inputTsOrder;
pInfo->binfo.outputTsOrder = pVirtualScanPhyNode->scan.node.outputTsOrder;
SVirtualTableScanInfo* pVirtualScanInfo = &pInfo->virtualScanInfo;
pInfo->binfo.pRes = createDataBlockFromDescNode(pDescNode);
TSDB_CHECK_NULL(pInfo->binfo.pRes, code, lino, _return, terrno);
SSDataBlock* pInputBlock = createDataBlockFromDescNode(pPhyNode->pOutputDataBlockDesc);
TSDB_CHECK_NULL(pInputBlock, code, lino, _return, terrno);
pVirtualScanInfo->pInputBlock = pInputBlock;
if (pVirtualScanPhyNode->scan.pScanPseudoCols != NULL) {
SExprSupp* pSup = &pVirtualScanInfo->base.pseudoSup;
pSup->pExprInfo = NULL;
VTS_ERR_JRET(createExprInfo(pVirtualScanPhyNode->scan.pScanPseudoCols, NULL, &pSup->pExprInfo, &pSup->numOfExprs));
pSup->pCtx = createSqlFunctionCtx(pSup->pExprInfo, pSup->numOfExprs, &pSup->rowEntryInfoOffset,
&pTaskInfo->storageAPI.functionStore);
TSDB_CHECK_NULL(pSup->pCtx, code, lino, _return, terrno);
}
initResultSizeInfo(&pOperator->resultInfo, 1024);
TSDB_CHECK_CODE(blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity), lino, _return);
size_t numOfCols = taosArrayGetSize(pInfo->binfo.pRes->pDataBlock);
int32_t rowSize = pInfo->binfo.pRes->info.rowSize;
if (!pVirtualScanPhyNode->scan.node.dynamicOp) {
VTS_ERR_JRET(makeTSMergeKey(&pMergeKeys, 0));
pVirtualScanInfo->pSortInfo = createSortInfo(pMergeKeys);
TSDB_CHECK_NULL(pVirtualScanInfo->pSortInfo, code, lino, _return, terrno);
}
pVirtualScanInfo->bufPageSize = getProperSortPageSize(rowSize, numOfCols);
pVirtualScanInfo->sortBufSize =
pVirtualScanInfo->bufPageSize * (numOfDownstream + 1); // one additional is reserved for merged result.
VTS_ERR_JRET(extractColMap(pVirtualScanPhyNode->pTargets, &pVirtualScanInfo->dataSlotMap, &pVirtualScanInfo->tsSlotId));
pVirtualScanInfo->scanAllCols = pVirtualScanPhyNode->scanAllCols;
VTS_ERR_JRET(filterInitFromNode((SNode*)pVirtualScanPhyNode->scan.node.pConditions, &pOperator->exprSupp.pFilterInfo, 0));
pVirtualScanInfo->base.metaCache.pTableMetaEntryCache = taosLRUCacheInit(1024 * 128, -1, .5);
QUERY_CHECK_NULL(pVirtualScanInfo->base.metaCache.pTableMetaEntryCache, code, lino, _return, terrno);
pVirtualScanInfo->base.readHandle = *readHandle;
pVirtualScanInfo->base.pTableListInfo = pTableListInfo;
setOperatorInfo(pOperator, "VirtualTableScanOperator", QUERY_NODE_PHYSICAL_PLAN_VIRTUAL_TABLE_SCAN, false,
OP_NOT_OPENED, pInfo, pTaskInfo);
pOperator->fpSet =
createOperatorFpSet(openVirtualTableScanOperator, virtualTableGetNext, NULL, destroyVirtualTableScanOperatorInfo,
optrDefaultBufFn, NULL, optrDefaultGetNextExtFn, NULL);
if (NULL != pDownstream) {
VTS_ERR_JRET(appendDownstream(pOperator, pDownstream, numOfDownstream));
}
nodesDestroyList(pMergeKeys);
*pOptrInfo = pOperator;
return TSDB_CODE_SUCCESS;
_return:
if (code != TSDB_CODE_SUCCESS) {
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
}
if (pInfo != NULL) {
destroyVirtualTableScanOperatorInfo(pInfo);
}
nodesDestroyList(pMergeKeys);
pTaskInfo->code = code;
destroyOperatorAndDownstreams(pOperator, pDownstream, numOfDownstream);
return code;
}

View File

@ -3146,7 +3146,7 @@ void qptExecPlan(SReadHandle* pReadHandle, SNode* pNode, SExecTaskInfo* pTaskInf
case QUERY_NODE_PHYSICAL_PLAN_QUERY_INSERT: case QUERY_NODE_PHYSICAL_PLAN_QUERY_INSERT:
case QUERY_NODE_PHYSICAL_PLAN_DELETE: { case QUERY_NODE_PHYSICAL_PLAN_DELETE: {
DataSinkHandle handle = NULL; DataSinkHandle handle = NULL;
qptCtx.result.code = dsCreateDataSinker(NULL, (SDataSinkNode**)&pNode, &handle, NULL, NULL); qptCtx.result.code = dsCreateDataSinker(NULL, (SDataSinkNode**)&pNode, &handle, NULL, NULL, false);
dsDestroyDataSinker(handle); dsDestroyDataSinker(handle);
break; break;
} }
@ -3176,7 +3176,7 @@ void qptExecPlan(SReadHandle* pReadHandle, SNode* pNode, SExecTaskInfo* pTaskInf
qptCtx.result.code = createGroupCacheOperatorInfo(NULL, 0, (SGroupCachePhysiNode*)pNode, pTaskInfo, ppOperaotr); qptCtx.result.code = createGroupCacheOperatorInfo(NULL, 0, (SGroupCachePhysiNode*)pNode, pTaskInfo, ppOperaotr);
break; break;
case QUERY_NODE_PHYSICAL_PLAN_DYN_QUERY_CTRL: case QUERY_NODE_PHYSICAL_PLAN_DYN_QUERY_CTRL:
qptCtx.result.code = createDynQueryCtrlOperatorInfo(NULL, 0, (SDynQueryCtrlPhysiNode*)pNode, pTaskInfo, ppOperaotr); qptCtx.result.code = createDynQueryCtrlOperatorInfo(NULL, 0, (SDynQueryCtrlPhysiNode*)pNode, pTaskInfo, pReadHandle, ppOperaotr);
break; break;
case QUERY_NODE_PHYSICAL_PLAN_MERGE_COUNT: case QUERY_NODE_PHYSICAL_PLAN_MERGE_COUNT:
qptCtx.result.code = createCountwindowOperatorInfo(NULL, (SPhysiNode*)pNode, pTaskInfo, ppOperaotr); qptCtx.result.code = createCountwindowOperatorInfo(NULL, (SPhysiNode*)pNode, pTaskInfo, ppOperaotr);

View File

@ -276,8 +276,6 @@ static SDataType* getSDataTypeFromNode(SNode* pNode) {
if (pNode == NULL) return NULL; if (pNode == NULL) return NULL;
if (nodesIsExprNode(pNode)) { if (nodesIsExprNode(pNode)) {
return &((SExprNode*)pNode)->resType; return &((SExprNode*)pNode)->resType;
} else if (QUERY_NODE_COLUMN_REF == pNode->type) {
return &((SColumnRefNode*)pNode)->resType;
} else { } else {
return NULL; return NULL;
} }

View File

@ -254,6 +254,13 @@ bool fmIsLastRowFunc(int32_t funcId) {
return FUNCTION_TYPE_LAST_ROW == funcMgtBuiltins[funcId].type; return FUNCTION_TYPE_LAST_ROW == funcMgtBuiltins[funcId].type;
} }
bool fmIsLastFunc(int32_t funcId) {
if (funcId < 0 || funcId >= funcMgtBuiltinsNum) {
return false;
}
return FUNCTION_TYPE_LAST == funcMgtBuiltins[funcId].type;
}
bool fmIsNotNullOutputFunc(int32_t funcId) { bool fmIsNotNullOutputFunc(int32_t funcId) {
if (funcId < 0 || funcId >= funcMgtBuiltinsNum) { if (funcId < 0 || funcId >= funcMgtBuiltinsNum) {
return false; return false;

View File

@ -133,6 +133,11 @@ static int32_t columnNodeCopy(const SColumnNode* pSrc, SColumnNode* pDst) {
COPY_SCALAR_FIELD(numOfPKs); COPY_SCALAR_FIELD(numOfPKs);
COPY_SCALAR_FIELD(projRefIdx); COPY_SCALAR_FIELD(projRefIdx);
COPY_SCALAR_FIELD(resIdx); COPY_SCALAR_FIELD(resIdx);
COPY_SCALAR_FIELD(hasDep);
COPY_SCALAR_FIELD(hasRef);
COPY_CHAR_ARRAY_FIELD(refDbName);
COPY_CHAR_ARRAY_FIELD(refTableName);
COPY_CHAR_ARRAY_FIELD(refColName);
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
@ -467,6 +472,13 @@ static int32_t windowOffsetCopy(const SWindowOffsetNode* pSrc, SWindowOffsetNode
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
static int32_t virtualTableNodeCopy(const SVirtualTableNode * pSrc, SVirtualTableNode* pDst) {
COPY_BASE_OBJECT_FIELD(table, tableNodeCopy);
CLONE_OBJECT_FIELD(pMeta, tableMetaClone);
CLONE_OBJECT_FIELD(pVgroupList, vgroupsInfoClone);
CLONE_NODE_LIST_FIELD(refTables);
return TSDB_CODE_SUCCESS;
}
static int32_t logicNodeCopy(const SLogicNode* pSrc, SLogicNode* pDst) { static int32_t logicNodeCopy(const SLogicNode* pSrc, SLogicNode* pDst) {
CLONE_NODE_LIST_FIELD(pTargets); CLONE_NODE_LIST_FIELD(pTargets);
@ -530,6 +542,21 @@ static int32_t logicScanCopy(const SScanLogicNode* pSrc, SScanLogicNode* pDst) {
COPY_SCALAR_FIELD(smallDataTsSort); COPY_SCALAR_FIELD(smallDataTsSort);
COPY_SCALAR_FIELD(needSplit); COPY_SCALAR_FIELD(needSplit);
COPY_SCALAR_FIELD(noPseudoRefAfterGrp); COPY_SCALAR_FIELD(noPseudoRefAfterGrp);
COPY_SCALAR_FIELD(virtualStableScan);
return TSDB_CODE_SUCCESS;
}
static int32_t logicVirtualScanCopy(const SVirtualScanLogicNode * pSrc, SVirtualScanLogicNode* pDst) {
COPY_BASE_OBJECT_FIELD(node, logicNodeCopy);
COPY_SCALAR_FIELD(scanAllCols);
CLONE_NODE_LIST_FIELD(pScanCols);
CLONE_NODE_LIST_FIELD(pScanPseudoCols);
COPY_SCALAR_FIELD(tableType);
COPY_SCALAR_FIELD(tableId);
COPY_SCALAR_FIELD(stableId);
CLONE_OBJECT_FIELD(pVgroupList, vgroupsInfoClone);
COPY_SCALAR_FIELD(scanType);
COPY_OBJECT_FIELD(tableName, sizeof(SName));
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
@ -744,6 +771,9 @@ static int32_t logicDynQueryCtrlCopy(const SDynQueryCtrlLogicNode* pSrc, SDynQue
CLONE_NODE_LIST_FIELD(stbJoin.pVgList); CLONE_NODE_LIST_FIELD(stbJoin.pVgList);
CLONE_NODE_LIST_FIELD(stbJoin.pUidList); CLONE_NODE_LIST_FIELD(stbJoin.pUidList);
COPY_OBJECT_FIELD(stbJoin.srcScan, sizeof(pDst->stbJoin.srcScan)); COPY_OBJECT_FIELD(stbJoin.srcScan, sizeof(pDst->stbJoin.srcScan));
COPY_SCALAR_FIELD(vtbScan.scanAllCols);
COPY_SCALAR_FIELD(vtbScan.suid);
CLONE_OBJECT_FIELD(vtbScan.pVgroupList, vgroupsInfoClone);
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
@ -753,6 +783,7 @@ static int32_t logicSubplanCopy(const SLogicSubplan* pSrc, SLogicSubplan* pDst)
COPY_SCALAR_FIELD(subplanType); COPY_SCALAR_FIELD(subplanType);
COPY_SCALAR_FIELD(level); COPY_SCALAR_FIELD(level);
COPY_SCALAR_FIELD(splitFlag); COPY_SCALAR_FIELD(splitFlag);
COPY_SCALAR_FIELD(processOneBlock);
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
@ -779,6 +810,15 @@ static int32_t physiScanCopy(const SScanPhysiNode* pSrc, SScanPhysiNode* pDst) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
static int32_t physiVirtualTableScanCopy(const SVirtualScanPhysiNode* pSrc, SVirtualScanPhysiNode* pDst) {
COPY_BASE_OBJECT_FIELD(scan, physiScanCopy);
CLONE_NODE_LIST_FIELD(pGroupTags);
COPY_SCALAR_FIELD(groupSort);
COPY_SCALAR_FIELD(scanAllCols);
CLONE_NODE_LIST_FIELD(pTargets);
return TSDB_CODE_SUCCESS;
}
static int32_t physiTagScanCopy(const STagScanPhysiNode* pSrc, STagScanPhysiNode* pDst) { static int32_t physiTagScanCopy(const STagScanPhysiNode* pSrc, STagScanPhysiNode* pDst) {
COPY_BASE_OBJECT_FIELD(scan, physiScanCopy); COPY_BASE_OBJECT_FIELD(scan, physiScanCopy);
COPY_SCALAR_FIELD(onlyMetaCtbIdx); COPY_SCALAR_FIELD(onlyMetaCtbIdx);
@ -1067,6 +1107,9 @@ int32_t nodesCloneNode(const SNode* pNode, SNode** ppNode) {
case QUERY_NODE_WINDOW_OFFSET: case QUERY_NODE_WINDOW_OFFSET:
code = windowOffsetCopy((const SWindowOffsetNode*)pNode, (SWindowOffsetNode*)pDst); code = windowOffsetCopy((const SWindowOffsetNode*)pNode, (SWindowOffsetNode*)pDst);
break; break;
case QUERY_NODE_VIRTUAL_TABLE:
code = virtualTableNodeCopy((const SVirtualTableNode*)pNode, (SVirtualTableNode*)pDst);
break;
case QUERY_NODE_SET_OPERATOR: case QUERY_NODE_SET_OPERATOR:
code = setOperatorCopy((const SSetOperator*)pNode, (SSetOperator*)pDst); code = setOperatorCopy((const SSetOperator*)pNode, (SSetOperator*)pDst);
break; break;
@ -1121,6 +1164,9 @@ int32_t nodesCloneNode(const SNode* pNode, SNode** ppNode) {
case QUERY_NODE_LOGIC_PLAN_DYN_QUERY_CTRL: case QUERY_NODE_LOGIC_PLAN_DYN_QUERY_CTRL:
code = logicDynQueryCtrlCopy((const SDynQueryCtrlLogicNode*)pNode, (SDynQueryCtrlLogicNode*)pDst); code = logicDynQueryCtrlCopy((const SDynQueryCtrlLogicNode*)pNode, (SDynQueryCtrlLogicNode*)pDst);
break; break;
case QUERY_NODE_LOGIC_PLAN_VIRTUAL_TABLE_SCAN:
code = logicVirtualScanCopy((const SVirtualScanLogicNode *)pNode, (SVirtualScanLogicNode*)pDst);
break;
case QUERY_NODE_LOGIC_SUBPLAN: case QUERY_NODE_LOGIC_SUBPLAN:
code = logicSubplanCopy((const SLogicSubplan*)pNode, (SLogicSubplan*)pDst); code = logicSubplanCopy((const SLogicSubplan*)pNode, (SLogicSubplan*)pDst);
break; break;
@ -1156,6 +1202,9 @@ int32_t nodesCloneNode(const SNode* pNode, SNode** ppNode) {
case QUERY_NODE_PHYSICAL_PLAN_STREAM_PARTITION: case QUERY_NODE_PHYSICAL_PLAN_STREAM_PARTITION:
code = physiPartitionCopy((const SPartitionPhysiNode*)pNode, (SPartitionPhysiNode*)pDst); code = physiPartitionCopy((const SPartitionPhysiNode*)pNode, (SPartitionPhysiNode*)pDst);
break; break;
case QUERY_NODE_PHYSICAL_PLAN_VIRTUAL_TABLE_SCAN:
code = physiVirtualTableScanCopy((const SVirtualScanPhysiNode*)pNode, (SVirtualScanPhysiNode*)pDst);
break;
case QUERY_NODE_PHYSICAL_PLAN_PROJECT: case QUERY_NODE_PHYSICAL_PLAN_PROJECT:
code = physiProjectCopy((const SProjectPhysiNode*)pNode, (SProjectPhysiNode*)pDst); code = physiProjectCopy((const SProjectPhysiNode*)pNode, (SProjectPhysiNode*)pDst);
break; break;

View File

@ -41,6 +41,8 @@ const char* nodesNodeName(ENodeType type) {
return "Function"; return "Function";
case QUERY_NODE_REAL_TABLE: case QUERY_NODE_REAL_TABLE:
return "RealTable"; return "RealTable";
case QUERY_NODE_VIRTUAL_TABLE:
return "VirtualTable";
case QUERY_NODE_TEMP_TABLE: case QUERY_NODE_TEMP_TABLE:
return "TempTable"; return "TempTable";
case QUERY_NODE_JOIN_TABLE: case QUERY_NODE_JOIN_TABLE:
@ -87,6 +89,8 @@ const char* nodesNodeName(ENodeType type) {
return "StreamOptions"; return "StreamOptions";
case QUERY_NODE_LEFT_VALUE: case QUERY_NODE_LEFT_VALUE:
return "LeftValue"; return "LeftValue";
case QUERY_NODE_COLUMN_REF:
return "ColumnReference";
case QUERY_NODE_WHEN_THEN: case QUERY_NODE_WHEN_THEN:
return "WhenThen"; return "WhenThen";
case QUERY_NODE_CASE_WHEN: case QUERY_NODE_CASE_WHEN:
@ -123,6 +127,10 @@ const char* nodesNodeName(ENodeType type) {
return "CreateTableStmt"; return "CreateTableStmt";
case QUERY_NODE_CREATE_SUBTABLE_CLAUSE: case QUERY_NODE_CREATE_SUBTABLE_CLAUSE:
return "CreateSubtableClause"; return "CreateSubtableClause";
case QUERY_NODE_CREATE_VIRTUAL_TABLE_STMT:
return "CreateVirtualtableStmt";
case QUERY_NODE_CREATE_VIRTUAL_SUBTABLE_STMT:
return "CreateVirtualsubtableStmt";
case QUERY_NODE_CREATE_MULTI_TABLES_STMT: case QUERY_NODE_CREATE_MULTI_TABLES_STMT:
return "CreateMultiTableStmt"; return "CreateMultiTableStmt";
case QUERY_NODE_DROP_TABLE_CLAUSE: case QUERY_NODE_DROP_TABLE_CLAUSE:
@ -131,10 +139,14 @@ const char* nodesNodeName(ENodeType type) {
return "DropTableStmt"; return "DropTableStmt";
case QUERY_NODE_DROP_SUPER_TABLE_STMT: case QUERY_NODE_DROP_SUPER_TABLE_STMT:
return "DropSuperTableStmt"; return "DropSuperTableStmt";
case QUERY_NODE_DROP_VIRTUAL_TABLE_STMT:
return "DropVirtualTableStmt";
case QUERY_NODE_ALTER_TABLE_STMT: case QUERY_NODE_ALTER_TABLE_STMT:
return "AlterTableStmt"; return "AlterTableStmt";
case QUERY_NODE_ALTER_SUPER_TABLE_STMT: case QUERY_NODE_ALTER_SUPER_TABLE_STMT:
return "AlterSuperTableStmt"; return "AlterSuperTableStmt";
case QUERY_NODE_ALTER_VIRTUAL_TABLE_STMT:
return "AlterVirtualTableStmt";
case QUERY_NODE_CREATE_USER_STMT: case QUERY_NODE_CREATE_USER_STMT:
return "CreateUserStmt"; return "CreateUserStmt";
case QUERY_NODE_ALTER_USER_STMT: case QUERY_NODE_ALTER_USER_STMT:
@ -202,7 +214,6 @@ const char* nodesNodeName(ENodeType type) {
case QUERY_NODE_ASSIGN_LEADER_STMT: case QUERY_NODE_ASSIGN_LEADER_STMT:
return "AssignLeaderStmt"; return "AssignLeaderStmt";
case QUERY_NODE_BALANCE_VGROUP_LEADER_STMT: case QUERY_NODE_BALANCE_VGROUP_LEADER_STMT:
return "BalanceVgroupLeaderStmt";
case QUERY_NODE_BALANCE_VGROUP_LEADER_DATABASE_STMT: case QUERY_NODE_BALANCE_VGROUP_LEADER_DATABASE_STMT:
return "BalanceVgroupLeaderStmt"; return "BalanceVgroupLeaderStmt";
case QUERY_NODE_MERGE_VGROUP_STMT: case QUERY_NODE_MERGE_VGROUP_STMT:
@ -253,6 +264,8 @@ const char* nodesNodeName(ENodeType type) {
return "ShowStreamsStmt"; return "ShowStreamsStmt";
case QUERY_NODE_SHOW_TABLES_STMT: case QUERY_NODE_SHOW_TABLES_STMT:
return "ShowTablesStmt"; return "ShowTablesStmt";
case QUERY_NODE_SHOW_VTABLES_STMT:
return "ShowVtablesStmt";
case QUERY_NODE_SHOW_TAGS_STMT: case QUERY_NODE_SHOW_TAGS_STMT:
return "ShowTagsStmt"; return "ShowTagsStmt";
case QUERY_NODE_SHOW_USERS_STMT: case QUERY_NODE_SHOW_USERS_STMT:
@ -284,6 +297,8 @@ const char* nodesNodeName(ENodeType type) {
return "ShowCreateDatabasesStmt"; return "ShowCreateDatabasesStmt";
case QUERY_NODE_SHOW_CREATE_TABLE_STMT: case QUERY_NODE_SHOW_CREATE_TABLE_STMT:
return "ShowCreateTablesStmt"; return "ShowCreateTablesStmt";
case QUERY_NODE_SHOW_CREATE_VTABLE_STMT:
return "ShowCreateVtablesstmt";
case QUERY_NODE_SHOW_CREATE_STABLE_STMT: case QUERY_NODE_SHOW_CREATE_STABLE_STMT:
return "ShowCreateStablesStmt"; return "ShowCreateStablesStmt";
case QUERY_NODE_SHOW_CREATE_VIEW_STMT: case QUERY_NODE_SHOW_CREATE_VIEW_STMT:
@ -358,6 +373,8 @@ const char* nodesNodeName(ENodeType type) {
return "LogicGroupCache"; return "LogicGroupCache";
case QUERY_NODE_LOGIC_PLAN_DYN_QUERY_CTRL: case QUERY_NODE_LOGIC_PLAN_DYN_QUERY_CTRL:
return "LogicDynamicQueryCtrl"; return "LogicDynamicQueryCtrl";
case QUERY_NODE_LOGIC_PLAN_VIRTUAL_TABLE_SCAN:
return "LogicVirtualTableScan";
case QUERY_NODE_LOGIC_SUBPLAN: case QUERY_NODE_LOGIC_SUBPLAN:
return "LogicSubplan"; return "LogicSubplan";
case QUERY_NODE_LOGIC_PLAN: case QUERY_NODE_LOGIC_PLAN:
@ -465,6 +482,8 @@ const char* nodesNodeName(ENodeType type) {
return "PhysiGroupCache"; return "PhysiGroupCache";
case QUERY_NODE_PHYSICAL_PLAN_DYN_QUERY_CTRL: case QUERY_NODE_PHYSICAL_PLAN_DYN_QUERY_CTRL:
return "PhysiDynamicQueryCtrl"; return "PhysiDynamicQueryCtrl";
case QUERY_NODE_PHYSICAL_PLAN_VIRTUAL_TABLE_SCAN:
return "PhysiVirtualTableScan";
case QUERY_NODE_PHYSICAL_SUBPLAN: case QUERY_NODE_PHYSICAL_SUBPLAN:
return "PhysiSubplan"; return "PhysiSubplan";
case QUERY_NODE_PHYSICAL_PLAN: case QUERY_NODE_PHYSICAL_PLAN:
@ -1867,6 +1886,72 @@ static int32_t jsonToLogicJoinNode(const SJson* pJson, void* pObj) {
return code; return code;
} }
static const char* jkVirtualTableScanLogicPlanScanCols = "ScanCols";
static const char* jkVirtualTableScanLogicPlanScanPseudoCols = "ScanPseudoCols";
static const char* jkVirtualTableScanLogicPlanTableType = "TableType";
static const char* jkVirtualTableScanLogicPlanTableId = "TableId";
static const char* jkVirtualTableScanLogicPlanStableId = "StableId";
static const char* jkVirtualTableScanLogicPlanScanType = "ScanType";
static const char* jkVirtualTableScanLogicPlanscanAllCols = "scanAllCols";
static int32_t logicVirtualTableScanNodeToJson(const void* pObj, SJson* pJson) {
const SVirtualScanLogicNode* pNode = (const SVirtualScanLogicNode*)pObj;
int32_t code = logicPlanNodeToJson(pObj, pJson);
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddBoolToObject(pJson, jkVirtualTableScanLogicPlanscanAllCols, pNode->scanAllCols);
}
if (TSDB_CODE_SUCCESS == code) {
code = nodeListToJson(pJson, jkVirtualTableScanLogicPlanScanCols, pNode->pScanCols);
}
if (TSDB_CODE_SUCCESS == code) {
code = nodeListToJson(pJson, jkVirtualTableScanLogicPlanScanPseudoCols, pNode->pScanPseudoCols);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddIntegerToObject(pJson, jkVirtualTableScanLogicPlanTableType, pNode->tableType);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddIntegerToObject(pJson, jkVirtualTableScanLogicPlanTableId, pNode->tableId);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddIntegerToObject(pJson, jkVirtualTableScanLogicPlanStableId, pNode->stableId);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddIntegerToObject(pJson, jkVirtualTableScanLogicPlanScanType, pNode->scanType);
}
return code;
}
static int32_t jsonToLogicVirtualTableScanNode(const SJson* pJson, void* pObj) {
SVirtualScanLogicNode* pNode = (SVirtualScanLogicNode *)pObj;
int32_t objSize = 0;
int32_t code = jsonToLogicPlanNode(pJson, pObj);
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetBoolValue(pJson, jkVirtualTableScanLogicPlanscanAllCols, &pNode->scanAllCols);
}
if (TSDB_CODE_SUCCESS == code) {
code = jsonToNodeList(pJson, jkVirtualTableScanLogicPlanScanCols, &pNode->pScanCols);
}
if (TSDB_CODE_SUCCESS == code) {
code = jsonToNodeList(pJson, jkVirtualTableScanLogicPlanScanPseudoCols, &pNode->pScanPseudoCols);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetTinyIntValue(pJson, jkVirtualTableScanLogicPlanTableType, &pNode->tableType);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetUBigIntValue(pJson, jkVirtualTableScanLogicPlanTableId, &pNode->tableId);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetUBigIntValue(pJson, jkVirtualTableScanLogicPlanStableId, &pNode->stableId);
}
if (TSDB_CODE_SUCCESS == code) {
tjsonGetNumberValue(pJson, jkVirtualTableScanLogicPlanScanType, pNode->scanType, code);
}
return code;
}
static const char* jkPhysiPlanOutputDataBlockDesc = "OutputDataBlockDesc"; static const char* jkPhysiPlanOutputDataBlockDesc = "OutputDataBlockDesc";
static const char* jkPhysiPlanConditions = "Conditions"; static const char* jkPhysiPlanConditions = "Conditions";
static const char* jkPhysiPlanChildren = "Children"; static const char* jkPhysiPlanChildren = "Children";
@ -2326,6 +2411,54 @@ static int32_t jsonToPhysiTableScanNode(const SJson* pJson, void* pObj) {
} }
return code; return code;
} }
static const char* jkVirtualTableScanPhysiPlanGroupTags = "GroupTags";
static const char* jkVirtualTableScanPhysiPlanGroupSort = "GroupSort";
static const char* jkVirtualTableScanPhysiPlanscanAllCols= "scanAllCols";
static const char* jkVirtualTableScanPhysiPlanTargets = "Targets";
static int32_t physiVirtualTableScanNodeToJson(const void* pObj, SJson* pJson) {
const SVirtualScanPhysiNode* pNode = (const SVirtualScanPhysiNode*)pObj;
int32_t code = physiScanNodeToJson(pObj, pJson);
if (TSDB_CODE_SUCCESS == code) {
code = nodeListToJson(pJson, jkVirtualTableScanPhysiPlanTargets, pNode->pGroupTags);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddBoolToObject(pJson, jkVirtualTableScanPhysiPlanTargets, pNode->groupSort);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddBoolToObject(pJson, jkVirtualTableScanPhysiPlanscanAllCols, pNode->scanAllCols);
}
if (TSDB_CODE_SUCCESS == code) {
code = nodeListToJson(pJson, jkVirtualTableScanPhysiPlanTargets, pNode->pTargets);
}
return code;
}
static int32_t jsonToPhysiVirtualTableScanNode(const SJson* pJson, void* pObj) {
SVirtualScanPhysiNode* pNode = (SVirtualScanPhysiNode*)pObj;
int32_t code = jsonToPhysicPlanNode(pJson, pObj);
if (TSDB_CODE_SUCCESS == code) {
code = jsonToNodeList(pJson, jkVirtualTableScanPhysiPlanGroupTags, &pNode->pGroupTags);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetBoolValue(pJson, jkVirtualTableScanPhysiPlanGroupSort, &pNode->groupSort);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetBoolValue(pJson, jkVirtualTableScanPhysiPlanscanAllCols, &pNode->scanAllCols);
}
if (TSDB_CODE_SUCCESS == code) {
code = jsonToNodeList(pJson, jkVirtualTableScanPhysiPlanTargets, &pNode->pTargets);
}
return code;
}
static const char* jkSysTableScanPhysiPlanMnodeEpSet = "MnodeEpSet"; static const char* jkSysTableScanPhysiPlanMnodeEpSet = "MnodeEpSet";
static const char* jkSysTableScanPhysiPlanShowRewrite = "ShowRewrite"; static const char* jkSysTableScanPhysiPlanShowRewrite = "ShowRewrite";
@ -4965,6 +5098,61 @@ static int32_t jsonToJoinTableNode(const SJson* pJson, void* pObj) {
return code; return code;
} }
static const char* jkVirtualTableMetaSize = "MetaSize";
static const char* jkVirtuaTableMeta = "Meta";
static const char* jkVirtuaTableVgroupsInfoSize = "VgroupsInfoSize";
static const char* jkVirtuaTableVgroupsInfo = "VgroupsInfo";
static const char* jkVirtuaTableRefTables = "RefTables";
static int32_t virtualTableNodeToJson(const void* pObj, SJson* pJson) {
const SVirtualTableNode* pNode = (const SVirtualTableNode*)pObj;
int32_t code = tableNodeToJson(pObj, pJson);
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddIntegerToObject(pJson, jkVirtualTableMetaSize, TABLE_META_SIZE(pNode->pMeta));
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddObject(pJson, jkVirtuaTableMeta, tableMetaToJson, pNode->pMeta);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddIntegerToObject(pJson, jkVirtuaTableVgroupsInfoSize, VGROUPS_INFO_SIZE(pNode->pVgroupList));
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddObject(pJson, jkVirtuaTableVgroupsInfo, vgroupsInfoToJson, pNode->pVgroupList);
}
if (TSDB_CODE_SUCCESS == code) {
code = nodeListToJson(pJson, jkVirtuaTableRefTables, pNode->refTables);
}
return code;
}
static int32_t jsonToVirtualTableNode(const SJson* pJson, void* pObj) {
SVirtualTableNode* pNode = (SVirtualTableNode*)pObj;
int32_t objSize = 0;
int32_t code = jsonToTableNode(pJson, pObj);
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetIntValue(pJson, jkVirtualTableMetaSize, &objSize);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonMakeObject(pJson, jkVirtuaTableMeta, jsonToTableMeta, (void**)&pNode->pMeta, objSize);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetIntValue(pJson, jkVirtuaTableVgroupsInfoSize, &objSize);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonMakeObject(pJson, jkVirtuaTableVgroupsInfo, jsonToVgroupsInfo, (void**)&pNode->pVgroupList, objSize);
}
if (TSDB_CODE_SUCCESS == code) {
code = jsonToNodeList(pJson, jkVirtuaTableRefTables, &pNode->refTables);
}
return code;
}
static const char* jkGroupingSetType = "GroupingSetType"; static const char* jkGroupingSetType = "GroupingSetType";
static const char* jkGroupingSetParameter = "Parameters"; static const char* jkGroupingSetParameter = "Parameters";
@ -5961,6 +6149,42 @@ static int32_t jsonToStreamNotifyOptions(const SJson* pJson, void* pObj) {
if (code == TSDB_CODE_SUCCESS) { if (code == TSDB_CODE_SUCCESS) {
code = tjsonGetBoolValue(pJson, jkStreamNotifyOptionsNotifyHistory, &pNotifyOption->notifyHistory); code = tjsonGetBoolValue(pJson, jkStreamNotifyOptionsNotifyHistory, &pNotifyOption->notifyHistory);
} }
return code;
}
static const char* jkColumnReferenceColumnName = "ColumnName";
static const char* jkColumnReferenceRefDbName = "RefDbName";
static const char* jkColumnReferenceRefTableName = "RefTableName";
static const char* jkColumnReferenceRefColumnName = "RefColumnName";
static int32_t columnReferenceToJson(const void* pObj, SJson* pJson) {
const SColumnRefNode* pNode = (const SColumnRefNode*)pObj;
int32_t code = tjsonAddStringToObject(pJson, jkColumnReferenceColumnName, pNode->colName);
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddStringToObject(pJson, jkColumnReferenceRefDbName, pNode->refDbName);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddStringToObject(pJson, jkColumnReferenceRefTableName, pNode->refTableName);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddStringToObject(pJson, jkColumnReferenceRefColumnName, pNode->refColName);
}
return code;
}
static int32_t jsonToColumnReference(const SJson* pJson, void* pObj) {
SColumnRefNode* pNode = (SColumnRefNode*)pObj;
int32_t code = tjsonGetStringValue(pJson, jkColumnReferenceColumnName, pNode->colName);
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetStringValue(pJson, jkColumnReferenceRefDbName, pNode->refDbName);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetStringValue(pJson, jkColumnReferenceRefTableName, pNode->refTableName);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetStringValue(pJson, jkColumnReferenceRefColumnName, pNode->refColName);
}
return code; return code;
} }
@ -6542,6 +6766,117 @@ static int32_t jsonToCreateMultiTablesStmt(const SJson* pJson, void* pObj) {
return jsonToNodeList(pJson, jkCreateMultiTablesStmtSubTables, &pNode->pSubTables); return jsonToNodeList(pJson, jkCreateMultiTablesStmtSubTables, &pNode->pSubTables);
} }
static const char* jkCreateVTableStmtDbName = "DbName";
static const char* jkCreateVTableStmtTableName = "TableName";
static const char* jkCreateVTableStmtIgnoreExists = "IgnoreExists";
static const char* jkCreateVTableStmtCols = "Cols";
static int32_t createVTableStmtToJson(const void* pObj, SJson* pJson) {
const SCreateVTableStmt* pNode = (const SCreateVTableStmt*)pObj;
int32_t code = tjsonAddStringToObject(pJson, jkCreateVTableStmtDbName, pNode->dbName);
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddStringToObject(pJson, jkCreateVTableStmtTableName, pNode->tableName);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddBoolToObject(pJson, jkCreateVTableStmtIgnoreExists, pNode->ignoreExists);
}
if (TSDB_CODE_SUCCESS == code) {
code = nodeListToJson(pJson, jkCreateVTableStmtCols, pNode->pCols);
}
return code;
}
static int32_t jsonToCreateVTableStmt(const SJson* pJson, void* pObj) {
SCreateVTableStmt* pNode = (SCreateVTableStmt*)pObj;
int32_t code = tjsonGetStringValue(pJson, jkCreateTableStmtDbName, pNode->dbName);
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetStringValue(pJson, jkCreateTableStmtTableName, pNode->tableName);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetBoolValue(pJson, jkCreateTableStmtIgnoreExists, &pNode->ignoreExists);
}
if (TSDB_CODE_SUCCESS == code) {
code = jsonToNodeList(pJson, jkCreateTableStmtCols, &pNode->pCols);
}
return code;
}
static const char* jkCreateVSubTableStmtDbName = "DbName";
static const char* jkCreateVSubTableStmtTableName = "TableName";
static const char* jkCreateVSubTableStmtUseDbName = "UseDbName";
static const char* jkCreateVSubTableStmtUseTableName = "UseTableName";
static const char* jkCreateVSubTableStmtIgnoreExists = "IgnoreExists";
static const char* jkCreateVSubTableStmtSpecificTags = "SpecificTags";
static const char* jkCreateVSubTableStmtValsOfTags = "ValsOfTags";
static const char* jkCreateVSubTableStmtSpecificColRefs = "SpecificColRefs";
static const char* jkCreateVSubTableStmtValsOfColRefs = "ValsOfColRefs";
static int32_t createVSubTableStmtToJson(const void* pObj, SJson* pJson) {
const SCreateVSubTableStmt* pNode = (const SCreateVSubTableStmt*)pObj;
int32_t code = tjsonAddStringToObject(pJson, jkCreateVSubTableStmtDbName, pNode->dbName);
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddStringToObject(pJson, jkCreateVSubTableStmtTableName, pNode->tableName);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddStringToObject(pJson, jkCreateVSubTableStmtUseDbName, pNode->useDbName);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddStringToObject(pJson, jkCreateVSubTableStmtUseTableName, pNode->useTableName);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddBoolToObject(pJson, jkCreateVSubTableStmtIgnoreExists, pNode->ignoreExists);
}
if (TSDB_CODE_SUCCESS == code) {
code = nodeListToJson(pJson, jkCreateVSubTableStmtSpecificTags, pNode->pSpecificTags);
}
if (TSDB_CODE_SUCCESS == code) {
code = nodeListToJson(pJson, jkCreateVSubTableStmtValsOfTags, pNode->pValsOfTags);
}
if (TSDB_CODE_SUCCESS == code) {
code = nodeListToJson(pJson, jkCreateVSubTableStmtSpecificColRefs, pNode->pSpecificColRefs);
}
if (TSDB_CODE_SUCCESS == code) {
code = nodeListToJson(pJson, jkCreateVSubTableStmtValsOfColRefs, pNode->pColRefs);
}
return code;
}
static int32_t jsonToCreateVSubTableStmt(const SJson* pJson, void* pObj) {
SCreateVSubTableStmt* pNode = (SCreateVSubTableStmt*)pObj;
int32_t code = tjsonGetStringValue(pJson, jkCreateVSubTableStmtDbName, pNode->dbName);
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetStringValue(pJson, jkCreateVSubTableStmtTableName, pNode->tableName);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetStringValue(pJson, jkCreateVSubTableStmtUseDbName, pNode->useDbName);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetStringValue(pJson, jkCreateVSubTableStmtUseTableName, pNode->useTableName);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetBoolValue(pJson, jkCreateVSubTableStmtIgnoreExists, &pNode->ignoreExists);
}
if (TSDB_CODE_SUCCESS == code) {
code = jsonToNodeList(pJson, jkCreateVSubTableStmtSpecificTags, &pNode->pSpecificTags);
}
if (TSDB_CODE_SUCCESS == code) {
code = jsonToNodeList(pJson, jkCreateVSubTableStmtValsOfTags, &pNode->pValsOfTags);
}
if (TSDB_CODE_SUCCESS == code) {
code = jsonToNodeList(pJson, jkCreateVSubTableStmtSpecificColRefs, &pNode->pSpecificColRefs);
}
if (TSDB_CODE_SUCCESS == code) {
code = jsonToNodeList(pJson, jkCreateVSubTableStmtValsOfColRefs, &pNode->pColRefs);
}
return code;
}
static const char* jkDropTableClauseDbName = "DbName"; static const char* jkDropTableClauseDbName = "DbName";
static const char* jkDropTableClauseTableName = "TableName"; static const char* jkDropTableClauseTableName = "TableName";
static const char* jkDropTableClauseIgnoreNotExists = "IgnoreNotExists"; static const char* jkDropTableClauseIgnoreNotExists = "IgnoreNotExists";
@ -6625,6 +6960,45 @@ static int32_t jsonToDropStableStmt(const SJson* pJson, void* pObj) {
return code; return code;
} }
static const char* jkDropVirtualTableStmtDbName = "DbName";
static const char* jkDropVirtualTableStmtTableName = "TableName";
static const char* jkDropVirtualTableStmtIgnoreNotExists = "IgnoreNotExists";
static const char* jkDropVirtualTableStmtwithOpt = "withOpt";
static int32_t dropVtableStmtToJson(const void* pObj, SJson* pJson) {
const SDropVirtualTableStmt* pNode = (const SDropVirtualTableStmt*)pObj;
int32_t code = tjsonAddStringToObject(pJson, jkDropVirtualTableStmtDbName, pNode->dbName);
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddStringToObject(pJson, jkDropVirtualTableStmtTableName, pNode->tableName);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddBoolToObject(pJson, jkDropVirtualTableStmtIgnoreNotExists, pNode->ignoreNotExists);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddBoolToObject(pJson, jkDropVirtualTableStmtwithOpt, pNode->withOpt);
}
return code;
}
static int32_t jsonToDropVtableStmt(const SJson* pJson, void* pObj) {
SDropVirtualTableStmt* pNode = (SDropVirtualTableStmt*)pObj;
int32_t code = tjsonGetStringValue(pJson, jkDropSuperTableStmtDbName, pNode->dbName);
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetStringValue(pJson, jkDropVirtualTableStmtTableName, pNode->tableName);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetBoolValue(pJson, jkDropVirtualTableStmtIgnoreNotExists, &pNode->ignoreNotExists);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetBoolValue(pJson, jkDropVirtualTableStmtwithOpt, &pNode->withOpt);
}
return code;
}
static const char* jkAlterTableStmtDbName = "DbName"; static const char* jkAlterTableStmtDbName = "DbName";
static const char* jkAlterTableStmtTableName = "TableName"; static const char* jkAlterTableStmtTableName = "TableName";
static const char* jkAlterTableStmtAlterType = "AlterType"; static const char* jkAlterTableStmtAlterType = "AlterType";
@ -8134,6 +8508,8 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
return tempTableNodeToJson(pObj, pJson); return tempTableNodeToJson(pObj, pJson);
case QUERY_NODE_JOIN_TABLE: case QUERY_NODE_JOIN_TABLE:
return joinTableNodeToJson(pObj, pJson); return joinTableNodeToJson(pObj, pJson);
case QUERY_NODE_VIRTUAL_TABLE:
return virtualTableNodeToJson(pObj, pJson);
case QUERY_NODE_GROUPING_SET: case QUERY_NODE_GROUPING_SET:
return groupingSetNodeToJson(pObj, pJson); return groupingSetNodeToJson(pObj, pJson);
case QUERY_NODE_ORDER_BY_EXPR: case QUERY_NODE_ORDER_BY_EXPR:
@ -8176,6 +8552,8 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
return streamOptionsToJson(pObj, pJson); return streamOptionsToJson(pObj, pJson);
case QUERY_NODE_LEFT_VALUE: case QUERY_NODE_LEFT_VALUE:
return TSDB_CODE_SUCCESS; // SLeftValueNode has no fields to serialize. return TSDB_CODE_SUCCESS; // SLeftValueNode has no fields to serialize.
case QUERY_NODE_COLUMN_REF:
return columnReferenceToJson(pObj, pJson);
case QUERY_NODE_WHEN_THEN: case QUERY_NODE_WHEN_THEN:
return whenThenNodeToJson(pObj, pJson); return whenThenNodeToJson(pObj, pJson);
case QUERY_NODE_CASE_WHEN: case QUERY_NODE_CASE_WHEN:
@ -8208,6 +8586,10 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
return createTableStmtToJson(pObj, pJson); return createTableStmtToJson(pObj, pJson);
case QUERY_NODE_CREATE_SUBTABLE_CLAUSE: case QUERY_NODE_CREATE_SUBTABLE_CLAUSE:
return createSubTableClauseToJson(pObj, pJson); return createSubTableClauseToJson(pObj, pJson);
case QUERY_NODE_CREATE_VIRTUAL_TABLE_STMT:
return createVTableStmtToJson(pObj, pJson);
case QUERY_NODE_CREATE_VIRTUAL_SUBTABLE_STMT:
return createVSubTableStmtToJson(pObj, pJson);
case QUERY_NODE_CREATE_MULTI_TABLES_STMT: case QUERY_NODE_CREATE_MULTI_TABLES_STMT:
return createMultiTablesStmtToJson(pObj, pJson); return createMultiTablesStmtToJson(pObj, pJson);
case QUERY_NODE_DROP_TABLE_CLAUSE: case QUERY_NODE_DROP_TABLE_CLAUSE:
@ -8216,6 +8598,8 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
return dropTableStmtToJson(pObj, pJson); return dropTableStmtToJson(pObj, pJson);
case QUERY_NODE_DROP_SUPER_TABLE_STMT: case QUERY_NODE_DROP_SUPER_TABLE_STMT:
return dropStableStmtToJson(pObj, pJson); return dropStableStmtToJson(pObj, pJson);
case QUERY_NODE_DROP_VIRTUAL_TABLE_STMT:
return dropVtableStmtToJson(pObj, pJson);
case QUERY_NODE_ALTER_TABLE_STMT: case QUERY_NODE_ALTER_TABLE_STMT:
return alterTableStmtToJson(pObj, pJson); return alterTableStmtToJson(pObj, pJson);
case QUERY_NODE_ALTER_SUPER_TABLE_STMT: case QUERY_NODE_ALTER_SUPER_TABLE_STMT:
@ -8321,6 +8705,7 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
case QUERY_NODE_SHOW_STREAMS_STMT: case QUERY_NODE_SHOW_STREAMS_STMT:
return showStreamsStmtToJson(pObj, pJson); return showStreamsStmtToJson(pObj, pJson);
case QUERY_NODE_SHOW_TABLES_STMT: case QUERY_NODE_SHOW_TABLES_STMT:
case QUERY_NODE_SHOW_VTABLES_STMT:
return showTablesStmtToJson(pObj, pJson); return showTablesStmtToJson(pObj, pJson);
case QUERY_NODE_SHOW_TAGS_STMT: case QUERY_NODE_SHOW_TAGS_STMT:
return showTagsStmtToJson(pObj, pJson); return showTagsStmtToJson(pObj, pJson);
@ -8354,6 +8739,7 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
case QUERY_NODE_SHOW_CREATE_DATABASE_STMT: case QUERY_NODE_SHOW_CREATE_DATABASE_STMT:
return showCreateDatabaseStmtToJson(pObj, pJson); return showCreateDatabaseStmtToJson(pObj, pJson);
case QUERY_NODE_SHOW_CREATE_TABLE_STMT: case QUERY_NODE_SHOW_CREATE_TABLE_STMT:
case QUERY_NODE_SHOW_CREATE_VTABLE_STMT:
return showCreateTableStmtToJson(pObj, pJson); return showCreateTableStmtToJson(pObj, pJson);
case QUERY_NODE_SHOW_CREATE_STABLE_STMT: case QUERY_NODE_SHOW_CREATE_STABLE_STMT:
return showCreateStableStmtToJson(pObj, pJson); return showCreateStableStmtToJson(pObj, pJson);
@ -8375,6 +8761,8 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
return logicScanNodeToJson(pObj, pJson); return logicScanNodeToJson(pObj, pJson);
case QUERY_NODE_LOGIC_PLAN_JOIN: case QUERY_NODE_LOGIC_PLAN_JOIN:
return logicJoinNodeToJson(pObj, pJson); return logicJoinNodeToJson(pObj, pJson);
case QUERY_NODE_LOGIC_PLAN_VIRTUAL_TABLE_SCAN:
return logicVirtualTableScanNodeToJson(pObj, pJson);
case QUERY_NODE_LOGIC_PLAN_AGG: case QUERY_NODE_LOGIC_PLAN_AGG:
return logicAggNodeToJson(pObj, pJson); return logicAggNodeToJson(pObj, pJson);
case QUERY_NODE_LOGIC_PLAN_PROJECT: case QUERY_NODE_LOGIC_PLAN_PROJECT:
@ -8418,6 +8806,8 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
case QUERY_NODE_PHYSICAL_PLAN_TABLE_MERGE_SCAN: case QUERY_NODE_PHYSICAL_PLAN_TABLE_MERGE_SCAN:
case QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN: case QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN:
return physiTableScanNodeToJson(pObj, pJson); return physiTableScanNodeToJson(pObj, pJson);
case QUERY_NODE_PHYSICAL_PLAN_VIRTUAL_TABLE_SCAN:
return physiVirtualTableScanNodeToJson(pObj, pJson);
case QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN: case QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN:
return physiSysTableScanNodeToJson(pObj, pJson); return physiSysTableScanNodeToJson(pObj, pJson);
case QUERY_NODE_PHYSICAL_PLAN_PROJECT: case QUERY_NODE_PHYSICAL_PLAN_PROJECT:
@ -8522,6 +8912,8 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) {
return jsonToTempTableNode(pJson, pObj); return jsonToTempTableNode(pJson, pObj);
case QUERY_NODE_JOIN_TABLE: case QUERY_NODE_JOIN_TABLE:
return jsonToJoinTableNode(pJson, pObj); return jsonToJoinTableNode(pJson, pObj);
case QUERY_NODE_VIRTUAL_TABLE:
return jsonToVirtualTableNode(pJson, pObj);
case QUERY_NODE_GROUPING_SET: case QUERY_NODE_GROUPING_SET:
return jsonToGroupingSetNode(pJson, pObj); return jsonToGroupingSetNode(pJson, pObj);
case QUERY_NODE_ORDER_BY_EXPR: case QUERY_NODE_ORDER_BY_EXPR:
@ -8562,6 +8954,8 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) {
return jsonToStreamOptions(pJson, pObj); return jsonToStreamOptions(pJson, pObj);
case QUERY_NODE_LEFT_VALUE: case QUERY_NODE_LEFT_VALUE:
return TSDB_CODE_SUCCESS; // SLeftValueNode has no fields to deserialize. return TSDB_CODE_SUCCESS; // SLeftValueNode has no fields to deserialize.
case QUERY_NODE_COLUMN_REF:
return jsonToColumnReference(pJson, pObj);
case QUERY_NODE_WHEN_THEN: case QUERY_NODE_WHEN_THEN:
return jsonToWhenThenNode(pJson, pObj); return jsonToWhenThenNode(pJson, pObj);
case QUERY_NODE_CASE_WHEN: case QUERY_NODE_CASE_WHEN:
@ -8594,6 +8988,10 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) {
return jsonToCreateTableStmt(pJson, pObj); return jsonToCreateTableStmt(pJson, pObj);
case QUERY_NODE_CREATE_SUBTABLE_CLAUSE: case QUERY_NODE_CREATE_SUBTABLE_CLAUSE:
return jsonToCreateSubTableClause(pJson, pObj); return jsonToCreateSubTableClause(pJson, pObj);
case QUERY_NODE_CREATE_VIRTUAL_TABLE_STMT:
return jsonToCreateVTableStmt(pJson, pObj);
case QUERY_NODE_CREATE_VIRTUAL_SUBTABLE_STMT:
return jsonToCreateVSubTableStmt(pJson, pObj);
case QUERY_NODE_CREATE_MULTI_TABLES_STMT: case QUERY_NODE_CREATE_MULTI_TABLES_STMT:
return jsonToCreateMultiTablesStmt(pJson, pObj); return jsonToCreateMultiTablesStmt(pJson, pObj);
case QUERY_NODE_DROP_TABLE_CLAUSE: case QUERY_NODE_DROP_TABLE_CLAUSE:
@ -8602,6 +9000,8 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) {
return jsonToDropTableStmt(pJson, pObj); return jsonToDropTableStmt(pJson, pObj);
case QUERY_NODE_DROP_SUPER_TABLE_STMT: case QUERY_NODE_DROP_SUPER_TABLE_STMT:
return jsonToDropStableStmt(pJson, pObj); return jsonToDropStableStmt(pJson, pObj);
case QUERY_NODE_DROP_VIRTUAL_TABLE_STMT:
return jsonToDropVtableStmt(pJson, pObj);
case QUERY_NODE_ALTER_TABLE_STMT: case QUERY_NODE_ALTER_TABLE_STMT:
return jsonToAlterTableStmt(pJson, pObj); return jsonToAlterTableStmt(pJson, pObj);
case QUERY_NODE_ALTER_SUPER_TABLE_STMT: case QUERY_NODE_ALTER_SUPER_TABLE_STMT:
@ -8701,6 +9101,7 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) {
case QUERY_NODE_SHOW_STREAMS_STMT: case QUERY_NODE_SHOW_STREAMS_STMT:
return jsonToShowStreamsStmt(pJson, pObj); return jsonToShowStreamsStmt(pJson, pObj);
case QUERY_NODE_SHOW_TABLES_STMT: case QUERY_NODE_SHOW_TABLES_STMT:
case QUERY_NODE_SHOW_VTABLES_STMT:
return jsonToShowTablesStmt(pJson, pObj); return jsonToShowTablesStmt(pJson, pObj);
case QUERY_NODE_SHOW_TAGS_STMT: case QUERY_NODE_SHOW_TAGS_STMT:
return jsonToShowTagsStmt(pJson, pObj); return jsonToShowTagsStmt(pJson, pObj);
@ -8734,6 +9135,7 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) {
case QUERY_NODE_SHOW_CREATE_DATABASE_STMT: case QUERY_NODE_SHOW_CREATE_DATABASE_STMT:
return jsonToShowCreateDatabaseStmt(pJson, pObj); return jsonToShowCreateDatabaseStmt(pJson, pObj);
case QUERY_NODE_SHOW_CREATE_TABLE_STMT: case QUERY_NODE_SHOW_CREATE_TABLE_STMT:
case QUERY_NODE_SHOW_CREATE_VTABLE_STMT:
return jsonToShowCreateTableStmt(pJson, pObj); return jsonToShowCreateTableStmt(pJson, pObj);
case QUERY_NODE_SHOW_CREATE_STABLE_STMT: case QUERY_NODE_SHOW_CREATE_STABLE_STMT:
return jsonToShowCreateStableStmt(pJson, pObj); return jsonToShowCreateStableStmt(pJson, pObj);
@ -8763,6 +9165,8 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) {
return jsonToLogicScanNode(pJson, pObj); return jsonToLogicScanNode(pJson, pObj);
case QUERY_NODE_LOGIC_PLAN_JOIN: case QUERY_NODE_LOGIC_PLAN_JOIN:
return jsonToLogicJoinNode(pJson, pObj); return jsonToLogicJoinNode(pJson, pObj);
case QUERY_NODE_LOGIC_PLAN_VIRTUAL_TABLE_SCAN:
return jsonToLogicVirtualTableScanNode(pJson, pObj);
case QUERY_NODE_LOGIC_PLAN_AGG: case QUERY_NODE_LOGIC_PLAN_AGG:
return jsonToLogicAggNode(pJson, pObj); return jsonToLogicAggNode(pJson, pObj);
case QUERY_NODE_LOGIC_PLAN_PROJECT: case QUERY_NODE_LOGIC_PLAN_PROJECT:
@ -8806,6 +9210,8 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) {
case QUERY_NODE_PHYSICAL_PLAN_TABLE_MERGE_SCAN: case QUERY_NODE_PHYSICAL_PLAN_TABLE_MERGE_SCAN:
case QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN: case QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN:
return jsonToPhysiTableScanNode(pJson, pObj); return jsonToPhysiTableScanNode(pJson, pObj);
case QUERY_NODE_PHYSICAL_PLAN_VIRTUAL_TABLE_SCAN:
return jsonToPhysiVirtualTableScanNode(pJson, pObj);
case QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN: case QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN:
return jsonToPhysiSysTableScanNode(pJson, pObj); return jsonToPhysiSysTableScanNode(pJson, pObj);
case QUERY_NODE_PHYSICAL_PLAN_PROJECT: case QUERY_NODE_PHYSICAL_PLAN_PROJECT:

View File

@ -200,6 +200,7 @@ bool nodesEqualNode(const SNode* a, const SNode* b) {
case QUERY_NODE_GROUPING_SET: case QUERY_NODE_GROUPING_SET:
return groupingSetNodeEqual((const SGroupingSetNode*)a, (const SGroupingSetNode*)b); return groupingSetNodeEqual((const SGroupingSetNode*)a, (const SGroupingSetNode*)b);
case QUERY_NODE_REAL_TABLE: case QUERY_NODE_REAL_TABLE:
case QUERY_NODE_VIRTUAL_TABLE:
case QUERY_NODE_TEMP_TABLE: case QUERY_NODE_TEMP_TABLE:
case QUERY_NODE_JOIN_TABLE: case QUERY_NODE_JOIN_TABLE:
case QUERY_NODE_ORDER_BY_EXPR: case QUERY_NODE_ORDER_BY_EXPR:

View File

@ -168,6 +168,7 @@ bool nodesMatchNode(const SNode* pSub, const SNode* p) {
case QUERY_NODE_REAL_TABLE: case QUERY_NODE_REAL_TABLE:
case QUERY_NODE_TEMP_TABLE: case QUERY_NODE_TEMP_TABLE:
case QUERY_NODE_JOIN_TABLE: case QUERY_NODE_JOIN_TABLE:
case QUERY_NODE_VIRTUAL_TABLE:
case QUERY_NODE_GROUPING_SET: case QUERY_NODE_GROUPING_SET:
case QUERY_NODE_ORDER_BY_EXPR: case QUERY_NODE_ORDER_BY_EXPR:
case QUERY_NODE_LIMIT: case QUERY_NODE_LIMIT:

View File

@ -758,6 +758,24 @@ static int32_t columnNodeInlineToMsg(const void* pObj, STlvEncoder* pEncoder) {
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
code = tlvEncodeValueI16(pEncoder, pNode->numOfPKs); code = tlvEncodeValueI16(pEncoder, pNode->numOfPKs);
} }
if (TSDB_CODE_SUCCESS == code) {
code = tlvEncodeValueBool(pEncoder, pNode->isPrimTs);
}
if (TSDB_CODE_SUCCESS == code) {
code = tlvEncodeValueBool(pEncoder, pNode->hasDep);
}
if (TSDB_CODE_SUCCESS == code) {
code = tlvEncodeValueBool(pEncoder, pNode->hasRef);
}
if (TSDB_CODE_SUCCESS == code) {
code = tlvEncodeValueCStr(pEncoder, pNode->refDbName);
}
if (TSDB_CODE_SUCCESS == code) {
code = tlvEncodeValueCStr(pEncoder, pNode->refTableName);
}
if (TSDB_CODE_SUCCESS == code) {
code = tlvEncodeValueCStr(pEncoder, pNode->refColName);
}
return code; return code;
} }
@ -814,6 +832,24 @@ static int32_t msgToColumnNodeInline(STlvDecoder* pDecoder, void* pObj) {
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
code = tlvDecodeValueI16(pDecoder, &pNode->numOfPKs); code = tlvDecodeValueI16(pDecoder, &pNode->numOfPKs);
} }
if (TSDB_CODE_SUCCESS == code) {
code = tlvDecodeValueBool(pDecoder, &pNode->isPrimTs);
}
if (TSDB_CODE_SUCCESS == code) {
code = tlvDecodeValueBool(pDecoder, &pNode->hasDep);
}
if (TSDB_CODE_SUCCESS == code) {
code = tlvDecodeValueBool(pDecoder, &pNode->hasRef);
}
if (TSDB_CODE_SUCCESS == code) {
code = tlvDecodeValueCStr(pDecoder, pNode->refDbName);
}
if (TSDB_CODE_SUCCESS == code) {
code = tlvDecodeValueCStr(pDecoder, pNode->refTableName);
}
if (TSDB_CODE_SUCCESS == code) {
code = tlvDecodeValueCStr(pDecoder, pNode->refColName);
}
return code; return code;
} }
@ -2088,7 +2124,8 @@ enum {
PHY_SCAN_CODE_BASE_SUID, PHY_SCAN_CODE_BASE_SUID,
PHY_SCAN_CODE_BASE_TABLE_TYPE, PHY_SCAN_CODE_BASE_TABLE_TYPE,
PHY_SCAN_CODE_BASE_TABLE_NAME, PHY_SCAN_CODE_BASE_TABLE_NAME,
PHY_SCAN_CODE_BASE_GROUP_ORDER_SCAN PHY_SCAN_CODE_BASE_GROUP_ORDER_SCAN,
PHY_SCAN_CODE_BASE_VIRTUAL_STABLE_SCAN
}; };
static int32_t physiScanNodeToMsg(const void* pObj, STlvEncoder* pEncoder) { static int32_t physiScanNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
@ -2116,6 +2153,9 @@ static int32_t physiScanNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
code = tlvEncodeBool(pEncoder, PHY_SCAN_CODE_BASE_GROUP_ORDER_SCAN, pNode->groupOrderScan); code = tlvEncodeBool(pEncoder, PHY_SCAN_CODE_BASE_GROUP_ORDER_SCAN, pNode->groupOrderScan);
} }
if (TSDB_CODE_SUCCESS == code) {
code = tlvEncodeBool(pEncoder, PHY_SCAN_CODE_BASE_VIRTUAL_STABLE_SCAN, pNode->virtualStableScan);
}
return code; return code;
} }
@ -2151,6 +2191,69 @@ static int32_t msgToPhysiScanNode(STlvDecoder* pDecoder, void* pObj) {
case PHY_SCAN_CODE_BASE_GROUP_ORDER_SCAN: case PHY_SCAN_CODE_BASE_GROUP_ORDER_SCAN:
code = tlvDecodeBool(pTlv, &pNode->groupOrderScan); code = tlvDecodeBool(pTlv, &pNode->groupOrderScan);
break; break;
case PHY_SCAN_CODE_BASE_VIRTUAL_STABLE_SCAN:
code = tlvDecodeBool(pTlv, &pNode->virtualStableScan);
default:
break;
}
}
return code;
}
enum {
PHY_VIRTUAL_TABLE_SCAN_CODE_SCAN = 1,
PHY_VIRTUAL_TABLE_SCAN_CODE_GROUPTAGS,
PHY_VIRTUAL_TABLE_SCAN_CODE_GROUP_SORT,
PHY_VIRTUAL_TABLE_SCAN_CODE_ONLY_TS,
PHY_VIRTUAL_TABLE_SCAN_CODE_TARGETS,
};
static int32_t physiVirtualTableScanNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
const SVirtualScanPhysiNode* pNode = (const SVirtualScanPhysiNode *)pObj;
int32_t code = tlvEncodeObj(pEncoder, PHY_VIRTUAL_TABLE_SCAN_CODE_SCAN, physiScanNodeToMsg, &pNode->scan);
if (TSDB_CODE_SUCCESS == code) {
code = tlvEncodeObj(pEncoder, PHY_VIRTUAL_TABLE_SCAN_CODE_GROUPTAGS, nodeListToMsg, pNode->pGroupTags);
}
if (TSDB_CODE_SUCCESS == code) {
code = tlvEncodeBool(pEncoder, PHY_VIRTUAL_TABLE_SCAN_CODE_GROUP_SORT, pNode->groupSort);
}
if (TSDB_CODE_SUCCESS == code) {
code = tlvEncodeBool(pEncoder, PHY_VIRTUAL_TABLE_SCAN_CODE_ONLY_TS, pNode->scanAllCols);
}
if (TSDB_CODE_SUCCESS == code) {
code = tlvEncodeObj(pEncoder, PHY_VIRTUAL_TABLE_SCAN_CODE_TARGETS, nodeListToMsg, pNode->pTargets);
}
return code;
}
static int32_t msgToPhysiVirtualTableScanNode(STlvDecoder* pDecoder, void* pObj) {
SVirtualScanPhysiNode* pNode = (SVirtualScanPhysiNode*)pObj;
int32_t code = TSDB_CODE_SUCCESS;
STlv* pTlv = NULL;
tlvForEach(pDecoder, pTlv, code) {
switch (pTlv->type) {
case PHY_VIRTUAL_TABLE_SCAN_CODE_SCAN:
code = tlvDecodeObjFromTlv(pTlv, msgToPhysiScanNode, &pNode->scan);
break;
case PHY_VIRTUAL_TABLE_SCAN_CODE_GROUPTAGS:
code = msgToNodeListFromTlv(pTlv, (void**)&pNode->pGroupTags);
break;
case PHY_VIRTUAL_TABLE_SCAN_CODE_GROUP_SORT:
code = tlvDecodeBool(pTlv, &pNode->groupSort);
break;
case PHY_VIRTUAL_TABLE_SCAN_CODE_ONLY_TS:
code = tlvDecodeBool(pTlv, &pNode->scanAllCols);
break;
case PHY_VIRTUAL_TABLE_SCAN_CODE_TARGETS:
code = msgToNodeListFromTlv(pTlv, (void**)&pNode->pTargets);
break;
default: default:
break; break;
} }
@ -4248,6 +4351,11 @@ enum {
PHY_DYN_QUERY_CTRL_CODE_STB_JOIN_UID_SLOT1, PHY_DYN_QUERY_CTRL_CODE_STB_JOIN_UID_SLOT1,
PHY_DYN_QUERY_CTRL_CODE_STB_JOIN_SRC_SCAN0, PHY_DYN_QUERY_CTRL_CODE_STB_JOIN_SRC_SCAN0,
PHY_DYN_QUERY_CTRL_CODE_STB_JOIN_SRC_SCAN1, PHY_DYN_QUERY_CTRL_CODE_STB_JOIN_SRC_SCAN1,
PHY_DYN_QUERY_CTRL_CODE_VTB_SCAN_SCAN_ALL_COLS,
PHY_DYN_QUERY_CTRL_CODE_VTB_SCAN_SUID,
PHY_DYN_QUERY_CTRL_CODE_VTB_SCAN_ACCOUNT_ID,
PHY_DYN_QUERY_CTRL_CODE_VTB_SCAN_EP_SET,
PHY_DYN_QUERY_CTRL_CODE_VTB_SCAN_SCAN_COLS,
}; };
static int32_t physiDynQueryCtrlNodeToMsg(const void* pObj, STlvEncoder* pEncoder) { static int32_t physiDynQueryCtrlNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
@ -4281,6 +4389,22 @@ static int32_t physiDynQueryCtrlNodeToMsg(const void* pObj, STlvEncoder* pEncode
} }
break; break;
} }
case DYN_QTYPE_VTB_SCAN: {
code = tlvEncodeBool(pEncoder, PHY_DYN_QUERY_CTRL_CODE_VTB_SCAN_SCAN_ALL_COLS, pNode->vtbScan.scanAllCols);
if (TSDB_CODE_SUCCESS == code) {
code = tlvEncodeU64(pEncoder, PHY_DYN_QUERY_CTRL_CODE_VTB_SCAN_SUID, pNode->vtbScan.suid);
}
if (TSDB_CODE_SUCCESS == code) {
code = tlvEncodeI32(pEncoder, PHY_DYN_QUERY_CTRL_CODE_VTB_SCAN_ACCOUNT_ID, pNode->vtbScan.accountId);
}
if (TSDB_CODE_SUCCESS == code) {
code = tlvEncodeObj(pEncoder, PHY_DYN_QUERY_CTRL_CODE_VTB_SCAN_EP_SET, epSetToMsg, &pNode->vtbScan.mgmtEpSet);
}
if (TSDB_CODE_SUCCESS == code) {
code = tlvEncodeObj(pEncoder, PHY_DYN_QUERY_CTRL_CODE_VTB_SCAN_SCAN_COLS, nodeListToMsg, pNode->vtbScan.pScanCols);
}
break;
}
default: default:
return TSDB_CODE_INVALID_PARA; return TSDB_CODE_INVALID_PARA;
} }
@ -4322,6 +4446,20 @@ static int32_t msgToPhysiDynQueryCtrlNode(STlvDecoder* pDecoder, void* pObj) {
case PHY_DYN_QUERY_CTRL_CODE_STB_JOIN_SRC_SCAN1: case PHY_DYN_QUERY_CTRL_CODE_STB_JOIN_SRC_SCAN1:
code = tlvDecodeBool(pTlv, &pNode->stbJoin.srcScan[1]); code = tlvDecodeBool(pTlv, &pNode->stbJoin.srcScan[1]);
break; break;
case PHY_DYN_QUERY_CTRL_CODE_VTB_SCAN_SCAN_ALL_COLS:
code = tlvDecodeBool(pTlv, &pNode->vtbScan.scanAllCols);
break;
case PHY_DYN_QUERY_CTRL_CODE_VTB_SCAN_SUID:
code = tlvDecodeU64(pTlv, &pNode->vtbScan.suid);
break;
case PHY_DYN_QUERY_CTRL_CODE_VTB_SCAN_ACCOUNT_ID:
code = tlvDecodeI32(pTlv, &pNode->vtbScan.accountId);
break;
case PHY_DYN_QUERY_CTRL_CODE_VTB_SCAN_EP_SET:
code = tlvDecodeObjFromTlv(pTlv, msgToEpSet, &pNode->vtbScan.mgmtEpSet);
break;
case PHY_DYN_QUERY_CTRL_CODE_VTB_SCAN_SCAN_COLS:
code = msgToNodeListFromTlv(pTlv, (void**)&pNode->vtbScan.pScanCols);
default: default:
break; break;
} }
@ -4445,7 +4583,9 @@ static int32_t subplanInlineToMsg(const void* pObj, STlvEncoder* pEncoder) {
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
code = tlvEncodeValueBool(pEncoder, pNode->isAudit); code = tlvEncodeValueBool(pEncoder, pNode->isAudit);
} }
if (TSDB_CODE_SUCCESS == code) {
code = tlvEncodeValueBool(pEncoder, pNode->processOneBlock);
}
return code; return code;
} }
@ -4506,6 +4646,9 @@ static int32_t msgToSubplanInline(STlvDecoder* pDecoder, void* pObj) {
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
code = tlvDecodeValueBool(pDecoder, &pNode->isAudit); code = tlvDecodeValueBool(pDecoder, &pNode->isAudit);
} }
if (TSDB_CODE_SUCCESS == code) {
code = tlvDecodeValueBool(pDecoder, &pNode->processOneBlock);
}
return code; return code;
} }
@ -4759,6 +4902,9 @@ static int32_t specificNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
case QUERY_NODE_PHYSICAL_PLAN_DYN_QUERY_CTRL: case QUERY_NODE_PHYSICAL_PLAN_DYN_QUERY_CTRL:
code = physiDynQueryCtrlNodeToMsg(pObj, pEncoder); code = physiDynQueryCtrlNodeToMsg(pObj, pEncoder);
break; break;
case QUERY_NODE_PHYSICAL_PLAN_VIRTUAL_TABLE_SCAN:
code = physiVirtualTableScanNodeToMsg(pObj, pEncoder);
break;
case QUERY_NODE_PHYSICAL_SUBPLAN: case QUERY_NODE_PHYSICAL_SUBPLAN:
code = subplanToMsg(pObj, pEncoder); code = subplanToMsg(pObj, pEncoder);
break; break;
@ -4937,6 +5083,9 @@ static int32_t msgToSpecificNode(STlvDecoder* pDecoder, void* pObj) {
case QUERY_NODE_PHYSICAL_PLAN_DYN_QUERY_CTRL: case QUERY_NODE_PHYSICAL_PLAN_DYN_QUERY_CTRL:
code = msgToPhysiDynQueryCtrlNode(pDecoder, pObj); code = msgToPhysiDynQueryCtrlNode(pDecoder, pObj);
break; break;
case QUERY_NODE_PHYSICAL_PLAN_VIRTUAL_TABLE_SCAN:
code = msgToPhysiVirtualTableScanNode(pDecoder, pObj);
break;
case QUERY_NODE_PHYSICAL_SUBPLAN: case QUERY_NODE_PHYSICAL_SUBPLAN:
code = msgToSubplan(pDecoder, pObj); code = msgToSubplan(pDecoder, pObj);
break; break;

View File

@ -78,6 +78,7 @@ static EDealRes dispatchExpr(SNode* pNode, ETraversalOrder order, FNodeWalker wa
break; break;
case QUERY_NODE_REAL_TABLE: case QUERY_NODE_REAL_TABLE:
case QUERY_NODE_TEMP_TABLE: case QUERY_NODE_TEMP_TABLE:
case QUERY_NODE_VIRTUAL_TABLE:
break; // todo break; // todo
case QUERY_NODE_JOIN_TABLE: { case QUERY_NODE_JOIN_TABLE: {
SJoinTableNode* pJoinTableNode = (SJoinTableNode*)pNode; SJoinTableNode* pJoinTableNode = (SJoinTableNode*)pNode;
@ -295,6 +296,7 @@ static EDealRes rewriteExpr(SNode** pRawNode, ETraversalOrder order, FNodeRewrit
} }
case QUERY_NODE_REAL_TABLE: case QUERY_NODE_REAL_TABLE:
case QUERY_NODE_TEMP_TABLE: case QUERY_NODE_TEMP_TABLE:
case QUERY_NODE_VIRTUAL_TABLE:
break; // todo break; // todo
case QUERY_NODE_JOIN_TABLE: { case QUERY_NODE_JOIN_TABLE: {
SJoinTableNode* pJoinTableNode = (SJoinTableNode*)pNode; SJoinTableNode* pJoinTableNode = (SJoinTableNode*)pNode;

View File

@ -382,6 +382,9 @@ int32_t nodesMakeNode(ENodeType type, SNode** ppNodeOut) {
case QUERY_NODE_REAL_TABLE: case QUERY_NODE_REAL_TABLE:
code = makeNode(type, sizeof(SRealTableNode), &pNode); code = makeNode(type, sizeof(SRealTableNode), &pNode);
break; break;
case QUERY_NODE_VIRTUAL_TABLE:
code = makeNode(type, sizeof(SVirtualTableNode), &pNode);
break;
case QUERY_NODE_TEMP_TABLE: case QUERY_NODE_TEMP_TABLE:
code = makeNode(type, sizeof(STempTableNode), &pNode); code = makeNode(type, sizeof(STempTableNode), &pNode);
break; break;
@ -517,6 +520,12 @@ int32_t nodesMakeNode(ENodeType type, SNode** ppNodeOut) {
case QUERY_NODE_CREATE_SUBTABLE_CLAUSE: case QUERY_NODE_CREATE_SUBTABLE_CLAUSE:
code = makeNode(type, sizeof(SCreateSubTableClause), &pNode); code = makeNode(type, sizeof(SCreateSubTableClause), &pNode);
break; break;
case QUERY_NODE_CREATE_VIRTUAL_TABLE_STMT:
code = makeNode(type, sizeof(SCreateVTableStmt), &pNode);
break;
case QUERY_NODE_CREATE_VIRTUAL_SUBTABLE_STMT:
code = makeNode(type, sizeof(SCreateVSubTableStmt), &pNode);
break;
case QUERY_NODE_CREATE_SUBTABLE_FROM_FILE_CLAUSE: case QUERY_NODE_CREATE_SUBTABLE_FROM_FILE_CLAUSE:
code = makeNode(type, sizeof(SCreateSubTableFromFileClause), &pNode); code = makeNode(type, sizeof(SCreateSubTableFromFileClause), &pNode);
break; break;
@ -532,8 +541,12 @@ int32_t nodesMakeNode(ENodeType type, SNode** ppNodeOut) {
case QUERY_NODE_DROP_SUPER_TABLE_STMT: case QUERY_NODE_DROP_SUPER_TABLE_STMT:
code = makeNode(type, sizeof(SDropSuperTableStmt), &pNode); code = makeNode(type, sizeof(SDropSuperTableStmt), &pNode);
break; break;
case QUERY_NODE_DROP_VIRTUAL_TABLE_STMT:
code = makeNode(type, sizeof(SDropVirtualTableStmt), &pNode);
break;
case QUERY_NODE_ALTER_TABLE_STMT: case QUERY_NODE_ALTER_TABLE_STMT:
case QUERY_NODE_ALTER_SUPER_TABLE_STMT: case QUERY_NODE_ALTER_SUPER_TABLE_STMT:
case QUERY_NODE_ALTER_VIRTUAL_TABLE_STMT:
code = makeNode(type, sizeof(SAlterTableStmt), &pNode); code = makeNode(type, sizeof(SAlterTableStmt), &pNode);
break; break;
case QUERY_NODE_CREATE_USER_STMT: case QUERY_NODE_CREATE_USER_STMT:
@ -680,6 +693,7 @@ int32_t nodesMakeNode(ENodeType type, SNode** ppNodeOut) {
case QUERY_NODE_SHOW_STABLES_STMT: case QUERY_NODE_SHOW_STABLES_STMT:
case QUERY_NODE_SHOW_STREAMS_STMT: case QUERY_NODE_SHOW_STREAMS_STMT:
case QUERY_NODE_SHOW_TABLES_STMT: case QUERY_NODE_SHOW_TABLES_STMT:
case QUERY_NODE_SHOW_VTABLES_STMT:
case QUERY_NODE_SHOW_USERS_STMT: case QUERY_NODE_SHOW_USERS_STMT:
case QUERY_NODE_SHOW_USERS_FULL_STMT: case QUERY_NODE_SHOW_USERS_FULL_STMT:
case QUERY_NODE_SHOW_LICENCES_STMT: case QUERY_NODE_SHOW_LICENCES_STMT:
@ -720,6 +734,7 @@ int32_t nodesMakeNode(ENodeType type, SNode** ppNodeOut) {
code = makeNode(type, sizeof(SShowAliveStmt), &pNode); code = makeNode(type, sizeof(SShowAliveStmt), &pNode);
break; break;
case QUERY_NODE_SHOW_CREATE_TABLE_STMT: case QUERY_NODE_SHOW_CREATE_TABLE_STMT:
case QUERY_NODE_SHOW_CREATE_VTABLE_STMT:
case QUERY_NODE_SHOW_CREATE_STABLE_STMT: case QUERY_NODE_SHOW_CREATE_STABLE_STMT:
code = makeNode(type, sizeof(SShowCreateTableStmt), &pNode); code = makeNode(type, sizeof(SShowCreateTableStmt), &pNode);
break; break;
@ -824,6 +839,9 @@ int32_t nodesMakeNode(ENodeType type, SNode** ppNodeOut) {
case QUERY_NODE_LOGIC_PLAN_DYN_QUERY_CTRL: case QUERY_NODE_LOGIC_PLAN_DYN_QUERY_CTRL:
code = makeNode(type, sizeof(SDynQueryCtrlLogicNode), &pNode); code = makeNode(type, sizeof(SDynQueryCtrlLogicNode), &pNode);
break; break;
case QUERY_NODE_LOGIC_PLAN_VIRTUAL_TABLE_SCAN:
code = makeNode(type, sizeof(SVirtualScanLogicNode), &pNode);
break;
case QUERY_NODE_LOGIC_SUBPLAN: case QUERY_NODE_LOGIC_SUBPLAN:
code = makeNode(type, sizeof(SLogicSubplan), &pNode); code = makeNode(type, sizeof(SLogicSubplan), &pNode);
break; break;
@ -990,6 +1008,9 @@ int32_t nodesMakeNode(ENodeType type, SNode** ppNodeOut) {
case QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERP_FUNC: case QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERP_FUNC:
code = makeNode(type, sizeof(SStreamInterpFuncPhysiNode), &pNode); code = makeNode(type, sizeof(SStreamInterpFuncPhysiNode), &pNode);
break; break;
case QUERY_NODE_PHYSICAL_PLAN_VIRTUAL_TABLE_SCAN:
code = makeNode(type, sizeof(SVirtualScanPhysiNode), &pNode);
break;
default: default:
break; break;
} }
@ -1061,6 +1082,7 @@ static void destroyTableCfg(STableCfg* pCfg) {
taosMemoryFree(pCfg->pComment); taosMemoryFree(pCfg->pComment);
taosMemoryFree(pCfg->pSchemas); taosMemoryFree(pCfg->pSchemas);
taosMemoryFree(pCfg->pSchemaExt); taosMemoryFree(pCfg->pSchemaExt);
taosMemoryFree(pCfg->pColRefs);
taosMemoryFree(pCfg->pTags); taosMemoryFree(pCfg->pTags);
taosMemoryFree(pCfg); taosMemoryFree(pCfg);
} }
@ -1120,6 +1142,13 @@ void nodesDestroyNode(SNode* pNode) {
taosArrayDestroy(pReal->tsmaTargetTbInfo); taosArrayDestroy(pReal->tsmaTargetTbInfo);
break; break;
} }
case QUERY_NODE_VIRTUAL_TABLE: {
SVirtualTableNode *pVirtual = (SVirtualTableNode*)pNode;
taosMemoryFreeClear(pVirtual->pMeta);
taosMemoryFreeClear(pVirtual->pVgroupList);
nodesDestroyList(pVirtual->refTables);
break;
}
case QUERY_NODE_TEMP_TABLE: case QUERY_NODE_TEMP_TABLE:
nodesDestroyNode(((STempTableNode*)pNode)->pSubquery); nodesDestroyNode(((STempTableNode*)pNode)->pSubquery);
break; break;
@ -1409,6 +1438,19 @@ void nodesDestroyNode(SNode* pNode) {
nodesDestroyNode((SNode*)pStmt->pOptions); nodesDestroyNode((SNode*)pStmt->pOptions);
break; break;
} }
case QUERY_NODE_CREATE_VIRTUAL_TABLE_STMT: {
SCreateVTableStmt* pStmt = (SCreateVTableStmt*)pNode;
nodesDestroyList(pStmt->pCols);
break;
}
case QUERY_NODE_CREATE_VIRTUAL_SUBTABLE_STMT: {
SCreateVSubTableStmt* pStmt = (SCreateVSubTableStmt*)pNode;
nodesDestroyList(pStmt->pSpecificColRefs);
nodesDestroyList(pStmt->pColRefs);
nodesDestroyList(pStmt->pSpecificTags);
nodesDestroyList(pStmt->pValsOfTags);
break;
}
case QUERY_NODE_CREATE_SUBTABLE_FROM_FILE_CLAUSE: { case QUERY_NODE_CREATE_SUBTABLE_FROM_FILE_CLAUSE: {
SCreateSubTableFromFileClause* pStmt = (SCreateSubTableFromFileClause*)pNode; SCreateSubTableFromFileClause* pStmt = (SCreateSubTableFromFileClause*)pNode;
nodesDestroyList(pStmt->pSpecificTags); nodesDestroyList(pStmt->pSpecificTags);
@ -1422,10 +1464,12 @@ void nodesDestroyNode(SNode* pNode) {
case QUERY_NODE_DROP_TABLE_STMT: case QUERY_NODE_DROP_TABLE_STMT:
nodesDestroyList(((SDropTableStmt*)pNode)->pTables); nodesDestroyList(((SDropTableStmt*)pNode)->pTables);
break; break;
case QUERY_NODE_DROP_SUPER_TABLE_STMT: // no pointer field case QUERY_NODE_DROP_SUPER_TABLE_STMT:
case QUERY_NODE_DROP_VIRTUAL_TABLE_STMT: // no pointer field
break; break;
case QUERY_NODE_ALTER_TABLE_STMT: case QUERY_NODE_ALTER_TABLE_STMT:
case QUERY_NODE_ALTER_SUPER_TABLE_STMT: { case QUERY_NODE_ALTER_SUPER_TABLE_STMT:
case QUERY_NODE_ALTER_VIRTUAL_TABLE_STMT: {
SAlterTableStmt* pStmt = (SAlterTableStmt*)pNode; SAlterTableStmt* pStmt = (SAlterTableStmt*)pNode;
nodesDestroyNode((SNode*)pStmt->pOptions); nodesDestroyNode((SNode*)pStmt->pOptions);
nodesDestroyNode((SNode*)pStmt->pVal); nodesDestroyNode((SNode*)pStmt->pVal);
@ -1567,6 +1611,7 @@ void nodesDestroyNode(SNode* pNode) {
case QUERY_NODE_SHOW_STABLES_STMT: case QUERY_NODE_SHOW_STABLES_STMT:
case QUERY_NODE_SHOW_STREAMS_STMT: case QUERY_NODE_SHOW_STREAMS_STMT:
case QUERY_NODE_SHOW_TABLES_STMT: case QUERY_NODE_SHOW_TABLES_STMT:
case QUERY_NODE_SHOW_VTABLES_STMT:
case QUERY_NODE_SHOW_USERS_STMT: case QUERY_NODE_SHOW_USERS_STMT:
case QUERY_NODE_SHOW_USERS_FULL_STMT: case QUERY_NODE_SHOW_USERS_FULL_STMT:
case QUERY_NODE_SHOW_LICENCES_STMT: case QUERY_NODE_SHOW_LICENCES_STMT:
@ -1623,6 +1668,7 @@ void nodesDestroyNode(SNode* pNode) {
taosMemoryFreeClear(((SShowCreateDatabaseStmt*)pNode)->pCfg); taosMemoryFreeClear(((SShowCreateDatabaseStmt*)pNode)->pCfg);
break; break;
case QUERY_NODE_SHOW_CREATE_TABLE_STMT: case QUERY_NODE_SHOW_CREATE_TABLE_STMT:
case QUERY_NODE_SHOW_CREATE_VTABLE_STMT:
case QUERY_NODE_SHOW_CREATE_STABLE_STMT: case QUERY_NODE_SHOW_CREATE_STABLE_STMT:
taosMemoryFreeClear(((SShowCreateTableStmt*)pNode)->pDbCfg); taosMemoryFreeClear(((SShowCreateTableStmt*)pNode)->pDbCfg);
destroyTableCfg((STableCfg*)(((SShowCreateTableStmt*)pNode)->pTableCfg)); destroyTableCfg((STableCfg*)(((SShowCreateTableStmt*)pNode)->pTableCfg));
@ -1728,6 +1774,14 @@ void nodesDestroyNode(SNode* pNode) {
nodesDestroyNode(pLogicNode->pRightOnCond); nodesDestroyNode(pLogicNode->pRightOnCond);
break; break;
} }
case QUERY_NODE_LOGIC_PLAN_VIRTUAL_TABLE_SCAN: {
SVirtualScanLogicNode * pLogicNode = (SVirtualScanLogicNode*)pNode;
destroyLogicNode((SLogicNode*)pLogicNode);
nodesDestroyList(pLogicNode->pScanCols);
nodesDestroyList(pLogicNode->pScanPseudoCols);
taosMemoryFreeClear(pLogicNode->pVgroupList);
break;
}
case QUERY_NODE_LOGIC_PLAN_AGG: { case QUERY_NODE_LOGIC_PLAN_AGG: {
SAggLogicNode* pLogicNode = (SAggLogicNode*)pNode; SAggLogicNode* pLogicNode = (SAggLogicNode*)pNode;
destroyLogicNode((SLogicNode*)pLogicNode); destroyLogicNode((SLogicNode*)pLogicNode);
@ -1828,6 +1882,9 @@ void nodesDestroyNode(SNode* pNode) {
case QUERY_NODE_LOGIC_PLAN_DYN_QUERY_CTRL: { case QUERY_NODE_LOGIC_PLAN_DYN_QUERY_CTRL: {
SDynQueryCtrlLogicNode* pLogicNode = (SDynQueryCtrlLogicNode*)pNode; SDynQueryCtrlLogicNode* pLogicNode = (SDynQueryCtrlLogicNode*)pNode;
destroyLogicNode((SLogicNode*)pLogicNode); destroyLogicNode((SLogicNode*)pLogicNode);
if (pLogicNode->qType == DYN_QTYPE_VTB_SCAN) {
taosMemoryFreeClear(pLogicNode->vtbScan.pVgroupList);
}
break; break;
} }
case QUERY_NODE_LOGIC_SUBPLAN: { case QUERY_NODE_LOGIC_SUBPLAN: {
@ -1846,6 +1903,13 @@ void nodesDestroyNode(SNode* pNode) {
case QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN: case QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN:
destroyScanPhysiNode((SScanPhysiNode*)pNode); destroyScanPhysiNode((SScanPhysiNode*)pNode);
break; break;
case QUERY_NODE_PHYSICAL_PLAN_VIRTUAL_TABLE_SCAN: {
SVirtualScanPhysiNode* pPhyNode = (SVirtualScanPhysiNode*)pNode;
destroyScanPhysiNode((SScanPhysiNode*)pNode);
nodesDestroyList(pPhyNode->pGroupTags);
nodesDestroyList(pPhyNode->pTargets);
break;
}
case QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN: case QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN:
case QUERY_NODE_PHYSICAL_PLAN_TABLE_COUNT_SCAN: { case QUERY_NODE_PHYSICAL_PLAN_TABLE_COUNT_SCAN: {
SLastRowScanPhysiNode* pPhyNode = (SLastRowScanPhysiNode*)pNode; SLastRowScanPhysiNode* pPhyNode = (SLastRowScanPhysiNode*)pNode;
@ -2066,6 +2130,9 @@ void nodesDestroyNode(SNode* pNode) {
} }
case QUERY_NODE_PHYSICAL_PLAN_DYN_QUERY_CTRL: { case QUERY_NODE_PHYSICAL_PLAN_DYN_QUERY_CTRL: {
SDynQueryCtrlPhysiNode* pPhyNode = (SDynQueryCtrlPhysiNode*)pNode; SDynQueryCtrlPhysiNode* pPhyNode = (SDynQueryCtrlPhysiNode*)pNode;
if (pPhyNode->qType == DYN_QTYPE_VTB_SCAN) {
nodesDestroyList(pPhyNode->vtbScan.pScanCols);
}
destroyPhysiNode((SPhysiNode*)pPhyNode); destroyPhysiNode((SPhysiNode*)pPhyNode);
break; break;
} }

View File

@ -83,7 +83,8 @@ typedef enum ETableOptionType {
TABLE_OPTION_TTL, TABLE_OPTION_TTL,
TABLE_OPTION_SMA, TABLE_OPTION_SMA,
TABLE_OPTION_DELETE_MARK, TABLE_OPTION_DELETE_MARK,
TABLE_OPTION_KEEP TABLE_OPTION_KEEP,
TABLE_OPTION_VIRTUAL
} ETableOptionType; } ETableOptionType;
typedef enum EColumnOptionType { typedef enum EColumnOptionType {
@ -105,6 +106,12 @@ typedef struct STokenPair {
SToken second; SToken second;
} STokenPair; } STokenPair;
typedef struct STokenTriplet {
ENodeType type;
int32_t numOfName;
SToken name[3];
} STokenTriplet;
typedef struct SShowTablesOption { typedef struct SShowTablesOption {
EShowKind kind; EShowKind kind;
SToken dbName; SToken dbName;
@ -210,20 +217,31 @@ SNode* createCompactVgroupsStmt(SAstCreateContext* pCxt, SNode* pDbName, SNodeLi
SNode* createDefaultTableOptions(SAstCreateContext* pCxt); SNode* createDefaultTableOptions(SAstCreateContext* pCxt);
SNode* createAlterTableOptions(SAstCreateContext* pCxt); SNode* createAlterTableOptions(SAstCreateContext* pCxt);
SNode* setTableOption(SAstCreateContext* pCxt, SNode* pOptions, ETableOptionType type, void* pVal); SNode* setTableOption(SAstCreateContext* pCxt, SNode* pOptions, ETableOptionType type, void* pVal);
STokenTriplet* createTokenTriplet(SAstCreateContext* pCxt, SToken pName);
STokenTriplet* setColumnName(SAstCreateContext* pCxt, STokenTriplet* pTokenTri, SToken pName);
SNode* createColumnRefNodeByName(SAstCreateContext* pCxt, STokenTriplet* pTokenTri);
SNode* createColumnRefNodeByNode(SAstCreateContext* pCxt, SToken* pColName, SNode* pRef);
SNode* createColumnDefNode(SAstCreateContext* pCxt, SToken* pColName, SDataType dataType, SNode* pOptions); SNode* createColumnDefNode(SAstCreateContext* pCxt, SToken* pColName, SDataType dataType, SNode* pOptions);
SNode* setColumnOptions(SAstCreateContext* pCxt, SNode* pOptions, const SToken* pVal1, void* pVal2); SNode* setColumnOptions(SAstCreateContext* pCxt, SNode* pOptions, const SToken* pVal1, void* pVal2);
SNode* setColumnOptionsPK(SAstCreateContext* pCxt, SNode* pOptions); SNode* setColumnOptionsPK(SAstCreateContext* pCxt, SNode* pOptions);
SNode* setColumnReference(SAstCreateContext* pCxt, SNode* pOptions, SNode* pRef);
SNode* createDefaultColumnOptions(SAstCreateContext* pCxt); SNode* createDefaultColumnOptions(SAstCreateContext* pCxt);
SNode* createCreateTableStmt(SAstCreateContext* pCxt, bool ignoreExists, SNode* pRealTable, SNodeList* pCols, SNode* createCreateTableStmt(SAstCreateContext* pCxt, bool ignoreExists, SNode* pRealTable, SNodeList* pCols,
SNodeList* pTags, SNode* pOptions); SNodeList* pTags, SNode* pOptions);
SNode* createCreateSubTableClause(SAstCreateContext* pCxt, bool ignoreExists, SNode* pRealTable, SNode* pUseRealTable, SNode* createCreateSubTableClause(SAstCreateContext* pCxt, bool ignoreExists, SNode* pRealTable, SNode* pUseRealTable,
SNodeList* pSpecificTags, SNodeList* pValsOfTags, SNode* pOptions); SNodeList* pSpecificTags, SNodeList* pValsOfTags, SNode* pOptions);
SNode* createCreateVTableStmt(SAstCreateContext* pCxt, bool ignoreExists, SNode* pRealTable, SNodeList* pCols);
SNode* createCreateVSubTableStmt(SAstCreateContext* pCxt, bool ignoreExists, SNode* pRealTable,
SNodeList* pSpecificColRefs, SNodeList* pColRefs, SNode* pUseRealTable,
SNodeList* pSpecificTags, SNodeList* pValsOfTags);
SNode* createCreateSubTableFromFileClause(SAstCreateContext* pCxt, bool ignoreExists, SNode* pUseRealTable, SNode* createCreateSubTableFromFileClause(SAstCreateContext* pCxt, bool ignoreExists, SNode* pUseRealTable,
SNodeList* pSpecificTags, const SToken* pFilePath); SNodeList* pSpecificTags, const SToken* pFilePath);
SNode* createCreateMultiTableStmt(SAstCreateContext* pCxt, SNodeList* pSubTables); SNode* createCreateMultiTableStmt(SAstCreateContext* pCxt, SNodeList* pSubTables);
SNode* createDropTableClause(SAstCreateContext* pCxt, bool ignoreNotExists, SNode* pRealTable); SNode* createDropTableClause(SAstCreateContext* pCxt, bool ignoreNotExists, SNode* pRealTable);
SNode* createDropTableStmt(SAstCreateContext* pCxt, bool withOpt, SNodeList* pTables); SNode* createDropTableStmt(SAstCreateContext* pCxt, bool withOpt, SNodeList* pTables);
SNode* createDropSuperTableStmt(SAstCreateContext* pCxt, bool withOpt, bool ignoreNotExists, SNode* pRealTable); SNode* createDropSuperTableStmt(SAstCreateContext* pCxt, bool withOpt, bool ignoreNotExists, SNode* pRealTable);
SNode* createDropVirtualTableStmt(SAstCreateContext* pCxt, bool withOpt, bool ignoreNotExists, SNode* pRealTable);
SNode* createAlterTableModifyOptions(SAstCreateContext* pCxt, SNode* pRealTable, SNode* pOptions); SNode* createAlterTableModifyOptions(SAstCreateContext* pCxt, SNode* pRealTable, SNode* pOptions);
SNode* createAlterTableAddModifyCol(SAstCreateContext* pCxt, SNode* pRealTable, int8_t alterType, SToken* pColName, SNode* createAlterTableAddModifyCol(SAstCreateContext* pCxt, SNode* pRealTable, int8_t alterType, SToken* pColName,
SDataType dataType); SDataType dataType);
@ -236,9 +254,14 @@ SNode* createAlterTableAddModifyColOptions(SAstCreateContext* pCxt, SNode* pReal
SNode* createAlterTableDropCol(SAstCreateContext* pCxt, SNode* pRealTable, int8_t alterType, SToken* pColName); SNode* createAlterTableDropCol(SAstCreateContext* pCxt, SNode* pRealTable, int8_t alterType, SToken* pColName);
SNode* createAlterTableRenameCol(SAstCreateContext* pCxt, SNode* pRealTable, int8_t alterType, SToken* pOldColName, SNode* createAlterTableRenameCol(SAstCreateContext* pCxt, SNode* pRealTable, int8_t alterType, SToken* pOldColName,
SToken* pNewColName); SToken* pNewColName);
SNode* createAlterTableAlterColRef(SAstCreateContext* pCxt, SNode* pRealTable, int8_t alterType, SToken* pColName,
SNode* pRef);
SNode* createAlterTableRemoveColRef(SAstCreateContext* pCxt, SNode* pRealTable, int8_t alterType, SToken* pColName,
const SToken* pLiteral);
SNode* createAlterTableSetTag(SAstCreateContext* pCxt, SNode* pRealTable, SToken* pTagName, SNode* pVal); SNode* createAlterTableSetTag(SAstCreateContext* pCxt, SNode* pRealTable, SToken* pTagName, SNode* pVal);
SNode* createAlterTableSetMultiTagValue(SAstCreateContext* pCxt, SNode* pRealTable, SNodeList* singleNode); SNode* createAlterTableSetMultiTagValue(SAstCreateContext* pCxt, SNode* pRealTable, SNodeList* singleNode);
SNode* setAlterSuperTableType(SNode* pStmt); SNode* setAlterSuperTableType(SNode* pStmt);
SNode* setAlterVirtualTableType(SNode* pStmt);
SNode* createUseDatabaseStmt(SAstCreateContext* pCxt, SToken* pDbName); SNode* createUseDatabaseStmt(SAstCreateContext* pCxt, SToken* pDbName);
SNode* setShowKind(SAstCreateContext* pCxt, SNode* pStmt, EShowKind showKind); SNode* setShowKind(SAstCreateContext* pCxt, SNode* pStmt, EShowKind showKind);
SNode* createShowStmt(SAstCreateContext* pCxt, ENodeType type); SNode* createShowStmt(SAstCreateContext* pCxt, ENodeType type);
@ -248,9 +271,14 @@ SNode* createShowStmtWithCond(SAstCreateContext* pCxt, ENodeType type, SNode* pD
EOperatorType tableCondType); EOperatorType tableCondType);
SNode* createShowTablesStmt(SAstCreateContext* pCxt, SShowTablesOption option, SNode* pTbName, SNode* createShowTablesStmt(SAstCreateContext* pCxt, SShowTablesOption option, SNode* pTbName,
EOperatorType tableCondType); EOperatorType tableCondType);
SNode* createShowVTablesStmt(SAstCreateContext* pCxt, SShowTablesOption option, SNode* pTbName,
EOperatorType tableCondType);
SNode* createShowSTablesStmt(SAstCreateContext* pCxt, SShowTablesOption option, SNode* pTbName,
EOperatorType tableCondType);
SNode* createShowCreateDatabaseStmt(SAstCreateContext* pCxt, SToken* pDbName); SNode* createShowCreateDatabaseStmt(SAstCreateContext* pCxt, SToken* pDbName);
SNode* createShowAliveStmt(SAstCreateContext* pCxt, SNode* pDbName, ENodeType type); SNode* createShowAliveStmt(SAstCreateContext* pCxt, SNode* pDbName, ENodeType type);
SNode* createShowCreateTableStmt(SAstCreateContext* pCxt, ENodeType type, SNode* pRealTable); SNode* createShowCreateTableStmt(SAstCreateContext* pCxt, ENodeType type, SNode* pRealTable);
SNode* createShowCreateVTableStmt(SAstCreateContext* pCxt, ENodeType type, SNode* pRealTable);
SNode* createShowCreateViewStmt(SAstCreateContext* pCxt, ENodeType type, SNode* pRealTable); SNode* createShowCreateViewStmt(SAstCreateContext* pCxt, ENodeType type, SNode* pRealTable);
SNode* createShowTableDistributedStmt(SAstCreateContext* pCxt, SNode* pRealTable); SNode* createShowTableDistributedStmt(SAstCreateContext* pCxt, SNode* pRealTable);
SNode* createShowDnodeVariablesStmt(SAstCreateContext* pCxt, SNode* pDnodeId, SNode* pLikePattern); SNode* createShowDnodeVariablesStmt(SAstCreateContext* pCxt, SNode* pDnodeId, SNode* pLikePattern);

View File

@ -48,6 +48,7 @@ typedef struct STranslateContext {
SNode* pPostRoot; SNode* pPostRoot;
bool dual; // whether select stmt without from stmt, true for without. bool dual; // whether select stmt without from stmt, true for without.
bool skipCheck; bool skipCheck;
bool refTable;
} STranslateContext; } STranslateContext;
int32_t biRewriteToTbnameFunc(STranslateContext* pCxt, SNode** ppNode, bool* pRet); int32_t biRewriteToTbnameFunc(STranslateContext* pCxt, SNode** ppNode, bool* pRet);

View File

@ -403,11 +403,23 @@ cmd ::= CREATE TABLE not_exists_opt(B) USING full_table_name(C)
NK_LP tag_list_opt(D) NK_RP FILE NK_STRING(E). { pCxt->pRootNode = createCreateSubTableFromFileClause(pCxt, B, C, D, &E); } NK_LP tag_list_opt(D) NK_RP FILE NK_STRING(E). { pCxt->pRootNode = createCreateSubTableFromFileClause(pCxt, B, C, D, &E); }
cmd ::= CREATE STABLE not_exists_opt(A) full_table_name(B) cmd ::= CREATE STABLE not_exists_opt(A) full_table_name(B)
NK_LP column_def_list(C) NK_RP tags_def(D) table_options(E). { pCxt->pRootNode = createCreateTableStmt(pCxt, A, B, C, D, E); } NK_LP column_def_list(C) NK_RP tags_def(D) table_options(E). { pCxt->pRootNode = createCreateTableStmt(pCxt, A, B, C, D, E); }
cmd ::= CREATE VTABLE not_exists_opt(A) full_table_name(B)
NK_LP column_def_list(C) NK_RP. { pCxt->pRootNode = createCreateVTableStmt(pCxt, A, B, C); }
cmd ::= CREATE VTABLE not_exists_opt(A) full_table_name(B)
NK_LP specific_column_ref_list(C) NK_RP USING full_table_name(D)
specific_cols_opt(E) TAGS NK_LP tags_literal_list(F) NK_RP. { pCxt->pRootNode = createCreateVSubTableStmt(pCxt, A, B, C, NULL, D, E, F); }
cmd ::= CREATE VTABLE not_exists_opt(A) full_table_name(B)
NK_LP column_ref_list(C) NK_RP USING full_table_name(D)
specific_cols_opt(E) TAGS NK_LP tags_literal_list(F) NK_RP. { pCxt->pRootNode = createCreateVSubTableStmt(pCxt, A, B, NULL, C, D, E, F); }
cmd ::= CREATE VTABLE not_exists_opt(A) full_table_name(B) USING full_table_name(C)
specific_cols_opt(D) TAGS NK_LP tags_literal_list(E) NK_RP. { pCxt->pRootNode = createCreateVSubTableStmt(pCxt, A, B, NULL, NULL, C, D, E); }
cmd ::= DROP TABLE with_opt(A) multi_drop_clause(B). { pCxt->pRootNode = createDropTableStmt(pCxt, A, B); } cmd ::= DROP TABLE with_opt(A) multi_drop_clause(B). { pCxt->pRootNode = createDropTableStmt(pCxt, A, B); }
cmd ::= DROP STABLE with_opt(A) exists_opt(B) full_table_name(C). { pCxt->pRootNode = createDropSuperTableStmt(pCxt, A, B, C); } cmd ::= DROP STABLE with_opt(A) exists_opt(B) full_table_name(C). { pCxt->pRootNode = createDropSuperTableStmt(pCxt, A, B, C); }
cmd ::= DROP VTABLE with_opt(A) exists_opt(B) full_table_name(C). { pCxt->pRootNode = createDropVirtualTableStmt(pCxt, A, B, C); }
cmd ::= ALTER TABLE alter_table_clause(A). { pCxt->pRootNode = A; } cmd ::= ALTER TABLE alter_table_clause(A). { pCxt->pRootNode = A; }
cmd ::= ALTER STABLE alter_table_clause(A). { pCxt->pRootNode = setAlterSuperTableType(A); } cmd ::= ALTER STABLE alter_table_clause(A). { pCxt->pRootNode = setAlterSuperTableType(A); }
cmd ::= ALTER VTABLE alter_table_clause(A). { pCxt->pRootNode = setAlterVirtualTableType(A); }
alter_table_clause(A) ::= full_table_name(B) alter_table_options(C). { A = createAlterTableModifyOptions(pCxt, B, C); } alter_table_clause(A) ::= full_table_name(B) alter_table_options(C). { A = createAlterTableModifyOptions(pCxt, B, C); }
@ -427,7 +439,12 @@ alter_table_clause(A) ::=
full_table_name(B) MODIFY TAG column_name(C) type_name(D). { A = createAlterTableAddModifyCol(pCxt, B, TSDB_ALTER_TABLE_UPDATE_TAG_BYTES, &C, D); } full_table_name(B) MODIFY TAG column_name(C) type_name(D). { A = createAlterTableAddModifyCol(pCxt, B, TSDB_ALTER_TABLE_UPDATE_TAG_BYTES, &C, D); }
alter_table_clause(A) ::= alter_table_clause(A) ::=
full_table_name(B) RENAME TAG column_name(C) column_name(D). { A = createAlterTableRenameCol(pCxt, B, TSDB_ALTER_TABLE_UPDATE_TAG_NAME, &C, &D); } full_table_name(B) RENAME TAG column_name(C) column_name(D). { A = createAlterTableRenameCol(pCxt, B, TSDB_ALTER_TABLE_UPDATE_TAG_NAME, &C, &D); }
alter_table_clause(A) ::=
full_table_name(B) ALTER COLUMN column_name(C) SET column_ref(D).
{ A = createAlterTableAlterColRef(pCxt, B, TSDB_ALTER_TABLE_ALTER_COLUMN_REF, &C, D); }
alter_table_clause(A) ::=
full_table_name(B) ALTER COLUMN column_name(C) SET NULL(D). { A = createAlterTableRemoveColRef(pCxt, B, TSDB_ALTER_TABLE_REMOVE_COLUMN_REF, &C, &D); }
%type column_tag_value_list { SNodeList* } %type column_tag_value_list { SNodeList* }
%destructor column_tag_value_list { nodesDestroyList($$); } %destructor column_tag_value_list { nodesDestroyList($$); }
@ -481,6 +498,18 @@ column_def_list(A) ::= column_def_list(B) NK_COMMA column_def(C).
// column_def(A) ::= column_name(B) type_name(C). { A = createColumnDefNode(pCxt, &B, C, NULL); } // column_def(A) ::= column_name(B) type_name(C). { A = createColumnDefNode(pCxt, &B, C, NULL); }
column_def(A) ::= column_name(B) type_name(C) column_options(D). { A = createColumnDefNode(pCxt, &B, C, D); } column_def(A) ::= column_name(B) type_name(C) column_options(D). { A = createColumnDefNode(pCxt, &B, C, D); }
%type specific_column_ref_list { SNodeList* }
%destructor specific_column_ref_list { nodesDestroyList($$); }
specific_column_ref_list(A) ::= specific_column_ref(B). { A = createNodeList(pCxt, B); }
specific_column_ref_list(A) ::= specific_column_ref_list(B) NK_COMMA specific_column_ref(C). { A = addNodeToList(pCxt, B, C); }
specific_column_ref(A) ::= column_name(B) FROM column_ref(C). { A = createColumnRefNodeByNode(pCxt, &B, C); }
%type column_ref_list { SNodeList* }
%destructor column_ref_list { nodesDestroyList($$); }
column_ref_list(A) ::= column_ref(B). { A = createNodeList(pCxt, B); }
column_ref_list(A) ::= column_ref_list(B) NK_COMMA column_ref(C). { A = addNodeToList(pCxt, B, C); }
%type type_name { SDataType } %type type_name { SDataType }
%destructor type_name { } %destructor type_name { }
type_name(A) ::= BOOL. { A = createDataType(TSDB_DATA_TYPE_BOOL); } type_name(A) ::= BOOL. { A = createDataType(TSDB_DATA_TYPE_BOOL); }
@ -534,6 +563,7 @@ table_options(A) ::= table_options(B) SMA NK_LP col_name_list(C) NK_RP.
table_options(A) ::= table_options(B) DELETE_MARK duration_list(C). { A = setTableOption(pCxt, B, TABLE_OPTION_DELETE_MARK, C); } table_options(A) ::= table_options(B) DELETE_MARK duration_list(C). { A = setTableOption(pCxt, B, TABLE_OPTION_DELETE_MARK, C); }
table_options(A) ::= table_options(B) KEEP NK_INTEGER(C). { A = setTableOption(pCxt, B, TABLE_OPTION_KEEP, &C); } table_options(A) ::= table_options(B) KEEP NK_INTEGER(C). { A = setTableOption(pCxt, B, TABLE_OPTION_KEEP, &C); }
table_options(A) ::= table_options(B) KEEP NK_VARIABLE(C). { A = setTableOption(pCxt, B, TABLE_OPTION_KEEP, &C); } table_options(A) ::= table_options(B) KEEP NK_VARIABLE(C). { A = setTableOption(pCxt, B, TABLE_OPTION_KEEP, &C); }
table_options(A) ::= table_options(B) VIRTUAL NK_INTEGER(C). { A = setTableOption(pCxt, B, TABLE_OPTION_VIRTUAL, &C); }
alter_table_options(A) ::= alter_table_option(B). { A = createAlterTableOptions(pCxt); A = setTableOption(pCxt, A, B.type, &B.val); } alter_table_options(A) ::= alter_table_option(B). { A = createAlterTableOptions(pCxt); A = setTableOption(pCxt, A, B.type, &B.val); }
alter_table_options(A) ::= alter_table_options(B) alter_table_option(C). { A = setTableOption(pCxt, B, C.type, &C.val); } alter_table_options(A) ::= alter_table_options(B) alter_table_option(C). { A = setTableOption(pCxt, B, C.type, &C.val); }
@ -579,7 +609,12 @@ cmd ::= SHOW db_kind_opt(A) DATABASES.
cmd ::= SHOW table_kind_db_name_cond_opt(A) TABLES like_pattern_opt(B). { cmd ::= SHOW table_kind_db_name_cond_opt(A) TABLES like_pattern_opt(B). {
pCxt->pRootNode = createShowTablesStmt(pCxt, A, B, OP_TYPE_LIKE); pCxt->pRootNode = createShowTablesStmt(pCxt, A, B, OP_TYPE_LIKE);
} }
cmd ::= SHOW db_name_cond_opt(A) STABLES like_pattern_opt(B). { pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_STABLES_STMT, A, B, OP_TYPE_LIKE); } cmd ::= SHOW table_kind_db_name_cond_opt(A) VTABLES like_pattern_opt(B). {
pCxt->pRootNode = createShowVTablesStmt(pCxt, A, B, OP_TYPE_LIKE);
}
cmd ::= SHOW table_kind_db_name_cond_opt(A) STABLES like_pattern_opt(B). {
pCxt->pRootNode = createShowSTablesStmt(pCxt, A, B, OP_TYPE_LIKE);
}
cmd ::= SHOW db_name_cond_opt(A) VGROUPS. { pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_VGROUPS_STMT, A, NULL, OP_TYPE_LIKE); } cmd ::= SHOW db_name_cond_opt(A) VGROUPS. { pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_VGROUPS_STMT, A, NULL, OP_TYPE_LIKE); }
cmd ::= SHOW MNODES. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_MNODES_STMT); } cmd ::= SHOW MNODES. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_MNODES_STMT); }
//cmd ::= SHOW MODULES. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_MODULES_STMT); } //cmd ::= SHOW MODULES. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_MODULES_STMT); }
@ -601,6 +636,7 @@ cmd ::= SHOW GRANTS LOGS.
cmd ::= SHOW CLUSTER MACHINES. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_CLUSTER_MACHINES_STMT); } cmd ::= SHOW CLUSTER MACHINES. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_CLUSTER_MACHINES_STMT); }
cmd ::= SHOW CREATE DATABASE db_name(A). { pCxt->pRootNode = createShowCreateDatabaseStmt(pCxt, &A); } cmd ::= SHOW CREATE DATABASE db_name(A). { pCxt->pRootNode = createShowCreateDatabaseStmt(pCxt, &A); }
cmd ::= SHOW CREATE TABLE full_table_name(A). { pCxt->pRootNode = createShowCreateTableStmt(pCxt, QUERY_NODE_SHOW_CREATE_TABLE_STMT, A); } cmd ::= SHOW CREATE TABLE full_table_name(A). { pCxt->pRootNode = createShowCreateTableStmt(pCxt, QUERY_NODE_SHOW_CREATE_TABLE_STMT, A); }
cmd ::= SHOW CREATE VTABLE full_table_name(A). { pCxt->pRootNode = createShowCreateVTableStmt(pCxt, QUERY_NODE_SHOW_CREATE_VTABLE_STMT, A); }
cmd ::= SHOW CREATE STABLE full_table_name(A). { pCxt->pRootNode = createShowCreateTableStmt(pCxt, QUERY_NODE_SHOW_CREATE_STABLE_STMT, cmd ::= SHOW CREATE STABLE full_table_name(A). { pCxt->pRootNode = createShowCreateTableStmt(pCxt, QUERY_NODE_SHOW_CREATE_STABLE_STMT,
A); } A); }
cmd ::= SHOW ENCRYPTIONS. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_ENCRYPTIONS_STMT); } cmd ::= SHOW ENCRYPTIONS. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_ENCRYPTIONS_STMT); }
@ -645,6 +681,7 @@ table_kind_db_name_cond_opt(A) ::= table_kind(B) db_name(C) NK_DOT.
%destructor table_kind { } %destructor table_kind { }
table_kind(A) ::= NORMAL. { A = SHOW_KIND_TABLES_NORMAL; } table_kind(A) ::= NORMAL. { A = SHOW_KIND_TABLES_NORMAL; }
table_kind(A) ::= CHILD. { A = SHOW_KIND_TABLES_CHILD; } table_kind(A) ::= CHILD. { A = SHOW_KIND_TABLES_CHILD; }
table_kind(A) ::= VIRTUAL. { A = SHOW_KIND_TABLES_VIRTUAL; }
db_name_cond_opt(A) ::= . { A = createDefaultDatabaseCondValue(pCxt); } db_name_cond_opt(A) ::= . { A = createDefaultDatabaseCondValue(pCxt); }
db_name_cond_opt(A) ::= db_name(B) NK_DOT. { A = createIdentifierValueNode(pCxt, &B); } db_name_cond_opt(A) ::= db_name(B) NK_DOT. { A = createIdentifierValueNode(pCxt, &B); }
@ -1834,3 +1871,11 @@ null_ordering_opt(A) ::= NULLS LAST.
column_options(A) ::= . { A = createDefaultColumnOptions(pCxt); } column_options(A) ::= . { A = createDefaultColumnOptions(pCxt); }
column_options(A) ::= column_options(B) PRIMARY KEY. { A = setColumnOptionsPK(pCxt, B); } column_options(A) ::= column_options(B) PRIMARY KEY. { A = setColumnOptionsPK(pCxt, B); }
column_options(A) ::= column_options(B) NK_ID(C) NK_STRING(D). { A = setColumnOptions(pCxt, B, &C, &D); } column_options(A) ::= column_options(B) NK_ID(C) NK_STRING(D). { A = setColumnOptions(pCxt, B, &C, &D); }
column_options(A) ::= column_options(B) FROM column_ref(C). { A = setColumnReference(pCxt, B, C); }
column_ref(A) ::= column_name_list(B). { A = createColumnRefNodeByName(pCxt, B); }
%type column_name_list { STokenTriplet* }
%destructor column_name_list { }
column_name_list(A) ::= NK_ID(B). { A = createTokenTriplet(pCxt, B); }
column_name_list(A) ::= column_name_list(B) NK_DOT NK_ID(C). { A = setColumnName(pCxt, B, C); }

View File

@ -2380,6 +2380,15 @@ SNode* setTableOption(SAstCreateContext* pCxt, SNode* pOptions, ETableOptionType
((STableOptions*)pOptions)->pKeepNode = (SValueNode*)createDurationValueNode(pCxt, (SToken*)pVal); ((STableOptions*)pOptions)->pKeepNode = (SValueNode*)createDurationValueNode(pCxt, (SToken*)pVal);
} }
break; break;
case TABLE_OPTION_VIRTUAL: {
int64_t virtualStb = taosStr2Int64(((SToken*)pVal)->z, NULL, 10);
if (virtualStb != 0 && virtualStb != 1) {
pCxt->errCode = TSDB_CODE_TSC_VALUE_OUT_OF_RANGE;
} else {
((STableOptions*)pOptions)->virtualStb = virtualStb;
}
break;
}
default: default:
break; break;
} }
@ -2396,6 +2405,7 @@ SNode* createDefaultColumnOptions(SAstCreateContext* pCxt) {
CHECK_MAKE_NODE(pOptions); CHECK_MAKE_NODE(pOptions);
pOptions->commentNull = true; pOptions->commentNull = true;
pOptions->bPrimaryKey = false; pOptions->bPrimaryKey = false;
pOptions->hasRef = false;
return (SNode*)pOptions; return (SNode*)pOptions;
_err: _err:
return NULL; return NULL;
@ -2411,6 +2421,20 @@ EColumnOptionType getColumnOptionType(const char* optionType) {
} }
return 0; return 0;
} }
SNode* setColumnReference(SAstCreateContext* pCxt, SNode* pOptions, SNode* pRef) {
CHECK_PARSER_STATUS(pCxt);
((SColumnOptions*)pOptions)->hasRef = true;
tstrncpy(((SColumnOptions*)pOptions)->refDb, ((SColumnRefNode*)pRef)->refDbName, TSDB_DB_NAME_LEN);
tstrncpy(((SColumnOptions*)pOptions)->refTable, ((SColumnRefNode*)pRef)->refTableName, TSDB_TABLE_NAME_LEN);
tstrncpy(((SColumnOptions*)pOptions)->refColumn, ((SColumnRefNode*)pRef)->refColName, TSDB_COL_NAME_LEN);
return pOptions;
_err:
nodesDestroyNode(pOptions);
return NULL;
}
SNode* setColumnOptionsPK(SAstCreateContext* pCxt, SNode* pOptions) { SNode* setColumnOptionsPK(SAstCreateContext* pCxt, SNode* pOptions) {
CHECK_PARSER_STATUS(pCxt); CHECK_PARSER_STATUS(pCxt);
((SColumnOptions*)pOptions)->bPrimaryKey = true; ((SColumnOptions*)pOptions)->bPrimaryKey = true;
@ -2463,6 +2487,90 @@ _err:
return NULL; return NULL;
} }
SNode* createColumnRefNodeByNode(SAstCreateContext* pCxt, SToken* pColName, SNode* pRef) {
CHECK_PARSER_STATUS(pCxt);
CHECK_NAME(checkColumnName(pCxt, pColName));
SColumnRefNode* pCol = NULL;
pCxt->errCode = nodesMakeNode(QUERY_NODE_COLUMN_REF, (SNode**)&pCol);
CHECK_MAKE_NODE(pCol);
if (pColName) {
COPY_STRING_FORM_ID_TOKEN(pCol->colName, pColName);
}
tstrncpy(pCol->refDbName, ((SColumnRefNode*)pRef)->refDbName, TSDB_DB_NAME_LEN);
tstrncpy(pCol->refTableName, ((SColumnRefNode*)pRef)->refTableName, TSDB_TABLE_NAME_LEN);
tstrncpy(pCol->refColName, ((SColumnRefNode*)pRef)->refColName, TSDB_COL_NAME_LEN);
return (SNode*)pCol;
_err:
return NULL;
}
STokenTriplet* createTokenTriplet(SAstCreateContext* pCxt, SToken pName) {
CHECK_PARSER_STATUS(pCxt);
STokenTriplet *pTokenTri = taosMemoryMalloc(sizeof(STokenTriplet));
CHECK_OUT_OF_MEM(pTokenTri);
pTokenTri->name[0] = pName;
pTokenTri->numOfName = 1;
return pTokenTri;
_err:
return NULL;
}
STokenTriplet* setColumnName(SAstCreateContext* pCxt, STokenTriplet* pTokenTri, SToken pName) {
CHECK_PARSER_STATUS(pCxt);
if (pTokenTri->numOfName >= 3) {
pCxt->errCode = TSDB_CODE_PAR_SYNTAX_ERROR;
goto _err;
}
pTokenTri->name[pTokenTri->numOfName] = pName;
pTokenTri->numOfName++;
return pTokenTri;
_err:
return NULL;
}
SNode* createColumnRefNodeByName(SAstCreateContext* pCxt, STokenTriplet* pTokenTri) {
SColumnRefNode* pCol = NULL;
CHECK_PARSER_STATUS(pCxt);
pCxt->errCode = nodesMakeNode(QUERY_NODE_COLUMN_REF, (SNode**)&pCol);
CHECK_MAKE_NODE(pCol);
switch(pTokenTri->numOfName) {
case 2: {
CHECK_NAME(checkTableName(pCxt, &pTokenTri->name[0]));
CHECK_NAME(checkColumnName(pCxt, &pTokenTri->name[1]));
snprintf(pCol->refDbName, TSDB_DB_NAME_LEN, "%s", pCxt->pQueryCxt->db);
COPY_STRING_FORM_ID_TOKEN(pCol->refTableName, &pTokenTri->name[0]);
COPY_STRING_FORM_ID_TOKEN(pCol->refColName, &pTokenTri->name[1]);
break;
}
case 3: {
CHECK_NAME(checkDbName(pCxt, &pTokenTri->name[0], true));
CHECK_NAME(checkTableName(pCxt, &pTokenTri->name[1]));
CHECK_NAME(checkColumnName(pCxt, &pTokenTri->name[2]));
COPY_STRING_FORM_ID_TOKEN(pCol->refDbName, &pTokenTri->name[0]);
COPY_STRING_FORM_ID_TOKEN(pCol->refTableName, &pTokenTri->name[1]);
COPY_STRING_FORM_ID_TOKEN(pCol->refColName, &pTokenTri->name[2]);
break;
}
default: {
pCxt->errCode = TSDB_CODE_PAR_SYNTAX_ERROR;
goto _err;
}
}
taosMemFree(pTokenTri);
return (SNode*)pCol;
_err:
taosMemFree(pTokenTri);
nodesDestroyNode((SNode*)pCol);
return NULL;
}
SNode* createColumnDefNode(SAstCreateContext* pCxt, SToken* pColName, SDataType dataType, SNode* pNode) { SNode* createColumnDefNode(SAstCreateContext* pCxt, SToken* pColName, SDataType dataType, SNode* pNode) {
CHECK_PARSER_STATUS(pCxt); CHECK_PARSER_STATUS(pCxt);
CHECK_NAME(checkColumnName(pCxt, pColName)); CHECK_NAME(checkColumnName(pCxt, pColName));
@ -2505,6 +2613,52 @@ SDataType createDecimalDataType(uint8_t type, const SToken* pPrecisionToken, con
return dt; return dt;
} }
SNode* createCreateVTableStmt(SAstCreateContext* pCxt, bool ignoreExists, SNode* pRealTable, SNodeList* pCols) {
SCreateVTableStmt * pStmt = NULL;
CHECK_PARSER_STATUS(pCxt);
pCxt->errCode = nodesMakeNode(QUERY_NODE_CREATE_VIRTUAL_TABLE_STMT, (SNode**)&pStmt);
CHECK_MAKE_NODE(pStmt);
strcpy(pStmt->dbName, ((SRealTableNode*)pRealTable)->table.dbName);
strcpy(pStmt->tableName, ((SRealTableNode*)pRealTable)->table.tableName);
pStmt->ignoreExists = ignoreExists;
pStmt->pCols = pCols;
nodesDestroyNode(pRealTable);
return (SNode*)pStmt;
_err:
nodesDestroyNode(pRealTable);
nodesDestroyList(pCols);
return NULL;
}
SNode* createCreateVSubTableStmt(SAstCreateContext* pCxt, bool ignoreExists, SNode* pRealTable,
SNodeList* pSpecificColRefs, SNodeList* pColRefs, SNode* pUseRealTable,
SNodeList* pSpecificTags, SNodeList* pValsOfTags) {
CHECK_PARSER_STATUS(pCxt);
SCreateVSubTableStmt* pStmt = NULL;
pCxt->errCode = nodesMakeNode(QUERY_NODE_CREATE_VIRTUAL_SUBTABLE_STMT, (SNode**)&pStmt);
CHECK_MAKE_NODE(pStmt);
strcpy(pStmt->dbName, ((SRealTableNode*)pRealTable)->table.dbName);
strcpy(pStmt->tableName, ((SRealTableNode*)pRealTable)->table.tableName);
strcpy(pStmt->useDbName, ((SRealTableNode*)pUseRealTable)->table.dbName);
strcpy(pStmt->useTableName, ((SRealTableNode*)pUseRealTable)->table.tableName);
pStmt->ignoreExists = ignoreExists;
pStmt->pSpecificTags = pSpecificTags;
pStmt->pValsOfTags = pValsOfTags;
pStmt->pSpecificColRefs = pSpecificColRefs;
pStmt->pColRefs = pColRefs;
nodesDestroyNode(pRealTable);
nodesDestroyNode(pUseRealTable);
return (SNode*)pStmt;
_err:
nodesDestroyNode(pRealTable);
nodesDestroyNode(pUseRealTable);
nodesDestroyList(pSpecificTags);
nodesDestroyList(pValsOfTags);
nodesDestroyList(pSpecificColRefs);
nodesDestroyList(pColRefs);
return NULL;
}
SNode* createCreateTableStmt(SAstCreateContext* pCxt, bool ignoreExists, SNode* pRealTable, SNodeList* pCols, SNode* createCreateTableStmt(SAstCreateContext* pCxt, bool ignoreExists, SNode* pRealTable, SNodeList* pCols,
SNodeList* pTags, SNode* pOptions) { SNodeList* pTags, SNode* pOptions) {
CHECK_PARSER_STATUS(pCxt); CHECK_PARSER_STATUS(pCxt);
@ -2633,6 +2787,22 @@ _err:
return NULL; return NULL;
} }
SNode* createDropVirtualTableStmt(SAstCreateContext* pCxt, bool withOpt, bool ignoreNotExists, SNode* pRealTable) {
CHECK_PARSER_STATUS(pCxt);
SDropVirtualTableStmt* pStmt = NULL;
pCxt->errCode = nodesMakeNode(QUERY_NODE_DROP_VIRTUAL_TABLE_STMT, (SNode**)&pStmt);
CHECK_MAKE_NODE(pStmt);
tstrncpy(pStmt->dbName, ((SRealTableNode*)pRealTable)->table.dbName, TSDB_DB_NAME_LEN);
tstrncpy(pStmt->tableName, ((SRealTableNode*)pRealTable)->table.tableName, TSDB_TABLE_NAME_LEN);
pStmt->ignoreNotExists = ignoreNotExists;
pStmt->withOpt = withOpt;
nodesDestroyNode(pRealTable);
return (SNode*)pStmt;
_err:
nodesDestroyNode(pRealTable);
return NULL;
}
static SNode* createAlterTableStmtFinalize(SNode* pRealTable, SAlterTableStmt* pStmt) { static SNode* createAlterTableStmtFinalize(SNode* pRealTable, SAlterTableStmt* pStmt) {
tstrncpy(pStmt->dbName, ((SRealTableNode*)pRealTable)->table.dbName, TSDB_DB_NAME_LEN); tstrncpy(pStmt->dbName, ((SRealTableNode*)pRealTable)->table.dbName, TSDB_DB_NAME_LEN);
tstrncpy(pStmt->tableName, ((SRealTableNode*)pRealTable)->table.tableName, TSDB_TABLE_NAME_LEN); tstrncpy(pStmt->tableName, ((SRealTableNode*)pRealTable)->table.tableName, TSDB_TABLE_NAME_LEN);
@ -2669,6 +2839,7 @@ _err:
nodesDestroyNode(pRealTable); nodesDestroyNode(pRealTable);
return NULL; return NULL;
} }
SNode* createAlterTableAddModifyColOptions2(SAstCreateContext* pCxt, SNode* pRealTable, int8_t alterType, SNode* createAlterTableAddModifyColOptions2(SAstCreateContext* pCxt, SNode* pRealTable, int8_t alterType,
SToken* pColName, SDataType dataType, SNode* pOptions) { SToken* pColName, SDataType dataType, SNode* pOptions) {
SAlterTableStmt* pStmt = NULL; SAlterTableStmt* pStmt = NULL;
@ -2683,7 +2854,17 @@ SNode* createAlterTableAddModifyColOptions2(SAstCreateContext* pCxt, SNode* pRea
if (pOptions != NULL) { if (pOptions != NULL) {
SColumnOptions* pOption = (SColumnOptions*)pOptions; SColumnOptions* pOption = (SColumnOptions*)pOptions;
if (pOption->bPrimaryKey == false && pOption->commentNull == true) { if (pOption->hasRef) {
if (!pOption->commentNull || pOption->bPrimaryKey || 0 != strcmp(pOption->compress, "") ||
0 != strcmp(pOption->encode, "") || 0 != strcmp(pOption->compressLevel, "")) {
pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ALTER_TABLE);
}
pStmt->alterType = TSDB_ALTER_TABLE_ADD_COLUMN_WITH_COLUMN_REF;
tstrncpy(pStmt->refDbName, pOption->refDb, TSDB_DB_NAME_LEN);
tstrncpy(pStmt->refTableName, pOption->refTable, TSDB_TABLE_NAME_LEN);
tstrncpy(pStmt->refColName, pOption->refColumn, TSDB_COL_NAME_LEN);
CHECK_PARSER_STATUS(pCxt);
} else if (pOption->bPrimaryKey == false && pOption->commentNull == true) {
if (strlen(pOption->compress) != 0 || strlen(pOption->compressLevel) || strlen(pOption->encode) != 0) { if (strlen(pOption->compress) != 0 || strlen(pOption->compressLevel) || strlen(pOption->encode) != 0) {
pStmt->alterType = TSDB_ALTER_TABLE_ADD_COLUMN_WITH_COMPRESS_OPTION; pStmt->alterType = TSDB_ALTER_TABLE_ADD_COLUMN_WITH_COMPRESS_OPTION;
} else { } else {
@ -2753,6 +2934,39 @@ _err:
return NULL; return NULL;
} }
SNode* createAlterTableAlterColRef(SAstCreateContext* pCxt, SNode* pRealTable, int8_t alterType, SToken* pColName,
SNode* pRef) {
CHECK_PARSER_STATUS(pCxt);
CHECK_NAME(checkColumnName(pCxt, pColName));
SAlterTableStmt* pStmt = NULL;
pCxt->errCode = nodesMakeNode(QUERY_NODE_ALTER_TABLE_STMT, (SNode**)&pStmt);
CHECK_MAKE_NODE(pStmt);
pStmt->alterType = alterType;
COPY_STRING_FORM_ID_TOKEN(pStmt->colName, pColName);
tstrncpy(pStmt->refDbName, ((SColumnRefNode*)pRef)->refDbName, TSDB_DB_NAME_LEN);
tstrncpy(pStmt->refTableName, ((SColumnRefNode*)pRef)->refTableName, TSDB_TABLE_NAME_LEN);
tstrncpy(pStmt->refColName, ((SColumnRefNode*)pRef)->refColName, TSDB_COL_NAME_LEN);
return createAlterTableStmtFinalize(pRealTable, pStmt);
_err:
nodesDestroyNode(pRealTable);
return NULL;
}
SNode* createAlterTableRemoveColRef(SAstCreateContext* pCxt, SNode* pRealTable, int8_t alterType, SToken* pColName,
const SToken* pLiteral) {
CHECK_PARSER_STATUS(pCxt);
CHECK_NAME(checkColumnName(pCxt, pColName));
SAlterTableStmt* pStmt = NULL;
pCxt->errCode = nodesMakeNode(QUERY_NODE_ALTER_TABLE_STMT, (SNode**)&pStmt);
CHECK_MAKE_NODE(pStmt);
pStmt->alterType = alterType;
COPY_STRING_FORM_ID_TOKEN(pStmt->colName, pColName);
return createAlterTableStmtFinalize(pRealTable, pStmt);
_err:
nodesDestroyNode(pRealTable);
return NULL;
}
SNode* createAlterSingleTagColumnNode(SAstCreateContext* pCtx, SToken* pTagName, SNode* pVal) { SNode* createAlterSingleTagColumnNode(SAstCreateContext* pCtx, SToken* pTagName, SNode* pVal) {
CHECK_PARSER_STATUS(pCtx); CHECK_PARSER_STATUS(pCtx);
SAlterTableStmt* pStmt = NULL; SAlterTableStmt* pStmt = NULL;
@ -2803,6 +3017,12 @@ SNode* setAlterSuperTableType(SNode* pStmt) {
return pStmt; return pStmt;
} }
SNode* setAlterVirtualTableType(SNode* pStmt) {
if (!pStmt) return NULL;
setNodeType(pStmt, QUERY_NODE_ALTER_VIRTUAL_TABLE_STMT);
return pStmt;
}
SNode* createUseDatabaseStmt(SAstCreateContext* pCxt, SToken* pDbName) { SNode* createUseDatabaseStmt(SAstCreateContext* pCxt, SToken* pDbName) {
CHECK_PARSER_STATUS(pCxt); CHECK_PARSER_STATUS(pCxt);
CHECK_NAME(checkDbName(pCxt, pDbName, false)); CHECK_NAME(checkDbName(pCxt, pDbName, false));
@ -2819,7 +3039,8 @@ static bool needDbShowStmt(ENodeType type) {
return QUERY_NODE_SHOW_TABLES_STMT == type || QUERY_NODE_SHOW_STABLES_STMT == type || return QUERY_NODE_SHOW_TABLES_STMT == type || QUERY_NODE_SHOW_STABLES_STMT == type ||
QUERY_NODE_SHOW_VGROUPS_STMT == type || QUERY_NODE_SHOW_INDEXES_STMT == type || QUERY_NODE_SHOW_VGROUPS_STMT == type || QUERY_NODE_SHOW_INDEXES_STMT == type ||
QUERY_NODE_SHOW_TAGS_STMT == type || QUERY_NODE_SHOW_TABLE_TAGS_STMT == type || QUERY_NODE_SHOW_TAGS_STMT == type || QUERY_NODE_SHOW_TABLE_TAGS_STMT == type ||
QUERY_NODE_SHOW_VIEWS_STMT == type || QUERY_NODE_SHOW_TSMAS_STMT == type || QUERY_NODE_SHOW_USAGE_STMT == type; QUERY_NODE_SHOW_VIEWS_STMT == type || QUERY_NODE_SHOW_TSMAS_STMT == type ||
QUERY_NODE_SHOW_USAGE_STMT == type || QUERY_NODE_SHOW_VTABLES_STMT == type;
} }
SNode* createShowStmtWithLike(SAstCreateContext* pCxt, ENodeType type, SNode* pLikePattern) { SNode* createShowStmtWithLike(SAstCreateContext* pCxt, ENodeType type, SNode* pLikePattern) {
@ -2909,6 +3130,12 @@ SNode* createShowTablesStmt(SAstCreateContext* pCxt, SShowTablesOption option, S
} else { } else {
pDbName = createIdentifierValueNode(pCxt, &option.dbName); pDbName = createIdentifierValueNode(pCxt, &option.dbName);
} }
if (option.kind != SHOW_KIND_TABLES_NORMAL && option.kind != SHOW_KIND_TABLES_CHILD && option.kind != SHOW_KIND_ALL) {
pCxt->errCode = TSDB_CODE_PAR_SYNTAX_ERROR;
return NULL;
}
SNode* pStmt = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_TABLES_STMT, pDbName, pTbName, tableCondType); SNode* pStmt = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_TABLES_STMT, pDbName, pTbName, tableCondType);
CHECK_PARSER_STATUS(pCxt); CHECK_PARSER_STATUS(pCxt);
(void)setShowKind(pCxt, pStmt, option.kind); (void)setShowKind(pCxt, pStmt, option.kind);
@ -2918,6 +3145,54 @@ _err:
return NULL; return NULL;
} }
SNode* createShowVTablesStmt(SAstCreateContext* pCxt, SShowTablesOption option, SNode* pTbName,
EOperatorType tableCondType) {
CHECK_PARSER_STATUS(pCxt);
SNode* pDbName = NULL;
if (option.dbName.type == TK_NK_NIL) {
pDbName = createDefaultDatabaseCondValue(pCxt);
} else {
pDbName = createIdentifierValueNode(pCxt, &option.dbName);
}
if (option.kind != SHOW_KIND_TABLES_NORMAL && option.kind != SHOW_KIND_TABLES_CHILD && option.kind != SHOW_KIND_ALL) {
pCxt->errCode = TSDB_CODE_PAR_SYNTAX_ERROR;
return NULL;
}
SNode* pStmt = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_VTABLES_STMT, pDbName, pTbName, tableCondType);
CHECK_PARSER_STATUS(pCxt);
(void)setShowKind(pCxt, pStmt, option.kind);
return pStmt;
_err:
nodesDestroyNode(pTbName);
return NULL;
}
SNode* createShowSTablesStmt(SAstCreateContext* pCxt, SShowTablesOption option, SNode* pTbName,
EOperatorType tableCondType) {
CHECK_PARSER_STATUS(pCxt);
SNode* pDbName = NULL;
if (option.dbName.type == TK_NK_NIL) {
pDbName = createDefaultDatabaseCondValue(pCxt);
} else {
pDbName = createIdentifierValueNode(pCxt, &option.dbName);
}
if (option.kind != SHOW_KIND_TABLES_NORMAL && option.kind != SHOW_KIND_TABLES_VIRTUAL && option.kind != SHOW_KIND_ALL) {
pCxt->errCode = TSDB_CODE_PAR_SYNTAX_ERROR;
return NULL;
}
SNode* pStmt = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_STABLES_STMT, pDbName, pTbName, tableCondType);
CHECK_PARSER_STATUS(pCxt);
(void)setShowKind(pCxt, pStmt, option.kind);
return pStmt;
_err:
nodesDestroyNode(pTbName);
return NULL;
}
SNode* createShowCreateDatabaseStmt(SAstCreateContext* pCxt, SToken* pDbName) { SNode* createShowCreateDatabaseStmt(SAstCreateContext* pCxt, SToken* pDbName) {
CHECK_PARSER_STATUS(pCxt); CHECK_PARSER_STATUS(pCxt);
CHECK_NAME(checkDbName(pCxt, pDbName, true)); CHECK_NAME(checkDbName(pCxt, pDbName, true));
@ -2979,6 +3254,20 @@ _err:
return NULL; return NULL;
} }
SNode* createShowCreateVTableStmt(SAstCreateContext* pCxt, ENodeType type, SNode* pRealTable) {
CHECK_PARSER_STATUS(pCxt);
SShowCreateTableStmt* pStmt = NULL;
pCxt->errCode = nodesMakeNode(type, (SNode**)&pStmt);
CHECK_MAKE_NODE(pStmt);
tstrncpy(pStmt->dbName, ((SRealTableNode*)pRealTable)->table.dbName, TSDB_DB_NAME_LEN);
tstrncpy(pStmt->tableName, ((SRealTableNode*)pRealTable)->table.tableName, TSDB_TABLE_NAME_LEN);
nodesDestroyNode(pRealTable);
return (SNode*)pStmt;
_err:
nodesDestroyNode(pRealTable);
return NULL;
}
SNode* createShowCreateViewStmt(SAstCreateContext* pCxt, ENodeType type, SNode* pRealTable) { SNode* createShowCreateViewStmt(SAstCreateContext* pCxt, ENodeType type, SNode* pRealTable) {
CHECK_PARSER_STATUS(pCxt); CHECK_PARSER_STATUS(pCxt);
SShowCreateViewStmt* pStmt = NULL; SShowCreateViewStmt* pStmt = NULL;

View File

@ -320,6 +320,76 @@ static int32_t collectMetaKeyFromCreateTable(SCollectMetaKeyCxt* pCxt, SCreateTa
return code; return code;
} }
static int32_t collectMetaKeyFromCreateVTable(SCollectMetaKeyCxt* pCxt, SCreateVTableStmt* pStmt) {
int32_t code = reserveDbCfgInCache(pCxt->pParseCxt->acctId, pStmt->dbName, pCxt->pMetaCache);
if (TSDB_CODE_SUCCESS == code) {
code = reserveTableVgroupInCache(pCxt->pParseCxt->acctId, pStmt->dbName, pStmt->tableName, pCxt->pMetaCache);
}
if (TSDB_CODE_SUCCESS == code) {
code = reserveUserAuthInCache(pCxt->pParseCxt->acctId, pCxt->pParseCxt->pUser, pStmt->dbName, NULL, AUTH_TYPE_WRITE,
pCxt->pMetaCache);
}
if (TSDB_CODE_SUCCESS == code) {
SNode *pNode = NULL;
FOREACH(pNode, pStmt->pCols) {
SColumnDefNode *pCol = (SColumnDefNode*)pNode;
if (NULL == pCol) {
code = TSDB_CODE_PAR_INVALID_COLUMN;
break;
}
SColumnOptions *pOptions = (SColumnOptions*)pCol->pOptions;
if (pOptions && pOptions->hasRef) {
code = reserveTableMetaInCache(pCxt->pParseCxt->acctId, pOptions->refDb, pOptions->refTable, pCxt->pMetaCache);
if (TSDB_CODE_SUCCESS == code) {
code = reserveTableVgroupInCache(pCxt->pParseCxt->acctId, pOptions->refDb, pOptions->refTable, pCxt->pMetaCache);
}
if (TSDB_CODE_SUCCESS == code) {
code = reserveUserAuthInCache(pCxt->pParseCxt->acctId, pCxt->pParseCxt->pUser, pOptions->refDb,
pOptions->refTable, AUTH_TYPE_READ, pCxt->pMetaCache);
}
if (TSDB_CODE_SUCCESS != code) {
break;
}
}
}
}
return code;
}
static int32_t collectMetaKeyFromCreateVSubTable(SCollectMetaKeyCxt* pCxt, SCreateVSubTableStmt* pStmt) {
int32_t code = TSDB_CODE_SUCCESS;
PAR_ERR_RET(reserveDbCfgInCache(pCxt->pParseCxt->acctId, pStmt->dbName, pCxt->pMetaCache));
// super table's meta
PAR_ERR_RET(reserveTableMetaInCache(pCxt->pParseCxt->acctId, pStmt->useDbName, pStmt->useTableName,pCxt->pMetaCache));
// child table's meta
PAR_ERR_RET(reserveTableVgroupInCache(pCxt->pParseCxt->acctId, pStmt->dbName, pStmt->tableName, pCxt->pMetaCache));
// check db's write auth
PAR_ERR_RET(reserveUserAuthInCache(pCxt->pParseCxt->acctId, pCxt->pParseCxt->pUser, pStmt->dbName, NULL,
AUTH_TYPE_WRITE, pCxt->pMetaCache));
// check org table's read auth
SNode *pNode = NULL;
SNodeList *pTmpNodeList = pStmt->pSpecificColRefs ? pStmt->pSpecificColRefs : pStmt->pColRefs;
if (NULL == pTmpNodeList) {
// no column reference
return TSDB_CODE_SUCCESS;
}
FOREACH(pNode, pTmpNodeList) {
SColumnRefNode *pColRef = (SColumnRefNode*)pNode;
if (NULL == pColRef) {
code = TSDB_CODE_PAR_INVALID_COLUMN;
break;
}
PAR_ERR_RET(reserveTableMetaInCache(pCxt->pParseCxt->acctId, pColRef->refDbName, pColRef->refTableName,
pCxt->pMetaCache));
PAR_ERR_RET(reserveTableVgroupInCache(pCxt->pParseCxt->acctId, pColRef->refDbName, pColRef->refTableName,
pCxt->pMetaCache));
PAR_ERR_RET(reserveUserAuthInCache(pCxt->pParseCxt->acctId, pCxt->pParseCxt->pUser, pColRef->refDbName,
pColRef->refTableName, AUTH_TYPE_READ, pCxt->pMetaCache));
}
return code;
}
static int32_t collectMetaKeyFromCreateMultiTable(SCollectMetaKeyCxt* pCxt, SCreateMultiTablesStmt* pStmt) { static int32_t collectMetaKeyFromCreateMultiTable(SCollectMetaKeyCxt* pCxt, SCreateMultiTablesStmt* pStmt) {
int32_t code = TSDB_CODE_SUCCESS; int32_t code = TSDB_CODE_SUCCESS;
SNode* pNode = NULL; SNode* pNode = NULL;
@ -416,6 +486,30 @@ static int32_t collectMetaKeyFromDropStable(SCollectMetaKeyCxt* pCxt, SDropSuper
AUTH_TYPE_WRITE, pCxt->pMetaCache); AUTH_TYPE_WRITE, pCxt->pMetaCache);
} }
static int32_t collectMetaKeyFromDropVtable(SCollectMetaKeyCxt* pCxt, SDropVirtualTableStmt* pStmt) {
int32_t code = TSDB_CODE_SUCCESS;
if (pStmt->withOpt) {
code = reserveTableUidInCache(pCxt->pParseCxt->acctId, pStmt->dbName, pStmt->tableName, pCxt->pMetaCache);
if (TSDB_CODE_SUCCESS == code) {
code = reserveDbVgInfoInCache(pCxt->pParseCxt->acctId, pStmt->dbName, pCxt->pMetaCache);
}
if (TSDB_CODE_SUCCESS == code) {
code = reserveDbCfgInCache(pCxt->pParseCxt->acctId, pStmt->dbName, pCxt->pMetaCache);
}
} else {
code = reserveTableMetaInCache(pCxt->pParseCxt->acctId, pStmt->dbName, pStmt->tableName, pCxt->pMetaCache);
if (TSDB_CODE_SUCCESS == code) {
code =
reserveTableVgroupInCache(pCxt->pParseCxt->acctId, pStmt->dbName, pStmt->tableName, pCxt->pMetaCache);
}
if (TSDB_CODE_SUCCESS == code) {
code = reserveUserAuthInCache(pCxt->pParseCxt->acctId, pCxt->pParseCxt->pUser, pStmt->dbName,
pStmt->tableName, AUTH_TYPE_WRITE, pCxt->pMetaCache);
}
}
return code;
}
static int32_t collectMetaKeyFromAlterTable(SCollectMetaKeyCxt* pCxt, SAlterTableStmt* pStmt) { static int32_t collectMetaKeyFromAlterTable(SCollectMetaKeyCxt* pCxt, SAlterTableStmt* pStmt) {
int32_t code = reserveDbCfgInCache(pCxt->pParseCxt->acctId, pStmt->dbName, pCxt->pMetaCache); int32_t code = reserveDbCfgInCache(pCxt->pParseCxt->acctId, pStmt->dbName, pCxt->pMetaCache);
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
@ -443,6 +537,20 @@ static int32_t collectMetaKeyFromAlterStable(SCollectMetaKeyCxt* pCxt, SAlterTab
return code; return code;
} }
static int32_t collectMetaKeyFromAlterVtable(SCollectMetaKeyCxt* pCxt, SAlterTableStmt* pStmt) {
PAR_ERR_RET(reserveDbCfgInCache(pCxt->pParseCxt->acctId, pStmt->dbName, pCxt->pMetaCache));
PAR_ERR_RET(reserveTableMetaInCache(pCxt->pParseCxt->acctId, pStmt->dbName, pStmt->tableName, pCxt->pMetaCache));
PAR_ERR_RET(reserveTableVgroupInCache(pCxt->pParseCxt->acctId, pStmt->dbName, pStmt->tableName, pCxt->pMetaCache));
PAR_ERR_RET(reserveUserAuthInCache(pCxt->pParseCxt->acctId, pCxt->pParseCxt->pUser, pStmt->dbName, pStmt->tableName,
AUTH_TYPE_WRITE, pCxt->pMetaCache));
if (pStmt->alterType == TSDB_ALTER_TABLE_ALTER_COLUMN_REF || pStmt->alterType == TSDB_ALTER_TABLE_ADD_COLUMN_WITH_COLUMN_REF) {
PAR_ERR_RET(reserveTableMetaInCache(pCxt->pParseCxt->acctId, pStmt->refDbName, pStmt->refTableName, pCxt->pMetaCache));
PAR_ERR_RET(reserveUserAuthInCache(pCxt->pParseCxt->acctId, pCxt->pParseCxt->pUser, pStmt->refDbName, pStmt->refTableName,
AUTH_TYPE_READ, pCxt->pMetaCache));
}
return TSDB_CODE_SUCCESS;
}
static int32_t collectMetaKeyFromUseDatabase(SCollectMetaKeyCxt* pCxt, SUseDatabaseStmt* pStmt) { static int32_t collectMetaKeyFromUseDatabase(SCollectMetaKeyCxt* pCxt, SUseDatabaseStmt* pStmt) {
return reserveDbVgVersionInCache(pCxt->pParseCxt->acctId, pStmt->dbName, pCxt->pMetaCache); return reserveDbVgVersionInCache(pCxt->pParseCxt->acctId, pStmt->dbName, pCxt->pMetaCache);
} }
@ -1000,6 +1108,10 @@ static int32_t collectMetaKeyFromQuery(SCollectMetaKeyCxt* pCxt, SNode* pStmt) {
return collectMetaKeyFromFlushDatabase(pCxt, (SFlushDatabaseStmt*)pStmt); return collectMetaKeyFromFlushDatabase(pCxt, (SFlushDatabaseStmt*)pStmt);
case QUERY_NODE_CREATE_TABLE_STMT: case QUERY_NODE_CREATE_TABLE_STMT:
return collectMetaKeyFromCreateTable(pCxt, (SCreateTableStmt*)pStmt); return collectMetaKeyFromCreateTable(pCxt, (SCreateTableStmt*)pStmt);
case QUERY_NODE_CREATE_VIRTUAL_TABLE_STMT:
return collectMetaKeyFromCreateVTable(pCxt, (SCreateVTableStmt*)pStmt);
case QUERY_NODE_CREATE_VIRTUAL_SUBTABLE_STMT:
return collectMetaKeyFromCreateVSubTable(pCxt, (SCreateVSubTableStmt*)pStmt);
case QUERY_NODE_CREATE_MULTI_TABLES_STMT: case QUERY_NODE_CREATE_MULTI_TABLES_STMT:
return collectMetaKeyFromCreateMultiTable(pCxt, (SCreateMultiTablesStmt*)pStmt); return collectMetaKeyFromCreateMultiTable(pCxt, (SCreateMultiTablesStmt*)pStmt);
case QUERY_NODE_CREATE_SUBTABLE_FROM_FILE_CLAUSE: case QUERY_NODE_CREATE_SUBTABLE_FROM_FILE_CLAUSE:
@ -1008,10 +1120,14 @@ static int32_t collectMetaKeyFromQuery(SCollectMetaKeyCxt* pCxt, SNode* pStmt) {
return collectMetaKeyFromDropTable(pCxt, (SDropTableStmt*)pStmt); return collectMetaKeyFromDropTable(pCxt, (SDropTableStmt*)pStmt);
case QUERY_NODE_DROP_SUPER_TABLE_STMT: case QUERY_NODE_DROP_SUPER_TABLE_STMT:
return collectMetaKeyFromDropStable(pCxt, (SDropSuperTableStmt*)pStmt); return collectMetaKeyFromDropStable(pCxt, (SDropSuperTableStmt*)pStmt);
case QUERY_NODE_DROP_VIRTUAL_TABLE_STMT:
return collectMetaKeyFromDropVtable(pCxt, (SDropVirtualTableStmt*)pStmt);
case QUERY_NODE_ALTER_TABLE_STMT: case QUERY_NODE_ALTER_TABLE_STMT:
return collectMetaKeyFromAlterTable(pCxt, (SAlterTableStmt*)pStmt); return collectMetaKeyFromAlterTable(pCxt, (SAlterTableStmt*)pStmt);
case QUERY_NODE_ALTER_SUPER_TABLE_STMT: case QUERY_NODE_ALTER_SUPER_TABLE_STMT:
return collectMetaKeyFromAlterStable(pCxt, (SAlterTableStmt*)pStmt); return collectMetaKeyFromAlterStable(pCxt, (SAlterTableStmt*)pStmt);
case QUERY_NODE_ALTER_VIRTUAL_TABLE_STMT:
return collectMetaKeyFromAlterVtable(pCxt, (SAlterTableStmt*)pStmt);
case QUERY_NODE_USE_DATABASE_STMT: case QUERY_NODE_USE_DATABASE_STMT:
return collectMetaKeyFromUseDatabase(pCxt, (SUseDatabaseStmt*)pStmt); return collectMetaKeyFromUseDatabase(pCxt, (SUseDatabaseStmt*)pStmt);
case QUERY_NODE_CREATE_INDEX_STMT: case QUERY_NODE_CREATE_INDEX_STMT:
@ -1063,6 +1179,7 @@ static int32_t collectMetaKeyFromQuery(SCollectMetaKeyCxt* pCxt, SNode* pStmt) {
case QUERY_NODE_SHOW_STREAMS_STMT: case QUERY_NODE_SHOW_STREAMS_STMT:
return collectMetaKeyFromShowStreams(pCxt, (SShowStmt*)pStmt); return collectMetaKeyFromShowStreams(pCxt, (SShowStmt*)pStmt);
case QUERY_NODE_SHOW_TABLES_STMT: case QUERY_NODE_SHOW_TABLES_STMT:
case QUERY_NODE_SHOW_VTABLES_STMT:
return collectMetaKeyFromShowTables(pCxt, (SShowStmt*)pStmt); return collectMetaKeyFromShowTables(pCxt, (SShowStmt*)pStmt);
case QUERY_NODE_SHOW_FILESETS_STMT: case QUERY_NODE_SHOW_FILESETS_STMT:
return collectMetaKeyFromShowFilesets(pCxt, (SShowStmt*)pStmt); return collectMetaKeyFromShowFilesets(pCxt, (SShowStmt*)pStmt);
@ -1113,6 +1230,7 @@ static int32_t collectMetaKeyFromQuery(SCollectMetaKeyCxt* pCxt, SNode* pStmt) {
case QUERY_NODE_SHOW_CREATE_DATABASE_STMT: case QUERY_NODE_SHOW_CREATE_DATABASE_STMT:
return collectMetaKeyFromShowCreateDatabase(pCxt, (SShowCreateDatabaseStmt*)pStmt); return collectMetaKeyFromShowCreateDatabase(pCxt, (SShowCreateDatabaseStmt*)pStmt);
case QUERY_NODE_SHOW_CREATE_TABLE_STMT: case QUERY_NODE_SHOW_CREATE_TABLE_STMT:
case QUERY_NODE_SHOW_CREATE_VTABLE_STMT:
case QUERY_NODE_SHOW_CREATE_STABLE_STMT: case QUERY_NODE_SHOW_CREATE_STABLE_STMT:
return collectMetaKeyFromShowCreateTable(pCxt, (SShowCreateTableStmt*)pStmt); return collectMetaKeyFromShowCreateTable(pCxt, (SShowCreateTableStmt*)pStmt);
case QUERY_NODE_SHOW_CREATE_VIEW_STMT: case QUERY_NODE_SHOW_CREATE_VIEW_STMT:

View File

@ -250,6 +250,10 @@ static int32_t authShowTables(SAuthCxt* pCxt, SShowStmt* pStmt) {
return checkAuth(pCxt, ((SValueNode*)pStmt->pDbName)->literal, NULL, AUTH_TYPE_READ_OR_WRITE, NULL); return checkAuth(pCxt, ((SValueNode*)pStmt->pDbName)->literal, NULL, AUTH_TYPE_READ_OR_WRITE, NULL);
} }
static int32_t authShowVtables(SAuthCxt* pCxt, SShowStmt* pStmt) {
return authShowTables(pCxt, pStmt);
}
static int32_t authShowUsage(SAuthCxt* pCxt, SShowStmt* pStmt) { static int32_t authShowUsage(SAuthCxt* pCxt, SShowStmt* pStmt) {
return checkAuth(pCxt, ((SValueNode*)pStmt->pDbName)->literal, NULL, AUTH_TYPE_READ_OR_WRITE, NULL); return checkAuth(pCxt, ((SValueNode*)pStmt->pDbName)->literal, NULL, AUTH_TYPE_READ_OR_WRITE, NULL);
} }
@ -274,6 +278,42 @@ static int32_t authCreateTable(SAuthCxt* pCxt, SCreateTableStmt* pStmt) {
return checkAuth(pCxt, pStmt->dbName, NULL, AUTH_TYPE_WRITE, &pTagCond); return checkAuth(pCxt, pStmt->dbName, NULL, AUTH_TYPE_WRITE, &pTagCond);
} }
static int32_t authCreateVTable(SAuthCxt* pCxt, SCreateVTableStmt* pStmt) {
PAR_ERR_RET(checkAuth(pCxt, pStmt->dbName, NULL, AUTH_TYPE_WRITE, NULL));
SNode *pCol = NULL;
FOREACH(pCol, pStmt->pCols) {
SColumnDefNode *pColDef = (SColumnDefNode*)pCol;
if (NULL == pColDef) {
PAR_ERR_RET(TSDB_CODE_PAR_INVALID_COLUMN);
}
SColumnOptions *pOptions = (SColumnOptions*)pColDef->pOptions;
if (pOptions && pOptions->hasRef) {
PAR_ERR_RET(checkAuth(pCxt, pOptions->refDb, pOptions->refTable, AUTH_TYPE_READ, NULL));
}
}
return TSDB_CODE_SUCCESS;
}
static int32_t authCreateVSubTable(SAuthCxt* pCxt, SCreateVSubTableStmt* pStmt) {
int32_t code = TSDB_CODE_SUCCESS;
SNode *pNode = NULL;
SNodeList* pTmpList = pStmt->pSpecificColRefs ? pStmt->pSpecificColRefs : pStmt->pColRefs;
PAR_ERR_RET(checkAuth(pCxt, pStmt->dbName, NULL, AUTH_TYPE_WRITE, NULL));
if (NULL == pTmpList) {
// no column reference
return TSDB_CODE_SUCCESS;
}
FOREACH(pNode, pTmpList) {
SColumnRefNode *pColRef = (SColumnRefNode*)pNode;
if (NULL == pColRef) {
PAR_ERR_RET(TSDB_CODE_PAR_INVALID_COLUMN);
}
PAR_ERR_RET(checkAuth(pCxt, pColRef->refDbName, pColRef->refTableName, AUTH_TYPE_READ, NULL));
}
return code;
}
static int32_t authCreateMultiTable(SAuthCxt* pCxt, SCreateMultiTablesStmt* pStmt) { static int32_t authCreateMultiTable(SAuthCxt* pCxt, SCreateMultiTablesStmt* pStmt) {
int32_t code = TSDB_CODE_SUCCESS; int32_t code = TSDB_CODE_SUCCESS;
SNode* pNode = NULL; SNode* pNode = NULL;
@ -318,12 +358,28 @@ static int32_t authDropStable(SAuthCxt* pCxt, SDropSuperTableStmt* pStmt) {
return checkAuth(pCxt, pStmt->dbName, pStmt->tableName, AUTH_TYPE_WRITE, NULL); return checkAuth(pCxt, pStmt->dbName, pStmt->tableName, AUTH_TYPE_WRITE, NULL);
} }
static int32_t authDropVtable(SAuthCxt* pCxt, SDropVirtualTableStmt* pStmt) {
if (pStmt->withOpt && !pCxt->pParseCxt->isSuperUser) {
return TSDB_CODE_PAR_PERMISSION_DENIED;
}
return checkAuth(pCxt, pStmt->dbName, pStmt->tableName, AUTH_TYPE_WRITE, NULL);
}
static int32_t authAlterTable(SAuthCxt* pCxt, SAlterTableStmt* pStmt) { static int32_t authAlterTable(SAuthCxt* pCxt, SAlterTableStmt* pStmt) {
SNode* pTagCond = NULL; SNode* pTagCond = NULL;
// todo check tag condition for subtable // todo check tag condition for subtable
return checkAuth(pCxt, pStmt->dbName, pStmt->tableName, AUTH_TYPE_WRITE, NULL); return checkAuth(pCxt, pStmt->dbName, pStmt->tableName, AUTH_TYPE_WRITE, NULL);
} }
static int32_t authAlterVTable(SAuthCxt* pCxt, SAlterTableStmt* pStmt) {
PAR_ERR_RET(checkAuth(pCxt, pStmt->dbName, pStmt->tableName, AUTH_TYPE_WRITE, NULL));
if (pStmt->alterType == TSDB_ALTER_TABLE_ADD_COLUMN_WITH_COLUMN_REF ||
pStmt->alterType == TSDB_ALTER_TABLE_ALTER_COLUMN_REF) {
PAR_ERR_RET(checkAuth(pCxt, pStmt->dbName, pStmt->refTableName, AUTH_TYPE_READ, NULL));
}
PAR_RET(TSDB_CODE_SUCCESS);
}
static int32_t authCreateView(SAuthCxt* pCxt, SCreateViewStmt* pStmt) { static int32_t authCreateView(SAuthCxt* pCxt, SCreateViewStmt* pStmt) {
#ifndef TD_ENTERPRISE #ifndef TD_ENTERPRISE
return TSDB_CODE_OPS_NOT_SUPPORT; return TSDB_CODE_OPS_NOT_SUPPORT;
@ -352,15 +408,23 @@ static int32_t authQuery(SAuthCxt* pCxt, SNode* pStmt) {
return authInsert(pCxt, (SInsertStmt*)pStmt); return authInsert(pCxt, (SInsertStmt*)pStmt);
case QUERY_NODE_CREATE_TABLE_STMT: case QUERY_NODE_CREATE_TABLE_STMT:
return authCreateTable(pCxt, (SCreateTableStmt*)pStmt); return authCreateTable(pCxt, (SCreateTableStmt*)pStmt);
case QUERY_NODE_CREATE_VIRTUAL_TABLE_STMT:
return authCreateVTable(pCxt, (SCreateVTableStmt*)pStmt);
case QUERY_NODE_CREATE_VIRTUAL_SUBTABLE_STMT:
return authCreateVSubTable(pCxt, (SCreateVSubTableStmt*)pStmt);
case QUERY_NODE_CREATE_MULTI_TABLES_STMT: case QUERY_NODE_CREATE_MULTI_TABLES_STMT:
return authCreateMultiTable(pCxt, (SCreateMultiTablesStmt*)pStmt); return authCreateMultiTable(pCxt, (SCreateMultiTablesStmt*)pStmt);
case QUERY_NODE_DROP_TABLE_STMT: case QUERY_NODE_DROP_TABLE_STMT:
return authDropTable(pCxt, (SDropTableStmt*)pStmt); return authDropTable(pCxt, (SDropTableStmt*)pStmt);
case QUERY_NODE_DROP_SUPER_TABLE_STMT: case QUERY_NODE_DROP_SUPER_TABLE_STMT:
return authDropStable(pCxt, (SDropSuperTableStmt*)pStmt); return authDropStable(pCxt, (SDropSuperTableStmt*)pStmt);
case QUERY_NODE_DROP_VIRTUAL_TABLE_STMT:
return authDropVtable(pCxt, (SDropVirtualTableStmt*)pStmt);
case QUERY_NODE_ALTER_TABLE_STMT: case QUERY_NODE_ALTER_TABLE_STMT:
case QUERY_NODE_ALTER_SUPER_TABLE_STMT: case QUERY_NODE_ALTER_SUPER_TABLE_STMT:
return authAlterTable(pCxt, (SAlterTableStmt*)pStmt); return authAlterTable(pCxt, (SAlterTableStmt*)pStmt);
case QUERY_NODE_ALTER_VIRTUAL_TABLE_STMT:
return authAlterVTable(pCxt, (SAlterTableStmt*)pStmt);
case QUERY_NODE_SHOW_DNODES_STMT: case QUERY_NODE_SHOW_DNODES_STMT:
case QUERY_NODE_SHOW_MNODES_STMT: case QUERY_NODE_SHOW_MNODES_STMT:
case QUERY_NODE_SHOW_MODULES_STMT: case QUERY_NODE_SHOW_MODULES_STMT:
@ -392,7 +456,10 @@ static int32_t authQuery(SAuthCxt* pCxt, SNode* pStmt) {
case QUERY_NODE_SHOW_TABLES_STMT: case QUERY_NODE_SHOW_TABLES_STMT:
case QUERY_NODE_SHOW_STABLES_STMT: case QUERY_NODE_SHOW_STABLES_STMT:
return authShowTables(pCxt, (SShowStmt*)pStmt); return authShowTables(pCxt, (SShowStmt*)pStmt);
case QUERY_NODE_SHOW_VTABLES_STMT:
return authShowVtables(pCxt, (SShowStmt*)pStmt);
case QUERY_NODE_SHOW_CREATE_TABLE_STMT: case QUERY_NODE_SHOW_CREATE_TABLE_STMT:
case QUERY_NODE_SHOW_CREATE_VTABLE_STMT:
case QUERY_NODE_SHOW_CREATE_STABLE_STMT: case QUERY_NODE_SHOW_CREATE_STABLE_STMT:
return authShowCreateTable(pCxt, (SShowCreateTableStmt*)pStmt); return authShowCreateTable(pCxt, (SShowCreateTableStmt*)pStmt);
// case QUERY_NODE_SHOW_CREATE_VIEW_STMT: // case QUERY_NODE_SHOW_CREATE_VIEW_STMT:

View File

@ -365,7 +365,7 @@ static int32_t createConstantValue(SValueNode** ppNode) {
static int32_t calcConstProjections(SCalcConstContext* pCxt, SSelectStmt* pSelect, bool subquery) { static int32_t calcConstProjections(SCalcConstContext* pCxt, SSelectStmt* pSelect, bool subquery) {
SNode* pProj = NULL; SNode* pProj = NULL;
WHERE_EACH(pProj, pSelect->pProjectionList) { WHERE_EACH(pProj, pSelect->pProjectionList) {
if (subquery && !pSelect->isDistinct && !pSelect->tagScan && isUselessCol((SExprNode*)pProj)) { if (subquery && !pSelect->isDistinct && !pSelect->tagScan && isUselessCol((SExprNode*)pProj) && (pSelect->pFromTable && nodeType(pSelect->pFromTable) != QUERY_NODE_VIRTUAL_TABLE)) {
ERASE_NODE(pSelect->pProjectionList); ERASE_NODE(pSelect->pProjectionList);
continue; continue;
} }

View File

@ -313,8 +313,10 @@ static SKeyword keywordTable[] = {
{"VGROUPS", TK_VGROUPS}, {"VGROUPS", TK_VGROUPS},
{"VIEW", TK_VIEW}, {"VIEW", TK_VIEW},
{"VIEWS", TK_VIEWS}, {"VIEWS", TK_VIEWS},
{"VIRTUAL", TK_VIRTUAL},
{"VNODE", TK_VNODE}, {"VNODE", TK_VNODE},
{"VNODES", TK_VNODES}, {"VNODES", TK_VNODES},
{"VTABLE", TK_VTABLE},
{"WAL_FSYNC_PERIOD", TK_WAL_FSYNC_PERIOD}, {"WAL_FSYNC_PERIOD", TK_WAL_FSYNC_PERIOD},
{"WAL_LEVEL", TK_WAL_LEVEL}, {"WAL_LEVEL", TK_WAL_LEVEL},
{"WAL_RETENTION_PERIOD", TK_WAL_RETENTION_PERIOD}, {"WAL_RETENTION_PERIOD", TK_WAL_RETENTION_PERIOD},
@ -366,6 +368,8 @@ static SKeyword keywordTable[] = {
{"META_ONLY", TK_META_ONLY}, {"META_ONLY", TK_META_ONLY},
{"CONTINUOUS_WINDOW_CLOSE", TK_CONTINUOUS_WINDOW_CLOSE}, {"CONTINUOUS_WINDOW_CLOSE", TK_CONTINUOUS_WINDOW_CLOSE},
{"RECALCULATE", TK_RECALCULATE}, {"RECALCULATE", TK_RECALCULATE},
{"VTABLES", TK_VTABLES},
{"META_ONLY", TK_META_ONLY}
}; };
// clang-format on // clang-format on

File diff suppressed because it is too large Load Diff

View File

@ -232,6 +232,14 @@ static char* getSyntaxErrFormat(int32_t errCode) {
return "True_for duration cannot be negative"; return "True_for duration cannot be negative";
case TSDB_CODE_PAR_TRUE_FOR_UNIT: case TSDB_CODE_PAR_TRUE_FOR_UNIT:
return "Cannot use 'year' or 'month' as true_for duration"; return "Cannot use 'year' or 'month' as true_for duration";
case TSDB_CODE_PAR_INVALID_REF_COLUMN:
return "Invalid virtual table's ref column";
case TSDB_CODE_PAR_INVALID_TABLE_TYPE:
return "Invalid table type";
case TSDB_CODE_PAR_INVALID_REF_COLUMN_TYPE:
return "Invalid virtual table's ref column type";
case TSDB_CODE_PAR_MISMATCH_STABLE_TYPE:
return "Create child table using virtual super table";
default: default:
return "Unknown error"; return "Unknown error";
} }
@ -334,17 +342,24 @@ STableMeta* tableMetaDup(const STableMeta* pTableMeta) {
bool hasSchemaExt = pTableMeta->schemaExt == NULL ? false : true; bool hasSchemaExt = pTableMeta->schemaExt == NULL ? false : true;
size_t schemaExtSize = hasSchemaExt ? pTableMeta->tableInfo.numOfColumns * sizeof(SSchemaExt) : 0; size_t schemaExtSize = hasSchemaExt ? pTableMeta->tableInfo.numOfColumns * sizeof(SSchemaExt) : 0;
bool hasColRef = pTableMeta->colRef == NULL ? false : true;
size_t colRefSize = hasColRef ? pTableMeta->numOfColRefs * sizeof(SColRef) : 0;
size_t size = sizeof(STableMeta) + numOfFields * sizeof(SSchema); size_t size = sizeof(STableMeta) + numOfFields * sizeof(SSchema);
STableMeta* p = taosMemoryMalloc(size + schemaExtSize); STableMeta* p = taosMemoryMalloc(size + schemaExtSize + colRefSize);
if (NULL == p) return NULL; if (NULL == p) return NULL;
memcpy(p, pTableMeta, schemaExtSize + size); memcpy(p, pTableMeta, colRefSize + schemaExtSize + size);
if (hasSchemaExt) { if (hasSchemaExt) {
p->schemaExt = (SSchemaExt*)(((char*)p) + size); p->schemaExt = (SSchemaExt*)(((char*)p) + size);
} else { } else {
p->schemaExt = NULL; p->schemaExt = NULL;
} }
if (hasColRef) {
p->colRef = (SColRef*)(((char*)p) + size + schemaExtSize);
} else {
p->colRef = NULL;
}
return p; return p;
} }
@ -1074,7 +1089,8 @@ int32_t getTableNameFromCache(SParseMetaCache* pMetaCache, const SName* pName, c
sizeof(STableMeta) + sizeof(SSchema) * (pMeta->tableInfo.numOfColumns + pMeta->tableInfo.numOfTags); sizeof(STableMeta) + sizeof(SSchema) * (pMeta->tableInfo.numOfColumns + pMeta->tableInfo.numOfTags);
int32_t schemaExtSize = int32_t schemaExtSize =
(withExtSchema(pMeta->tableType) && pMeta->schemaExt) ? sizeof(SSchemaExt) * pMeta->tableInfo.numOfColumns : 0; (withExtSchema(pMeta->tableType) && pMeta->schemaExt) ? sizeof(SSchemaExt) * pMeta->tableInfo.numOfColumns : 0;
const char* pTableName = (const char*)pMeta + metaSize + schemaExtSize; int32_t colRefSize = (hasRefCol(pMeta->tableType) && pMeta->colRef) ? sizeof(SColRef) * pMeta->numOfColRefs : 0;
const char* pTableName = (const char*)pMeta + metaSize + schemaExtSize + colRefSize;
tstrncpy(pTbName, pTableName, TSDB_TABLE_NAME_LEN); tstrncpy(pTbName, pTableName, TSDB_TABLE_NAME_LEN);
} }
@ -1381,6 +1397,7 @@ STableCfg* tableCfgDup(STableCfg* pCfg) {
pNew->pTags = NULL; pNew->pTags = NULL;
pNew->pSchemas = NULL; pNew->pSchemas = NULL;
pNew->pSchemaExt = NULL; pNew->pSchemaExt = NULL;
pNew->pColRefs = NULL;
if (NULL != pCfg->pComment) { if (NULL != pCfg->pComment) {
pNew->pComment = taosMemoryCalloc(pNew->commentLen + 1, 1); pNew->pComment = taosMemoryCalloc(pNew->commentLen + 1, 1);
if (!pNew->pComment) goto err; if (!pNew->pComment) goto err;
@ -1413,6 +1430,16 @@ STableCfg* tableCfgDup(STableCfg* pCfg) {
pNew->pSchemaExt = pSchemaExt; pNew->pSchemaExt = pSchemaExt;
SColRef *pColRef = NULL;
if (hasRefCol(pCfg->tableType) && pCfg->pColRefs) {
int32_t colRefSize = pCfg->numOfColumns * sizeof(SColRef);
pColRef = taosMemoryMalloc(colRefSize);
if (!pColRef) goto err;
memcpy(pColRef, pCfg->pColRefs, colRefSize);
}
pNew->pColRefs = pColRef;
return pNew; return pNew;
err: err:
if (pNew->pComment) taosMemoryFreeClear(pNew->pComment); if (pNew->pComment) taosMemoryFreeClear(pNew->pComment);

View File

@ -0,0 +1 @@
---

View File

@ -65,10 +65,11 @@ void generateInformationSchema(MockCatalogService* mcs) {
.addColumn("db_name", TSDB_DATA_TYPE_BINARY, TSDB_DB_NAME_LEN) .addColumn("db_name", TSDB_DATA_TYPE_BINARY, TSDB_DB_NAME_LEN)
.addColumn("stable_name", TSDB_DATA_TYPE_BINARY, TSDB_TABLE_NAME_LEN) .addColumn("stable_name", TSDB_DATA_TYPE_BINARY, TSDB_TABLE_NAME_LEN)
.done(); .done();
mcs->createTableBuilder(TSDB_INFORMATION_SCHEMA_DB, TSDB_INS_TABLE_TABLES, TSDB_SYSTEM_TABLE, 3) mcs->createTableBuilder(TSDB_INFORMATION_SCHEMA_DB, TSDB_INS_TABLE_TABLES, TSDB_SYSTEM_TABLE, 4)
.addColumn("table_name", TSDB_DATA_TYPE_BINARY, TSDB_TABLE_NAME_LEN) .addColumn("table_name", TSDB_DATA_TYPE_BINARY, TSDB_TABLE_NAME_LEN)
.addColumn("db_name", TSDB_DATA_TYPE_BINARY, TSDB_DB_NAME_LEN) .addColumn("db_name", TSDB_DATA_TYPE_BINARY, TSDB_DB_NAME_LEN)
.addColumn("stable_name", TSDB_DATA_TYPE_BINARY, TSDB_TABLE_NAME_LEN) .addColumn("stable_name", TSDB_DATA_TYPE_BINARY, TSDB_TABLE_NAME_LEN)
.addColumn("type", TSDB_DATA_TYPE_BINARY, 23)
.done(); .done();
mcs->createTableBuilder(TSDB_INFORMATION_SCHEMA_DB, TSDB_INS_TABLE_TABLE_DISTRIBUTED, TSDB_SYSTEM_TABLE, 2) mcs->createTableBuilder(TSDB_INFORMATION_SCHEMA_DB, TSDB_INS_TABLE_TABLE_DISTRIBUTED, TSDB_SYSTEM_TABLE, 2)
.addColumn("db_name", TSDB_DATA_TYPE_BINARY, TSDB_DB_NAME_LEN) .addColumn("db_name", TSDB_DATA_TYPE_BINARY, TSDB_DB_NAME_LEN)

View File

@ -122,7 +122,7 @@ TEST_F(ParserSelectTest, timelineFunc) {
run("select diff(ts) from (select _wstart as ts, count(*) from st1 partition by tbname interval(1d) order by ts)"); run("select diff(ts) from (select _wstart as ts, count(*) from st1 partition by tbname interval(1d) order by ts)");
run("select t1.* from st1s1 t1, (select _wstart as ts, count(*) from st1s2 partition by tbname interval(1d)) WHERE t1.ts = t2.ts", TSDB_CODE_PAR_NOT_SUPPORT_JOIN); run("select t1.* from st1s1 t1, (select _wstart as ts, count(*) from st1s2 partition by tbname interval(1d)) t2 WHERE t1.ts = t2.ts");
run("select t1.* from st1s1 t1, (select _wstart as ts, count(*) from st1s2 partition by tbname interval(1d) order by ts) t2 WHERE t1.ts = t2.ts"); run("select t1.* from st1s1 t1, (select _wstart as ts, count(*) from st1s2 partition by tbname interval(1d) order by ts) t2 WHERE t1.ts = t2.ts");
@ -505,8 +505,7 @@ TEST_F(ParserSelectTest, withoutFromSemanticCheck) {
TEST_F(ParserSelectTest, joinSemanticCheck) { TEST_F(ParserSelectTest, joinSemanticCheck) {
useDb("root", "test"); useDb("root", "test");
run("SELECT * FROM (SELECT tag1, SUM(c1) s FROM st1 GROUP BY tag1) t1, st1 t2 where t1.tag1 = t2.tag1", run("SELECT * FROM (SELECT tag1, SUM(c1) s FROM st1 GROUP BY tag1) t1, st1 t2 where t1.tag1 = t2.tag1");
TSDB_CODE_PAR_NOT_SUPPORT_JOIN);
run("SELECT count(*) FROM t1 a join t1 b on a.ts=b.ts where a.ts=b.ts"); run("SELECT count(*) FROM t1 a join t1 b on a.ts=b.ts where a.ts=b.ts");
} }

View File

@ -44,6 +44,32 @@ typedef struct SPhysiPlanContext {
#define planDebugL(param, ...) qDebugL("PLAN: " param, ##__VA_ARGS__) #define planDebugL(param, ...) qDebugL("PLAN: " param, ##__VA_ARGS__)
#define planTrace(param, ...) qTrace("PLAN: " param, ##__VA_ARGS__) #define planTrace(param, ...) qTrace("PLAN: " param, ##__VA_ARGS__)
#define PLAN_ERR_RET(c) \
do { \
int32_t _code = c; \
if (_code != TSDB_CODE_SUCCESS) { \
terrno = _code; \
return _code; \
} \
} while (0)
#define PLAN_RET(c) \
do { \
int32_t _code = c; \
if (_code != TSDB_CODE_SUCCESS) { \
terrno = _code; \
} \
return _code; \
} while (0)
#define PLAN_ERR_JRET(c) \
do { \
code = c; \
if (code != TSDB_CODE_SUCCESS) { \
terrno = code; \
goto _return; \
} \
} while (0)
int32_t generateUsageErrMsg(char* pBuf, int32_t len, int32_t errCode, ...); int32_t generateUsageErrMsg(char* pBuf, int32_t len, int32_t errCode, ...);
int32_t createColumnByRewriteExprs(SNodeList* pExprs, SNodeList** pList); int32_t createColumnByRewriteExprs(SNodeList* pExprs, SNodeList** pList);
int32_t createColumnByRewriteExpr(SNode* pExpr, SNodeList** pList); int32_t createColumnByRewriteExpr(SNode* pExpr, SNodeList** pList);

View File

@ -324,6 +324,44 @@ static SNode* createFirstCol(SRealTableNode* pTable, const SSchema* pSchema) {
return (SNode*)pCol; return (SNode*)pCol;
} }
static SNode* createVtbFirstCol(SVirtualTableNode* pTable, const SSchema* pSchema) {
SColumnNode* pCol = NULL;
terrno = nodesMakeNode(QUERY_NODE_COLUMN, (SNode**)&pCol);
if (NULL == pCol) {
return NULL;
}
pCol->node.resType.type = pSchema->type;
pCol->node.resType.bytes = pSchema->bytes;
pCol->tableId = pTable->pMeta->uid;
pCol->colId = pSchema->colId;
pCol->colType = COLUMN_TYPE_COLUMN;
tstrncpy(pCol->tableAlias, pTable->table.tableAlias, TSDB_TABLE_NAME_LEN);
tstrncpy(pCol->tableName, pTable->table.tableName, TSDB_TABLE_NAME_LEN);
pCol->isPk = pSchema->flags & COL_IS_KEY;
pCol->tableHasPk = false;
pCol->numOfPKs = 0;
pCol->isPrimTs = true;
tstrncpy(pCol->colName, pSchema->name, TSDB_COL_NAME_LEN);
return (SNode*)pCol;
}
static int32_t addVtbPrimaryTsCol(SVirtualTableNode* pTable, SNodeList** pCols) {
bool found = false;
SNode* pCol = NULL;
SSchema* pSchema = &pTable->pMeta->schema[0];
FOREACH(pCol, *pCols) {
if (pSchema->colId == ((SColumnNode*)pCol)->colId) {
found = true;
break;
}
}
if (!found) {
return nodesListMakeStrictAppend(pCols, createVtbFirstCol(pTable, pSchema));
}
return TSDB_CODE_SUCCESS;
}
static int32_t addPrimaryTsCol(SRealTableNode* pTable, SNodeList** pCols) { static int32_t addPrimaryTsCol(SRealTableNode* pTable, SNodeList** pCols) {
bool found = false; bool found = false;
SNode* pCol = NULL; SNode* pCol = NULL;
@ -492,7 +530,6 @@ static int32_t createScanLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect
// rewrite the expression in subsequent clauses // rewrite the expression in subsequent clauses
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
SNodeList* pNewScanPseudoCols = NULL;
code = rewriteExprsForSelect(pScan->pScanPseudoCols, pSelect, SQL_CLAUSE_FROM, NULL); code = rewriteExprsForSelect(pScan->pScanPseudoCols, pSelect, SQL_CLAUSE_FROM, NULL);
/* /*
if (TSDB_CODE_SUCCESS == code && NULL != pScan->pScanPseudoCols) { if (TSDB_CODE_SUCCESS == code && NULL != pScan->pScanPseudoCols) {
@ -554,6 +591,28 @@ static int32_t createScanLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect
} else { } else {
nodesDestroyNode((SNode*)pScan); nodesDestroyNode((SNode*)pScan);
} }
pScan->virtualStableScan = false;
return code;
}
static int32_t createRefScanLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SRealTableNode* pRealTable,
SLogicNode** pLogicNode) {
SScanLogicNode* pScan = NULL;
int32_t code = makeScanLogicNode(pCxt, pRealTable, pSelect->hasRepeatScanFuncs, (SLogicNode**)&pScan);
pScan->node.groupAction = GROUP_ACTION_NONE;
pScan->node.resultDataOrder = DATA_ORDER_LEVEL_GLOBAL;
if (TSDB_CODE_SUCCESS == code) {
pScan->scanType = getScanType(pCxt, pScan->pScanPseudoCols, pScan->pScanCols, pScan->tableType, pSelect->tagScan);
}
if (TSDB_CODE_SUCCESS == code) {
code = addDefaultScanCol(pRealTable, &pScan->pScanCols);
}
*pLogicNode = (SLogicNode*)pScan;
pCxt->hasScan = true;
return code; return code;
} }
@ -720,8 +779,377 @@ static int32_t createJoinLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect
return code; return code;
} }
static int32_t findRefTableNode(SNodeList *refTableList, const char *dbName, const char *tableName, SNode **pRefTable) {
SNode *pRef = NULL;
FOREACH(pRef, refTableList) {
if (0 == strcasecmp(((SRealTableNode*)pRef)->table.tableName, tableName) &&
0 == strcasecmp(((SRealTableNode*)pRef)->table.dbName, dbName)) {
PLAN_RET(nodesCloneNode(pRef, pRefTable));
}
}
return TSDB_CODE_NOT_FOUND;
}
static int32_t findRefColId(SNode *pRefTable, const char *colName, col_id_t *colId) {
SRealTableNode *pRealTable = (SRealTableNode*)pRefTable;
for (int32_t i = 0; i < pRealTable->pMeta->tableInfo.numOfColumns; ++i) {
if (0 == strcasecmp(pRealTable->pMeta->schema[i].name, colName)) {
*colId = pRealTable->pMeta->schema[i].colId;
return TSDB_CODE_SUCCESS;
}
}
return TSDB_CODE_NOT_FOUND;
}
static int32_t scanAddCol(SLogicNode* pLogicNode, SColRef* colRef, STableNode* pVirtualTableNode, const SSchema* pSchema, col_id_t colId) {
int32_t code = TSDB_CODE_SUCCESS;
SColumnNode *pRefTableScanCol = NULL;
SScanLogicNode *pLogicScan = (SScanLogicNode*)pLogicNode;
PLAN_ERR_JRET(nodesMakeNode(QUERY_NODE_COLUMN, (SNode**)&pRefTableScanCol));
if (colRef) {
tstrncpy(pRefTableScanCol->tableAlias, colRef->refTableName, sizeof(pRefTableScanCol->tableAlias));
tstrncpy(pRefTableScanCol->dbName, colRef->refDbName, sizeof(pRefTableScanCol->dbName));
tstrncpy(pRefTableScanCol->tableName, colRef->refTableName, sizeof(pRefTableScanCol->tableName));
tstrncpy(pRefTableScanCol->colName, colRef->refColName, sizeof(pRefTableScanCol->colName));
} else {
tstrncpy(pRefTableScanCol->tableAlias, pVirtualTableNode->tableAlias, sizeof(pRefTableScanCol->tableAlias));
tstrncpy(pRefTableScanCol->dbName, pVirtualTableNode->dbName, sizeof(pRefTableScanCol->dbName));
tstrncpy(pRefTableScanCol->tableName, pVirtualTableNode->tableName, sizeof(pRefTableScanCol->tableName));
tstrncpy(pRefTableScanCol->colName, pSchema->name, sizeof(pRefTableScanCol->colName));
}
// eliminate duplicate scan cols.
SNode *pCol = NULL;
FOREACH(pCol, pLogicScan->pScanCols) {
if (0 == strncmp(((SColumnNode*)pCol)->colName, pRefTableScanCol->colName, TSDB_COL_NAME_LEN) &&
0 == strncmp(((SColumnNode*)pCol)->tableName, pRefTableScanCol->tableName, TSDB_TABLE_NAME_LEN) &&
0 == strncmp(((SColumnNode*)pCol)->dbName, pRefTableScanCol->dbName, TSDB_DB_NAME_LEN)) {
nodesDestroyNode((SNode*)pRefTableScanCol);
return TSDB_CODE_SUCCESS;
}
}
pRefTableScanCol->colId = colId;
pRefTableScanCol->tableId = pLogicScan->tableId;
pRefTableScanCol->tableType = pLogicScan->tableType;
pRefTableScanCol->node.resType.type = pSchema->type;
pRefTableScanCol->node.resType.bytes = pSchema->bytes;
pRefTableScanCol->colType = COLUMN_TYPE_COLUMN;
pRefTableScanCol->isPk = false;
pRefTableScanCol->tableHasPk = false;
pRefTableScanCol->numOfPKs = 0;
pRefTableScanCol->hasRef = false;
pRefTableScanCol->hasDep = true;
PLAN_ERR_JRET(nodesListMakeAppend(&pLogicScan->pScanCols, (SNode*)pRefTableScanCol));
return code;
_return:
nodesDestroyNode((SNode*)pRefTableScanCol);
return code;
}
static int32_t checkColRefType(const SSchema* vtbSchema, const SSchema* refSchema) {
if (vtbSchema->type != refSchema->type || vtbSchema->bytes != refSchema->bytes) {
qError("virtual table column:%s type mismatch, virtual table column type:%d, bytes:%d, "
"ref table column:%s, type:%d, bytes:%d",
vtbSchema->name, vtbSchema->type, vtbSchema->bytes, refSchema->name, refSchema->type, refSchema->bytes);
return TSDB_CODE_PAR_INVALID_REF_COLUMN_TYPE;
}
return TSDB_CODE_SUCCESS;
}
static int32_t addSubScanNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SVirtualTableNode* pVirtualTable,
int32_t colRefIndex, int32_t schemaIndex, SHashObj *refTablesMap) {
int32_t code = TSDB_CODE_SUCCESS;
col_id_t colId = 0;
SColRef *pColRef = &pVirtualTable->pMeta->colRef[colRefIndex];
SNode *pRefTable = NULL;
SLogicNode *pRefScan = NULL;
bool put = false;
PLAN_ERR_JRET(findRefTableNode(pVirtualTable->refTables, pColRef->refDbName, pColRef->refTableName, &pRefTable));
PLAN_ERR_JRET(findRefColId(pRefTable, pColRef->refColName, &colId));
char tableNameKey[TSDB_TABLE_FNAME_LEN] = {0};
strcat(tableNameKey, pColRef->refDbName);
strcat(tableNameKey, ".");
strcat(tableNameKey, pColRef->refTableName);
SLogicNode **ppRefScan = (SLogicNode **)taosHashGet(refTablesMap, &tableNameKey, strlen(tableNameKey));
if (NULL == ppRefScan) {
PLAN_ERR_JRET(createRefScanLogicNode(pCxt, pSelect, (SRealTableNode*)pRefTable, &pRefScan));
PLAN_ERR_JRET(checkColRefType(&pVirtualTable->pMeta->schema[schemaIndex], &((SRealTableNode*)pRefTable)->pMeta->schema[colId - 1]));
PLAN_ERR_JRET(scanAddCol(pRefScan, pColRef, &pVirtualTable->table, &pVirtualTable->pMeta->schema[schemaIndex], colId));
PLAN_ERR_JRET(taosHashPut(refTablesMap, &tableNameKey, strlen(tableNameKey), &pRefScan, POINTER_BYTES));
put = true;
} else {
pRefScan = *ppRefScan;
PLAN_ERR_JRET(checkColRefType(&pVirtualTable->pMeta->schema[schemaIndex], &((SRealTableNode*)pRefTable)->pMeta->schema[colId - 1]));
PLAN_ERR_JRET(scanAddCol(pRefScan, pColRef, &pVirtualTable->table, &pVirtualTable->pMeta->schema[schemaIndex], colId));
}
nodesDestroyNode((SNode*)pRefTable);
return code;
_return:
nodesDestroyNode((SNode*)pRefTable);
if (!put) {
nodesDestroyNode((SNode*)pRefScan);
}
return code;
}
static int32_t makeVirtualScanLogicNode(SLogicPlanContext* pCxt, SVirtualTableNode* pVirtualTable,
SVirtualScanLogicNode* pScan) {
TSWAP(pScan->pVgroupList, pVirtualTable->pVgroupList);
pScan->tableId = pVirtualTable->pMeta->uid;
pScan->stableId = pVirtualTable->pMeta->suid;
pScan->tableType = pVirtualTable->pMeta->tableType;
pScan->tableName.type = TSDB_TABLE_NAME_T;
pScan->tableName.acctId = pCxt->pPlanCxt->acctId;
tstrncpy(pScan->tableName.dbname, pVirtualTable->table.dbName, TSDB_DB_NAME_LEN);
tstrncpy(pScan->tableName.tname, pVirtualTable->table.tableName, TSDB_TABLE_NAME_LEN);
return TSDB_CODE_SUCCESS;
}
static void destroyScanLogicNode(void* data) {
if (data == NULL) {
return;
}
SScanLogicNode* pNode = *(SScanLogicNode **)data;
nodesDestroyNode((SNode*)pNode);
}
static int32_t findColRefIndex(SColRef* pColRef, SVirtualTableNode* pVirtualTable, col_id_t colId) {
for (int32_t i = 0; i < pVirtualTable->pMeta->numOfColRefs; i++) {
if (pColRef[i].hasRef && pColRef[i].id == colId) {
return i;
}
}
return -1;
}
static int32_t findSchemaIndex(const SSchema* pSchema, int32_t numOfColumns, col_id_t colId) {
for (int32_t i = 0; i < numOfColumns; i++) {
if (pSchema[i].colId == colId) {
return i;
}
}
return -1;
}
static int32_t eliminateDupScanCols(SNodeList* pScanCols) {
int32_t code = TSDB_CODE_SUCCESS;
SNode* pCols = NULL;
SHashObj* colsMap = taosHashInit(LIST_LENGTH(pScanCols), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
if (NULL == colsMap) {
return terrno;
}
FOREACH(pCols, pScanCols) {
SColumnNode* pCol = (SColumnNode*)pCols;
if (!pCol->hasRef) {
continue;
}
char key[TSDB_COL_FNAME_EX_LEN] = {0};
strcat(key, pCol->refDbName);
strcat(key, ".");
strcat(key, pCol->refTableName);
strcat(key, ".");
strcat(key, pCol->refColName);
if (NULL != taosHashGet(colsMap, key, strlen(key))) {
ERASE_NODE(pScanCols);
} else {
PLAN_ERR_JRET(taosHashPut(colsMap, key, strlen(key), NULL, 0));
}
}
_return:
taosHashCleanup(colsMap);
return code;
}
static int32_t createVirtualSuperTableLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect,
SVirtualTableNode* pVirtualTable, SVirtualScanLogicNode* pVtableScan,
SLogicNode** pLogicNode) {
int32_t code = TSDB_CODE_SUCCESS;
SLogicNode* pRealTableScan = NULL;
SDynQueryCtrlLogicNode* pDynCtrl = NULL;
SNode* pNode = NULL;
bool scanAllCols = true;
// Virtual table scan node -> Real table scan node
PLAN_ERR_JRET(createScanLogicNode(pCxt, pSelect, (SRealTableNode*)nodesListGetNode(pVirtualTable->refTables, 0), &pRealTableScan));
PLAN_ERR_JRET(addVtbPrimaryTsCol(pVirtualTable, &pVtableScan->pScanCols));
FOREACH(pNode, pVtableScan->pScanCols) {
SColumnNode *pCol = (SColumnNode*)pNode;
if (pCol->isPrimTs || pCol->colId == PRIMARYKEY_TIMESTAMP_COL_ID) {
// do nothing
} else {
scanAllCols &= false;
}
}
if (scanAllCols) {
nodesDestroyList(((SScanLogicNode*)pRealTableScan)->node.pTargets);
((SScanLogicNode*)pRealTableScan)->node.pTargets = NULL;
pVtableScan->scanAllCols = true;
for (int32_t i = 0; i < pVirtualTable->pMeta->tableInfo.numOfColumns; i++) {
if (pVirtualTable->pMeta->schema[i].colId == PRIMARYKEY_TIMESTAMP_COL_ID) {
continue;
} else {
PLAN_ERR_JRET(scanAddCol(pRealTableScan, NULL, &pVirtualTable->table, &pVirtualTable->pMeta->schema[i], pVirtualTable->pMeta->schema[i].colId));
}
}
PLAN_ERR_JRET(createColumnByRewriteExprs(((SScanLogicNode*)pRealTableScan)->pScanCols, &((SScanLogicNode*)pRealTableScan)->node.pTargets));
}
((SScanLogicNode *)pRealTableScan)->node.dynamicOp = true;
((SScanLogicNode *)pRealTableScan)->virtualStableScan = true;
PLAN_ERR_JRET(nodesListStrictAppend(pVtableScan->node.pChildren, (SNode*)(pRealTableScan)));
pRealTableScan->pParent = (SLogicNode *)pVtableScan;
PLAN_ERR_JRET(createColumnByRewriteExprs(pVtableScan->pScanCols, &pVtableScan->node.pTargets));
PLAN_ERR_JRET(createColumnByRewriteExprs(pVtableScan->pScanPseudoCols, &pVtableScan->node.pTargets));
// Dynamic query control node -> Virtual table scan node -> Real table scan node
PLAN_ERR_JRET(nodesMakeNode(QUERY_NODE_LOGIC_PLAN_DYN_QUERY_CTRL, (SNode**)&pDynCtrl));
pDynCtrl->qType = DYN_QTYPE_VTB_SCAN;
pDynCtrl->vtbScan.scanAllCols = pVtableScan->scanAllCols;
pDynCtrl->vtbScan.suid = pVtableScan->stableId;
PLAN_ERR_JRET(nodesListMakeStrictAppend(&pDynCtrl->node.pChildren, (SNode*)pVtableScan));
PLAN_ERR_JRET(nodesCloneList(pVtableScan->node.pTargets, &pDynCtrl->node.pTargets));
TSWAP(pVtableScan->pVgroupList, pDynCtrl->vtbScan.pVgroupList);
pVtableScan->node.pParent = (SLogicNode*)pDynCtrl;
pVtableScan->node.dynamicOp = true;
*pLogicNode = (SLogicNode*)pDynCtrl;
pCxt->pPlanCxt->virtualStableQuery = true;
return code;
_return:
planError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(code));
nodesDestroyNode((SNode*)pRealTableScan);
nodesDestroyNode((SNode*)pDynCtrl);
return code;
}
static int32_t createVirtualNormalChildTableLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect,
SVirtualTableNode* pVirtualTable, SVirtualScanLogicNode* pVtableScan,
SLogicNode** pLogicNode) {
int32_t code = TSDB_CODE_SUCCESS;
SNode* pNode = NULL;
int32_t slotId = 0;
bool scanAllCols = true;
SHashObj* pRefTablesMap = NULL;
pRefTablesMap = taosHashInit(LIST_LENGTH(pVtableScan->pScanCols), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
if (NULL == pRefTablesMap) {
PLAN_ERR_JRET(terrno);
}
PLAN_ERR_JRET(eliminateDupScanCols(pVtableScan->pScanCols));
FOREACH(pNode, pVtableScan->pScanCols) {
SColumnNode *pCol = (SColumnNode*)pNode;
int32_t colRefIndex = findColRefIndex(pVirtualTable->pMeta->colRef, pVirtualTable, pCol->colId);
int32_t schemaIndex = findSchemaIndex(pVirtualTable->pMeta->schema, pVirtualTable->pMeta->tableInfo.numOfColumns, pCol->colId);
if (colRefIndex != -1 && pVirtualTable->pMeta->colRef[colRefIndex].hasRef) {
if (pCol->isPrimTs || pCol->colId == PRIMARYKEY_TIMESTAMP_COL_ID) {
PLAN_ERR_JRET(TSDB_CODE_VTABLE_PRIMTS_HAS_REF);
}
scanAllCols &= false;
PLAN_ERR_JRET(addSubScanNode(pCxt, pSelect, pVirtualTable, colRefIndex, schemaIndex, pRefTablesMap));
} else if (pCol->isPrimTs || pCol->colId == PRIMARYKEY_TIMESTAMP_COL_ID) {
// do nothing
} else {
scanAllCols &= false;
}
}
if (scanAllCols) {
pVtableScan->scanAllCols = true;
taosHashClear(pRefTablesMap);
for (int32_t i = 0; i < pVirtualTable->pMeta->tableInfo.numOfColumns; i++) {
if (pVirtualTable->pMeta->schema[i].colId == PRIMARYKEY_TIMESTAMP_COL_ID) {
continue;
} else {
col_id_t colRefIndex = (col_id_t)findColRefIndex(pVirtualTable->pMeta->colRef, pVirtualTable, pVirtualTable->pMeta->schema[i].colId);
if (colRefIndex != -1 && pVirtualTable->pMeta->colRef[colRefIndex].hasRef) {
PLAN_ERR_JRET(addSubScanNode(pCxt, pSelect, pVirtualTable, colRefIndex, i, pRefTablesMap));
}
}
}
}
// Iterate the table map, build scan logic node for each origin table and add these node to vtable scan's child list.
void* pIter = NULL;
while ((pIter = taosHashIterate(pRefTablesMap, pIter))) {
SScanLogicNode **pRefScanNode = (SScanLogicNode**)pIter;
PLAN_ERR_JRET(createColumnByRewriteExprs((*pRefScanNode)->pScanCols, &(*pRefScanNode)->node.pTargets));
PLAN_ERR_JRET(nodesListStrictAppend(pVtableScan->node.pChildren, (SNode*)(*pRefScanNode)));
}
// set output
PLAN_ERR_JRET(createColumnByRewriteExprs(pVtableScan->pScanCols, &pVtableScan->node.pTargets));
PLAN_ERR_JRET(createColumnByRewriteExprs(pVtableScan->pScanPseudoCols, &pVtableScan->node.pTargets));
*pLogicNode = (SLogicNode*)pVtableScan;
taosHashCleanup(pRefTablesMap);
return code;
_return:
planError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(code));
taosHashSetFreeFp(pRefTablesMap, destroyScanLogicNode);
taosHashCleanup(pRefTablesMap);
return code;
}
static int32_t createVirtualTableLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect,
SVirtualTableNode* pVirtualTable, SLogicNode** pLogicNode) {
int32_t code = TSDB_CODE_SUCCESS;
SVirtualScanLogicNode *pVtableScan = NULL;
PLAN_ERR_JRET(nodesMakeNode(QUERY_NODE_LOGIC_PLAN_VIRTUAL_TABLE_SCAN, (SNode**)&pVtableScan));
PLAN_ERR_JRET(nodesMakeList(&pVtableScan->node.pChildren));
PLAN_ERR_JRET(makeVirtualScanLogicNode(pCxt, pVirtualTable, pVtableScan));
PLAN_ERR_JRET(nodesCollectColumns(pSelect, SQL_CLAUSE_FROM, pVirtualTable->table.tableAlias, COLLECT_COL_TYPE_COL,
&pVtableScan->pScanCols));
PLAN_ERR_JRET(nodesCollectColumns(pSelect, SQL_CLAUSE_FROM, pVirtualTable->table.tableAlias, COLLECT_COL_TYPE_TAG,
&pVtableScan->pScanPseudoCols));
PLAN_ERR_JRET(nodesCollectFuncs(pSelect, SQL_CLAUSE_FROM, pVirtualTable->table.tableAlias, fmIsScanPseudoColumnFunc,
&pVtableScan->pScanPseudoCols));
PLAN_ERR_JRET(rewriteExprsForSelect(pVtableScan->pScanPseudoCols, pSelect, SQL_CLAUSE_FROM, NULL));
switch (pVtableScan->tableType) {
case TSDB_SUPER_TABLE:
PLAN_ERR_JRET(createVirtualSuperTableLogicNode(pCxt, pSelect, pVirtualTable, pVtableScan, pLogicNode));
break;
case TSDB_VIRTUAL_NORMAL_TABLE:
case TSDB_VIRTUAL_CHILD_TABLE:
PLAN_ERR_JRET(createVirtualNormalChildTableLogicNode(pCxt, pSelect, pVirtualTable, pVtableScan, pLogicNode));
break;
default:
PLAN_ERR_JRET(TSDB_CODE_PLAN_INVALID_TABLE_TYPE);
}
return code;
_return:
planError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(code));
nodesDestroyNode((SNode*)pVtableScan);
return code;
}
static int32_t doCreateLogicNodeByTable(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SNode* pTable, static int32_t doCreateLogicNodeByTable(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SNode* pTable,
SLogicNode** pLogicNode) { SLogicNode** pLogicNode) {
int32_t code = TSDB_CODE_SUCCESS;
switch (nodeType(pTable)) { switch (nodeType(pTable)) {
case QUERY_NODE_REAL_TABLE: case QUERY_NODE_REAL_TABLE:
return createScanLogicNode(pCxt, pSelect, (SRealTableNode*)pTable, pLogicNode); return createScanLogicNode(pCxt, pSelect, (SRealTableNode*)pTable, pLogicNode);
@ -729,27 +1157,38 @@ static int32_t doCreateLogicNodeByTable(SLogicPlanContext* pCxt, SSelectStmt* pS
return createSubqueryLogicNode(pCxt, pSelect, (STempTableNode*)pTable, pLogicNode); return createSubqueryLogicNode(pCxt, pSelect, (STempTableNode*)pTable, pLogicNode);
case QUERY_NODE_JOIN_TABLE: case QUERY_NODE_JOIN_TABLE:
return createJoinLogicNode(pCxt, pSelect, (SJoinTableNode*)pTable, pLogicNode); return createJoinLogicNode(pCxt, pSelect, (SJoinTableNode*)pTable, pLogicNode);
case QUERY_NODE_VIRTUAL_TABLE:
return createVirtualTableLogicNode(pCxt, pSelect, (SVirtualTableNode*)pTable, pLogicNode);
default: default:
code = TSDB_CODE_PLAN_INVALID_TABLE_TYPE;
break; break;
} }
return TSDB_CODE_FAILED; planError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(code));
return code;
} }
static int32_t createLogicNodeByTable(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SNode* pTable, static int32_t createLogicNodeByTable(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SNode* pTable,
SLogicNode** pLogicNode) { SLogicNode** pLogicNode) {
SLogicNode* pNode = NULL; SLogicNode* pNode = NULL;
int32_t code = doCreateLogicNodeByTable(pCxt, pSelect, pTable, &pNode); int32_t code = TSDB_CODE_SUCCESS;
if (TSDB_CODE_SUCCESS == code) { PLAN_ERR_JRET(doCreateLogicNodeByTable(pCxt, pSelect, pTable, &pNode));
if (nodeType(pNode) == QUERY_NODE_LOGIC_PLAN_DYN_QUERY_CTRL) {
SLogicNode* pVScan = (SLogicNode*)nodesListGetNode(((SDynQueryCtrlLogicNode*)pNode)->node.pChildren, 0);
pVScan->pConditions = NULL;
PLAN_ERR_JRET(nodesCloneNode(pSelect->pWhere, &pVScan->pConditions));
} else {
pNode->pConditions = NULL; pNode->pConditions = NULL;
code = nodesCloneNode(pSelect->pWhere, &pNode->pConditions); PLAN_ERR_JRET(nodesCloneNode(pSelect->pWhere, &pNode->pConditions));
if (NULL != pSelect->pWhere && NULL == pNode->pConditions) {
nodesDestroyNode((SNode*)pNode);
return code;
} }
pNode->precision = pSelect->precision; pNode->precision = pSelect->precision;
*pLogicNode = pNode; *pLogicNode = pNode;
pCxt->pCurrRoot = pNode; pCxt->pCurrRoot = pNode;
} return code;
_return:
planError("%s failed since %s", __func__, tstrerror(code));
nodesDestroyNode((SNode*)pNode);
return code; return code;
} }
@ -2065,10 +2504,14 @@ static int32_t getMsgType(ENodeType sqlType) {
case QUERY_NODE_CREATE_TABLE_STMT: case QUERY_NODE_CREATE_TABLE_STMT:
case QUERY_NODE_CREATE_MULTI_TABLES_STMT: case QUERY_NODE_CREATE_MULTI_TABLES_STMT:
case QUERY_NODE_CREATE_SUBTABLE_FROM_FILE_CLAUSE: case QUERY_NODE_CREATE_SUBTABLE_FROM_FILE_CLAUSE:
case QUERY_NODE_CREATE_VIRTUAL_TABLE_STMT:
case QUERY_NODE_CREATE_VIRTUAL_SUBTABLE_STMT:
return TDMT_VND_CREATE_TABLE; return TDMT_VND_CREATE_TABLE;
case QUERY_NODE_DROP_TABLE_STMT: case QUERY_NODE_DROP_TABLE_STMT:
case QUERY_NODE_DROP_VIRTUAL_TABLE_STMT:
return TDMT_VND_DROP_TABLE; return TDMT_VND_DROP_TABLE;
case QUERY_NODE_ALTER_TABLE_STMT: case QUERY_NODE_ALTER_TABLE_STMT:
case QUERY_NODE_ALTER_VIRTUAL_TABLE_STMT:
return TDMT_VND_ALTER_TABLE; return TDMT_VND_ALTER_TABLE;
case QUERY_NODE_FLUSH_DATABASE_STMT: case QUERY_NODE_FLUSH_DATABASE_STMT:
return TDMT_VND_COMMIT; return TDMT_VND_COMMIT;

View File

@ -2190,6 +2190,14 @@ static int32_t pdcTrivialPushDown(SOptimizeContext* pCxt, SLogicNode* pLogicNode
return code; return code;
} }
static int32_t pdcDealVirtualTable(SOptimizeContext* pCxt, SVirtualScanLogicNode* pVScan) {
// TODO: remove it after full implementation of pushing down to child
if (1 != LIST_LENGTH(pVScan->node.pChildren) || 0 != LIST_LENGTH(pVScan->pScanPseudoCols) || pVScan->tableType == TSDB_SUPER_TABLE) {
return TSDB_CODE_SUCCESS;
}
return pdcTrivialPushDown(pCxt, (SLogicNode*)pVScan);
}
static int32_t pdcOptimizeImpl(SOptimizeContext* pCxt, SLogicNode* pLogicNode) { static int32_t pdcOptimizeImpl(SOptimizeContext* pCxt, SLogicNode* pLogicNode) {
int32_t code = TSDB_CODE_SUCCESS; int32_t code = TSDB_CODE_SUCCESS;
switch (nodeType(pLogicNode)) { switch (nodeType(pLogicNode)) {
@ -2209,6 +2217,9 @@ static int32_t pdcOptimizeImpl(SOptimizeContext* pCxt, SLogicNode* pLogicNode) {
case QUERY_NODE_LOGIC_PLAN_PARTITION: case QUERY_NODE_LOGIC_PLAN_PARTITION:
code = pdcTrivialPushDown(pCxt, pLogicNode); code = pdcTrivialPushDown(pCxt, pLogicNode);
break; break;
case QUERY_NODE_LOGIC_PLAN_VIRTUAL_TABLE_SCAN:
code = pdcDealVirtualTable(pCxt, (SVirtualScanLogicNode*)pLogicNode);
break;
default: default:
break; break;
} }
@ -3525,7 +3536,8 @@ static bool eliminateProjOptMayBeOptimized(SLogicNode* pNode, void* pCtx) {
if (NULL != pNode->pParent && if (NULL != pNode->pParent &&
(QUERY_NODE_LOGIC_PLAN_PROJECT != nodeType(pNode) || 1 != LIST_LENGTH(pNode->pChildren) || (QUERY_NODE_LOGIC_PLAN_PROJECT != nodeType(pNode) || 1 != LIST_LENGTH(pNode->pChildren) ||
QUERY_NODE_LOGIC_PLAN_SCAN != nodeType(nodesListGetNode(pNode->pChildren, 0)) || QUERY_NODE_LOGIC_PLAN_SCAN != nodeType(nodesListGetNode(pNode->pChildren, 0)) ||
QUERY_NODE_LOGIC_PLAN_JOIN != nodeType(pNode->pParent))) { QUERY_NODE_LOGIC_PLAN_JOIN != nodeType(pNode->pParent) ||
QUERY_NODE_LOGIC_PLAN_VIRTUAL_TABLE_SCAN != nodeType(pNode->pParent))) {
return false; return false;
} }
@ -3538,6 +3550,9 @@ static bool eliminateProjOptMayBeOptimized(SLogicNode* pNode, void* pCtx) {
if (LIST_LENGTH(pChild->pTargets) != LIST_LENGTH(pNode->pTargets)) { if (LIST_LENGTH(pChild->pTargets) != LIST_LENGTH(pNode->pTargets)) {
return false; return false;
} }
if (((SDynQueryCtrlLogicNode*)pChild)->qType == DYN_QTYPE_VTB_SCAN) {
return false;
}
} }
SProjectLogicNode* pProjectNode = (SProjectLogicNode*)pNode; SProjectLogicNode* pProjectNode = (SProjectLogicNode*)pNode;
@ -3594,6 +3609,9 @@ static bool eliminateProjOptCanChildConditionUseChildTargets(SLogicNode* pChild,
if (!cxt.canUse) return false; if (!cxt.canUse) return false;
} }
if (QUERY_NODE_LOGIC_PLAN_VIRTUAL_TABLE_SCAN == nodeType(pChild)) {
return false;
}
if (QUERY_NODE_LOGIC_PLAN_JOIN == nodeType(pChild) && ((SJoinLogicNode*)pChild)->joinAlgo != JOIN_ALGO_UNKNOWN) { if (QUERY_NODE_LOGIC_PLAN_JOIN == nodeType(pChild) && ((SJoinLogicNode*)pChild)->joinAlgo != JOIN_ALGO_UNKNOWN) {
return false; return false;
} }
@ -4161,8 +4179,7 @@ static int32_t rewriteUniqueOptCreateProjectCol(SFunctionNode* pFunc, SNode** pp
if (FUNCTION_TYPE_UNIQUE == pFunc->funcType) { if (FUNCTION_TYPE_UNIQUE == pFunc->funcType) {
SExprNode* pExpr = (SExprNode*)nodesListGetNode(pFunc->pParameterList, 0); SExprNode* pExpr = (SExprNode*)nodesListGetNode(pFunc->pParameterList, 0);
if (QUERY_NODE_COLUMN == nodeType(pExpr)) { if (QUERY_NODE_COLUMN == nodeType(pExpr)) {
tstrncpy(pCol->tableAlias, ((SColumnNode*)pExpr)->tableAlias, TSDB_TABLE_NAME_LEN); PLAN_ERR_RET(nodesCloneNode((SNode*)pExpr, (SNode**)&pCol));
tstrncpy(pCol->colName, ((SColumnNode*)pExpr)->colName, TSDB_COL_NAME_LEN);
} else { } else {
tstrncpy(pCol->colName, pExpr->aliasName, TSDB_COL_NAME_LEN); tstrncpy(pCol->colName, pExpr->aliasName, TSDB_COL_NAME_LEN);
} }
@ -6207,6 +6224,7 @@ static int32_t stbJoinOptCreateTagScanNode(SLogicNode* pJoin, SNodeList** ppList
} }
SScanLogicNode* pScan = (SScanLogicNode*)pNode; SScanLogicNode* pScan = (SScanLogicNode*)pNode;
// If join node's two children are scan on same table and on only one vgroup, don't need to split. Vice versa.
if (pScan->pVgroupList && 1 == pScan->pVgroupList->numOfVgroups) { if (pScan->pVgroupList && 1 == pScan->pVgroupList->numOfVgroups) {
if (NULL == pPrev || 0 == strcmp(pPrev->dbname, pScan->tableName.dbname)) { if (NULL == pPrev || 0 == strcmp(pPrev->dbname, pScan->tableName.dbname)) {
pPrev = &pScan->tableName; pPrev = &pScan->tableName;
@ -7707,6 +7725,289 @@ static int32_t tsmaOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan
return code; return code;
} }
static bool eliminateVirtualScanMayBeOptimized(SLogicNode* pNode, void* pCtx) {
if (NULL == pNode->pParent) {
return false;
}
if (nodeType(pNode) != QUERY_NODE_LOGIC_PLAN_VIRTUAL_TABLE_SCAN || LIST_LENGTH(pNode->pChildren) != 1) {
return false;
}
if (pNode->pConditions || ((SVirtualScanLogicNode *)pNode)->pScanPseudoCols) {
return false;
}
SVirtualScanLogicNode* pVScan = (SVirtualScanLogicNode *)pNode;
SNode* pCol;
FOREACH(pCol, pVScan->pScanCols) {
SColumnNode* pScanCol = (SColumnNode* )pCol;
if (!pScanCol->hasRef) {
// if col don't have ref, it can't be eliminated. If the vscan operator is eliminated,
// the upper operator can't find the right slot id.
return false;
}
}
return true;
}
static int32_t eliminateVirtualScanOptimizeImpl(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan,
SLogicNode* pVirtualScanNode) {
SNode* pTargets = NULL;
SNode* pSibling = NULL;
FOREACH(pSibling, pVirtualScanNode->pParent->pChildren) {
if (nodesEqualNode(pSibling, (SNode*)pVirtualScanNode)) {
SNode* pChild;
FOREACH(pChild, pVirtualScanNode->pChildren) {
// clear the mask to try scanPathOptimize again.
OPTIMIZE_FLAG_CLEAR_MASK(((SScanLogicNode*)pChild)->node.optimizedFlag, OPTIMIZE_FLAG_SCAN_PATH);
((SLogicNode*)pChild)->pParent = pVirtualScanNode->pParent;
}
INSERT_LIST(pVirtualScanNode->pParent->pChildren, pVirtualScanNode->pChildren);
pVirtualScanNode->pChildren = NULL;
ERASE_NODE(pVirtualScanNode->pParent->pChildren);
pCxt->optimized = true;
return TSDB_CODE_SUCCESS;
}
}
return TSDB_CODE_PLAN_INTERNAL_ERROR;
}
// eliminate virtual scan node when it has only one child
static int32_t eliminateVirtualScanOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan) {
SLogicNode* pVirtualScanNode = optFindPossibleNode(pLogicSubplan->pNode, eliminateVirtualScanMayBeOptimized, NULL);
if (NULL == pVirtualScanNode) {
return TSDB_CODE_SUCCESS;
}
return eliminateVirtualScanOptimizeImpl(pCxt, pLogicSubplan, pVirtualScanNode);
}
static bool pdaMayBeOptimized(SLogicNode* pNode, void* pCtx) {
if (QUERY_NODE_LOGIC_PLAN_AGG != nodeType(pNode) || 1 != LIST_LENGTH(pNode->pChildren) ||
QUERY_NODE_LOGIC_PLAN_VIRTUAL_TABLE_SCAN != nodeType(nodesListGetNode(pNode->pChildren, 0))) {
return false;
}
// virtual table scan should have more than one child.
if (LIST_LENGTH(((SVirtualScanLogicNode *)nodesListGetNode(pNode->pChildren, 0))->node.pChildren) < 2) {
return false;
}
SVirtualScanLogicNode* pVScan = (SVirtualScanLogicNode *)nodesListGetNode(pNode->pChildren, 0);
SNode* pCol;
FOREACH(pCol, pVScan->pScanCols) {
SColumnNode* pScanCol = (SColumnNode* )pCol;
if (!pScanCol->hasRef) {
// if col don't have ref, it can't be eliminated. If the vscan operator is eliminated,
// the upper operator can't find the right slot id.
return false;
}
}
SAggLogicNode* pAgg = (SAggLogicNode*)pNode;
SNode* pAggFunc = NULL;
FOREACH(pAggFunc, pAgg->pAggFuncs) {
SFunctionNode *pFunc = (SFunctionNode *)pAggFunc;
if (fmIsSelectFunc(pFunc->funcId) || fmIsGroupKeyFunc(pFunc->funcId)) {
return false;
}
}
if (pAgg->hasGroup || 0 != LIST_LENGTH(pAgg->pTsmaSubplans) || NULL != pAgg->node.pConditions ||
NULL != pAgg->node.pLimit || NULL != pAgg->node.pSlimit) {
return false;
}
return true;
}
static int32_t findDepTableScanNode(SColumnNode* pCol, SVirtualScanLogicNode *pVScan, SNode **ppNode) {
int32_t code = TSDB_CODE_SUCCESS;
SNode *pScan = NULL;
FOREACH(pScan, pVScan->node.pChildren) {
SScanLogicNode *pScanNode = (SScanLogicNode *)pScan;
SNode *pScanCol = NULL;
FOREACH(pScanCol, pScanNode->pScanCols) {
if (QUERY_NODE_COLUMN == nodeType(pScanCol)) {
SColumnNode *pScanColNode = (SColumnNode *)pScanCol;
if (pScanColNode->hasDep && pCol->hasRef) {
if (strcmp(pScanColNode->dbName, pCol->refDbName) == 0 &&
strcmp(pScanColNode->tableAlias, pCol->refTableName) == 0 &&
strcmp(pScanColNode->colName, pCol->refColName) == 0) {
PLAN_RET(nodesCloneNode(pScan, ppNode));
}
} else {
// TODO(smj): make a proper error code.
*ppNode = NULL;
planError("column %s.%s has no depend column", pCol->tableAlias, pCol->colName);
return TSDB_CODE_PLAN_INTERNAL_ERROR;
}
}
}
}
*ppNode = NULL;
planError("column %s.%s's depend column not found in virtual scan node", pCol->tableAlias, pCol->colName);
// TODO(smj): make a proper error code.
return TSDB_CODE_PLAN_INTERNAL_ERROR;
}
static int32_t mergeAggFuncToAggNode(SAggLogicNode* pAgg, SFunctionNode* pFunc) {
int32_t code = TSDB_CODE_SUCCESS;
SNode *ppFuncNode = NULL;
PLAN_ERR_JRET(nodesCloneNode((SNode *)pFunc, &ppFuncNode));
PLAN_ERR_JRET(nodesListMakeAppend(&pAgg->pAggFuncs, (SNode *)ppFuncNode));
pAgg->hasLast |= fmIsLastFunc(((SFunctionNode *)ppFuncNode)->funcId);
pAgg->hasLastRow |= fmIsLastRowFunc(((SFunctionNode *)ppFuncNode)->funcId);
pAgg->hasTimeLineFunc |= fmIsTimelineFunc(((SFunctionNode *)ppFuncNode)->funcId);
pAgg->onlyHasKeepOrderFunc &= fmIsKeepOrderFunc(((SFunctionNode *)ppFuncNode)->funcId);
pAgg->hasGroupKeyOptimized = false;
pAgg->hasGroup = false;
pAgg->isGroupTb = false;
pAgg->isPartTb = false;
return code;
_return:
nodesDestroyNode(ppFuncNode);
return code;
}
static int32_t rebuildPlanForPdaOptimize(SColumnNode* pCol, SFunctionNode* pAggFunc, SVirtualScanLogicNode* pVScan,
SHashObj* pAggNodeMap) {
int32_t code = TSDB_CODE_SUCCESS;
SScanLogicNode* pDepScan = NULL;
SAggLogicNode* pAggNode = NULL;
bool append = false;
SAggLogicNode** pNodeFound = NULL;
// pAggNodeMap is a hash map, the key is the vtable's origin table's name, the value is the SAggLogicNode ptr.
// if 2 more agg func has the same origin table, we should merge them into one agg node.
PLAN_ERR_JRET(findDepTableScanNode(pCol, pVScan, (SNode**)&pDepScan));
char tableFNameKey[TSDB_COL_FNAME_LEN + 1] = {0};
TAOS_STRNCAT(tableFNameKey, pDepScan->tableName.tname, TSDB_TABLE_NAME_LEN);
TAOS_STRNCAT(tableFNameKey, ".", 2);
TAOS_STRNCAT(tableFNameKey, pCol->colName, TSDB_COL_NAME_LEN);
pNodeFound = (SAggLogicNode **)taosHashGet(pAggNodeMap, &tableFNameKey, strlen(tableFNameKey));
if (NULL == pNodeFound) {
// make new agg node.
PLAN_ERR_JRET(nodesMakeNode(QUERY_NODE_LOGIC_PLAN_AGG, (SNode**)&pAggNode));
PLAN_ERR_JRET(mergeAggFuncToAggNode(pAggNode, pAggFunc));
PLAN_ERR_JRET(nodesListMakeAppend(&pAggNode->node.pChildren, (SNode*)pDepScan));
append = true;
PLAN_ERR_JRET(taosHashPut(pAggNodeMap, &tableFNameKey, strlen(tableFNameKey), &pAggNode, POINTER_BYTES));
} else {
pAggNode = *pNodeFound;
// merge the agg func to the existed agg node.
PLAN_ERR_JRET(mergeAggFuncToAggNode(pAggNode, pAggFunc));
nodesDestroyNode((SNode*)pDepScan);
}
return code;
_return:
if (!append) {
nodesDestroyNode((SNode*)pDepScan);
}
return code;
}
static void destroyAggLogicNode(void* data) {
if (data == NULL) {
return;
}
SAggLogicNode* pNode = *(SAggLogicNode **)data;
nodesDestroyNode((SNode*)pNode);
}
// This optimization rule will optimize plan tree from
// Agg -> VirtualScan -> TableScan
// \> TableScan
// \> TableScan
// to
// Merge -> Agg -> TableScan
// \> Agg -> TableScan
// \> Agg -> TableScan
static int32_t pdaOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan) {
int32_t code = TSDB_CODE_SUCCESS;
SMergeLogicNode* pMerge = NULL;
SAggLogicNode* pAgg = (SAggLogicNode*)optFindPossibleNode(pLogicSubplan->pNode, pdaMayBeOptimized, &code);
if (NULL == pAgg) {
return code;
}
SVirtualScanLogicNode *pVScan = (SVirtualScanLogicNode*)nodesListGetNode(pAgg->node.pChildren, 0);
SNode *pAggFunc = NULL;
SHashObj *pAggNodeMap = taosHashInit(LIST_LENGTH(pAgg->pAggFuncs), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
if (NULL == pAggNodeMap) {
PLAN_ERR_JRET(terrno);
}
FOREACH(pAggFunc, pAgg->pAggFuncs) {
SFunctionNode *pFunc = (SFunctionNode *)pAggFunc;
SNode *pParam = NULL;
FOREACH(pParam, pFunc->pParameterList) {
if (QUERY_NODE_COLUMN == nodeType(pParam)) {
SColumnNode *pCol = (SColumnNode *)pParam;
if (pCol->colType == COLUMN_TYPE_TAG) {
// If the column is a tag column, we should not optimize the aggregation. Since tag will be read from the
// virtual tablescan operator.
goto _return;
}
PLAN_ERR_JRET(rebuildPlanForPdaOptimize(pCol, pFunc, pVScan, pAggNodeMap));
}
}
}
if (taosHashGetSize(pAggNodeMap) != LIST_LENGTH(pVScan->node.pChildren)) {
// The number of agg nodes should be equal to the number of virtual scan nodes.
// If not, it means that some virtual scan nodes are not used in the aggregation.
// In this case, we should not optimize the aggregation.
goto _return;
}
PLAN_ERR_JRET(nodesMakeNode(QUERY_NODE_LOGIC_PLAN_MERGE, (SNode**)&pMerge));
pMerge->colsMerge = true;
pMerge->numOfChannels = LIST_LENGTH(pAgg->pAggFuncs);
pMerge->srcGroupId = -1;
pMerge->node.precision = pAgg->node.precision;
void *pIter = NULL;
while ((pIter = taosHashIterate(pAggNodeMap, pIter))) {
SAggLogicNode **pAggNode = (SAggLogicNode**)pIter;
(*pAggNode)->node.pParent = (SLogicNode*)pMerge;
SNode* pNode = NULL;
FOREACH(pNode, (*pAggNode)->node.pChildren) {
// clear the mask to try scanPathOptimize again.
OPTIMIZE_FLAG_CLEAR_MASK(((SScanLogicNode*)pNode)->node.optimizedFlag, OPTIMIZE_FLAG_SCAN_PATH);
((SLogicNode*)pNode)->pParent = (SLogicNode*)*pAggNode;
}
PLAN_ERR_JRET(createColumnByRewriteExprs((*pAggNode)->pAggFuncs, &(*pAggNode)->node.pTargets));
PLAN_ERR_JRET(nodesListMakeAppend(&pMerge->node.pChildren, (SNode*)*pAggNode));
FOREACH(pNode, (*pAggNode)->node.pTargets) {
PLAN_ERR_JRET(nodesListMakeStrictAppend(&pMerge->node.pTargets, pNode));
}
}
PLAN_ERR_JRET(replaceLogicNode(pLogicSubplan, (SLogicNode*)pAgg, (SLogicNode*)pMerge));
nodesDestroyNode((SNode*)pVScan);
nodesDestroyNode((SNode*)pAgg);
taosHashCleanup(pAggNodeMap);
pCxt->optimized = true;
return code;
_return:
nodesDestroyNode((SNode*)pMerge);
taosHashSetFreeFp(pAggNodeMap, destroyAggLogicNode);
taosHashCleanup(pAggNodeMap);
return code;
}
// clang-format off // clang-format off
static const SOptimizeRule optimizeRuleSet[] = { static const SOptimizeRule optimizeRuleSet[] = {
{.pName = "ScanPath", .optimizeFunc = scanPathOptimize}, {.pName = "ScanPath", .optimizeFunc = scanPathOptimize},
@ -7733,6 +8034,8 @@ static const SOptimizeRule optimizeRuleSet[] = {
{.pName = "EliminateSetOperator", .optimizeFunc = eliminateSetOpOptimize}, {.pName = "EliminateSetOperator", .optimizeFunc = eliminateSetOpOptimize},
{.pName = "PartitionCols", .optimizeFunc = partitionColsOpt}, {.pName = "PartitionCols", .optimizeFunc = partitionColsOpt},
{.pName = "Tsma", .optimizeFunc = tsmaOptimize}, {.pName = "Tsma", .optimizeFunc = tsmaOptimize},
{.pName = "EliminateVirtualScan", .optimizeFunc = eliminateVirtualScanOptimize},
{.pName = "PushDownAgg", .optimizeFunc = pdaOptimize},
}; };
// clang-format on // clang-format on

View File

@ -34,6 +34,7 @@ typedef struct SSlotIndex {
enum { enum {
SLOT_KEY_TYPE_ALL = 1, SLOT_KEY_TYPE_ALL = 1,
SLOT_KEY_TYPE_COLNAME = 2, SLOT_KEY_TYPE_COLNAME = 2,
SLOT_KEY_TYPE_REF = 3,
}; };
static int32_t getSlotKeyHelper(SNode* pNode, const char* pPreName, const char* name, char** ppKey, int32_t callocLen, static int32_t getSlotKeyHelper(SNode* pNode, const char* pPreName, const char* name, char** ppKey, int32_t callocLen,
@ -77,6 +78,32 @@ static int32_t getSlotKey(SNode* pNode, const char* pStmtName, char** ppKey, int
return getSlotKeyHelper(pNode, pStmtName, pCol->colName, ppKey, callocLen, pLen, extraBufLen, return getSlotKeyHelper(pNode, pStmtName, pCol->colName, ppKey, callocLen, pLen, extraBufLen,
SLOT_KEY_TYPE_COLNAME); SLOT_KEY_TYPE_COLNAME);
} }
if (pCol->hasRef) {
*ppKey = taosMemoryCalloc(1, TSDB_TABLE_FNAME_LEN + 1 + TSDB_COL_NAME_LEN + 1 + extraBufLen);
if (!*ppKey) {
return terrno;
}
TAOS_STRNCAT(*ppKey, pCol->refDbName, TSDB_DB_NAME_LEN);
TAOS_STRNCAT(*ppKey, ".", 2);
TAOS_STRNCAT(*ppKey, pCol->refTableName, TSDB_TABLE_NAME_LEN);
TAOS_STRNCAT(*ppKey, ".", 2);
TAOS_STRNCAT(*ppKey, pCol->refColName, TSDB_COL_NAME_LEN);
*pLen = taosHashBinary(*ppKey, strlen(*ppKey));
return code;
}
if (pCol->hasDep) {
*ppKey = taosMemoryCalloc(1, TSDB_TABLE_FNAME_LEN + 1 + TSDB_COL_NAME_LEN + 1 + extraBufLen);
if (!*ppKey) {
return terrno;
}
TAOS_STRNCAT(*ppKey, pCol->dbName, TSDB_DB_NAME_LEN);
TAOS_STRNCAT(*ppKey, ".", 2);
TAOS_STRNCAT(*ppKey, pCol->tableAlias, TSDB_TABLE_NAME_LEN);
TAOS_STRNCAT(*ppKey, ".", 2);
TAOS_STRNCAT(*ppKey, pCol->colName, TSDB_COL_NAME_LEN);
*pLen = taosHashBinary(*ppKey, strlen(*ppKey));
return code;
}
callocLen = TSDB_TABLE_NAME_LEN + 1 + TSDB_COL_NAME_LEN + 1 + extraBufLen; callocLen = TSDB_TABLE_NAME_LEN + 1 + TSDB_COL_NAME_LEN + 1 + extraBufLen;
return getSlotKeyHelper(pNode, pCol->tableAlias, pCol->colName, ppKey, callocLen, pLen, extraBufLen, return getSlotKeyHelper(pNode, pCol->tableAlias, pCol->colName, ppKey, callocLen, pLen, extraBufLen,
SLOT_KEY_TYPE_ALL); SLOT_KEY_TYPE_ALL);
@ -354,6 +381,14 @@ typedef struct SSetSlotIdCxt {
SHashObj* pRightProdIdxHash; SHashObj* pRightProdIdxHash;
} SSetSlotIdCxt; } SSetSlotIdCxt;
typedef struct SMultiTableSetSlotIdCxt {
int32_t errCode;
SArray* hashArray;
SArray* projIdxHashArray;
SNodeList* pChild;
bool isVtb;
} SMultiTableSetSlotIdCxt;
static void dumpSlots(const char* pName, SHashObj* pHash) { static void dumpSlots(const char* pName, SHashObj* pHash) {
if (NULL == pHash) { if (NULL == pHash) {
return; return;
@ -400,7 +435,58 @@ static EDealRes doSetSlotId(SNode* pNode, void* pContext) {
planError("doSetSlotId failed, invalid slot name %s", name); planError("doSetSlotId failed, invalid slot name %s", name);
dumpSlots("left datablock desc", pCxt->pLeftHash); dumpSlots("left datablock desc", pCxt->pLeftHash);
dumpSlots("right datablock desc", pCxt->pRightHash); dumpSlots("right datablock desc", pCxt->pRightHash);
pCxt->errCode = TSDB_CODE_PLAN_INTERNAL_ERROR; pCxt->errCode = TSDB_CODE_PLAN_SLOT_NOT_FOUND;
taosMemoryFree(name);
return DEAL_RES_ERROR;
}
((SColumnNode*)pNode)->dataBlockId = pIndex->dataBlockId;
((SColumnNode*)pNode)->slotId = ((SSlotIdInfo*)taosArrayGet(pIndex->pSlotIdsInfo, 0))->slotId;
taosMemoryFree(name);
return DEAL_RES_IGNORE_CHILD;
}
return DEAL_RES_CONTINUE;
}
static EDealRes doSetMultiTableSlotId(SNode* pNode, void* pContext) {
if (QUERY_NODE_COLUMN == nodeType(pNode) && 0 != strcmp(((SColumnNode*)pNode)->colName, "*")) {
SMultiTableSetSlotIdCxt* pCxt = (SMultiTableSetSlotIdCxt*)pContext;
char* name = NULL;
int32_t len = 0;
if (pCxt->isVtb && !((SColumnNode*)pNode)->hasRef) {
return DEAL_RES_CONTINUE;
}
pCxt->errCode = getSlotKey(pNode, NULL, &name, &len, 16);
if (TSDB_CODE_SUCCESS != pCxt->errCode) {
return DEAL_RES_ERROR;
}
SSlotIndex* pIndex = NULL;
int32_t idx = 0;
if (((SColumnNode*)pNode)->projRefIdx > 0) {
sprintf(name + strlen(name), "_%d", ((SColumnNode*)pNode)->projRefIdx);
while (!pIndex && idx < LIST_LENGTH(pCxt->pChild)) {
SHashObj *tmpHash =
taosArrayGetP(pCxt->projIdxHashArray,
((SPhysiNode*)nodesListGetNode(pCxt->pChild, idx))->pOutputDataBlockDesc->dataBlockId);
pIndex = taosHashGet(tmpHash, name, strlen(name));
idx++;
}
} else {
while (!pIndex && idx < LIST_LENGTH(pCxt->pChild)) {
SHashObj *tmpHash =
taosArrayGetP(pCxt->hashArray,
((SPhysiNode*)nodesListGetNode(pCxt->pChild, idx))->pOutputDataBlockDesc->dataBlockId);
pIndex = taosHashGet(tmpHash, name, len);
idx++;
}
}
// pIndex is definitely not NULL, otherwise it is a bug
if (NULL == pIndex) {
planError("doSetMultiTableSlotId failed, invalid slot name %s", name);
for (int32_t i = 0; i < taosArrayGetSize(pCxt->hashArray); i++) {
//dumpSlots("vtable datablock desc", taosArrayGetP(pCxt->hashArray, i));
}
pCxt->errCode = TSDB_CODE_PLAN_SLOT_NOT_FOUND;
taosMemoryFree(name); taosMemoryFree(name);
return DEAL_RES_ERROR; return DEAL_RES_ERROR;
} }
@ -440,6 +526,33 @@ static int32_t setNodeSlotId(SPhysiPlanContext* pCxt, int16_t leftDataBlockId, i
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
static int32_t setVtableNodeSlotId(SPhysiPlanContext* pCxt, SNodeList* pChild, SNode* pNode,
SNode** pOutput) {
int32_t code = TSDB_CODE_SUCCESS;
if (NULL == pNode) {
PLAN_RET(code);
}
SNode* pRes = NULL;
PLAN_ERR_JRET(nodesCloneNode(pNode, &pRes));
SMultiTableSetSlotIdCxt cxt = {
.errCode = TSDB_CODE_SUCCESS,
.hashArray = pCxt->pLocationHelper,
.projIdxHashArray = pCxt->pProjIdxLocHelper,
.pChild = pChild
};
nodesWalkExpr(pRes, doSetMultiTableSlotId, &cxt);
PLAN_ERR_JRET(cxt.errCode);
*pOutput = pRes;
return code;
_return:
nodesDestroyNode(pRes);
return code;
}
static int32_t setListSlotId(SPhysiPlanContext* pCxt, int16_t leftDataBlockId, int16_t rightDataBlockId, static int32_t setListSlotId(SPhysiPlanContext* pCxt, int16_t leftDataBlockId, int16_t rightDataBlockId,
const SNodeList* pList, SNodeList** pOutput) { const SNodeList* pList, SNodeList** pOutput) {
if (NULL == pList) { if (NULL == pList) {
@ -467,6 +580,34 @@ static int32_t setListSlotId(SPhysiPlanContext* pCxt, int16_t leftDataBlockId, i
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
static int32_t setMultiBlockSlotId(SPhysiPlanContext* pCxt, SNodeList* pChild, bool isVtb, const SNodeList* pList,
SNodeList** pOutput) {
int32_t code = TSDB_CODE_SUCCESS;
if (NULL == pList) {
PLAN_RET(code);
}
SNodeList* pRes = NULL;
PLAN_ERR_JRET(nodesCloneList(pList, &pRes));
SMultiTableSetSlotIdCxt cxt = {
.errCode = TSDB_CODE_SUCCESS,
.hashArray = pCxt->pLocationHelper,
.projIdxHashArray = pCxt->pProjIdxLocHelper,
.pChild = pChild,
.isVtb = isVtb
};
nodesWalkExprs(pRes, doSetMultiTableSlotId, &cxt);
PLAN_ERR_JRET(cxt.errCode);
*pOutput = pRes;
return code;
_return:
nodesDestroyList(pRes);
return code;
}
static SPhysiNode* makePhysiNode(SPhysiPlanContext* pCxt, SLogicNode* pLogicNode, ENodeType type) { static SPhysiNode* makePhysiNode(SPhysiPlanContext* pCxt, SLogicNode* pLogicNode, ENodeType type) {
SPhysiNode* pPhysiNode = NULL; SPhysiNode* pPhysiNode = NULL;
int32_t code = nodesMakeNode(type, (SNode**)&pPhysiNode); int32_t code = nodesMakeNode(type, (SNode**)&pPhysiNode);
@ -570,6 +711,7 @@ static int32_t createScanPhysiNodeFinalize(SPhysiPlanContext* pCxt, SSubplan* pS
pScanPhysiNode->suid = pScanLogicNode->stableId; pScanPhysiNode->suid = pScanLogicNode->stableId;
pScanPhysiNode->tableType = pScanLogicNode->tableType; pScanPhysiNode->tableType = pScanLogicNode->tableType;
pScanPhysiNode->groupOrderScan = pScanLogicNode->groupOrderScan; pScanPhysiNode->groupOrderScan = pScanLogicNode->groupOrderScan;
pScanPhysiNode->virtualStableScan = pScanLogicNode->virtualStableScan;
memcpy(&pScanPhysiNode->tableName, &pScanLogicNode->tableName, sizeof(SName)); memcpy(&pScanPhysiNode->tableName, &pScanLogicNode->tableName, sizeof(SName));
if (NULL != pScanLogicNode->pTagCond) { if (NULL != pScanLogicNode->pTagCond) {
pSubplan->pTagCond = NULL; pSubplan->pTagCond = NULL;
@ -1642,6 +1784,69 @@ static int32_t createJoinPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren
return TSDB_CODE_FAILED; return TSDB_CODE_FAILED;
} }
static int32_t createVirtualScanCols(SPhysiPlanContext* pCxt, SVirtualScanPhysiNode* pScanPhysiNode, SNodeList* pScanCols) {
if (NULL == pScanCols) {
return TSDB_CODE_SUCCESS;
}
pScanPhysiNode->scan.pScanCols = NULL;
int32_t code = nodesCloneList(pScanCols, &pScanPhysiNode->scan.pScanCols);
if (NULL == pScanPhysiNode->scan.pScanCols) {
return code;
}
return sortScanCols(pScanPhysiNode->scan.pScanCols);
}
static int32_t createVirtualTableScanPhysiNodeFinalize(SPhysiPlanContext* pCxt,
SNodeList* pChild,
SVirtualScanLogicNode* pScanLogicNode,
SVirtualScanPhysiNode* pScanPhysiNode,
SPhysiNode** pPhyNode) {
int32_t code = TSDB_CODE_SUCCESS;
PLAN_ERR_JRET(createVirtualScanCols(pCxt, pScanPhysiNode, pScanLogicNode->pScanCols));
PLAN_ERR_JRET(addDataBlockSlots(pCxt, pScanPhysiNode->scan.pScanCols, pScanPhysiNode->scan.node.pOutputDataBlockDesc));
if (NULL != pScanLogicNode->pScanPseudoCols) {
pScanPhysiNode->scan.pScanPseudoCols = NULL;
PLAN_ERR_JRET(nodesCloneList(pScanLogicNode->pScanPseudoCols, &pScanPhysiNode->scan.pScanPseudoCols));
PLAN_ERR_JRET(addDataBlockSlots(pCxt, pScanPhysiNode->scan.pScanPseudoCols, pScanPhysiNode->scan.node.pOutputDataBlockDesc));
}
PLAN_ERR_JRET(setConditionsSlotId(pCxt, (const SLogicNode*)pScanLogicNode, (SPhysiNode*)pScanPhysiNode));
pScanPhysiNode->scan.uid = pScanLogicNode->tableId;
pScanPhysiNode->scan.suid = pScanLogicNode->stableId;
pScanPhysiNode->scan.tableType = pScanLogicNode->tableType;
memcpy(&pScanPhysiNode->scan.tableName, &pScanLogicNode->tableName, sizeof(SName));
pScanPhysiNode->scanAllCols = pScanLogicNode->scanAllCols;
*pPhyNode = (SPhysiNode*)pScanPhysiNode;
return code;
_return:
nodesDestroyNode((SNode*)pScanPhysiNode);
return code;
}
static int32_t createVirtualTableScanPhysiNode(SPhysiPlanContext* pCxt, SSubplan* pSubplan, SNodeList* pChildren,
SVirtualScanLogicNode* pScanLogicNode, SPhysiNode** pPhyNode) {
int32_t code = TSDB_CODE_SUCCESS;
SVirtualScanPhysiNode * pVirtualScan =
(SVirtualScanPhysiNode*)makePhysiNode(pCxt, (SLogicNode*)pScanLogicNode, QUERY_NODE_PHYSICAL_PLAN_VIRTUAL_TABLE_SCAN);
if (NULL == pVirtualScan) {
return terrno;
}
if (pScanLogicNode->pVgroupList) {
vgroupInfoToNodeAddr(pScanLogicNode->pVgroupList->vgroups, &pSubplan->execNode);
pSubplan->execNodeStat.tableNum = pScanLogicNode->pVgroupList->vgroups[0].numOfTable;
}
PLAN_ERR_RET(createVirtualTableScanPhysiNodeFinalize(pCxt, pChildren, pScanLogicNode, (SVirtualScanPhysiNode*)pVirtualScan, pPhyNode));
PLAN_ERR_RET(setMultiBlockSlotId(pCxt, pChildren, true, pScanLogicNode->node.pTargets, &pVirtualScan->pTargets));
return code;
}
static int32_t createGroupCachePhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren, static int32_t createGroupCachePhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren,
SGroupCacheLogicNode* pLogicNode, SPhysiNode** pPhyNode) { SGroupCacheLogicNode* pLogicNode, SPhysiNode** pPhyNode) {
SGroupCachePhysiNode* pGrpCache = SGroupCachePhysiNode* pGrpCache =
@ -1698,29 +1903,55 @@ static int32_t updateDynQueryCtrlStbJoinInfo(SPhysiPlanContext* pCxt, SNodeList*
return code; return code;
} }
static int32_t createDynQueryCtrlPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren, static int32_t updateDynQueryCtrlVtbScanInfo(SPhysiPlanContext* pCxt, SNodeList* pChildren,
SDynQueryCtrlLogicNode* pLogicNode, SPhysiNode** pPhyNode) { SDynQueryCtrlLogicNode* pLogicNode, SDynQueryCtrlPhysiNode* pDynCtrl,
SSubplan* pSubPlan) {
int32_t code = TSDB_CODE_SUCCESS; int32_t code = TSDB_CODE_SUCCESS;
if (pLogicNode->vtbScan.pVgroupList) {
vgroupInfoToNodeAddr(pLogicNode->vtbScan.pVgroupList->vgroups, &pSubPlan->execNode);
pSubPlan->execNodeStat.tableNum = pLogicNode->vtbScan.pVgroupList->vgroups[0].numOfTable;
}
PLAN_ERR_JRET(nodesCloneList(pLogicNode->node.pTargets, &pDynCtrl->vtbScan.pScanCols));
pDynCtrl->vtbScan.scanAllCols = pLogicNode->vtbScan.scanAllCols;
pDynCtrl->vtbScan.suid = pLogicNode->vtbScan.suid;
pDynCtrl->vtbScan.mgmtEpSet = pCxt->pPlanCxt->mgmtEpSet;
pDynCtrl->vtbScan.accountId = pCxt->pPlanCxt->acctId;
return code;
_return:
planError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(code));
return code;
}
static int32_t createDynQueryCtrlPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren,
SDynQueryCtrlLogicNode* pLogicNode, SPhysiNode** pPhyNode, SSubplan* pSubPlan) {
int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
SDynQueryCtrlPhysiNode* pDynCtrl = SDynQueryCtrlPhysiNode* pDynCtrl =
(SDynQueryCtrlPhysiNode*)makePhysiNode(pCxt, (SLogicNode*)pLogicNode, QUERY_NODE_PHYSICAL_PLAN_DYN_QUERY_CTRL); (SDynQueryCtrlPhysiNode*)makePhysiNode(pCxt, (SLogicNode*)pLogicNode, QUERY_NODE_PHYSICAL_PLAN_DYN_QUERY_CTRL);
if (NULL == pDynCtrl) { QUERY_CHECK_NULL(pDynCtrl, code, lino, _return, terrno);
return terrno;
}
switch (pLogicNode->qType) { switch (pLogicNode->qType) {
case DYN_QTYPE_STB_HASH: case DYN_QTYPE_STB_HASH:
code = updateDynQueryCtrlStbJoinInfo(pCxt, pChildren, pLogicNode, pDynCtrl); PLAN_ERR_JRET(updateDynQueryCtrlStbJoinInfo(pCxt, pChildren, pLogicNode, pDynCtrl));
break;
case DYN_QTYPE_VTB_SCAN:
PLAN_ERR_JRET(updateDynQueryCtrlVtbScanInfo(pCxt, pChildren, pLogicNode, pDynCtrl, pSubPlan));
break; break;
default: default:
planError("Invalid dyn query ctrl type:%d", pLogicNode->qType); PLAN_ERR_JRET(TSDB_CODE_PLAN_INVALID_DYN_CTRL_TYPE);
return TSDB_CODE_PLAN_INTERNAL_ERROR;
} }
if (TSDB_CODE_SUCCESS == code) {
pDynCtrl->qType = pLogicNode->qType; pDynCtrl->qType = pLogicNode->qType;
*pPhyNode = (SPhysiNode*)pDynCtrl; *pPhyNode = (SPhysiNode*)pDynCtrl;
}
return code;
_return:
planError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(code));
return code; return code;
} }
@ -2828,49 +3059,31 @@ static int32_t createMergePhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildre
pMerge->inputWithGroupId = pMergeLogicNode->inputWithGroupId; pMerge->inputWithGroupId = pMergeLogicNode->inputWithGroupId;
if (!pMergeLogicNode->colsMerge) { if (!pMergeLogicNode->colsMerge) {
code = addDataBlockSlots(pCxt, pMergeLogicNode->pInputs, pMerge->node.pOutputDataBlockDesc); PLAN_ERR_JRET(addDataBlockSlots(pCxt, pMergeLogicNode->pInputs, pMerge->node.pOutputDataBlockDesc));
if (TSDB_CODE_SUCCESS == code) {
for (int32_t j = 0; j < pMergeLogicNode->numOfSubplans; ++j) { for (int32_t j = 0; j < pMergeLogicNode->numOfSubplans; ++j) {
for (int32_t i = 0; i < pMerge->numOfChannels; ++i) { for (int32_t i = 0; i < pMerge->numOfChannels; ++i) {
code = createExchangePhysiNodeByMerge(pMerge, j); PLAN_ERR_JRET(createExchangePhysiNodeByMerge(pMerge, j));
if (TSDB_CODE_SUCCESS != code) {
break;
}
}
if (code) break;
} }
} }
if (TSDB_CODE_SUCCESS == code && NULL != pMergeLogicNode->pMergeKeys) { if (NULL != pMergeLogicNode->pMergeKeys) {
code = setListSlotId(pCxt, pMerge->node.pOutputDataBlockDesc->dataBlockId, -1, pMergeLogicNode->pMergeKeys, PLAN_ERR_JRET(setListSlotId(pCxt, pMerge->node.pOutputDataBlockDesc->dataBlockId, -1, pMergeLogicNode->pMergeKeys,
&pMerge->pMergeKeys); &pMerge->pMergeKeys));
} }
if (TSDB_CODE_SUCCESS == code) { PLAN_ERR_JRET(setListSlotId(pCxt, pMerge->node.pOutputDataBlockDesc->dataBlockId, -1, pMergeLogicNode->node.pTargets,
code = setListSlotId(pCxt, pMerge->node.pOutputDataBlockDesc->dataBlockId, -1, pMergeLogicNode->node.pTargets, &pMerge->pTargets));
&pMerge->pTargets); PLAN_ERR_JRET(addDataBlockSlots(pCxt, pMerge->pTargets, pMerge->node.pOutputDataBlockDesc));
}
if (TSDB_CODE_SUCCESS == code) {
code = addDataBlockSlots(pCxt, pMerge->pTargets, pMerge->node.pOutputDataBlockDesc);
}
} else { } else {
SDataBlockDescNode* pLeftDesc = ((SPhysiNode*)nodesListGetNode(pChildren, 0))->pOutputDataBlockDesc; PLAN_ERR_JRET(setMultiBlockSlotId(pCxt, pChildren, false, pMergeLogicNode->node.pTargets, &pMerge->pTargets));
SDataBlockDescNode* pRightDesc = ((SPhysiNode*)nodesListGetNode(pChildren, 1))->pOutputDataBlockDesc; PLAN_ERR_JRET(addDataBlockSlots(pCxt, pMerge->pTargets, pMerge->node.pOutputDataBlockDesc));
code = setListSlotId(pCxt, pLeftDesc->dataBlockId, pRightDesc->dataBlockId, pMergeLogicNode->node.pTargets,
&pMerge->pTargets);
if (TSDB_CODE_SUCCESS == code) {
code = addDataBlockSlots(pCxt, pMerge->pTargets, pMerge->node.pOutputDataBlockDesc);
}
} }
if (TSDB_CODE_SUCCESS == code) {
*pPhyNode = (SPhysiNode*)pMerge; *pPhyNode = (SPhysiNode*)pMerge;
} else { return code;
_return:
nodesDestroyNode((SNode*)pMerge); nodesDestroyNode((SNode*)pMerge);
}
return code; return code;
} }
@ -2906,7 +3119,9 @@ static int32_t doCreatePhysiNode(SPhysiPlanContext* pCxt, SLogicNode* pLogicNode
case QUERY_NODE_LOGIC_PLAN_GROUP_CACHE: case QUERY_NODE_LOGIC_PLAN_GROUP_CACHE:
return createGroupCachePhysiNode(pCxt, pChildren, (SGroupCacheLogicNode*)pLogicNode, pPhyNode); return createGroupCachePhysiNode(pCxt, pChildren, (SGroupCacheLogicNode*)pLogicNode, pPhyNode);
case QUERY_NODE_LOGIC_PLAN_DYN_QUERY_CTRL: case QUERY_NODE_LOGIC_PLAN_DYN_QUERY_CTRL:
return createDynQueryCtrlPhysiNode(pCxt, pChildren, (SDynQueryCtrlLogicNode*)pLogicNode, pPhyNode); return createDynQueryCtrlPhysiNode(pCxt, pChildren, (SDynQueryCtrlLogicNode*)pLogicNode, pPhyNode, pSubplan);
case QUERY_NODE_LOGIC_PLAN_VIRTUAL_TABLE_SCAN:
return createVirtualTableScanPhysiNode(pCxt, pSubplan, pChildren, (SVirtualScanLogicNode*)pLogicNode, pPhyNode);
default: default:
break; break;
} }
@ -3000,6 +3215,7 @@ static int32_t makeSubplan(SPhysiPlanContext* pCxt, SLogicSubplan* pLogicSubplan
pSubplan->dynamicRowThreshold = false; pSubplan->dynamicRowThreshold = false;
pSubplan->isView = pCxt->pPlanCxt->isView; pSubplan->isView = pCxt->pPlanCxt->isView;
pSubplan->isAudit = pCxt->pPlanCxt->isAudit; pSubplan->isAudit = pCxt->pPlanCxt->isAudit;
pSubplan->processOneBlock = pLogicSubplan->processOneBlock;
if (NULL != pCxt->pPlanCxt->pUser) { if (NULL != pCxt->pPlanCxt->pUser) {
snprintf(pSubplan->user, sizeof(pSubplan->user), "%s", pCxt->pPlanCxt->pUser); snprintf(pSubplan->user, sizeof(pSubplan->user), "%s", pCxt->pPlanCxt->pUser);
} }

View File

@ -39,6 +39,7 @@ static SLogicSubplan* singleCloneSubLogicPlan(SScaleOutContext* pCxt, SLogicSubp
pDst->id.queryId = pSrc->id.queryId; pDst->id.queryId = pSrc->id.queryId;
pDst->id.groupId = pSrc->id.groupId; pDst->id.groupId = pSrc->id.groupId;
pDst->id.subplanId = pCxt->subplanId++; pDst->id.subplanId = pCxt->subplanId++;
pDst->processOneBlock = pSrc->processOneBlock;
return pDst; return pDst;
} }
@ -52,6 +53,17 @@ static int32_t doSetScanVgroup(SLogicNode* pNode, const SVgroupInfo* pVgroup, bo
memcpy(pScan->pVgroupList->vgroups, pVgroup, sizeof(SVgroupInfo)); memcpy(pScan->pVgroupList->vgroups, pVgroup, sizeof(SVgroupInfo));
*pFound = true; *pFound = true;
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} else if (QUERY_NODE_LOGIC_PLAN_DYN_QUERY_CTRL == nodeType(pNode)) {
SDynQueryCtrlLogicNode* pCtrl = (SDynQueryCtrlLogicNode*)pNode;
if (DYN_QTYPE_VTB_SCAN == pCtrl->qType) {
pCtrl->vtbScan.pVgroupList = taosMemoryCalloc(1, sizeof(SVgroupsInfo) + sizeof(SVgroupInfo));
if (NULL == pCtrl->vtbScan.pVgroupList) {
return terrno;
}
memcpy(pCtrl->vtbScan.pVgroupList->vgroups, pVgroup, sizeof(SVgroupInfo));
*pFound = true;
return TSDB_CODE_SUCCESS;
}
} }
SNode* pChild = NULL; SNode* pChild = NULL;
FOREACH(pChild, pNode->pChildren) { FOREACH(pChild, pNode->pChildren) {
@ -87,8 +99,13 @@ static int32_t scaleOutByVgroups(SScaleOutContext* pCxt, SLogicSubplan* pSubplan
} }
static int32_t scaleOutForMerge(SScaleOutContext* pCxt, SLogicSubplan* pSubplan, int32_t level, SNodeList* pGroup) { static int32_t scaleOutForMerge(SScaleOutContext* pCxt, SLogicSubplan* pSubplan, int32_t level, SNodeList* pGroup) {
if (QUERY_NODE_LOGIC_PLAN_DYN_QUERY_CTRL == nodeType(pSubplan->pNode) &&
((SDynQueryCtrlLogicNode*)pSubplan->pNode)->qType == DYN_QTYPE_VTB_SCAN) {
return scaleOutByVgroups(pCxt, pSubplan, level, pGroup);
} else {
return nodesListStrictAppend(pGroup, (SNode*)singleCloneSubLogicPlan(pCxt, pSubplan, level)); return nodesListStrictAppend(pGroup, (SNode*)singleCloneSubLogicPlan(pCxt, pSubplan, level));
} }
}
static int32_t scaleOutForInsertValues(SScaleOutContext* pCxt, SLogicSubplan* pSubplan, int32_t level, static int32_t scaleOutForInsertValues(SScaleOutContext* pCxt, SLogicSubplan* pSubplan, int32_t level,
SNodeList* pGroup) { SNodeList* pGroup) {

View File

@ -51,6 +51,10 @@ static int32_t stbSplCreateMergeKeys(SNodeList* pSortKeys, SNodeList* pTargets,
static void splSetSubplanVgroups(SLogicSubplan* pSubplan, SLogicNode* pNode) { static void splSetSubplanVgroups(SLogicSubplan* pSubplan, SLogicNode* pNode) {
if (QUERY_NODE_LOGIC_PLAN_SCAN == nodeType(pNode)) { if (QUERY_NODE_LOGIC_PLAN_SCAN == nodeType(pNode)) {
TSWAP(pSubplan->pVgroupList, ((SScanLogicNode*)pNode)->pVgroupList); TSWAP(pSubplan->pVgroupList, ((SScanLogicNode*)pNode)->pVgroupList);
} else if (QUERY_NODE_LOGIC_PLAN_VIRTUAL_TABLE_SCAN == nodeType(pNode)) {
// do nothing, since virtual table scan node is SUBPLAN_TYPE_MERGE
} else if (QUERY_NODE_LOGIC_PLAN_DYN_QUERY_CTRL == nodeType(pNode) && ((SDynQueryCtrlLogicNode *)pNode)->qType == DYN_QTYPE_VTB_SCAN) {
TSWAP(pSubplan->pVgroupList, ((SDynQueryCtrlLogicNode*)pNode)->vtbScan.pVgroupList);
} else { } else {
if (1 == LIST_LENGTH(pNode->pChildren)) { if (1 == LIST_LENGTH(pNode->pChildren)) {
splSetSubplanVgroups(pSubplan, (SLogicNode*)nodesListGetNode(pNode->pChildren, 0)); splSetSubplanVgroups(pSubplan, (SLogicNode*)nodesListGetNode(pNode->pChildren, 0));
@ -66,7 +70,8 @@ static SLogicSubplan* splCreateScanSubplan(SSplitContext* pCxt, SLogicNode* pNod
} }
pSubplan->id.queryId = pCxt->queryId; pSubplan->id.queryId = pCxt->queryId;
pSubplan->id.groupId = pCxt->groupId; pSubplan->id.groupId = pCxt->groupId;
pSubplan->subplanType = SUBPLAN_TYPE_SCAN; // TODO(smj):refact here.
pSubplan->subplanType = nodeType(pNode) == QUERY_NODE_LOGIC_PLAN_VIRTUAL_TABLE_SCAN ? SUBPLAN_TYPE_MERGE : SUBPLAN_TYPE_SCAN;
pSubplan->pNode = pNode; pSubplan->pNode = pNode;
pSubplan->pNode->pParent = NULL; pSubplan->pNode->pParent = NULL;
splSetSubplanVgroups(pSubplan, pNode); splSetSubplanVgroups(pSubplan, pNode);
@ -146,10 +151,11 @@ static int32_t splCreateExchangeNode(SSplitContext* pCxt, SLogicNode* pChild, SE
} }
static int32_t splCreateExchangeNodeForSubplan(SSplitContext* pCxt, SLogicSubplan* pSubplan, SLogicNode* pSplitNode, static int32_t splCreateExchangeNodeForSubplan(SSplitContext* pCxt, SLogicSubplan* pSubplan, SLogicNode* pSplitNode,
ESubplanType subplanType) { ESubplanType subplanType, bool seqScan) {
SExchangeLogicNode* pExchange = NULL; SExchangeLogicNode* pExchange = NULL;
int32_t code = splCreateExchangeNode(pCxt, pSplitNode, &pExchange); int32_t code = splCreateExchangeNode(pCxt, pSplitNode, &pExchange);
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
pExchange->seqRecvData = seqScan;
code = replaceLogicNode(pSubplan, pSplitNode, (SLogicNode*)pExchange); code = replaceLogicNode(pSubplan, pSplitNode, (SLogicNode*)pExchange);
} }
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
@ -338,6 +344,9 @@ static bool stbSplIsTableCountQuery(SLogicNode* pNode) {
} }
static bool stbSplNeedSplit(SFindSplitNodeCtx* pCtx, SLogicNode* pNode) { static bool stbSplNeedSplit(SFindSplitNodeCtx* pCtx, SLogicNode* pNode) {
if (pCtx->pSplitCtx->pPlanCxt->virtualStableQuery) {
return false;
}
bool streamQuery = pCtx->pSplitCtx->pPlanCxt->streamQuery; bool streamQuery = pCtx->pSplitCtx->pPlanCxt->streamQuery;
switch (nodeType(pNode)) { switch (nodeType(pNode)) {
case QUERY_NODE_LOGIC_PLAN_SCAN: case QUERY_NODE_LOGIC_PLAN_SCAN:
@ -1083,7 +1092,7 @@ static int32_t stbSplCreatePartAggNode(SAggLogicNode* pMergeAgg, SLogicNode** pO
} }
static int32_t stbSplSplitAggNodeForPartTable(SSplitContext* pCxt, SStableSplitInfo* pInfo) { static int32_t stbSplSplitAggNodeForPartTable(SSplitContext* pCxt, SStableSplitInfo* pInfo) {
int32_t code = splCreateExchangeNodeForSubplan(pCxt, pInfo->pSubplan, pInfo->pSplitNode, SUBPLAN_TYPE_MERGE); int32_t code = splCreateExchangeNodeForSubplan(pCxt, pInfo->pSubplan, pInfo->pSplitNode, SUBPLAN_TYPE_MERGE, false);
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
code = nodesListMakeStrictAppend(&pInfo->pSubplan->pChildren, code = nodesListMakeStrictAppend(&pInfo->pSubplan->pChildren,
(SNode*)splCreateScanSubplan(pCxt, pInfo->pSplitNode, SPLIT_FLAG_STABLE_SPLIT)); (SNode*)splCreateScanSubplan(pCxt, pInfo->pSplitNode, SPLIT_FLAG_STABLE_SPLIT));
@ -1461,7 +1470,7 @@ static int32_t stbSplSplitScanNodeWithoutPartTags(SSplitContext* pCxt, SStableSp
SLogicNode* pSplitNode = NULL; SLogicNode* pSplitNode = NULL;
int32_t code = stbSplGetSplitNodeForScan(pInfo, &pSplitNode); int32_t code = stbSplGetSplitNodeForScan(pInfo, &pSplitNode);
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
code = splCreateExchangeNodeForSubplan(pCxt, pInfo->pSubplan, pSplitNode, pInfo->pSubplan->subplanType); code = splCreateExchangeNodeForSubplan(pCxt, pInfo->pSubplan, pSplitNode, pInfo->pSubplan->subplanType, false);
} }
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
splSetSubplanType(pInfo->pSubplan); splSetSubplanType(pInfo->pSubplan);
@ -1781,7 +1790,7 @@ static int32_t singleTableJoinSplit(SSplitContext* pCxt, SLogicSubplan* pSubplan
if (!splMatch(pCxt, pSubplan, 0, (FSplFindSplitNode)sigTbJoinSplFindSplitNode, &info)) { if (!splMatch(pCxt, pSubplan, 0, (FSplFindSplitNode)sigTbJoinSplFindSplitNode, &info)) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
int32_t code = splCreateExchangeNodeForSubplan(pCxt, info.pSubplan, info.pSplitNode, info.pSubplan->subplanType); int32_t code = splCreateExchangeNodeForSubplan(pCxt, info.pSubplan, info.pSplitNode, info.pSubplan->subplanType, false);
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
code = nodesListMakeStrictAppend(&info.pSubplan->pChildren, (SNode*)splCreateScanSubplan(pCxt, info.pSplitNode, 0)); code = nodesListMakeStrictAppend(&info.pSubplan->pChildren, (SNode*)splCreateScanSubplan(pCxt, info.pSplitNode, 0));
} }
@ -2009,7 +2018,7 @@ static int32_t insertSelectSplit(SSplitContext* pCxt, SLogicSubplan* pSubplan) {
SLogicSubplan* pNewSubplan = NULL; SLogicSubplan* pNewSubplan = NULL;
SNodeList* pSubplanChildren = info.pSubplan->pChildren; SNodeList* pSubplanChildren = info.pSubplan->pChildren;
int32_t code = splCreateExchangeNodeForSubplan(pCxt, info.pSubplan, info.pQueryRoot, SUBPLAN_TYPE_MODIFY); int32_t code = splCreateExchangeNodeForSubplan(pCxt, info.pSubplan, info.pQueryRoot, SUBPLAN_TYPE_MODIFY, false);
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
code = splCreateSubplan(pCxt, info.pQueryRoot, &pNewSubplan); code = splCreateSubplan(pCxt, info.pQueryRoot, &pNewSubplan);
} }
@ -2026,6 +2035,87 @@ static int32_t insertSelectSplit(SSplitContext* pCxt, SLogicSubplan* pSubplan) {
return code; return code;
} }
typedef struct SVirtualTableSplitInfo {
SVirtualScanLogicNode *pVirtual;
SLogicSubplan *pSubplan;
} SVirtualTableSplitInfo;
static bool virtualTableFindSplitNode(SSplitContext* pCxt, SLogicSubplan* pSubplan, SLogicNode* pNode,
SVirtualTableSplitInfo* pInfo) {
if (QUERY_NODE_LOGIC_PLAN_VIRTUAL_TABLE_SCAN == nodeType(pNode) && 0 != LIST_LENGTH(pNode->pChildren) &&
QUERY_NODE_LOGIC_PLAN_EXCHANGE != nodeType(nodesListGetNode(pNode->pChildren, 0))) {
pInfo->pVirtual = (SVirtualScanLogicNode*)pNode;
pInfo->pSubplan = pSubplan;
return true;
}
return false;
}
static int32_t virtualTableSplit(SSplitContext* pCxt, SLogicSubplan* pSubplan) {
int32_t code = TSDB_CODE_SUCCESS;
SVirtualTableSplitInfo info = {0};
if (!splMatch(pCxt, pSubplan, 0, (FSplFindSplitNode)virtualTableFindSplitNode, &info)) {
return TSDB_CODE_SUCCESS;
}
int32_t startGroupId = pCxt->groupId;
SNode* pChild = NULL;
FOREACH(pChild, info.pVirtual->node.pChildren) {
PLAN_ERR_JRET(splCreateExchangeNodeForSubplan(pCxt, info.pSubplan, (SLogicNode*)pChild, info.pSubplan->subplanType, info.pVirtual->tableType == TSDB_SUPER_TABLE));
SLogicSubplan *sub = splCreateScanSubplan(pCxt, (SLogicNode*)pChild, 0);
sub->processOneBlock = (info.pVirtual->tableType == TSDB_SUPER_TABLE);
PLAN_ERR_JRET(nodesListMakeStrictAppend(&info.pSubplan->pChildren, (SNode*)sub));
++(pCxt->groupId);
}
info.pSubplan->subplanType = SUBPLAN_TYPE_MERGE;
_return:
pCxt->split = true;
return code;
}
typedef struct SMergeAggColsSplitInfo {
SAggLogicNode *pAgg;
SLogicNode *pSplitNode;
SLogicSubplan *pSubplan;
} SMergeAggColsSplitInfo;
static bool mergeAggColsNeedSplit(SLogicNode* pNode) {
if (QUERY_NODE_LOGIC_PLAN_AGG == nodeType(pNode) && 1 == LIST_LENGTH(pNode->pChildren) &&
NULL != pNode->pParent &&
QUERY_NODE_LOGIC_PLAN_MERGE == nodeType(pNode->pParent) &&
((SMergeLogicNode *)pNode->pParent)->colsMerge &&
QUERY_NODE_LOGIC_PLAN_SCAN == nodeType(nodesListGetNode(pNode->pChildren, 0))) {
return true;
}
return false;
}
static bool mergeAggColsFindSplitNode(SSplitContext* pCxt, SLogicSubplan* pSubplan, SLogicNode* pNode,
SMergeAggColsSplitInfo* pInfo) {
if (mergeAggColsNeedSplit(pNode)) {
pInfo->pAgg = (SAggLogicNode *)pNode;
pInfo->pSplitNode = (SLogicNode*)nodesListGetNode(pNode->pChildren, 0);
pInfo->pSubplan = pSubplan;
return true;
}
return false;
}
static int32_t mergeAggColsSplit(SSplitContext* pCxt, SLogicSubplan* pSubplan) {
int32_t code = TSDB_CODE_SUCCESS;
SMergeAggColsSplitInfo info = {0};
if (!splMatch(pCxt, pSubplan, 0, (FSplFindSplitNode)mergeAggColsFindSplitNode, &info)) {
return TSDB_CODE_SUCCESS;
}
PLAN_ERR_RET(splCreateExchangeNodeForSubplan(pCxt, info.pSubplan, info.pSplitNode, SUBPLAN_TYPE_MERGE, false));
PLAN_ERR_RET(nodesListMakeStrictAppend(&info.pSubplan->pChildren, (SNode*)splCreateScanSubplan(pCxt, info.pSplitNode, 0)));
++(pCxt->groupId);
pCxt->split = true;
return code;
}
typedef struct SQnodeSplitInfo { typedef struct SQnodeSplitInfo {
SLogicNode* pSplitNode; SLogicNode* pSplitNode;
SLogicSubplan* pSubplan; SLogicSubplan* pSubplan;
@ -2054,7 +2144,7 @@ static int32_t qnodeSplit(SSplitContext* pCxt, SLogicSubplan* pSubplan) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
((SScanLogicNode*)info.pSplitNode)->dataRequired = FUNC_DATA_REQUIRED_DATA_LOAD; ((SScanLogicNode*)info.pSplitNode)->dataRequired = FUNC_DATA_REQUIRED_DATA_LOAD;
int32_t code = splCreateExchangeNodeForSubplan(pCxt, info.pSubplan, info.pSplitNode, info.pSubplan->subplanType); int32_t code = splCreateExchangeNodeForSubplan(pCxt, info.pSubplan, info.pSplitNode, info.pSubplan->subplanType, false);
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
SLogicSubplan* pScanSubplan = splCreateScanSubplan(pCxt, info.pSplitNode, 0); SLogicSubplan* pScanSubplan = splCreateScanSubplan(pCxt, info.pSplitNode, 0);
if (NULL != pScanSubplan) { if (NULL != pScanSubplan) {
@ -2075,6 +2165,45 @@ static int32_t qnodeSplit(SSplitContext* pCxt, SLogicSubplan* pSubplan) {
return code; return code;
} }
typedef struct SDynVirtualScanSplitInfo {
SDynQueryCtrlLogicNode *pDyn;
SLogicSubplan *pSubplan;
} SDynVirtualScanSplitInfo;
static bool dynVirtualScanFindSplitNode(SSplitContext* pCxt, SLogicSubplan* pSubplan, SLogicNode* pNode,
SDynVirtualScanSplitInfo* pInfo) {
if (QUERY_NODE_LOGIC_PLAN_DYN_QUERY_CTRL == nodeType(pNode) && NULL != pNode->pParent &&
QUERY_NODE_LOGIC_PLAN_EXCHANGE != nodeType(pNode->pParent) &&
((SDynQueryCtrlLogicNode*)pNode)->qType == DYN_QTYPE_VTB_SCAN) {
pInfo->pDyn = (SDynQueryCtrlLogicNode*)pNode;
pInfo->pSubplan = pSubplan;
return true;
}
return false;
}
static int32_t dynVirtualScanSplit(SSplitContext* pCxt, SLogicSubplan* pSubplan) {
int32_t code = TSDB_CODE_SUCCESS;
SDynVirtualScanSplitInfo info = {0};
if (!splMatch(pCxt, pSubplan, 0, (FSplFindSplitNode)dynVirtualScanFindSplitNode, &info)) {
return TSDB_CODE_SUCCESS;
}
SNode *pSub = NULL;
SNodeList *pSubplanChildren = info.pSubplan->pChildren;
PLAN_ERR_JRET(splCreateExchangeNodeForSubplan(pCxt, info.pSubplan, (SLogicNode*)info.pDyn, info.pSubplan->subplanType, true));
PLAN_ERR_JRET(splCreateSubplan(pCxt, (SLogicNode*)info.pDyn, (SLogicSubplan**)&pSub));
((SLogicSubplan*)pSub)->subplanType = SUBPLAN_TYPE_MERGE;
splSetSubplanVgroups((SLogicSubplan*)pSub, (SLogicNode*)info.pDyn);
PLAN_ERR_JRET(nodesListMakeStrictAppend(&info.pSubplan->pChildren, pSub));
PLAN_ERR_JRET(splMountSubplan((SLogicSubplan*)pSub, pSubplanChildren));
++(pCxt->groupId);
_return:
pCxt->split = true;
return code;
}
// clang-format off // clang-format off
static const SSplitRule splitRuleSet[] = { static const SSplitRule splitRuleSet[] = {
{.pName = "SuperTableSplit", .splitFunc = stableSplit}, {.pName = "SuperTableSplit", .splitFunc = stableSplit},
@ -2082,7 +2211,10 @@ static const SSplitRule splitRuleSet[] = {
{.pName = "UnionAllSplit", .splitFunc = unionAllSplit}, {.pName = "UnionAllSplit", .splitFunc = unionAllSplit},
{.pName = "UnionDistinctSplit", .splitFunc = unionDistinctSplit}, {.pName = "UnionDistinctSplit", .splitFunc = unionDistinctSplit},
{.pName = "SmaIndexSplit", .splitFunc = smaIndexSplit}, // not used yet {.pName = "SmaIndexSplit", .splitFunc = smaIndexSplit}, // not used yet
{.pName = "InsertSelectSplit", .splitFunc = insertSelectSplit} {.pName = "InsertSelectSplit", .splitFunc = insertSelectSplit},
{.pName = "VirtualtableSplit", .splitFunc = virtualTableSplit},
{.pName = "MergeAggColsSplit", .splitFunc = mergeAggColsSplit},
{.pName = "DynVirtualScanSplit", .splitFunc = dynVirtualScanSplit},
}; };
// clang-format on // clang-format on
@ -2138,6 +2270,9 @@ static void setVgroupsInfo(SLogicNode* pNode, SLogicSubplan* pSubplan) {
if (QUERY_NODE_LOGIC_PLAN_SCAN == nodeType(pNode)) { if (QUERY_NODE_LOGIC_PLAN_SCAN == nodeType(pNode)) {
TSWAP(((SScanLogicNode*)pNode)->pVgroupList, pSubplan->pVgroupList); TSWAP(((SScanLogicNode*)pNode)->pVgroupList, pSubplan->pVgroupList);
return; return;
} else if (QUERY_NODE_LOGIC_PLAN_VIRTUAL_TABLE_SCAN == nodeType(pNode)) {
// do nothing, since virtual table scan node is SUBPLAN_TYPE_MERGE
return;
} }
SNode* pChild; SNode* pChild;

Some files were not shown because too many files have changed in this diff Show More