未验证 提交 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 {
#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;
}
\ No newline at end of file
}
......@@ -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())
\ No newline at end of file
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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册