未验证 提交 3319c093 编写于 作者: S Shengliang Guan 提交者: GitHub

Merge pull request #15801 from taosdata/feature/3.0_fill_enh

fix(query): fix bug in fill
...@@ -27,10 +27,6 @@ else () ...@@ -27,10 +27,6 @@ else ()
cat("${TD_SUPPORT_DIR}/taosadapter_CMakeLists.txt.in" ${CONTRIB_TMP_FILE}) cat("${TD_SUPPORT_DIR}/taosadapter_CMakeLists.txt.in" ${CONTRIB_TMP_FILE})
endif() endif()
if(TD_LINUX_64 AND JEMALLOC_ENABLED)
cat("${TD_SUPPORT_DIR}/jemalloc_CMakeLists.txt.in" ${CONTRIB_TMP_FILE})
endif()
# pthread # pthread
if(${BUILD_PTHREAD}) if(${BUILD_PTHREAD})
cat("${TD_SUPPORT_DIR}/pthread_CMakeLists.txt.in" ${CONTRIB_TMP_FILE}) cat("${TD_SUPPORT_DIR}/pthread_CMakeLists.txt.in" ${CONTRIB_TMP_FILE})
...@@ -396,19 +392,6 @@ if(${BUILD_WITH_SQLITE}) ...@@ -396,19 +392,6 @@ if(${BUILD_WITH_SQLITE})
endif(NOT TD_WINDOWS) endif(NOT TD_WINDOWS)
endif(${BUILD_WITH_SQLITE}) endif(${BUILD_WITH_SQLITE})
# jemalloc
IF (TD_LINUX_64 AND JEMALLOC_ENABLED)
include(ExternalProject)
ExternalProject_Add(jemalloc
PREFIX "jemalloc"
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/jemalloc
BUILD_IN_SOURCE 1
CONFIGURE_COMMAND ./autogen.sh COMMAND ./configure --prefix=${CMAKE_BINARY_DIR}/build/
BUILD_COMMAND ${MAKE}
)
INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}/build/include)
ENDIF ()
# addr2line # addr2line
if(${BUILD_ADDR2LINE}) if(${BUILD_ADDR2LINE})
if(NOT ${TD_WINDOWS}) if(NOT ${TD_WINDOWS})
......
...@@ -213,6 +213,8 @@ typedef struct SWindowLogicNode { ...@@ -213,6 +213,8 @@ typedef struct SWindowLogicNode {
typedef struct SFillLogicNode { typedef struct SFillLogicNode {
SLogicNode node; SLogicNode node;
EFillMode mode; EFillMode mode;
SNodeList* pFillExprs;
SNodeList* pNotFillExprs;
SNode* pWStartTs; SNode* pWStartTs;
SNode* pValues; // SNodeListNode SNode* pValues; // SNodeListNode
STimeWindow timeRange; STimeWindow timeRange;
...@@ -440,9 +442,10 @@ typedef SIntervalPhysiNode SStreamSemiIntervalPhysiNode; ...@@ -440,9 +442,10 @@ typedef SIntervalPhysiNode SStreamSemiIntervalPhysiNode;
typedef struct SFillPhysiNode { typedef struct SFillPhysiNode {
SPhysiNode node; SPhysiNode node;
EFillMode mode; EFillMode mode;
SNodeList* pFillExprs;
SNodeList* pNotFillExprs;
SNode* pWStartTs; // SColumnNode SNode* pWStartTs; // SColumnNode
SNode* pValues; // SNodeListNode SNode* pValues; // SNodeListNode
SNodeList* pTargets;
STimeWindow timeRange; STimeWindow timeRange;
EOrder inputTsOrder; EOrder inputTsOrder;
} SFillPhysiNode; } SFillPhysiNode;
......
...@@ -53,7 +53,13 @@ typedef struct SExprNode { ...@@ -53,7 +53,13 @@ typedef struct SExprNode {
bool orderAlias; bool orderAlias;
} SExprNode; } SExprNode;
typedef enum EColumnType { COLUMN_TYPE_COLUMN = 1, COLUMN_TYPE_TAG, COLUMN_TYPE_TBNAME } EColumnType; typedef enum EColumnType {
COLUMN_TYPE_COLUMN = 1,
COLUMN_TYPE_TAG,
COLUMN_TYPE_TBNAME,
COLUMN_TYPE_WINDOW_PC,
COLUMN_TYPE_GROUP_KEY
} EColumnType;
typedef struct SColumnNode { typedef struct SColumnNode {
SExprNode node; // QUERY_NODE_COLUMN SExprNode node; // QUERY_NODE_COLUMN
...@@ -293,6 +299,7 @@ typedef enum ESqlClause { ...@@ -293,6 +299,7 @@ typedef enum ESqlClause {
SQL_CLAUSE_WHERE, SQL_CLAUSE_WHERE,
SQL_CLAUSE_PARTITION_BY, SQL_CLAUSE_PARTITION_BY,
SQL_CLAUSE_WINDOW, SQL_CLAUSE_WINDOW,
SQL_CLAUSE_FILL,
SQL_CLAUSE_GROUP_BY, SQL_CLAUSE_GROUP_BY,
SQL_CLAUSE_HAVING, SQL_CLAUSE_HAVING,
SQL_CLAUSE_DISTINCT, SQL_CLAUSE_DISTINCT,
......
...@@ -619,15 +619,20 @@ typedef struct SIndefOperatorInfo { ...@@ -619,15 +619,20 @@ typedef struct SIndefOperatorInfo {
typedef struct SFillOperatorInfo { typedef struct SFillOperatorInfo {
struct SFillInfo* pFillInfo; struct SFillInfo* pFillInfo;
SSDataBlock* pRes; SSDataBlock* pRes;
SSDataBlock* pFinalRes;
int64_t totalInputRows; int64_t totalInputRows;
void** p; void** p;
SSDataBlock* existNewGroupBlock; SSDataBlock* existNewGroupBlock;
bool multigroupResult;
STimeWindow win; STimeWindow win;
SNode* pCondition; SNode* pCondition;
SArray* pColMatchColInfo; SArray* pColMatchColInfo;
int32_t primaryTsCol; int32_t primaryTsCol;
int32_t primarySrcSlotId;
uint64_t curGroupId; // current handled group id uint64_t curGroupId; // current handled group id
SExprInfo* pExprInfo;
int32_t numOfExpr;
SExprInfo* pNotFillExprInfo;
int32_t numOfNotFillExpr;
} SFillOperatorInfo; } SFillOperatorInfo;
typedef struct SGroupbyOperatorInfo { typedef struct SGroupbyOperatorInfo {
......
...@@ -28,8 +28,7 @@ struct SSDataBlock; ...@@ -28,8 +28,7 @@ struct SSDataBlock;
typedef struct SFillColInfo { typedef struct SFillColInfo {
SExprInfo *pExpr; SExprInfo *pExpr;
int16_t flag; // column flag: TAG COLUMN|NORMAL COLUMN bool notFillCol; // denote if this column needs fill operation
int16_t tagIndex; // index of current tag in SFillTagColInfo array list
SVariant fillVal; SVariant fillVal;
} SFillColInfo; } SFillColInfo;
...@@ -46,25 +45,27 @@ typedef struct { ...@@ -46,25 +45,27 @@ typedef struct {
char* tagVal; char* tagVal;
} SFillTagColInfo; } SFillTagColInfo;
typedef struct {
int64_t key;
SArray* pRowVal;
} SRowVal;
typedef struct SFillInfo { typedef struct SFillInfo {
TSKEY start; // start timestamp TSKEY start; // start timestamp
TSKEY end; // endKey for fill TSKEY end; // endKey for fill
TSKEY currentKey; // current active timestamp, the value may be changed during the fill procedure. TSKEY currentKey; // current active timestamp, the value may be changed during the fill procedure.
int32_t tsSlotId; // primary time stamp slot id int32_t tsSlotId; // primary time stamp slot id
int32_t srcTsSlotId; // timestamp column id in the source data block.
int32_t order; // order [TSDB_ORDER_ASC|TSDB_ORDER_DESC] int32_t order; // order [TSDB_ORDER_ASC|TSDB_ORDER_DESC]
int32_t type; // fill type int32_t type; // fill type
int32_t numOfRows; // number of rows in the input data block int32_t numOfRows; // number of rows in the input data block
int32_t index; // active row index int32_t index; // active row index
int32_t numOfTotal; // number of filled rows in one round int32_t numOfTotal; // number of filled rows in one round
int32_t numOfCurrent; // number of filled rows in current results int32_t numOfCurrent; // number of filled rows in current results
int32_t numOfTags; // number of tags
int32_t numOfCols; // number of columns, including the tags columns int32_t numOfCols; // number of columns, including the tags columns
int32_t rowSize; // size of each row
SInterval interval; SInterval interval;
SRowVal prev;
SArray *prev; SRowVal next;
SArray *next;
SSDataBlock *pSrcBlock; SSDataBlock *pSrcBlock;
int32_t alloc; // data buffer size in rows int32_t alloc; // data buffer size in rows
...@@ -79,10 +80,10 @@ int64_t getNumOfResultsAfterFillGap(SFillInfo* pFillInfo, int64_t ekey, int32_t ...@@ -79,10 +80,10 @@ int64_t getNumOfResultsAfterFillGap(SFillInfo* pFillInfo, int64_t ekey, int32_t
void taosFillSetStartInfo(struct SFillInfo* pFillInfo, int32_t numOfRows, TSKEY endKey); void taosFillSetStartInfo(struct SFillInfo* pFillInfo, int32_t numOfRows, TSKEY endKey);
void taosResetFillInfo(struct SFillInfo* pFillInfo, TSKEY startTimestamp); void taosResetFillInfo(struct SFillInfo* pFillInfo, TSKEY startTimestamp);
void taosFillSetInputDataBlock(struct SFillInfo* pFillInfo, const struct SSDataBlock* pInput); void taosFillSetInputDataBlock(struct SFillInfo* pFillInfo, const struct SSDataBlock* pInput);
struct SFillColInfo* createFillColInfo(SExprInfo* pExpr, int32_t numOfOutput, const struct SNodeListNode* val); struct SFillColInfo* createFillColInfo(SExprInfo* pExpr, int32_t numOfFillExpr, SExprInfo* pNotFillExpr, int32_t numOfNotFillCols, const struct SNodeListNode* val);
bool taosFillHasMoreResults(struct SFillInfo* pFillInfo); bool taosFillHasMoreResults(struct SFillInfo* pFillInfo);
SFillInfo* taosCreateFillInfo(TSKEY skey, int32_t numOfTags, int32_t capacity, int32_t numOfCols, SFillInfo* taosCreateFillInfo(TSKEY skey, int32_t numOfFillCols, int32_t numOfNotFillCols, int32_t capacity,
SInterval* pInterval, int32_t fillType, struct SFillColInfo* pCol, int32_t slotId, SInterval* pInterval, int32_t fillType, struct SFillColInfo* pCol, int32_t slotId,
int32_t order, const char* id); int32_t order, const char* id);
......
...@@ -3216,36 +3216,71 @@ int32_t handleLimitOffset(SOperatorInfo* pOperator, SLimitInfo* pLimitInfo, SSDa ...@@ -3216,36 +3216,71 @@ int32_t handleLimitOffset(SOperatorInfo* pOperator, SLimitInfo* pLimitInfo, SSDa
} }
} }
static void doHandleRemainBlockForNewGroupImpl(SFillOperatorInfo* pInfo, SResultInfo* pResultInfo, static void doApplyScalarCalculation(SOperatorInfo* pOperator, SSDataBlock* pBlock, int32_t order, int32_t scanFlag);
static void doHandleRemainBlockForNewGroupImpl(SOperatorInfo *pOperator, SFillOperatorInfo* pInfo, SResultInfo* pResultInfo,
SExecTaskInfo* pTaskInfo) { SExecTaskInfo* pTaskInfo) {
pInfo->totalInputRows = pInfo->existNewGroupBlock->info.rows; pInfo->totalInputRows = pInfo->existNewGroupBlock->info.rows;
SSDataBlock* pResBlock = pInfo->pFinalRes;
int32_t order = TSDB_ORDER_ASC;
int32_t scanFlag = MAIN_SCAN;
getTableScanInfo(pOperator, &order, &scanFlag);
int64_t ekey = int64_t ekey =
Q_STATUS_EQUAL(pTaskInfo->status, TASK_COMPLETED) ? pInfo->win.ekey : pInfo->existNewGroupBlock->info.window.ekey; Q_STATUS_EQUAL(pTaskInfo->status, TASK_COMPLETED) ? pInfo->win.ekey : pInfo->existNewGroupBlock->info.window.ekey;
taosResetFillInfo(pInfo->pFillInfo, getFillInfoStart(pInfo->pFillInfo)); taosResetFillInfo(pInfo->pFillInfo, getFillInfoStart(pInfo->pFillInfo));
taosFillSetStartInfo(pInfo->pFillInfo, pInfo->existNewGroupBlock->info.rows, ekey); doApplyScalarCalculation(pOperator, pInfo->existNewGroupBlock, order, scanFlag);
taosFillSetInputDataBlock(pInfo->pFillInfo, pInfo->existNewGroupBlock);
taosFillSetStartInfo(pInfo->pFillInfo, pInfo->pRes->info.rows, ekey);
taosFillSetInputDataBlock(pInfo->pFillInfo, pInfo->pRes);
int32_t numOfResultRows = pResultInfo->capacity - pInfo->pRes->info.rows; int32_t numOfResultRows = pResultInfo->capacity - pResBlock->info.rows;
taosFillResultDataBlock(pInfo->pFillInfo, pInfo->pRes, numOfResultRows); taosFillResultDataBlock(pInfo->pFillInfo, pResBlock, numOfResultRows);
pInfo->curGroupId = pInfo->existNewGroupBlock->info.groupId; pInfo->curGroupId = pInfo->existNewGroupBlock->info.groupId;
pInfo->existNewGroupBlock = NULL; pInfo->existNewGroupBlock = NULL;
} }
static void doHandleRemainBlockFromNewGroup(SFillOperatorInfo* pInfo, SResultInfo* pResultInfo, static void doHandleRemainBlockFromNewGroup(SOperatorInfo* pOperator, SFillOperatorInfo* pInfo, SResultInfo* pResultInfo,
SExecTaskInfo* pTaskInfo) { SExecTaskInfo* pTaskInfo) {
if (taosFillHasMoreResults(pInfo->pFillInfo)) { if (taosFillHasMoreResults(pInfo->pFillInfo)) {
int32_t numOfResultRows = pResultInfo->capacity - pInfo->pRes->info.rows; int32_t numOfResultRows = pResultInfo->capacity - pInfo->pFinalRes->info.rows;
taosFillResultDataBlock(pInfo->pFillInfo, pInfo->pRes, numOfResultRows); taosFillResultDataBlock(pInfo->pFillInfo, pInfo->pFinalRes, numOfResultRows);
pInfo->pRes->info.groupId = pInfo->curGroupId; pInfo->pRes->info.groupId = pInfo->curGroupId;
return; return;
} }
// handle the cached new group data block // handle the cached new group data block
if (pInfo->existNewGroupBlock) { if (pInfo->existNewGroupBlock) {
doHandleRemainBlockForNewGroupImpl(pInfo, pResultInfo, pTaskInfo); doHandleRemainBlockForNewGroupImpl(pOperator, pInfo, pResultInfo, pTaskInfo);
}
}
static void doApplyScalarCalculation(SOperatorInfo* pOperator, SSDataBlock* pBlock, int32_t order, int32_t scanFlag) {
SFillOperatorInfo* pInfo = pOperator->info;
SExprSupp* pSup = &pOperator->exprSupp;
SSDataBlock* pResBlock = pInfo->pFinalRes;
setInputDataBlock(pOperator, pSup->pCtx, pBlock, order, scanFlag, false);
projectApplyFunctions(pSup->pExprInfo, pInfo->pRes, pBlock, pSup->pCtx, pSup->numOfExprs, NULL);
pInfo->pRes->info.groupId = pBlock->info.groupId;
SColumnInfoData* pDst = taosArrayGet(pInfo->pRes->pDataBlock, pInfo->primaryTsCol);
SColumnInfoData* pSrc = taosArrayGet(pBlock->pDataBlock, pInfo->primarySrcSlotId);
colDataAssign(pDst, pSrc, pInfo->pRes->info.rows, &pResBlock->info);
for(int32_t i = 0; i < pInfo->numOfNotFillExpr; ++i) {
SFillColInfo* pCol = &pInfo->pFillInfo->pFillCol[i + pInfo->numOfExpr];
ASSERT(pCol->notFillCol);
SExprInfo* pExpr = pCol->pExpr;
int32_t srcSlotId = pExpr->base.pParam[0].pCol->slotId;
int32_t dstSlotId = pExpr->base.resSchema.slotId;
SColumnInfoData* pDst1 = taosArrayGet(pInfo->pRes->pDataBlock, dstSlotId);
SColumnInfoData* pSrc1 = taosArrayGet(pBlock->pDataBlock, srcSlotId);
colDataAssign(pDst1, pSrc1, pInfo->pRes->info.rows, &pResBlock->info);
} }
} }
...@@ -3254,11 +3289,16 @@ static SSDataBlock* doFillImpl(SOperatorInfo* pOperator) { ...@@ -3254,11 +3289,16 @@ static SSDataBlock* doFillImpl(SOperatorInfo* pOperator) {
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
SResultInfo* pResultInfo = &pOperator->resultInfo; SResultInfo* pResultInfo = &pOperator->resultInfo;
SSDataBlock* pResBlock = pInfo->pRes; SSDataBlock* pResBlock = pInfo->pFinalRes;
blockDataCleanup(pResBlock); blockDataCleanup(pResBlock);
blockDataCleanup(pInfo->pRes);
doHandleRemainBlockFromNewGroup(pInfo, pResultInfo, pTaskInfo); int32_t order = TSDB_ORDER_ASC;
int32_t scanFlag = MAIN_SCAN;
getTableScanInfo(pOperator, &order, &scanFlag);
doHandleRemainBlockFromNewGroup(pOperator, pInfo, pResultInfo, pTaskInfo);
if (pResBlock->info.rows > 0) { if (pResBlock->info.rows > 0) {
pResBlock->info.groupId = pInfo->curGroupId; pResBlock->info.groupId = pInfo->curGroupId;
return pResBlock; return pResBlock;
...@@ -3269,21 +3309,21 @@ static SSDataBlock* doFillImpl(SOperatorInfo* pOperator) { ...@@ -3269,21 +3309,21 @@ static SSDataBlock* doFillImpl(SOperatorInfo* pOperator) {
SSDataBlock* pBlock = pDownstream->fpSet.getNextFn(pDownstream); SSDataBlock* pBlock = pDownstream->fpSet.getNextFn(pDownstream);
if (pBlock == NULL) { if (pBlock == NULL) {
if (pInfo->totalInputRows == 0) { if (pInfo->totalInputRows == 0) {
pOperator->status = OP_EXEC_DONE; doSetOperatorCompleted(pOperator);
return NULL; return NULL;
} }
taosFillSetStartInfo(pInfo->pFillInfo, 0, pInfo->win.ekey); taosFillSetStartInfo(pInfo->pFillInfo, 0, pInfo->win.ekey);
} else { } else {
blockDataUpdateTsWindow(pBlock, pInfo->primaryTsCol); blockDataUpdateTsWindow(pBlock, pInfo->primaryTsCol);
doApplyScalarCalculation(pOperator, pBlock, order, scanFlag);
if (pInfo->curGroupId == 0 || pInfo->curGroupId == pBlock->info.groupId) { if (pInfo->curGroupId == 0 || pInfo->curGroupId == pInfo->pRes->info.groupId) {
pInfo->curGroupId = pBlock->info.groupId; // the first data block pInfo->curGroupId = pInfo->pRes->info.groupId; // the first data block
pInfo->totalInputRows += pInfo->pRes->info.rows;
pInfo->totalInputRows += pBlock->info.rows;
taosFillSetStartInfo(pInfo->pFillInfo, pBlock->info.rows, pBlock->info.window.ekey); taosFillSetStartInfo(pInfo->pFillInfo, pInfo->pRes->info.rows, pBlock->info.window.ekey);
taosFillSetInputDataBlock(pInfo->pFillInfo, pBlock); taosFillSetInputDataBlock(pInfo->pFillInfo, pInfo->pRes);
} else if (pInfo->curGroupId != pBlock->info.groupId) { // the new group data block } else if (pInfo->curGroupId != pBlock->info.groupId) { // the new group data block
pInfo->existNewGroupBlock = pBlock; pInfo->existNewGroupBlock = pBlock;
...@@ -3293,8 +3333,6 @@ static SSDataBlock* doFillImpl(SOperatorInfo* pOperator) { ...@@ -3293,8 +3333,6 @@ static SSDataBlock* doFillImpl(SOperatorInfo* pOperator) {
} }
} }
blockDataEnsureCapacity(pResBlock, pOperator->resultInfo.capacity);
int32_t numOfResultRows = pOperator->resultInfo.capacity - pResBlock->info.rows; int32_t numOfResultRows = pOperator->resultInfo.capacity - pResBlock->info.rows;
taosFillResultDataBlock(pInfo->pFillInfo, pResBlock, numOfResultRows); taosFillResultDataBlock(pInfo->pFillInfo, pResBlock, numOfResultRows);
...@@ -3307,14 +3345,18 @@ static SSDataBlock* doFillImpl(SOperatorInfo* pOperator) { ...@@ -3307,14 +3345,18 @@ static SSDataBlock* doFillImpl(SOperatorInfo* pOperator) {
return pResBlock; return pResBlock;
} }
doHandleRemainBlockFromNewGroup(pInfo, pResultInfo, pTaskInfo); doHandleRemainBlockFromNewGroup(pOperator, pInfo, pResultInfo, pTaskInfo);
if (pResBlock->info.rows >= pOperator->resultInfo.threshold || pBlock == NULL) { if (pResBlock->info.rows >= pOperator->resultInfo.threshold || pBlock == NULL) {
pResBlock->info.groupId = pInfo->curGroupId; pResBlock->info.groupId = pInfo->curGroupId;
return pResBlock; return pResBlock;
} }
} else if (pInfo->existNewGroupBlock) { // try next group } else if (pInfo->existNewGroupBlock) { // try next group
assert(pBlock != NULL); assert(pBlock != NULL);
doHandleRemainBlockForNewGroupImpl(pInfo, pResultInfo, pTaskInfo);
blockDataCleanup(pResBlock);
blockDataCleanup(pInfo->pRes);
doHandleRemainBlockForNewGroupImpl(pOperator, pInfo, pResultInfo, pTaskInfo);
if (pResBlock->info.rows > pResultInfo->threshold) { if (pResBlock->info.rows > pResultInfo->threshold) {
pResBlock->info.groupId = pInfo->curGroupId; pResBlock->info.groupId = pInfo->curGroupId;
return pResBlock; return pResBlock;
...@@ -3605,6 +3647,13 @@ void destroyFillOperatorInfo(void* param, int32_t numOfOutput) { ...@@ -3605,6 +3647,13 @@ void destroyFillOperatorInfo(void* param, int32_t numOfOutput) {
SFillOperatorInfo* pInfo = (SFillOperatorInfo*)param; SFillOperatorInfo* pInfo = (SFillOperatorInfo*)param;
pInfo->pFillInfo = taosDestroyFillInfo(pInfo->pFillInfo); pInfo->pFillInfo = taosDestroyFillInfo(pInfo->pFillInfo);
pInfo->pRes = blockDataDestroy(pInfo->pRes); pInfo->pRes = blockDataDestroy(pInfo->pRes);
pInfo->pFinalRes = blockDataDestroy(pInfo->pFinalRes);
if (pInfo->pNotFillExprInfo != NULL) {
destroyExprInfo(pInfo->pNotFillExprInfo, pInfo->numOfNotFillExpr);
taosMemoryFree(pInfo->pNotFillExprInfo);
}
taosMemoryFreeClear(pInfo->p); taosMemoryFreeClear(pInfo->p);
taosArrayDestroy(pInfo->pColMatchColInfo); taosArrayDestroy(pInfo->pColMatchColInfo);
taosMemoryFreeClear(param); taosMemoryFreeClear(param);
...@@ -3637,16 +3686,16 @@ void doDestroyExchangeOperatorInfo(void* param) { ...@@ -3637,16 +3686,16 @@ void doDestroyExchangeOperatorInfo(void* param) {
taosMemoryFreeClear(param); taosMemoryFreeClear(param);
} }
static int32_t initFillInfo(SFillOperatorInfo* pInfo, SExprInfo* pExpr, int32_t numOfCols, SNodeListNode* pValNode, static int32_t initFillInfo(SFillOperatorInfo* pInfo, SExprInfo* pExpr, int32_t numOfCols, SExprInfo* pNotFillExpr,
STimeWindow win, int32_t capacity, const char* id, SInterval* pInterval, int32_t fillType, int32_t numOfNotFillCols, SNodeListNode* pValNode, STimeWindow win, int32_t capacity,
int32_t order) { const char* id, SInterval* pInterval, int32_t fillType, int32_t order) {
SFillColInfo* pColInfo = createFillColInfo(pExpr, numOfCols, pValNode); SFillColInfo* pColInfo = createFillColInfo(pExpr, numOfCols, pNotFillExpr, numOfNotFillCols, pValNode);
STimeWindow w = getAlignQueryTimeWindow(pInterval, pInterval->precision, win.skey); STimeWindow w = getAlignQueryTimeWindow(pInterval, pInterval->precision, win.skey);
w = getFirstQualifiedTimeWindow(win.skey, &w, pInterval, TSDB_ORDER_ASC); w = getFirstQualifiedTimeWindow(win.skey, &w, pInterval, TSDB_ORDER_ASC);
pInfo->pFillInfo = pInfo->pFillInfo =
taosCreateFillInfo(w.skey, 0, capacity, numOfCols, pInterval, fillType, pColInfo, pInfo->primaryTsCol, order, id); taosCreateFillInfo(w.skey, numOfCols, numOfNotFillCols, capacity, pInterval, fillType, pColInfo, pInfo->primaryTsCol, order, id);
pInfo->win = win; pInfo->win = win;
pInfo->p = taosMemoryCalloc(numOfCols, POINTER_BYTES); pInfo->p = taosMemoryCalloc(numOfCols, POINTER_BYTES);
...@@ -3668,9 +3717,10 @@ SOperatorInfo* createFillOperatorInfo(SOperatorInfo* downstream, SFillPhysiNode* ...@@ -3668,9 +3717,10 @@ SOperatorInfo* createFillOperatorInfo(SOperatorInfo* downstream, SFillPhysiNode*
goto _error; goto _error;
} }
int32_t num = 0;
SSDataBlock* pResBlock = createResDataBlock(pPhyFillNode->node.pOutputDataBlockDesc); SSDataBlock* pResBlock = createResDataBlock(pPhyFillNode->node.pOutputDataBlockDesc);
SExprInfo* pExprInfo = createExprInfo(pPhyFillNode->pTargets, NULL, &num); SExprInfo* pExprInfo = createExprInfo(pPhyFillNode->pFillExprs, NULL, &pInfo->numOfExpr);
pInfo->pNotFillExprInfo = createExprInfo(pPhyFillNode->pNotFillExprs, NULL, &pInfo->numOfNotFillExpr);
SInterval* pInterval = SInterval* pInterval =
QUERY_NODE_PHYSICAL_PLAN_MERGE_ALIGNED_INTERVAL == downstream->operatorType QUERY_NODE_PHYSICAL_PLAN_MERGE_ALIGNED_INTERVAL == downstream->operatorType
? &((SMergeAlignedIntervalAggOperatorInfo*)downstream->info)->intervalAggOperatorInfo->interval ? &((SMergeAlignedIntervalAggOperatorInfo*)downstream->info)->intervalAggOperatorInfo->interval
...@@ -3681,19 +3731,27 @@ SOperatorInfo* createFillOperatorInfo(SOperatorInfo* downstream, SFillPhysiNode* ...@@ -3681,19 +3731,27 @@ SOperatorInfo* createFillOperatorInfo(SOperatorInfo* downstream, SFillPhysiNode*
SResultInfo* pResultInfo = &pOperator->resultInfo; SResultInfo* pResultInfo = &pOperator->resultInfo;
initResultSizeInfo(&pOperator->resultInfo, 4096); initResultSizeInfo(&pOperator->resultInfo, 4096);
pInfo->primaryTsCol = ((SColumnNode*)pPhyFillNode->pWStartTs)->slotId; blockDataEnsureCapacity(pResBlock, pOperator->resultInfo.capacity);
initExprSupp(&pOperator->exprSupp, pExprInfo, pInfo->numOfExpr);
pInfo->primaryTsCol = ((STargetNode*)pPhyFillNode->pWStartTs)->slotId;
pInfo->primarySrcSlotId = ((SColumnNode*)((STargetNode*)pPhyFillNode->pWStartTs)->pExpr)->slotId;
int32_t numOfOutputCols = 0; int32_t numOfOutputCols = 0;
SArray* pColMatchColInfo = extractColMatchInfo(pPhyFillNode->pTargets, pPhyFillNode->node.pOutputDataBlockDesc, SArray* pColMatchColInfo = extractColMatchInfo(pPhyFillNode->pFillExprs, pPhyFillNode->node.pOutputDataBlockDesc,
&numOfOutputCols, COL_MATCH_FROM_SLOT_ID); &numOfOutputCols, COL_MATCH_FROM_SLOT_ID);
int32_t code = initFillInfo(pInfo, pExprInfo, num, (SNodeListNode*)pPhyFillNode->pValues, pPhyFillNode->timeRange, int32_t code =
pResultInfo->capacity, pTaskInfo->id.str, pInterval, type, order); initFillInfo(pInfo, pExprInfo, pInfo->numOfExpr, pInfo->pNotFillExprInfo, pInfo->numOfNotFillExpr, (SNodeListNode*)pPhyFillNode->pValues,
pPhyFillNode->timeRange, pResultInfo->capacity, pTaskInfo->id.str, pInterval, type, order);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
goto _error; goto _error;
} }
pInfo->pRes = pResBlock; pInfo->pRes = pResBlock;
pInfo->pFinalRes = createOneDataBlock(pResBlock, false);
blockDataEnsureCapacity(pInfo->pFinalRes, pOperator->resultInfo.capacity);
pInfo->pCondition = pPhyFillNode->node.pConditions; pInfo->pCondition = pPhyFillNode->node.pConditions;
pInfo->pColMatchColInfo = pColMatchColInfo; pInfo->pColMatchColInfo = pColMatchColInfo;
pOperator->name = "FillOperator"; pOperator->name = "FillOperator";
...@@ -3701,7 +3759,7 @@ SOperatorInfo* createFillOperatorInfo(SOperatorInfo* downstream, SFillPhysiNode* ...@@ -3701,7 +3759,7 @@ SOperatorInfo* createFillOperatorInfo(SOperatorInfo* downstream, SFillPhysiNode*
pOperator->status = OP_NOT_OPENED; pOperator->status = OP_NOT_OPENED;
pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_FILL; pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_FILL;
pOperator->exprSupp.pExprInfo = pExprInfo; pOperator->exprSupp.pExprInfo = pExprInfo;
pOperator->exprSupp.numOfExprs = num; pOperator->exprSupp.numOfExprs = pInfo->numOfExpr;
pOperator->info = pInfo; pOperator->info = pInfo;
pOperator->pTaskInfo = pTaskInfo; pOperator->pTaskInfo = pTaskInfo;
......
此差异已折叠。
...@@ -2675,10 +2675,8 @@ SOperatorInfo* createTimeSliceOperatorInfo(SOperatorInfo* downstream, SPhysiNode ...@@ -2675,10 +2675,8 @@ SOperatorInfo* createTimeSliceOperatorInfo(SOperatorInfo* downstream, SPhysiNode
pInfo->fillType = convertFillType(pInterpPhyNode->fillMode); pInfo->fillType = convertFillType(pInterpPhyNode->fillMode);
initResultSizeInfo(&pOperator->resultInfo, 4096); initResultSizeInfo(&pOperator->resultInfo, 4096);
pInfo->pPrevRow = NULL; pInfo->pFillColInfo = createFillColInfo(pExprInfo, numOfExprs, NULL, 0, (SNodeListNode*)pInterpPhyNode->pFillValues);
pInfo->pNextRow = NULL;
pInfo->pLinearInfo = NULL; pInfo->pLinearInfo = NULL;
pInfo->pFillColInfo = createFillColInfo(pExprInfo, numOfExprs, (SNodeListNode*)pInterpPhyNode->pFillValues);
pInfo->pRes = createResDataBlock(pPhyNode->pOutputDataBlockDesc); pInfo->pRes = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
pInfo->win = pInterpPhyNode->timeRange; pInfo->win = pInterpPhyNode->timeRange;
pInfo->interval.interval = pInterpPhyNode->interval; pInfo->interval.interval = pInterpPhyNode->interval;
......
...@@ -451,6 +451,8 @@ static int32_t logicWindowCopy(const SWindowLogicNode* pSrc, SWindowLogicNode* p ...@@ -451,6 +451,8 @@ static int32_t logicWindowCopy(const SWindowLogicNode* pSrc, SWindowLogicNode* p
static int32_t logicFillCopy(const SFillLogicNode* pSrc, SFillLogicNode* pDst) { static int32_t logicFillCopy(const SFillLogicNode* pSrc, SFillLogicNode* pDst) {
COPY_BASE_OBJECT_FIELD(node, logicNodeCopy); COPY_BASE_OBJECT_FIELD(node, logicNodeCopy);
COPY_SCALAR_FIELD(mode); COPY_SCALAR_FIELD(mode);
CLONE_NODE_LIST_FIELD(pFillExprs);
CLONE_NODE_LIST_FIELD(pNotFillExprs);
CLONE_NODE_FIELD(pWStartTs); CLONE_NODE_FIELD(pWStartTs);
CLONE_NODE_FIELD(pValues); CLONE_NODE_FIELD(pValues);
COPY_OBJECT_FIELD(timeRange, sizeof(STimeWindow)); COPY_OBJECT_FIELD(timeRange, sizeof(STimeWindow));
......
...@@ -2086,9 +2086,10 @@ static int32_t jsonToPhysiIntervalNode(const SJson* pJson, void* pObj) { ...@@ -2086,9 +2086,10 @@ static int32_t jsonToPhysiIntervalNode(const SJson* pJson, void* pObj) {
} }
static const char* jkFillPhysiPlanMode = "Mode"; static const char* jkFillPhysiPlanMode = "Mode";
static const char* jkFillPhysiPlanFillExprs = "FillExprs";
static const char* jkFillPhysiPlanNotFillExprs = "NotFillExprs";
static const char* jkFillPhysiPlanWStartTs = "WStartTs"; static const char* jkFillPhysiPlanWStartTs = "WStartTs";
static const char* jkFillPhysiPlanValues = "Values"; static const char* jkFillPhysiPlanValues = "Values";
static const char* jkFillPhysiPlanTargets = "Targets";
static const char* jkFillPhysiPlanStartTime = "StartTime"; static const char* jkFillPhysiPlanStartTime = "StartTime";
static const char* jkFillPhysiPlanEndTime = "EndTime"; static const char* jkFillPhysiPlanEndTime = "EndTime";
static const char* jkFillPhysiPlanInputTsOrder = "inputTsOrder"; static const char* jkFillPhysiPlanInputTsOrder = "inputTsOrder";
...@@ -2101,13 +2102,16 @@ static int32_t physiFillNodeToJson(const void* pObj, SJson* pJson) { ...@@ -2101,13 +2102,16 @@ static int32_t physiFillNodeToJson(const void* pObj, SJson* pJson) {
code = tjsonAddIntegerToObject(pJson, jkFillPhysiPlanMode, pNode->mode); code = tjsonAddIntegerToObject(pJson, jkFillPhysiPlanMode, pNode->mode);
} }
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddObject(pJson, jkFillPhysiPlanWStartTs, nodeToJson, pNode->pWStartTs); code = nodeListToJson(pJson, jkFillPhysiPlanFillExprs, pNode->pFillExprs);
} }
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddObject(pJson, jkFillPhysiPlanValues, nodeToJson, pNode->pValues); code = nodeListToJson(pJson, jkFillPhysiPlanNotFillExprs, pNode->pNotFillExprs);
} }
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
code = nodeListToJson(pJson, jkFillPhysiPlanTargets, pNode->pTargets); code = tjsonAddObject(pJson, jkFillPhysiPlanWStartTs, nodeToJson, pNode->pWStartTs);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddObject(pJson, jkFillPhysiPlanValues, nodeToJson, pNode->pValues);
} }
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddIntegerToObject(pJson, jkFillPhysiPlanStartTime, pNode->timeRange.skey); code = tjsonAddIntegerToObject(pJson, jkFillPhysiPlanStartTime, pNode->timeRange.skey);
...@@ -2128,16 +2132,18 @@ static int32_t jsonToPhysiFillNode(const SJson* pJson, void* pObj) { ...@@ -2128,16 +2132,18 @@ static int32_t jsonToPhysiFillNode(const SJson* pJson, void* pObj) {
int32_t code = jsonToPhysicPlanNode(pJson, pObj); int32_t code = jsonToPhysicPlanNode(pJson, pObj);
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
tjsonGetNumberValue(pJson, jkFillPhysiPlanMode, pNode->mode, code); tjsonGetNumberValue(pJson, jkFillPhysiPlanMode, pNode->mode, code);
;
} }
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
code = jsonToNodeObject(pJson, jkFillPhysiPlanWStartTs, &pNode->pWStartTs); code = jsonToNodeList(pJson, jkFillPhysiPlanFillExprs, &pNode->pFillExprs);
} }
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
code = jsonToNodeObject(pJson, jkFillPhysiPlanValues, &pNode->pValues); code = jsonToNodeList(pJson, jkFillPhysiPlanNotFillExprs, &pNode->pNotFillExprs);
}
if (TSDB_CODE_SUCCESS == code) {
code = jsonToNodeObject(pJson, jkFillPhysiPlanWStartTs, &pNode->pWStartTs);
} }
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
code = jsonToNodeList(pJson, jkFillPhysiPlanTargets, &pNode->pTargets); code = jsonToNodeObject(pJson, jkFillPhysiPlanValues, &pNode->pValues);
} }
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetBigIntValue(pJson, jkFillPhysiPlanStartTime, &pNode->timeRange.skey); code = tjsonGetBigIntValue(pJson, jkFillPhysiPlanStartTime, &pNode->timeRange.skey);
......
...@@ -346,6 +346,7 @@ void nodesWalkSelectStmt(SSelectStmt* pSelect, ESqlClause clause, FNodeWalker wa ...@@ -346,6 +346,7 @@ void nodesWalkSelectStmt(SSelectStmt* pSelect, ESqlClause clause, FNodeWalker wa
if (NULL != pSelect->pWindow && QUERY_NODE_INTERVAL_WINDOW == nodeType(pSelect->pWindow)) { if (NULL != pSelect->pWindow && QUERY_NODE_INTERVAL_WINDOW == nodeType(pSelect->pWindow)) {
nodesWalkExpr(((SIntervalWindowNode*)pSelect->pWindow)->pFill, walker, pContext); nodesWalkExpr(((SIntervalWindowNode*)pSelect->pWindow)->pFill, walker, pContext);
} }
case SQL_CLAUSE_FILL:
nodesWalkExprs(pSelect->pGroupByList, walker, pContext); nodesWalkExprs(pSelect->pGroupByList, walker, pContext);
case SQL_CLAUSE_GROUP_BY: case SQL_CLAUSE_GROUP_BY:
nodesWalkExpr(pSelect->pHaving, walker, pContext); nodesWalkExpr(pSelect->pHaving, walker, pContext);
...@@ -379,6 +380,7 @@ void nodesRewriteSelectStmt(SSelectStmt* pSelect, ESqlClause clause, FNodeRewrit ...@@ -379,6 +380,7 @@ void nodesRewriteSelectStmt(SSelectStmt* pSelect, ESqlClause clause, FNodeRewrit
if (NULL != pSelect->pWindow && QUERY_NODE_INTERVAL_WINDOW == nodeType(pSelect->pWindow)) { if (NULL != pSelect->pWindow && QUERY_NODE_INTERVAL_WINDOW == nodeType(pSelect->pWindow)) {
nodesRewriteExpr(&(((SIntervalWindowNode*)pSelect->pWindow)->pFill), rewriter, pContext); nodesRewriteExpr(&(((SIntervalWindowNode*)pSelect->pWindow)->pFill), rewriter, pContext);
} }
case SQL_CLAUSE_FILL:
nodesRewriteExprs(pSelect->pGroupByList, rewriter, pContext); nodesRewriteExprs(pSelect->pGroupByList, rewriter, pContext);
case SQL_CLAUSE_GROUP_BY: case SQL_CLAUSE_GROUP_BY:
nodesRewriteExpr(&(pSelect->pHaving), rewriter, pContext); nodesRewriteExpr(&(pSelect->pHaving), rewriter, pContext);
......
...@@ -931,9 +931,10 @@ void nodesDestroyNode(SNode* pNode) { ...@@ -931,9 +931,10 @@ void nodesDestroyNode(SNode* pNode) {
case QUERY_NODE_PHYSICAL_PLAN_FILL: { case QUERY_NODE_PHYSICAL_PLAN_FILL: {
SFillPhysiNode* pPhyNode = (SFillPhysiNode*)pNode; SFillPhysiNode* pPhyNode = (SFillPhysiNode*)pNode;
destroyPhysiNode((SPhysiNode*)pPhyNode); destroyPhysiNode((SPhysiNode*)pPhyNode);
nodesDestroyList(pPhyNode->pFillExprs);
nodesDestroyList(pPhyNode->pNotFillExprs);
nodesDestroyNode(pPhyNode->pWStartTs); nodesDestroyNode(pPhyNode->pWStartTs);
nodesDestroyNode(pPhyNode->pValues); nodesDestroyNode(pPhyNode->pValues);
nodesDestroyList(pPhyNode->pTargets);
break; break;
} }
case QUERY_NODE_PHYSICAL_PLAN_MERGE_SESSION: case QUERY_NODE_PHYSICAL_PLAN_MERGE_SESSION:
......
...@@ -38,6 +38,27 @@ typedef struct SRewriteExprCxt { ...@@ -38,6 +38,27 @@ typedef struct SRewriteExprCxt {
SNodeList* pExprs; SNodeList* pExprs;
} SRewriteExprCxt; } SRewriteExprCxt;
static void setColumnInfo(SFunctionNode* pFunc, SColumnNode* pCol) {
switch (pFunc->funcType) {
case FUNCTION_TYPE_TBNAME:
pCol->colType = COLUMN_TYPE_TBNAME;
break;
case FUNCTION_TYPE_WSTART:
case FUNCTION_TYPE_WEND:
pCol->colId = PRIMARYKEY_TIMESTAMP_COL_ID;
pCol->colType = COLUMN_TYPE_WINDOW_PC;
break;
case FUNCTION_TYPE_WDURATION:
pCol->colType = COLUMN_TYPE_WINDOW_PC;
break;
case FUNCTION_TYPE_GROUP_KEY:
pCol->colType = COLUMN_TYPE_GROUP_KEY;
break;
default:
break;
}
}
static EDealRes doRewriteExpr(SNode** pNode, void* pContext) { static EDealRes doRewriteExpr(SNode** pNode, void* pContext) {
switch (nodeType(*pNode)) { switch (nodeType(*pNode)) {
case QUERY_NODE_OPERATOR: case QUERY_NODE_OPERATOR:
...@@ -60,11 +81,7 @@ static EDealRes doRewriteExpr(SNode** pNode, void* pContext) { ...@@ -60,11 +81,7 @@ static EDealRes doRewriteExpr(SNode** pNode, void* pContext) {
strcpy(pCol->node.aliasName, pToBeRewrittenExpr->aliasName); strcpy(pCol->node.aliasName, pToBeRewrittenExpr->aliasName);
strcpy(pCol->colName, ((SExprNode*)pExpr)->aliasName); strcpy(pCol->colName, ((SExprNode*)pExpr)->aliasName);
if (QUERY_NODE_FUNCTION == nodeType(pExpr)) { if (QUERY_NODE_FUNCTION == nodeType(pExpr)) {
if (FUNCTION_TYPE_WSTART == ((SFunctionNode*)pExpr)->funcType) { setColumnInfo((SFunctionNode*)pExpr, pCol);
pCol->colId = PRIMARYKEY_TIMESTAMP_COL_ID;
} else if (FUNCTION_TYPE_TBNAME == ((SFunctionNode*)pExpr)->funcType) {
pCol->colType = COLUMN_TYPE_TBNAME;
}
} }
nodesDestroyNode(*pNode); nodesDestroyNode(*pNode);
*pNode = (SNode*)pCol; *pNode = (SNode*)pCol;
...@@ -764,6 +781,57 @@ static int32_t createWindowLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSele ...@@ -764,6 +781,57 @@ static int32_t createWindowLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSele
return TSDB_CODE_FAILED; return TSDB_CODE_FAILED;
} }
static EDealRes needFillValueImpl(SNode* pNode, void* pContext) {
if (QUERY_NODE_COLUMN == nodeType(pNode)) {
SColumnNode* pCol = (SColumnNode*)pNode;
if (COLUMN_TYPE_WINDOW_PC != pCol->colType && COLUMN_TYPE_GROUP_KEY != pCol->colType) {
*(bool*)pContext = true;
return DEAL_RES_END;
}
}
return DEAL_RES_CONTINUE;
}
static bool needFillValue(SNode* pNode) {
bool hasFillCol = false;
nodesWalkExpr(pNode, needFillValueImpl, &hasFillCol);
return hasFillCol;
}
static int32_t partFillExprs(SSelectStmt* pSelect, SNodeList** pFillExprs, SNodeList** pNotFillExprs) {
int32_t code = TSDB_CODE_SUCCESS;
SNode* pProject = NULL;
FOREACH(pProject, pSelect->pProjectionList) {
if (needFillValue(pProject)) {
code = nodesListMakeStrictAppend(pFillExprs, nodesCloneNode(pProject));
} else if (QUERY_NODE_VALUE != nodeType(pProject)) {
code = nodesListMakeStrictAppend(pNotFillExprs, nodesCloneNode(pProject));
}
if (TSDB_CODE_SUCCESS != code) {
NODES_DESTORY_LIST(*pFillExprs);
NODES_DESTORY_LIST(*pNotFillExprs);
break;
}
}
if (!pSelect->isDistinct) {
SNode* pOrderExpr = NULL;
FOREACH(pOrderExpr, pSelect->pOrderByList) {
SNode* pExpr = ((SOrderByExprNode*)pOrderExpr)->pExpr;
if (needFillValue(pExpr)) {
code = nodesListMakeStrictAppend(pFillExprs, nodesCloneNode(pExpr));
} else if (QUERY_NODE_VALUE != nodeType(pExpr)) {
code = nodesListMakeStrictAppend(pNotFillExprs, nodesCloneNode(pExpr));
}
if (TSDB_CODE_SUCCESS != code) {
NODES_DESTORY_LIST(*pFillExprs);
NODES_DESTORY_LIST(*pNotFillExprs);
break;
}
}
}
return code;
}
static int32_t createFillLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) { static int32_t createFillLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) {
if (NULL == pSelect->pWindow || QUERY_NODE_INTERVAL_WINDOW != nodeType(pSelect->pWindow) || if (NULL == pSelect->pWindow || QUERY_NODE_INTERVAL_WINDOW != nodeType(pSelect->pWindow) ||
NULL == ((SIntervalWindowNode*)pSelect->pWindow)->pFill) { NULL == ((SIntervalWindowNode*)pSelect->pWindow)->pFill) {
...@@ -785,10 +853,18 @@ static int32_t createFillLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect ...@@ -785,10 +853,18 @@ static int32_t createFillLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect
pFill->node.resultDataOrder = pFill->node.requireDataOrder; pFill->node.resultDataOrder = pFill->node.requireDataOrder;
pFill->inputTsOrder = ORDER_ASC; pFill->inputTsOrder = ORDER_ASC;
int32_t code = nodesCollectColumns(pSelect, SQL_CLAUSE_WINDOW, NULL, COLLECT_COL_TYPE_ALL, &pFill->node.pTargets); int32_t code = partFillExprs(pSelect, &pFill->pFillExprs, &pFill->pNotFillExprs);
if (TSDB_CODE_SUCCESS == code && NULL == pFill->node.pTargets) { if (TSDB_CODE_SUCCESS == code) {
code = nodesListMakeStrictAppend(&pFill->node.pTargets, code = rewriteExprsForSelect(pFill->pFillExprs, pSelect, SQL_CLAUSE_FILL);
nodesCloneNode(nodesListGetNode(pCxt->pCurrRoot->pTargets, 0))); }
if (TSDB_CODE_SUCCESS == code) {
code = rewriteExprsForSelect(pFill->pNotFillExprs, pSelect, SQL_CLAUSE_FILL);
}
if (TSDB_CODE_SUCCESS == code) {
code = createColumnByRewriteExprs(pFill->pFillExprs, &pFill->node.pTargets);
}
if (TSDB_CODE_SUCCESS == code) {
code = createColumnByRewriteExprs(pFill->pNotFillExprs, &pFill->node.pTargets);
} }
pFill->mode = pFillNode->mode; pFill->mode = pFillNode->mode;
......
...@@ -195,7 +195,7 @@ static int32_t addDataBlockSlotsImpl(SPhysiPlanContext* pCxt, SNodeList* pList, ...@@ -195,7 +195,7 @@ static int32_t addDataBlockSlotsImpl(SPhysiPlanContext* pCxt, SNodeList* pList,
int32_t code = TSDB_CODE_SUCCESS; int32_t code = TSDB_CODE_SUCCESS;
SHashObj* pHash = taosArrayGetP(pCxt->pLocationHelper, pDataBlockDesc->dataBlockId); SHashObj* pHash = taosArrayGetP(pCxt->pLocationHelper, pDataBlockDesc->dataBlockId);
int16_t nextSlotId = taosHashGetSize(pHash), slotId = 0; int16_t nextSlotId = LIST_LENGTH(pDataBlockDesc->pSlots), slotId = 0;
SNode* pNode = NULL; SNode* pNode = NULL;
FOREACH(pNode, pList) { FOREACH(pNode, pList) {
SNode* pExpr = QUERY_NODE_ORDER_BY_EXPR == nodeType(pNode) ? ((SOrderByExprNode*)pNode)->pExpr : pNode; SNode* pExpr = QUERY_NODE_ORDER_BY_EXPR == nodeType(pNode) ? ((SOrderByExprNode*)pNode)->pExpr : pNode;
...@@ -311,6 +311,10 @@ static EDealRes doSetSlotId(SNode* pNode, void* pContext) { ...@@ -311,6 +311,10 @@ static EDealRes doSetSlotId(SNode* pNode, void* pContext) {
static int32_t setNodeSlotId(SPhysiPlanContext* pCxt, int16_t leftDataBlockId, int16_t rightDataBlockId, SNode* pNode, static int32_t setNodeSlotId(SPhysiPlanContext* pCxt, int16_t leftDataBlockId, int16_t rightDataBlockId, SNode* pNode,
SNode** pOutput) { SNode** pOutput) {
if (NULL == pNode) {
return TSDB_CODE_SUCCESS;
}
SNode* pRes = nodesCloneNode(pNode); SNode* pRes = nodesCloneNode(pNode);
if (NULL == pRes) { if (NULL == pRes) {
return TSDB_CODE_OUT_OF_MEMORY; return TSDB_CODE_OUT_OF_MEMORY;
...@@ -332,6 +336,10 @@ static int32_t setNodeSlotId(SPhysiPlanContext* pCxt, int16_t leftDataBlockId, i ...@@ -332,6 +336,10 @@ static int32_t setNodeSlotId(SPhysiPlanContext* pCxt, int16_t leftDataBlockId, i
static int32_t setListSlotId(SPhysiPlanContext* pCxt, int16_t leftDataBlockId, int16_t rightDataBlockId, static int32_t setListSlotId(SPhysiPlanContext* pCxt, int16_t leftDataBlockId, int16_t rightDataBlockId,
const SNodeList* pList, SNodeList** pOutput) { const SNodeList* pList, SNodeList** pOutput) {
if (NULL == pList) {
return TSDB_CODE_SUCCESS;
}
SNodeList* pRes = nodesCloneList(pList); SNodeList* pRes = nodesCloneList(pList);
if (NULL == pRes) { if (NULL == pRes) {
return TSDB_CODE_OUT_OF_MEMORY; return TSDB_CODE_OUT_OF_MEMORY;
...@@ -1372,14 +1380,23 @@ static int32_t createFillPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren ...@@ -1372,14 +1380,23 @@ static int32_t createFillPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren
pFill->inputTsOrder = pFillNode->inputTsOrder; pFill->inputTsOrder = pFillNode->inputTsOrder;
SDataBlockDescNode* pChildTupe = (((SPhysiNode*)nodesListGetNode(pChildren, 0))->pOutputDataBlockDesc); SDataBlockDescNode* pChildTupe = (((SPhysiNode*)nodesListGetNode(pChildren, 0))->pOutputDataBlockDesc);
int32_t code = setListSlotId(pCxt, pChildTupe->dataBlockId, -1, pFillNode->node.pTargets, &pFill->pTargets); int32_t code = setListSlotId(pCxt, pChildTupe->dataBlockId, -1, pFillNode->pFillExprs, &pFill->pFillExprs);
if (TSDB_CODE_SUCCESS == code) {
code = addDataBlockSlots(pCxt, pFill->pFillExprs, pFill->node.pOutputDataBlockDesc);
}
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
code = addDataBlockSlots(pCxt, pFill->pTargets, pFill->node.pOutputDataBlockDesc); code = setListSlotId(pCxt, pChildTupe->dataBlockId, -1, pFillNode->pNotFillExprs, &pFill->pNotFillExprs);
}
if (TSDB_CODE_SUCCESS == code) {
code = addDataBlockSlots(pCxt, pFill->pNotFillExprs, pFill->node.pOutputDataBlockDesc);
} }
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
code = setNodeSlotId(pCxt, pChildTupe->dataBlockId, -1, pFillNode->pWStartTs, &pFill->pWStartTs); code = setNodeSlotId(pCxt, pChildTupe->dataBlockId, -1, pFillNode->pWStartTs, &pFill->pWStartTs);
} }
if (TSDB_CODE_SUCCESS == code) {
code = addDataBlockSlot(pCxt, &pFill->pWStartTs, pFill->node.pOutputDataBlockDesc);
}
if (TSDB_CODE_SUCCESS == code && NULL != pFillNode->pValues) { if (TSDB_CODE_SUCCESS == code && NULL != pFillNode->pValues) {
pFill->pValues = nodesCloneNode(pFillNode->pValues); pFill->pValues = nodesCloneNode(pFillNode->pValues);
......
...@@ -45,8 +45,15 @@ TEST_F(PlanIntervalTest, fill) { ...@@ -45,8 +45,15 @@ TEST_F(PlanIntervalTest, fill) {
"WHERE ts > TIMESTAMP '2022-04-01 00:00:00' and ts < TIMESTAMP '2022-04-30 23:59:59' " "WHERE ts > TIMESTAMP '2022-04-01 00:00:00' and ts < TIMESTAMP '2022-04-30 23:59:59' "
"INTERVAL(10s) FILL(VALUE, 10, 20)"); "INTERVAL(10s) FILL(VALUE, 10, 20)");
run("SELECT COUNT(*) FROM st1 WHERE ts > TIMESTAMP '2022-04-01 00:00:00' and ts < TIMESTAMP '2022-04-30 23:59:59' " run("SELECT _WSTART, TBNAME, COUNT(*) FROM st1 "
"PARTITION BY TBNAME interval(10s) fill(prev)"); "WHERE ts > '2022-04-01 00:00:00' and ts < '2022-04-30 23:59:59' "
"PARTITION BY TBNAME INTERVAL(10s) FILL(PREV)");
run("SELECT COUNT(c1), MAX(c3), COUNT(c1) FROM t1 "
"WHERE ts > '2022-04-01 00:00:00' and ts < '2022-04-30 23:59:59' INTERVAL(10s) FILL(PREV)");
run("SELECT COUNT(c1) FROM t1 WHERE ts > '2022-04-01 00:00:00' and ts < '2022-04-30 23:59:59' "
"PARTITION BY c2 INTERVAL(10s) FILL(PREV) ORDER BY c2");
} }
TEST_F(PlanIntervalTest, selectFunc) { TEST_F(PlanIntervalTest, selectFunc) {
......
...@@ -467,7 +467,6 @@ TAOS_DEFINE_ERROR(TSDB_CODE_FS_APP_ERROR, "tfs out of memory") ...@@ -467,7 +467,6 @@ TAOS_DEFINE_ERROR(TSDB_CODE_FS_APP_ERROR, "tfs out of memory")
TAOS_DEFINE_ERROR(TSDB_CODE_CTG_INTERNAL_ERROR, "catalog internal error") TAOS_DEFINE_ERROR(TSDB_CODE_CTG_INTERNAL_ERROR, "catalog internal error")
TAOS_DEFINE_ERROR(TSDB_CODE_CTG_INVALID_INPUT, "invalid catalog input parameters") TAOS_DEFINE_ERROR(TSDB_CODE_CTG_INVALID_INPUT, "invalid catalog input parameters")
TAOS_DEFINE_ERROR(TSDB_CODE_CTG_NOT_READY, "catalog is not ready") TAOS_DEFINE_ERROR(TSDB_CODE_CTG_NOT_READY, "catalog is not ready")
TAOS_DEFINE_ERROR(TSDB_CODE_OUT_OF_MEMORY, "catalog memory error")
TAOS_DEFINE_ERROR(TSDB_CODE_CTG_SYS_ERROR, "catalog system error") TAOS_DEFINE_ERROR(TSDB_CODE_CTG_SYS_ERROR, "catalog system error")
TAOS_DEFINE_ERROR(TSDB_CODE_CTG_DB_DROPPED, "Database is dropped") TAOS_DEFINE_ERROR(TSDB_CODE_CTG_DB_DROPPED, "Database is dropped")
TAOS_DEFINE_ERROR(TSDB_CODE_CTG_OUT_OF_SERVICE, "catalog is out of service") TAOS_DEFINE_ERROR(TSDB_CODE_CTG_OUT_OF_SERVICE, "catalog is out of service")
......
...@@ -885,15 +885,15 @@ if $data10 != @20-01-01 01:01:10.000@ then ...@@ -885,15 +885,15 @@ if $data10 != @20-01-01 01:01:10.000@ then
return -1 return -1
endi endi
if $data11 != 1.000000000 then if $data11 != 99.000000000 then
return -1 return -1
endi endi
if $data12 != 1.000000000 then if $data12 != 91.000000000 then
return -1 return -1
endi endi
if $data13 != -87.000000000 then if $data13 != 90.000000000 then
return -1 return -1
endi endi
...@@ -917,15 +917,15 @@ if $data70 != @20-01-01 01:02:10.000@ then ...@@ -917,15 +917,15 @@ if $data70 != @20-01-01 01:02:10.000@ then
return -1 return -1
endi endi
if $data71 != 1.000000000 then if $data71 != 99.000000000 then
return -1 return -1
endi endi
if $data72 != 1.000000000 then if $data72 != 91.000000000 then
return -1 return -1
endi endi
if $data73 != -87.000000000 then if $data73 != 90.000000000 then
return -1 return -1
endi endi
...@@ -994,19 +994,19 @@ if $data10 != @20-01-01 01:01:10.000@ then ...@@ -994,19 +994,19 @@ if $data10 != @20-01-01 01:01:10.000@ then
return -1 return -1
endi endi
if $data11 != 1.000000000 then if $data11 != 99.000000000 then
return -1 return -1
endi endi
if $data12 != 1.000000000 then if $data12 != 91.000000000 then
return -1 return -1
endi endi
if $data13 != -87.000000000 then if $data13 != 90.000000000 then
return -1 return -1
endi endi
if $data14 != 86 then if $data14 != 89 then
return -1 return -1
endi endi
......
...@@ -111,13 +111,15 @@ endi ...@@ -111,13 +111,15 @@ endi
if $data12 != -2 then if $data12 != -2 then
return -1 return -1
endi endi
if $data13 != -3.00000 then if $data13 != -3 then
return -1 return -1
endi endi
if $data14 != -4.000000000 then if $data14 != -4.00000 then
print expect -4.00000, actual: $data14
return -1 return -1
endi endi
if $data15 != -5 then if $data15 != -5.000000000 then
print expect -5.000000000, actual: $data15
return -1 return -1
endi endi
if $data31 != -1 then if $data31 != -1 then
...@@ -126,10 +128,10 @@ endi ...@@ -126,10 +128,10 @@ endi
if $data52 != -2 then if $data52 != -2 then
return -1 return -1
endi endi
if $data73 != -3.00000 then if $data73 != -3 then
return -1 return -1
endi endi
if $data74 != -4.000000000 then if $data74 != -4.00000 then
return -1 return -1
endi endi
......
...@@ -1010,6 +1010,7 @@ if $data31 != 9.000000000 then ...@@ -1010,6 +1010,7 @@ if $data31 != 9.000000000 then
return -1 return -1
endi endi
if $data41 != 12.500000000 then if $data41 != 12.500000000 then
print expect 12.500000000, actual: $data41
return -1 return -1
endi endi
if $data51 != 16.000000000 then if $data51 != 16.000000000 then
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册