fix: last/first must return not null values
This commit is contained in:
parent
a16a6b73c8
commit
81d3a2c385
|
@ -202,6 +202,7 @@ bool fmIsForbidStreamFunc(int32_t funcId);
|
||||||
bool fmIsIntervalInterpoFunc(int32_t funcId);
|
bool fmIsIntervalInterpoFunc(int32_t funcId);
|
||||||
bool fmIsInterpFunc(int32_t funcId);
|
bool fmIsInterpFunc(int32_t funcId);
|
||||||
bool fmIsLastRowFunc(int32_t funcId);
|
bool fmIsLastRowFunc(int32_t funcId);
|
||||||
|
bool fmIsReturnNotNullFunc(int32_t funcId);
|
||||||
bool fmIsSelectValueFunc(int32_t funcId);
|
bool fmIsSelectValueFunc(int32_t funcId);
|
||||||
bool fmIsSystemInfoFunc(int32_t funcId);
|
bool fmIsSystemInfoFunc(int32_t funcId);
|
||||||
bool fmIsImplicitTsFunc(int32_t funcId);
|
bool fmIsImplicitTsFunc(int32_t funcId);
|
||||||
|
|
|
@ -1437,7 +1437,8 @@ static void setExecutionContext(SOperatorInfo* pOperator, int32_t numOfOutput, u
|
||||||
pAggInfo->groupId = groupId;
|
pAggInfo->groupId = groupId;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void doUpdateNumOfRows(SResultRow* pRow, int32_t numOfExprs, const int32_t* rowCellOffset) {
|
static void doUpdateNumOfRows(SqlFunctionCtx* pCtx, SResultRow* pRow, int32_t numOfExprs, const int32_t* rowCellOffset) {
|
||||||
|
bool returnNotNull = false;
|
||||||
for (int32_t j = 0; j < numOfExprs; ++j) {
|
for (int32_t j = 0; j < numOfExprs; ++j) {
|
||||||
struct SResultRowEntryInfo* pResInfo = getResultEntryInfo(pRow, j, rowCellOffset);
|
struct SResultRowEntryInfo* pResInfo = getResultEntryInfo(pRow, j, rowCellOffset);
|
||||||
if (!isRowEntryInitialized(pResInfo)) {
|
if (!isRowEntryInitialized(pResInfo)) {
|
||||||
|
@ -1447,9 +1448,13 @@ static void doUpdateNumOfRows(SResultRow* pRow, int32_t numOfExprs, const int32_
|
||||||
if (pRow->numOfRows < pResInfo->numOfRes) {
|
if (pRow->numOfRows < pResInfo->numOfRes) {
|
||||||
pRow->numOfRows = pResInfo->numOfRes;
|
pRow->numOfRows = pResInfo->numOfRes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fmIsReturnNotNullFunc(pCtx[j].functionId)) {
|
||||||
|
returnNotNull = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// TODO: if all expr skips all blocks, e.g. all null inputs for max function, output one row in final result.
|
// TODO: if all expr skips all blocks, e.g. all null inputs for max function, output one row in final result.
|
||||||
if (pRow->numOfRows == 0) {
|
if (pRow->numOfRows == 0 && !returnNotNull) {
|
||||||
pRow->numOfRows = 1;
|
pRow->numOfRows = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1462,7 +1467,7 @@ int32_t finalizeResultRowIntoResultDataBlock(SDiskbasedBuf* pBuf, SResultRowPosi
|
||||||
SFilePage* page = getBufPage(pBuf, resultRowPosition->pageId);
|
SFilePage* page = getBufPage(pBuf, resultRowPosition->pageId);
|
||||||
SResultRow* pRow = (SResultRow*)((char*)page + resultRowPosition->offset);
|
SResultRow* pRow = (SResultRow*)((char*)page + resultRowPosition->offset);
|
||||||
|
|
||||||
doUpdateNumOfRows(pRow, numOfExprs, rowCellOffset);
|
doUpdateNumOfRows(pCtx, pRow, numOfExprs, rowCellOffset);
|
||||||
if (pRow->numOfRows == 0) {
|
if (pRow->numOfRows == 0) {
|
||||||
releaseBufPage(pBuf, page);
|
releaseBufPage(pBuf, page);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1518,7 +1523,7 @@ int32_t doCopyToSDataBlock(SExecTaskInfo* pTaskInfo, SSDataBlock* pBlock, SExprI
|
||||||
|
|
||||||
SResultRow* pRow = (SResultRow*)((char*)page + pPos->pos.offset);
|
SResultRow* pRow = (SResultRow*)((char*)page + pPos->pos.offset);
|
||||||
|
|
||||||
doUpdateNumOfRows(pRow, numOfExprs, rowCellOffset);
|
doUpdateNumOfRows(pCtx, pRow, numOfExprs, rowCellOffset);
|
||||||
if (pRow->numOfRows == 0) {
|
if (pRow->numOfRows == 0) {
|
||||||
pGroupResInfo->index += 1;
|
pGroupResInfo->index += 1;
|
||||||
releaseBufPage(pBuf, page);
|
releaseBufPage(pBuf, page);
|
||||||
|
|
|
@ -221,6 +221,18 @@ bool fmIsLastRowFunc(int32_t funcId) {
|
||||||
return FUNCTION_TYPE_LAST_ROW == funcMgtBuiltins[funcId].type;
|
return FUNCTION_TYPE_LAST_ROW == funcMgtBuiltins[funcId].type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool fmIsReturnNotNullFunc(int32_t funcId) {
|
||||||
|
if (funcId < 0 || funcId >= funcMgtBuiltinsNum) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return FUNCTION_TYPE_LAST == funcMgtBuiltins[funcId].type ||
|
||||||
|
FUNCTION_TYPE_LAST_PARTIAL == funcMgtBuiltins[funcId].type ||
|
||||||
|
FUNCTION_TYPE_LAST_MERGE == funcMgtBuiltins[funcId].type ||
|
||||||
|
FUNCTION_TYPE_FIRST == funcMgtBuiltins[funcId].type ||
|
||||||
|
FUNCTION_TYPE_FIRST_PARTIAL == funcMgtBuiltins[funcId].type ||
|
||||||
|
FUNCTION_TYPE_FIRST_MERGE == funcMgtBuiltins[funcId].type;
|
||||||
|
}
|
||||||
|
|
||||||
bool fmIsSelectValueFunc(int32_t funcId) {
|
bool fmIsSelectValueFunc(int32_t funcId) {
|
||||||
if (funcId < 0 || funcId >= funcMgtBuiltinsNum) {
|
if (funcId < 0 || funcId >= funcMgtBuiltinsNum) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -327,8 +327,8 @@ endi
|
||||||
|
|
||||||
print =================>td-2610
|
print =================>td-2610
|
||||||
sql select stddev(k) from tm2 where ts='2020-12-29 18:46:19.109'
|
sql select stddev(k) from tm2 where ts='2020-12-29 18:46:19.109'
|
||||||
if $rows != 0 then
|
if $rows != 1 then
|
||||||
print expect 0, actual:$rows
|
print expect 1, actual:$rows
|
||||||
return -1
|
return -1
|
||||||
endi
|
endi
|
||||||
sql select twa(k) from tm2 where ts='2020-12-29 18:46:19.109'
|
sql select twa(k) from tm2 where ts='2020-12-29 18:46:19.109'
|
||||||
|
@ -406,7 +406,7 @@ if $data00 != 1.378704626 then
|
||||||
endi
|
endi
|
||||||
|
|
||||||
sql select stddev(c) from m1
|
sql select stddev(c) from m1
|
||||||
if $rows != 0 then
|
if $rows != 1 then
|
||||||
return -1
|
return -1
|
||||||
endi
|
endi
|
||||||
|
|
||||||
|
|
|
@ -295,7 +295,7 @@ class TDTestCase:
|
||||||
tdSql.checkData(0, 0, 4.500000000)
|
tdSql.checkData(0, 0, 4.500000000)
|
||||||
|
|
||||||
tdSql.query(f" select avg(c1) from {dbname}.stb1 where c1 is null ")
|
tdSql.query(f" select avg(c1) from {dbname}.stb1 where c1 is null ")
|
||||||
tdSql.checkRows(0)
|
tdSql.checkRows(1)
|
||||||
|
|
||||||
|
|
||||||
def avg_func_filter(self, dbname="db"):
|
def avg_func_filter(self, dbname="db"):
|
||||||
|
|
|
@ -86,7 +86,7 @@ class TDTestCase:
|
||||||
def distribute_agg_query(self, dbname="testdb"):
|
def distribute_agg_query(self, dbname="testdb"):
|
||||||
# basic filter
|
# basic filter
|
||||||
tdSql.query(f"select apercentile(c1 , 20) from {dbname}.stb1 where c1 is null")
|
tdSql.query(f"select apercentile(c1 , 20) from {dbname}.stb1 where c1 is null")
|
||||||
tdSql.checkRows(0)
|
tdSql.checkRows(1)
|
||||||
|
|
||||||
tdSql.query(f"select apercentile(c1 , 20) from {dbname}.stb1 where t1=1")
|
tdSql.query(f"select apercentile(c1 , 20) from {dbname}.stb1 where t1=1")
|
||||||
tdSql.checkData(0,0,2.800000000)
|
tdSql.checkData(0,0,2.800000000)
|
||||||
|
|
|
@ -168,7 +168,7 @@ class TDTestCase:
|
||||||
def distribute_agg_query(self, dbname="testdb"):
|
def distribute_agg_query(self, dbname="testdb"):
|
||||||
# basic filter
|
# basic filter
|
||||||
tdSql.query(f"select max(c1) from {dbname}.stb1 where c1 is null")
|
tdSql.query(f"select max(c1) from {dbname}.stb1 where c1 is null")
|
||||||
tdSql.checkRows(0)
|
tdSql.checkRows(1)
|
||||||
|
|
||||||
tdSql.query(f"select max(c1) from {dbname}.stb1 where t1=1")
|
tdSql.query(f"select max(c1) from {dbname}.stb1 where t1=1")
|
||||||
tdSql.checkData(0,0,10)
|
tdSql.checkData(0,0,10)
|
||||||
|
|
|
@ -167,7 +167,7 @@ class TDTestCase:
|
||||||
def distribute_agg_query(self, dbname="testdb"):
|
def distribute_agg_query(self, dbname="testdb"):
|
||||||
# basic filter
|
# basic filter
|
||||||
tdSql.query(f"select min(c1) from {dbname}.stb1 where c1 is null")
|
tdSql.query(f"select min(c1) from {dbname}.stb1 where c1 is null")
|
||||||
tdSql.checkRows(0)
|
tdSql.checkRows(1)
|
||||||
|
|
||||||
tdSql.query(f"select min(c1) from {dbname}.stb1 where t1=1")
|
tdSql.query(f"select min(c1) from {dbname}.stb1 where t1=1")
|
||||||
tdSql.checkData(0,0,2)
|
tdSql.checkData(0,0,2)
|
||||||
|
|
|
@ -195,7 +195,7 @@ class TDTestCase:
|
||||||
def distribute_agg_query(self):
|
def distribute_agg_query(self):
|
||||||
# basic filter
|
# basic filter
|
||||||
tdSql.query("select spread(c1) from stb1 where c1 is null")
|
tdSql.query("select spread(c1) from stb1 where c1 is null")
|
||||||
tdSql.checkRows(0)
|
tdSql.checkRows(1)
|
||||||
|
|
||||||
tdSql.query("select spread(c1) from stb1 where t1=1")
|
tdSql.query("select spread(c1) from stb1 where t1=1")
|
||||||
tdSql.checkData(0,0,8.000000000)
|
tdSql.checkData(0,0,8.000000000)
|
||||||
|
|
|
@ -743,7 +743,7 @@ class TDTestCase:
|
||||||
# filter data
|
# filter data
|
||||||
|
|
||||||
tdSql.query(" select sample(c1, 20 ) from t1 where c1 is null ")
|
tdSql.query(" select sample(c1, 20 ) from t1 where c1 is null ")
|
||||||
tdSql.checkRows(0)
|
tdSql.checkRows(1)
|
||||||
|
|
||||||
tdSql.query(" select sample(c1, 20 ) from t1 where c1 =6 ")
|
tdSql.query(" select sample(c1, 20 ) from t1 where c1 =6 ")
|
||||||
tdSql.checkRows(1)
|
tdSql.checkRows(1)
|
||||||
|
@ -891,4 +891,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())
|
||||||
|
|
Loading…
Reference in New Issue