Merge pull request #18501 from taosdata/fix/TS-2149
fix(query): handle countAlwaysReturnValue behavior
This commit is contained in:
commit
45cf5acc32
|
@ -57,7 +57,7 @@ typedef struct SFuncExecFuncs {
|
|||
#define MAX_INTERVAL_TIME_WINDOW 10000000 // maximum allowed time windows in final results
|
||||
|
||||
#define TOP_BOTTOM_QUERY_LIMIT 100
|
||||
#define FUNCTIONS_NAME_MAX_LENGTH 16
|
||||
#define FUNCTIONS_NAME_MAX_LENGTH 32
|
||||
|
||||
typedef struct SResultRowEntryInfo {
|
||||
bool initialized : 1; // output buffer has been initialized
|
||||
|
|
|
@ -332,6 +332,7 @@ typedef struct STableScanInfo {
|
|||
int32_t currentTable;
|
||||
int8_t scanMode;
|
||||
int8_t assignBlockUid;
|
||||
bool hasGroupByTag;
|
||||
} STableScanInfo;
|
||||
|
||||
typedef struct STableMergeScanInfo {
|
||||
|
|
|
@ -1419,6 +1419,78 @@ int32_t getTableScanInfo(SOperatorInfo* pOperator, int32_t* order, int32_t* scan
|
|||
}
|
||||
}
|
||||
|
||||
static int32_t createDataBlockForEmptyInput(SOperatorInfo* pOperator, SSDataBlock **ppBlock) {
|
||||
if (!tsCountAlwaysReturnValue) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
SOperatorInfo* downstream = pOperator->pDownstream[0];
|
||||
if (downstream->operatorType == QUERY_NODE_PHYSICAL_PLAN_PARTITION ||
|
||||
(downstream->operatorType == QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN &&
|
||||
((STableScanInfo *)downstream->info)->hasGroupByTag == true)) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
SqlFunctionCtx* pCtx = pOperator->exprSupp.pCtx;
|
||||
bool hasCountFunc = false;
|
||||
for (int32_t i = 0; i < pOperator->exprSupp.numOfExprs; ++i) {
|
||||
if ((strcmp(pCtx[i].pExpr->pExpr->_function.functionName, "count") == 0) ||
|
||||
(strcmp(pCtx[i].pExpr->pExpr->_function.functionName, "hyperloglog") == 0) ||
|
||||
(strcmp(pCtx[i].pExpr->pExpr->_function.functionName, "_hyperloglog_partial") == 0) ||
|
||||
(strcmp(pCtx[i].pExpr->pExpr->_function.functionName, "_hyperloglog_merge") == 0)) {
|
||||
hasCountFunc = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasCountFunc) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
SSDataBlock* pBlock = createDataBlock();
|
||||
pBlock->info.rows = 1;
|
||||
pBlock->info.capacity = 0;
|
||||
|
||||
for (int32_t i = 0; i < pOperator->exprSupp.numOfExprs; ++i) {
|
||||
SColumnInfoData colInfo = {0};
|
||||
colInfo.hasNull = true;
|
||||
colInfo.info.type = TSDB_DATA_TYPE_NULL;
|
||||
colInfo.info.bytes = 1;
|
||||
|
||||
SExprInfo* pOneExpr = &pOperator->exprSupp.pExprInfo[i];
|
||||
for (int32_t j = 0; j < pOneExpr->base.numOfParams; ++j) {
|
||||
SFunctParam* pFuncParam = &pOneExpr->base.pParam[j];
|
||||
if (pFuncParam->type == FUNC_PARAM_TYPE_COLUMN) {
|
||||
int32_t slotId = pFuncParam->pCol->slotId;
|
||||
int32_t numOfCols = taosArrayGetSize(pBlock->pDataBlock);
|
||||
if (slotId >= numOfCols) {
|
||||
taosArrayEnsureCap(pBlock->pDataBlock, slotId + 1);
|
||||
for (int32_t k = numOfCols; k < slotId + 1; ++k) {
|
||||
taosArrayPush(pBlock->pDataBlock, &colInfo);
|
||||
}
|
||||
}
|
||||
} else if (pFuncParam->type == FUNC_PARAM_TYPE_VALUE) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
blockDataEnsureCapacity(pBlock, pBlock->info.rows);
|
||||
*ppBlock = pBlock;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static void destroyDataBlockForEmptyInput(bool blockAllocated, SSDataBlock **ppBlock) {
|
||||
if (!blockAllocated) {
|
||||
return;
|
||||
}
|
||||
|
||||
blockDataDestroy(*ppBlock);
|
||||
*ppBlock = NULL;
|
||||
}
|
||||
|
||||
|
||||
// this is a blocking operator
|
||||
static int32_t doOpenAggregateOptr(SOperatorInfo* pOperator) {
|
||||
if (OPTR_IS_OPENED(pOperator)) {
|
||||
|
@ -1436,22 +1508,36 @@ static int32_t doOpenAggregateOptr(SOperatorInfo* pOperator) {
|
|||
int32_t order = TSDB_ORDER_ASC;
|
||||
int32_t scanFlag = MAIN_SCAN;
|
||||
|
||||
bool hasValidBlock = false;
|
||||
bool blockAllocated = false;
|
||||
|
||||
while (1) {
|
||||
SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream);
|
||||
if (pBlock == NULL) {
|
||||
break;
|
||||
if (!hasValidBlock) {
|
||||
createDataBlockForEmptyInput(pOperator, &pBlock);
|
||||
if (pBlock == NULL) {
|
||||
break;
|
||||
}
|
||||
blockAllocated = true;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
hasValidBlock = true;
|
||||
|
||||
int32_t code = getTableScanInfo(pOperator, &order, &scanFlag);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
destroyDataBlockForEmptyInput(blockAllocated, &pBlock);
|
||||
T_LONG_JMP(pTaskInfo->env, code);
|
||||
}
|
||||
|
||||
// there is an scalar expression that needs to be calculated before apply the group aggregation.
|
||||
if (pAggInfo->scalarExprSup.pExprInfo != NULL) {
|
||||
if (pAggInfo->scalarExprSup.pExprInfo != NULL && !blockAllocated) {
|
||||
SExprSupp* pSup1 = &pAggInfo->scalarExprSup;
|
||||
code = projectApplyFunctions(pSup1->pExprInfo, pBlock, pBlock, pSup1->pCtx, pSup1->numOfExprs, NULL);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
destroyDataBlockForEmptyInput(blockAllocated, &pBlock);
|
||||
T_LONG_JMP(pTaskInfo->env, code);
|
||||
}
|
||||
}
|
||||
|
@ -1461,8 +1547,12 @@ static int32_t doOpenAggregateOptr(SOperatorInfo* pOperator) {
|
|||
setInputDataBlock(pSup, pBlock, order, scanFlag, true);
|
||||
code = doAggregateImpl(pOperator, pSup->pCtx);
|
||||
if (code != 0) {
|
||||
destroyDataBlockForEmptyInput(blockAllocated, &pBlock);
|
||||
T_LONG_JMP(pTaskInfo->env, code);
|
||||
}
|
||||
|
||||
destroyDataBlockForEmptyInput(blockAllocated, &pBlock);
|
||||
|
||||
}
|
||||
|
||||
// the downstream operator may return with error code, so let's check the code before generating results.
|
||||
|
|
|
@ -895,6 +895,7 @@ SOperatorInfo* createTableScanOperatorInfo(STableScanPhysiNode* pTableScanNode,
|
|||
|
||||
pInfo->currentGroupId = -1;
|
||||
pInfo->assignBlockUid = pTableScanNode->assignBlockUid;
|
||||
pInfo->hasGroupByTag = pTableScanNode->pGroupTags ? true : false;
|
||||
|
||||
setOperatorInfo(pOperator, "TableScanOperator", QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN, false, OP_NOT_OPENED, pInfo,
|
||||
pTaskInfo);
|
||||
|
|
|
@ -526,7 +526,7 @@ static int32_t getNumOfElems(SqlFunctionCtx* pCtx) {
|
|||
* count function does not use the pCtx->interResBuf to keep the intermediate buffer
|
||||
*/
|
||||
int32_t countFunction(SqlFunctionCtx* pCtx) {
|
||||
int32_t numOfElem = getNumOfElems(pCtx);
|
||||
int32_t numOfElem = 0;
|
||||
|
||||
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
|
||||
SInputColumnInfoData* pInput = &pCtx->input;
|
||||
|
@ -539,6 +539,7 @@ int32_t countFunction(SqlFunctionCtx* pCtx) {
|
|||
numOfElem = 1;
|
||||
*((int64_t*)buf) = 0;
|
||||
} else {
|
||||
numOfElem = getNumOfElems(pCtx);
|
||||
*((int64_t*)buf) += numOfElem;
|
||||
}
|
||||
|
||||
|
@ -2043,12 +2044,16 @@ int32_t firstFunction(SqlFunctionCtx* pCtx) {
|
|||
|
||||
pInfo->bytes = pInputCol->info.bytes;
|
||||
|
||||
if (IS_NULL_TYPE(pInputCol->info.type)) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
// All null data column, return directly.
|
||||
if (pInput->colDataSMAIsSet && (pInput->pColumnDataAgg[0]->numOfNull == pInput->totalRows)) {
|
||||
ASSERT(pInputCol->hasNull == true);
|
||||
// save selectivity value for column consisted of all null values
|
||||
firstlastSaveTupleData(pCtx->pSrcBlock, pInput->startRowIndex, pCtx, pInfo);
|
||||
return 0;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
SColumnDataAgg* pColAgg = (pInput->colDataSMAIsSet) ? pInput->pColumnDataAgg[0] : NULL;
|
||||
|
@ -2147,12 +2152,16 @@ int32_t lastFunction(SqlFunctionCtx* pCtx) {
|
|||
int32_t bytes = pInputCol->info.bytes;
|
||||
pInfo->bytes = bytes;
|
||||
|
||||
if (IS_NULL_TYPE(type)) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
// All null data column, return directly.
|
||||
if (pInput->colDataSMAIsSet && (pInput->pColumnDataAgg[0]->numOfNull == pInput->totalRows)) {
|
||||
ASSERT(pInputCol->hasNull == true);
|
||||
// save selectivity value for column consisted of all null values
|
||||
firstlastSaveTupleData(pCtx->pSrcBlock, pInput->startRowIndex, pCtx, pInfo);
|
||||
return 0;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
SColumnDataAgg* pColAgg = (pInput->colDataSMAIsSet) ? pInput->pColumnDataAgg[0] : NULL;
|
||||
|
@ -2417,9 +2426,14 @@ int32_t lastRowFunction(SqlFunctionCtx* pCtx) {
|
|||
SInputColumnInfoData* pInput = &pCtx->input;
|
||||
SColumnInfoData* pInputCol = pInput->pData[0];
|
||||
|
||||
int32_t type = pInputCol->info.type;
|
||||
int32_t bytes = pInputCol->info.bytes;
|
||||
pInfo->bytes = bytes;
|
||||
|
||||
if (IS_NULL_TYPE(type)) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
TSKEY startKey = getRowPTs(pInput->pPTS, 0);
|
||||
TSKEY endKey = getRowPTs(pInput->pPTS, pInput->totalRows - 1);
|
||||
|
||||
|
@ -3869,6 +3883,10 @@ int32_t hllFunction(SqlFunctionCtx* pCtx) {
|
|||
int32_t numOfRows = pInput->numOfRows;
|
||||
|
||||
int32_t numOfElems = 0;
|
||||
if (IS_NULL_TYPE(type)) {
|
||||
goto _hll_over;
|
||||
}
|
||||
|
||||
for (int32_t i = start; i < numOfRows + start; ++i) {
|
||||
if (pCol->hasNull && colDataIsNull_s(pCol, i)) {
|
||||
continue;
|
||||
|
@ -3890,6 +3908,7 @@ int32_t hllFunction(SqlFunctionCtx* pCtx) {
|
|||
}
|
||||
}
|
||||
|
||||
_hll_over:
|
||||
pInfo->totalCount += numOfElems;
|
||||
|
||||
if (pInfo->totalCount == 0 && !tsCountAlwaysReturnValue) {
|
||||
|
@ -3913,12 +3932,16 @@ static void hllTransferInfo(SHLLInfo* pInput, SHLLInfo* pOutput) {
|
|||
int32_t hllFunctionMerge(SqlFunctionCtx* pCtx) {
|
||||
SInputColumnInfoData* pInput = &pCtx->input;
|
||||
SColumnInfoData* pCol = pInput->pData[0];
|
||||
ASSERT(pCol->info.type == TSDB_DATA_TYPE_BINARY);
|
||||
|
||||
if (pCol->info.type != TSDB_DATA_TYPE_BINARY) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
SHLLInfo* pInfo = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
|
||||
|
||||
int32_t start = pInput->startRowIndex;
|
||||
|
||||
|
||||
for (int32_t i = start; i < start + pInput->numOfRows; ++i) {
|
||||
char* data = colDataGetData(pCol, i);
|
||||
SHLLInfo* pInputInfo = (SHLLInfo*)varDataVal(data);
|
||||
|
|
|
@ -471,7 +471,6 @@ int32_t avgFunction(SqlFunctionCtx* pCtx) {
|
|||
int32_t type = pInput->pData[0]->info.type;
|
||||
|
||||
SAvgRes* pAvgRes = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
|
||||
pAvgRes->type = type;
|
||||
|
||||
// computing based on the true data block
|
||||
SColumnInfoData* pCol = pInput->pData[0];
|
||||
|
@ -483,6 +482,8 @@ int32_t avgFunction(SqlFunctionCtx* pCtx) {
|
|||
goto _over;
|
||||
}
|
||||
|
||||
pAvgRes->type = type;
|
||||
|
||||
if (pInput->colDataSMAIsSet) { // try to use SMA if available
|
||||
numOfElem = calculateAvgBySMAInfo(pAvgRes, numOfRows, type, pAgg);
|
||||
} else if (!pCol->hasNull) { // try to employ the simd instructions to speed up the loop
|
||||
|
@ -592,6 +593,10 @@ _over:
|
|||
}
|
||||
|
||||
static void avgTransferInfo(SAvgRes* pInput, SAvgRes* pOutput) {
|
||||
if (IS_NULL_TYPE(pInput->type)) {
|
||||
return;
|
||||
}
|
||||
|
||||
pOutput->type = pInput->type;
|
||||
if (IS_SIGNED_NUMERIC_TYPE(pOutput->type)) {
|
||||
pOutput->sum.isum += pInput->sum.isum;
|
||||
|
@ -748,4 +753,4 @@ int32_t avgPartialFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
|||
|
||||
taosMemoryFree(res);
|
||||
return pResInfo->numOfRes;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -496,18 +496,18 @@ sql create table tm0 using m1 tags('abc', 1);
|
|||
sql create table m2(ts timestamp, k int) tags(a int, b binary(12));
|
||||
|
||||
sql select count(*) from m1, m2 where m1.ts=m2.ts and m1.b=m2.a;
|
||||
if $rows != 0 then
|
||||
if $rows != 1 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql create table tm2 using m2 tags(2, 'abc');
|
||||
sql select count(*) from tm0, tm2 where tm0.ts=tm2.ts;
|
||||
if $rows != 0 then
|
||||
if $rows != 1 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql select count(*) from m1, m2 where m1.ts=m2.ts and m1.b=m2.a;
|
||||
if $rows != 0 then
|
||||
if $rows != 1 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ endi
|
|||
|
||||
# regression test case 1
|
||||
sql select count(*) from lr_tb1 where ts>'2018-09-18 08:45:00.1' and ts<'2018-09-18 08:45:00.2'
|
||||
if $row != 0 then
|
||||
if $row != 1 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
|
|
|
@ -245,12 +245,12 @@ endi
|
|||
|
||||
# first subclause are empty
|
||||
sql (select count(*) as c from union_tb0 where ts > now + 3650d) union all (select sum(c1) as c from union_tb1);
|
||||
if $rows != 1 then
|
||||
return -1
|
||||
endi
|
||||
if $data00 != 495000 then
|
||||
if $rows != 2 then
|
||||
return -1
|
||||
endi
|
||||
#if $data00 != 495000 then
|
||||
# return -1
|
||||
#endi
|
||||
|
||||
# all subclause are empty
|
||||
sql (select c1 from union_tb0 limit 0) union all (select c1 from union_tb1 where ts>'2021-1-1 0:0:0')
|
||||
|
|
|
@ -121,7 +121,7 @@ class TDTestCase:
|
|||
tdSql.checkRows(0)
|
||||
tdSql.query(f'select count(*) from {stbname}')
|
||||
if tb_num <= 1:
|
||||
if len(tdSql.queryResult) != 0:
|
||||
if len(tdSql.queryResult) != 1 and tdSql.queryResult[0][0] != 0:
|
||||
tdLog.exit('delete case failure!')
|
||||
else:
|
||||
tdSql.checkEqual(tdSql.queryResult[0][0],(tb_num-1)*row_num)
|
||||
|
@ -229,4 +229,4 @@ class TDTestCase:
|
|||
tdLog.success("%s successfully executed" % __file__)
|
||||
|
||||
tdCases.addWindows(__file__, TDTestCase())
|
||||
tdCases.addLinux(__file__, TDTestCase())
|
||||
tdCases.addLinux(__file__, TDTestCase())
|
||||
|
|
|
@ -51,6 +51,129 @@ class TDTestCase:
|
|||
tdSql.checkEqual(tdSql.queryResult[0][0],rownum)
|
||||
tdSql.query(f'select count({k}) from {ntbname} where ts <={self.ts+self.rowNum-2}')
|
||||
tdSql.checkEqual(tdSql.queryResult[0][0],rownum-1)
|
||||
def query_empty_stb(self):
|
||||
tdSql.query(f'select count(*) from (select distinct tbname from {self.stbname})')
|
||||
tdSql.checkEqual(tdSql.queryResult[0][0],self.tbnum)
|
||||
tdSql.query(f'select count(*) from {self.stbname}')
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, 0)
|
||||
function_names = ['count', 'hyperloglog']
|
||||
for function_name in function_names:
|
||||
tdSql.query(f'select {function_name}(tbname) from {self.stbname}')
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, 0)
|
||||
tdSql.query(f'select {function_name}(c1) from {self.stbname}')
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, 0)
|
||||
tdSql.query(f'select {function_name}(ts) from {self.stbname}')
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, 0)
|
||||
tdSql.query(f'select {function_name}(1) from {self.stbname}')
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, 0)
|
||||
tdSql.query(f'select {function_name}(c1),sum(c2),max(1) from {self.stbname}')
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkCols(3)
|
||||
tdSql.checkData(0, 0, 0)
|
||||
tdSql.checkData(0, 1, None)
|
||||
tdSql.checkData(0, 2, None)
|
||||
tdSql.query(f'select sum(1),{function_name}(1),max(c2) from {self.stbname}')
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkCols(3)
|
||||
tdSql.checkData(0, 0, None)
|
||||
tdSql.checkData(0, 1, 0)
|
||||
tdSql.checkData(0, 2, None)
|
||||
tdSql.query(f'select {function_name}(1),sum(1),max(c2),min(1),min(2),min(3),min(4),min(5),min(6),min(7),min(8) from {self.stbname}')
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkCols(11)
|
||||
tdSql.checkData(0, 0, 0)
|
||||
tdSql.checkData(0, 1, None)
|
||||
tdSql.checkData(0, 2, None)
|
||||
tdSql.checkData(0, 10, None)
|
||||
tdSql.query(f'select sum(1),max(c2),min(1),leastsquares(c1,1,1) from {self.stbname}')
|
||||
tdSql.checkRows(0)
|
||||
tdSql.query(f'select {function_name}(c1),sum(c1) from {self.stbname} group by tbname')
|
||||
tdSql.checkRows(0)
|
||||
tdSql.query(f'select {function_name}(c1),sum(c1) from {self.stbname} group by c1')
|
||||
tdSql.checkRows(0)
|
||||
tdSql.query(f'select {function_name}(c1),sum(c1) from {self.stbname} group by t0')
|
||||
tdSql.checkRows(0)
|
||||
tdSql.query(f'select {function_name}(c1),sum(c1) from {self.stbname} partition by tbname')
|
||||
tdSql.checkRows(0)
|
||||
tdSql.query(f'select {function_name}(c1),sum(c1) from {self.stbname} partition by c1')
|
||||
tdSql.checkRows(0)
|
||||
tdSql.query(f'select {function_name}(c1),sum(c1) from {self.stbname} partition by t0')
|
||||
tdSql.checkRows(0)
|
||||
tdSql.query(f'select {function_name}(1) from (select {function_name}(c1),sum(c1) from {self.stbname} group by c1)')
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, 0)
|
||||
tdSql.query(f'select {function_name}(c1),sum(c1) from {self.stbname} interval(1s)')
|
||||
tdSql.checkRows(0)
|
||||
tdSql.query(f'select {function_name}(c1),sum(c1) from {self.stbname} partition by tbname interval(1s)')
|
||||
tdSql.checkRows(0)
|
||||
tdSql.query(f'select {function_name}(c1),sum(c1) from {self.stbname} partition by c1 interval(1s)')
|
||||
tdSql.checkRows(0)
|
||||
tdSql.query(f'select {function_name}(1),sum(1) from (select {function_name}(1) from {self.stbname} group by tbname)')
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, 0)
|
||||
tdSql.checkData(0, 1, None)
|
||||
|
||||
def query_empty_ntb(self):
|
||||
tdSql.query(f'select count(*) from {self.ntbname}')
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, 0)
|
||||
function_names = ['count', 'hyperloglog']
|
||||
for function_name in function_names:
|
||||
tdSql.query(f'select {function_name}(tbname) from {self.ntbname}')
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, 0)
|
||||
tdSql.query(f'select {function_name}(c1) from {self.ntbname}')
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, 0)
|
||||
tdSql.query(f'select {function_name}(ts) from {self.ntbname}')
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, 0)
|
||||
tdSql.query(f'select {function_name}(1) from {self.ntbname}')
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, 0)
|
||||
tdSql.query(f'select {function_name}(c1),sum(c2),max(1) from {self.ntbname}')
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkCols(3)
|
||||
tdSql.checkData(0, 0, 0)
|
||||
tdSql.checkData(0, 1, None)
|
||||
tdSql.checkData(0, 2, None)
|
||||
tdSql.query(f'select sum(1),{function_name}(1),max(c2) from {self.ntbname}')
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkCols(3)
|
||||
tdSql.checkData(0, 0, None)
|
||||
tdSql.checkData(0, 1, 0)
|
||||
tdSql.checkData(0, 2, None)
|
||||
tdSql.query(f'select {function_name}(1),sum(1),max(c2),min(1),min(2),min(3),min(4),min(5),min(6),min(7),min(8) from {self.ntbname}')
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkCols(11)
|
||||
tdSql.checkData(0, 0, 0)
|
||||
tdSql.checkData(0, 1, None)
|
||||
tdSql.checkData(0, 2, None)
|
||||
tdSql.checkData(0, 10, None)
|
||||
tdSql.query(f'select sum(1),max(c2),min(1),leastsquares(c1,1,1) from {self.ntbname}')
|
||||
tdSql.checkRows(0)
|
||||
tdSql.query(f'select {function_name}(c1),sum(c1) from {self.ntbname} group by tbname')
|
||||
tdSql.checkRows(0)
|
||||
tdSql.query(f'select {function_name}(c1),sum(c1) from {self.ntbname} group by c1')
|
||||
tdSql.checkRows(0)
|
||||
tdSql.query(f'select {function_name}(1) from (select {function_name}(c1),sum(c1) from {self.ntbname} group by c1)')
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, 0)
|
||||
tdSql.query(f'select {function_name}(c1),sum(c1) from {self.ntbname} interval(1s)')
|
||||
tdSql.checkRows(0)
|
||||
tdSql.query(f'select {function_name}(c1),sum(c1) from {self.ntbname} partition by tbname interval(1s)')
|
||||
tdSql.checkRows(0)
|
||||
tdSql.query(f'select {function_name}(c1),sum(c1) from {self.ntbname} partition by c1 interval(1s)')
|
||||
tdSql.checkRows(0)
|
||||
tdSql.query(f'select count(1),sum(1) from (select count(1) from {self.ntbname} group by tbname)')
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, 0)
|
||||
tdSql.checkData(0, 1, None)
|
||||
def count_query_stb(self,column_dict,tag_dict,stbname,tbnum,rownum):
|
||||
tdSql.query(f'select count(tbname) from {stbname}')
|
||||
tdSql.checkEqual(tdSql.queryResult[0][0],tbnum*rownum)
|
||||
|
@ -81,11 +204,11 @@ class TDTestCase:
|
|||
def check_ntb(self):
|
||||
tdSql.prepare()
|
||||
tdSql.execute(self.setsql.set_create_normaltable_sql(self.ntbname,self.column_dict))
|
||||
tdSql.query(f'select count(tbname) from {self.ntbname}')
|
||||
tdSql.checkRows(0)
|
||||
self.query_empty_ntb()
|
||||
tdSql.execute('flush database db')
|
||||
tdSql.query(f'select count(tbname) from {self.ntbname}')
|
||||
tdSql.checkRows(0)
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, 0)
|
||||
self.insert_data(self.column_dict,self.ntbname,self.rowNum)
|
||||
self.count_query_ntb(self.column_dict,self.ntbname,self.rowNum)
|
||||
tdSql.execute('flush database db')
|
||||
|
@ -96,13 +219,11 @@ class TDTestCase:
|
|||
tdSql.execute(self.setsql.set_create_stable_sql(self.stbname,self.column_dict,self.tag_dict))
|
||||
for i in range(self.tbnum):
|
||||
tdSql.execute(f'create table {self.stbname}_{i} using {self.stbname} tags({self.tag_values[i]})')
|
||||
tdSql.query(f'SELECT count(*) from (select distinct tbname from {self.stbname})')
|
||||
tdSql.checkEqual(tdSql.queryResult[0][0],self.tbnum)
|
||||
tdSql.query(f'select count(tbname) from {self.stbname}')
|
||||
tdSql.checkRows(0)
|
||||
self.query_empty_stb()
|
||||
tdSql.execute('flush database db')
|
||||
tdSql.query(f'select count(tbname) from {self.stbname}')
|
||||
tdSql.checkRows(0)
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, 0)
|
||||
tdSql.query(f'SELECT count(*) from (select distinct tbname from {self.stbname})')
|
||||
tdSql.checkEqual(tdSql.queryResult[0][0],self.tbnum)
|
||||
for i in range(self.tbnum):
|
||||
|
|
|
@ -33,6 +33,19 @@ class TDTestCase:
|
|||
f"create table {dbname}.ctb2 using {dbname}.stb tags (2)"
|
||||
)
|
||||
|
||||
tdSql.execute(
|
||||
f"create table {dbname}.tb_empty (ts timestamp, c0 int)"
|
||||
)
|
||||
tdSql.execute(
|
||||
f"create table {dbname}.stb_empty (ts timestamp, c0 int) tags (t0 int)"
|
||||
)
|
||||
tdSql.execute(
|
||||
f"create table {dbname}.ctb1_empty using {dbname}.stb tags (1)"
|
||||
)
|
||||
tdSql.execute(
|
||||
f"create table {dbname}.ctb2_empty using {dbname}.stb tags (2)"
|
||||
)
|
||||
|
||||
tdSql.execute(
|
||||
f"insert into {dbname}.tb values (now(), NULL)")
|
||||
|
||||
|
@ -94,6 +107,61 @@ class TDTestCase:
|
|||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, 0)
|
||||
|
||||
# test empty table/input
|
||||
tdSql.query(f"select count(*) from {dbname}.tb where ts > now + 1h")
|
||||
tdSql.checkRows(0)
|
||||
|
||||
tdSql.query(f"select count(ts) from {dbname}.stb where ts > now + 1h")
|
||||
tdSql.checkRows(0)
|
||||
|
||||
tdSql.query(f"select count(c0) from {dbname}.ctb1 where ts > now + 1h")
|
||||
tdSql.checkRows(0)
|
||||
|
||||
tdSql.query(f"select count(1) from {dbname}.ctb2 where ts > now + 1h")
|
||||
tdSql.checkRows(0)
|
||||
|
||||
tdSql.query(f"select count(*) from {dbname}.tb_empty")
|
||||
tdSql.checkRows(0)
|
||||
|
||||
tdSql.query(f"select count(ts) from {dbname}.stb_empty")
|
||||
tdSql.checkRows(0)
|
||||
|
||||
tdSql.query(f"select count(c0) from {dbname}.ctb1_empty")
|
||||
tdSql.checkRows(0)
|
||||
|
||||
tdSql.query(f"select count(1) from {dbname}.ctb2_empty")
|
||||
tdSql.checkRows(0)
|
||||
|
||||
tdSql.query(f"select hyperloglog(c0) from {dbname}.tb where ts > now + 1h")
|
||||
tdSql.checkRows(0)
|
||||
|
||||
tdSql.query(f"select hyperloglog(ts) from {dbname}.stb where ts > now + 1h")
|
||||
tdSql.checkRows(0)
|
||||
|
||||
tdSql.query(f"select hyperloglog(1) from {dbname}.ctb1 where ts > now + 1h")
|
||||
tdSql.checkRows(0)
|
||||
|
||||
tdSql.query(f"select hyperloglog(1) from {dbname}.ctb2 where ts > now + 1h")
|
||||
tdSql.checkRows(0)
|
||||
|
||||
tdSql.query(f"select hyperloglog(c0) from {dbname}.tb_empty")
|
||||
tdSql.checkRows(0)
|
||||
|
||||
tdSql.query(f"select hyperloglog(ts) from {dbname}.stb_empty")
|
||||
tdSql.checkRows(0)
|
||||
|
||||
tdSql.query(f"select hyperloglog(1) from {dbname}.ctb1_empty")
|
||||
tdSql.checkRows(0)
|
||||
|
||||
tdSql.query(f"select hyperloglog(1) from {dbname}.ctb2_empty")
|
||||
tdSql.checkRows(0)
|
||||
|
||||
tdSql.query(f"select count(*), hyperloglog(c0), sum(1), max(c0) from {dbname}.tb where ts > now + 1h")
|
||||
tdSql.checkRows(0)
|
||||
|
||||
tdSql.query(f"select count(*), hyperloglog(c0), sum(1), max(c0) from {dbname}.tb_empty")
|
||||
tdSql.checkRows(0)
|
||||
|
||||
def run(self):
|
||||
tdSql.prepare()
|
||||
|
||||
|
|
|
@ -402,7 +402,8 @@ class TDTestCase:
|
|||
tdSql.checkRows(0)
|
||||
|
||||
tdSql.query(f"select count(c1) from {dbname}.ct4 where t1 = 1 ")
|
||||
tdSql.checkRows(0)
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0,0,0)
|
||||
|
||||
tdSql.query(f"select last_row(c1) ,last(c1) from {dbname}.stb1 where c1 is null")
|
||||
tdSql.checkRows(1)
|
||||
|
|
|
@ -298,7 +298,7 @@ class TDTestCase:
|
|||
if (platform.system().lower() == 'windows' and pre_result.dtype == 'int32'):
|
||||
pre_result = np.array(pre_result, dtype = 'int64')
|
||||
|
||||
pre_mavg = pre_mavg = np.convolve(pre_result, np.ones(k), "valid")[offset_val:]/k
|
||||
#pre_mavg = pre_mavg = np.convolve(pre_result, np.ones(k), "valid")[offset_val:]/k
|
||||
tdSql.query(self.mavg_query_form(
|
||||
sel=sel, func=func, col=col, m_comm=m_comm, k=k, r_comm=r_comm, alias=alias, fr=fr,
|
||||
table_expr=table_expr, condition=condition
|
||||
|
|
Loading…
Reference in New Issue