fix:[TS-5839] Fix crash when use last function on a column with all null value with partition subclause.
This commit is contained in:
parent
f9c8b6cd7b
commit
64bb49e0db
|
@ -110,6 +110,8 @@ typedef struct SFirstLastRes {
|
||||||
int32_t pkBytes;
|
int32_t pkBytes;
|
||||||
int8_t pkType;
|
int8_t pkType;
|
||||||
STuplePos pos;
|
STuplePos pos;
|
||||||
|
STuplePos nullTuplePos;
|
||||||
|
bool nullTupleSaved;
|
||||||
char buf[];
|
char buf[];
|
||||||
} SFirstLastRes;
|
} SFirstLastRes;
|
||||||
|
|
||||||
|
|
|
@ -152,6 +152,7 @@ int32_t getIrateInfoSize(int32_t pkBytes);
|
||||||
int32_t cachedLastRowFunction(SqlFunctionCtx* pCtx);
|
int32_t cachedLastRowFunction(SqlFunctionCtx* pCtx);
|
||||||
|
|
||||||
bool getFirstLastFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
|
bool getFirstLastFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
|
||||||
|
int32_t firstLastFunctionSetup(SqlFunctionCtx* pCtx, SResultRowEntryInfo* pResultInfo);
|
||||||
int32_t firstFunction(SqlFunctionCtx* pCtx);
|
int32_t firstFunction(SqlFunctionCtx* pCtx);
|
||||||
int32_t firstFunctionMerge(SqlFunctionCtx* pCtx);
|
int32_t firstFunctionMerge(SqlFunctionCtx* pCtx);
|
||||||
int32_t lastFunction(SqlFunctionCtx* pCtx);
|
int32_t lastFunction(SqlFunctionCtx* pCtx);
|
||||||
|
|
|
@ -3469,7 +3469,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||||
.translateFunc = translateFirstLast,
|
.translateFunc = translateFirstLast,
|
||||||
.dynDataRequiredFunc = lastDynDataReq,
|
.dynDataRequiredFunc = lastDynDataReq,
|
||||||
.getEnvFunc = getFirstLastFuncEnv,
|
.getEnvFunc = getFirstLastFuncEnv,
|
||||||
.initFunc = functionSetup,
|
.initFunc = firstLastFunctionSetup,
|
||||||
.processFunc = lastFunction,
|
.processFunc = lastFunction,
|
||||||
.sprocessFunc = firstLastScalarFunction,
|
.sprocessFunc = firstLastScalarFunction,
|
||||||
.finalizeFunc = firstLastFinalize,
|
.finalizeFunc = firstLastFinalize,
|
||||||
|
|
|
@ -2617,6 +2617,22 @@ static FORCE_INLINE TSKEY getRowPTs(SColumnInfoData* pTsColInfo, int32_t rowInde
|
||||||
return *(TSKEY*)colDataGetData(pTsColInfo, rowIndex);
|
return *(TSKEY*)colDataGetData(pTsColInfo, rowIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t firstLastFunctionSetup(SqlFunctionCtx* pCtx, SResultRowEntryInfo* pResInfo) {
|
||||||
|
if (pResInfo->initialized) {
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS != functionSetup(pCtx, pResInfo)) {
|
||||||
|
return TSDB_CODE_FUNC_SETUP_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
SFirstLastRes * pRes = GET_ROWCELL_INTERBUF(pResInfo);
|
||||||
|
SInputColumnInfoData* pInput = &pCtx->input;
|
||||||
|
|
||||||
|
pRes->nullTupleSaved = false;
|
||||||
|
pRes->nullTuplePos.pageId = -1;
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t prepareBuf(SqlFunctionCtx* pCtx) {
|
static int32_t prepareBuf(SqlFunctionCtx* pCtx) {
|
||||||
if (pCtx->subsidiaries.rowLen == 0) {
|
if (pCtx->subsidiaries.rowLen == 0) {
|
||||||
int32_t rowLen = 0;
|
int32_t rowLen = 0;
|
||||||
|
@ -2635,7 +2651,7 @@ static int32_t prepareBuf(SqlFunctionCtx* pCtx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t firstlastSaveTupleData(const SSDataBlock* pSrcBlock, int32_t rowIndex, SqlFunctionCtx* pCtx,
|
static int32_t firstlastSaveTupleData(const SSDataBlock* pSrcBlock, int32_t rowIndex, SqlFunctionCtx* pCtx,
|
||||||
SFirstLastRes* pInfo) {
|
SFirstLastRes* pInfo, bool noElements) {
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
|
||||||
if (pCtx->subsidiaries.num <= 0) {
|
if (pCtx->subsidiaries.num <= 0) {
|
||||||
|
@ -2643,7 +2659,7 @@ static int32_t firstlastSaveTupleData(const SSDataBlock* pSrcBlock, int32_t rowI
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pInfo->hasResult) {
|
if (!pInfo->hasResult) {
|
||||||
code = saveTupleData(pCtx, rowIndex, pSrcBlock, &pInfo->pos);
|
code = saveTupleData(pCtx, rowIndex, pSrcBlock, noElements ? &pInfo->nullTuplePos : &pInfo->pos);
|
||||||
} else {
|
} else {
|
||||||
code = updateTupleData(pCtx, rowIndex, pSrcBlock, &pInfo->pos);
|
code = updateTupleData(pCtx, rowIndex, pSrcBlock, &pInfo->pos);
|
||||||
}
|
}
|
||||||
|
@ -2669,7 +2685,7 @@ static int32_t doSaveCurrentVal(SqlFunctionCtx* pCtx, int32_t rowIndex, int64_t
|
||||||
}
|
}
|
||||||
|
|
||||||
pInfo->ts = currentTs;
|
pInfo->ts = currentTs;
|
||||||
int32_t code = firstlastSaveTupleData(pCtx->pSrcBlock, rowIndex, pCtx, pInfo);
|
int32_t code = firstlastSaveTupleData(pCtx->pSrcBlock, rowIndex, pCtx, pInfo, false);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -2708,10 +2724,11 @@ int32_t firstFunction(SqlFunctionCtx* pCtx) {
|
||||||
if (pInput->colDataSMAIsSet && (pInput->pColumnDataAgg[0]->numOfNull == pInput->totalRows) &&
|
if (pInput->colDataSMAIsSet && (pInput->pColumnDataAgg[0]->numOfNull == pInput->totalRows) &&
|
||||||
pInputCol->hasNull == true) {
|
pInputCol->hasNull == true) {
|
||||||
// save selectivity value for column consisted of all null values
|
// save selectivity value for column consisted of all null values
|
||||||
int32_t code = firstlastSaveTupleData(pCtx->pSrcBlock, pInput->startRowIndex, pCtx, pInfo);
|
int32_t code = firstlastSaveTupleData(pCtx->pSrcBlock, pInput->startRowIndex, pCtx, pInfo, !pInfo->nullTupleSaved);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
pInfo->nullTupleSaved = true;
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2802,10 +2819,11 @@ int32_t firstFunction(SqlFunctionCtx* pCtx) {
|
||||||
|
|
||||||
if (numOfElems == 0) {
|
if (numOfElems == 0) {
|
||||||
// save selectivity value for column consisted of all null values
|
// save selectivity value for column consisted of all null values
|
||||||
int32_t code = firstlastSaveTupleData(pCtx->pSrcBlock, pInput->startRowIndex, pCtx, pInfo);
|
int32_t code = firstlastSaveTupleData(pCtx->pSrcBlock, pInput->startRowIndex, pCtx, pInfo, !pInfo->nullTupleSaved);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
pInfo->nullTupleSaved = true;
|
||||||
}
|
}
|
||||||
SET_VAL(pResInfo, numOfElems, 1);
|
SET_VAL(pResInfo, numOfElems, 1);
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
@ -2841,10 +2859,11 @@ int32_t lastFunction(SqlFunctionCtx* pCtx) {
|
||||||
if (pInput->colDataSMAIsSet && (pInput->pColumnDataAgg[0]->numOfNull == pInput->totalRows) &&
|
if (pInput->colDataSMAIsSet && (pInput->pColumnDataAgg[0]->numOfNull == pInput->totalRows) &&
|
||||||
pInputCol->hasNull == true) {
|
pInputCol->hasNull == true) {
|
||||||
// save selectivity value for column consisted of all null values
|
// save selectivity value for column consisted of all null values
|
||||||
int32_t code = firstlastSaveTupleData(pCtx->pSrcBlock, pInput->startRowIndex, pCtx, pInfo);
|
int32_t code = firstlastSaveTupleData(pCtx->pSrcBlock, pInput->startRowIndex, pCtx, pInfo, !pInfo->nullTupleSaved);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
pInfo->nullTupleSaved = true;
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2983,10 +3002,11 @@ int32_t lastFunction(SqlFunctionCtx* pCtx) {
|
||||||
|
|
||||||
// save selectivity value for column consisted of all null values
|
// save selectivity value for column consisted of all null values
|
||||||
if (numOfElems == 0) {
|
if (numOfElems == 0) {
|
||||||
int32_t code = firstlastSaveTupleData(pCtx->pSrcBlock, pInput->startRowIndex, pCtx, pInfo);
|
int32_t code = firstlastSaveTupleData(pCtx->pSrcBlock, pInput->startRowIndex, pCtx, pInfo, !pInfo->nullTupleSaved);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
pInfo->nullTupleSaved = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
@ -3031,7 +3051,7 @@ static bool firstLastTransferInfoImpl(SFirstLastRes* pInput, SFirstLastRes* pOut
|
||||||
static int32_t firstLastTransferInfo(SqlFunctionCtx* pCtx, SFirstLastRes* pInput, SFirstLastRes* pOutput, bool isFirst,
|
static int32_t firstLastTransferInfo(SqlFunctionCtx* pCtx, SFirstLastRes* pInput, SFirstLastRes* pOutput, bool isFirst,
|
||||||
int32_t rowIndex) {
|
int32_t rowIndex) {
|
||||||
if (firstLastTransferInfoImpl(pInput, pOutput, isFirst)) {
|
if (firstLastTransferInfoImpl(pInput, pOutput, isFirst)) {
|
||||||
int32_t code = firstlastSaveTupleData(pCtx->pSrcBlock, rowIndex, pCtx, pOutput);
|
int32_t code = firstlastSaveTupleData(pCtx->pSrcBlock, rowIndex, pCtx, pOutput, pOutput->nullTupleSaved);
|
||||||
if (TSDB_CODE_SUCCESS != code) {
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -3079,6 +3099,14 @@ static int32_t firstLastFunctionMergeImpl(SqlFunctionCtx* pCtx, bool isFirstQuer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (numOfElems == 0) {
|
||||||
|
int32_t code = firstlastSaveTupleData(pCtx->pSrcBlock, pInput->startRowIndex, pCtx, pInfo, !pInfo->nullTupleSaved);
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
pInfo->nullTupleSaved = true;
|
||||||
|
}
|
||||||
|
|
||||||
SET_VAL(GET_RES_INFO(pCtx), numOfElems, 1);
|
SET_VAL(GET_RES_INFO(pCtx), numOfElems, 1);
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -3099,6 +3127,11 @@ int32_t firstLastFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||||
pResInfo->isNullRes = (pResInfo->numOfRes == 0) ? 1 : 0;
|
pResInfo->isNullRes = (pResInfo->numOfRes == 0) ? 1 : 0;
|
||||||
|
|
||||||
SFirstLastRes* pRes = GET_ROWCELL_INTERBUF(pResInfo);
|
SFirstLastRes* pRes = GET_ROWCELL_INTERBUF(pResInfo);
|
||||||
|
|
||||||
|
if (pResInfo->isNullRes) {
|
||||||
|
colDataSetNULL(pCol, pBlock->info.rows);
|
||||||
|
return setSelectivityValue(pCtx, pBlock, &pRes->nullTuplePos, pBlock->info.rows);
|
||||||
|
}
|
||||||
code = colDataSetVal(pCol, pBlock->info.rows, pRes->buf, pRes->isNull || pResInfo->isNullRes);
|
code = colDataSetVal(pCol, pBlock->info.rows, pRes->buf, pRes->isNull || pResInfo->isNullRes);
|
||||||
if (TSDB_CODE_SUCCESS != code) {
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
return code;
|
return code;
|
||||||
|
@ -3134,12 +3167,16 @@ int32_t firstLastPartialFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||||
return TSDB_CODE_OUT_OF_RANGE;
|
return TSDB_CODE_OUT_OF_RANGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
code = colDataSetVal(pCol, pBlock->info.rows, res, false);
|
if (pEntryInfo->numOfRes == 0) {
|
||||||
if (TSDB_CODE_SUCCESS != code) {
|
colDataSetNULL(pCol, pBlock->info.rows);
|
||||||
return TSDB_CODE_OUT_OF_MEMORY;
|
code = setSelectivityValue(pCtx, pBlock, &pRes->nullTuplePos, pBlock->info.rows);
|
||||||
|
} else {
|
||||||
|
code = colDataSetVal(pCol, pBlock->info.rows, res, false);
|
||||||
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
code = setSelectivityValue(pCtx, pBlock, &pRes->pos, pBlock->info.rows);
|
||||||
}
|
}
|
||||||
code = setSelectivityValue(pCtx, pBlock, &pRes->pos, pBlock->info.rows);
|
|
||||||
|
|
||||||
taosMemoryFree(res);
|
taosMemoryFree(res);
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -3185,7 +3222,7 @@ static int32_t doSaveLastrow(SqlFunctionCtx* pCtx, char* pData, int32_t rowIndex
|
||||||
pInfo->pkData = pInfo->buf + pInfo->bytes;
|
pInfo->pkData = pInfo->buf + pInfo->bytes;
|
||||||
}
|
}
|
||||||
pInfo->ts = cts;
|
pInfo->ts = cts;
|
||||||
int32_t code = firstlastSaveTupleData(pCtx->pSrcBlock, rowIndex, pCtx, pInfo);
|
int32_t code = firstlastSaveTupleData(pCtx->pSrcBlock, rowIndex, pCtx, pInfo, false);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,7 +89,7 @@ if $data10 != @ -> Merge (columns=3 width=24 input_order=unknown output_order=
|
||||||
return -1
|
return -1
|
||||||
endi
|
endi
|
||||||
sql explain select count(*), last_row(f1), min(f1) from sta interval(1s);
|
sql explain select count(*), last_row(f1), min(f1) from sta interval(1s);
|
||||||
if $data10 != @ -> Merge (columns=4 width=82 input_order=asc output_order=asc mode=sort)@ then
|
if $data10 != @ -> Merge (columns=4 width=106 input_order=asc output_order=asc mode=sort)@ then
|
||||||
return -1
|
return -1
|
||||||
endi
|
endi
|
||||||
sql explain select distinct count(*), last_row(f1), min(f1) from tba1;
|
sql explain select distinct count(*), last_row(f1), min(f1) from tba1;
|
||||||
|
|
Loading…
Reference in New Issue