|
|
@ -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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|