enh(query): support sum(NULL), max(NULL), min(NULL)
This commit is contained in:
parent
485a1aedd5
commit
26c618e5ad
|
@ -179,6 +179,8 @@ typedef struct {
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
//TODO: use varchar(0) to represent NULL type
|
||||||
|
#define IS_NULL_TYPE(_t) ((_t) == TSDB_DATA_TYPE_NULL)
|
||||||
#define IS_SIGNED_NUMERIC_TYPE(_t) ((_t) >= TSDB_DATA_TYPE_TINYINT && (_t) <= TSDB_DATA_TYPE_BIGINT)
|
#define IS_SIGNED_NUMERIC_TYPE(_t) ((_t) >= TSDB_DATA_TYPE_TINYINT && (_t) <= TSDB_DATA_TYPE_BIGINT)
|
||||||
#define IS_UNSIGNED_NUMERIC_TYPE(_t) ((_t) >= TSDB_DATA_TYPE_UTINYINT && (_t) <= TSDB_DATA_TYPE_UBIGINT)
|
#define IS_UNSIGNED_NUMERIC_TYPE(_t) ((_t) >= TSDB_DATA_TYPE_UTINYINT && (_t) <= TSDB_DATA_TYPE_UBIGINT)
|
||||||
#define IS_FLOAT_TYPE(_t) ((_t) == TSDB_DATA_TYPE_FLOAT || (_t) == TSDB_DATA_TYPE_DOUBLE)
|
#define IS_FLOAT_TYPE(_t) ((_t) == TSDB_DATA_TYPE_FLOAT || (_t) == TSDB_DATA_TYPE_DOUBLE)
|
||||||
|
|
|
@ -322,8 +322,10 @@ int32_t colDataAssign(SColumnInfoData* pColumnInfoData, const SColumnInfoData* p
|
||||||
}
|
}
|
||||||
|
|
||||||
pColumnInfoData->pData = tmp;
|
pColumnInfoData->pData = tmp;
|
||||||
|
if (pColumnInfoData->info.type != TSDB_DATA_TYPE_NULL) {
|
||||||
memcpy(pColumnInfoData->pData, pSource->pData, pSource->info.bytes * numOfRows);
|
memcpy(pColumnInfoData->pData, pSource->pData, pSource->info.bytes * numOfRows);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pColumnInfoData->hasNull = pSource->hasNull;
|
pColumnInfoData->hasNull = pSource->hasNull;
|
||||||
pColumnInfoData->info = pSource->info;
|
pColumnInfoData->info = pSource->info;
|
||||||
|
|
|
@ -46,8 +46,10 @@ static int32_t translateInOutNum(SFunctionNode* pFunc, char* pErrBuf, int32_t le
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||||
if (!IS_NUMERIC_TYPE(paraType)) {
|
if (!IS_NUMERIC_TYPE(paraType) && !IS_NULL_TYPE(paraType)) {
|
||||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||||
|
} else if (IS_NULL_TYPE(paraType)) {
|
||||||
|
paraType = TSDB_DATA_TYPE_BIGINT;
|
||||||
}
|
}
|
||||||
|
|
||||||
pFunc->node.resType = (SDataType){.bytes = tDataTypes[paraType].bytes, .type = paraType};
|
pFunc->node.resType = (SDataType){.bytes = tDataTypes[paraType].bytes, .type = paraType};
|
||||||
|
@ -114,18 +116,19 @@ static int32_t translateSum(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||||
if (!IS_NUMERIC_TYPE(paraType)) {
|
if (!IS_NUMERIC_TYPE(paraType) && !IS_NULL_TYPE(paraType)) {
|
||||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t resType = 0;
|
uint8_t resType = 0;
|
||||||
if (IS_SIGNED_NUMERIC_TYPE(paraType) || paraType == TSDB_DATA_TYPE_BOOL) {
|
if (IS_SIGNED_NUMERIC_TYPE(paraType) || TSDB_DATA_TYPE_BOOL == paraType || IS_NULL_TYPE(paraType)) {
|
||||||
resType = TSDB_DATA_TYPE_BIGINT;
|
resType = TSDB_DATA_TYPE_BIGINT;
|
||||||
} else if (IS_UNSIGNED_NUMERIC_TYPE(paraType)) {
|
} else if (IS_UNSIGNED_NUMERIC_TYPE(paraType)) {
|
||||||
resType = TSDB_DATA_TYPE_UBIGINT;
|
resType = TSDB_DATA_TYPE_UBIGINT;
|
||||||
} else if (IS_FLOAT_TYPE(paraType)) {
|
} else if (IS_FLOAT_TYPE(paraType)) {
|
||||||
resType = TSDB_DATA_TYPE_DOUBLE;
|
resType = TSDB_DATA_TYPE_DOUBLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
pFunc->node.resType = (SDataType){.bytes = tDataTypes[resType].bytes, .type = resType};
|
pFunc->node.resType = (SDataType){.bytes = tDataTypes[resType].bytes, .type = resType};
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -255,7 +255,7 @@ int32_t functionFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||||
SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, slotId);
|
SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, slotId);
|
||||||
|
|
||||||
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
|
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
|
||||||
pResInfo->isNullRes = (pResInfo->numOfRes == 0) ? 1 : 0;
|
//pResInfo->isNullRes = (pResInfo->numOfRes == 0) ? 1 : 0;
|
||||||
|
|
||||||
char* in = GET_ROWCELL_INTERBUF(pResInfo);
|
char* in = GET_ROWCELL_INTERBUF(pResInfo);
|
||||||
colDataAppend(pCol, pBlock->info.rows, in, pResInfo->isNullRes);
|
colDataAppend(pCol, pBlock->info.rows, in, pResInfo->isNullRes);
|
||||||
|
@ -382,6 +382,12 @@ int32_t sumFunction(SqlFunctionCtx* pCtx) {
|
||||||
|
|
||||||
SSumRes* pSumRes = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
|
SSumRes* pSumRes = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
|
||||||
|
|
||||||
|
if (IS_NULL_TYPE(type)) {
|
||||||
|
GET_RES_INFO(pCtx)->isNullRes = 1;
|
||||||
|
numOfElem = 1;
|
||||||
|
goto _sum_over;
|
||||||
|
}
|
||||||
|
|
||||||
if (pInput->colDataAggIsSet) {
|
if (pInput->colDataAggIsSet) {
|
||||||
numOfElem = pInput->numOfRows - pAgg->numOfNull;
|
numOfElem = pInput->numOfRows - pAgg->numOfNull;
|
||||||
ASSERT(numOfElem >= 0);
|
ASSERT(numOfElem >= 0);
|
||||||
|
@ -426,6 +432,7 @@ int32_t sumFunction(SqlFunctionCtx* pCtx) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_sum_over:
|
||||||
// data in the check operation are all null, not output
|
// data in the check operation are all null, not output
|
||||||
SET_VAL(GET_RES_INFO(pCtx), numOfElem, 1);
|
SET_VAL(GET_RES_INFO(pCtx), numOfElem, 1);
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
@ -782,6 +789,12 @@ int32_t doMinMaxHelper(SqlFunctionCtx* pCtx, int32_t isMinFunc) {
|
||||||
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
|
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
|
||||||
SMinmaxResInfo *pBuf = GET_ROWCELL_INTERBUF(pResInfo);
|
SMinmaxResInfo *pBuf = GET_ROWCELL_INTERBUF(pResInfo);
|
||||||
|
|
||||||
|
if (IS_NULL_TYPE(type)) {
|
||||||
|
GET_RES_INFO(pCtx)->isNullRes = 1;
|
||||||
|
numOfElems = 1;
|
||||||
|
goto _min_max_over;
|
||||||
|
}
|
||||||
|
|
||||||
// data in current data block are qualified to the query
|
// data in current data block are qualified to the query
|
||||||
if (pInput->colDataAggIsSet) {
|
if (pInput->colDataAggIsSet) {
|
||||||
numOfElems = pInput->numOfRows - pAgg->numOfNull;
|
numOfElems = pInput->numOfRows - pAgg->numOfNull;
|
||||||
|
@ -1202,6 +1215,7 @@ int32_t doMinMaxHelper(SqlFunctionCtx* pCtx, int32_t isMinFunc) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_min_max_over:
|
||||||
return numOfElems;
|
return numOfElems;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1234,9 +1248,9 @@ int32_t minmaxFunctionFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||||
|
|
||||||
if (pCol->info.type == TSDB_DATA_TYPE_FLOAT) {
|
if (pCol->info.type == TSDB_DATA_TYPE_FLOAT) {
|
||||||
float v = *(double*) &pRes->v;
|
float v = *(double*) &pRes->v;
|
||||||
colDataAppend(pCol, currentRow, (const char*)&v, false);
|
colDataAppend(pCol, currentRow, (const char*)&v, pEntryInfo->isNullRes);
|
||||||
} else {
|
} else {
|
||||||
colDataAppend(pCol, currentRow, (const char*)&pRes->v, false);
|
colDataAppend(pCol, currentRow, (const char*)&pRes->v, pEntryInfo->isNullRes);
|
||||||
}
|
}
|
||||||
|
|
||||||
setSelectivityValue(pCtx, pBlock, &pRes->tuplePos, currentRow);
|
setSelectivityValue(pCtx, pBlock, &pRes->tuplePos, currentRow);
|
||||||
|
|
Loading…
Reference in New Issue