TD-13704 super table plan split
This commit is contained in:
parent
cde4c9a79f
commit
b91899e757
|
@ -66,6 +66,7 @@ typedef enum ENodeType {
|
||||||
QUERY_NODE_DATABLOCK_DESC,
|
QUERY_NODE_DATABLOCK_DESC,
|
||||||
QUERY_NODE_SLOT_DESC,
|
QUERY_NODE_SLOT_DESC,
|
||||||
QUERY_NODE_COLUMN_DEF,
|
QUERY_NODE_COLUMN_DEF,
|
||||||
|
QUERY_NODE_DOWNSTREAM_SOURCE,
|
||||||
|
|
||||||
// Statement nodes are used in parser and planner module.
|
// Statement nodes are used in parser and planner module.
|
||||||
QUERY_NODE_SET_OPERATOR,
|
QUERY_NODE_SET_OPERATOR,
|
||||||
|
@ -98,6 +99,7 @@ typedef enum ENodeType {
|
||||||
QUERY_NODE_LOGIC_PLAN_AGG,
|
QUERY_NODE_LOGIC_PLAN_AGG,
|
||||||
QUERY_NODE_LOGIC_PLAN_PROJECT,
|
QUERY_NODE_LOGIC_PLAN_PROJECT,
|
||||||
QUERY_NODE_LOGIC_PLAN_VNODE_MODIF,
|
QUERY_NODE_LOGIC_PLAN_VNODE_MODIF,
|
||||||
|
QUERY_NODE_LOGIC_PLAN_EXCHANGE,
|
||||||
QUERY_NODE_LOGIC_SUBPLAN,
|
QUERY_NODE_LOGIC_SUBPLAN,
|
||||||
QUERY_NODE_LOGIC_PLAN,
|
QUERY_NODE_LOGIC_PLAN,
|
||||||
|
|
||||||
|
|
|
@ -67,12 +67,17 @@ typedef struct SProjectLogicNode {
|
||||||
} SProjectLogicNode;
|
} SProjectLogicNode;
|
||||||
|
|
||||||
typedef struct SVnodeModifLogicNode {
|
typedef struct SVnodeModifLogicNode {
|
||||||
ENodeType type;;
|
SLogicNode node;;
|
||||||
int32_t msgType;
|
int32_t msgType;
|
||||||
SArray* pDataBlocks;
|
SArray* pDataBlocks;
|
||||||
SVgDataBlocks* pVgDataBlocks;
|
SVgDataBlocks* pVgDataBlocks;
|
||||||
} SVnodeModifLogicNode;
|
} SVnodeModifLogicNode;
|
||||||
|
|
||||||
|
typedef struct SExchangeLogicNode {
|
||||||
|
SLogicNode node;
|
||||||
|
int32_t srcGroupId;
|
||||||
|
} SExchangeLogicNode;
|
||||||
|
|
||||||
typedef enum ESubplanType {
|
typedef enum ESubplanType {
|
||||||
SUBPLAN_TYPE_MERGE = 1,
|
SUBPLAN_TYPE_MERGE = 1,
|
||||||
SUBPLAN_TYPE_PARTIAL,
|
SUBPLAN_TYPE_PARTIAL,
|
||||||
|
@ -80,13 +85,22 @@ typedef enum ESubplanType {
|
||||||
SUBPLAN_TYPE_MODIFY
|
SUBPLAN_TYPE_MODIFY
|
||||||
} ESubplanType;
|
} ESubplanType;
|
||||||
|
|
||||||
|
typedef struct SSubplanId {
|
||||||
|
uint64_t queryId;
|
||||||
|
int32_t groupId;
|
||||||
|
int32_t subplanId;
|
||||||
|
} SSubplanId;
|
||||||
|
|
||||||
typedef struct SSubLogicPlan {
|
typedef struct SSubLogicPlan {
|
||||||
ENodeType type;
|
ENodeType type;
|
||||||
|
SSubplanId id;
|
||||||
SNodeList* pChildren;
|
SNodeList* pChildren;
|
||||||
SNodeList* pParents;
|
SNodeList* pParents;
|
||||||
SLogicNode* pNode;
|
SLogicNode* pNode;
|
||||||
ESubplanType subplanType;
|
ESubplanType subplanType;
|
||||||
|
SVgroupsInfo* pVgroupList;
|
||||||
int32_t level;
|
int32_t level;
|
||||||
|
int32_t splitFlag;
|
||||||
} SSubLogicPlan;
|
} SSubLogicPlan;
|
||||||
|
|
||||||
typedef struct SQueryLogicPlan {
|
typedef struct SQueryLogicPlan {
|
||||||
|
@ -161,20 +175,21 @@ typedef struct SAggPhysiNode {
|
||||||
SNodeList* pAggFuncs;
|
SNodeList* pAggFuncs;
|
||||||
} SAggPhysiNode;
|
} SAggPhysiNode;
|
||||||
|
|
||||||
typedef struct SDownstreamSource {
|
typedef struct SDownstreamSourceNode {
|
||||||
|
ENodeType type;
|
||||||
SQueryNodeAddr addr;
|
SQueryNodeAddr addr;
|
||||||
uint64_t taskId;
|
uint64_t taskId;
|
||||||
uint64_t schedId;
|
uint64_t schedId;
|
||||||
} SDownstreamSource;
|
} SDownstreamSourceNode;
|
||||||
|
|
||||||
typedef struct SExchangePhysiNode {
|
typedef struct SExchangePhysiNode {
|
||||||
SPhysiNode node;
|
SPhysiNode node;
|
||||||
uint64_t srcTemplateId; // template id of datasource suplans
|
int32_t srcGroupId; // group id of datasource suplans
|
||||||
SArray* pSrcEndPoints; // SArray<SDownstreamSource>, scheduler fill by calling qSetSuplanExecutionNode
|
SNodeList* pSrcEndPoints; // element is SDownstreamSource, scheduler fill by calling qSetSuplanExecutionNode
|
||||||
} SExchangePhysiNode;
|
} SExchangePhysiNode;
|
||||||
|
|
||||||
typedef struct SDataSinkNode {
|
typedef struct SDataSinkNode {
|
||||||
ENodeType type;;
|
ENodeType type;
|
||||||
SDataBlockDescNode* pInputDataBlockDesc;
|
SDataBlockDescNode* pInputDataBlockDesc;
|
||||||
} SDataSinkNode;
|
} SDataSinkNode;
|
||||||
|
|
||||||
|
@ -189,12 +204,6 @@ typedef struct SDataInserterNode {
|
||||||
char *pData;
|
char *pData;
|
||||||
} SDataInserterNode;
|
} SDataInserterNode;
|
||||||
|
|
||||||
typedef struct SSubplanId {
|
|
||||||
uint64_t queryId;
|
|
||||||
int32_t templateId;
|
|
||||||
int32_t subplanId;
|
|
||||||
} SSubplanId;
|
|
||||||
|
|
||||||
typedef struct SSubplan {
|
typedef struct SSubplan {
|
||||||
ENodeType type;
|
ENodeType type;
|
||||||
SSubplanId id; // unique id of the subplan
|
SSubplanId id; // unique id of the subplan
|
||||||
|
|
|
@ -32,9 +32,9 @@ int32_t qCreateQueryPlan(SPlanContext* pCxt, SQueryPlan** pPlan, SArray* pExecNo
|
||||||
|
|
||||||
// Set datasource of this subplan, multiple calls may be made to a subplan.
|
// Set datasource of this subplan, multiple calls may be made to a subplan.
|
||||||
// @subplan subplan to be schedule
|
// @subplan subplan to be schedule
|
||||||
// @templateId templateId of a group of datasource subplans of this @subplan
|
// @groupId id of a group of datasource subplans of this @subplan
|
||||||
// @ep one execution location of this group of datasource subplans
|
// @ep one execution location of this group of datasource subplans
|
||||||
void qSetSubplanExecutionNode(SSubplan* subplan, uint64_t templateId, SDownstreamSource* pSource);
|
void qSetSubplanExecutionNode(SSubplan* subplan, int32_t groupId, SDownstreamSourceNode* pSource);
|
||||||
|
|
||||||
// Convert to subplan to string for the scheduler to send to the executor
|
// Convert to subplan to string for the scheduler to send to the executor
|
||||||
int32_t qSubPlanToString(const SSubplan* subplan, char** str, int32_t* len);
|
int32_t qSubPlanToString(const SSubplan* subplan, char** str, int32_t* len);
|
||||||
|
|
|
@ -4984,7 +4984,7 @@ static int32_t doSendFetchDataRequest(SExchangeInfo *pExchangeInfo, SExecTaskInf
|
||||||
return pTaskInfo->code;
|
return pTaskInfo->code;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDownstreamSource *pSource = taosArrayGet(pExchangeInfo->pSources, sourceIndex);
|
SDownstreamSourceNode *pSource = taosArrayGet(pExchangeInfo->pSources, sourceIndex);
|
||||||
SSourceDataInfo *pDataInfo = taosArrayGet(pExchangeInfo->pSourceDataInfo, sourceIndex);
|
SSourceDataInfo *pDataInfo = taosArrayGet(pExchangeInfo->pSourceDataInfo, sourceIndex);
|
||||||
|
|
||||||
qDebug("%s build fetch msg and send to vgId:%d, ep:%s, taskId:0x%" PRIx64 ", %d/%" PRIzu,
|
qDebug("%s build fetch msg and send to vgId:%d, ep:%s, taskId:0x%" PRIx64 ", %d/%" PRIzu,
|
||||||
|
@ -5082,7 +5082,7 @@ static SSDataBlock* concurrentlyLoadRemoteDataImpl(SOperatorInfo *pOperator, SEx
|
||||||
}
|
}
|
||||||
|
|
||||||
SRetrieveTableRsp* pRsp = pDataInfo->pRsp;
|
SRetrieveTableRsp* pRsp = pDataInfo->pRsp;
|
||||||
SDownstreamSource* pSource = taosArrayGet(pExchangeInfo->pSources, i);
|
SDownstreamSourceNode* pSource = taosArrayGet(pExchangeInfo->pSources, i);
|
||||||
|
|
||||||
SSDataBlock* pRes = pExchangeInfo->pResult;
|
SSDataBlock* pRes = pExchangeInfo->pResult;
|
||||||
|
|
||||||
|
@ -5179,7 +5179,7 @@ static SSDataBlock* seqLoadRemoteData(SOperatorInfo *pOperator) {
|
||||||
tsem_wait(&pExchangeInfo->ready);
|
tsem_wait(&pExchangeInfo->ready);
|
||||||
|
|
||||||
SSourceDataInfo* pDataInfo = taosArrayGet(pExchangeInfo->pSourceDataInfo, pExchangeInfo->current);
|
SSourceDataInfo* pDataInfo = taosArrayGet(pExchangeInfo->pSourceDataInfo, pExchangeInfo->current);
|
||||||
SDownstreamSource* pSource = taosArrayGet(pExchangeInfo->pSources, pExchangeInfo->current);
|
SDownstreamSourceNode* pSource = taosArrayGet(pExchangeInfo->pSources, pExchangeInfo->current);
|
||||||
|
|
||||||
SRetrieveTableRsp* pRsp = pDataInfo->pRsp;
|
SRetrieveTableRsp* pRsp = pDataInfo->pRsp;
|
||||||
if (pRsp->numOfRows == 0) {
|
if (pRsp->numOfRows == 0) {
|
||||||
|
|
|
@ -51,7 +51,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const int funcMgtBuiltinsNum = (sizeof(funcMgtBuiltins) / sizeof(SBuiltinFuncDefinition));
|
const int32_t funcMgtBuiltinsNum = (sizeof(funcMgtBuiltins) / sizeof(SBuiltinFuncDefinition));
|
||||||
|
|
||||||
int32_t stubCheckAndGetResultType(SFunctionNode* pFunc) {
|
int32_t stubCheckAndGetResultType(SFunctionNode* pFunc) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
|
|
@ -60,6 +60,9 @@
|
||||||
|
|
||||||
#define CLONE_OBJECT_FIELD(fldname, cloneFunc) \
|
#define CLONE_OBJECT_FIELD(fldname, cloneFunc) \
|
||||||
do { \
|
do { \
|
||||||
|
if (NULL == (pSrc)->fldname) { \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
(pDst)->fldname = cloneFunc((pSrc)->fldname); \
|
(pDst)->fldname = cloneFunc((pSrc)->fldname); \
|
||||||
if (NULL == (pDst)->fldname) { \
|
if (NULL == (pDst)->fldname) { \
|
||||||
nodesDestroyNode((SNode*)(pDst)); \
|
nodesDestroyNode((SNode*)(pDst)); \
|
||||||
|
@ -234,10 +237,17 @@ static SNode* logicProjectCopy(const SProjectLogicNode* pSrc, SProjectLogicNode*
|
||||||
}
|
}
|
||||||
|
|
||||||
static SNode* logicVnodeModifCopy(const SVnodeModifLogicNode* pSrc, SVnodeModifLogicNode* pDst) {
|
static SNode* logicVnodeModifCopy(const SVnodeModifLogicNode* pSrc, SVnodeModifLogicNode* pDst) {
|
||||||
|
COPY_BASE_OBJECT_FIELD(node, logicNodeCopy);
|
||||||
COPY_SCALAR_FIELD(msgType);
|
COPY_SCALAR_FIELD(msgType);
|
||||||
return (SNode*)pDst;
|
return (SNode*)pDst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SNode* logicExchangeCopy(const SExchangeLogicNode* pSrc, SExchangeLogicNode* pDst) {
|
||||||
|
COPY_BASE_OBJECT_FIELD(node, logicNodeCopy);
|
||||||
|
COPY_SCALAR_FIELD(srcGroupId);
|
||||||
|
return (SNode*)pDst;
|
||||||
|
}
|
||||||
|
|
||||||
static SNode* logicSubplanCopy(const SSubLogicPlan* pSrc, SSubLogicPlan* pDst) {
|
static SNode* logicSubplanCopy(const SSubLogicPlan* pSrc, SSubLogicPlan* pDst) {
|
||||||
CLONE_NODE_FIELD(pNode);
|
CLONE_NODE_FIELD(pNode);
|
||||||
COPY_SCALAR_FIELD(subplanType);
|
COPY_SCALAR_FIELD(subplanType);
|
||||||
|
@ -304,6 +314,8 @@ SNodeptr nodesCloneNode(const SNodeptr pNode) {
|
||||||
return logicProjectCopy((const SProjectLogicNode*)pNode, (SProjectLogicNode*)pDst);
|
return logicProjectCopy((const SProjectLogicNode*)pNode, (SProjectLogicNode*)pDst);
|
||||||
case QUERY_NODE_LOGIC_PLAN_VNODE_MODIF:
|
case QUERY_NODE_LOGIC_PLAN_VNODE_MODIF:
|
||||||
return logicVnodeModifCopy((const SVnodeModifLogicNode*)pNode, (SVnodeModifLogicNode*)pDst);
|
return logicVnodeModifCopy((const SVnodeModifLogicNode*)pNode, (SVnodeModifLogicNode*)pDst);
|
||||||
|
case QUERY_NODE_LOGIC_PLAN_EXCHANGE:
|
||||||
|
return logicExchangeCopy((const SExchangeLogicNode*)pNode, (SExchangeLogicNode*)pDst);
|
||||||
case QUERY_NODE_LOGIC_SUBPLAN:
|
case QUERY_NODE_LOGIC_SUBPLAN:
|
||||||
return logicSubplanCopy((const SSubLogicPlan*)pNode, (SSubLogicPlan*)pDst);
|
return logicSubplanCopy((const SSubLogicPlan*)pNode, (SSubLogicPlan*)pDst);
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -496,6 +496,37 @@ static int32_t jsonToPhysiAggNode(const SJson* pJson, void* pObj) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char* jkExchangePhysiPlanSrcGroupId = "SrcGroupId";
|
||||||
|
static const char* jkExchangePhysiPlanSrcEndPoints = "SrcEndPoints";
|
||||||
|
|
||||||
|
static int32_t physiExchangeNodeToJson(const void* pObj, SJson* pJson) {
|
||||||
|
const SExchangePhysiNode* pNode = (const SExchangePhysiNode*)pObj;
|
||||||
|
|
||||||
|
int32_t code = physicPlanNodeToJson(pObj, pJson);
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonAddIntegerToObject(pJson, jkExchangePhysiPlanSrcGroupId, pNode->srcGroupId);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = nodeListToJson(pJson, jkExchangePhysiPlanSrcEndPoints, pNode->pSrcEndPoints);
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t jsonToPhysiExchangeNode(const SJson* pJson, void* pObj) {
|
||||||
|
SExchangePhysiNode* pNode = (SExchangePhysiNode*)pObj;
|
||||||
|
|
||||||
|
int32_t code = jsonToPhysicPlanNode(pJson, pObj);
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonGetIntValue(pJson, jkExchangePhysiPlanSrcGroupId, &pNode->srcGroupId);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = jsonToNodeList(pJson, jkExchangePhysiPlanSrcEndPoints, &pNode->pSrcEndPoints);
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
static const char* jkDataSinkInputDataBlockDesc = "InputDataBlockDesc";
|
static const char* jkDataSinkInputDataBlockDesc = "InputDataBlockDesc";
|
||||||
|
|
||||||
static int32_t physicDataSinkNodeToJson(const void* pObj, SJson* pJson) {
|
static int32_t physicDataSinkNodeToJson(const void* pObj, SJson* pJson) {
|
||||||
|
@ -517,7 +548,7 @@ static int32_t jsonToPhysiDispatchNode(const SJson* pJson, void* pObj) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char* jkSubplanIdQueryId = "QueryId";
|
static const char* jkSubplanIdQueryId = "QueryId";
|
||||||
static const char* jkSubplanIdTemplateId = "TemplateId";
|
static const char* jkSubplanIdGroupId = "GroupId";
|
||||||
static const char* jkSubplanIdSubplanId = "SubplanId";
|
static const char* jkSubplanIdSubplanId = "SubplanId";
|
||||||
|
|
||||||
static int32_t subplanIdToJson(const void* pObj, SJson* pJson) {
|
static int32_t subplanIdToJson(const void* pObj, SJson* pJson) {
|
||||||
|
@ -525,7 +556,7 @@ static int32_t subplanIdToJson(const void* pObj, SJson* pJson) {
|
||||||
|
|
||||||
int32_t code = tjsonAddIntegerToObject(pJson, jkSubplanIdQueryId, pNode->queryId);
|
int32_t code = tjsonAddIntegerToObject(pJson, jkSubplanIdQueryId, pNode->queryId);
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = tjsonAddIntegerToObject(pJson, jkSubplanIdTemplateId, pNode->templateId);
|
code = tjsonAddIntegerToObject(pJson, jkSubplanIdGroupId, pNode->groupId);
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = tjsonAddIntegerToObject(pJson, jkSubplanIdSubplanId, pNode->subplanId);
|
code = tjsonAddIntegerToObject(pJson, jkSubplanIdSubplanId, pNode->subplanId);
|
||||||
|
@ -539,7 +570,7 @@ static int32_t jsonToSubplanId(const SJson* pJson, void* pObj) {
|
||||||
|
|
||||||
int32_t code = tjsonGetUBigIntValue(pJson, jkSubplanIdQueryId, &pNode->queryId);
|
int32_t code = tjsonGetUBigIntValue(pJson, jkSubplanIdQueryId, &pNode->queryId);
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = tjsonGetIntValue(pJson, jkSubplanIdTemplateId, &pNode->templateId);
|
code = tjsonGetIntValue(pJson, jkSubplanIdGroupId, &pNode->groupId);
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = tjsonGetIntValue(pJson, jkSubplanIdSubplanId, &pNode->subplanId);
|
code = tjsonGetIntValue(pJson, jkSubplanIdSubplanId, &pNode->subplanId);
|
||||||
|
@ -1387,7 +1418,9 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_AGG:
|
case QUERY_NODE_PHYSICAL_PLAN_AGG:
|
||||||
return physiAggNodeToJson(pObj, pJson);
|
return physiAggNodeToJson(pObj, pJson);
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_EXCHANGE:
|
case QUERY_NODE_PHYSICAL_PLAN_EXCHANGE:
|
||||||
|
return physiExchangeNodeToJson(pObj, pJson);
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_SORT:
|
case QUERY_NODE_PHYSICAL_PLAN_SORT:
|
||||||
|
break;
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_DISPATCH:
|
case QUERY_NODE_PHYSICAL_PLAN_DISPATCH:
|
||||||
return physiDispatchNodeToJson(pObj, pJson);
|
return physiDispatchNodeToJson(pObj, pJson);
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_INSERT:
|
case QUERY_NODE_PHYSICAL_PLAN_INSERT:
|
||||||
|
@ -1459,6 +1492,8 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) {
|
||||||
return jsonToPhysiJoinNode(pJson, pObj);
|
return jsonToPhysiJoinNode(pJson, pObj);
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_AGG:
|
case QUERY_NODE_PHYSICAL_PLAN_AGG:
|
||||||
return jsonToPhysiAggNode(pJson, pObj);
|
return jsonToPhysiAggNode(pJson, pObj);
|
||||||
|
case QUERY_NODE_PHYSICAL_PLAN_EXCHANGE:
|
||||||
|
return jsonToPhysiExchangeNode(pJson, pObj);
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_DISPATCH:
|
case QUERY_NODE_PHYSICAL_PLAN_DISPATCH:
|
||||||
return jsonToPhysiDispatchNode(pJson, pObj);
|
return jsonToPhysiDispatchNode(pJson, pObj);
|
||||||
case QUERY_NODE_PHYSICAL_SUBPLAN:
|
case QUERY_NODE_PHYSICAL_SUBPLAN:
|
||||||
|
|
|
@ -129,6 +129,8 @@ SNodeptr nodesMakeNode(ENodeType type) {
|
||||||
return makeNode(type, sizeof(SProjectLogicNode));
|
return makeNode(type, sizeof(SProjectLogicNode));
|
||||||
case QUERY_NODE_LOGIC_PLAN_VNODE_MODIF:
|
case QUERY_NODE_LOGIC_PLAN_VNODE_MODIF:
|
||||||
return makeNode(type, sizeof(SVnodeModifLogicNode));
|
return makeNode(type, sizeof(SVnodeModifLogicNode));
|
||||||
|
case QUERY_NODE_LOGIC_PLAN_EXCHANGE:
|
||||||
|
return makeNode(type, sizeof(SExchangeLogicNode));
|
||||||
case QUERY_NODE_LOGIC_SUBPLAN:
|
case QUERY_NODE_LOGIC_SUBPLAN:
|
||||||
return makeNode(type, sizeof(SSubLogicPlan));
|
return makeNode(type, sizeof(SSubLogicPlan));
|
||||||
case QUERY_NODE_LOGIC_PLAN:
|
case QUERY_NODE_LOGIC_PLAN:
|
||||||
|
|
|
@ -50,6 +50,7 @@ extern "C" {
|
||||||
|
|
||||||
int32_t createLogicPlan(SPlanContext* pCxt, SLogicNode** pLogicNode);
|
int32_t createLogicPlan(SPlanContext* pCxt, SLogicNode** pLogicNode);
|
||||||
int32_t optimize(SPlanContext* pCxt, SLogicNode* pLogicNode);
|
int32_t optimize(SPlanContext* pCxt, SLogicNode* pLogicNode);
|
||||||
|
int32_t applySplitRule(SSubLogicPlan* pSubplan);
|
||||||
int32_t createPhysiPlan(SPlanContext* pCxt, SLogicNode* pLogicNode, SQueryPlan** pPlan, SArray* pExecNodeList);
|
int32_t createPhysiPlan(SPlanContext* pCxt, SLogicNode* pLogicNode, SQueryPlan** pPlan, SArray* pExecNodeList);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -28,6 +28,8 @@ typedef struct SPhysiPlanContext {
|
||||||
int16_t nextDataBlockId;
|
int16_t nextDataBlockId;
|
||||||
SArray* pLocationHelper;
|
SArray* pLocationHelper;
|
||||||
SArray* pExecNodeList;
|
SArray* pExecNodeList;
|
||||||
|
int32_t groupId;
|
||||||
|
int32_t subplanId;
|
||||||
} SPhysiPlanContext;
|
} SPhysiPlanContext;
|
||||||
|
|
||||||
static int32_t getSlotKey(SNode* pNode, char* pKey) {
|
static int32_t getSlotKey(SNode* pNode, char* pKey) {
|
||||||
|
@ -81,12 +83,7 @@ static int32_t addDataBlockDesc(SPhysiPlanContext* pCxt, SNodeList* pList, SData
|
||||||
SNode* pNode = NULL;
|
SNode* pNode = NULL;
|
||||||
int16_t slotId = taosHashGetSize(pHash);
|
int16_t slotId = taosHashGetSize(pHash);
|
||||||
FOREACH(pNode, pList) {
|
FOREACH(pNode, pList) {
|
||||||
SNode* pSlot = createSlotDesc(pCxt, pNode, slotId);
|
CHECK_CODE_EXT(nodesListStrictAppend(pDataBlockDesc->pSlots, createSlotDesc(pCxt, pNode, slotId)));
|
||||||
CHECK_ALLOC(pSlot, TSDB_CODE_OUT_OF_MEMORY);
|
|
||||||
if (TSDB_CODE_SUCCESS != nodesListAppend(pDataBlockDesc->pSlots, (SNode*)pSlot)) {
|
|
||||||
nodesDestroyNode(pSlot);
|
|
||||||
return TSDB_CODE_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
SSlotIndex index = { .dataBlockId = pDataBlockDesc->dataBlockId, .slotId = slotId };
|
SSlotIndex index = { .dataBlockId = pDataBlockDesc->dataBlockId, .slotId = slotId };
|
||||||
char name[TSDB_TABLE_NAME_LEN + TSDB_COL_NAME_LEN];
|
char name[TSDB_TABLE_NAME_LEN + TSDB_COL_NAME_LEN];
|
||||||
|
@ -97,7 +94,7 @@ static int32_t addDataBlockDesc(SPhysiPlanContext* pCxt, SNodeList* pList, SData
|
||||||
CHECK_ALLOC(pTarget, TSDB_CODE_OUT_OF_MEMORY);
|
CHECK_ALLOC(pTarget, TSDB_CODE_OUT_OF_MEMORY);
|
||||||
REPLACE_NODE(pTarget);
|
REPLACE_NODE(pTarget);
|
||||||
|
|
||||||
pDataBlockDesc->resultRowSize += ((SSlotDescNode*)pSlot)->dataType.bytes;
|
pDataBlockDesc->resultRowSize += ((SExprNode*)pNode)->resType.bytes;
|
||||||
++slotId;
|
++slotId;
|
||||||
}
|
}
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
@ -467,6 +464,14 @@ static SPhysiNode* createProjectPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pC
|
||||||
return (SPhysiNode*)pProject;
|
return (SPhysiNode*)pProject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SPhysiNode* createExchangePhysiNode(SPhysiPlanContext* pCxt, SExchangeLogicNode* pExchangeLogicNode) {
|
||||||
|
SExchangePhysiNode* pExchange = (SExchangePhysiNode*)makePhysiNode(pCxt, QUERY_NODE_PHYSICAL_PLAN_EXCHANGE);
|
||||||
|
CHECK_ALLOC(pExchange, NULL);
|
||||||
|
CHECK_CODE(addDataBlockDesc(pCxt, pExchangeLogicNode->node.pTargets, pExchange->node.pOutputDataBlockDesc), (SPhysiNode*)pExchange);
|
||||||
|
pExchange->srcGroupId = pExchangeLogicNode->srcGroupId;
|
||||||
|
return (SPhysiNode*)pExchange;
|
||||||
|
}
|
||||||
|
|
||||||
static SPhysiNode* createPhysiNode(SPhysiPlanContext* pCxt, SSubplan* pSubplan, SLogicNode* pLogicPlan) {
|
static SPhysiNode* createPhysiNode(SPhysiPlanContext* pCxt, SSubplan* pSubplan, SLogicNode* pLogicPlan) {
|
||||||
SNodeList* pChildren = nodesMakeList();
|
SNodeList* pChildren = nodesMakeList();
|
||||||
CHECK_ALLOC(pChildren, NULL);
|
CHECK_ALLOC(pChildren, NULL);
|
||||||
|
@ -495,6 +500,9 @@ static SPhysiNode* createPhysiNode(SPhysiPlanContext* pCxt, SSubplan* pSubplan,
|
||||||
case QUERY_NODE_LOGIC_PLAN_PROJECT:
|
case QUERY_NODE_LOGIC_PLAN_PROJECT:
|
||||||
pPhyNode = createProjectPhysiNode(pCxt, pChildren, (SProjectLogicNode*)pLogicPlan);
|
pPhyNode = createProjectPhysiNode(pCxt, pChildren, (SProjectLogicNode*)pLogicPlan);
|
||||||
break;
|
break;
|
||||||
|
case QUERY_NODE_LOGIC_PLAN_EXCHANGE:
|
||||||
|
pPhyNode = createExchangePhysiNode(pCxt, (SExchangeLogicNode*)pLogicPlan);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -525,8 +533,15 @@ static SDataSinkNode* createDataDispatcher(SPhysiPlanContext* pCxt, const SPhysi
|
||||||
return (SDataSinkNode*)pDispatcher;
|
return (SDataSinkNode*)pDispatcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SSubplan* makeSubplan(SPhysiPlanContext* pCxt, SSubLogicPlan* pLogicSubplan) {
|
||||||
|
SSubplan* pSubplan = nodesMakeNode(QUERY_NODE_PHYSICAL_SUBPLAN);
|
||||||
|
CHECK_ALLOC(pSubplan, NULL);
|
||||||
|
pSubplan->id = pLogicSubplan->id;
|
||||||
|
return pSubplan;
|
||||||
|
}
|
||||||
|
|
||||||
static SSubplan* createPhysiSubplan(SPhysiPlanContext* pCxt, SSubLogicPlan* pLogicSubplan) {
|
static SSubplan* createPhysiSubplan(SPhysiPlanContext* pCxt, SSubLogicPlan* pLogicSubplan) {
|
||||||
SSubplan* pSubplan = (SSubplan*)nodesMakeNode(QUERY_NODE_PHYSICAL_SUBPLAN);
|
SSubplan* pSubplan = makeSubplan(pCxt, pLogicSubplan);
|
||||||
CHECK_ALLOC(pSubplan, NULL);
|
CHECK_ALLOC(pSubplan, NULL);
|
||||||
if (SUBPLAN_TYPE_MODIFY == pLogicSubplan->subplanType) {
|
if (SUBPLAN_TYPE_MODIFY == pLogicSubplan->subplanType) {
|
||||||
SVnodeModifLogicNode* pModif = (SVnodeModifLogicNode*)pLogicSubplan->pNode;
|
SVnodeModifLogicNode* pModif = (SVnodeModifLogicNode*)pLogicSubplan->pNode;
|
||||||
|
@ -540,9 +555,22 @@ static SSubplan* createPhysiSubplan(SPhysiPlanContext* pCxt, SSubLogicPlan* pLog
|
||||||
pSubplan->msgType = TDMT_VND_QUERY;
|
pSubplan->msgType = TDMT_VND_QUERY;
|
||||||
}
|
}
|
||||||
pSubplan->subplanType = pLogicSubplan->subplanType;
|
pSubplan->subplanType = pLogicSubplan->subplanType;
|
||||||
|
pSubplan->level = pLogicSubplan->level;
|
||||||
return pSubplan;
|
return pSubplan;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void doSetLogicNodeParent(SLogicNode* pNode, SLogicNode* pParent) {
|
||||||
|
pNode->pParent = pParent;
|
||||||
|
SNode* pChild;
|
||||||
|
FOREACH(pChild, pNode->pChildren) {
|
||||||
|
doSetLogicNodeParent((SLogicNode*)pChild, pNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setLogicNodeParent(SLogicNode* pNode) {
|
||||||
|
doSetLogicNodeParent(pNode, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t splitLogicPlan(SPhysiPlanContext* pCxt, SLogicNode* pLogicNode, SSubLogicPlan** pSubLogicPlan) {
|
static int32_t splitLogicPlan(SPhysiPlanContext* pCxt, SLogicNode* pLogicNode, SSubLogicPlan** pSubLogicPlan) {
|
||||||
*pSubLogicPlan = (SSubLogicPlan*)nodesMakeNode(QUERY_NODE_LOGIC_SUBPLAN);
|
*pSubLogicPlan = (SSubLogicPlan*)nodesMakeNode(QUERY_NODE_LOGIC_SUBPLAN);
|
||||||
CHECK_ALLOC(*pSubLogicPlan, TSDB_CODE_OUT_OF_MEMORY);
|
CHECK_ALLOC(*pSubLogicPlan, TSDB_CODE_OUT_OF_MEMORY);
|
||||||
|
@ -553,8 +581,9 @@ static int32_t splitLogicPlan(SPhysiPlanContext* pCxt, SLogicNode* pLogicNode, S
|
||||||
} else {
|
} else {
|
||||||
(*pSubLogicPlan)->subplanType = SUBPLAN_TYPE_MERGE;
|
(*pSubLogicPlan)->subplanType = SUBPLAN_TYPE_MERGE;
|
||||||
}
|
}
|
||||||
// todo split
|
(*pSubLogicPlan)->id.queryId = pCxt->pPlanCxt->queryId;
|
||||||
return TSDB_CODE_SUCCESS;
|
setLogicNodeParent((*pSubLogicPlan)->pNode);
|
||||||
|
return applySplitRule(*pSubLogicPlan);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t pushSubplan(SPhysiPlanContext* pCxt, SNodeptr pSubplan, int32_t level, SNodeList* pSubplans) {
|
static int32_t pushSubplan(SPhysiPlanContext* pCxt, SNodeptr pSubplan, int32_t level, SNodeList* pSubplans) {
|
||||||
|
@ -571,6 +600,7 @@ static int32_t pushSubplan(SPhysiPlanContext* pCxt, SNodeptr pSubplan, int32_t l
|
||||||
CHECK_ALLOC(pGroup->pNodeList, TSDB_CODE_OUT_OF_MEMORY);
|
CHECK_ALLOC(pGroup->pNodeList, TSDB_CODE_OUT_OF_MEMORY);
|
||||||
}
|
}
|
||||||
CHECK_CODE(nodesListStrictAppend(pGroup->pNodeList, pSubplan), TSDB_CODE_OUT_OF_MEMORY);
|
CHECK_CODE(nodesListStrictAppend(pGroup->pNodeList, pSubplan), TSDB_CODE_OUT_OF_MEMORY);
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
SSubLogicPlan* singleCloneSubLogicPlan(SPhysiPlanContext* pCxt, SSubLogicPlan* pSrc, int32_t level) {
|
SSubLogicPlan* singleCloneSubLogicPlan(SPhysiPlanContext* pCxt, SSubLogicPlan* pSrc, int32_t level) {
|
||||||
|
@ -583,29 +613,105 @@ SSubLogicPlan* singleCloneSubLogicPlan(SPhysiPlanContext* pCxt, SSubLogicPlan* p
|
||||||
}
|
}
|
||||||
pDst->subplanType = pSrc->subplanType;
|
pDst->subplanType = pSrc->subplanType;
|
||||||
pDst->level = level;
|
pDst->level = level;
|
||||||
|
pDst->id.queryId = pCxt->pPlanCxt->queryId;
|
||||||
|
pDst->id.groupId = pCxt->groupId;
|
||||||
|
pDst->id.subplanId = pCxt->subplanId++;
|
||||||
return pDst;
|
return pDst;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t doScaleOut(SPhysiPlanContext* pCxt, SSubLogicPlan* pSubplan, int32_t level, SQueryLogicPlan* pLogicPlan) {
|
static int32_t scaleOutForModify(SPhysiPlanContext* pCxt, SSubLogicPlan* pSubplan, int32_t level, SQueryLogicPlan* pLogicPlan, SNodeList* pGroup) {
|
||||||
if (SUBPLAN_TYPE_MODIFY == pSubplan->subplanType) {
|
SVnodeModifLogicNode* pNode = (SVnodeModifLogicNode*)pSubplan->pNode;
|
||||||
SVnodeModifLogicNode* pNode = (SVnodeModifLogicNode*)pSubplan->pNode;
|
size_t numOfVgroups = taosArrayGetSize(pNode->pDataBlocks);
|
||||||
size_t numOfVgroups = taosArrayGetSize(pNode->pDataBlocks);
|
for (int32_t i = 0; i < numOfVgroups; ++i) {
|
||||||
for (int32_t i = 0; i < numOfVgroups; ++i) {
|
|
||||||
SSubLogicPlan* pNewSubplan = singleCloneSubLogicPlan(pCxt, pSubplan, level);
|
|
||||||
CHECK_ALLOC(pNewSubplan, TSDB_CODE_OUT_OF_MEMORY);
|
|
||||||
SVgDataBlocks* blocks = (SVgDataBlocks*)taosArrayGetP(pNode->pDataBlocks, i);
|
|
||||||
((SVnodeModifLogicNode*)pNewSubplan->pNode)->pVgDataBlocks = blocks;
|
|
||||||
CHECK_CODE_EXT(pushSubplan(pCxt, pNewSubplan, level, pLogicPlan->pSubplans));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
SSubLogicPlan* pNewSubplan = singleCloneSubLogicPlan(pCxt, pSubplan, level);
|
SSubLogicPlan* pNewSubplan = singleCloneSubLogicPlan(pCxt, pSubplan, level);
|
||||||
CHECK_ALLOC(pNewSubplan, TSDB_CODE_OUT_OF_MEMORY);
|
CHECK_ALLOC(pNewSubplan, TSDB_CODE_OUT_OF_MEMORY);
|
||||||
CHECK_CODE_EXT(pushSubplan(pCxt, pNewSubplan, level, pLogicPlan->pSubplans));
|
SVgDataBlocks* blocks = (SVgDataBlocks*)taosArrayGetP(pNode->pDataBlocks, i);
|
||||||
|
((SVnodeModifLogicNode*)pNewSubplan->pNode)->pVgDataBlocks = blocks;
|
||||||
|
// CHECK_CODE_EXT(pushSubplan(pCxt, pNewSubplan, level, pLogicPlan->pSubplans));
|
||||||
|
CHECK_CODE_EXT(nodesListAppend(pGroup, pNewSubplan));
|
||||||
}
|
}
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t scaleOutForMerge(SPhysiPlanContext* pCxt, SSubLogicPlan* pSubplan, int32_t level, SQueryLogicPlan* pLogicPlan, SNodeList* pGroup) {
|
||||||
|
// SSubLogicPlan* pNewSubplan = singleCloneSubLogicPlan(pCxt, pSubplan, level);
|
||||||
|
// CHECK_ALLOC(pNewSubplan, TSDB_CODE_OUT_OF_MEMORY);
|
||||||
|
// CHECK_CODE_EXT(pushSubplan(pCxt, pNewSubplan, level, pLogicPlan->pSubplans));
|
||||||
|
// return TSDB_CODE_SUCCESS;
|
||||||
|
return nodesListStrictAppend(pGroup, singleCloneSubLogicPlan(pCxt, pSubplan, level));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t doSetScanVgroup(SPhysiPlanContext* pCxt, SLogicNode* pNode, const SVgroupInfo* pVgroup, bool* pFound) {
|
||||||
|
if (QUERY_NODE_LOGIC_PLAN_SCAN == nodeType(pNode)) {
|
||||||
|
SScanLogicNode* pScan = (SScanLogicNode*)pNode;
|
||||||
|
pScan->pVgroupList = calloc(1, sizeof(SVgroupsInfo) + sizeof(SVgroupInfo));
|
||||||
|
CHECK_ALLOC(pScan->pVgroupList, TSDB_CODE_OUT_OF_MEMORY);
|
||||||
|
memcpy(pScan->pVgroupList->vgroups, pVgroup, sizeof(SVgroupInfo));
|
||||||
|
*pFound = true;
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
SNode* pChild = NULL;
|
||||||
|
FOREACH(pChild, pNode->pChildren) {
|
||||||
|
int32_t code = doSetScanVgroup(pCxt, (SLogicNode*)pChild, pVgroup, pFound);
|
||||||
|
if (TSDB_CODE_SUCCESS != code || *pFound) {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t setScanVgroup(SPhysiPlanContext* pCxt, SLogicNode* pNode, const SVgroupInfo* pVgroup) {
|
||||||
|
bool found = false;
|
||||||
|
return doSetScanVgroup(pCxt, pNode, pVgroup, &found);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t scaleOutForScan(SPhysiPlanContext* pCxt, SSubLogicPlan* pSubplan, int32_t level, SQueryLogicPlan* pLogicPlan, SNodeList* pGroup) {
|
||||||
|
if (pSubplan->pVgroupList) {
|
||||||
|
for (int32_t i = 0; i < pSubplan->pVgroupList->numOfVgroups; ++i) {
|
||||||
|
SSubLogicPlan* pNewSubplan = singleCloneSubLogicPlan(pCxt, pSubplan, level);
|
||||||
|
CHECK_ALLOC(pNewSubplan, TSDB_CODE_OUT_OF_MEMORY);
|
||||||
|
CHECK_CODE_EXT(setScanVgroup(pCxt, pNewSubplan->pNode, pSubplan->pVgroupList->vgroups + i));
|
||||||
|
// CHECK_CODE_EXT(pushSubplan(pCxt, pNewSubplan, level, pLogicPlan->pSubplans));
|
||||||
|
CHECK_CODE_EXT(nodesListAppend(pGroup, pNewSubplan));
|
||||||
|
}
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
} else {
|
||||||
|
return scaleOutForMerge(pCxt, pSubplan, level, pLogicPlan, pGroup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// static int32_t pushHierarchicalPlan(SNodeList* pParentsGroup, SNodeList* pCurrentGroup, int32_t level, SQueryLogicPlan* pLogicPlan) {
|
||||||
|
// FOREACH() {
|
||||||
|
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
static int32_t doScaleOut(SPhysiPlanContext* pCxt, SSubLogicPlan* pSubplan, int32_t level, SQueryLogicPlan* pLogicPlan, SHashObj* pHash, SNodeList* pParentsGroup) {
|
||||||
|
SNodeList* pCurrentGroup = nodesMakeList();
|
||||||
|
CHECK_ALLOC(pCurrentGroup, TSDB_CODE_OUT_OF_MEMORY);
|
||||||
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
switch (pSubplan->subplanType) {
|
||||||
|
case SUBPLAN_TYPE_MERGE:
|
||||||
|
code = scaleOutForMerge(pCxt, pSubplan, level, pLogicPlan, pCurrentGroup);
|
||||||
|
break;
|
||||||
|
case SUBPLAN_TYPE_SCAN:
|
||||||
|
code = scaleOutForScan(pCxt, pSubplan, level, pLogicPlan, pCurrentGroup);
|
||||||
|
break;
|
||||||
|
case SUBPLAN_TYPE_MODIFY:
|
||||||
|
code = scaleOutForModify(pCxt, pSubplan, level, pLogicPlan, pCurrentGroup);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
// pushHierarchicalPlan(pParentsGroup, pCurrentGroup, level, pLogicPlan);
|
||||||
|
CHECK_CODE(taosHashPut(pHash, &pCxt->groupId, sizeof(pCxt->groupId), &pSubplan->id.groupId, sizeof(pSubplan->id.groupId)), TSDB_CODE_OUT_OF_MEMORY);
|
||||||
|
++(pCxt->groupId);
|
||||||
SNode* pChild;
|
SNode* pChild;
|
||||||
FOREACH(pChild, pSubplan->pChildren) {
|
FOREACH(pChild, pSubplan->pChildren) {
|
||||||
CHECK_CODE_EXT(doScaleOut(pCxt, (SSubLogicPlan*)pChild, level + 1, pLogicPlan));
|
CHECK_CODE_EXT(doScaleOut(pCxt, (SSubLogicPlan*)pChild, level + 1, pLogicPlan, pHash, pCurrentGroup));
|
||||||
}
|
}
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
@ -622,10 +728,49 @@ static SQueryLogicPlan* makeQueryLogicPlan(SPhysiPlanContext* pCxt) {
|
||||||
return pLogicPlan;
|
return pLogicPlan;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t doMappingLogicPlan(SLogicNode* pNode, SHashObj* pHash) {
|
||||||
|
if (QUERY_NODE_LOGIC_PLAN_EXCHANGE == nodeType(pNode)) {
|
||||||
|
SExchangeLogicNode* pExchange = (SExchangeLogicNode*)pNode;
|
||||||
|
int32_t* pGroupId = taosHashGet(pHash, &pExchange->srcGroupId, sizeof(pExchange->srcGroupId));
|
||||||
|
if (NULL == pGroupId) {
|
||||||
|
return TSDB_CODE_FAILED;
|
||||||
|
}
|
||||||
|
pExchange->srcGroupId = *pGroupId;
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
SNode* pChild;
|
||||||
|
FOREACH(pChild, pNode->pChildren) {
|
||||||
|
doMappingLogicPlan((SLogicNode*)pChild, pHash);
|
||||||
|
}
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mappingLogicPlan(SQueryLogicPlan* pLogicPlan, SHashObj* pHash) {
|
||||||
|
SNode* pNode = NULL;
|
||||||
|
FOREACH(pNode, pLogicPlan->pSubplans) {
|
||||||
|
SNode* pSubplan = NULL;
|
||||||
|
FOREACH(pSubplan, ((SNodeListNode*)pNode)->pNodeList) {
|
||||||
|
int32_t code = doMappingLogicPlan(((SSubLogicPlan*)pSubplan)->pNode, pHash);
|
||||||
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t scaleOutLogicPlan(SPhysiPlanContext* pCxt, SSubLogicPlan* pRootSubLogicPlan, SQueryLogicPlan** pLogicPlan) {
|
static int32_t scaleOutLogicPlan(SPhysiPlanContext* pCxt, SSubLogicPlan* pRootSubLogicPlan, SQueryLogicPlan** pLogicPlan) {
|
||||||
*pLogicPlan = makeQueryLogicPlan(pCxt);
|
*pLogicPlan = makeQueryLogicPlan(pCxt);
|
||||||
CHECK_ALLOC(*pLogicPlan, TSDB_CODE_OUT_OF_MEMORY);
|
CHECK_ALLOC(*pLogicPlan, TSDB_CODE_OUT_OF_MEMORY);
|
||||||
return doScaleOut(pCxt, pRootSubLogicPlan, 0, *pLogicPlan);
|
SHashObj* pHash = taosHashInit(8, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_NO_LOCK);
|
||||||
|
CHECK_ALLOC(pHash, TSDB_CODE_OUT_OF_MEMORY);
|
||||||
|
int32_t code = doScaleOut(pCxt, pRootSubLogicPlan, 0, *pLogicPlan, pHash, NULL);
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = mappingLogicPlan(*pLogicPlan, pHash);
|
||||||
|
}
|
||||||
|
taosHashCleanup(pHash);
|
||||||
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct SBuildPhysiSubplanCxt {
|
typedef struct SBuildPhysiSubplanCxt {
|
||||||
|
@ -681,13 +826,12 @@ int32_t createPhysiPlan(SPlanContext* pCxt, SLogicNode* pLogicNode, SQueryPlan**
|
||||||
if (NULL == cxt.pLocationHelper) {
|
if (NULL == cxt.pLocationHelper) {
|
||||||
return TSDB_CODE_OUT_OF_MEMORY;
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
SQueryLogicPlan* pLogicPlan;
|
SQueryLogicPlan* pLogicPlan = NULL;
|
||||||
SSubLogicPlan* pSubLogicPlan;
|
SSubLogicPlan* pSubLogicPlan = NULL;
|
||||||
int32_t code = splitLogicPlan(&cxt, pLogicNode, &pSubLogicPlan);
|
int32_t code = splitLogicPlan(&cxt, pLogicNode, &pSubLogicPlan);
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = scaleOutLogicPlan(&cxt, pSubLogicPlan, &pLogicPlan);
|
code = scaleOutLogicPlan(&cxt, pSubLogicPlan, &pLogicPlan);
|
||||||
}
|
}
|
||||||
// todo maping
|
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = buildPhysiPlan(&cxt, pLogicPlan, pPlan);
|
code = buildPhysiPlan(&cxt, pLogicPlan, pPlan);
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ int32_t qCreateQueryPlan(SPlanContext* pCxt, SQueryPlan** pPlan, SArray* pExecNo
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
void qSetSubplanExecutionNode(SSubplan* subplan, uint64_t templateId, SDownstreamSource* pSource) {
|
void qSetSubplanExecutionNode(SSubplan* subplan, int32_t groupId, SDownstreamSourceNode* pSource) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,5 +62,5 @@ SQueryPlan* qStringToQueryPlan(const char* pStr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void qDestroyQueryPlan(SQueryPlan* pPlan) {
|
void qDestroyQueryPlan(SQueryPlan* pPlan) {
|
||||||
|
nodesDestroyNode(pPlan);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,165 @@
|
||||||
|
/*
|
||||||
|
* 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 "plannerInt.h"
|
||||||
|
|
||||||
|
#define SPLIT_FLAG_MASK(n) (1 << n)
|
||||||
|
|
||||||
|
#define SPLIT_FLAG_STS SPLIT_FLAG_MASK(0)
|
||||||
|
|
||||||
|
#define SPLIT_FLAG_SET_MASK(val, mask) (val) |= (mask)
|
||||||
|
#define SPLIT_FLAG_TEST_MASK(val, mask) (((val) & (mask)) != 0)
|
||||||
|
|
||||||
|
typedef struct SSplitContext {
|
||||||
|
int32_t errCode;
|
||||||
|
int32_t groupId;
|
||||||
|
bool match;
|
||||||
|
void* pInfo;
|
||||||
|
} SSplitContext;
|
||||||
|
|
||||||
|
typedef int32_t (*FMatch)(SSplitContext* pCxt, SSubLogicPlan* pSubplan);
|
||||||
|
typedef int32_t (*FSplit)(SSplitContext* pCxt);
|
||||||
|
|
||||||
|
typedef struct SSplitRule {
|
||||||
|
char* pName;
|
||||||
|
FMatch matchFunc;
|
||||||
|
FSplit splitFunc;
|
||||||
|
} SSplitRule;
|
||||||
|
|
||||||
|
typedef struct SStsInfo {
|
||||||
|
SScanLogicNode* pScan;
|
||||||
|
SSubLogicPlan* pSubplan;
|
||||||
|
} SStsInfo;
|
||||||
|
|
||||||
|
static SLogicNode* stsMatchByNode(SLogicNode* pNode) {
|
||||||
|
if (QUERY_NODE_LOGIC_PLAN_SCAN == nodeType(pNode) && TSDB_SUPER_TABLE == ((SScanLogicNode*)pNode)->pMeta->tableType) {
|
||||||
|
return pNode;
|
||||||
|
}
|
||||||
|
SNode* pChild;
|
||||||
|
FOREACH(pChild, pNode->pChildren) {
|
||||||
|
SLogicNode* pSplitNode = stsMatchByNode((SLogicNode*)pChild);
|
||||||
|
if (NULL != pSplitNode) {
|
||||||
|
return pSplitNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t stsMatch(SSplitContext* pCxt, SSubLogicPlan* pSubplan) {
|
||||||
|
if (SPLIT_FLAG_TEST_MASK(pSubplan->splitFlag, SPLIT_FLAG_STS)) {
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
SLogicNode* pSplitNode = stsMatchByNode(pSubplan->pNode);
|
||||||
|
if (NULL != pSplitNode) {
|
||||||
|
SStsInfo* pInfo = calloc(1, sizeof(SStsInfo));
|
||||||
|
CHECK_ALLOC(pInfo, TSDB_CODE_OUT_OF_MEMORY);
|
||||||
|
pInfo->pScan = (SScanLogicNode*)pSplitNode;
|
||||||
|
pInfo->pSubplan = pSubplan;
|
||||||
|
pCxt->pInfo = pInfo;
|
||||||
|
pCxt->match = true;
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
SNode* pChild;
|
||||||
|
FOREACH(pChild, pSubplan->pChildren) {
|
||||||
|
int32_t code = stsMatch(pCxt, (SSubLogicPlan*)pChild);
|
||||||
|
if (TSDB_CODE_SUCCESS != code || pCxt->match) {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SSubLogicPlan* stsCreateScanSubplan(SSplitContext* pCxt, SScanLogicNode* pScan) {
|
||||||
|
SSubLogicPlan* pSubplan = nodesMakeNode(QUERY_NODE_LOGIC_SUBPLAN);
|
||||||
|
if (NULL == pSubplan) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
pSubplan->id.groupId = pCxt->groupId;
|
||||||
|
pSubplan->subplanType = SUBPLAN_TYPE_SCAN;
|
||||||
|
pSubplan->pNode = (SLogicNode*)nodesCloneNode(pScan);
|
||||||
|
TSWAP(pSubplan->pVgroupList, ((SScanLogicNode*)pSubplan->pNode)->pVgroupList, SVgroupsInfo);
|
||||||
|
SPLIT_FLAG_SET_MASK(pSubplan->splitFlag, SPLIT_FLAG_STS);
|
||||||
|
return pSubplan;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t stsCreateExchangeNode(SSplitContext* pCxt, SSubLogicPlan* pSubplan, SScanLogicNode* pScan) {
|
||||||
|
SExchangeLogicNode* pExchange = nodesMakeNode(QUERY_NODE_LOGIC_PLAN_EXCHANGE);
|
||||||
|
if (NULL == pExchange) {
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
pExchange->srcGroupId = pCxt->groupId;
|
||||||
|
pExchange->node.pTargets = nodesCloneList(pScan->node.pTargets);
|
||||||
|
if (NULL == pExchange->node.pTargets) {
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NULL == pScan->node.pParent) {
|
||||||
|
pSubplan->pNode = (SLogicNode*)pExchange;
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
SNode* pNode;
|
||||||
|
FOREACH(pNode, pScan->node.pParent->pChildren) {
|
||||||
|
if (nodesEqualNode(pNode, pScan)) {
|
||||||
|
REPLACE_NODE(pExchange);
|
||||||
|
nodesDestroyNode(pNode);
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nodesDestroyNode(pExchange);
|
||||||
|
return TSDB_CODE_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t stsSplit(SSplitContext* pCxt) {
|
||||||
|
SStsInfo* pInfo = pCxt->pInfo;
|
||||||
|
if (NULL == pInfo->pSubplan->pChildren) {
|
||||||
|
pInfo->pSubplan->pChildren = nodesMakeList();
|
||||||
|
if (NULL == pInfo->pSubplan->pChildren) {
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int32_t code = nodesListStrictAppend(pInfo->pSubplan->pChildren, stsCreateScanSubplan(pCxt, pInfo->pScan));
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = stsCreateExchangeNode(pCxt, pInfo->pSubplan, pInfo->pScan);
|
||||||
|
}
|
||||||
|
++(pCxt->groupId);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const SSplitRule splitRuleSet[] = {
|
||||||
|
{ .pName = "SuperTableScan", .matchFunc = stsMatch, .splitFunc = stsSplit }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int32_t splitRuleNum = (sizeof(splitRuleSet) / sizeof(SSplitRule));
|
||||||
|
|
||||||
|
int32_t applySplitRule(SSubLogicPlan* pSubplan) {
|
||||||
|
SSplitContext cxt = { .errCode = TSDB_CODE_SUCCESS, .groupId = pSubplan->id.groupId + 1, .match = false, .pInfo = NULL };
|
||||||
|
bool split = false;
|
||||||
|
do {
|
||||||
|
split = false;
|
||||||
|
for (int32_t i = 0; i < splitRuleNum; ++i) {
|
||||||
|
cxt.match = false;
|
||||||
|
int32_t code = splitRuleSet[i].matchFunc(&cxt, pSubplan);
|
||||||
|
if (TSDB_CODE_SUCCESS == code && cxt.match) {
|
||||||
|
code = splitRuleSet[i].splitFunc(&cxt);
|
||||||
|
split = true;
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (split);
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
|
@ -137,6 +137,13 @@ TEST_F(PlannerTest, simple) {
|
||||||
ASSERT_TRUE(run());
|
ASSERT_TRUE(run());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(PlannerTest, stSimple) {
|
||||||
|
setDatabase("root", "test");
|
||||||
|
|
||||||
|
bind("SELECT * FROM st1");
|
||||||
|
ASSERT_TRUE(run());
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(PlannerTest, groupBy) {
|
TEST_F(PlannerTest, groupBy) {
|
||||||
setDatabase("root", "test");
|
setDatabase("root", "test");
|
||||||
|
|
||||||
|
|
|
@ -797,8 +797,8 @@ int32_t schProcessOnTaskSuccess(SSchJob *pJob, SSchTask *pTask) {
|
||||||
int32_t readyNum = atomic_add_fetch_32(&par->childReady, 1);
|
int32_t readyNum = atomic_add_fetch_32(&par->childReady, 1);
|
||||||
|
|
||||||
SCH_LOCK(SCH_WRITE, &par->lock);
|
SCH_LOCK(SCH_WRITE, &par->lock);
|
||||||
SDownstreamSource source = {.taskId = pTask->taskId, .schedId = schMgmt.sId, .addr = pTask->succeedAddr};
|
SDownstreamSourceNode source = {.type = QUERY_NODE_DOWNSTREAM_SOURCE, .taskId = pTask->taskId, .schedId = schMgmt.sId, .addr = pTask->succeedAddr};
|
||||||
qSetSubplanExecutionNode(par->plan, pTask->plan->id.templateId, &source);
|
qSetSubplanExecutionNode(par->plan, pTask->plan->id.groupId, &source);
|
||||||
SCH_UNLOCK(SCH_WRITE, &par->lock);
|
SCH_UNLOCK(SCH_WRITE, &par->lock);
|
||||||
|
|
||||||
if (SCH_TASK_READY_TO_LUNCH(readyNum, par)) {
|
if (SCH_TASK_READY_TO_LUNCH(readyNum, par)) {
|
||||||
|
|
|
@ -99,7 +99,7 @@ void schtBuildQueryDag(SQueryPlan *dag) {
|
||||||
SSubplan *mergePlan = (SSubplan *)calloc(1, sizeof(SSubplan));
|
SSubplan *mergePlan = (SSubplan *)calloc(1, sizeof(SSubplan));
|
||||||
|
|
||||||
scanPlan->id.queryId = qId;
|
scanPlan->id.queryId = qId;
|
||||||
scanPlan->id.templateId = 0x0000000000000002;
|
scanPlan->id.groupId = 0x0000000000000002;
|
||||||
scanPlan->id.subplanId = 0x0000000000000003;
|
scanPlan->id.subplanId = 0x0000000000000003;
|
||||||
scanPlan->subplanType = SUBPLAN_TYPE_SCAN;
|
scanPlan->subplanType = SUBPLAN_TYPE_SCAN;
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@ void schtBuildQueryDag(SQueryPlan *dag) {
|
||||||
scanPlan->msgType = TDMT_VND_QUERY;
|
scanPlan->msgType = TDMT_VND_QUERY;
|
||||||
|
|
||||||
mergePlan->id.queryId = qId;
|
mergePlan->id.queryId = qId;
|
||||||
mergePlan->id.templateId = schtMergeTemplateId;
|
mergePlan->id.groupId = schtMergeTemplateId;
|
||||||
mergePlan->id.subplanId = 0x5555;
|
mergePlan->id.subplanId = 0x5555;
|
||||||
mergePlan->subplanType = SUBPLAN_TYPE_MERGE;
|
mergePlan->subplanType = SUBPLAN_TYPE_MERGE;
|
||||||
mergePlan->level = 0;
|
mergePlan->level = 0;
|
||||||
|
@ -158,7 +158,7 @@ void schtBuildQueryFlowCtrlDag(SQueryPlan *dag) {
|
||||||
|
|
||||||
for (int32_t i = 0; i < scanPlanNum; ++i) {
|
for (int32_t i = 0; i < scanPlanNum; ++i) {
|
||||||
scanPlan[i].id.queryId = qId;
|
scanPlan[i].id.queryId = qId;
|
||||||
scanPlan[i].id.templateId = 0x0000000000000002;
|
scanPlan[i].id.groupId = 0x0000000000000002;
|
||||||
scanPlan[i].id.subplanId = 0x0000000000000003 + i;
|
scanPlan[i].id.subplanId = 0x0000000000000003 + i;
|
||||||
scanPlan[i].subplanType = SUBPLAN_TYPE_SCAN;
|
scanPlan[i].subplanType = SUBPLAN_TYPE_SCAN;
|
||||||
|
|
||||||
|
@ -183,7 +183,7 @@ void schtBuildQueryFlowCtrlDag(SQueryPlan *dag) {
|
||||||
}
|
}
|
||||||
|
|
||||||
mergePlan->id.queryId = qId;
|
mergePlan->id.queryId = qId;
|
||||||
mergePlan->id.templateId = schtMergeTemplateId;
|
mergePlan->id.groupId = schtMergeTemplateId;
|
||||||
mergePlan->id.subplanId = 0x5555;
|
mergePlan->id.subplanId = 0x5555;
|
||||||
mergePlan->subplanType = SUBPLAN_TYPE_MERGE;
|
mergePlan->subplanType = SUBPLAN_TYPE_MERGE;
|
||||||
mergePlan->level = 0;
|
mergePlan->level = 0;
|
||||||
|
@ -216,7 +216,7 @@ void schtBuildInsertDag(SQueryPlan *dag) {
|
||||||
SSubplan *insertPlan = (SSubplan *)calloc(2, sizeof(SSubplan));
|
SSubplan *insertPlan = (SSubplan *)calloc(2, sizeof(SSubplan));
|
||||||
|
|
||||||
insertPlan[0].id.queryId = qId;
|
insertPlan[0].id.queryId = qId;
|
||||||
insertPlan[0].id.templateId = 0x0000000000000003;
|
insertPlan[0].id.groupId = 0x0000000000000003;
|
||||||
insertPlan[0].id.subplanId = 0x0000000000000004;
|
insertPlan[0].id.subplanId = 0x0000000000000004;
|
||||||
insertPlan[0].subplanType = SUBPLAN_TYPE_MODIFY;
|
insertPlan[0].subplanType = SUBPLAN_TYPE_MODIFY;
|
||||||
insertPlan[0].level = 0;
|
insertPlan[0].level = 0;
|
||||||
|
@ -232,7 +232,7 @@ void schtBuildInsertDag(SQueryPlan *dag) {
|
||||||
insertPlan[0].msgType = TDMT_VND_SUBMIT;
|
insertPlan[0].msgType = TDMT_VND_SUBMIT;
|
||||||
|
|
||||||
insertPlan[1].id.queryId = qId;
|
insertPlan[1].id.queryId = qId;
|
||||||
insertPlan[1].id.templateId = 0x0000000000000003;
|
insertPlan[1].id.groupId = 0x0000000000000003;
|
||||||
insertPlan[1].id.subplanId = 0x0000000000000005;
|
insertPlan[1].id.subplanId = 0x0000000000000005;
|
||||||
insertPlan[1].subplanType = SUBPLAN_TYPE_MODIFY;
|
insertPlan[1].subplanType = SUBPLAN_TYPE_MODIFY;
|
||||||
insertPlan[1].level = 0;
|
insertPlan[1].level = 0;
|
||||||
|
@ -263,7 +263,7 @@ int32_t schtPlanToString(const SSubplan *subplan, char** str, int32_t* len) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void schtExecNode(SSubplan* subplan, uint64_t templateId, SQueryNodeAddr* ep) {
|
void schtExecNode(SSubplan* subplan, uint64_t groupId, SQueryNodeAddr* ep) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue