feat: sql command 'interp'
This commit is contained in:
parent
bd61367f0a
commit
bac6e27c20
|
@ -241,20 +241,22 @@
|
||||||
#define TK_LINEAR 223
|
#define TK_LINEAR 223
|
||||||
#define TK_NEXT 224
|
#define TK_NEXT 224
|
||||||
#define TK_HAVING 225
|
#define TK_HAVING 225
|
||||||
#define TK_ORDER 226
|
#define TK_RANGE 226
|
||||||
#define TK_SLIMIT 227
|
#define TK_EVERY 227
|
||||||
#define TK_SOFFSET 228
|
#define TK_ORDER 228
|
||||||
#define TK_LIMIT 229
|
#define TK_SLIMIT 229
|
||||||
#define TK_OFFSET 230
|
#define TK_SOFFSET 230
|
||||||
#define TK_ASC 231
|
#define TK_LIMIT 231
|
||||||
#define TK_NULLS 232
|
#define TK_OFFSET 232
|
||||||
#define TK_ID 233
|
#define TK_ASC 233
|
||||||
#define TK_NK_BITNOT 234
|
#define TK_NULLS 234
|
||||||
#define TK_INSERT 235
|
#define TK_ID 235
|
||||||
#define TK_VALUES 236
|
#define TK_NK_BITNOT 236
|
||||||
#define TK_IMPORT 237
|
#define TK_INSERT 237
|
||||||
#define TK_NK_SEMI 238
|
#define TK_VALUES 238
|
||||||
#define TK_FILE 239
|
#define TK_IMPORT 239
|
||||||
|
#define TK_NK_SEMI 240
|
||||||
|
#define TK_FILE 241
|
||||||
|
|
||||||
#define TK_NK_SPACE 300
|
#define TK_NK_SPACE 300
|
||||||
#define TK_NK_COMMENT 301
|
#define TK_NK_COMMENT 301
|
||||||
|
|
|
@ -189,6 +189,7 @@ bool fmIsForbidStreamFunc(int32_t funcId);
|
||||||
bool fmIsForbidWindowFunc(int32_t funcId);
|
bool fmIsForbidWindowFunc(int32_t funcId);
|
||||||
bool fmIsForbidGroupByFunc(int32_t funcId);
|
bool fmIsForbidGroupByFunc(int32_t funcId);
|
||||||
bool fmIsIntervalInterpoFunc(int32_t funcId);
|
bool fmIsIntervalInterpoFunc(int32_t funcId);
|
||||||
|
bool fmIsInterpFunc(int32_t funcId);
|
||||||
|
|
||||||
int32_t fmGetDistMethod(const SFunctionNode* pFunc, SFunctionNode** pPartialFunc, SFunctionNode** pMergeFunc);
|
int32_t fmGetDistMethod(const SFunctionNode* pFunc, SFunctionNode** pPartialFunc, SFunctionNode** pMergeFunc);
|
||||||
|
|
||||||
|
|
|
@ -205,6 +205,7 @@ typedef enum ENodeType {
|
||||||
QUERY_NODE_LOGIC_PLAN_SORT,
|
QUERY_NODE_LOGIC_PLAN_SORT,
|
||||||
QUERY_NODE_LOGIC_PLAN_PARTITION,
|
QUERY_NODE_LOGIC_PLAN_PARTITION,
|
||||||
QUERY_NODE_LOGIC_PLAN_INDEF_ROWS_FUNC,
|
QUERY_NODE_LOGIC_PLAN_INDEF_ROWS_FUNC,
|
||||||
|
QUERY_NODE_LOGIC_PLAN_INTERP_FUNC,
|
||||||
QUERY_NODE_LOGIC_SUBPLAN,
|
QUERY_NODE_LOGIC_SUBPLAN,
|
||||||
QUERY_NODE_LOGIC_PLAN,
|
QUERY_NODE_LOGIC_PLAN,
|
||||||
|
|
||||||
|
@ -236,6 +237,7 @@ typedef enum ENodeType {
|
||||||
QUERY_NODE_PHYSICAL_PLAN_STREAM_STATE,
|
QUERY_NODE_PHYSICAL_PLAN_STREAM_STATE,
|
||||||
QUERY_NODE_PHYSICAL_PLAN_PARTITION,
|
QUERY_NODE_PHYSICAL_PLAN_PARTITION,
|
||||||
QUERY_NODE_PHYSICAL_PLAN_INDEF_ROWS_FUNC,
|
QUERY_NODE_PHYSICAL_PLAN_INDEF_ROWS_FUNC,
|
||||||
|
QUERY_NODE_PHYSICAL_PLAN_INTERP_FUNC,
|
||||||
QUERY_NODE_PHYSICAL_PLAN_DISPATCH,
|
QUERY_NODE_PHYSICAL_PLAN_DISPATCH,
|
||||||
QUERY_NODE_PHYSICAL_PLAN_INSERT,
|
QUERY_NODE_PHYSICAL_PLAN_INSERT,
|
||||||
QUERY_NODE_PHYSICAL_PLAN_DELETE,
|
QUERY_NODE_PHYSICAL_PLAN_DELETE,
|
||||||
|
|
|
@ -98,9 +98,16 @@ typedef struct SProjectLogicNode {
|
||||||
|
|
||||||
typedef struct SIndefRowsFuncLogicNode {
|
typedef struct SIndefRowsFuncLogicNode {
|
||||||
SLogicNode node;
|
SLogicNode node;
|
||||||
SNodeList* pVectorFuncs;
|
SNodeList* pFuncs;
|
||||||
} SIndefRowsFuncLogicNode;
|
} SIndefRowsFuncLogicNode;
|
||||||
|
|
||||||
|
typedef struct SInterpFuncLogicNode {
|
||||||
|
SLogicNode node;
|
||||||
|
SNodeList* pFuncs;
|
||||||
|
STimeWindow timeRange;
|
||||||
|
int64_t interval;
|
||||||
|
} SInterpFuncLogicNode;
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
typedef struct SVnodeModifyLogicNode {
|
typedef struct SVnodeModifyLogicNode {
|
||||||
|
@ -293,9 +300,17 @@ typedef struct SProjectPhysiNode {
|
||||||
typedef struct SIndefRowsFuncPhysiNode {
|
typedef struct SIndefRowsFuncPhysiNode {
|
||||||
SPhysiNode node;
|
SPhysiNode node;
|
||||||
SNodeList* pExprs;
|
SNodeList* pExprs;
|
||||||
SNodeList* pVectorFuncs;
|
SNodeList* pFuncs;
|
||||||
} SIndefRowsFuncPhysiNode;
|
} SIndefRowsFuncPhysiNode;
|
||||||
|
|
||||||
|
typedef struct SInterpFuncPhysiNode {
|
||||||
|
SPhysiNode node;
|
||||||
|
SNodeList* pExprs;
|
||||||
|
SNodeList* pFuncs;
|
||||||
|
STimeWindow timeRange;
|
||||||
|
int64_t interval;
|
||||||
|
} SInterpFuncPhysiNode;
|
||||||
|
|
||||||
typedef struct SJoinPhysiNode {
|
typedef struct SJoinPhysiNode {
|
||||||
SPhysiNode node;
|
SPhysiNode node;
|
||||||
EJoinType joinType;
|
EJoinType joinType;
|
||||||
|
|
|
@ -240,6 +240,9 @@ typedef struct SSelectStmt {
|
||||||
SNode* pWindow;
|
SNode* pWindow;
|
||||||
SNodeList* pGroupByList; // SGroupingSetNode
|
SNodeList* pGroupByList; // SGroupingSetNode
|
||||||
SNode* pHaving;
|
SNode* pHaving;
|
||||||
|
SNode* pRange;
|
||||||
|
SNode* pEvery;
|
||||||
|
SNode* pFill;
|
||||||
SNodeList* pOrderByList; // SOrderByExprNode
|
SNodeList* pOrderByList; // SOrderByExprNode
|
||||||
SLimitNode* pLimit;
|
SLimitNode* pLimit;
|
||||||
SLimitNode* pSlimit;
|
SLimitNode* pSlimit;
|
||||||
|
@ -254,6 +257,7 @@ typedef struct SSelectStmt {
|
||||||
bool hasSelectValFunc;
|
bool hasSelectValFunc;
|
||||||
bool hasUniqueFunc;
|
bool hasUniqueFunc;
|
||||||
bool hasTailFunc;
|
bool hasTailFunc;
|
||||||
|
bool hasInterpFunc;
|
||||||
} SSelectStmt;
|
} SSelectStmt;
|
||||||
|
|
||||||
typedef enum ESetOperatorType { SET_OP_TYPE_UNION_ALL = 1, SET_OP_TYPE_UNION } ESetOperatorType;
|
typedef enum ESetOperatorType { SET_OP_TYPE_UNION_ALL = 1, SET_OP_TYPE_UNION } ESetOperatorType;
|
||||||
|
|
|
@ -631,8 +631,8 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
||||||
QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
|
QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
|
||||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||||
}
|
}
|
||||||
if (pIndefNode->pVectorFuncs) {
|
if (pIndefNode->pFuncs) {
|
||||||
EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pIndefNode->pVectorFuncs->length);
|
EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pIndefNode->pFuncs->length);
|
||||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||||
}
|
}
|
||||||
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pIndefNode->node.pOutputDataBlockDesc->totalRowSize);
|
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pIndefNode->node.pOutputDataBlockDesc->totalRowSize);
|
||||||
|
|
|
@ -3716,7 +3716,7 @@ SOperatorInfo* createIndefinitOutputOperatorInfo(SOperatorInfo* downstream, SPhy
|
||||||
SIndefRowsFuncPhysiNode* pPhyNode = (SIndefRowsFuncPhysiNode*)pNode;
|
SIndefRowsFuncPhysiNode* pPhyNode = (SIndefRowsFuncPhysiNode*)pNode;
|
||||||
|
|
||||||
int32_t numOfExpr = 0;
|
int32_t numOfExpr = 0;
|
||||||
SExprInfo* pExprInfo = createExprInfo(pPhyNode->pVectorFuncs, NULL, &numOfExpr);
|
SExprInfo* pExprInfo = createExprInfo(pPhyNode->pFuncs, NULL, &numOfExpr);
|
||||||
|
|
||||||
if (pPhyNode->pExprs != NULL) {
|
if (pPhyNode->pExprs != NULL) {
|
||||||
SExprSupp* pSup1 = &pInfo->scalarSup;
|
SExprSupp* pSup1 = &pInfo->scalarSup;
|
||||||
|
|
|
@ -1881,7 +1881,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||||
{
|
{
|
||||||
.name = "interp",
|
.name = "interp",
|
||||||
.type = FUNCTION_TYPE_INTERP,
|
.type = FUNCTION_TYPE_INTERP,
|
||||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_INTERVAL_INTERPO_FUNC,
|
.classification = FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_INTERVAL_INTERPO_FUNC,
|
||||||
.translateFunc = translateFirstLast,
|
.translateFunc = translateFirstLast,
|
||||||
.getEnvFunc = getSelectivityFuncEnv,
|
.getEnvFunc = getSelectivityFuncEnv,
|
||||||
.initFunc = functionSetup,
|
.initFunc = functionSetup,
|
||||||
|
|
|
@ -179,6 +179,13 @@ bool fmIsForbidWindowFunc(int32_t funcId) { return isSpecificClassifyFunc(funcId
|
||||||
|
|
||||||
bool fmIsForbidGroupByFunc(int32_t funcId) { return isSpecificClassifyFunc(funcId, FUNC_MGT_FORBID_GROUP_BY_FUNC); }
|
bool fmIsForbidGroupByFunc(int32_t funcId) { return isSpecificClassifyFunc(funcId, FUNC_MGT_FORBID_GROUP_BY_FUNC); }
|
||||||
|
|
||||||
|
bool fmIsInterpFunc(int32_t funcId) {
|
||||||
|
if (funcId < 0 || funcId >= funcMgtBuiltinsNum) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return FUNCTION_TYPE_INTERP == funcMgtBuiltins[funcId].type;
|
||||||
|
}
|
||||||
|
|
||||||
void fmFuncMgtDestroy() {
|
void fmFuncMgtDestroy() {
|
||||||
void* m = gFunMgtService.pFuncNameHashTable;
|
void* m = gFunMgtService.pFuncNameHashTable;
|
||||||
if (m != NULL && atomic_val_compare_exchange_ptr((void**)&gFunMgtService.pFuncNameHashTable, m, 0) == m) {
|
if (m != NULL && atomic_val_compare_exchange_ptr((void**)&gFunMgtService.pFuncNameHashTable, m, 0) == m) {
|
||||||
|
|
|
@ -455,7 +455,15 @@ static SNode* logicPartitionCopy(const SPartitionLogicNode* pSrc, SPartitionLogi
|
||||||
|
|
||||||
static SNode* logicIndefRowsFuncCopy(const SIndefRowsFuncLogicNode* pSrc, SIndefRowsFuncLogicNode* pDst) {
|
static SNode* logicIndefRowsFuncCopy(const SIndefRowsFuncLogicNode* pSrc, SIndefRowsFuncLogicNode* pDst) {
|
||||||
COPY_BASE_OBJECT_FIELD(node, logicNodeCopy);
|
COPY_BASE_OBJECT_FIELD(node, logicNodeCopy);
|
||||||
CLONE_NODE_LIST_FIELD(pVectorFuncs);
|
CLONE_NODE_LIST_FIELD(pFuncs);
|
||||||
|
return (SNode*)pDst;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SNode* logicInterpFuncCopy(const SInterpFuncLogicNode* pSrc, SInterpFuncLogicNode* pDst) {
|
||||||
|
COPY_BASE_OBJECT_FIELD(node, logicNodeCopy);
|
||||||
|
CLONE_NODE_LIST_FIELD(pFuncs);
|
||||||
|
COPY_OBJECT_FIELD(timeRange, sizeof(STimeWindow));
|
||||||
|
COPY_SCALAR_FIELD(interval);
|
||||||
return (SNode*)pDst;
|
return (SNode*)pDst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -670,6 +678,8 @@ SNode* nodesCloneNode(const SNode* pNode) {
|
||||||
return logicPartitionCopy((const SPartitionLogicNode*)pNode, (SPartitionLogicNode*)pDst);
|
return logicPartitionCopy((const SPartitionLogicNode*)pNode, (SPartitionLogicNode*)pDst);
|
||||||
case QUERY_NODE_LOGIC_PLAN_INDEF_ROWS_FUNC:
|
case QUERY_NODE_LOGIC_PLAN_INDEF_ROWS_FUNC:
|
||||||
return logicIndefRowsFuncCopy((const SIndefRowsFuncLogicNode*)pNode, (SIndefRowsFuncLogicNode*)pDst);
|
return logicIndefRowsFuncCopy((const SIndefRowsFuncLogicNode*)pNode, (SIndefRowsFuncLogicNode*)pDst);
|
||||||
|
case QUERY_NODE_LOGIC_PLAN_INTERP_FUNC:
|
||||||
|
return logicInterpFuncCopy((const SInterpFuncLogicNode*)pNode, (SInterpFuncLogicNode*)pDst);
|
||||||
case QUERY_NODE_LOGIC_SUBPLAN:
|
case QUERY_NODE_LOGIC_SUBPLAN:
|
||||||
return logicSubplanCopy((const SLogicSubplan*)pNode, (SLogicSubplan*)pDst);
|
return logicSubplanCopy((const SLogicSubplan*)pNode, (SLogicSubplan*)pDst);
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN:
|
case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN:
|
||||||
|
|
|
@ -202,6 +202,8 @@ const char* nodesNodeName(ENodeType type) {
|
||||||
return "LogicPartition";
|
return "LogicPartition";
|
||||||
case QUERY_NODE_LOGIC_PLAN_INDEF_ROWS_FUNC:
|
case QUERY_NODE_LOGIC_PLAN_INDEF_ROWS_FUNC:
|
||||||
return "LogicIndefRowsFunc";
|
return "LogicIndefRowsFunc";
|
||||||
|
case QUERY_NODE_LOGIC_PLAN_INTERP_FUNC:
|
||||||
|
return "LogicInterpFunc";
|
||||||
case QUERY_NODE_LOGIC_SUBPLAN:
|
case QUERY_NODE_LOGIC_SUBPLAN:
|
||||||
return "LogicSubplan";
|
return "LogicSubplan";
|
||||||
case QUERY_NODE_LOGIC_PLAN:
|
case QUERY_NODE_LOGIC_PLAN:
|
||||||
|
@ -258,6 +260,8 @@ const char* nodesNodeName(ENodeType type) {
|
||||||
return "PhysiPartition";
|
return "PhysiPartition";
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_INDEF_ROWS_FUNC:
|
case QUERY_NODE_PHYSICAL_PLAN_INDEF_ROWS_FUNC:
|
||||||
return "PhysiIndefRowsFunc";
|
return "PhysiIndefRowsFunc";
|
||||||
|
case QUERY_NODE_PHYSICAL_PLAN_INTERP_FUNC:
|
||||||
|
return "PhysiInterpFunc";
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_DISPATCH:
|
case QUERY_NODE_PHYSICAL_PLAN_DISPATCH:
|
||||||
return "PhysiDispatch";
|
return "PhysiDispatch";
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_INSERT:
|
case QUERY_NODE_PHYSICAL_PLAN_INSERT:
|
||||||
|
@ -935,14 +939,14 @@ static int32_t jsonToLogicPartitionNode(const SJson* pJson, void* pObj) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char* jkIndefRowsFuncLogicPlanVectorFuncs = "VectorFuncs";
|
static const char* jkIndefRowsFuncLogicPlanFuncs = "Funcs";
|
||||||
|
|
||||||
static int32_t logicIndefRowsFuncNodeToJson(const void* pObj, SJson* pJson) {
|
static int32_t logicIndefRowsFuncNodeToJson(const void* pObj, SJson* pJson) {
|
||||||
const SIndefRowsFuncLogicNode* pNode = (const SIndefRowsFuncLogicNode*)pObj;
|
const SIndefRowsFuncLogicNode* pNode = (const SIndefRowsFuncLogicNode*)pObj;
|
||||||
|
|
||||||
int32_t code = logicPlanNodeToJson(pObj, pJson);
|
int32_t code = logicPlanNodeToJson(pObj, pJson);
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = nodeListToJson(pJson, jkIndefRowsFuncLogicPlanVectorFuncs, pNode->pVectorFuncs);
|
code = nodeListToJson(pJson, jkIndefRowsFuncLogicPlanFuncs, pNode->pFuncs);
|
||||||
}
|
}
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
|
@ -953,7 +957,52 @@ static int32_t jsonToLogicIndefRowsFuncNode(const SJson* pJson, void* pObj) {
|
||||||
|
|
||||||
int32_t code = jsonToLogicPlanNode(pJson, pObj);
|
int32_t code = jsonToLogicPlanNode(pJson, pObj);
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = jsonToNodeList(pJson, jkIndefRowsFuncLogicPlanVectorFuncs, &pNode->pVectorFuncs);
|
code = jsonToNodeList(pJson, jkIndefRowsFuncLogicPlanFuncs, &pNode->pFuncs);
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* jkInterpFuncLogicPlanFuncs = "Funcs";
|
||||||
|
static const char* jkInterpFuncLogicPlanStartTime = "StartTime";
|
||||||
|
static const char* jkInterpFuncLogicPlanEndTime = "EndTime";
|
||||||
|
static const char* jkInterpFuncLogicPlanInterval = "Interval";
|
||||||
|
|
||||||
|
static int32_t logicInterpFuncNodeToJson(const void* pObj, SJson* pJson) {
|
||||||
|
const SInterpFuncLogicNode* pNode = (const SInterpFuncLogicNode*)pObj;
|
||||||
|
|
||||||
|
int32_t code = logicPlanNodeToJson(pObj, pJson);
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = nodeListToJson(pJson, jkInterpFuncLogicPlanFuncs, pNode->pFuncs);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonAddIntegerToObject(pJson, jkInterpFuncLogicPlanStartTime, pNode->timeRange.skey);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonAddIntegerToObject(pJson, jkInterpFuncLogicPlanEndTime, pNode->timeRange.ekey);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonAddIntegerToObject(pJson, jkInterpFuncLogicPlanInterval, pNode->interval);
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t jsonToLogicInterpFuncNode(const SJson* pJson, void* pObj) {
|
||||||
|
SInterpFuncLogicNode* pNode = (SInterpFuncLogicNode*)pObj;
|
||||||
|
|
||||||
|
int32_t code = jsonToLogicPlanNode(pJson, pObj);
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = jsonToNodeList(pJson, jkInterpFuncLogicPlanFuncs, &pNode->pFuncs);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonGetBigIntValue(pJson, jkInterpFuncLogicPlanStartTime, &pNode->timeRange.skey);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonGetBigIntValue(pJson, jkInterpFuncLogicPlanEndTime, &pNode->timeRange.ekey);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonGetBigIntValue(pJson, jkInterpFuncLogicPlanInterval, &pNode->interval);
|
||||||
}
|
}
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
|
@ -2049,7 +2098,7 @@ static int32_t jsonToPhysiPartitionNode(const SJson* pJson, void* pObj) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char* jkIndefRowsFuncPhysiPlanExprs = "Exprs";
|
static const char* jkIndefRowsFuncPhysiPlanExprs = "Exprs";
|
||||||
static const char* jkIndefRowsFuncPhysiPlanVectorFuncs = "VectorFuncs";
|
static const char* jkIndefRowsFuncPhysiPlanFuncs = "Funcs";
|
||||||
|
|
||||||
static int32_t physiIndefRowsFuncNodeToJson(const void* pObj, SJson* pJson) {
|
static int32_t physiIndefRowsFuncNodeToJson(const void* pObj, SJson* pJson) {
|
||||||
const SIndefRowsFuncPhysiNode* pNode = (const SIndefRowsFuncPhysiNode*)pObj;
|
const SIndefRowsFuncPhysiNode* pNode = (const SIndefRowsFuncPhysiNode*)pObj;
|
||||||
|
@ -2059,7 +2108,7 @@ static int32_t physiIndefRowsFuncNodeToJson(const void* pObj, SJson* pJson) {
|
||||||
code = nodeListToJson(pJson, jkIndefRowsFuncPhysiPlanExprs, pNode->pExprs);
|
code = nodeListToJson(pJson, jkIndefRowsFuncPhysiPlanExprs, pNode->pExprs);
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = nodeListToJson(pJson, jkIndefRowsFuncPhysiPlanVectorFuncs, pNode->pVectorFuncs);
|
code = nodeListToJson(pJson, jkIndefRowsFuncPhysiPlanFuncs, pNode->pFuncs);
|
||||||
}
|
}
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
|
@ -2073,7 +2122,59 @@ static int32_t jsonToPhysiIndefRowsFuncNode(const SJson* pJson, void* pObj) {
|
||||||
code = jsonToNodeList(pJson, jkIndefRowsFuncPhysiPlanExprs, &pNode->pExprs);
|
code = jsonToNodeList(pJson, jkIndefRowsFuncPhysiPlanExprs, &pNode->pExprs);
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = jsonToNodeList(pJson, jkIndefRowsFuncPhysiPlanVectorFuncs, &pNode->pVectorFuncs);
|
code = jsonToNodeList(pJson, jkIndefRowsFuncPhysiPlanFuncs, &pNode->pFuncs);
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* jkInterpFuncPhysiPlanExprs = "Exprs";
|
||||||
|
static const char* jkInterpFuncPhysiPlanFuncs = "Funcs";
|
||||||
|
static const char* jkInterpFuncPhysiPlanStartTime = "StartTime";
|
||||||
|
static const char* jkInterpFuncPhysiPlanEndTime = "EndTime";
|
||||||
|
static const char* jkInterpFuncPhysiPlanInterval = "Interval";
|
||||||
|
|
||||||
|
static int32_t physiInterpFuncNodeToJson(const void* pObj, SJson* pJson) {
|
||||||
|
const SInterpFuncPhysiNode* pNode = (const SInterpFuncPhysiNode*)pObj;
|
||||||
|
|
||||||
|
int32_t code = physicPlanNodeToJson(pObj, pJson);
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = nodeListToJson(pJson, jkInterpFuncPhysiPlanExprs, pNode->pExprs);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = nodeListToJson(pJson, jkInterpFuncPhysiPlanFuncs, pNode->pFuncs);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonAddIntegerToObject(pJson, jkInterpFuncPhysiPlanStartTime, pNode->timeRange.skey);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonAddIntegerToObject(pJson, jkInterpFuncPhysiPlanEndTime, pNode->timeRange.ekey);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonAddIntegerToObject(pJson, jkInterpFuncPhysiPlanInterval, pNode->interval);
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t jsonToPhysiInterpFuncNode(const SJson* pJson, void* pObj) {
|
||||||
|
SInterpFuncPhysiNode* pNode = (SInterpFuncPhysiNode*)pObj;
|
||||||
|
|
||||||
|
int32_t code = jsonToPhysicPlanNode(pJson, pObj);
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = jsonToNodeList(pJson, jkInterpFuncPhysiPlanExprs, &pNode->pExprs);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = jsonToNodeList(pJson, jkInterpFuncPhysiPlanFuncs, &pNode->pFuncs);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonGetBigIntValue(pJson, jkInterpFuncPhysiPlanStartTime, &pNode->timeRange.skey);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonGetBigIntValue(pJson, jkInterpFuncPhysiPlanEndTime, &pNode->timeRange.ekey);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonGetBigIntValue(pJson, jkInterpFuncPhysiPlanInterval, &pNode->interval);
|
||||||
}
|
}
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
|
@ -3975,6 +4076,8 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
|
||||||
return logicPartitionNodeToJson(pObj, pJson);
|
return logicPartitionNodeToJson(pObj, pJson);
|
||||||
case QUERY_NODE_LOGIC_PLAN_INDEF_ROWS_FUNC:
|
case QUERY_NODE_LOGIC_PLAN_INDEF_ROWS_FUNC:
|
||||||
return logicIndefRowsFuncNodeToJson(pObj, pJson);
|
return logicIndefRowsFuncNodeToJson(pObj, pJson);
|
||||||
|
case QUERY_NODE_LOGIC_PLAN_INTERP_FUNC:
|
||||||
|
return logicInterpFuncNodeToJson(pObj, pJson);
|
||||||
case QUERY_NODE_LOGIC_SUBPLAN:
|
case QUERY_NODE_LOGIC_SUBPLAN:
|
||||||
return logicSubplanToJson(pObj, pJson);
|
return logicSubplanToJson(pObj, pJson);
|
||||||
case QUERY_NODE_LOGIC_PLAN:
|
case QUERY_NODE_LOGIC_PLAN:
|
||||||
|
@ -4020,6 +4123,8 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
|
||||||
return physiPartitionNodeToJson(pObj, pJson);
|
return physiPartitionNodeToJson(pObj, pJson);
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_INDEF_ROWS_FUNC:
|
case QUERY_NODE_PHYSICAL_PLAN_INDEF_ROWS_FUNC:
|
||||||
return physiIndefRowsFuncNodeToJson(pObj, pJson);
|
return physiIndefRowsFuncNodeToJson(pObj, pJson);
|
||||||
|
case QUERY_NODE_PHYSICAL_PLAN_INTERP_FUNC:
|
||||||
|
return physiInterpFuncNodeToJson(pObj, pJson);
|
||||||
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:
|
||||||
|
@ -4111,6 +4216,8 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) {
|
||||||
return jsonToLogicPartitionNode(pJson, pObj);
|
return jsonToLogicPartitionNode(pJson, pObj);
|
||||||
case QUERY_NODE_LOGIC_PLAN_INDEF_ROWS_FUNC:
|
case QUERY_NODE_LOGIC_PLAN_INDEF_ROWS_FUNC:
|
||||||
return jsonToLogicIndefRowsFuncNode(pJson, pObj);
|
return jsonToLogicIndefRowsFuncNode(pJson, pObj);
|
||||||
|
case QUERY_NODE_LOGIC_PLAN_INTERP_FUNC:
|
||||||
|
return jsonToLogicInterpFuncNode(pJson, pObj);
|
||||||
case QUERY_NODE_LOGIC_SUBPLAN:
|
case QUERY_NODE_LOGIC_SUBPLAN:
|
||||||
return jsonToLogicSubplan(pJson, pObj);
|
return jsonToLogicSubplan(pJson, pObj);
|
||||||
case QUERY_NODE_LOGIC_PLAN:
|
case QUERY_NODE_LOGIC_PLAN:
|
||||||
|
@ -4156,6 +4263,8 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) {
|
||||||
return jsonToPhysiPartitionNode(pJson, pObj);
|
return jsonToPhysiPartitionNode(pJson, pObj);
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_INDEF_ROWS_FUNC:
|
case QUERY_NODE_PHYSICAL_PLAN_INDEF_ROWS_FUNC:
|
||||||
return jsonToPhysiIndefRowsFuncNode(pJson, pObj);
|
return jsonToPhysiIndefRowsFuncNode(pJson, pObj);
|
||||||
|
case QUERY_NODE_PHYSICAL_PLAN_INTERP_FUNC:
|
||||||
|
return jsonToPhysiInterpFuncNode(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_PLAN_DELETE:
|
case QUERY_NODE_PHYSICAL_PLAN_DELETE:
|
||||||
|
|
|
@ -250,6 +250,8 @@ SNode* nodesMakeNode(ENodeType type) {
|
||||||
return makeNode(type, sizeof(SPartitionLogicNode));
|
return makeNode(type, sizeof(SPartitionLogicNode));
|
||||||
case QUERY_NODE_LOGIC_PLAN_INDEF_ROWS_FUNC:
|
case QUERY_NODE_LOGIC_PLAN_INDEF_ROWS_FUNC:
|
||||||
return makeNode(type, sizeof(SIndefRowsFuncLogicNode));
|
return makeNode(type, sizeof(SIndefRowsFuncLogicNode));
|
||||||
|
case QUERY_NODE_LOGIC_PLAN_INTERP_FUNC:
|
||||||
|
return makeNode(type, sizeof(SInterpFuncLogicNode));
|
||||||
case QUERY_NODE_LOGIC_SUBPLAN:
|
case QUERY_NODE_LOGIC_SUBPLAN:
|
||||||
return makeNode(type, sizeof(SLogicSubplan));
|
return makeNode(type, sizeof(SLogicSubplan));
|
||||||
case QUERY_NODE_LOGIC_PLAN:
|
case QUERY_NODE_LOGIC_PLAN:
|
||||||
|
@ -308,6 +310,8 @@ SNode* nodesMakeNode(ENodeType type) {
|
||||||
return makeNode(type, sizeof(SPartitionPhysiNode));
|
return makeNode(type, sizeof(SPartitionPhysiNode));
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_INDEF_ROWS_FUNC:
|
case QUERY_NODE_PHYSICAL_PLAN_INDEF_ROWS_FUNC:
|
||||||
return makeNode(type, sizeof(SIndefRowsFuncPhysiNode));
|
return makeNode(type, sizeof(SIndefRowsFuncPhysiNode));
|
||||||
|
case QUERY_NODE_PHYSICAL_PLAN_INTERP_FUNC:
|
||||||
|
return makeNode(type, sizeof(SInterpFuncLogicNode));
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_DISPATCH:
|
case QUERY_NODE_PHYSICAL_PLAN_DISPATCH:
|
||||||
return makeNode(type, sizeof(SDataDispatcherNode));
|
return makeNode(type, sizeof(SDataDispatcherNode));
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_INSERT:
|
case QUERY_NODE_PHYSICAL_PLAN_INSERT:
|
||||||
|
@ -744,7 +748,13 @@ void nodesDestroyNode(SNode* pNode) {
|
||||||
case QUERY_NODE_LOGIC_PLAN_INDEF_ROWS_FUNC: {
|
case QUERY_NODE_LOGIC_PLAN_INDEF_ROWS_FUNC: {
|
||||||
SIndefRowsFuncLogicNode* pLogicNode = (SIndefRowsFuncLogicNode*)pNode;
|
SIndefRowsFuncLogicNode* pLogicNode = (SIndefRowsFuncLogicNode*)pNode;
|
||||||
destroyLogicNode((SLogicNode*)pLogicNode);
|
destroyLogicNode((SLogicNode*)pLogicNode);
|
||||||
nodesDestroyList(pLogicNode->pVectorFuncs);
|
nodesDestroyList(pLogicNode->pFuncs);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case QUERY_NODE_LOGIC_PLAN_INTERP_FUNC: {
|
||||||
|
SInterpFuncLogicNode* pLogicNode = (SInterpFuncLogicNode*)pNode;
|
||||||
|
destroyLogicNode((SLogicNode*)pLogicNode);
|
||||||
|
nodesDestroyList(pLogicNode->pFuncs);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case QUERY_NODE_LOGIC_SUBPLAN: {
|
case QUERY_NODE_LOGIC_SUBPLAN: {
|
||||||
|
@ -847,7 +857,14 @@ void nodesDestroyNode(SNode* pNode) {
|
||||||
SIndefRowsFuncPhysiNode* pPhyNode = (SIndefRowsFuncPhysiNode*)pNode;
|
SIndefRowsFuncPhysiNode* pPhyNode = (SIndefRowsFuncPhysiNode*)pNode;
|
||||||
destroyPhysiNode((SPhysiNode*)pPhyNode);
|
destroyPhysiNode((SPhysiNode*)pPhyNode);
|
||||||
nodesDestroyList(pPhyNode->pExprs);
|
nodesDestroyList(pPhyNode->pExprs);
|
||||||
nodesDestroyList(pPhyNode->pVectorFuncs);
|
nodesDestroyList(pPhyNode->pFuncs);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case QUERY_NODE_PHYSICAL_PLAN_INTERP_FUNC: {
|
||||||
|
SInterpFuncPhysiNode* pPhyNode = (SInterpFuncPhysiNode*)pNode;
|
||||||
|
destroyPhysiNode((SPhysiNode*)pPhyNode);
|
||||||
|
nodesDestroyList(pPhyNode->pExprs);
|
||||||
|
nodesDestroyList(pPhyNode->pFuncs);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_DISPATCH:
|
case QUERY_NODE_PHYSICAL_PLAN_DISPATCH:
|
||||||
|
|
|
@ -109,6 +109,7 @@ SNode* createIntervalWindowNode(SAstCreateContext* pCxt, SNode* pInterval, SNode
|
||||||
SNode* pFill);
|
SNode* pFill);
|
||||||
SNode* createFillNode(SAstCreateContext* pCxt, EFillMode mode, SNode* pValues);
|
SNode* createFillNode(SAstCreateContext* pCxt, EFillMode mode, SNode* pValues);
|
||||||
SNode* createGroupingSetNode(SAstCreateContext* pCxt, SNode* pNode);
|
SNode* createGroupingSetNode(SAstCreateContext* pCxt, SNode* pNode);
|
||||||
|
SNode* createInterpTimeRange(SAstCreateContext* pCxt, SNode* pStart, SNode* pEnd);
|
||||||
|
|
||||||
SNode* addWhereClause(SAstCreateContext* pCxt, SNode* pStmt, SNode* pWhere);
|
SNode* addWhereClause(SAstCreateContext* pCxt, SNode* pStmt, SNode* pWhere);
|
||||||
SNode* addPartitionByClause(SAstCreateContext* pCxt, SNode* pStmt, SNodeList* pPartitionByList);
|
SNode* addPartitionByClause(SAstCreateContext* pCxt, SNode* pStmt, SNodeList* pPartitionByList);
|
||||||
|
@ -118,6 +119,9 @@ SNode* addHavingClause(SAstCreateContext* pCxt, SNode* pStmt, SNode* pHaving);
|
||||||
SNode* addOrderByClause(SAstCreateContext* pCxt, SNode* pStmt, SNodeList* pOrderByList);
|
SNode* addOrderByClause(SAstCreateContext* pCxt, SNode* pStmt, SNodeList* pOrderByList);
|
||||||
SNode* addSlimitClause(SAstCreateContext* pCxt, SNode* pStmt, SNode* pSlimit);
|
SNode* addSlimitClause(SAstCreateContext* pCxt, SNode* pStmt, SNode* pSlimit);
|
||||||
SNode* addLimitClause(SAstCreateContext* pCxt, SNode* pStmt, SNode* pLimit);
|
SNode* addLimitClause(SAstCreateContext* pCxt, SNode* pStmt, SNode* pLimit);
|
||||||
|
SNode* addRangeClause(SAstCreateContext* pCxt, SNode* pStmt, SNode* pRange);
|
||||||
|
SNode* addEveryClause(SAstCreateContext* pCxt, SNode* pStmt, SNode* pEvery);
|
||||||
|
SNode* addFillClause(SAstCreateContext* pCxt, SNode* pStmt, SNode* pFill);
|
||||||
SNode* createSelectStmt(SAstCreateContext* pCxt, bool isDistinct, SNodeList* pProjectionList, SNode* pTable);
|
SNode* createSelectStmt(SAstCreateContext* pCxt, bool isDistinct, SNodeList* pProjectionList, SNode* pTable);
|
||||||
SNode* createSetOperator(SAstCreateContext* pCxt, ESetOperatorType type, SNode* pLeft, SNode* pRight);
|
SNode* createSetOperator(SAstCreateContext* pCxt, ESetOperatorType type, SNode* pLeft, SNode* pRight);
|
||||||
|
|
||||||
|
|
|
@ -791,7 +791,7 @@ join_type(A) ::= INNER.
|
||||||
/************************************************ query_specification *************************************************/
|
/************************************************ query_specification *************************************************/
|
||||||
query_specification(A) ::=
|
query_specification(A) ::=
|
||||||
SELECT set_quantifier_opt(B) select_list(C) from_clause(D) where_clause_opt(E)
|
SELECT set_quantifier_opt(B) select_list(C) from_clause(D) where_clause_opt(E)
|
||||||
partition_by_clause_opt(F) twindow_clause_opt(G)
|
partition_by_clause_opt(F) range_opt(J) every_opt(K) fill_opt(L) twindow_clause_opt(G)
|
||||||
group_by_clause_opt(H) having_clause_opt(I). {
|
group_by_clause_opt(H) having_clause_opt(I). {
|
||||||
A = createSelectStmt(pCxt, B, C, D);
|
A = createSelectStmt(pCxt, B, C, D);
|
||||||
A = addWhereClause(pCxt, A, E);
|
A = addWhereClause(pCxt, A, E);
|
||||||
|
@ -799,6 +799,9 @@ query_specification(A) ::=
|
||||||
A = addWindowClauseClause(pCxt, A, G);
|
A = addWindowClauseClause(pCxt, A, G);
|
||||||
A = addGroupByClause(pCxt, A, H);
|
A = addGroupByClause(pCxt, A, H);
|
||||||
A = addHavingClause(pCxt, A, I);
|
A = addHavingClause(pCxt, A, I);
|
||||||
|
A = addRangeClause(pCxt, A, J);
|
||||||
|
A = addEveryClause(pCxt, A, K);
|
||||||
|
A = addFillClause(pCxt, A, L);
|
||||||
}
|
}
|
||||||
|
|
||||||
%type set_quantifier_opt { bool }
|
%type set_quantifier_opt { bool }
|
||||||
|
@ -868,6 +871,12 @@ group_by_list(A) ::= group_by_list(B) NK_COMMA expression(C).
|
||||||
having_clause_opt(A) ::= . { A = NULL; }
|
having_clause_opt(A) ::= . { A = NULL; }
|
||||||
having_clause_opt(A) ::= HAVING search_condition(B). { A = B; }
|
having_clause_opt(A) ::= HAVING search_condition(B). { A = B; }
|
||||||
|
|
||||||
|
range_opt(A) ::= . { A = NULL; }
|
||||||
|
range_opt(A) ::= RANGE NK_LP expression(B) NK_COMMA expression(C) NK_RP. { A = createInterpTimeRange(pCxt, releaseRawExprNode(pCxt, B), releaseRawExprNode(pCxt, C)); }
|
||||||
|
|
||||||
|
every_opt(A) ::= . { A = NULL; }
|
||||||
|
every_opt(A) ::= EVERY NK_LP duration_literal(B) NK_RP. { A = releaseRawExprNode(pCxt, B); }
|
||||||
|
|
||||||
/************************************************ query_expression ****************************************************/
|
/************************************************ query_expression ****************************************************/
|
||||||
query_expression(A) ::=
|
query_expression(A) ::=
|
||||||
query_expression_body(B)
|
query_expression_body(B)
|
||||||
|
|
|
@ -599,6 +599,11 @@ SNode* createGroupingSetNode(SAstCreateContext* pCxt, SNode* pNode) {
|
||||||
return (SNode*)groupingSet;
|
return (SNode*)groupingSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SNode* createInterpTimeRange(SAstCreateContext* pCxt, SNode* pStart, SNode* pEnd) {
|
||||||
|
CHECK_PARSER_STATUS(pCxt);
|
||||||
|
return createBetweenAnd(pCxt, createPrimaryKeyCol(pCxt), pStart, pEnd);
|
||||||
|
}
|
||||||
|
|
||||||
SNode* setProjectionAlias(SAstCreateContext* pCxt, SNode* pNode, const SToken* pAlias) {
|
SNode* setProjectionAlias(SAstCreateContext* pCxt, SNode* pNode, const SToken* pAlias) {
|
||||||
CHECK_PARSER_STATUS(pCxt);
|
CHECK_PARSER_STATUS(pCxt);
|
||||||
int32_t len = TMIN(sizeof(((SExprNode*)pNode)->aliasName) - 1, pAlias->n);
|
int32_t len = TMIN(sizeof(((SExprNode*)pNode)->aliasName) - 1, pAlias->n);
|
||||||
|
@ -671,6 +676,32 @@ SNode* addLimitClause(SAstCreateContext* pCxt, SNode* pStmt, SNode* pLimit) {
|
||||||
CHECK_PARSER_STATUS(pCxt);
|
CHECK_PARSER_STATUS(pCxt);
|
||||||
if (QUERY_NODE_SELECT_STMT == nodeType(pStmt)) {
|
if (QUERY_NODE_SELECT_STMT == nodeType(pStmt)) {
|
||||||
((SSelectStmt*)pStmt)->pLimit = (SLimitNode*)pLimit;
|
((SSelectStmt*)pStmt)->pLimit = (SLimitNode*)pLimit;
|
||||||
|
} else {
|
||||||
|
((SSetOperator*)pStmt)->pLimit = pLimit;
|
||||||
|
}
|
||||||
|
return pStmt;
|
||||||
|
}
|
||||||
|
|
||||||
|
SNode* addRangeClause(SAstCreateContext* pCxt, SNode* pStmt, SNode* pRange) {
|
||||||
|
CHECK_PARSER_STATUS(pCxt);
|
||||||
|
if (QUERY_NODE_SELECT_STMT == nodeType(pStmt)) {
|
||||||
|
((SSelectStmt*)pStmt)->pRange = pRange;
|
||||||
|
}
|
||||||
|
return pStmt;
|
||||||
|
}
|
||||||
|
|
||||||
|
SNode* addEveryClause(SAstCreateContext* pCxt, SNode* pStmt, SNode* pEvery) {
|
||||||
|
CHECK_PARSER_STATUS(pCxt);
|
||||||
|
if (QUERY_NODE_SELECT_STMT == nodeType(pStmt)) {
|
||||||
|
((SSelectStmt*)pStmt)->pEvery = pEvery;
|
||||||
|
}
|
||||||
|
return pStmt;
|
||||||
|
}
|
||||||
|
|
||||||
|
SNode* addFillClause(SAstCreateContext* pCxt, SNode* pStmt, SNode* pFill) {
|
||||||
|
CHECK_PARSER_STATUS(pCxt);
|
||||||
|
if (QUERY_NODE_SELECT_STMT == nodeType(pStmt)) {
|
||||||
|
((SSelectStmt*)pStmt)->pFill = pFill;
|
||||||
}
|
}
|
||||||
return pStmt;
|
return pStmt;
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,6 +81,7 @@ static SKeyword keywordTable[] = {
|
||||||
{"DURATION", TK_DURATION},
|
{"DURATION", TK_DURATION},
|
||||||
{"EXISTS", TK_EXISTS},
|
{"EXISTS", TK_EXISTS},
|
||||||
{"EXPLAIN", TK_EXPLAIN},
|
{"EXPLAIN", TK_EXPLAIN},
|
||||||
|
{"EVERY", TK_EVERY},
|
||||||
{"FILL", TK_FILL},
|
{"FILL", TK_FILL},
|
||||||
{"FIRST", TK_FIRST},
|
{"FIRST", TK_FIRST},
|
||||||
{"FLOAT", TK_FLOAT},
|
{"FLOAT", TK_FLOAT},
|
||||||
|
@ -152,6 +153,7 @@ static SKeyword keywordTable[] = {
|
||||||
{"QTIME", TK_QTIME},
|
{"QTIME", TK_QTIME},
|
||||||
{"QUERIES", TK_QUERIES},
|
{"QUERIES", TK_QUERIES},
|
||||||
{"QUERY", TK_QUERY},
|
{"QUERY", TK_QUERY},
|
||||||
|
{"RANGE", TK_RANGE},
|
||||||
{"RATIO", TK_RATIO},
|
{"RATIO", TK_RATIO},
|
||||||
{"READ", TK_READ},
|
{"READ", TK_READ},
|
||||||
{"REDISTRIBUTE", TK_REDISTRIBUTE},
|
{"REDISTRIBUTE", TK_REDISTRIBUTE},
|
||||||
|
@ -258,7 +260,6 @@ static SKeyword keywordTable[] = {
|
||||||
// {"LP", TK_LP},
|
// {"LP", TK_LP},
|
||||||
// {"RP", TK_RP},
|
// {"RP", TK_RP},
|
||||||
// {"COMMA", TK_COMMA},
|
// {"COMMA", TK_COMMA},
|
||||||
// {"EVERY", TK_EVERY},
|
|
||||||
// {"VARIABLE", TK_VARIABLE},
|
// {"VARIABLE", TK_VARIABLE},
|
||||||
// {"UPDATE", TK_UPDATE},
|
// {"UPDATE", TK_UPDATE},
|
||||||
// {"CHANGE", TK_CHANGE},
|
// {"CHANGE", TK_CHANGE},
|
||||||
|
|
|
@ -1157,6 +1157,7 @@ static void setFuncClassification(SSelectStmt* pSelect, SFunctionNode* pFunc) {
|
||||||
pSelect->hasIndefiniteRowsFunc = pSelect->hasIndefiniteRowsFunc ? true : fmIsIndefiniteRowsFunc(pFunc->funcId);
|
pSelect->hasIndefiniteRowsFunc = pSelect->hasIndefiniteRowsFunc ? true : fmIsIndefiniteRowsFunc(pFunc->funcId);
|
||||||
pSelect->hasUniqueFunc = pSelect->hasUniqueFunc ? true : (FUNCTION_TYPE_UNIQUE == pFunc->funcType);
|
pSelect->hasUniqueFunc = pSelect->hasUniqueFunc ? true : (FUNCTION_TYPE_UNIQUE == pFunc->funcType);
|
||||||
pSelect->hasTailFunc = pSelect->hasTailFunc ? true : (FUNCTION_TYPE_TAIL == pFunc->funcType);
|
pSelect->hasTailFunc = pSelect->hasTailFunc ? true : (FUNCTION_TYPE_TAIL == pFunc->funcType);
|
||||||
|
pSelect->hasInterpFunc = pSelect->hasInterpFunc ? true : (FUNCTION_TYPE_INTERP == pFunc->funcType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -256,6 +256,24 @@ TEST_F(ParserSelectTest, intervalSemanticCheck) {
|
||||||
run("SELECT _WSTARTTS, _WENDTS, _WDURATION, sum(c1) FROM t1", TSDB_CODE_PAR_INVALID_WINDOW_PC);
|
run("SELECT _WSTARTTS, _WENDTS, _WDURATION, sum(c1) FROM t1", TSDB_CODE_PAR_INVALID_WINDOW_PC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserSelectTest, interp) {
|
||||||
|
useDb("root", "test");
|
||||||
|
|
||||||
|
run("SELECT INTERP(c1) FROM t1");
|
||||||
|
|
||||||
|
run("SELECT INTERP(c1) FROM t1 RANGE('2017-7-14 18:00:00', '2017-7-14 19:00:00')");
|
||||||
|
|
||||||
|
run("SELECT INTERP(c1) FROM t1 RANGE('2017-7-14 18:00:00', '2017-7-14 19:00:00') FILL(LINEAR)");
|
||||||
|
|
||||||
|
run("SELECT INTERP(c1) FROM t1 EVERY(5s)");
|
||||||
|
|
||||||
|
run("SELECT INTERP(c1) FROM t1 EVERY(5s) FILL(LINEAR)");
|
||||||
|
|
||||||
|
run("SELECT INTERP(c1) FROM t1 RANGE('2017-7-14 18:00:00', '2017-7-14 19:00:00') EVERY(5s)");
|
||||||
|
|
||||||
|
run("SELECT INTERP(c1) FROM t1 RANGE('2017-7-14 18:00:00', '2017-7-14 19:00:00') EVERY(5s) FILL(LINEAR)");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(ParserSelectTest, subquery) {
|
TEST_F(ParserSelectTest, subquery) {
|
||||||
useDb("root", "test");
|
useDb("root", "test");
|
||||||
|
|
||||||
|
|
|
@ -91,7 +91,7 @@ static EDealRes doNameExpr(SNode* pNode, void* pContext) {
|
||||||
return DEAL_RES_CONTINUE;
|
return DEAL_RES_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t rewriteExprForSelect(SNodeList* pExprs, SSelectStmt* pSelect, ESqlClause clause) {
|
static int32_t rewriteExprsForSelect(SNodeList* pExprs, SSelectStmt* pSelect, ESqlClause clause) {
|
||||||
nodesWalkExprs(pExprs, doNameExpr, NULL);
|
nodesWalkExprs(pExprs, doNameExpr, NULL);
|
||||||
SRewriteExprCxt cxt = {.errCode = TSDB_CODE_SUCCESS, .pExprs = pExprs};
|
SRewriteExprCxt cxt = {.errCode = TSDB_CODE_SUCCESS, .pExprs = pExprs};
|
||||||
nodesRewriteSelectStmt(pSelect, clause, doRewriteExpr, &cxt);
|
nodesRewriteSelectStmt(pSelect, clause, doRewriteExpr, &cxt);
|
||||||
|
@ -266,7 +266,7 @@ 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) {
|
||||||
code = rewriteExprForSelect(pScan->pScanPseudoCols, pSelect, SQL_CLAUSE_FROM);
|
code = rewriteExprsForSelect(pScan->pScanPseudoCols, pSelect, SQL_CLAUSE_FROM);
|
||||||
}
|
}
|
||||||
|
|
||||||
pScan->scanType = getScanType(pCxt, pScan->pScanPseudoCols, pScan->pScanCols, pScan->tableType);
|
pScan->scanType = getScanType(pCxt, pScan->pScanPseudoCols, pScan->pScanCols, pScan->tableType);
|
||||||
|
@ -425,7 +425,7 @@ static int32_t createAggLogicNode(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) {
|
||||||
code = rewriteExprForSelect(pAgg->pGroupKeys, pSelect, SQL_CLAUSE_GROUP_BY);
|
code = rewriteExprsForSelect(pAgg->pGroupKeys, pSelect, SQL_CLAUSE_GROUP_BY);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TSDB_CODE_SUCCESS == code && pSelect->hasAggFuncs) {
|
if (TSDB_CODE_SUCCESS == code && pSelect->hasAggFuncs) {
|
||||||
|
@ -434,7 +434,7 @@ static int32_t createAggLogicNode(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) {
|
||||||
code = rewriteExprForSelect(pAgg->pAggFuncs, pSelect, SQL_CLAUSE_GROUP_BY);
|
code = rewriteExprsForSelect(pAgg->pAggFuncs, pSelect, SQL_CLAUSE_GROUP_BY);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TSDB_CODE_SUCCESS == code && NULL != pSelect->pHaving) {
|
if (TSDB_CODE_SUCCESS == code && NULL != pSelect->pHaving) {
|
||||||
|
@ -473,14 +473,15 @@ static int32_t createIndefRowsFuncLogicNode(SLogicPlanContext* pCxt, SSelectStmt
|
||||||
return TSDB_CODE_OUT_OF_MEMORY;
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t code = nodesCollectFuncs(pSelect, SQL_CLAUSE_SELECT, fmIsVectorFunc, &pIdfRowsFunc->pVectorFuncs);
|
// indefinite rows functions and _select_values functions
|
||||||
|
int32_t code = nodesCollectFuncs(pSelect, SQL_CLAUSE_SELECT, fmIsVectorFunc, &pIdfRowsFunc->pFuncs);
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = rewriteExprForSelect(pIdfRowsFunc->pVectorFuncs, pSelect, SQL_CLAUSE_SELECT);
|
code = rewriteExprsForSelect(pIdfRowsFunc->pFuncs, pSelect, SQL_CLAUSE_SELECT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the output
|
// set the output
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = createColumnByRewriteExprs(pIdfRowsFunc->pVectorFuncs, &pIdfRowsFunc->node.pTargets);
|
code = createColumnByRewriteExprs(pIdfRowsFunc->pFuncs, &pIdfRowsFunc->node.pTargets);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
@ -492,6 +493,45 @@ static int32_t createIndefRowsFuncLogicNode(SLogicPlanContext* pCxt, SSelectStmt
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t createInterpFuncLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) {
|
||||||
|
if (!pSelect->hasInterpFunc) {
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
SInterpFuncLogicNode* pInterpFunc = (SInterpFuncLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_INTERP_FUNC);
|
||||||
|
if (NULL == pInterpFunc) {
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t code = nodesCollectFuncs(pSelect, SQL_CLAUSE_SELECT, fmIsInterpFunc, &pInterpFunc->pFuncs);
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = rewriteExprsForSelect(pInterpFunc->pFuncs, pSelect, SQL_CLAUSE_SELECT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TSDB_CODE_SUCCESS == code && NULL != pSelect->pRange) {
|
||||||
|
// SRangeNode* pRange = (SRangeNode*)pSelect->pRange;
|
||||||
|
// pInterpFunc->timeRange.skey = ((SValueNode*)pRange->pStart)->datum.i;
|
||||||
|
// pInterpFunc->timeRange.ekey = ((SValueNode*)pRange->pEnd)->datum.i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TSDB_CODE_SUCCESS == code && NULL != pSelect->pEvery) {
|
||||||
|
pInterpFunc->interval = ((SValueNode*)pSelect->pEvery)->datum.i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the output
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = createColumnByRewriteExprs(pInterpFunc->pFuncs, &pInterpFunc->node.pTargets);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
*pLogicNode = (SLogicNode*)pInterpFunc;
|
||||||
|
} else {
|
||||||
|
nodesDestroyNode((SNode*)pInterpFunc);
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t createWindowLogicNodeFinalize(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SWindowLogicNode* pWindow,
|
static int32_t createWindowLogicNodeFinalize(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SWindowLogicNode* pWindow,
|
||||||
SLogicNode** pLogicNode) {
|
SLogicNode** pLogicNode) {
|
||||||
int32_t code = nodesCollectFuncs(pSelect, SQL_CLAUSE_WINDOW, fmIsWindowClauseFunc, &pWindow->pFuncs);
|
int32_t code = nodesCollectFuncs(pSelect, SQL_CLAUSE_WINDOW, fmIsWindowClauseFunc, &pWindow->pFuncs);
|
||||||
|
@ -506,7 +546,7 @@ static int32_t createWindowLogicNodeFinalize(SLogicPlanContext* pCxt, SSelectStm
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = rewriteExprForSelect(pWindow->pFuncs, pSelect, SQL_CLAUSE_WINDOW);
|
code = rewriteExprsForSelect(pWindow->pFuncs, pSelect, SQL_CLAUSE_WINDOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
@ -778,7 +818,7 @@ static int32_t createDistinctLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSe
|
||||||
|
|
||||||
// rewrite the expression in subsequent clauses
|
// rewrite the expression in subsequent clauses
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = rewriteExprForSelect(pAgg->pGroupKeys, pSelect, SQL_CLAUSE_DISTINCT);
|
code = rewriteExprsForSelect(pAgg->pGroupKeys, pSelect, SQL_CLAUSE_DISTINCT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the output
|
// set the output
|
||||||
|
@ -813,6 +853,9 @@ static int32_t createSelectLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSele
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = createSelectRootLogicNode(pCxt, pSelect, createIndefRowsFuncLogicNode, &pRoot);
|
code = createSelectRootLogicNode(pCxt, pSelect, createIndefRowsFuncLogicNode, &pRoot);
|
||||||
}
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = createSelectRootLogicNode(pCxt, pSelect, createInterpFuncLogicNode, &pRoot);
|
||||||
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = createSelectRootLogicNode(pCxt, pSelect, createDistinctLogicNode, &pRoot);
|
code = createSelectRootLogicNode(pCxt, pSelect, createDistinctLogicNode, &pRoot);
|
||||||
}
|
}
|
||||||
|
|
|
@ -825,8 +825,8 @@ static int32_t createIndefRowsFuncPhysiNode(SPhysiPlanContext* pCxt, SNodeList*
|
||||||
}
|
}
|
||||||
|
|
||||||
SNodeList* pPrecalcExprs = NULL;
|
SNodeList* pPrecalcExprs = NULL;
|
||||||
SNodeList* pVectorFuncs = NULL;
|
SNodeList* pFuncs = NULL;
|
||||||
int32_t code = rewritePrecalcExprs(pCxt, pFuncLogicNode->pVectorFuncs, &pPrecalcExprs, &pVectorFuncs);
|
int32_t code = rewritePrecalcExprs(pCxt, pFuncLogicNode->pFuncs, &pPrecalcExprs, &pFuncs);
|
||||||
|
|
||||||
SDataBlockDescNode* pChildTupe = (((SPhysiNode*)nodesListGetNode(pChildren, 0))->pOutputDataBlockDesc);
|
SDataBlockDescNode* pChildTupe = (((SPhysiNode*)nodesListGetNode(pChildren, 0))->pOutputDataBlockDesc);
|
||||||
// push down expression to pOutputDataBlockDesc of child node
|
// push down expression to pOutputDataBlockDesc of child node
|
||||||
|
@ -837,10 +837,10 @@ static int32_t createIndefRowsFuncPhysiNode(SPhysiPlanContext* pCxt, SNodeList*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TSDB_CODE_SUCCESS == code && NULL != pVectorFuncs) {
|
|
||||||
code = setListSlotId(pCxt, pChildTupe->dataBlockId, -1, pVectorFuncs, &pIdfRowsFunc->pVectorFuncs);
|
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = addDataBlockSlots(pCxt, pIdfRowsFunc->pVectorFuncs, pIdfRowsFunc->node.pOutputDataBlockDesc);
|
code = setListSlotId(pCxt, pChildTupe->dataBlockId, -1, pFuncs, &pIdfRowsFunc->pFuncs);
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = addDataBlockSlots(pCxt, pIdfRowsFunc->pFuncs, pIdfRowsFunc->node.pOutputDataBlockDesc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -853,6 +853,48 @@ static int32_t createIndefRowsFuncPhysiNode(SPhysiPlanContext* pCxt, SNodeList*
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t createInterpFuncPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren,
|
||||||
|
SInterpFuncLogicNode* pFuncLogicNode, SPhysiNode** pPhyNode) {
|
||||||
|
SInterpFuncPhysiNode* pInterpFunc =
|
||||||
|
(SInterpFuncPhysiNode*)makePhysiNode(pCxt, (SLogicNode*)pFuncLogicNode, QUERY_NODE_PHYSICAL_PLAN_INTERP_FUNC);
|
||||||
|
if (NULL == pInterpFunc) {
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
SNodeList* pPrecalcExprs = NULL;
|
||||||
|
SNodeList* pFuncs = NULL;
|
||||||
|
int32_t code = rewritePrecalcExprs(pCxt, pFuncLogicNode->pFuncs, &pPrecalcExprs, &pFuncs);
|
||||||
|
|
||||||
|
SDataBlockDescNode* pChildTupe = (((SPhysiNode*)nodesListGetNode(pChildren, 0))->pOutputDataBlockDesc);
|
||||||
|
// push down expression to pOutputDataBlockDesc of child node
|
||||||
|
if (TSDB_CODE_SUCCESS == code && NULL != pPrecalcExprs) {
|
||||||
|
code = setListSlotId(pCxt, pChildTupe->dataBlockId, -1, pPrecalcExprs, &pInterpFunc->pExprs);
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = pushdownDataBlockSlots(pCxt, pInterpFunc->pExprs, pChildTupe);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = setListSlotId(pCxt, pChildTupe->dataBlockId, -1, pFuncs, &pInterpFunc->pFuncs);
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = addDataBlockSlots(pCxt, pInterpFunc->pFuncs, pInterpFunc->node.pOutputDataBlockDesc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
pInterpFunc->timeRange = pFuncLogicNode->timeRange;
|
||||||
|
pInterpFunc->interval = pFuncLogicNode->interval;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
*pPhyNode = (SPhysiNode*)pInterpFunc;
|
||||||
|
} else {
|
||||||
|
nodesDestroyNode((SNode*)pInterpFunc);
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t createProjectPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren,
|
static int32_t createProjectPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren,
|
||||||
SProjectLogicNode* pProjectLogicNode, SPhysiNode** pPhyNode) {
|
SProjectLogicNode* pProjectLogicNode, SPhysiNode** pPhyNode) {
|
||||||
SProjectPhysiNode* pProject =
|
SProjectPhysiNode* pProject =
|
||||||
|
@ -1298,6 +1340,8 @@ static int32_t doCreatePhysiNode(SPhysiPlanContext* pCxt, SLogicNode* pLogicNode
|
||||||
return createFillPhysiNode(pCxt, pChildren, (SFillLogicNode*)pLogicNode, pPhyNode);
|
return createFillPhysiNode(pCxt, pChildren, (SFillLogicNode*)pLogicNode, pPhyNode);
|
||||||
case QUERY_NODE_LOGIC_PLAN_INDEF_ROWS_FUNC:
|
case QUERY_NODE_LOGIC_PLAN_INDEF_ROWS_FUNC:
|
||||||
return createIndefRowsFuncPhysiNode(pCxt, pChildren, (SIndefRowsFuncLogicNode*)pLogicNode, pPhyNode);
|
return createIndefRowsFuncPhysiNode(pCxt, pChildren, (SIndefRowsFuncLogicNode*)pLogicNode, pPhyNode);
|
||||||
|
case QUERY_NODE_LOGIC_PLAN_INTERP_FUNC:
|
||||||
|
return createInterpFuncPhysiNode(pCxt, pChildren, (SInterpFuncLogicNode*)pLogicNode, pPhyNode);
|
||||||
case QUERY_NODE_LOGIC_PLAN_MERGE:
|
case QUERY_NODE_LOGIC_PLAN_MERGE:
|
||||||
return createMergePhysiNode(pCxt, (SMergeLogicNode*)pLogicNode, pPhyNode);
|
return createMergePhysiNode(pCxt, (SMergeLogicNode*)pLogicNode, pPhyNode);
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -75,3 +75,11 @@ TEST_F(PlanBasicTest, tailFunc) {
|
||||||
|
|
||||||
run("SELECT TAIL(c2 + 10, 10, 80) FROM t1 WHERE c1 > 10");
|
run("SELECT TAIL(c2 + 10, 10, 80) FROM t1 WHERE c1 > 10");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(PlanBasicTest, interpFunc) {
|
||||||
|
useDb("root", "test");
|
||||||
|
|
||||||
|
run("SELECT INTERP(c1) FROM t1");
|
||||||
|
|
||||||
|
run("SELECT INTERP(c1) FROM t1 RANGE('2017-7-14 18:00:00', '2017-7-14 19:00:00') EVERY(5s) FILL(LINEAR)");
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue