未验证 提交 45cf5acc 编写于 作者: D dapan1121 提交者: GitHub

Merge pull request #18501 from taosdata/fix/TS-2149

fix(query): handle countAlwaysReturnValue behavior 
...@@ -57,7 +57,7 @@ typedef struct SFuncExecFuncs { ...@@ -57,7 +57,7 @@ typedef struct SFuncExecFuncs {
#define MAX_INTERVAL_TIME_WINDOW 10000000 // maximum allowed time windows in final results #define MAX_INTERVAL_TIME_WINDOW 10000000 // maximum allowed time windows in final results
#define TOP_BOTTOM_QUERY_LIMIT 100 #define TOP_BOTTOM_QUERY_LIMIT 100
#define FUNCTIONS_NAME_MAX_LENGTH 16 #define FUNCTIONS_NAME_MAX_LENGTH 32
typedef struct SResultRowEntryInfo { typedef struct SResultRowEntryInfo {
bool initialized : 1; // output buffer has been initialized bool initialized : 1; // output buffer has been initialized
......
...@@ -332,6 +332,7 @@ typedef struct STableScanInfo { ...@@ -332,6 +332,7 @@ typedef struct STableScanInfo {
int32_t currentTable; int32_t currentTable;
int8_t scanMode; int8_t scanMode;
int8_t assignBlockUid; int8_t assignBlockUid;
bool hasGroupByTag;
} STableScanInfo; } STableScanInfo;
typedef struct STableMergeScanInfo { typedef struct STableMergeScanInfo {
......
...@@ -1419,6 +1419,78 @@ int32_t getTableScanInfo(SOperatorInfo* pOperator, int32_t* order, int32_t* scan ...@@ -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 // this is a blocking operator
static int32_t doOpenAggregateOptr(SOperatorInfo* pOperator) { static int32_t doOpenAggregateOptr(SOperatorInfo* pOperator) {
if (OPTR_IS_OPENED(pOperator)) { if (OPTR_IS_OPENED(pOperator)) {
...@@ -1436,22 +1508,36 @@ static int32_t doOpenAggregateOptr(SOperatorInfo* pOperator) { ...@@ -1436,22 +1508,36 @@ static int32_t doOpenAggregateOptr(SOperatorInfo* pOperator) {
int32_t order = TSDB_ORDER_ASC; int32_t order = TSDB_ORDER_ASC;
int32_t scanFlag = MAIN_SCAN; int32_t scanFlag = MAIN_SCAN;
bool hasValidBlock = false;
bool blockAllocated = false;
while (1) { while (1) {
SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream); SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream);
if (pBlock == NULL) { 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); int32_t code = getTableScanInfo(pOperator, &order, &scanFlag);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
destroyDataBlockForEmptyInput(blockAllocated, &pBlock);
T_LONG_JMP(pTaskInfo->env, code); T_LONG_JMP(pTaskInfo->env, code);
} }
// there is an scalar expression that needs to be calculated before apply the group aggregation. // 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; SExprSupp* pSup1 = &pAggInfo->scalarExprSup;
code = projectApplyFunctions(pSup1->pExprInfo, pBlock, pBlock, pSup1->pCtx, pSup1->numOfExprs, NULL); code = projectApplyFunctions(pSup1->pExprInfo, pBlock, pBlock, pSup1->pCtx, pSup1->numOfExprs, NULL);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
destroyDataBlockForEmptyInput(blockAllocated, &pBlock);
T_LONG_JMP(pTaskInfo->env, code); T_LONG_JMP(pTaskInfo->env, code);
} }
} }
...@@ -1461,8 +1547,12 @@ static int32_t doOpenAggregateOptr(SOperatorInfo* pOperator) { ...@@ -1461,8 +1547,12 @@ static int32_t doOpenAggregateOptr(SOperatorInfo* pOperator) {
setInputDataBlock(pSup, pBlock, order, scanFlag, true); setInputDataBlock(pSup, pBlock, order, scanFlag, true);
code = doAggregateImpl(pOperator, pSup->pCtx); code = doAggregateImpl(pOperator, pSup->pCtx);
if (code != 0) { if (code != 0) {
destroyDataBlockForEmptyInput(blockAllocated, &pBlock);
T_LONG_JMP(pTaskInfo->env, code); 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. // 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, ...@@ -895,6 +895,7 @@ SOperatorInfo* createTableScanOperatorInfo(STableScanPhysiNode* pTableScanNode,
pInfo->currentGroupId = -1; pInfo->currentGroupId = -1;
pInfo->assignBlockUid = pTableScanNode->assignBlockUid; pInfo->assignBlockUid = pTableScanNode->assignBlockUid;
pInfo->hasGroupByTag = pTableScanNode->pGroupTags ? true : false;
setOperatorInfo(pOperator, "TableScanOperator", QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN, false, OP_NOT_OPENED, pInfo, setOperatorInfo(pOperator, "TableScanOperator", QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN, false, OP_NOT_OPENED, pInfo,
pTaskInfo); pTaskInfo);
......
...@@ -526,7 +526,7 @@ static int32_t getNumOfElems(SqlFunctionCtx* pCtx) { ...@@ -526,7 +526,7 @@ static int32_t getNumOfElems(SqlFunctionCtx* pCtx) {
* count function does not use the pCtx->interResBuf to keep the intermediate buffer * count function does not use the pCtx->interResBuf to keep the intermediate buffer
*/ */
int32_t countFunction(SqlFunctionCtx* pCtx) { int32_t countFunction(SqlFunctionCtx* pCtx) {
int32_t numOfElem = getNumOfElems(pCtx); int32_t numOfElem = 0;
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
SInputColumnInfoData* pInput = &pCtx->input; SInputColumnInfoData* pInput = &pCtx->input;
...@@ -539,6 +539,7 @@ int32_t countFunction(SqlFunctionCtx* pCtx) { ...@@ -539,6 +539,7 @@ int32_t countFunction(SqlFunctionCtx* pCtx) {
numOfElem = 1; numOfElem = 1;
*((int64_t*)buf) = 0; *((int64_t*)buf) = 0;
} else { } else {
numOfElem = getNumOfElems(pCtx);
*((int64_t*)buf) += numOfElem; *((int64_t*)buf) += numOfElem;
} }
...@@ -2043,12 +2044,16 @@ int32_t firstFunction(SqlFunctionCtx* pCtx) { ...@@ -2043,12 +2044,16 @@ int32_t firstFunction(SqlFunctionCtx* pCtx) {
pInfo->bytes = pInputCol->info.bytes; pInfo->bytes = pInputCol->info.bytes;
if (IS_NULL_TYPE(pInputCol->info.type)) {
return TSDB_CODE_SUCCESS;
}
// All null data column, return directly. // All null data column, return directly.
if (pInput->colDataSMAIsSet && (pInput->pColumnDataAgg[0]->numOfNull == pInput->totalRows)) { if (pInput->colDataSMAIsSet && (pInput->pColumnDataAgg[0]->numOfNull == pInput->totalRows)) {
ASSERT(pInputCol->hasNull == true); ASSERT(pInputCol->hasNull == true);
// save selectivity value for column consisted of all null values // save selectivity value for column consisted of all null values
firstlastSaveTupleData(pCtx->pSrcBlock, pInput->startRowIndex, pCtx, pInfo); firstlastSaveTupleData(pCtx->pSrcBlock, pInput->startRowIndex, pCtx, pInfo);
return 0; return TSDB_CODE_SUCCESS;
} }
SColumnDataAgg* pColAgg = (pInput->colDataSMAIsSet) ? pInput->pColumnDataAgg[0] : NULL; SColumnDataAgg* pColAgg = (pInput->colDataSMAIsSet) ? pInput->pColumnDataAgg[0] : NULL;
...@@ -2147,12 +2152,16 @@ int32_t lastFunction(SqlFunctionCtx* pCtx) { ...@@ -2147,12 +2152,16 @@ int32_t lastFunction(SqlFunctionCtx* pCtx) {
int32_t bytes = pInputCol->info.bytes; int32_t bytes = pInputCol->info.bytes;
pInfo->bytes = bytes; pInfo->bytes = bytes;
if (IS_NULL_TYPE(type)) {
return TSDB_CODE_SUCCESS;
}
// All null data column, return directly. // All null data column, return directly.
if (pInput->colDataSMAIsSet && (pInput->pColumnDataAgg[0]->numOfNull == pInput->totalRows)) { if (pInput->colDataSMAIsSet && (pInput->pColumnDataAgg[0]->numOfNull == pInput->totalRows)) {
ASSERT(pInputCol->hasNull == true); ASSERT(pInputCol->hasNull == true);
// save selectivity value for column consisted of all null values // save selectivity value for column consisted of all null values
firstlastSaveTupleData(pCtx->pSrcBlock, pInput->startRowIndex, pCtx, pInfo); firstlastSaveTupleData(pCtx->pSrcBlock, pInput->startRowIndex, pCtx, pInfo);
return 0; return TSDB_CODE_SUCCESS;
} }
SColumnDataAgg* pColAgg = (pInput->colDataSMAIsSet) ? pInput->pColumnDataAgg[0] : NULL; SColumnDataAgg* pColAgg = (pInput->colDataSMAIsSet) ? pInput->pColumnDataAgg[0] : NULL;
...@@ -2417,9 +2426,14 @@ int32_t lastRowFunction(SqlFunctionCtx* pCtx) { ...@@ -2417,9 +2426,14 @@ int32_t lastRowFunction(SqlFunctionCtx* pCtx) {
SInputColumnInfoData* pInput = &pCtx->input; SInputColumnInfoData* pInput = &pCtx->input;
SColumnInfoData* pInputCol = pInput->pData[0]; SColumnInfoData* pInputCol = pInput->pData[0];
int32_t type = pInputCol->info.type;
int32_t bytes = pInputCol->info.bytes; int32_t bytes = pInputCol->info.bytes;
pInfo->bytes = bytes; pInfo->bytes = bytes;
if (IS_NULL_TYPE(type)) {
return TSDB_CODE_SUCCESS;
}
TSKEY startKey = getRowPTs(pInput->pPTS, 0); TSKEY startKey = getRowPTs(pInput->pPTS, 0);
TSKEY endKey = getRowPTs(pInput->pPTS, pInput->totalRows - 1); TSKEY endKey = getRowPTs(pInput->pPTS, pInput->totalRows - 1);
...@@ -3869,6 +3883,10 @@ int32_t hllFunction(SqlFunctionCtx* pCtx) { ...@@ -3869,6 +3883,10 @@ int32_t hllFunction(SqlFunctionCtx* pCtx) {
int32_t numOfRows = pInput->numOfRows; int32_t numOfRows = pInput->numOfRows;
int32_t numOfElems = 0; int32_t numOfElems = 0;
if (IS_NULL_TYPE(type)) {
goto _hll_over;
}
for (int32_t i = start; i < numOfRows + start; ++i) { for (int32_t i = start; i < numOfRows + start; ++i) {
if (pCol->hasNull && colDataIsNull_s(pCol, i)) { if (pCol->hasNull && colDataIsNull_s(pCol, i)) {
continue; continue;
...@@ -3890,6 +3908,7 @@ int32_t hllFunction(SqlFunctionCtx* pCtx) { ...@@ -3890,6 +3908,7 @@ int32_t hllFunction(SqlFunctionCtx* pCtx) {
} }
} }
_hll_over:
pInfo->totalCount += numOfElems; pInfo->totalCount += numOfElems;
if (pInfo->totalCount == 0 && !tsCountAlwaysReturnValue) { if (pInfo->totalCount == 0 && !tsCountAlwaysReturnValue) {
...@@ -3913,12 +3932,16 @@ static void hllTransferInfo(SHLLInfo* pInput, SHLLInfo* pOutput) { ...@@ -3913,12 +3932,16 @@ static void hllTransferInfo(SHLLInfo* pInput, SHLLInfo* pOutput) {
int32_t hllFunctionMerge(SqlFunctionCtx* pCtx) { int32_t hllFunctionMerge(SqlFunctionCtx* pCtx) {
SInputColumnInfoData* pInput = &pCtx->input; SInputColumnInfoData* pInput = &pCtx->input;
SColumnInfoData* pCol = pInput->pData[0]; 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)); SHLLInfo* pInfo = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
int32_t start = pInput->startRowIndex; int32_t start = pInput->startRowIndex;
for (int32_t i = start; i < start + pInput->numOfRows; ++i) { for (int32_t i = start; i < start + pInput->numOfRows; ++i) {
char* data = colDataGetData(pCol, i); char* data = colDataGetData(pCol, i);
SHLLInfo* pInputInfo = (SHLLInfo*)varDataVal(data); SHLLInfo* pInputInfo = (SHLLInfo*)varDataVal(data);
......
...@@ -471,7 +471,6 @@ int32_t avgFunction(SqlFunctionCtx* pCtx) { ...@@ -471,7 +471,6 @@ int32_t avgFunction(SqlFunctionCtx* pCtx) {
int32_t type = pInput->pData[0]->info.type; int32_t type = pInput->pData[0]->info.type;
SAvgRes* pAvgRes = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx)); SAvgRes* pAvgRes = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
pAvgRes->type = type;
// computing based on the true data block // computing based on the true data block
SColumnInfoData* pCol = pInput->pData[0]; SColumnInfoData* pCol = pInput->pData[0];
...@@ -483,6 +482,8 @@ int32_t avgFunction(SqlFunctionCtx* pCtx) { ...@@ -483,6 +482,8 @@ int32_t avgFunction(SqlFunctionCtx* pCtx) {
goto _over; goto _over;
} }
pAvgRes->type = type;
if (pInput->colDataSMAIsSet) { // try to use SMA if available if (pInput->colDataSMAIsSet) { // try to use SMA if available
numOfElem = calculateAvgBySMAInfo(pAvgRes, numOfRows, type, pAgg); numOfElem = calculateAvgBySMAInfo(pAvgRes, numOfRows, type, pAgg);
} else if (!pCol->hasNull) { // try to employ the simd instructions to speed up the loop } else if (!pCol->hasNull) { // try to employ the simd instructions to speed up the loop
...@@ -592,6 +593,10 @@ _over: ...@@ -592,6 +593,10 @@ _over:
} }
static void avgTransferInfo(SAvgRes* pInput, SAvgRes* pOutput) { static void avgTransferInfo(SAvgRes* pInput, SAvgRes* pOutput) {
if (IS_NULL_TYPE(pInput->type)) {
return;
}
pOutput->type = pInput->type; pOutput->type = pInput->type;
if (IS_SIGNED_NUMERIC_TYPE(pOutput->type)) { if (IS_SIGNED_NUMERIC_TYPE(pOutput->type)) {
pOutput->sum.isum += pInput->sum.isum; pOutput->sum.isum += pInput->sum.isum;
...@@ -748,4 +753,4 @@ int32_t avgPartialFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) { ...@@ -748,4 +753,4 @@ int32_t avgPartialFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
taosMemoryFree(res); taosMemoryFree(res);
return pResInfo->numOfRes; return pResInfo->numOfRes;
} }
\ No newline at end of file
...@@ -496,18 +496,18 @@ sql create table tm0 using m1 tags('abc', 1); ...@@ -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 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; 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 return -1
endi endi
sql create table tm2 using m2 tags(2, 'abc'); sql create table tm2 using m2 tags(2, 'abc');
sql select count(*) from tm0, tm2 where tm0.ts=tm2.ts; sql select count(*) from tm0, tm2 where tm0.ts=tm2.ts;
if $rows != 0 then if $rows != 1 then
return -1 return -1
endi endi
sql select count(*) from m1, m2 where m1.ts=m2.ts and m1.b=m2.a; 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 return -1
endi endi
......
...@@ -55,7 +55,7 @@ endi ...@@ -55,7 +55,7 @@ endi
# regression test case 1 # 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' 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 return -1
endi endi
......
...@@ -245,12 +245,12 @@ endi ...@@ -245,12 +245,12 @@ endi
# first subclause are empty # 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); 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 if $rows != 2 then
return -1
endi
if $data00 != 495000 then
return -1 return -1
endi endi
#if $data00 != 495000 then
# return -1
#endi
# all subclause are empty # 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') 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: ...@@ -121,7 +121,7 @@ class TDTestCase:
tdSql.checkRows(0) tdSql.checkRows(0)
tdSql.query(f'select count(*) from {stbname}') tdSql.query(f'select count(*) from {stbname}')
if tb_num <= 1: 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!') tdLog.exit('delete case failure!')
else: else:
tdSql.checkEqual(tdSql.queryResult[0][0],(tb_num-1)*row_num) tdSql.checkEqual(tdSql.queryResult[0][0],(tb_num-1)*row_num)
...@@ -229,4 +229,4 @@ class TDTestCase: ...@@ -229,4 +229,4 @@ class TDTestCase:
tdLog.success("%s successfully executed" % __file__) tdLog.success("%s successfully executed" % __file__)
tdCases.addWindows(__file__, TDTestCase()) tdCases.addWindows(__file__, TDTestCase())
tdCases.addLinux(__file__, TDTestCase()) tdCases.addLinux(__file__, TDTestCase())
\ No newline at end of file
...@@ -51,6 +51,129 @@ class TDTestCase: ...@@ -51,6 +51,129 @@ class TDTestCase:
tdSql.checkEqual(tdSql.queryResult[0][0],rownum) tdSql.checkEqual(tdSql.queryResult[0][0],rownum)
tdSql.query(f'select count({k}) from {ntbname} where ts <={self.ts+self.rowNum-2}') tdSql.query(f'select count({k}) from {ntbname} where ts <={self.ts+self.rowNum-2}')
tdSql.checkEqual(tdSql.queryResult[0][0],rownum-1) 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): def count_query_stb(self,column_dict,tag_dict,stbname,tbnum,rownum):
tdSql.query(f'select count(tbname) from {stbname}') tdSql.query(f'select count(tbname) from {stbname}')
tdSql.checkEqual(tdSql.queryResult[0][0],tbnum*rownum) tdSql.checkEqual(tdSql.queryResult[0][0],tbnum*rownum)
...@@ -81,11 +204,11 @@ class TDTestCase: ...@@ -81,11 +204,11 @@ class TDTestCase:
def check_ntb(self): def check_ntb(self):
tdSql.prepare() tdSql.prepare()
tdSql.execute(self.setsql.set_create_normaltable_sql(self.ntbname,self.column_dict)) tdSql.execute(self.setsql.set_create_normaltable_sql(self.ntbname,self.column_dict))
tdSql.query(f'select count(tbname) from {self.ntbname}') self.query_empty_ntb()
tdSql.checkRows(0)
tdSql.execute('flush database db') tdSql.execute('flush database db')
tdSql.query(f'select count(tbname) from {self.ntbname}') 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.insert_data(self.column_dict,self.ntbname,self.rowNum)
self.count_query_ntb(self.column_dict,self.ntbname,self.rowNum) self.count_query_ntb(self.column_dict,self.ntbname,self.rowNum)
tdSql.execute('flush database db') tdSql.execute('flush database db')
...@@ -96,13 +219,11 @@ class TDTestCase: ...@@ -96,13 +219,11 @@ class TDTestCase:
tdSql.execute(self.setsql.set_create_stable_sql(self.stbname,self.column_dict,self.tag_dict)) tdSql.execute(self.setsql.set_create_stable_sql(self.stbname,self.column_dict,self.tag_dict))
for i in range(self.tbnum): for i in range(self.tbnum):
tdSql.execute(f'create table {self.stbname}_{i} using {self.stbname} tags({self.tag_values[i]})') 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})') self.query_empty_stb()
tdSql.checkEqual(tdSql.queryResult[0][0],self.tbnum)
tdSql.query(f'select count(tbname) from {self.stbname}')
tdSql.checkRows(0)
tdSql.execute('flush database db') tdSql.execute('flush database db')
tdSql.query(f'select count(tbname) from {self.stbname}') 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.query(f'SELECT count(*) from (select distinct tbname from {self.stbname})')
tdSql.checkEqual(tdSql.queryResult[0][0],self.tbnum) tdSql.checkEqual(tdSql.queryResult[0][0],self.tbnum)
for i in range(self.tbnum): for i in range(self.tbnum):
......
...@@ -33,6 +33,19 @@ class TDTestCase: ...@@ -33,6 +33,19 @@ class TDTestCase:
f"create table {dbname}.ctb2 using {dbname}.stb tags (2)" 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( tdSql.execute(
f"insert into {dbname}.tb values (now(), NULL)") f"insert into {dbname}.tb values (now(), NULL)")
...@@ -94,6 +107,61 @@ class TDTestCase: ...@@ -94,6 +107,61 @@ class TDTestCase:
tdSql.checkRows(1) tdSql.checkRows(1)
tdSql.checkData(0, 0, 0) 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): def run(self):
tdSql.prepare() tdSql.prepare()
......
...@@ -402,7 +402,8 @@ class TDTestCase: ...@@ -402,7 +402,8 @@ class TDTestCase:
tdSql.checkRows(0) tdSql.checkRows(0)
tdSql.query(f"select count(c1) from {dbname}.ct4 where t1 = 1 ") 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.query(f"select last_row(c1) ,last(c1) from {dbname}.stb1 where c1 is null")
tdSql.checkRows(1) tdSql.checkRows(1)
......
...@@ -298,7 +298,7 @@ class TDTestCase: ...@@ -298,7 +298,7 @@ class TDTestCase:
if (platform.system().lower() == 'windows' and pre_result.dtype == 'int32'): if (platform.system().lower() == 'windows' and pre_result.dtype == 'int32'):
pre_result = np.array(pre_result, dtype = 'int64') 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( 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, 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 table_expr=table_expr, condition=condition
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册