2021-11-02 05:37:31 +00:00
/*
* Copyright ( c ) 2019 TAOS Data , Inc . < jhtao @ taosdata . com >
*
* This program is free software : you can use , redistribute , and / or modify
* it under the terms of the GNU Affero General Public License , version 3
* or later ( " AGPL " ) , as published by the Free Software Foundation .
*
* This program is distributed in the hope that it will be useful , but WITHOUT
* ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE .
*
* You should have received a copy of the GNU Affero General Public License
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
2022-02-04 14:41:54 +00:00
# include <tep.h>
2022-01-20 09:10:28 +00:00
# include "exception.h"
2021-11-02 05:37:31 +00:00
# include "os.h"
2022-02-04 14:41:54 +00:00
# include "parser.h"
2021-11-02 05:37:31 +00:00
# include "tglobal.h"
2022-01-20 09:10:28 +00:00
# include "tmsg.h"
2022-02-04 14:41:54 +00:00
# include "tq.h"
2021-11-05 02:35:50 +00:00
# include "ttime.h"
2022-01-08 08:28:44 +00:00
2021-11-02 05:37:31 +00:00
# include "executorimpl.h"
# include "function.h"
# include "tcompare.h"
# include "tcompression.h"
2022-01-08 14:59:24 +00:00
# include "thash.h"
2021-11-02 05:37:31 +00:00
# include "ttypes.h"
2022-01-08 14:59:24 +00:00
# include "query.h"
2022-01-21 08:12:02 +00:00
# include "vnode.h"
2022-01-10 11:48:21 +00:00
# include "tsdb.h"
2021-11-02 05:37:31 +00:00
2022-01-08 14:59:24 +00:00
# define IS_MAIN_SCAN(runtime) ((runtime)->scanFlag == MAIN_SCAN)
2021-11-02 05:37:31 +00:00
# define IS_REVERSE_SCAN(runtime) ((runtime)->scanFlag == REVERSE_SCAN)
# define IS_REPEAT_SCAN(runtime) ((runtime)->scanFlag == REPEAT_SCAN)
2022-01-08 14:59:24 +00:00
# define SET_MAIN_SCAN_FLAG(runtime) ((runtime)->scanFlag = MAIN_SCAN)
2021-11-02 05:37:31 +00:00
# define SET_REVERSE_SCAN_FLAG(runtime) ((runtime)->scanFlag = REVERSE_SCAN)
# define TSWINDOW_IS_EQUAL(t1, t2) (((t1).skey == (t2).skey) && ((t1).ekey == (t2).ekey))
# define SWITCH_ORDER(n) (((n) = ((n) == TSDB_ORDER_ASC) ? TSDB_ORDER_DESC : TSDB_ORDER_ASC))
# define SDATA_BLOCK_INITIALIZER (SDataBlockInfo) {{0}, 0}
# define GET_FORWARD_DIRECTION_FACTOR(ord) (((ord) == TSDB_ORDER_ASC) ? QUERY_ASC_FORWARD_STEP : QUERY_DESC_FORWARD_STEP)
# define MULTI_KEY_DELIM "-"
enum {
TS_JOIN_TS_EQUAL = 0 ,
TS_JOIN_TS_NOT_EQUALS = 1 ,
TS_JOIN_TAG_NOT_EQUALS = 2 ,
} ;
typedef enum SResultTsInterpType {
RESULT_ROW_START_INTERP = 1 ,
RESULT_ROW_END_INTERP = 2 ,
} SResultTsInterpType ;
#if 0
static UNUSED_FUNC void * u_malloc ( size_t __size ) {
uint32_t v = rand ( ) ;
if ( v % 1000 < = 0 ) {
return NULL ;
} else {
return malloc ( __size ) ;
}
}
static UNUSED_FUNC void * u_calloc ( size_t num , size_t __size ) {
uint32_t v = rand ( ) ;
if ( v % 1000 < = 0 ) {
return NULL ;
} else {
return calloc ( num , __size ) ;
}
}
static UNUSED_FUNC void * u_realloc ( void * p , size_t __size ) {
uint32_t v = rand ( ) ;
if ( v % 5 < = 1 ) {
return NULL ;
} else {
return realloc ( p , __size ) ;
}
}
# define calloc u_calloc
# define malloc u_malloc
# define realloc u_realloc
# endif
# define CLEAR_QUERY_STATUS(q, st) ((q)->status &= (~(st)))
# define GET_NUM_OF_TABLEGROUP(q) taosArrayGetSize((q)->tableqinfoGroupInfo.pGroupList)
# define QUERY_IS_INTERVAL_QUERY(_q) ((_q)->interval.interval > 0)
# define TSKEY_MAX_ADD(a,b) \
do { \
if ( a < 0 ) { a = a + b ; break ; } \
if ( sizeof ( a ) = = sizeof ( int32_t ) ) { \
if ( ( b ) > 0 & & ( ( b ) > = INT32_MAX - ( a ) ) ) { \
a = INT32_MAX ; \
} else { \
a = a + b ; \
} \
} else { \
if ( ( b ) > 0 & & ( ( b ) > = INT64_MAX - ( a ) ) ) { \
a = INT64_MAX ; \
} else { \
a = a + b ; \
} \
} \
} while ( 0 )
# define TSKEY_MIN_SUB(a,b) \
do { \
if ( a > = 0 ) { a = a + b ; break ; } \
if ( sizeof ( a ) = = sizeof ( int32_t ) ) { \
if ( ( b ) < 0 & & ( ( b ) < = INT32_MIN - ( a ) ) ) { \
a = INT32_MIN ; \
} else { \
a = a + b ; \
} \
} else { \
if ( ( b ) < 0 & & ( ( b ) < = INT64_MIN - ( a ) ) ) { \
a = INT64_MIN ; \
} else { \
a = a + b ; \
} \
} \
} while ( 0 )
int32_t getMaximumIdleDurationSec ( ) {
return tsShellActivityTimer * 2 ;
}
static int32_t getExprFunctionId ( SExprInfo * pExprInfo ) {
assert ( pExprInfo ! = NULL & & pExprInfo - > pExpr ! = NULL & & pExprInfo - > pExpr - > nodeType = = TEXPR_UNARYEXPR_NODE ) ;
2021-11-08 02:32:06 +00:00
return 0 ;
2021-11-02 05:37:31 +00:00
}
2022-01-08 08:28:44 +00:00
static void getNextTimeWindow ( STaskAttr * pQueryAttr , STimeWindow * tw ) {
2021-11-02 05:37:31 +00:00
int32_t factor = GET_FORWARD_DIRECTION_FACTOR ( pQueryAttr - > order . order ) ;
if ( pQueryAttr - > interval . intervalUnit ! = ' n ' & & pQueryAttr - > interval . intervalUnit ! = ' y ' ) {
tw - > skey + = pQueryAttr - > interval . sliding * factor ;
tw - > ekey = tw - > skey + pQueryAttr - > interval . interval - 1 ;
return ;
}
int64_t key = tw - > skey , interval = pQueryAttr - > interval . interval ;
//convert key to second
key = convertTimePrecision ( key , pQueryAttr - > precision , TSDB_TIME_PRECISION_MILLI ) / 1000 ;
if ( pQueryAttr - > interval . intervalUnit = = ' y ' ) {
interval * = 12 ;
}
struct tm tm ;
time_t t = ( time_t ) key ;
localtime_r ( & t , & tm ) ;
int mon = ( int ) ( tm . tm_year * 12 + tm . tm_mon + interval * factor ) ;
tm . tm_year = mon / 12 ;
tm . tm_mon = mon % 12 ;
tw - > skey = convertTimePrecision ( ( int64_t ) mktime ( & tm ) * 1000L , TSDB_TIME_PRECISION_MILLI , pQueryAttr - > precision ) ;
mon = ( int ) ( mon + interval ) ;
tm . tm_year = mon / 12 ;
tm . tm_mon = mon % 12 ;
tw - > ekey = convertTimePrecision ( ( int64_t ) mktime ( & tm ) * 1000L , TSDB_TIME_PRECISION_MILLI , pQueryAttr - > precision ) ;
tw - > ekey - = 1 ;
}
static void doSetTagValueToResultBuf ( char * output , const char * val , int16_t type , int16_t bytes ) ;
2022-01-28 02:44:02 +00:00
static void setResultOutputBuf ( STaskRuntimeEnv * pRuntimeEnv , SResultRow * pResult , SqlFunctionCtx * pCtx ,
2021-11-02 05:37:31 +00:00
int32_t numOfCols , int32_t * rowCellInfoOffset ) ;
2022-01-28 02:44:02 +00:00
void setResultRowOutputBufInitCtx ( STaskRuntimeEnv * pRuntimeEnv , SResultRow * pResult , SqlFunctionCtx * pCtx , int32_t numOfOutput , int32_t * rowCellInfoOffset ) ;
static bool functionNeedToExecute ( STaskRuntimeEnv * pRuntimeEnv , SqlFunctionCtx * pCtx ) ;
2021-11-02 05:37:31 +00:00
2022-01-28 02:44:02 +00:00
static void setBlockStatisInfo ( SqlFunctionCtx * pCtx , SSDataBlock * pSDataBlock , SColumn * pColumn ) ;
2021-11-02 05:37:31 +00:00
static void destroyTableQueryInfoImpl ( STableQueryInfo * pTableQueryInfo ) ;
2022-01-08 08:28:44 +00:00
static bool hasMainOutput ( STaskAttr * pQueryAttr ) ;
2021-11-02 05:37:31 +00:00
static SColumnInfo * extractColumnFilterInfo ( SExprInfo * pExpr , int32_t numOfOutput , int32_t * numOfFilterCols ) ;
2022-01-08 08:28:44 +00:00
static int32_t setTimestampListJoinInfo ( STaskRuntimeEnv * pRuntimeEnv , SVariant * pTag , STableQueryInfo * pTableQueryInfo ) ;
2021-11-02 05:37:31 +00:00
static void releaseQueryBuf ( size_t numOfTables ) ;
static int32_t binarySearchForKey ( char * pValue , int num , TSKEY key , int order ) ;
2022-01-08 08:28:44 +00:00
//static STsdbQueryCond createTsdbQueryCond(STaskAttr* pQueryAttr, STimeWindow* win);
2021-11-02 05:37:31 +00:00
static STableIdInfo createTableIdInfo ( STableQueryInfo * pTableQueryInfo ) ;
static void setTableScanFilterOperatorInfo ( STableScanInfo * pTableScanInfo , SOperatorInfo * pDownstream ) ;
2022-01-08 08:28:44 +00:00
static int32_t getNumOfScanTimes ( STaskAttr * pQueryAttr ) ;
2021-11-02 05:37:31 +00:00
static void destroyBasicOperatorInfo ( void * param , int32_t numOfOutput ) ;
static void destroySFillOperatorInfo ( void * param , int32_t numOfOutput ) ;
static void destroyGroupbyOperatorInfo ( void * param , int32_t numOfOutput ) ;
static void destroyProjectOperatorInfo ( void * param , int32_t numOfOutput ) ;
static void destroyTagScanOperatorInfo ( void * param , int32_t numOfOutput ) ;
static void destroyOrderOperatorInfo ( void * param , int32_t numOfOutput ) ;
static void destroySWindowOperatorInfo ( void * param , int32_t numOfOutput ) ;
static void destroyStateWindowOperatorInfo ( void * param , int32_t numOfOutput ) ;
static void destroyAggOperatorInfo ( void * param , int32_t numOfOutput ) ;
static void destroyOperatorInfo ( SOperatorInfo * pOperator ) ;
static void doSetOperatorCompleted ( SOperatorInfo * pOperator ) {
pOperator - > status = OP_EXEC_DONE ;
2022-01-08 14:59:24 +00:00
if ( pOperator - > pTaskInfo ! = NULL ) {
2022-01-10 11:48:21 +00:00
setTaskStatus ( pOperator - > pTaskInfo , TASK_COMPLETED ) ;
2021-11-02 05:37:31 +00:00
}
}
2022-01-08 08:28:44 +00:00
static int32_t doCopyToSDataBlock ( STaskRuntimeEnv * pRuntimeEnv , SGroupResInfo * pGroupResInfo , int32_t orderType , SSDataBlock * pBlock ) ;
2021-11-02 05:37:31 +00:00
static int32_t getGroupbyColumnIndex ( SGroupbyExpr * pGroupbyExpr , SSDataBlock * pDataBlock ) ;
2022-01-08 08:28:44 +00:00
static int32_t setGroupResultOutputBuf ( STaskRuntimeEnv * pRuntimeEnv , SOptrBasicInfo * binf , int32_t numOfCols , char * pData , int16_t type , int16_t bytes , int32_t groupIndex ) ;
2021-11-02 05:37:31 +00:00
2022-01-28 02:44:02 +00:00
static void initCtxOutputBuffer ( SqlFunctionCtx * pCtx , int32_t size ) ;
2022-01-08 08:28:44 +00:00
static void getAlignQueryTimeWindow ( STaskAttr * pQueryAttr , int64_t key , int64_t keyFirst , int64_t keyLast , STimeWindow * win ) ;
static void setResultBufSize ( STaskAttr * pQueryAttr , SRspResultInfo * pResultInfo ) ;
2022-01-28 02:44:02 +00:00
static void setCtxTagForJoin ( STaskRuntimeEnv * pRuntimeEnv , SqlFunctionCtx * pCtx , SExprInfo * pExprInfo , void * pTable ) ;
static void setParamForStableStddev ( STaskRuntimeEnv * pRuntimeEnv , SqlFunctionCtx * pCtx , int32_t numOfOutput , SExprInfo * pExpr ) ;
static void setParamForStableStddevByColData ( STaskRuntimeEnv * pRuntimeEnv , SqlFunctionCtx * pCtx , int32_t numOfOutput , SExprInfo * pExpr , char * val , int16_t bytes ) ;
2022-01-08 08:28:44 +00:00
static void doSetTableGroupOutputBuf ( STaskRuntimeEnv * pRuntimeEnv , SResultRowInfo * pResultRowInfo ,
2022-01-28 02:44:02 +00:00
SqlFunctionCtx * pCtx , int32_t * rowCellInfoOffset , int32_t numOfOutput , int32_t tableGroupId ) ;
2021-11-02 05:37:31 +00:00
2022-01-08 08:28:44 +00:00
SArray * getOrderCheckColumns ( STaskAttr * pQuery ) ;
2021-11-02 05:37:31 +00:00
typedef struct SRowCompSupporter {
2022-01-08 08:28:44 +00:00
STaskRuntimeEnv * pRuntimeEnv ;
2021-11-02 05:37:31 +00:00
int16_t dataOffset ;
__compar_fn_t comFunc ;
} SRowCompSupporter ;
static int compareRowData ( const void * a , const void * b , const void * userData ) {
const SResultRow * pRow1 = ( const SResultRow * ) a ;
const SResultRow * pRow2 = ( const SResultRow * ) b ;
SRowCompSupporter * supporter = ( SRowCompSupporter * ) userData ;
2022-01-08 08:28:44 +00:00
STaskRuntimeEnv * pRuntimeEnv = supporter - > pRuntimeEnv ;
2021-11-02 05:37:31 +00:00
2022-02-10 05:49:17 +00:00
SFilePage * page1 = getBufPage ( pRuntimeEnv - > pResultBuf , pRow1 - > pageId ) ;
SFilePage * page2 = getBufPage ( pRuntimeEnv - > pResultBuf , pRow2 - > pageId ) ;
2021-11-02 05:37:31 +00:00
int16_t offset = supporter - > dataOffset ;
char * in1 = getPosInResultPage ( pRuntimeEnv - > pQueryAttr , page1 , pRow1 - > offset , offset ) ;
char * in2 = getPosInResultPage ( pRuntimeEnv - > pQueryAttr , page2 , pRow2 - > offset , offset ) ;
return ( in1 ! = NULL & & in2 ! = NULL ) ? supporter - > comFunc ( in1 , in2 ) : 0 ;
}
2022-01-08 08:28:44 +00:00
static void sortGroupResByOrderList ( SGroupResInfo * pGroupResInfo , STaskRuntimeEnv * pRuntimeEnv , SSDataBlock * pDataBlock ) {
2021-11-02 05:37:31 +00:00
SArray * columnOrderList = getOrderCheckColumns ( pRuntimeEnv - > pQueryAttr ) ;
size_t size = taosArrayGetSize ( columnOrderList ) ;
taosArrayDestroy ( columnOrderList ) ;
if ( size < = 0 ) {
return ;
}
2021-12-06 06:44:27 +00:00
int32_t orderId = pRuntimeEnv - > pQueryAttr - > order . col . info . colId ;
2021-11-02 05:37:31 +00:00
if ( orderId < = 0 ) {
return ;
}
bool found = false ;
int16_t dataOffset = 0 ;
for ( int32_t j = 0 ; j < pDataBlock - > info . numOfCols ; + + j ) {
SColumnInfoData * pColInfoData = ( SColumnInfoData * ) taosArrayGet ( pDataBlock - > pDataBlock , j ) ;
if ( orderId = = j ) {
found = true ;
break ;
}
dataOffset + = pColInfoData - > info . bytes ;
}
if ( found = = false ) {
return ;
}
int16_t type = pRuntimeEnv - > pQueryAttr - > pExpr1 [ orderId ] . base . resSchema . type ;
SRowCompSupporter support = { . pRuntimeEnv = pRuntimeEnv , . dataOffset = dataOffset , . comFunc = getComparFunc ( type , 0 ) } ;
taosArraySortPWithExt ( pGroupResInfo - > pRows , compareRowData , & support ) ;
}
//setup the output buffer for each operator
SSDataBlock * createOutputBuf ( SExprInfo * pExpr , int32_t numOfOutput , int32_t numOfRows ) {
const static int32_t minSize = 8 ;
SSDataBlock * res = calloc ( 1 , sizeof ( SSDataBlock ) ) ;
res - > info . numOfCols = numOfOutput ;
res - > pDataBlock = taosArrayInit ( numOfOutput , sizeof ( SColumnInfoData ) ) ;
for ( int32_t i = 0 ; i < numOfOutput ; + + i ) {
SColumnInfoData idata = { { 0 } } ;
idata . info . type = pExpr [ i ] . base . resSchema . type ;
idata . info . bytes = pExpr [ i ] . base . resSchema . bytes ;
idata . info . colId = pExpr [ i ] . base . resSchema . colId ;
2022-01-24 04:53:17 +00:00
int32_t size = TMAX ( idata . info . bytes * numOfRows , minSize ) ;
2021-11-02 05:37:31 +00:00
idata . pData = calloc ( 1 , size ) ; // at least to hold a pointer on x64 platform
taosArrayPush ( res - > pDataBlock , & idata ) ;
}
return res ;
}
2022-01-20 05:52:46 +00:00
SSDataBlock * createOutputBuf_rv ( SArray * pExprInfo , int32_t numOfRows ) {
const static int32_t minSize = 8 ;
size_t numOfOutput = taosArrayGetSize ( pExprInfo ) ;
SSDataBlock * res = calloc ( 1 , sizeof ( SSDataBlock ) ) ;
res - > info . numOfCols = numOfOutput ;
res - > pDataBlock = taosArrayInit ( numOfOutput , sizeof ( SColumnInfoData ) ) ;
for ( int32_t i = 0 ; i < numOfOutput ; + + i ) {
SColumnInfoData idata = { { 0 } } ;
2022-01-20 09:10:28 +00:00
SExprInfo * pExpr = taosArrayGetP ( pExprInfo , i ) ;
2022-01-20 05:52:46 +00:00
idata . info . type = pExpr - > base . resSchema . type ;
idata . info . bytes = pExpr - > base . resSchema . bytes ;
idata . info . colId = pExpr - > base . resSchema . colId ;
2022-01-24 04:53:17 +00:00
int32_t size = TMAX ( idata . info . bytes * numOfRows , minSize ) ;
2022-01-20 05:52:46 +00:00
idata . pData = calloc ( 1 , size ) ; // at least to hold a pointer on x64 platform
taosArrayPush ( res - > pDataBlock , & idata ) ;
}
return res ;
}
2022-01-28 02:44:02 +00:00
static bool isSelectivityWithTagsQuery ( SqlFunctionCtx * pCtx , int32_t numOfOutput ) {
2021-11-02 05:37:31 +00:00
return true ;
// bool hasTags = false;
// int32_t numOfSelectivity = 0;
//
// for (int32_t i = 0; i < numOfOutput; ++i) {
// int32_t functId = pCtx[i].functionId;
// if (functId == FUNCTION_TAG_DUMMY || functId == FUNCTION_TS_DUMMY) {
// hasTags = true;
// continue;
// }
//
// if ((aAggs[functId].status & FUNCSTATE_SELECTIVITY) != 0) {
// numOfSelectivity++;
// }
// }
//
// return (numOfSelectivity > 0 && hasTags);
}
2022-01-08 08:28:44 +00:00
static bool isProjQuery ( STaskAttr * pQueryAttr ) {
2021-11-02 05:37:31 +00:00
for ( int32_t i = 0 ; i < pQueryAttr - > numOfOutput ; + + i ) {
int32_t functId = getExprFunctionId ( & pQueryAttr - > pExpr1 [ i ] ) ;
if ( functId ! = FUNCTION_PRJ & & functId ! = FUNCTION_TAGPRJ ) {
return false ;
}
}
return true ;
}
2022-01-20 09:10:28 +00:00
static bool hasNull ( SColumn * pColumn , SColumnDataAgg * pStatis ) {
if ( TSDB_COL_IS_TAG ( pColumn - > flag ) | | TSDB_COL_IS_UD_COL ( pColumn - > flag ) | | pColumn - > info . colId = = PRIMARYKEY_TIMESTAMP_COL_ID ) {
2021-11-02 05:37:31 +00:00
return false ;
}
if ( pStatis ! = NULL & & pStatis - > numOfNull = = 0 ) {
return false ;
}
return true ;
}
2022-01-20 05:52:46 +00:00
static void prepareResultListBuffer ( SResultRowInfo * pResultRowInfo , jmp_buf env ) {
2021-11-02 05:37:31 +00:00
// more than the capacity, reallocate the resources
if ( pResultRowInfo - > size < pResultRowInfo - > capacity ) {
return ;
}
int64_t newCapacity = 0 ;
if ( pResultRowInfo - > capacity > 10000 ) {
newCapacity = ( int64_t ) ( pResultRowInfo - > capacity * 1.25 ) ;
} else {
newCapacity = ( int64_t ) ( pResultRowInfo - > capacity * 1.5 ) ;
}
char * t = realloc ( pResultRowInfo - > pResult , ( size_t ) ( newCapacity * POINTER_BYTES ) ) ;
if ( t = = NULL ) {
2022-01-20 05:52:46 +00:00
longjmp ( env , TSDB_CODE_QRY_OUT_OF_MEMORY ) ;
2021-11-02 05:37:31 +00:00
}
pResultRowInfo - > pResult = ( SResultRow * * ) t ;
int32_t inc = ( int32_t ) newCapacity - pResultRowInfo - > capacity ;
memset ( & pResultRowInfo - > pResult [ pResultRowInfo - > capacity ] , 0 , POINTER_BYTES * inc ) ;
pResultRowInfo - > capacity = ( int32_t ) newCapacity ;
}
2022-01-08 08:28:44 +00:00
static bool chkResultRowFromKey ( STaskRuntimeEnv * pRuntimeEnv , SResultRowInfo * pResultRowInfo , char * pData ,
2021-11-02 05:37:31 +00:00
int16_t bytes , bool masterscan , uint64_t uid ) {
bool existed = false ;
SET_RES_WINDOW_KEY ( pRuntimeEnv - > keyBuf , pData , bytes , uid ) ;
SResultRow * * p1 =
( SResultRow * * ) taosHashGet ( pRuntimeEnv - > pResultRowHashTable , pRuntimeEnv - > keyBuf , GET_RES_WINDOW_KEY_LEN ( bytes ) ) ;
// in case of repeat scan/reverse scan, no new time window added.
if ( QUERY_IS_INTERVAL_QUERY ( pRuntimeEnv - > pQueryAttr ) ) {
if ( ! masterscan ) { // the *p1 may be NULL in case of sliding+offset exists.
return p1 ! = NULL ;
}
if ( p1 ! = NULL ) {
if ( pResultRowInfo - > size = = 0 ) {
existed = false ;
assert ( pResultRowInfo - > curPos = = - 1 ) ;
} else if ( pResultRowInfo - > size = = 1 ) {
existed = ( pResultRowInfo - > pResult [ 0 ] = = ( * p1 ) ) ;
} else { // check if current pResultRowInfo contains the existed pResultRow
SET_RES_EXT_WINDOW_KEY ( pRuntimeEnv - > keyBuf , pData , bytes , uid , pResultRowInfo ) ;
int64_t * index = taosHashGet ( pRuntimeEnv - > pResultRowListSet , pRuntimeEnv - > keyBuf , GET_RES_EXT_WINDOW_KEY_LEN ( bytes ) ) ;
if ( index ! = NULL ) {
existed = true ;
} else {
existed = false ;
}
}
}
return existed ;
}
return p1 ! = NULL ;
}
2022-01-08 08:28:44 +00:00
static SResultRow * doSetResultOutBufByKey ( STaskRuntimeEnv * pRuntimeEnv , SResultRowInfo * pResultRowInfo , int64_t tid ,
2021-11-02 05:37:31 +00:00
char * pData , int16_t bytes , bool masterscan , uint64_t tableGroupId ) {
bool existed = false ;
SET_RES_WINDOW_KEY ( pRuntimeEnv - > keyBuf , pData , bytes , tableGroupId ) ;
SResultRow * * p1 =
( SResultRow * * ) taosHashGet ( pRuntimeEnv - > pResultRowHashTable , pRuntimeEnv - > keyBuf , GET_RES_WINDOW_KEY_LEN ( bytes ) ) ;
// in case of repeat scan/reverse scan, no new time window added.
if ( QUERY_IS_INTERVAL_QUERY ( pRuntimeEnv - > pQueryAttr ) ) {
if ( ! masterscan ) { // the *p1 may be NULL in case of sliding+offset exists.
return ( p1 ! = NULL ) ? * p1 : NULL ;
}
if ( p1 ! = NULL ) {
if ( pResultRowInfo - > size = = 0 ) {
existed = false ;
assert ( pResultRowInfo - > curPos = = - 1 ) ;
} else if ( pResultRowInfo - > size = = 1 ) {
existed = ( pResultRowInfo - > pResult [ 0 ] = = ( * p1 ) ) ;
pResultRowInfo - > curPos = 0 ;
} else { // check if current pResultRowInfo contains the existed pResultRow
SET_RES_EXT_WINDOW_KEY ( pRuntimeEnv - > keyBuf , pData , bytes , tid , pResultRowInfo ) ;
int64_t * index = taosHashGet ( pRuntimeEnv - > pResultRowListSet , pRuntimeEnv - > keyBuf , GET_RES_EXT_WINDOW_KEY_LEN ( bytes ) ) ;
if ( index ! = NULL ) {
pResultRowInfo - > curPos = ( int32_t ) * index ;
existed = true ;
} else {
existed = false ;
}
}
}
} else {
// In case of group by column query, the required SResultRow object must be existed in the pResultRowInfo object.
if ( p1 ! = NULL ) {
return * p1 ;
}
}
if ( ! existed ) {
2022-01-20 05:52:46 +00:00
// prepareResultListBuffer(pResultRowInfo, pRuntimeEnv);
2021-11-02 05:37:31 +00:00
SResultRow * pResult = NULL ;
if ( p1 = = NULL ) {
pResult = getNewResultRow ( pRuntimeEnv - > pool ) ;
int32_t ret = initResultRow ( pResult ) ;
if ( ret ! = TSDB_CODE_SUCCESS ) {
longjmp ( pRuntimeEnv - > env , TSDB_CODE_QRY_OUT_OF_MEMORY ) ;
}
// add a new result set for a new group
taosHashPut ( pRuntimeEnv - > pResultRowHashTable , pRuntimeEnv - > keyBuf , GET_RES_WINDOW_KEY_LEN ( bytes ) , & pResult , POINTER_BYTES ) ;
SResultRowCell cell = { . groupId = tableGroupId , . pRow = pResult } ;
taosArrayPush ( pRuntimeEnv - > pResultRowArrayList , & cell ) ;
} else {
pResult = * p1 ;
}
pResultRowInfo - > curPos = pResultRowInfo - > size ;
pResultRowInfo - > pResult [ pResultRowInfo - > size + + ] = pResult ;
int64_t index = pResultRowInfo - > curPos ;
SET_RES_EXT_WINDOW_KEY ( pRuntimeEnv - > keyBuf , pData , bytes , tid , pResultRowInfo ) ;
taosHashPut ( pRuntimeEnv - > pResultRowListSet , pRuntimeEnv - > keyBuf , GET_RES_EXT_WINDOW_KEY_LEN ( bytes ) , & index , POINTER_BYTES ) ;
}
// too many time window in query
if ( pResultRowInfo - > size > MAX_INTERVAL_TIME_WINDOW ) {
longjmp ( pRuntimeEnv - > env , TSDB_CODE_QRY_TOO_MANY_TIMEWINDOW ) ;
}
return pResultRowInfo - > pResult [ pResultRowInfo - > curPos ] ;
}
2022-01-20 05:52:46 +00:00
static SResultRow * doSetResultOutBufByKey_rv ( SResultRowInfo * pResultRowInfo , int64_t tid , char * pData , int16_t bytes ,
bool masterscan , uint64_t tableGroupId , SExecTaskInfo * pTaskInfo , bool isIntervalQuery , SAggOperatorInfo * pAggInfo ) {
bool existed = false ;
SET_RES_WINDOW_KEY ( pAggInfo - > keyBuf , pData , bytes , tableGroupId ) ;
SResultRow * * p1 =
( SResultRow * * ) taosHashGet ( pAggInfo - > pResultRowHashTable , pAggInfo - > keyBuf , GET_RES_WINDOW_KEY_LEN ( bytes ) ) ;
// in case of repeat scan/reverse scan, no new time window added.
if ( isIntervalQuery ) {
if ( ! masterscan ) { // the *p1 may be NULL in case of sliding+offset exists.
return ( p1 ! = NULL ) ? * p1 : NULL ;
}
if ( p1 ! = NULL ) {
if ( pResultRowInfo - > size = = 0 ) {
existed = false ;
assert ( pResultRowInfo - > curPos = = - 1 ) ;
} else if ( pResultRowInfo - > size = = 1 ) {
existed = ( pResultRowInfo - > pResult [ 0 ] = = ( * p1 ) ) ;
pResultRowInfo - > curPos = 0 ;
} else { // check if current pResultRowInfo contains the existed pResultRow
SET_RES_EXT_WINDOW_KEY ( pAggInfo - > keyBuf , pData , bytes , tid , pResultRowInfo ) ;
int64_t * index = taosHashGet ( pAggInfo - > pResultRowListSet , pAggInfo - > keyBuf , GET_RES_EXT_WINDOW_KEY_LEN ( bytes ) ) ;
if ( index ! = NULL ) {
pResultRowInfo - > curPos = ( int32_t ) * index ;
existed = true ;
} else {
existed = false ;
}
}
}
} else {
// In case of group by column query, the required SResultRow object must be existed in the pResultRowInfo object.
if ( p1 ! = NULL ) {
return * p1 ;
}
}
if ( ! existed ) {
prepareResultListBuffer ( pResultRowInfo , pTaskInfo - > env ) ;
SResultRow * pResult = NULL ;
if ( p1 = = NULL ) {
pResult = getNewResultRow ( pAggInfo - > pool ) ;
int32_t ret = initResultRow ( pResult ) ;
if ( ret ! = TSDB_CODE_SUCCESS ) {
longjmp ( pTaskInfo - > env , TSDB_CODE_QRY_OUT_OF_MEMORY ) ;
}
// add a new result set for a new group
taosHashPut ( pAggInfo - > pResultRowHashTable , pAggInfo - > keyBuf , GET_RES_WINDOW_KEY_LEN ( bytes ) , & pResult , POINTER_BYTES ) ;
SResultRowCell cell = { . groupId = tableGroupId , . pRow = pResult } ;
taosArrayPush ( pAggInfo - > pResultRowArrayList , & cell ) ;
} else {
pResult = * p1 ;
}
pResultRowInfo - > curPos = pResultRowInfo - > size ;
pResultRowInfo - > pResult [ pResultRowInfo - > size + + ] = pResult ;
int64_t index = pResultRowInfo - > curPos ;
SET_RES_EXT_WINDOW_KEY ( pAggInfo - > keyBuf , pData , bytes , tid , pResultRowInfo ) ;
taosHashPut ( pAggInfo - > pResultRowListSet , pAggInfo - > keyBuf , GET_RES_EXT_WINDOW_KEY_LEN ( bytes ) , & index , POINTER_BYTES ) ;
}
// too many time window in query
if ( pResultRowInfo - > size > MAX_INTERVAL_TIME_WINDOW ) {
longjmp ( pTaskInfo - > env , TSDB_CODE_QRY_TOO_MANY_TIMEWINDOW ) ;
}
return pResultRowInfo - > pResult [ pResultRowInfo - > curPos ] ;
}
2022-01-08 08:28:44 +00:00
static void getInitialStartTimeWindow ( STaskAttr * pQueryAttr , TSKEY ts , STimeWindow * w ) {
2021-11-02 05:37:31 +00:00
if ( QUERY_IS_ASC_QUERY ( pQueryAttr ) ) {
getAlignQueryTimeWindow ( pQueryAttr , ts , ts , pQueryAttr - > window . ekey , w ) ;
} else {
// the start position of the first time window in the endpoint that spreads beyond the queried last timestamp
getAlignQueryTimeWindow ( pQueryAttr , ts , pQueryAttr - > window . ekey , ts , w ) ;
int64_t key = w - > skey ;
while ( key < ts ) { // moving towards end
if ( pQueryAttr - > interval . intervalUnit = = ' n ' | | pQueryAttr - > interval . intervalUnit = = ' y ' ) {
key = taosTimeAdd ( key , pQueryAttr - > interval . sliding , pQueryAttr - > interval . slidingUnit , pQueryAttr - > precision ) ;
} else {
key + = pQueryAttr - > interval . sliding ;
}
if ( key > = ts ) {
break ;
}
w - > skey = key ;
}
}
}
// get the correct time window according to the handled timestamp
2022-01-08 08:28:44 +00:00
static STimeWindow getActiveTimeWindow ( SResultRowInfo * pResultRowInfo , int64_t ts , STaskAttr * pQueryAttr ) {
2021-11-02 05:37:31 +00:00
STimeWindow w = { 0 } ;
if ( pResultRowInfo - > curPos = = - 1 ) { // the first window, from the previous stored value
getInitialStartTimeWindow ( pQueryAttr , ts , & w ) ;
if ( pQueryAttr - > interval . intervalUnit = = ' n ' | | pQueryAttr - > interval . intervalUnit = = ' y ' ) {
w . ekey = taosTimeAdd ( w . skey , pQueryAttr - > interval . interval , pQueryAttr - > interval . intervalUnit , pQueryAttr - > precision ) - 1 ;
} else {
w . ekey = w . skey + pQueryAttr - > interval . interval - 1 ;
}
} else {
w = getResultRow ( pResultRowInfo , pResultRowInfo - > curPos ) - > win ;
}
if ( w . skey > ts | | w . ekey < ts ) {
if ( pQueryAttr - > interval . intervalUnit = = ' n ' | | pQueryAttr - > interval . intervalUnit = = ' y ' ) {
w . skey = taosTimeTruncate ( ts , & pQueryAttr - > interval , pQueryAttr - > precision ) ;
w . ekey = taosTimeAdd ( w . skey , pQueryAttr - > interval . interval , pQueryAttr - > interval . intervalUnit , pQueryAttr - > precision ) - 1 ;
} else {
int64_t st = w . skey ;
if ( st > ts ) {
st - = ( ( st - ts + pQueryAttr - > interval . sliding - 1 ) / pQueryAttr - > interval . sliding ) * pQueryAttr - > interval . sliding ;
}
int64_t et = st + pQueryAttr - > interval . interval - 1 ;
if ( et < ts ) {
st + = ( ( ts - et + pQueryAttr - > interval . sliding - 1 ) / pQueryAttr - > interval . sliding ) * pQueryAttr - > interval . sliding ;
}
w . skey = st ;
w . ekey = w . skey + pQueryAttr - > interval . interval - 1 ;
}
}
/*
* query border check , skey should not be bounded by the query time range , since the value skey will
* be used as the time window index value . So we only change ekey of time window accordingly .
*/
if ( w . ekey > pQueryAttr - > window . ekey & & QUERY_IS_ASC_QUERY ( pQueryAttr ) ) {
w . ekey = pQueryAttr - > window . ekey ;
}
return w ;
}
// get the correct time window according to the handled timestamp
2022-01-08 08:28:44 +00:00
static STimeWindow getCurrentActiveTimeWindow ( SResultRowInfo * pResultRowInfo , int64_t ts , STaskAttr * pQueryAttr ) {
2021-11-02 05:37:31 +00:00
STimeWindow w = { 0 } ;
if ( pResultRowInfo - > curPos = = - 1 ) { // the first window, from the previous stored value
getInitialStartTimeWindow ( pQueryAttr , ts , & w ) ;
if ( pQueryAttr - > interval . intervalUnit = = ' n ' | | pQueryAttr - > interval . intervalUnit = = ' y ' ) {
w . ekey = taosTimeAdd ( w . skey , pQueryAttr - > interval . interval , pQueryAttr - > interval . intervalUnit , pQueryAttr - > precision ) - 1 ;
} else {
w . ekey = w . skey + pQueryAttr - > interval . interval - 1 ;
}
} else {
w = getResultRow ( pResultRowInfo , pResultRowInfo - > curPos ) - > win ;
}
/*
* query border check , skey should not be bounded by the query time range , since the value skey will
* be used as the time window index value . So we only change ekey of time window accordingly .
*/
if ( w . ekey > pQueryAttr - > window . ekey & & QUERY_IS_ASC_QUERY ( pQueryAttr ) ) {
w . ekey = pQueryAttr - > window . ekey ;
}
return w ;
}
// a new buffer page for each table. Needs to opt this design
2022-02-08 02:21:00 +00:00
static int32_t addNewWindowResultBuf ( SResultRow * pWindowRes , SDiskbasedBuf * pResultBuf , int32_t tid , uint32_t size ) {
2021-11-02 05:37:31 +00:00
if ( pWindowRes - > pageId ! = - 1 ) {
return 0 ;
}
SFilePage * pData = NULL ;
// in the first scan, new space needed for results
int32_t pageId = - 1 ;
SIDList list = getDataBufPagesIdList ( pResultBuf , tid ) ;
if ( taosArrayGetSize ( list ) = = 0 ) {
pData = getNewDataBuf ( pResultBuf , tid , & pageId ) ;
} else {
SPageInfo * pi = getLastPageInfo ( list ) ;
2022-02-10 05:49:17 +00:00
pData = getBufPage ( pResultBuf , getPageId ( pi ) ) ;
2022-02-08 02:21:00 +00:00
pageId = getPageId ( pi ) ;
2021-11-02 05:37:31 +00:00
2022-02-08 02:21:00 +00:00
if ( pData - > num + size > getBufPageSize ( pResultBuf ) ) {
2021-11-02 05:37:31 +00:00
// release current page first, and prepare the next one
2022-02-10 05:49:17 +00:00
releaseBufPageInfo ( pResultBuf , pi ) ;
2021-11-02 05:37:31 +00:00
pData = getNewDataBuf ( pResultBuf , tid , & pageId ) ;
if ( pData ! = NULL ) {
assert ( pData - > num = = 0 ) ; // number of elements must be 0 for new allocated buffer
}
}
}
if ( pData = = NULL ) {
return - 1 ;
}
// set the number of rows in current disk page
if ( pWindowRes - > pageId = = - 1 ) { // not allocated yet, allocate new buffer
pWindowRes - > pageId = pageId ;
pWindowRes - > offset = ( int32_t ) pData - > num ;
pData - > num + = size ;
assert ( pWindowRes - > pageId > = 0 ) ;
}
return 0 ;
}
2022-01-08 08:28:44 +00:00
static bool chkWindowOutputBufByKey ( STaskRuntimeEnv * pRuntimeEnv , SResultRowInfo * pResultRowInfo , STimeWindow * win ,
2022-01-28 02:44:02 +00:00
bool masterscan , SResultRow * * pResult , int64_t groupId , SqlFunctionCtx * pCtx ,
2021-11-02 05:37:31 +00:00
int32_t numOfOutput , int32_t * rowCellInfoOffset ) {
assert ( win - > skey < = win - > ekey ) ;
return chkResultRowFromKey ( pRuntimeEnv , pResultRowInfo , ( char * ) & win - > skey , TSDB_KEYSIZE , masterscan , groupId ) ;
}
2022-01-08 08:28:44 +00:00
static int32_t setResultOutputBufByKey ( STaskRuntimeEnv * pRuntimeEnv , SResultRowInfo * pResultRowInfo , int64_t tid , STimeWindow * win ,
2022-01-28 02:44:02 +00:00
bool masterscan , SResultRow * * pResult , int64_t tableGroupId , SqlFunctionCtx * pCtx ,
2021-11-02 05:37:31 +00:00
int32_t numOfOutput , int32_t * rowCellInfoOffset ) {
assert ( win - > skey < = win - > ekey ) ;
2022-02-08 02:21:00 +00:00
SDiskbasedBuf * pResultBuf = pRuntimeEnv - > pResultBuf ;
2021-11-02 05:37:31 +00:00
SResultRow * pResultRow = doSetResultOutBufByKey ( pRuntimeEnv , pResultRowInfo , tid , ( char * ) & win - > skey , TSDB_KEYSIZE , masterscan , tableGroupId ) ;
if ( pResultRow = = NULL ) {
* pResult = NULL ;
return TSDB_CODE_SUCCESS ;
}
// not assign result buffer yet, add new result buffer
if ( pResultRow - > pageId = = - 1 ) {
int32_t ret = addNewWindowResultBuf ( pResultRow , pResultBuf , ( int32_t ) tableGroupId , pRuntimeEnv - > pQueryAttr - > intermediateResultRowSize ) ;
if ( ret ! = TSDB_CODE_SUCCESS ) {
return - 1 ;
}
}
// set time window for current result
pResultRow - > win = ( * win ) ;
* pResult = pResultRow ;
setResultRowOutputBufInitCtx ( pRuntimeEnv , pResultRow , pCtx , numOfOutput , rowCellInfoOffset ) ;
return TSDB_CODE_SUCCESS ;
}
static void setResultRowInterpo ( SResultRow * pResult , SResultTsInterpType type ) {
assert ( pResult ! = NULL & & ( type = = RESULT_ROW_START_INTERP | | type = = RESULT_ROW_END_INTERP ) ) ;
if ( type = = RESULT_ROW_START_INTERP ) {
pResult - > startInterp = true ;
} else {
pResult - > endInterp = true ;
}
}
static bool resultRowInterpolated ( SResultRow * pResult , SResultTsInterpType type ) {
assert ( pResult ! = NULL & & ( type = = RESULT_ROW_START_INTERP | | type = = RESULT_ROW_END_INTERP ) ) ;
if ( type = = RESULT_ROW_START_INTERP ) {
return pResult - > startInterp = = true ;
} else {
return pResult - > endInterp = = true ;
}
}
static FORCE_INLINE int32_t getForwardStepsInBlock ( int32_t numOfRows , __block_search_fn_t searchFn , TSKEY ekey , int16_t pos ,
int16_t order , int64_t * pData ) {
int32_t forwardStep = 0 ;
if ( order = = TSDB_ORDER_ASC ) {
int32_t end = searchFn ( ( char * ) & pData [ pos ] , numOfRows - pos , ekey , order ) ;
if ( end > = 0 ) {
forwardStep = end ;
if ( pData [ end + pos ] = = ekey ) {
forwardStep + = 1 ;
}
}
} else {
int32_t end = searchFn ( ( char * ) pData , pos + 1 , ekey , order ) ;
if ( end > = 0 ) {
forwardStep = pos - end ;
if ( pData [ end ] = = ekey ) {
forwardStep + = 1 ;
}
}
}
assert ( forwardStep > = 0 ) ;
return forwardStep ;
}
static void doUpdateResultRowIndex ( SResultRowInfo * pResultRowInfo , TSKEY lastKey , bool ascQuery , bool timeWindowInterpo ) {
int64_t skey = TSKEY_INITIAL_VAL ;
int32_t i = 0 ;
for ( i = pResultRowInfo - > size - 1 ; i > = 0 ; - - i ) {
SResultRow * pResult = pResultRowInfo - > pResult [ i ] ;
if ( pResult - > closed ) {
break ;
}
// new closed result rows
if ( timeWindowInterpo ) {
if ( pResult - > endInterp & & ( ( pResult - > win . skey < = lastKey & & ascQuery ) | | ( pResult - > win . skey > = lastKey & & ! ascQuery ) ) ) {
if ( i > 0 ) { // the first time window, the startInterp is false.
assert ( pResult - > startInterp ) ;
}
closeResultRow ( pResultRowInfo , i ) ;
} else {
skey = pResult - > win . skey ;
}
} else {
if ( ( pResult - > win . ekey < = lastKey & & ascQuery ) | | ( pResult - > win . skey > = lastKey & & ! ascQuery ) ) {
closeResultRow ( pResultRowInfo , i ) ;
} else {
skey = pResult - > win . skey ;
}
}
}
// all result rows are closed, set the last one to be the skey
if ( skey = = TSKEY_INITIAL_VAL ) {
if ( pResultRowInfo - > size = = 0 ) {
// assert(pResultRowInfo->current == NULL);
assert ( pResultRowInfo - > curPos = = - 1 ) ;
pResultRowInfo - > curPos = - 1 ;
} else {
pResultRowInfo - > curPos = pResultRowInfo - > size - 1 ;
}
} else {
for ( i = pResultRowInfo - > size - 1 ; i > = 0 ; - - i ) {
SResultRow * pResult = pResultRowInfo - > pResult [ i ] ;
if ( pResult - > closed ) {
break ;
}
}
if ( i = = pResultRowInfo - > size - 1 ) {
pResultRowInfo - > curPos = i ;
} else {
pResultRowInfo - > curPos = i + 1 ; // current not closed result object
}
}
}
2022-01-08 08:28:44 +00:00
static void updateResultRowInfoActiveIndex ( SResultRowInfo * pResultRowInfo , STaskAttr * pQueryAttr , TSKEY lastKey ) {
2021-11-02 05:37:31 +00:00
bool ascQuery = QUERY_IS_ASC_QUERY ( pQueryAttr ) ;
if ( ( lastKey > pQueryAttr - > window . ekey & & ascQuery ) | | ( lastKey < pQueryAttr - > window . ekey & & ( ! ascQuery ) ) ) {
closeAllResultRows ( pResultRowInfo ) ;
pResultRowInfo - > curPos = pResultRowInfo - > size - 1 ;
} else {
int32_t step = ascQuery ? 1 : - 1 ;
doUpdateResultRowIndex ( pResultRowInfo , lastKey - step , ascQuery , pQueryAttr - > timeWindowInterpo ) ;
}
}
2022-01-08 08:28:44 +00:00
static int32_t getNumOfRowsInTimeWindow ( STaskRuntimeEnv * pRuntimeEnv , SDataBlockInfo * pDataBlockInfo , TSKEY * pPrimaryColumn ,
2021-11-02 05:37:31 +00:00
int32_t startPos , TSKEY ekey , __block_search_fn_t searchFn , bool updateLastKey ) {
assert ( startPos > = 0 & & startPos < pDataBlockInfo - > rows ) ;
2022-01-08 08:28:44 +00:00
STaskAttr * pQueryAttr = pRuntimeEnv - > pQueryAttr ;
2021-11-02 05:37:31 +00:00
STableQueryInfo * item = pRuntimeEnv - > current ;
int32_t num = - 1 ;
int32_t order = pQueryAttr - > order . order ;
int32_t step = GET_FORWARD_DIRECTION_FACTOR ( order ) ;
if ( QUERY_IS_ASC_QUERY ( pQueryAttr ) ) {
if ( ekey < pDataBlockInfo - > window . ekey & & pPrimaryColumn ) {
num = getForwardStepsInBlock ( pDataBlockInfo - > rows , searchFn , ekey , startPos , order , pPrimaryColumn ) ;
if ( updateLastKey ) { // update the last key
item - > lastKey = pPrimaryColumn [ startPos + ( num - 1 ) ] + step ;
}
} else {
num = pDataBlockInfo - > rows - startPos ;
if ( updateLastKey ) {
item - > lastKey = pDataBlockInfo - > window . ekey + step ;
}
}
} else { // desc
if ( ekey > pDataBlockInfo - > window . skey & & pPrimaryColumn ) {
num = getForwardStepsInBlock ( pDataBlockInfo - > rows , searchFn , ekey , startPos , order , pPrimaryColumn ) ;
if ( updateLastKey ) { // update the last key
item - > lastKey = pPrimaryColumn [ startPos - ( num - 1 ) ] + step ;
}
} else {
num = startPos + 1 ;
if ( updateLastKey ) {
item - > lastKey = pDataBlockInfo - > window . skey + step ;
}
}
}
assert ( num > = 0 ) ;
return num ;
}
2022-01-28 02:44:02 +00:00
static void doApplyFunctions ( STaskRuntimeEnv * pRuntimeEnv , SqlFunctionCtx * pCtx , STimeWindow * pWin , int32_t offset ,
2021-11-02 05:37:31 +00:00
int32_t forwardStep , TSKEY * tsCol , int32_t numOfTotal , int32_t numOfOutput ) {
2022-01-08 08:28:44 +00:00
STaskAttr * pQueryAttr = pRuntimeEnv - > pQueryAttr ;
2021-11-02 05:37:31 +00:00
bool hasAggregates = pCtx [ 0 ] . isAggSet ;
for ( int32_t k = 0 ; k < numOfOutput ; + + k ) {
pCtx [ k ] . size = forwardStep ;
pCtx [ k ] . startTs = pWin - > skey ;
// keep it temporarialy
char * start = pCtx [ k ] . pInput ;
int32_t pos = ( QUERY_IS_ASC_QUERY ( pQueryAttr ) ) ? offset : offset - ( forwardStep - 1 ) ;
if ( pCtx [ k ] . pInput ! = NULL ) {
pCtx [ k ] . pInput = ( char * ) pCtx [ k ] . pInput + pos * pCtx [ k ] . inputBytes ;
}
if ( tsCol ! = NULL ) {
pCtx [ k ] . ptsList = & tsCol [ pos ] ;
}
// not a whole block involved in query processing, statistics data can not be used
// NOTE: the original value of isSet have been changed here
if ( pCtx [ k ] . isAggSet & & forwardStep < numOfTotal ) {
pCtx [ k ] . isAggSet = false ;
}
if ( functionNeedToExecute ( pRuntimeEnv , & pCtx [ k ] ) ) {
2021-11-02 07:08:00 +00:00
pCtx [ k ] . fpSet - > addInput ( & pCtx [ k ] ) ;
2021-11-02 05:37:31 +00:00
}
// restore it
pCtx [ k ] . isAggSet = hasAggregates ;
pCtx [ k ] . pInput = start ;
}
}
2022-01-08 08:28:44 +00:00
static int32_t getNextQualifiedWindow ( STaskAttr * pQueryAttr , STimeWindow * pNext , SDataBlockInfo * pDataBlockInfo ,
2021-11-02 07:08:00 +00:00
TSKEY * primaryKeys , __block_search_fn_t searchFn , int32_t prevPosition ) {
2021-11-02 05:37:31 +00:00
getNextTimeWindow ( pQueryAttr , pNext ) ;
// next time window is not in current block
if ( ( pNext - > skey > pDataBlockInfo - > window . ekey & & QUERY_IS_ASC_QUERY ( pQueryAttr ) ) | |
( pNext - > ekey < pDataBlockInfo - > window . skey & & ! QUERY_IS_ASC_QUERY ( pQueryAttr ) ) ) {
return - 1 ;
}
TSKEY startKey = - 1 ;
if ( QUERY_IS_ASC_QUERY ( pQueryAttr ) ) {
startKey = pNext - > skey ;
if ( startKey < pQueryAttr - > window . skey ) {
startKey = pQueryAttr - > window . skey ;
}
} else {
startKey = pNext - > ekey ;
if ( startKey > pQueryAttr - > window . skey ) {
startKey = pQueryAttr - > window . skey ;
}
}
int32_t startPos = 0 ;
// tumbling time window query, a special case of sliding time window query
if ( pQueryAttr - > interval . sliding = = pQueryAttr - > interval . interval & & prevPosition ! = - 1 ) {
int32_t factor = GET_FORWARD_DIRECTION_FACTOR ( pQueryAttr - > order . order ) ;
startPos = prevPosition + factor ;
} else {
if ( startKey < = pDataBlockInfo - > window . skey & & QUERY_IS_ASC_QUERY ( pQueryAttr ) ) {
startPos = 0 ;
} else if ( startKey > = pDataBlockInfo - > window . ekey & & ! QUERY_IS_ASC_QUERY ( pQueryAttr ) ) {
startPos = pDataBlockInfo - > rows - 1 ;
} else {
startPos = searchFn ( ( char * ) primaryKeys , pDataBlockInfo - > rows , startKey , pQueryAttr - > order . order ) ;
}
}
/* interp query with fill should not skip time window */
if ( pQueryAttr - > pointInterpQuery & & pQueryAttr - > fillType ! = TSDB_FILL_NONE ) {
return startPos ;
}
/*
* This time window does not cover any data , try next time window ,
* this case may happen when the time window is too small
*/
if ( primaryKeys = = NULL ) {
if ( QUERY_IS_ASC_QUERY ( pQueryAttr ) ) {
assert ( pDataBlockInfo - > window . skey < = pNext - > ekey ) ;
} else {
assert ( pDataBlockInfo - > window . ekey > = pNext - > skey ) ;
}
} else {
if ( QUERY_IS_ASC_QUERY ( pQueryAttr ) & & primaryKeys [ startPos ] > pNext - > ekey ) {
TSKEY next = primaryKeys [ startPos ] ;
if ( pQueryAttr - > interval . intervalUnit = = ' n ' | | pQueryAttr - > interval . intervalUnit = = ' y ' ) {
pNext - > skey = taosTimeTruncate ( next , & pQueryAttr - > interval , pQueryAttr - > precision ) ;
pNext - > ekey = taosTimeAdd ( pNext - > skey , pQueryAttr - > interval . interval , pQueryAttr - > interval . intervalUnit , pQueryAttr - > precision ) - 1 ;
} else {
pNext - > ekey + = ( ( next - pNext - > ekey + pQueryAttr - > interval . sliding - 1 ) / pQueryAttr - > interval . sliding ) * pQueryAttr - > interval . sliding ;
pNext - > skey = pNext - > ekey - pQueryAttr - > interval . interval + 1 ;
}
} else if ( ( ! QUERY_IS_ASC_QUERY ( pQueryAttr ) ) & & primaryKeys [ startPos ] < pNext - > skey ) {
TSKEY next = primaryKeys [ startPos ] ;
if ( pQueryAttr - > interval . intervalUnit = = ' n ' | | pQueryAttr - > interval . intervalUnit = = ' y ' ) {
pNext - > skey = taosTimeTruncate ( next , & pQueryAttr - > interval , pQueryAttr - > precision ) ;
pNext - > ekey = taosTimeAdd ( pNext - > skey , pQueryAttr - > interval . interval , pQueryAttr - > interval . intervalUnit , pQueryAttr - > precision ) - 1 ;
} else {
pNext - > skey - = ( ( pNext - > skey - next + pQueryAttr - > interval . sliding - 1 ) / pQueryAttr - > interval . sliding ) * pQueryAttr - > interval . sliding ;
pNext - > ekey = pNext - > skey + pQueryAttr - > interval . interval - 1 ;
}
}
}
return startPos ;
}
2022-01-08 08:28:44 +00:00
static FORCE_INLINE TSKEY reviseWindowEkey ( STaskAttr * pQueryAttr , STimeWindow * pWindow ) {
2021-11-02 05:37:31 +00:00
TSKEY ekey = - 1 ;
if ( QUERY_IS_ASC_QUERY ( pQueryAttr ) ) {
ekey = pWindow - > ekey ;
if ( ekey > pQueryAttr - > window . ekey ) {
ekey = pQueryAttr - > window . ekey ;
}
} else {
ekey = pWindow - > skey ;
if ( ekey < pQueryAttr - > window . ekey ) {
ekey = pQueryAttr - > window . ekey ;
}
}
return ekey ;
}
2022-01-28 02:44:02 +00:00
static void setNotInterpoWindowKey ( SqlFunctionCtx * pCtx , int32_t numOfOutput , int32_t type ) {
2021-11-02 05:37:31 +00:00
if ( type = = RESULT_ROW_START_INTERP ) {
for ( int32_t k = 0 ; k < numOfOutput ; + + k ) {
pCtx [ k ] . start . key = INT64_MIN ;
}
} else {
for ( int32_t k = 0 ; k < numOfOutput ; + + k ) {
pCtx [ k ] . end . key = INT64_MIN ;
}
}
}
2022-01-08 08:28:44 +00:00
static void saveDataBlockLastRow ( STaskRuntimeEnv * pRuntimeEnv , SDataBlockInfo * pDataBlockInfo , SArray * pDataBlock ,
2021-11-02 05:37:31 +00:00
int32_t rowIndex ) {
if ( pDataBlock = = NULL ) {
return ;
}
2022-01-08 08:28:44 +00:00
STaskAttr * pQueryAttr = pRuntimeEnv - > pQueryAttr ;
2021-11-02 05:37:31 +00:00
for ( int32_t k = 0 ; k < pQueryAttr - > numOfCols ; + + k ) {
SColumnInfoData * pColInfo = taosArrayGet ( pDataBlock , k ) ;
memcpy ( pRuntimeEnv - > prevRow [ k ] , ( ( char * ) pColInfo - > pData ) + ( pColInfo - > info . bytes * rowIndex ) , pColInfo - > info . bytes ) ;
}
}
2022-01-08 08:28:44 +00:00
static TSKEY getStartTsKey ( STaskAttr * pQueryAttr , STimeWindow * win , const TSKEY * tsCols , int32_t rows ) {
2021-11-02 05:37:31 +00:00
TSKEY ts = TSKEY_INITIAL_VAL ;
bool ascQuery = QUERY_IS_ASC_QUERY ( pQueryAttr ) ;
if ( tsCols = = NULL ) {
ts = ascQuery ? win - > skey : win - > ekey ;
} else {
int32_t offset = ascQuery ? 0 : rows - 1 ;
ts = tsCols [ offset ] ;
}
return ts ;
}
2022-01-28 02:44:02 +00:00
static void doSetInputDataBlock ( SOperatorInfo * pOperator , SqlFunctionCtx * pCtx , SSDataBlock * pBlock , int32_t order ) ;
2021-11-04 05:24:19 +00:00
2022-01-28 02:44:02 +00:00
static void doSetInputDataBlockInfo ( SOperatorInfo * pOperator , SqlFunctionCtx * pCtx , SSDataBlock * pBlock , int32_t order ) {
2021-11-02 05:37:31 +00:00
for ( int32_t i = 0 ; i < pOperator - > numOfOutput ; + + i ) {
pCtx [ i ] . order = order ;
pCtx [ i ] . size = pBlock - > info . rows ;
pCtx [ i ] . currentStage = ( uint8_t ) pOperator - > pRuntimeEnv - > scanFlag ;
2021-11-04 05:24:19 +00:00
setBlockStatisInfo ( & pCtx [ i ] , pBlock , NULL /*&pOperator->pExpr[i].base.colInfo*/ ) ;
2021-11-02 05:37:31 +00:00
}
}
2022-01-28 02:44:02 +00:00
void setInputDataBlock ( SOperatorInfo * pOperator , SqlFunctionCtx * pCtx , SSDataBlock * pBlock , int32_t order ) {
2022-01-20 09:10:28 +00:00
// if (pCtx[0].functionId == FUNCTION_ARITHM) {
2021-11-02 05:37:31 +00:00
// SScalar* pSupport = (SScalarFunctionSupport*) pCtx[0].param[1].pz;
// if (pSupport->colList == NULL) {
// doSetInputDataBlock(pOperator, pCtx, pBlock, order);
// } else {
// doSetInputDataBlockInfo(pOperator, pCtx, pBlock, order);
// }
2022-01-20 09:10:28 +00:00
// } else {
2021-11-02 05:37:31 +00:00
if ( pBlock - > pDataBlock ! = NULL ) {
doSetInputDataBlock ( pOperator , pCtx , pBlock , order ) ;
} else {
doSetInputDataBlockInfo ( pOperator , pCtx , pBlock , order ) ;
}
2022-01-20 09:10:28 +00:00
// }
2021-11-02 05:37:31 +00:00
}
2022-01-28 02:44:02 +00:00
static void doSetInputDataBlock ( SOperatorInfo * pOperator , SqlFunctionCtx * pCtx , SSDataBlock * pBlock , int32_t order ) {
2021-11-02 05:37:31 +00:00
for ( int32_t i = 0 ; i < pOperator - > numOfOutput ; + + i ) {
pCtx [ i ] . order = order ;
pCtx [ i ] . size = pBlock - > info . rows ;
2022-01-20 09:10:28 +00:00
pCtx [ i ] . currentStage = MAIN_SCAN /*(uint8_t)pOperator->pRuntimeEnv->scanFlag*/ ;
2021-11-02 05:37:31 +00:00
2022-01-20 09:10:28 +00:00
setBlockStatisInfo ( & pCtx [ i ] , pBlock , pOperator - > pExpr [ i ] . base . pColumns ) ;
2021-11-02 05:37:31 +00:00
if ( pCtx [ i ] . functionId = = FUNCTION_ARITHM ) {
// setArithParams((SScalarFunctionSupport*)pCtx[i].param[1].pz, &pOperator->pExpr[i], pBlock);
} else {
2022-01-20 09:10:28 +00:00
uint32_t flag = pOperator - > pExpr [ i ] . base . pColumns - > flag ;
if ( TSDB_COL_IS_NORMAL_COL ( flag ) /*|| (pCtx[i].functionId == FUNCTION_BLKINFO) ||
( TSDB_COL_IS_TAG ( flag ) & & pOperator - > pRuntimeEnv - > scanFlag = = MERGE_STAGE ) */ ) {
SColumn * pCol = pOperator - > pExpr [ i ] . base . pColumns ;
if ( pCtx [ i ] . columnIndex = = - 1 ) {
for ( int32_t j = 0 ; j < pBlock - > info . numOfCols ; + + j ) {
SColumnInfoData * pColData = taosArrayGet ( pBlock - > pDataBlock , j ) ;
if ( pColData - > info . colId = = pCol - > info . colId ) {
pCtx [ i ] . columnIndex = j ;
break ;
}
}
}
2021-11-02 05:37:31 +00:00
2022-01-20 09:10:28 +00:00
SColumnInfoData * p = taosArrayGet ( pBlock - > pDataBlock , pCtx [ i ] . columnIndex ) ;
2021-11-02 05:37:31 +00:00
// in case of the block distribution query, the inputBytes is not a constant value.
pCtx [ i ] . pInput = p - > pData ;
2022-01-20 09:10:28 +00:00
assert ( p - > info . colId = = pCol - > info . colId ) ;
2021-11-02 05:37:31 +00:00
if ( pCtx [ i ] . functionId < 0 ) {
SColumnInfoData * tsInfo = taosArrayGet ( pBlock - > pDataBlock , 0 ) ;
pCtx [ i ] . ptsList = ( int64_t * ) tsInfo - > pData ;
continue ;
}
// uint32_t status = aAggs[pCtx[i].functionId].status;
// if ((status & (FUNCSTATE_SELECTIVITY | FUNCSTATE_NEED_TS)) != 0) {
2022-01-20 09:10:28 +00:00
SColumnInfoData * tsInfo = taosArrayGet ( pBlock - > pDataBlock , 0 ) ;
// In case of the top/bottom query again the nest query result, which has no timestamp column
// don't set the ptsList attribute.
if ( tsInfo - > info . type = = TSDB_DATA_TYPE_TIMESTAMP ) {
pCtx [ i ] . ptsList = ( int64_t * ) tsInfo - > pData ;
} else {
pCtx [ i ] . ptsList = NULL ;
}
// }
// } else if (TSDB_COL_IS_UD_COL(pCol->flag) && (pOperator->pRuntimeEnv->scanFlag == MERGE_STAGE)) {
// SColIndex* pColIndex = &pOperator->pExpr[i].base.colInfo;
// SColumnInfoData* p = taosArrayGet(pBlock->pDataBlock, pColIndex->colIndex);
//
// pCtx[i].pInput = p->pData;
// assert(p->info.colId == pColIndex->info.colId && pCtx[i].inputType == p->info.type);
// for(int32_t j = 0; j < pBlock->info.rows; ++j) {
// char* dst = p->pData + j * p->info.bytes;
// taosVariantDump(&pOperator->pExpr[i].base.param[1], dst, p->info.type, true);
2021-11-02 05:37:31 +00:00
// }
}
}
}
}
2022-01-28 02:44:02 +00:00
static void doAggregateImpl ( SOperatorInfo * pOperator , TSKEY startTs , SqlFunctionCtx * pCtx , SSDataBlock * pSDataBlock ) {
2021-11-02 05:37:31 +00:00
for ( int32_t k = 0 ; k < pOperator - > numOfOutput ; + + k ) {
2022-01-20 08:02:09 +00:00
if ( functionNeedToExecute ( NULL , & pCtx [ k ] ) ) {
2021-11-02 05:37:31 +00:00
pCtx [ k ] . startTs = startTs ; // this can be set during create the struct
2021-11-02 07:08:00 +00:00
pCtx [ k ] . fpSet - > addInput ( & pCtx [ k ] ) ;
2021-11-02 05:37:31 +00:00
}
}
}
2022-01-28 02:44:02 +00:00
static void projectApplyFunctions ( STaskRuntimeEnv * pRuntimeEnv , SqlFunctionCtx * pCtx , int32_t numOfOutput ) {
2022-01-08 08:28:44 +00:00
STaskAttr * pQueryAttr = pRuntimeEnv - > pQueryAttr ;
2021-11-02 05:37:31 +00:00
for ( int32_t k = 0 ; k < numOfOutput ; + + k ) {
pCtx [ k ] . startTs = pQueryAttr - > window . skey ;
// Always set the asc order for merge stage process
if ( pCtx [ k ] . currentStage = = MERGE_STAGE ) {
pCtx [ k ] . order = TSDB_ORDER_ASC ;
}
pCtx [ k ] . startTs = pQueryAttr - > window . skey ;
if ( pCtx [ k ] . functionId < 0 ) {
// load the script and exec
// SUdfInfo* pUdfInfo = pRuntimeEnv->pUdfInfo;
// doInvokeUdf(pUdfInfo, &pCtx[k], 0, TSDB_UDF_FUNC_NORMAL);
// } else {
// aAggs[pCtx[k].functionId].xFunction(&pCtx[k]);
}
}
}
void doTimeWindowInterpolation ( SOperatorInfo * pOperator , SOptrBasicInfo * pInfo , SArray * pDataBlock , TSKEY prevTs ,
int32_t prevRowIndex , TSKEY curTs , int32_t curRowIndex , TSKEY windowKey , int32_t type ) {
2022-01-08 08:28:44 +00:00
STaskRuntimeEnv * pRuntimeEnv = pOperator - > pRuntimeEnv ;
2021-11-02 05:37:31 +00:00
SExprInfo * pExpr = pOperator - > pExpr ;
2022-01-28 02:44:02 +00:00
SqlFunctionCtx * pCtx = pInfo - > pCtx ;
2021-11-02 05:37:31 +00:00
for ( int32_t k = 0 ; k < pOperator - > numOfOutput ; + + k ) {
int32_t functionId = pCtx [ k ] . functionId ;
if ( functionId ! = FUNCTION_TWA & & functionId ! = FUNCTION_INTERP ) {
pCtx [ k ] . start . key = INT64_MIN ;
continue ;
}
2021-11-05 02:35:50 +00:00
SColIndex * pColIndex = NULL /*&pExpr[k].base.colInfo*/ ;
2021-11-02 05:37:31 +00:00
int16_t index = pColIndex - > colIndex ;
SColumnInfoData * pColInfo = taosArrayGet ( pDataBlock , index ) ;
2021-11-05 02:35:50 +00:00
// assert(pColInfo->info.colId == pColIndex->info.colId && curTs != windowKey);
2021-11-02 05:37:31 +00:00
double v1 = 0 , v2 = 0 , v = 0 ;
if ( prevRowIndex = = - 1 ) {
GET_TYPED_DATA ( v1 , double , pColInfo - > info . type , ( char * ) pRuntimeEnv - > prevRow [ index ] ) ;
} else {
GET_TYPED_DATA ( v1 , double , pColInfo - > info . type , ( char * ) pColInfo - > pData + prevRowIndex * pColInfo - > info . bytes ) ;
}
GET_TYPED_DATA ( v2 , double , pColInfo - > info . type , ( char * ) pColInfo - > pData + curRowIndex * pColInfo - > info . bytes ) ;
if ( functionId = = FUNCTION_INTERP ) {
if ( type = = RESULT_ROW_START_INTERP ) {
pCtx [ k ] . start . key = prevTs ;
pCtx [ k ] . start . val = v1 ;
pCtx [ k ] . end . key = curTs ;
pCtx [ k ] . end . val = v2 ;
if ( pColInfo - > info . type = = TSDB_DATA_TYPE_BINARY | | pColInfo - > info . type = = TSDB_DATA_TYPE_NCHAR ) {
if ( prevRowIndex = = - 1 ) {
pCtx [ k ] . start . ptr = ( char * ) pRuntimeEnv - > prevRow [ index ] ;
} else {
pCtx [ k ] . start . ptr = ( char * ) pColInfo - > pData + prevRowIndex * pColInfo - > info . bytes ;
}
pCtx [ k ] . end . ptr = ( char * ) pColInfo - > pData + curRowIndex * pColInfo - > info . bytes ;
}
}
} else if ( functionId = = FUNCTION_TWA ) {
SPoint point1 = ( SPoint ) { . key = prevTs , . val = & v1 } ;
SPoint point2 = ( SPoint ) { . key = curTs , . val = & v2 } ;
SPoint point = ( SPoint ) { . key = windowKey , . val = & v } ;
taosGetLinearInterpolationVal ( & point , TSDB_DATA_TYPE_DOUBLE , & point1 , & point2 , TSDB_DATA_TYPE_DOUBLE ) ;
if ( type = = RESULT_ROW_START_INTERP ) {
pCtx [ k ] . start . key = point . key ;
pCtx [ k ] . start . val = v ;
} else {
pCtx [ k ] . end . key = point . key ;
pCtx [ k ] . end . val = v ;
}
}
}
}
2022-01-28 02:44:02 +00:00
static bool setTimeWindowInterpolationStartTs ( SOperatorInfo * pOperatorInfo , SqlFunctionCtx * pCtx , int32_t pos ,
2021-11-02 05:37:31 +00:00
int32_t numOfRows , SArray * pDataBlock , const TSKEY * tsCols , STimeWindow * win ) {
2022-01-08 08:28:44 +00:00
STaskRuntimeEnv * pRuntimeEnv = pOperatorInfo - > pRuntimeEnv ;
STaskAttr * pQueryAttr = pRuntimeEnv - > pQueryAttr ;
2021-11-02 05:37:31 +00:00
bool ascQuery = QUERY_IS_ASC_QUERY ( pQueryAttr ) ;
TSKEY curTs = tsCols [ pos ] ;
TSKEY lastTs = * ( TSKEY * ) pRuntimeEnv - > prevRow [ 0 ] ;
// lastTs == INT64_MIN and pos == 0 means this is the first time window, interpolation is not needed.
// start exactly from this point, no need to do interpolation
TSKEY key = ascQuery ? win - > skey : win - > ekey ;
if ( key = = curTs ) {
setNotInterpoWindowKey ( pCtx , pOperatorInfo - > numOfOutput , RESULT_ROW_START_INTERP ) ;
return true ;
}
if ( lastTs = = INT64_MIN & & ( ( pos = = 0 & & ascQuery ) | | ( pos = = ( numOfRows - 1 ) & & ! ascQuery ) ) ) {
setNotInterpoWindowKey ( pCtx , pOperatorInfo - > numOfOutput , RESULT_ROW_START_INTERP ) ;
return true ;
}
int32_t step = GET_FORWARD_DIRECTION_FACTOR ( pQueryAttr - > order . order ) ;
TSKEY prevTs = ( ( pos = = 0 & & ascQuery ) | | ( pos = = ( numOfRows - 1 ) & & ! ascQuery ) ) ? lastTs : tsCols [ pos - step ] ;
doTimeWindowInterpolation ( pOperatorInfo , pOperatorInfo - > info , pDataBlock , prevTs , pos - step , curTs , pos ,
key , RESULT_ROW_START_INTERP ) ;
return true ;
}
2022-01-28 02:44:02 +00:00
static bool setTimeWindowInterpolationEndTs ( SOperatorInfo * pOperatorInfo , SqlFunctionCtx * pCtx ,
2021-11-02 05:37:31 +00:00
int32_t endRowIndex , SArray * pDataBlock , const TSKEY * tsCols , TSKEY blockEkey , STimeWindow * win ) {
2022-01-08 08:28:44 +00:00
STaskRuntimeEnv * pRuntimeEnv = pOperatorInfo - > pRuntimeEnv ;
STaskAttr * pQueryAttr = pRuntimeEnv - > pQueryAttr ;
2021-11-02 05:37:31 +00:00
int32_t numOfOutput = pOperatorInfo - > numOfOutput ;
TSKEY actualEndKey = tsCols [ endRowIndex ] ;
TSKEY key = QUERY_IS_ASC_QUERY ( pQueryAttr ) ? win - > ekey : win - > skey ;
// not ended in current data block, do not invoke interpolation
if ( ( key > blockEkey & & QUERY_IS_ASC_QUERY ( pQueryAttr ) ) | | ( key < blockEkey & & ! QUERY_IS_ASC_QUERY ( pQueryAttr ) ) ) {
setNotInterpoWindowKey ( pCtx , numOfOutput , RESULT_ROW_END_INTERP ) ;
return false ;
}
// there is actual end point of current time window, no interpolation need
if ( key = = actualEndKey ) {
setNotInterpoWindowKey ( pCtx , numOfOutput , RESULT_ROW_END_INTERP ) ;
return true ;
}
int32_t step = GET_FORWARD_DIRECTION_FACTOR ( pQueryAttr - > order . order ) ;
int32_t nextRowIndex = endRowIndex + step ;
assert ( nextRowIndex > = 0 ) ;
TSKEY nextKey = tsCols [ nextRowIndex ] ;
doTimeWindowInterpolation ( pOperatorInfo , pOperatorInfo - > info , pDataBlock , actualEndKey , endRowIndex , nextKey ,
nextRowIndex , key , RESULT_ROW_END_INTERP ) ;
return true ;
}
2022-01-28 02:44:02 +00:00
static void doWindowBorderInterpolation ( SOperatorInfo * pOperatorInfo , SSDataBlock * pBlock , SqlFunctionCtx * pCtx ,
2021-11-02 05:37:31 +00:00
SResultRow * pResult , STimeWindow * win , int32_t startPos , int32_t forwardStep ) {
2022-01-08 08:28:44 +00:00
STaskRuntimeEnv * pRuntimeEnv = pOperatorInfo - > pRuntimeEnv ;
STaskAttr * pQueryAttr = pRuntimeEnv - > pQueryAttr ;
2021-11-02 05:37:31 +00:00
if ( ! pQueryAttr - > timeWindowInterpo ) {
return ;
}
assert ( pBlock ! = NULL ) ;
int32_t step = GET_FORWARD_DIRECTION_FACTOR ( pQueryAttr - > order . order ) ;
if ( pBlock - > pDataBlock = = NULL ) {
// tscError("pBlock->pDataBlock == NULL");
return ;
}
SColumnInfoData * pColInfo = taosArrayGet ( pBlock - > pDataBlock , 0 ) ;
TSKEY * tsCols = ( TSKEY * ) ( pColInfo - > pData ) ;
bool done = resultRowInterpolated ( pResult , RESULT_ROW_START_INTERP ) ;
if ( ! done ) { // it is not interpolated, now start to generated the interpolated value
int32_t startRowIndex = startPos ;
bool interp = setTimeWindowInterpolationStartTs ( pOperatorInfo , pCtx , startRowIndex , pBlock - > info . rows , pBlock - > pDataBlock ,
tsCols , win ) ;
if ( interp ) {
setResultRowInterpo ( pResult , RESULT_ROW_START_INTERP ) ;
}
} else {
setNotInterpoWindowKey ( pCtx , pQueryAttr - > numOfOutput , RESULT_ROW_START_INTERP ) ;
}
// point interpolation does not require the end key time window interpolation.
if ( pQueryAttr - > pointInterpQuery ) {
return ;
}
// interpolation query does not generate the time window end interpolation
done = resultRowInterpolated ( pResult , RESULT_ROW_END_INTERP ) ;
if ( ! done ) {
int32_t endRowIndex = startPos + ( forwardStep - 1 ) * step ;
TSKEY endKey = QUERY_IS_ASC_QUERY ( pQueryAttr ) ? pBlock - > info . window . ekey : pBlock - > info . window . skey ;
bool interp = setTimeWindowInterpolationEndTs ( pOperatorInfo , pCtx , endRowIndex , pBlock - > pDataBlock , tsCols , endKey , win ) ;
if ( interp ) {
setResultRowInterpo ( pResult , RESULT_ROW_END_INTERP ) ;
}
} else {
setNotInterpoWindowKey ( pCtx , pQueryAttr - > numOfOutput , RESULT_ROW_END_INTERP ) ;
}
}
static void hashIntervalAgg ( SOperatorInfo * pOperatorInfo , SResultRowInfo * pResultRowInfo , SSDataBlock * pSDataBlock , int32_t tableGroupId ) {
STableIntervalOperatorInfo * pInfo = ( STableIntervalOperatorInfo * ) pOperatorInfo - > info ;
2022-01-08 08:28:44 +00:00
STaskRuntimeEnv * pRuntimeEnv = pOperatorInfo - > pRuntimeEnv ;
2021-11-02 05:37:31 +00:00
int32_t numOfOutput = pOperatorInfo - > numOfOutput ;
2022-01-08 08:28:44 +00:00
STaskAttr * pQueryAttr = pRuntimeEnv - > pQueryAttr ;
2021-11-02 05:37:31 +00:00
int32_t step = GET_FORWARD_DIRECTION_FACTOR ( pQueryAttr - > order . order ) ;
bool ascQuery = QUERY_IS_ASC_QUERY ( pQueryAttr ) ;
int32_t prevIndex = pResultRowInfo - > curPos ;
TSKEY * tsCols = NULL ;
if ( pSDataBlock - > pDataBlock ! = NULL ) {
SColumnInfoData * pColDataInfo = taosArrayGet ( pSDataBlock - > pDataBlock , 0 ) ;
tsCols = ( int64_t * ) pColDataInfo - > pData ;
assert ( tsCols [ 0 ] = = pSDataBlock - > info . window . skey & &
tsCols [ pSDataBlock - > info . rows - 1 ] = = pSDataBlock - > info . window . ekey ) ;
}
int32_t startPos = ascQuery ? 0 : ( pSDataBlock - > info . rows - 1 ) ;
TSKEY ts = getStartTsKey ( pQueryAttr , & pSDataBlock - > info . window , tsCols , pSDataBlock - > info . rows ) ;
STimeWindow win = getActiveTimeWindow ( pResultRowInfo , ts , pQueryAttr ) ;
2022-01-08 14:59:24 +00:00
bool masterScan = IS_MAIN_SCAN ( pRuntimeEnv ) ;
2021-11-02 05:37:31 +00:00
SResultRow * pResult = NULL ;
int32_t ret = setResultOutputBufByKey ( pRuntimeEnv , pResultRowInfo , pSDataBlock - > info . uid , & win , masterScan , & pResult , tableGroupId , pInfo - > pCtx ,
numOfOutput , pInfo - > rowCellInfoOffset ) ;
if ( ret ! = TSDB_CODE_SUCCESS | | pResult = = NULL ) {
longjmp ( pRuntimeEnv - > env , TSDB_CODE_QRY_OUT_OF_MEMORY ) ;
}
int32_t forwardStep = 0 ;
TSKEY ekey = reviseWindowEkey ( pQueryAttr , & win ) ;
forwardStep =
getNumOfRowsInTimeWindow ( pRuntimeEnv , & pSDataBlock - > info , tsCols , startPos , ekey , binarySearchForKey , true ) ;
// prev time window not interpolation yet.
int32_t curIndex = pResultRowInfo - > curPos ;
if ( prevIndex ! = - 1 & & prevIndex < curIndex & & pQueryAttr - > timeWindowInterpo ) {
for ( int32_t j = prevIndex ; j < curIndex ; + + j ) { // previous time window may be all closed already.
SResultRow * pRes = getResultRow ( pResultRowInfo , j ) ;
if ( pRes - > closed ) {
assert ( resultRowInterpolated ( pRes , RESULT_ROW_START_INTERP ) & & resultRowInterpolated ( pRes , RESULT_ROW_END_INTERP ) ) ;
continue ;
}
STimeWindow w = pRes - > win ;
ret = setResultOutputBufByKey ( pRuntimeEnv , pResultRowInfo , pSDataBlock - > info . uid , & w , masterScan , & pResult ,
tableGroupId , pInfo - > pCtx , numOfOutput , pInfo - > rowCellInfoOffset ) ;
if ( ret ! = TSDB_CODE_SUCCESS ) {
longjmp ( pRuntimeEnv - > env , TSDB_CODE_QRY_OUT_OF_MEMORY ) ;
}
assert ( ! resultRowInterpolated ( pResult , RESULT_ROW_END_INTERP ) ) ;
doTimeWindowInterpolation ( pOperatorInfo , pInfo , pSDataBlock - > pDataBlock , * ( TSKEY * ) pRuntimeEnv - > prevRow [ 0 ] , - 1 ,
tsCols [ startPos ] , startPos , w . ekey , RESULT_ROW_END_INTERP ) ;
setResultRowInterpo ( pResult , RESULT_ROW_END_INTERP ) ;
setNotInterpoWindowKey ( pInfo - > pCtx , pQueryAttr - > numOfOutput , RESULT_ROW_START_INTERP ) ;
doApplyFunctions ( pRuntimeEnv , pInfo - > pCtx , & w , startPos , 0 , tsCols , pSDataBlock - > info . rows , numOfOutput ) ;
}
// restore current time window
ret = setResultOutputBufByKey ( pRuntimeEnv , pResultRowInfo , pSDataBlock - > info . uid , & win , masterScan , & pResult , tableGroupId , pInfo - > pCtx ,
numOfOutput , pInfo - > rowCellInfoOffset ) ;
if ( ret ! = TSDB_CODE_SUCCESS ) {
longjmp ( pRuntimeEnv - > env , TSDB_CODE_QRY_OUT_OF_MEMORY ) ;
}
}
// window start key interpolation
doWindowBorderInterpolation ( pOperatorInfo , pSDataBlock , pInfo - > pCtx , pResult , & win , startPos , forwardStep ) ;
doApplyFunctions ( pRuntimeEnv , pInfo - > pCtx , & win , startPos , forwardStep , tsCols , pSDataBlock - > info . rows , numOfOutput ) ;
STimeWindow nextWin = win ;
while ( 1 ) {
int32_t prevEndPos = ( forwardStep - 1 ) * step + startPos ;
startPos = getNextQualifiedWindow ( pQueryAttr , & nextWin , & pSDataBlock - > info , tsCols , binarySearchForKey , prevEndPos ) ;
if ( startPos < 0 ) {
break ;
}
// null data, failed to allocate more memory buffer
int32_t code = setResultOutputBufByKey ( pRuntimeEnv , pResultRowInfo , pSDataBlock - > info . uid , & nextWin , masterScan , & pResult , tableGroupId ,
pInfo - > pCtx , numOfOutput , pInfo - > rowCellInfoOffset ) ;
if ( code ! = TSDB_CODE_SUCCESS | | pResult = = NULL ) {
longjmp ( pRuntimeEnv - > env , TSDB_CODE_QRY_OUT_OF_MEMORY ) ;
}
ekey = reviseWindowEkey ( pQueryAttr , & nextWin ) ;
forwardStep = getNumOfRowsInTimeWindow ( pRuntimeEnv , & pSDataBlock - > info , tsCols , startPos , ekey , binarySearchForKey , true ) ;
// window start(end) key interpolation
doWindowBorderInterpolation ( pOperatorInfo , pSDataBlock , pInfo - > pCtx , pResult , & nextWin , startPos , forwardStep ) ;
doApplyFunctions ( pRuntimeEnv , pInfo - > pCtx , & nextWin , startPos , forwardStep , tsCols , pSDataBlock - > info . rows , numOfOutput ) ;
}
if ( pQueryAttr - > timeWindowInterpo ) {
int32_t rowIndex = ascQuery ? ( pSDataBlock - > info . rows - 1 ) : 0 ;
saveDataBlockLastRow ( pRuntimeEnv , & pSDataBlock - > info , pSDataBlock - > pDataBlock , rowIndex ) ;
}
updateResultRowInfoActiveIndex ( pResultRowInfo , pQueryAttr , pRuntimeEnv - > current - > lastKey ) ;
}
static void hashAllIntervalAgg ( SOperatorInfo * pOperatorInfo , SResultRowInfo * pResultRowInfo , SSDataBlock * pSDataBlock , int32_t tableGroupId ) {
STableIntervalOperatorInfo * pInfo = ( STableIntervalOperatorInfo * ) pOperatorInfo - > info ;
2022-01-08 08:28:44 +00:00
STaskRuntimeEnv * pRuntimeEnv = pOperatorInfo - > pRuntimeEnv ;
2021-11-02 05:37:31 +00:00
int32_t numOfOutput = pOperatorInfo - > numOfOutput ;
2022-01-08 08:28:44 +00:00
STaskAttr * pQueryAttr = pRuntimeEnv - > pQueryAttr ;
2021-11-02 05:37:31 +00:00
int32_t step = GET_FORWARD_DIRECTION_FACTOR ( pQueryAttr - > order . order ) ;
bool ascQuery = QUERY_IS_ASC_QUERY ( pQueryAttr ) ;
TSKEY * tsCols = NULL ;
if ( pSDataBlock - > pDataBlock ! = NULL ) {
SColumnInfoData * pColDataInfo = taosArrayGet ( pSDataBlock - > pDataBlock , 0 ) ;
tsCols = ( int64_t * ) pColDataInfo - > pData ;
assert ( tsCols [ 0 ] = = pSDataBlock - > info . window . skey & &
tsCols [ pSDataBlock - > info . rows - 1 ] = = pSDataBlock - > info . window . ekey ) ;
}
int32_t startPos = ascQuery ? 0 : ( pSDataBlock - > info . rows - 1 ) ;
TSKEY ts = getStartTsKey ( pQueryAttr , & pSDataBlock - > info . window , tsCols , pSDataBlock - > info . rows ) ;
STimeWindow win = getCurrentActiveTimeWindow ( pResultRowInfo , ts , pQueryAttr ) ;
2022-01-08 14:59:24 +00:00
bool masterScan = IS_MAIN_SCAN ( pRuntimeEnv ) ;
2021-11-02 05:37:31 +00:00
SResultRow * pResult = NULL ;
int32_t forwardStep = 0 ;
int32_t ret = 0 ;
STimeWindow preWin = win ;
while ( 1 ) {
// null data, failed to allocate more memory buffer
ret = setResultOutputBufByKey ( pRuntimeEnv , pResultRowInfo , pSDataBlock - > info . uid , & win , masterScan , & pResult ,
tableGroupId , pInfo - > pCtx , numOfOutput , pInfo - > rowCellInfoOffset ) ;
if ( ret ! = TSDB_CODE_SUCCESS ) {
longjmp ( pRuntimeEnv - > env , TSDB_CODE_QRY_OUT_OF_MEMORY ) ;
}
TSKEY ekey = reviseWindowEkey ( pQueryAttr , & win ) ;
forwardStep = getNumOfRowsInTimeWindow ( pRuntimeEnv , & pSDataBlock - > info , tsCols , startPos , ekey , binarySearchForKey , true ) ;
// window start(end) key interpolation
doWindowBorderInterpolation ( pOperatorInfo , pSDataBlock , pInfo - > pCtx , pResult , & win , startPos , forwardStep ) ;
doApplyFunctions ( pRuntimeEnv , pInfo - > pCtx , ascQuery ? & win : & preWin , startPos , forwardStep , tsCols , pSDataBlock - > info . rows , numOfOutput ) ;
preWin = win ;
int32_t prevEndPos = ( forwardStep - 1 ) * step + startPos ;
startPos = getNextQualifiedWindow ( pQueryAttr , & win , & pSDataBlock - > info , tsCols , binarySearchForKey , prevEndPos ) ;
if ( startPos < 0 ) {
if ( ( ascQuery & & win . skey < = pQueryAttr - > window . ekey ) | | ( ( ! ascQuery ) & & win . ekey > = pQueryAttr - > window . ekey ) ) {
int32_t code = setResultOutputBufByKey ( pRuntimeEnv , pResultRowInfo , pSDataBlock - > info . uid , & win , masterScan , & pResult , tableGroupId ,
pInfo - > pCtx , numOfOutput , pInfo - > rowCellInfoOffset ) ;
if ( code ! = TSDB_CODE_SUCCESS | | pResult = = NULL ) {
longjmp ( pRuntimeEnv - > env , TSDB_CODE_QRY_OUT_OF_MEMORY ) ;
}
startPos = pSDataBlock - > info . rows - 1 ;
// window start(end) key interpolation
doWindowBorderInterpolation ( pOperatorInfo , pSDataBlock , pInfo - > pCtx , pResult , & win , startPos , forwardStep ) ;
doApplyFunctions ( pRuntimeEnv , pInfo - > pCtx , ascQuery ? & win : & preWin , startPos , forwardStep , tsCols , pSDataBlock - > info . rows , numOfOutput ) ;
}
break ;
}
setResultRowInterpo ( pResult , RESULT_ROW_END_INTERP ) ;
}
if ( pQueryAttr - > timeWindowInterpo ) {
int32_t rowIndex = ascQuery ? ( pSDataBlock - > info . rows - 1 ) : 0 ;
saveDataBlockLastRow ( pRuntimeEnv , & pSDataBlock - > info , pSDataBlock - > pDataBlock , rowIndex ) ;
}
updateResultRowInfoActiveIndex ( pResultRowInfo , pQueryAttr , pRuntimeEnv - > current - > lastKey ) ;
}
static void doHashGroupbyAgg ( SOperatorInfo * pOperator , SGroupbyOperatorInfo * pInfo , SSDataBlock * pSDataBlock ) {
2022-01-08 08:28:44 +00:00
STaskRuntimeEnv * pRuntimeEnv = pOperator - > pRuntimeEnv ;
2021-11-02 05:37:31 +00:00
STableQueryInfo * item = pRuntimeEnv - > current ;
SColumnInfoData * pColInfoData = taosArrayGet ( pSDataBlock - > pDataBlock , pInfo - > colIndex ) ;
2022-01-08 08:28:44 +00:00
STaskAttr * pQueryAttr = pRuntimeEnv - > pQueryAttr ;
2021-11-02 05:37:31 +00:00
int16_t bytes = pColInfoData - > info . bytes ;
int16_t type = pColInfoData - > info . type ;
if ( type = = TSDB_DATA_TYPE_FLOAT | | type = = TSDB_DATA_TYPE_DOUBLE ) {
2022-01-10 11:48:21 +00:00
//qError("QInfo:0x%"PRIx64" group by not supported on double/float columns, abort", GET_TASKID(pRuntimeEnv));
2021-11-02 05:37:31 +00:00
return ;
}
SColumnInfoData * pFirstColData = taosArrayGet ( pSDataBlock - > pDataBlock , 0 ) ;
int64_t * tsList = ( pFirstColData - > info . type = = TSDB_DATA_TYPE_TIMESTAMP ) ? ( int64_t * ) pFirstColData - > pData : NULL ;
STimeWindow w = TSWINDOW_INITIALIZER ;
int32_t num = 0 ;
for ( int32_t j = 0 ; j < pSDataBlock - > info . rows ; + + j ) {
char * val = ( ( char * ) pColInfoData - > pData ) + bytes * j ;
if ( isNull ( val , type ) ) {
continue ;
}
// Compare with the previous row of this column, and do not set the output buffer again if they are identical.
if ( pInfo - > prevData = = NULL ) {
pInfo - > prevData = malloc ( bytes ) ;
memcpy ( pInfo - > prevData , val , bytes ) ;
num + + ;
continue ;
}
if ( IS_VAR_DATA_TYPE ( type ) ) {
int32_t len = varDataLen ( val ) ;
if ( len = = varDataLen ( pInfo - > prevData ) & & memcmp ( varDataVal ( pInfo - > prevData ) , varDataVal ( val ) , len ) = = 0 ) {
num + + ;
continue ;
}
} else {
if ( memcmp ( pInfo - > prevData , val , bytes ) = = 0 ) {
num + + ;
continue ;
}
}
if ( pQueryAttr - > stableQuery & & pQueryAttr - > stabledev & & ( pRuntimeEnv - > prevResult ! = NULL ) ) {
setParamForStableStddevByColData ( pRuntimeEnv , pInfo - > binfo . pCtx , pOperator - > numOfOutput , pOperator - > pExpr , pInfo - > prevData , bytes ) ;
}
int32_t ret = setGroupResultOutputBuf ( pRuntimeEnv , & ( pInfo - > binfo ) , pOperator - > numOfOutput , pInfo - > prevData , type , bytes , item - > groupIndex ) ;
if ( ret ! = TSDB_CODE_SUCCESS ) { // null data, too many state code
longjmp ( pRuntimeEnv - > env , TSDB_CODE_QRY_APP_ERROR ) ;
}
doApplyFunctions ( pRuntimeEnv , pInfo - > binfo . pCtx , & w , j - num , num , tsList , pSDataBlock - > info . rows , pOperator - > numOfOutput ) ;
num = 1 ;
memcpy ( pInfo - > prevData , val , bytes ) ;
}
if ( num > 0 ) {
char * val = ( ( char * ) pColInfoData - > pData ) + bytes * ( pSDataBlock - > info . rows - num ) ;
memcpy ( pInfo - > prevData , val , bytes ) ;
if ( pQueryAttr - > stableQuery & & pQueryAttr - > stabledev & & ( pRuntimeEnv - > prevResult ! = NULL ) ) {
setParamForStableStddevByColData ( pRuntimeEnv , pInfo - > binfo . pCtx , pOperator - > numOfOutput , pOperator - > pExpr , val , bytes ) ;
}
int32_t ret = setGroupResultOutputBuf ( pRuntimeEnv , & ( pInfo - > binfo ) , pOperator - > numOfOutput , val , type , bytes , item - > groupIndex ) ;
if ( ret ! = TSDB_CODE_SUCCESS ) { // null data, too many state code
longjmp ( pRuntimeEnv - > env , TSDB_CODE_QRY_APP_ERROR ) ;
}
doApplyFunctions ( pRuntimeEnv , pInfo - > binfo . pCtx , & w , pSDataBlock - > info . rows - num , num , tsList , pSDataBlock - > info . rows , pOperator - > numOfOutput ) ;
}
tfree ( pInfo - > prevData ) ;
}
static void doSessionWindowAggImpl ( SOperatorInfo * pOperator , SSWindowOperatorInfo * pInfo , SSDataBlock * pSDataBlock ) {
2022-01-08 08:28:44 +00:00
STaskRuntimeEnv * pRuntimeEnv = pOperator - > pRuntimeEnv ;
2021-11-02 05:37:31 +00:00
STableQueryInfo * item = pRuntimeEnv - > current ;
// primary timestamp column
SColumnInfoData * pColInfoData = taosArrayGet ( pSDataBlock - > pDataBlock , 0 ) ;
2022-01-08 14:59:24 +00:00
bool masterScan = IS_MAIN_SCAN ( pRuntimeEnv ) ;
2021-11-02 05:37:31 +00:00
SOptrBasicInfo * pBInfo = & pInfo - > binfo ;
int64_t gap = pOperator - > pRuntimeEnv - > pQueryAttr - > sw . gap ;
pInfo - > numOfRows = 0 ;
if ( IS_REPEAT_SCAN ( pRuntimeEnv ) & & ! pInfo - > reptScan ) {
pInfo - > reptScan = true ;
pInfo - > prevTs = INT64_MIN ;
}
TSKEY * tsList = ( TSKEY * ) pColInfoData - > pData ;
for ( int32_t j = 0 ; j < pSDataBlock - > info . rows ; + + j ) {
if ( pInfo - > prevTs = = INT64_MIN ) {
pInfo - > curWindow . skey = tsList [ j ] ;
pInfo - > curWindow . ekey = tsList [ j ] ;
pInfo - > prevTs = tsList [ j ] ;
pInfo - > numOfRows = 1 ;
pInfo - > start = j ;
} else if ( tsList [ j ] - pInfo - > prevTs < = gap & & ( tsList [ j ] - pInfo - > prevTs ) > = 0 ) {
pInfo - > curWindow . ekey = tsList [ j ] ;
pInfo - > prevTs = tsList [ j ] ;
pInfo - > numOfRows + = 1 ;
if ( j = = 0 & & pInfo - > start ! = 0 ) {
pInfo - > numOfRows = 1 ;
pInfo - > start = 0 ;
}
} else { // start a new session window
SResultRow * pResult = NULL ;
pInfo - > curWindow . ekey = pInfo - > curWindow . skey ;
int32_t ret = setResultOutputBufByKey ( pRuntimeEnv , & pBInfo - > resultRowInfo , pSDataBlock - > info . uid , & pInfo - > curWindow , masterScan ,
& pResult , item - > groupIndex , pBInfo - > pCtx , pOperator - > numOfOutput ,
pBInfo - > rowCellInfoOffset ) ;
if ( ret ! = TSDB_CODE_SUCCESS ) { // null data, too many state code
longjmp ( pRuntimeEnv - > env , TSDB_CODE_QRY_APP_ERROR ) ;
}
doApplyFunctions ( pRuntimeEnv , pBInfo - > pCtx , & pInfo - > curWindow , pInfo - > start , pInfo - > numOfRows , tsList ,
pSDataBlock - > info . rows , pOperator - > numOfOutput ) ;
pInfo - > curWindow . skey = tsList [ j ] ;
pInfo - > curWindow . ekey = tsList [ j ] ;
pInfo - > prevTs = tsList [ j ] ;
pInfo - > numOfRows = 1 ;
pInfo - > start = j ;
}
}
SResultRow * pResult = NULL ;
pInfo - > curWindow . ekey = pInfo - > curWindow . skey ;
int32_t ret = setResultOutputBufByKey ( pRuntimeEnv , & pBInfo - > resultRowInfo , pSDataBlock - > info . uid , & pInfo - > curWindow , masterScan ,
& pResult , item - > groupIndex , pBInfo - > pCtx , pOperator - > numOfOutput ,
pBInfo - > rowCellInfoOffset ) ;
if ( ret ! = TSDB_CODE_SUCCESS ) { // null data, too many state code
longjmp ( pRuntimeEnv - > env , TSDB_CODE_QRY_APP_ERROR ) ;
}
doApplyFunctions ( pRuntimeEnv , pBInfo - > pCtx , & pInfo - > curWindow , pInfo - > start , pInfo - > numOfRows , tsList ,
pSDataBlock - > info . rows , pOperator - > numOfOutput ) ;
}
static void setResultRowKey ( SResultRow * pResultRow , char * pData , int16_t type ) {
if ( IS_VAR_DATA_TYPE ( type ) ) {
if ( pResultRow - > key = = NULL ) {
pResultRow - > key = malloc ( varDataTLen ( pData ) ) ;
varDataCopy ( pResultRow - > key , pData ) ;
} else {
assert ( memcmp ( pResultRow - > key , pData , varDataTLen ( pData ) ) = = 0 ) ;
}
} else {
int64_t v = - 1 ;
GET_TYPED_DATA ( v , int64_t , type , pData ) ;
pResultRow - > win . skey = v ;
pResultRow - > win . ekey = v ;
}
}
2022-01-08 08:28:44 +00:00
static int32_t setGroupResultOutputBuf ( STaskRuntimeEnv * pRuntimeEnv , SOptrBasicInfo * binfo , int32_t numOfCols , char * pData , int16_t type , int16_t bytes , int32_t groupIndex ) {
2022-02-08 02:21:00 +00:00
SDiskbasedBuf * pResultBuf = pRuntimeEnv - > pResultBuf ;
2021-11-02 05:37:31 +00:00
int32_t * rowCellInfoOffset = binfo - > rowCellInfoOffset ;
SResultRowInfo * pResultRowInfo = & binfo - > resultRowInfo ;
2022-01-28 02:44:02 +00:00
SqlFunctionCtx * pCtx = binfo - > pCtx ;
2021-11-02 05:37:31 +00:00
// not assign result buffer yet, add new result buffer, TODO remove it
char * d = pData ;
int16_t len = bytes ;
if ( IS_VAR_DATA_TYPE ( type ) ) {
d = varDataVal ( pData ) ;
len = varDataLen ( pData ) ;
}
int64_t tid = 0 ;
SResultRow * pResultRow = doSetResultOutBufByKey ( pRuntimeEnv , pResultRowInfo , tid , d , len , true , groupIndex ) ;
assert ( pResultRow ! = NULL ) ;
setResultRowKey ( pResultRow , pData , type ) ;
if ( pResultRow - > pageId = = - 1 ) {
int32_t ret = addNewWindowResultBuf ( pResultRow , pResultBuf , groupIndex , pRuntimeEnv - > pQueryAttr - > resultRowSize ) ;
if ( ret ! = 0 ) {
return - 1 ;
}
}
setResultOutputBuf ( pRuntimeEnv , pResultRow , pCtx , numOfCols , rowCellInfoOffset ) ;
initCtxOutputBuffer ( pCtx , numOfCols ) ;
return TSDB_CODE_SUCCESS ;
}
static int32_t getGroupbyColumnIndex ( SGroupbyExpr * pGroupbyExpr , SSDataBlock * pDataBlock ) {
size_t num = taosArrayGetSize ( pGroupbyExpr - > columnInfo ) ;
for ( int32_t k = 0 ; k < num ; + + k ) {
SColIndex * pColIndex = taosArrayGet ( pGroupbyExpr - > columnInfo , k ) ;
if ( TSDB_COL_IS_TAG ( pColIndex - > flag ) ) {
continue ;
}
int32_t colId = pColIndex - > colId ;
for ( int32_t i = 0 ; i < pDataBlock - > info . numOfCols ; + + i ) {
SColumnInfoData * pColInfo = taosArrayGet ( pDataBlock - > pDataBlock , i ) ;
if ( pColInfo - > info . colId = = colId ) {
return i ;
}
}
}
assert ( 0 ) ;
return - 1 ;
}
2022-01-28 02:44:02 +00:00
static bool functionNeedToExecute ( STaskRuntimeEnv * pRuntimeEnv , SqlFunctionCtx * pCtx ) {
2021-11-02 05:37:31 +00:00
struct SResultRowEntryInfo * pResInfo = GET_RES_INFO ( pCtx ) ;
// in case of timestamp column, always generated results.
int32_t functionId = pCtx - > functionId ;
if ( functionId = = FUNCTION_TS ) {
return true ;
}
if ( isRowEntryCompleted ( pResInfo ) | | functionId = = FUNCTION_TAG_DUMMY | | functionId = = FUNCTION_TS_DUMMY ) {
return false ;
}
if ( functionId = = FUNCTION_FIRST_DST | | functionId = = FUNCTION_FIRST ) {
2022-01-20 08:02:09 +00:00
// return QUERY_IS_ASC_QUERY(pQueryAttr);
2021-11-02 05:37:31 +00:00
}
// denote the order type
if ( ( functionId = = FUNCTION_LAST_DST | | functionId = = FUNCTION_LAST ) ) {
2022-01-20 08:02:09 +00:00
// return pCtx->param[0].i == pQueryAttr->order.order;
2021-11-02 05:37:31 +00:00
}
// in the reverse table scan, only the following functions need to be executed
2022-01-20 09:10:28 +00:00
// if (IS_REVERSE_SCAN(pRuntimeEnv) ||
// (pRuntimeEnv->scanFlag == REPEAT_SCAN && functionId != FUNCTION_STDDEV && functionId != FUNCTION_PERCT)) {
// return false;
// }
2021-11-02 05:37:31 +00:00
return true ;
}
2022-01-28 02:44:02 +00:00
void setBlockStatisInfo ( SqlFunctionCtx * pCtx , SSDataBlock * pSDataBlock , SColumn * pColumn ) {
2021-11-02 05:37:31 +00:00
SColumnDataAgg * pAgg = NULL ;
2022-01-20 09:10:28 +00:00
if ( pSDataBlock - > pBlockAgg ! = NULL & & TSDB_COL_IS_NORMAL_COL ( pColumn - > flag ) ) {
pAgg = & pSDataBlock - > pBlockAgg [ pCtx - > columnIndex ] ;
2021-11-02 05:37:31 +00:00
pCtx - > agg = * pAgg ;
pCtx - > isAggSet = true ;
assert ( pCtx - > agg . numOfNull < = pSDataBlock - > info . rows ) ;
} else {
pCtx - > isAggSet = false ;
}
2022-01-20 09:10:28 +00:00
pCtx - > hasNull = hasNull ( pColumn , pAgg ) ;
2021-11-02 05:37:31 +00:00
// set the statistics data for primary time stamp column
2022-01-20 09:10:28 +00:00
if ( pCtx - > functionId = = FUNCTION_SPREAD & & pColumn - > info . colId = = PRIMARYKEY_TIMESTAMP_COL_ID ) {
2021-11-02 05:37:31 +00:00
pCtx - > isAggSet = true ;
pCtx - > agg . min = pSDataBlock - > info . window . skey ;
pCtx - > agg . max = pSDataBlock - > info . window . ekey ;
}
}
// set the output buffer for the selectivity + tag query
2022-01-28 02:44:02 +00:00
static int32_t setCtxTagColumnInfo ( SqlFunctionCtx * pCtx , int32_t numOfOutput ) {
2021-11-02 05:37:31 +00:00
if ( ! isSelectivityWithTagsQuery ( pCtx , numOfOutput ) ) {
return TSDB_CODE_SUCCESS ;
}
int32_t num = 0 ;
int16_t tagLen = 0 ;
2022-01-28 02:44:02 +00:00
SqlFunctionCtx * p = NULL ;
SqlFunctionCtx * * pTagCtx = calloc ( numOfOutput , POINTER_BYTES ) ;
2021-11-02 05:37:31 +00:00
if ( pTagCtx = = NULL ) {
return TSDB_CODE_QRY_OUT_OF_MEMORY ;
}
for ( int32_t i = 0 ; i < numOfOutput ; + + i ) {
int32_t functionId = pCtx [ i ] . functionId ;
if ( functionId = = FUNCTION_TAG_DUMMY | | functionId = = FUNCTION_TS_DUMMY ) {
2021-11-02 07:08:00 +00:00
tagLen + = pCtx [ i ] . resDataInfo . bytes ;
2021-11-02 05:37:31 +00:00
pTagCtx [ num + + ] = & pCtx [ i ] ;
} else if ( 1 /*(aAggs[functionId].status & FUNCSTATE_SELECTIVITY) != 0*/ ) {
p = & pCtx [ i ] ;
} else if ( functionId = = FUNCTION_TS | | functionId = = FUNCTION_TAG ) {
// tag function may be the group by tag column
// ts may be the required primary timestamp column
continue ;
} else {
// the column may be the normal column, group by normal_column, the functionId is FUNCTION_PRJ
}
}
if ( p ! = NULL ) {
p - > tagInfo . pTagCtxList = pTagCtx ;
p - > tagInfo . numOfTagCols = num ;
p - > tagInfo . tagsLen = tagLen ;
} else {
tfree ( pTagCtx ) ;
}
return TSDB_CODE_SUCCESS ;
}
2022-01-28 02:44:02 +00:00
static SqlFunctionCtx * createSqlFunctionCtx ( STaskRuntimeEnv * pRuntimeEnv , SExprInfo * pExpr , int32_t numOfOutput ,
2021-11-02 05:37:31 +00:00
int32_t * * rowCellInfoOffset ) {
2022-01-08 08:28:44 +00:00
STaskAttr * pQueryAttr = pRuntimeEnv - > pQueryAttr ;
2021-11-02 05:37:31 +00:00
2022-01-28 02:44:02 +00:00
SqlFunctionCtx * pFuncCtx = ( SqlFunctionCtx * ) calloc ( numOfOutput , sizeof ( SqlFunctionCtx ) ) ;
2021-11-02 05:37:31 +00:00
if ( pFuncCtx = = NULL ) {
return NULL ;
}
* rowCellInfoOffset = calloc ( numOfOutput , sizeof ( int32_t ) ) ;
if ( * rowCellInfoOffset = = 0 ) {
tfree ( pFuncCtx ) ;
return NULL ;
}
for ( int32_t i = 0 ; i < numOfOutput ; + + i ) {
SSqlExpr * pSqlExpr = & pExpr [ i ] . base ;
2022-01-28 02:44:02 +00:00
SqlFunctionCtx * pCtx = & pFuncCtx [ i ] ;
2021-11-05 02:35:50 +00:00
#if 0
2021-11-02 05:37:31 +00:00
SColIndex * pIndex = & pSqlExpr - > colInfo ;
if ( TSDB_COL_REQ_NULL ( pIndex - > flag ) ) {
pCtx - > requireNull = true ;
pIndex - > flag & = ~ ( TSDB_COL_NULL ) ;
} else {
pCtx - > requireNull = false ;
}
2021-11-05 02:35:50 +00:00
# endif
2021-11-02 05:37:31 +00:00
// pCtx->inputBytes = pSqlExpr->colBytes;
// pCtx->inputType = pSqlExpr->colType;
pCtx - > ptsOutputBuf = NULL ;
2021-11-02 07:08:00 +00:00
pCtx - > resDataInfo . bytes = pSqlExpr - > resSchema . bytes ;
pCtx - > resDataInfo . type = pSqlExpr - > resSchema . type ;
2021-11-02 05:37:31 +00:00
pCtx - > order = pQueryAttr - > order . order ;
// pCtx->functionId = pSqlExpr->functionId;
pCtx - > stableQuery = pQueryAttr - > stableQuery ;
2021-11-02 07:08:00 +00:00
pCtx - > resDataInfo . intermediateBytes = pSqlExpr - > interBytes ;
2021-11-02 05:37:31 +00:00
pCtx - > start . key = INT64_MIN ;
pCtx - > end . key = INT64_MIN ;
pCtx - > numOfParams = pSqlExpr - > numOfParams ;
for ( int32_t j = 0 ; j < pCtx - > numOfParams ; + + j ) {
int16_t type = pSqlExpr - > param [ j ] . nType ;
int16_t bytes = pSqlExpr - > param [ j ] . nLen ;
// if (pSqlExpr->functionId == FUNCTION_STDDEV_DST) {
// continue;
// }
if ( type = = TSDB_DATA_TYPE_BINARY | | type = = TSDB_DATA_TYPE_NCHAR ) {
taosVariantCreateFromBinary ( & pCtx - > param [ j ] , pSqlExpr - > param [ j ] . pz , bytes , type ) ;
} else {
taosVariantCreateFromBinary ( & pCtx - > param [ j ] , ( char * ) & pSqlExpr - > param [ j ] . i , bytes , type ) ;
}
}
// set the order information for top/bottom query
int32_t functionId = pCtx - > functionId ;
if ( functionId = = FUNCTION_TOP | | functionId = = FUNCTION_BOTTOM | | functionId = = FUNCTION_DIFF ) {
int32_t f = getExprFunctionId ( & pExpr [ 0 ] ) ;
assert ( f = = FUNCTION_TS | | f = = FUNCTION_TS_DUMMY ) ;
pCtx - > param [ 2 ] . i = pQueryAttr - > order . order ;
pCtx - > param [ 2 ] . nType = TSDB_DATA_TYPE_BIGINT ;
pCtx - > param [ 3 ] . i = functionId ;
pCtx - > param [ 3 ] . nType = TSDB_DATA_TYPE_BIGINT ;
2021-12-06 06:44:27 +00:00
pCtx - > param [ 1 ] . i = pQueryAttr - > order . col . info . colId ;
2021-11-02 05:37:31 +00:00
} else if ( functionId = = FUNCTION_INTERP ) {
pCtx - > param [ 2 ] . i = ( int8_t ) pQueryAttr - > fillType ;
if ( pQueryAttr - > fillVal ! = NULL ) {
if ( isNull ( ( const char * ) & pQueryAttr - > fillVal [ i ] , pCtx - > inputType ) ) {
pCtx - > param [ 1 ] . nType = TSDB_DATA_TYPE_NULL ;
} else { // todo refactor, taosVariantCreateFromBinary should handle the NULL value
if ( pCtx - > inputType ! = TSDB_DATA_TYPE_BINARY & & pCtx - > inputType ! = TSDB_DATA_TYPE_NCHAR ) {
taosVariantCreateFromBinary ( & pCtx - > param [ 1 ] , ( char * ) & pQueryAttr - > fillVal [ i ] , pCtx - > inputBytes , pCtx - > inputType ) ;
}
}
}
} else if ( functionId = = FUNCTION_TS_COMP ) {
pCtx - > param [ 0 ] . i = pQueryAttr - > vgId ; //TODO this should be the parameter from client
pCtx - > param [ 0 ] . nType = TSDB_DATA_TYPE_BIGINT ;
} else if ( functionId = = FUNCTION_TWA ) {
pCtx - > param [ 1 ] . i = pQueryAttr - > window . skey ;
pCtx - > param [ 1 ] . nType = TSDB_DATA_TYPE_BIGINT ;
pCtx - > param [ 2 ] . i = pQueryAttr - > window . ekey ;
pCtx - > param [ 2 ] . nType = TSDB_DATA_TYPE_BIGINT ;
} else if ( functionId = = FUNCTION_ARITHM ) {
2022-01-10 11:48:21 +00:00
// pCtx->param[1].pz = (char*) getScalarFuncSupport(pRuntimeEnv->scalarSup, i);
2021-11-02 05:37:31 +00:00
}
}
// for(int32_t i = 1; i < numOfOutput; ++i) {
// (*rowCellInfoOffset)[i] = (int32_t)((*rowCellInfoOffset)[i - 1] + sizeof(SResultRowEntryInfo) + pExpr[i - 1].base.interBytes);
// }
setCtxTagColumnInfo ( pFuncCtx , numOfOutput ) ;
return pFuncCtx ;
}
2022-01-28 02:44:02 +00:00
static SqlFunctionCtx * createSqlFunctionCtx_rv ( SArray * pExprInfo , int32_t * * rowCellInfoOffset ) {
2022-01-20 05:52:46 +00:00
size_t numOfOutput = taosArrayGetSize ( pExprInfo ) ;
2022-01-28 02:44:02 +00:00
SqlFunctionCtx * pFuncCtx = ( SqlFunctionCtx * ) calloc ( numOfOutput , sizeof ( SqlFunctionCtx ) ) ;
2022-01-14 02:20:55 +00:00
if ( pFuncCtx = = NULL ) {
return NULL ;
}
* rowCellInfoOffset = calloc ( numOfOutput , sizeof ( int32_t ) ) ;
if ( * rowCellInfoOffset = = 0 ) {
tfree ( pFuncCtx ) ;
return NULL ;
}
for ( int32_t i = 0 ; i < numOfOutput ; + + i ) {
2022-01-20 05:52:46 +00:00
SExprInfo * pExpr = taosArrayGetP ( pExprInfo , i ) ;
SSqlExpr * pSqlExpr = & pExpr - > base ;
2022-01-28 02:44:02 +00:00
SqlFunctionCtx * pCtx = & pFuncCtx [ i ] ;
2022-01-20 09:10:28 +00:00
2022-01-14 02:20:55 +00:00
#if 0
SColIndex * pIndex = & pSqlExpr - > colInfo ;
if ( TSDB_COL_REQ_NULL ( pIndex - > flag ) ) {
pCtx - > requireNull = true ;
pIndex - > flag & = ~ ( TSDB_COL_NULL ) ;
} else {
pCtx - > requireNull = false ;
}
# endif
2022-01-20 09:10:28 +00:00
// pCtx->inputBytes = pSqlExpr->;
2022-01-14 02:20:55 +00:00
// pCtx->inputType = pSqlExpr->colType;
pCtx - > ptsOutputBuf = NULL ;
2022-01-20 08:02:09 +00:00
pCtx - > fpSet = fpSet ;
2022-01-20 09:10:28 +00:00
pCtx - > columnIndex = - 1 ;
2022-01-14 02:20:55 +00:00
pCtx - > resDataInfo . bytes = pSqlExpr - > resSchema . bytes ;
pCtx - > resDataInfo . type = pSqlExpr - > resSchema . type ;
2022-01-20 09:10:28 +00:00
pCtx - > order = TSDB_ORDER_ASC ;
2022-01-14 02:20:55 +00:00
// pCtx->functionId = pSqlExpr->functionId;
// pCtx->stableQuery = pQueryAttr->stableQuery;
pCtx - > resDataInfo . intermediateBytes = pSqlExpr - > interBytes ;
pCtx - > start . key = INT64_MIN ;
pCtx - > end . key = INT64_MIN ;
pCtx - > numOfParams = pSqlExpr - > numOfParams ;
for ( int32_t j = 0 ; j < pCtx - > numOfParams ; + + j ) {
int16_t type = pSqlExpr - > param [ j ] . nType ;
int16_t bytes = pSqlExpr - > param [ j ] . nLen ;
if ( type = = TSDB_DATA_TYPE_BINARY | | type = = TSDB_DATA_TYPE_NCHAR ) {
taosVariantCreateFromBinary ( & pCtx - > param [ j ] , pSqlExpr - > param [ j ] . pz , bytes , type ) ;
} else {
taosVariantCreateFromBinary ( & pCtx - > param [ j ] , ( char * ) & pSqlExpr - > param [ j ] . i , bytes , type ) ;
}
}
// set the order information for top/bottom query
int32_t functionId = pCtx - > functionId ;
if ( functionId = = FUNCTION_TOP | | functionId = = FUNCTION_BOTTOM | | functionId = = FUNCTION_DIFF ) {
int32_t f = getExprFunctionId ( & pExpr [ 0 ] ) ;
assert ( f = = FUNCTION_TS | | f = = FUNCTION_TS_DUMMY ) ;
// pCtx->param[2].i = pQueryAttr->order.order;
pCtx - > param [ 2 ] . nType = TSDB_DATA_TYPE_BIGINT ;
pCtx - > param [ 3 ] . i = functionId ;
pCtx - > param [ 3 ] . nType = TSDB_DATA_TYPE_BIGINT ;
// pCtx->param[1].i = pQueryAttr->order.col.info.colId;
} else if ( functionId = = FUNCTION_INTERP ) {
// pCtx->param[2].i = (int8_t)pQueryAttr->fillType;
// if (pQueryAttr->fillVal != NULL) {
// if (isNull((const char *)&pQueryAttr->fillVal[i], pCtx->inputType)) {
// pCtx->param[1].nType = TSDB_DATA_TYPE_NULL;
// } else { // todo refactor, taosVariantCreateFromBinary should handle the NULL value
// if (pCtx->inputType != TSDB_DATA_TYPE_BINARY && pCtx->inputType != TSDB_DATA_TYPE_NCHAR) {
// taosVariantCreateFromBinary(&pCtx->param[1], (char *)&pQueryAttr->fillVal[i], pCtx->inputBytes, pCtx->inputType);
// }
// }
// }
} else if ( functionId = = FUNCTION_TS_COMP ) {
// pCtx->param[0].i = pQueryAttr->vgId; //TODO this should be the parameter from client
pCtx - > param [ 0 ] . nType = TSDB_DATA_TYPE_BIGINT ;
} else if ( functionId = = FUNCTION_TWA ) {
// pCtx->param[1].i = pQueryAttr->window.skey;
pCtx - > param [ 1 ] . nType = TSDB_DATA_TYPE_BIGINT ;
// pCtx->param[2].i = pQueryAttr->window.ekey;
pCtx - > param [ 2 ] . nType = TSDB_DATA_TYPE_BIGINT ;
} else if ( functionId = = FUNCTION_ARITHM ) {
// pCtx->param[1].pz = (char*) getScalarFuncSupport(pRuntimeEnv->scalarSup, i);
}
}
2022-01-20 09:10:28 +00:00
for ( int32_t i = 1 ; i < numOfOutput ; + + i ) {
SExprInfo * pExpr = taosArrayGetP ( pExprInfo , i - 1 ) ;
( * rowCellInfoOffset ) [ i ] = ( int32_t ) ( ( * rowCellInfoOffset ) [ i - 1 ] + sizeof ( SResultRowEntryInfo ) + pExpr - > base . interBytes ) ;
}
2022-01-14 02:20:55 +00:00
setCtxTagColumnInfo ( pFuncCtx , numOfOutput ) ;
return pFuncCtx ;
}
2022-01-28 02:44:02 +00:00
static void * destroySQLFunctionCtx ( SqlFunctionCtx * pCtx , int32_t numOfOutput ) {
2021-11-02 05:37:31 +00:00
if ( pCtx = = NULL ) {
return NULL ;
}
for ( int32_t i = 0 ; i < numOfOutput ; + + i ) {
for ( int32_t j = 0 ; j < pCtx [ i ] . numOfParams ; + + j ) {
taosVariantDestroy ( & pCtx [ i ] . param [ j ] ) ;
}
taosVariantDestroy ( & pCtx [ i ] . tag ) ;
tfree ( pCtx [ i ] . tagInfo . pTagCtxList ) ;
}
tfree ( pCtx ) ;
return NULL ;
}
2022-01-08 08:28:44 +00:00
static int32_t setupQueryRuntimeEnv ( STaskRuntimeEnv * pRuntimeEnv , int32_t numOfTables , SArray * pOperator , void * merger ) {
2022-01-10 11:48:21 +00:00
//qDebug("QInfo:0x%"PRIx64" setup runtime env", GET_TASKID(pRuntimeEnv));
2022-01-08 08:28:44 +00:00
STaskAttr * pQueryAttr = pRuntimeEnv - > pQueryAttr ;
2021-11-02 05:37:31 +00:00
pRuntimeEnv - > prevGroupId = INT32_MIN ;
pRuntimeEnv - > pQueryAttr = pQueryAttr ;
pRuntimeEnv - > pResultRowHashTable = taosHashInit ( numOfTables , taosGetDefaultHashFunction ( TSDB_DATA_TYPE_BINARY ) , true , HASH_NO_LOCK ) ;
pRuntimeEnv - > pResultRowListSet = taosHashInit ( numOfTables * 10 , taosGetDefaultHashFunction ( TSDB_DATA_TYPE_BINARY ) , false , HASH_NO_LOCK ) ;
pRuntimeEnv - > keyBuf = malloc ( pQueryAttr - > maxTableColumnWidth + sizeof ( int64_t ) + POINTER_BYTES ) ;
2022-01-20 05:52:46 +00:00
// pRuntimeEnv->pool = initResultRowPool(getResultRowSize(pRuntimeEnv));
2021-11-02 05:37:31 +00:00
pRuntimeEnv - > pResultRowArrayList = taosArrayInit ( numOfTables , sizeof ( SResultRowCell ) ) ;
pRuntimeEnv - > prevRow = malloc ( POINTER_BYTES * pQueryAttr - > numOfCols + pQueryAttr - > srcRowSize ) ;
pRuntimeEnv - > tagVal = malloc ( pQueryAttr - > tagLen ) ;
// NOTE: pTableCheckInfo need to update the query time range and the lastKey info
pRuntimeEnv - > pTableRetrieveTsMap = taosHashInit ( numOfTables , taosGetDefaultHashFunction ( TSDB_DATA_TYPE_INT ) , false , HASH_NO_LOCK ) ;
pRuntimeEnv - > scalarSup = createScalarFuncSupport ( pQueryAttr - > numOfOutput ) ;
if ( pRuntimeEnv - > scalarSup = = NULL | | pRuntimeEnv - > pResultRowHashTable = = NULL | | pRuntimeEnv - > keyBuf = = NULL | |
pRuntimeEnv - > prevRow = = NULL | | pRuntimeEnv - > tagVal = = NULL ) {
goto _clean ;
}
if ( pQueryAttr - > numOfCols ) {
char * start = POINTER_BYTES * pQueryAttr - > numOfCols + ( char * ) pRuntimeEnv - > prevRow ;
pRuntimeEnv - > prevRow [ 0 ] = start ;
for ( int32_t i = 1 ; i < pQueryAttr - > numOfCols ; + + i ) {
pRuntimeEnv - > prevRow [ i ] = pRuntimeEnv - > prevRow [ i - 1 ] + pQueryAttr - > tableCols [ i - 1 ] . bytes ;
}
if ( pQueryAttr - > tableCols [ 0 ] . type = = TSDB_DATA_TYPE_TIMESTAMP ) {
* ( int64_t * ) pRuntimeEnv - > prevRow [ 0 ] = INT64_MIN ;
}
}
2022-01-10 11:48:21 +00:00
//qDebug("QInfo:0x%"PRIx64" init runtime environment completed", GET_TASKID(pRuntimeEnv));
2021-11-02 05:37:31 +00:00
// group by normal column, sliding window query, interval query are handled by interval query processor
// interval (down sampling operation)
return TSDB_CODE_SUCCESS ;
_clean :
destroyScalarFuncSupport ( pRuntimeEnv - > scalarSup , pRuntimeEnv - > pQueryAttr - > numOfOutput ) ;
tfree ( pRuntimeEnv - > pResultRowHashTable ) ;
tfree ( pRuntimeEnv - > keyBuf ) ;
tfree ( pRuntimeEnv - > prevRow ) ;
tfree ( pRuntimeEnv - > tagVal ) ;
return TSDB_CODE_QRY_OUT_OF_MEMORY ;
}
2022-01-08 08:28:44 +00:00
static void doFreeQueryHandle ( STaskRuntimeEnv * pRuntimeEnv ) {
STaskAttr * pQueryAttr = pRuntimeEnv - > pQueryAttr ;
2021-11-02 05:37:31 +00:00
2022-01-27 10:27:26 +00:00
// tsdbCleanupReadHandle(pRuntimeEnv->pTsdbReadHandle);
2022-01-10 11:48:21 +00:00
pRuntimeEnv - > pTsdbReadHandle = NULL ;
2021-11-02 05:37:31 +00:00
// SMemRef* pMemRef = &pQueryAttr->memRef;
// assert(pMemRef->ref == 0 && pMemRef->snapshot.imem == NULL && pMemRef->snapshot.mem == NULL);
}
2022-01-08 08:28:44 +00:00
static void destroyTsComp ( STaskRuntimeEnv * pRuntimeEnv , STaskAttr * pQueryAttr ) {
2021-11-02 05:37:31 +00:00
if ( pQueryAttr - > tsCompQuery & & pRuntimeEnv - > outputBuf & & pRuntimeEnv - > outputBuf - > pDataBlock & & taosArrayGetSize ( pRuntimeEnv - > outputBuf - > pDataBlock ) > 0 ) {
SColumnInfoData * pColInfoData = taosArrayGet ( pRuntimeEnv - > outputBuf - > pDataBlock , 0 ) ;
if ( pColInfoData ) {
FILE * f = * ( FILE * * ) pColInfoData - > pData ; // TODO refactor
if ( f ) {
fclose ( f ) ;
* ( FILE * * ) pColInfoData - > pData = NULL ;
}
}
}
}
2022-01-08 08:28:44 +00:00
static void teardownQueryRuntimeEnv ( STaskRuntimeEnv * pRuntimeEnv ) {
STaskAttr * pQueryAttr = pRuntimeEnv - > pQueryAttr ;
2021-11-02 05:37:31 +00:00
SQInfo * pQInfo = ( SQInfo * ) pRuntimeEnv - > qinfo ;
//qDebug("QInfo:0x%"PRIx64" teardown runtime env", pQInfo->qId);
destroyScalarFuncSupport ( pRuntimeEnv - > scalarSup , pQueryAttr - > numOfOutput ) ;
2022-01-10 11:48:21 +00:00
// destroyUdfInfo(pRuntimeEnv->pUdfInfo);
2021-11-02 05:37:31 +00:00
destroyResultBuf ( pRuntimeEnv - > pResultBuf ) ;
doFreeQueryHandle ( pRuntimeEnv ) ;
destroyTsComp ( pRuntimeEnv , pQueryAttr ) ;
pRuntimeEnv - > pTsBuf = tsBufDestroy ( pRuntimeEnv - > pTsBuf ) ;
tfree ( pRuntimeEnv - > keyBuf ) ;
tfree ( pRuntimeEnv - > prevRow ) ;
tfree ( pRuntimeEnv - > tagVal ) ;
taosHashCleanup ( pRuntimeEnv - > pResultRowHashTable ) ;
pRuntimeEnv - > pResultRowHashTable = NULL ;
taosHashCleanup ( pRuntimeEnv - > pTableRetrieveTsMap ) ;
pRuntimeEnv - > pTableRetrieveTsMap = NULL ;
taosHashCleanup ( pRuntimeEnv - > pResultRowListSet ) ;
pRuntimeEnv - > pResultRowListSet = NULL ;
destroyOperatorInfo ( pRuntimeEnv - > proot ) ;
pRuntimeEnv - > pool = destroyResultRowPool ( pRuntimeEnv - > pool ) ;
taosArrayDestroyEx ( pRuntimeEnv - > prevResult , freeInterResult ) ;
taosArrayDestroy ( pRuntimeEnv - > pResultRowArrayList ) ;
pRuntimeEnv - > prevResult = NULL ;
}
static bool needBuildResAfterQueryComplete ( SQInfo * pQInfo ) {
return pQInfo - > rspContext ! = NULL ;
}
2022-01-10 11:48:21 +00:00
bool isTaskKilled ( SExecTaskInfo * pTaskInfo ) {
2021-11-02 05:37:31 +00:00
// query has been executed more than tsShellActivityTimer, and the retrieve has not arrived
// abort current query execution.
2022-01-10 11:48:21 +00:00
if ( pTaskInfo - > owner ! = 0 & & ( ( taosGetTimestampSec ( ) - pTaskInfo - > cost . start / 1000 ) > 10 * getMaximumIdleDurationSec ( ) )
/*(!needBuildResAfterQueryComplete(pTaskInfo))*/ ) {
2021-11-02 05:37:31 +00:00
2022-01-10 11:48:21 +00:00
assert ( pTaskInfo - > cost . start ! = 0 ) ;
// qDebug("QInfo:%" PRIu64 " retrieve not arrive beyond %d ms, abort current query execution, start:%" PRId64
2021-11-02 05:37:31 +00:00
// ", current:%d", pQInfo->qId, 1, pQInfo->startExecTs, taosGetTimestampSec());
2022-01-25 02:41:35 +00:00
// return true;
2021-11-02 05:37:31 +00:00
}
return false ;
}
2022-01-25 02:41:35 +00:00
void setTaskKilled ( SExecTaskInfo * pTaskInfo ) { pTaskInfo - > code = TSDB_CODE_TSC_QUERY_CANCELLED ; }
2021-11-02 05:37:31 +00:00
2022-01-08 08:28:44 +00:00
//static bool isFixedOutputQuery(STaskAttr* pQueryAttr) {
2021-11-02 05:37:31 +00:00
// if (QUERY_IS_INTERVAL_QUERY(pQueryAttr)) {
// return false;
// }
//
// // Note:top/bottom query is fixed output query
// if (pQueryAttr->topBotQuery || pQueryAttr->groupbyColumn || pQueryAttr->tsCompQuery) {
// return true;
// }
//
// for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) {
// SSqlExpr *pExpr = &pQueryAttr->pExpr1[i].base;
//
// if (pExpr->functionId == FUNCTION_TS || pExpr->functionId == FUNCTION_TS_DUMMY) {
// continue;
// }
//
// if (!IS_MULTIOUTPUT(aAggs[pExpr->functionId].status)) {
// return true;
// }
// }
//
// return false;
//}
// todo refactor with isLastRowQuery
2022-01-08 08:28:44 +00:00
//bool isPointInterpoQuery(STaskAttr *pQueryAttr) {
2021-11-02 05:37:31 +00:00
// for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) {
// int32_t functionId = pQueryAttr->pExpr1[i].base.functionId;
// if (functionId == FUNCTION_INTERP) {
// return true;
// }
// }
//
// return false;
//}
2022-01-08 08:28:44 +00:00
static bool isFirstLastRowQuery ( STaskAttr * pQueryAttr ) {
2021-11-02 05:37:31 +00:00
for ( int32_t i = 0 ; i < pQueryAttr - > numOfOutput ; + + i ) {
int32_t functionID = getExprFunctionId ( & pQueryAttr - > pExpr1 [ i ] ) ;
if ( functionID = = FUNCTION_LAST_ROW ) {
return true ;
}
}
return false ;
}
2022-01-08 08:28:44 +00:00
static bool isCachedLastQuery ( STaskAttr * pQueryAttr ) {
2021-11-02 05:37:31 +00:00
for ( int32_t i = 0 ; i < pQueryAttr - > numOfOutput ; + + i ) {
int32_t functionId = getExprFunctionId ( & pQueryAttr - > pExpr1 [ i ] ) ;
if ( functionId = = FUNCTION_LAST | | functionId = = FUNCTION_LAST_DST ) {
continue ;
}
return false ;
}
if ( pQueryAttr - > order . order ! = TSDB_ORDER_DESC | | ! TSWINDOW_IS_EQUAL ( pQueryAttr - > window , TSWINDOW_DESC_INITIALIZER ) ) {
return false ;
}
if ( pQueryAttr - > groupbyColumn ) {
return false ;
}
if ( pQueryAttr - > interval . interval > 0 ) {
return false ;
}
if ( pQueryAttr - > numOfFilterCols > 0 | | pQueryAttr - > havingNum > 0 ) {
return false ;
}
return true ;
}
/**
* The following 4 kinds of query are treated as the tags query
* tagprj , tid_tag query , count ( tbname ) , ' abc ' ( user defined constant value column ) query
*/
2022-01-08 08:28:44 +00:00
bool onlyQueryTags ( STaskAttr * pQueryAttr ) {
2021-11-02 05:37:31 +00:00
for ( int32_t i = 0 ; i < pQueryAttr - > numOfOutput ; + + i ) {
SExprInfo * pExprInfo = & pQueryAttr - > pExpr1 [ i ] ;
int32_t functionId = getExprFunctionId ( pExprInfo ) ;
if ( functionId ! = FUNCTION_TAGPRJ & &
functionId ! = FUNCTION_TID_TAG & &
2021-11-05 02:35:50 +00:00
( ! ( functionId = = FUNCTION_COUNT & & pExprInfo - > base . pColumns - > info . colId = = TSDB_TBNAME_COLUMN_INDEX ) ) & &
2021-11-04 05:24:19 +00:00
( ! ( functionId = = FUNCTION_PRJ & & TSDB_COL_IS_UD_COL ( pExprInfo - > base . pColumns - > flag ) ) ) ) {
2021-11-02 05:37:31 +00:00
return false ;
}
}
return true ;
}
/////////////////////////////////////////////////////////////////////////////////////////////
2022-01-08 08:28:44 +00:00
void getAlignQueryTimeWindow ( STaskAttr * pQueryAttr , int64_t key , int64_t keyFirst , int64_t keyLast , STimeWindow * win ) {
2021-11-02 05:37:31 +00:00
assert ( key > = keyFirst & & key < = keyLast & & pQueryAttr - > interval . sliding < = pQueryAttr - > interval . interval ) ;
win - > skey = taosTimeTruncate ( key , & pQueryAttr - > interval , pQueryAttr - > precision ) ;
/*
* if the realSkey > INT64_MAX - pQueryAttr - > interval . interval , the query duration between
* realSkey and realEkey must be less than one interval . Therefore , no need to adjust the query ranges .
*/
if ( keyFirst > ( INT64_MAX - pQueryAttr - > interval . interval ) ) {
assert ( keyLast - keyFirst < pQueryAttr - > interval . interval ) ;
win - > ekey = INT64_MAX ;
} else if ( pQueryAttr - > interval . intervalUnit = = ' n ' | | pQueryAttr - > interval . intervalUnit = = ' y ' ) {
win - > ekey = taosTimeAdd ( win - > skey , pQueryAttr - > interval . interval , pQueryAttr - > interval . intervalUnit , pQueryAttr - > precision ) - 1 ;
} else {
win - > ekey = win - > skey + pQueryAttr - > interval . interval - 1 ;
}
}
/*
* todo add more parameters to check soon . .
*/
2022-01-08 08:28:44 +00:00
bool colIdCheck ( STaskAttr * pQueryAttr , uint64_t qId ) {
2021-11-02 05:37:31 +00:00
// load data column information is incorrect
for ( int32_t i = 0 ; i < pQueryAttr - > numOfCols - 1 ; + + i ) {
if ( pQueryAttr - > tableCols [ i ] . colId = = pQueryAttr - > tableCols [ i + 1 ] . colId ) {
//qError("QInfo:0x%"PRIx64" invalid data load column for query", qId);
return false ;
}
}
return true ;
}
// todo ignore the avg/sum/min/max/count/stddev/top/bottom functions, of which
// the scan order is not matter
2022-01-08 08:28:44 +00:00
static bool onlyOneQueryType ( STaskAttr * pQueryAttr , int32_t functId , int32_t functIdDst ) {
2021-11-02 05:37:31 +00:00
for ( int32_t i = 0 ; i < pQueryAttr - > numOfOutput ; + + i ) {
int32_t functionId = getExprFunctionId ( & pQueryAttr - > pExpr1 [ i ] ) ;
if ( functionId = = FUNCTION_TS | | functionId = = FUNCTION_TS_DUMMY | | functionId = = FUNCTION_TAG | |
functionId = = FUNCTION_TAG_DUMMY ) {
continue ;
}
if ( functionId ! = functId & & functionId ! = functIdDst ) {
return false ;
}
}
return true ;
}
2022-01-08 08:28:44 +00:00
static bool onlyFirstQuery ( STaskAttr * pQueryAttr ) { return onlyOneQueryType ( pQueryAttr , FUNCTION_FIRST , FUNCTION_FIRST_DST ) ; }
2021-11-02 05:37:31 +00:00
2022-01-08 08:28:44 +00:00
static bool onlyLastQuery ( STaskAttr * pQueryAttr ) { return onlyOneQueryType ( pQueryAttr , FUNCTION_LAST , FUNCTION_LAST_DST ) ; }
2021-11-02 05:37:31 +00:00
2022-01-08 08:28:44 +00:00
static bool notContainSessionOrStateWindow ( STaskAttr * pQueryAttr ) { return ! ( pQueryAttr - > sw . gap > 0 | | pQueryAttr - > stateWindow ) ; }
2021-11-02 05:37:31 +00:00
2022-01-08 08:28:44 +00:00
static int32_t updateBlockLoadStatus ( STaskAttr * pQuery , int32_t status ) {
2021-11-02 05:37:31 +00:00
bool hasFirstLastFunc = false ;
bool hasOtherFunc = false ;
if ( status = = BLK_DATA_ALL_NEEDED | | status = = BLK_DATA_DISCARD ) {
return status ;
}
for ( int32_t i = 0 ; i < pQuery - > numOfOutput ; + + i ) {
int32_t functionId = getExprFunctionId ( & pQuery - > pExpr1 [ i ] ) ;
if ( functionId = = FUNCTION_TS | | functionId = = FUNCTION_TS_DUMMY | | functionId = = FUNCTION_TAG | |
functionId = = FUNCTION_TAG_DUMMY ) {
continue ;
}
if ( functionId = = FUNCTION_FIRST_DST | | functionId = = FUNCTION_LAST_DST ) {
hasFirstLastFunc = true ;
} else {
hasOtherFunc = true ;
}
}
if ( hasFirstLastFunc & & status = = BLK_DATA_NO_NEEDED ) {
if ( ! hasOtherFunc ) {
return BLK_DATA_DISCARD ;
} else {
return BLK_DATA_ALL_NEEDED ;
}
}
return status ;
}
2022-01-08 08:28:44 +00:00
static void doUpdateLastKey ( STaskAttr * pQueryAttr ) {
2021-11-02 05:37:31 +00:00
STimeWindow * win = & pQueryAttr - > window ;
size_t num = taosArrayGetSize ( pQueryAttr - > tableGroupInfo . pGroupList ) ;
for ( int32_t i = 0 ; i < num ; + + i ) {
SArray * p1 = taosArrayGetP ( pQueryAttr - > tableGroupInfo . pGroupList , i ) ;
size_t len = taosArrayGetSize ( p1 ) ;
for ( int32_t j = 0 ; j < len ; + + j ) {
// STableKeyInfo* pInfo = taosArrayGet(p1, j);
//
// // update the new lastkey if it is equalled to the value of the old skey
// if (pInfo->lastKey == win->ekey) {
// pInfo->lastKey = win->skey;
// }
}
}
}
2022-01-10 12:44:11 +00:00
static void updateDataCheckOrder ( SQInfo * pQInfo , SQueryTableReq * pQueryMsg , bool stableQuery ) {
2022-01-08 08:28:44 +00:00
STaskAttr * pQueryAttr = pQInfo - > runtimeEnv . pQueryAttr ;
2021-11-02 05:37:31 +00:00
// in case of point-interpolation query, use asc order scan
char msg [ ] = " QInfo:0x% " PRIx64 " scan order changed for %s query, old:%d, new:%d, qrange exchanged, old qrange:% " PRId64
" -% " PRId64 " , new qrange:% " PRId64 " -% " PRId64 ;
// todo handle the case the the order irrelevant query type mixed up with order critical query type
// descending order query for last_row query
if ( isFirstLastRowQuery ( pQueryAttr ) ) {
//qDebug("QInfo:0x%"PRIx64" scan order changed for last_row query, old:%d, new:%d", pQInfo->qId, pQueryAttr->order.order, TSDB_ORDER_ASC);
pQueryAttr - > order . order = TSDB_ORDER_ASC ;
if ( pQueryAttr - > window . skey > pQueryAttr - > window . ekey ) {
2022-01-24 04:53:17 +00:00
TSWAP ( pQueryAttr - > window . skey , pQueryAttr - > window . ekey , TSKEY ) ;
2021-11-02 05:37:31 +00:00
}
pQueryAttr - > needReverseScan = false ;
return ;
}
if ( pQueryAttr - > groupbyColumn & & pQueryAttr - > order . order = = TSDB_ORDER_DESC ) {
pQueryAttr - > order . order = TSDB_ORDER_ASC ;
if ( pQueryAttr - > window . skey > pQueryAttr - > window . ekey ) {
2022-01-24 04:53:17 +00:00
TSWAP ( pQueryAttr - > window . skey , pQueryAttr - > window . ekey , TSKEY ) ;
2021-11-02 05:37:31 +00:00
}
pQueryAttr - > needReverseScan = false ;
doUpdateLastKey ( pQueryAttr ) ;
return ;
}
if ( pQueryAttr - > pointInterpQuery & & pQueryAttr - > interval . interval = = 0 ) {
if ( ! QUERY_IS_ASC_QUERY ( pQueryAttr ) ) {
//qDebug(msg, pQInfo->qId, "interp", pQueryAttr->order.order, TSDB_ORDER_ASC, pQueryAttr->window.skey, pQueryAttr->window.ekey, pQueryAttr->window.ekey, pQueryAttr->window.skey);
2022-01-24 04:53:17 +00:00
TSWAP ( pQueryAttr - > window . skey , pQueryAttr - > window . ekey , TSKEY ) ;
2021-11-02 05:37:31 +00:00
}
pQueryAttr - > order . order = TSDB_ORDER_ASC ;
return ;
}
if ( pQueryAttr - > interval . interval = = 0 ) {
if ( onlyFirstQuery ( pQueryAttr ) ) {
if ( ! QUERY_IS_ASC_QUERY ( pQueryAttr ) ) {
//qDebug(msg, pQInfo->qId, "only-first", pQueryAttr->order.order, TSDB_ORDER_ASC, pQueryAttr->window.skey,
// pQueryAttr->window.ekey, pQueryAttr->window.ekey, pQueryAttr->window.skey);
2022-01-24 04:53:17 +00:00
TSWAP ( pQueryAttr - > window . skey , pQueryAttr - > window . ekey , TSKEY ) ;
2021-11-02 05:37:31 +00:00
doUpdateLastKey ( pQueryAttr ) ;
}
pQueryAttr - > order . order = TSDB_ORDER_ASC ;
pQueryAttr - > needReverseScan = false ;
} else if ( onlyLastQuery ( pQueryAttr ) & & notContainSessionOrStateWindow ( pQueryAttr ) ) {
if ( QUERY_IS_ASC_QUERY ( pQueryAttr ) ) {
//qDebug(msg, pQInfo->qId, "only-last", pQueryAttr->order.order, TSDB_ORDER_DESC, pQueryAttr->window.skey,
// pQueryAttr->window.ekey, pQueryAttr->window.ekey, pQueryAttr->window.skey);
2022-01-24 04:53:17 +00:00
TSWAP ( pQueryAttr - > window . skey , pQueryAttr - > window . ekey , TSKEY ) ;
2021-11-02 05:37:31 +00:00
doUpdateLastKey ( pQueryAttr ) ;
}
pQueryAttr - > order . order = TSDB_ORDER_DESC ;
pQueryAttr - > needReverseScan = false ;
}
} else { // interval query
if ( stableQuery ) {
if ( onlyFirstQuery ( pQueryAttr ) ) {
if ( ! QUERY_IS_ASC_QUERY ( pQueryAttr ) ) {
//qDebug(msg, pQInfo->qId, "only-first stable", pQueryAttr->order.order, TSDB_ORDER_ASC,
// pQueryAttr->window.skey, pQueryAttr->window.ekey, pQueryAttr->window.ekey, pQueryAttr->window.skey);
2022-01-24 04:53:17 +00:00
TSWAP ( pQueryAttr - > window . skey , pQueryAttr - > window . ekey , TSKEY ) ;
2021-11-02 05:37:31 +00:00
doUpdateLastKey ( pQueryAttr ) ;
}
pQueryAttr - > order . order = TSDB_ORDER_ASC ;
pQueryAttr - > needReverseScan = false ;
} else if ( onlyLastQuery ( pQueryAttr ) ) {
if ( QUERY_IS_ASC_QUERY ( pQueryAttr ) ) {
//qDebug(msg, pQInfo->qId, "only-last stable", pQueryAttr->order.order, TSDB_ORDER_DESC,
// pQueryAttr->window.skey, pQueryAttr->window.ekey, pQueryAttr->window.ekey, pQueryAttr->window.skey);
2022-01-24 04:53:17 +00:00
TSWAP ( pQueryAttr - > window . skey , pQueryAttr - > window . ekey , TSKEY ) ;
2021-11-02 05:37:31 +00:00
doUpdateLastKey ( pQueryAttr ) ;
}
pQueryAttr - > order . order = TSDB_ORDER_DESC ;
pQueryAttr - > needReverseScan = false ;
}
}
}
}
2022-01-08 08:28:44 +00:00
static void getIntermediateBufInfo ( STaskRuntimeEnv * pRuntimeEnv , int32_t * ps , int32_t * rowsize ) {
STaskAttr * pQueryAttr = pRuntimeEnv - > pQueryAttr ;
2021-11-02 05:37:31 +00:00
int32_t MIN_ROWS_PER_PAGE = 4 ;
* rowsize = ( int32_t ) ( pQueryAttr - > resultRowSize * getRowNumForMultioutput ( pQueryAttr , pQueryAttr - > topBotQuery , pQueryAttr - > stableQuery ) ) ;
int32_t overhead = sizeof ( SFilePage ) ;
// one page contains at least two rows
* ps = DEFAULT_INTERN_BUF_PAGE_SIZE ;
while ( ( ( * rowsize ) * MIN_ROWS_PER_PAGE ) > ( * ps ) - overhead ) {
* ps = ( ( * ps ) < < 1u ) ;
}
}
# define IS_PREFILTER_TYPE(_t) ((_t) != TSDB_DATA_TYPE_BINARY && (_t) != TSDB_DATA_TYPE_NCHAR)
2022-01-28 02:44:02 +00:00
//static FORCE_INLINE bool doFilterByBlockStatistics(STaskRuntimeEnv* pRuntimeEnv, SDataStatis *pDataStatis, SqlFunctionCtx *pCtx, int32_t numOfRows) {
2022-01-08 08:28:44 +00:00
// STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr;
2021-11-02 05:37:31 +00:00
//
// if (pDataStatis == NULL || pQueryAttr->pFilters == NULL) {
// return true;
// }
//
// return filterRangeExecute(pQueryAttr->pFilters, pDataStatis, pQueryAttr->numOfCols, numOfRows);
//}
2022-01-08 08:28:44 +00:00
static bool overlapWithTimeWindow ( STaskAttr * pQueryAttr , SDataBlockInfo * pBlockInfo ) {
2021-11-02 05:37:31 +00:00
STimeWindow w = { 0 } ;
2022-01-24 04:53:17 +00:00
TSKEY sk = TMIN ( pQueryAttr - > window . skey , pQueryAttr - > window . ekey ) ;
TSKEY ek = TMAX ( pQueryAttr - > window . skey , pQueryAttr - > window . ekey ) ;
2021-11-02 05:37:31 +00:00
if ( QUERY_IS_ASC_QUERY ( pQueryAttr ) ) {
getAlignQueryTimeWindow ( pQueryAttr , pBlockInfo - > window . skey , sk , ek , & w ) ;
assert ( w . ekey > = pBlockInfo - > window . skey ) ;
if ( w . ekey < pBlockInfo - > window . ekey ) {
return true ;
}
while ( 1 ) {
getNextTimeWindow ( pQueryAttr , & w ) ;
if ( w . skey > pBlockInfo - > window . ekey ) {
break ;
}
assert ( w . ekey > pBlockInfo - > window . ekey ) ;
if ( w . skey < = pBlockInfo - > window . ekey & & w . skey > pBlockInfo - > window . skey ) {
return true ;
}
}
} else {
getAlignQueryTimeWindow ( pQueryAttr , pBlockInfo - > window . ekey , sk , ek , & w ) ;
assert ( w . skey < = pBlockInfo - > window . ekey ) ;
if ( w . skey > pBlockInfo - > window . skey ) {
return true ;
}
while ( 1 ) {
getNextTimeWindow ( pQueryAttr , & w ) ;
if ( w . ekey < pBlockInfo - > window . skey ) {
break ;
}
assert ( w . skey < pBlockInfo - > window . skey ) ;
if ( w . ekey < pBlockInfo - > window . ekey & & w . ekey > = pBlockInfo - > window . skey ) {
return true ;
}
}
}
return false ;
}
2022-01-08 08:28:44 +00:00
static int32_t doTSJoinFilter ( STaskRuntimeEnv * pRuntimeEnv , TSKEY key , bool ascQuery ) {
2021-11-02 05:37:31 +00:00
STSElem elem = tsBufGetElem ( pRuntimeEnv - > pTsBuf ) ;
# if defined(_DEBUG_VIEW)
printf ( " elem in comp ts file:% " PRId64 " , key:% " PRId64 " , tag:% " PRIu64 " , query order:%d, ts order:%d, traverse:%d, index:%d \n " ,
elem . ts , key , elem . tag . i , pQueryAttr - > order . order , pRuntimeEnv - > pTsBuf - > tsOrder ,
pRuntimeEnv - > pTsBuf - > cur . order , pRuntimeEnv - > pTsBuf - > cur . tsIndex ) ;
# endif
if ( ascQuery ) {
if ( key < elem . ts ) {
return TS_JOIN_TS_NOT_EQUALS ;
} else if ( key > elem . ts ) {
longjmp ( pRuntimeEnv - > env , TSDB_CODE_QRY_INCONSISTAN ) ;
}
} else {
if ( key > elem . ts ) {
return TS_JOIN_TS_NOT_EQUALS ;
} else if ( key < elem . ts ) {
longjmp ( pRuntimeEnv - > env , TSDB_CODE_QRY_INCONSISTAN ) ;
}
}
return TS_JOIN_TS_EQUAL ;
}
bool doFilterDataBlock ( SSingleColumnFilterInfo * pFilterInfo , int32_t numOfFilterCols , int32_t numOfRows , int8_t * p ) {
bool all = true ;
for ( int32_t i = 0 ; i < numOfRows ; + + i ) {
bool qualified = false ;
for ( int32_t k = 0 ; k < numOfFilterCols ; + + k ) {
char * pElem = ( char * ) pFilterInfo [ k ] . pData + pFilterInfo [ k ] . info . bytes * i ;
qualified = false ;
for ( int32_t j = 0 ; j < pFilterInfo [ k ] . numOfFilters ; + + j ) {
SColumnFilterElem * pFilterElem = NULL ;
// SColumnFilterElem* pFilterElem = &pFilterInfo[k].pFilters[j];
bool isnull = isNull ( pElem , pFilterInfo [ k ] . info . type ) ;
if ( isnull ) {
// if (pFilterElem->fp == isNullOperator) {
// qualified = true;
// break;
// } else {
// continue;
// }
} else {
// if (pFilterElem->fp == notNullOperator) {
// qualified = true;
// break;
// } else if (pFilterElem->fp == isNullOperator) {
// continue;
// }
}
if ( pFilterElem - > fp ( pFilterElem , pElem , pElem , pFilterInfo [ k ] . info . type ) ) {
qualified = true ;
break ;
}
}
if ( ! qualified ) {
break ;
}
}
p [ i ] = qualified ? 1 : 0 ;
if ( ! qualified ) {
all = false ;
}
}
return all ;
}
void doCompactSDataBlock ( SSDataBlock * pBlock , int32_t numOfRows , int8_t * p ) {
int32_t len = 0 ;
int32_t start = 0 ;
for ( int32_t j = 0 ; j < numOfRows ; + + j ) {
if ( p [ j ] = = 1 ) {
len + + ;
} else {
if ( len > 0 ) {
int32_t cstart = j - len ;
for ( int32_t i = 0 ; i < pBlock - > info . numOfCols ; + + i ) {
SColumnInfoData * pColumnInfoData = taosArrayGet ( pBlock - > pDataBlock , i ) ;
int16_t bytes = pColumnInfoData - > info . bytes ;
memmove ( ( ( char * ) pColumnInfoData - > pData ) + start * bytes , pColumnInfoData - > pData + cstart * bytes ,
len * bytes ) ;
}
start + = len ;
len = 0 ;
}
}
}
if ( len > 0 ) {
int32_t cstart = numOfRows - len ;
for ( int32_t i = 0 ; i < pBlock - > info . numOfCols ; + + i ) {
SColumnInfoData * pColumnInfoData = taosArrayGet ( pBlock - > pDataBlock , i ) ;
int16_t bytes = pColumnInfoData - > info . bytes ;
memmove ( pColumnInfoData - > pData + start * bytes , pColumnInfoData - > pData + cstart * bytes , len * bytes ) ;
}
start + = len ;
len = 0 ;
}
pBlock - > info . rows = start ;
pBlock - > pBlockAgg = NULL ; // clean the block statistics info
if ( start > 0 ) {
SColumnInfoData * pColumnInfoData = taosArrayGet ( pBlock - > pDataBlock , 0 ) ;
if ( pColumnInfoData - > info . type = = TSDB_DATA_TYPE_TIMESTAMP & &
pColumnInfoData - > info . colId = = PRIMARYKEY_TIMESTAMP_COL_ID ) {
pBlock - > info . window . skey = * ( int64_t * ) pColumnInfoData - > pData ;
pBlock - > info . window . ekey = * ( int64_t * ) ( pColumnInfoData - > pData + TSDB_KEYSIZE * ( start - 1 ) ) ;
}
}
}
2022-01-08 08:28:44 +00:00
void filterRowsInDataBlock ( STaskRuntimeEnv * pRuntimeEnv , SSingleColumnFilterInfo * pFilterInfo , int32_t numOfFilterCols ,
2021-11-02 05:37:31 +00:00
SSDataBlock * pBlock , bool ascQuery ) {
int32_t numOfRows = pBlock - > info . rows ;
int8_t * p = calloc ( numOfRows , sizeof ( int8_t ) ) ;
bool all = true ;
if ( pRuntimeEnv - > pTsBuf ! = NULL ) {
SColumnInfoData * pColInfoData = taosArrayGet ( pBlock - > pDataBlock , 0 ) ;
TSKEY * k = ( TSKEY * ) pColInfoData - > pData ;
for ( int32_t i = 0 ; i < numOfRows ; + + i ) {
int32_t offset = ascQuery ? i : ( numOfRows - i - 1 ) ;
int32_t ret = doTSJoinFilter ( pRuntimeEnv , k [ offset ] , ascQuery ) ;
if ( ret = = TS_JOIN_TAG_NOT_EQUALS ) {
break ;
} else if ( ret = = TS_JOIN_TS_NOT_EQUALS ) {
all = false ;
continue ;
} else {
assert ( ret = = TS_JOIN_TS_EQUAL ) ;
p [ offset ] = true ;
}
if ( ! tsBufNextPos ( pRuntimeEnv - > pTsBuf ) ) {
break ;
}
}
// save the cursor status
pRuntimeEnv - > current - > cur = tsBufGetCursor ( pRuntimeEnv - > pTsBuf ) ;
} else {
all = doFilterDataBlock ( pFilterInfo , numOfFilterCols , numOfRows , p ) ;
}
if ( ! all ) {
doCompactSDataBlock ( pBlock , numOfRows , p ) ;
}
tfree ( p ) ;
}
2022-01-08 08:28:44 +00:00
void filterColRowsInDataBlock ( STaskRuntimeEnv * pRuntimeEnv , SSDataBlock * pBlock , bool ascQuery ) {
2021-11-02 05:37:31 +00:00
int32_t numOfRows = pBlock - > info . rows ;
int8_t * p = NULL ;
bool all = true ;
if ( pRuntimeEnv - > pTsBuf ! = NULL ) {
SColumnInfoData * pColInfoData = taosArrayGet ( pBlock - > pDataBlock , 0 ) ;
p = calloc ( numOfRows , sizeof ( int8_t ) ) ;
TSKEY * k = ( TSKEY * ) pColInfoData - > pData ;
for ( int32_t i = 0 ; i < numOfRows ; + + i ) {
int32_t offset = ascQuery ? i : ( numOfRows - i - 1 ) ;
int32_t ret = doTSJoinFilter ( pRuntimeEnv , k [ offset ] , ascQuery ) ;
if ( ret = = TS_JOIN_TAG_NOT_EQUALS ) {
break ;
} else if ( ret = = TS_JOIN_TS_NOT_EQUALS ) {
all = false ;
continue ;
} else {
assert ( ret = = TS_JOIN_TS_EQUAL ) ;
p [ offset ] = true ;
}
if ( ! tsBufNextPos ( pRuntimeEnv - > pTsBuf ) ) {
break ;
}
}
// save the cursor status
pRuntimeEnv - > current - > cur = tsBufGetCursor ( pRuntimeEnv - > pTsBuf ) ;
} else {
// all = filterExecute(pRuntimeEnv->pQueryAttr->pFilters, numOfRows, &p, pBlock->pBlockAgg, pRuntimeEnv->pQueryAttr->numOfCols);
}
if ( ! all ) {
if ( p ) {
doCompactSDataBlock ( pBlock , numOfRows , p ) ;
} else {
pBlock - > info . rows = 0 ;
pBlock - > pBlockAgg = NULL ; // clean the block statistics info
}
}
tfree ( p ) ;
}
static SColumnInfo * doGetTagColumnInfoById ( SColumnInfo * pTagColList , int32_t numOfTags , int16_t colId ) ;
static void doSetTagValueInParam ( void * pTable , int32_t tagColId , SVariant * tag , int16_t type , int16_t bytes ) ;
static uint32_t doFilterByBlockTimeWindow ( STableScanInfo * pTableScanInfo , SSDataBlock * pBlock ) {
2022-01-28 02:44:02 +00:00
SqlFunctionCtx * pCtx = pTableScanInfo - > pCtx ;
2021-11-02 05:37:31 +00:00
uint32_t status = BLK_DATA_NO_NEEDED ;
int32_t numOfOutput = pTableScanInfo - > numOfOutput ;
for ( int32_t i = 0 ; i < numOfOutput ; + + i ) {
int32_t functionId = pCtx [ i ] . functionId ;
2021-11-05 02:35:50 +00:00
int32_t colId = pTableScanInfo - > pExpr [ i ] . base . pColumns - > info . colId ;
2021-11-02 05:37:31 +00:00
// group by + first/last should not apply the first/last block filter
if ( functionId < 0 ) {
status | = BLK_DATA_ALL_NEEDED ;
return status ;
} else {
// status |= aAggs[functionId].dataReqFunc(&pTableScanInfo->pCtx[i], &pBlock->info.window, colId);
// if ((status & BLK_DATA_ALL_NEEDED) == BLK_DATA_ALL_NEEDED) {
// return status;
// }
}
}
return status ;
}
void doSetFilterColumnInfo ( SSingleColumnFilterInfo * pFilterInfo , int32_t numOfFilterCols , SSDataBlock * pBlock ) {
// set the initial static data value filter expression
for ( int32_t i = 0 ; i < numOfFilterCols ; + + i ) {
for ( int32_t j = 0 ; j < pBlock - > info . numOfCols ; + + j ) {
SColumnInfoData * pColInfo = taosArrayGet ( pBlock - > pDataBlock , j ) ;
if ( pFilterInfo [ i ] . info . colId = = pColInfo - > info . colId ) {
pFilterInfo [ i ] . pData = pColInfo - > pData ;
break ;
}
}
}
}
2022-01-10 11:48:21 +00:00
int32_t loadDataBlock ( SExecTaskInfo * pTaskInfo , STableScanInfo * pTableScanInfo , SSDataBlock * pBlock , uint32_t * status ) {
2022-01-08 14:59:24 +00:00
STaskCostInfo * pCost = & pTaskInfo - > cost ;
pCost - > totalBlocks + = 1 ;
pCost - > totalRows + = pBlock - > info . rows ;
pCost - > totalCheckedRows + = pBlock - > info . rows ;
pCost - > loadBlocks + = 1 ;
2022-01-10 11:48:21 +00:00
pBlock - > pDataBlock = tsdbRetrieveDataBlock ( pTableScanInfo - > pTsdbReadHandle , NULL ) ;
2022-01-08 14:59:24 +00:00
if ( pBlock - > pDataBlock = = NULL ) {
return terrno ;
2022-01-10 11:48:21 +00:00
} else {
return TSDB_CODE_SUCCESS ;
2022-01-08 14:59:24 +00:00
}
}
2022-01-10 11:48:21 +00:00
int32_t loadDataBlockOnDemand ( SExecTaskInfo * pTaskInfo , STableScanInfo * pTableScanInfo , SSDataBlock * pBlock , uint32_t * status ) {
2021-11-02 05:37:31 +00:00
* status = BLK_DATA_NO_NEEDED ;
2022-01-08 14:59:24 +00:00
pBlock - > pDataBlock = NULL ;
pBlock - > pBlockAgg = NULL ;
// int64_t groupId = pRuntimeEnv->current->groupIndex;
// bool ascQuery = QUERY_IS_ASC_QUERY(pQueryAttr);
2021-11-02 05:37:31 +00:00
2022-01-08 14:59:24 +00:00
STaskCostInfo * pCost = & pTaskInfo - > cost ;
2021-11-02 05:37:31 +00:00
pCost - > totalBlocks + = 1 ;
pCost - > totalRows + = pBlock - > info . rows ;
2022-01-08 14:59:24 +00:00
#if 0
2021-11-02 05:37:31 +00:00
if ( pRuntimeEnv - > pTsBuf ! = NULL ) {
( * status ) = BLK_DATA_ALL_NEEDED ;
if ( pQueryAttr - > stableQuery ) { // todo refactor
SExprInfo * pExprInfo = & pTableScanInfo - > pExpr [ 0 ] ;
int16_t tagId = ( int16_t ) pExprInfo - > base . param [ 0 ] . i ;
SColumnInfo * pColInfo = doGetTagColumnInfoById ( pQueryAttr - > tagColList , pQueryAttr - > numOfTags , tagId ) ;
// compare tag first
SVariant t = { 0 } ;
doSetTagValueInParam ( pRuntimeEnv - > current - > pTable , tagId , & t , pColInfo - > type , pColInfo - > bytes ) ;
setTimestampListJoinInfo ( pRuntimeEnv , & t , pRuntimeEnv - > current ) ;
STSElem elem = tsBufGetElem ( pRuntimeEnv - > pTsBuf ) ;
if ( ! tsBufIsValidElem ( & elem ) | | ( tsBufIsValidElem ( & elem ) & & ( taosVariantCompare ( & t , elem . tag ) ! = 0 ) ) ) {
( * status ) = BLK_DATA_DISCARD ;
return TSDB_CODE_SUCCESS ;
}
}
}
// Calculate all time windows that are overlapping or contain current data block.
// If current data block is contained by all possible time window, do not load current data block.
if ( /*pQueryAttr->pFilters || */ pQueryAttr - > groupbyColumn | | pQueryAttr - > sw . gap > 0 | |
2022-01-08 14:59:24 +00:00
( QUERY_IS_INTERVAL_QUERY ( pQueryAttr ) & & overlapWithTimeWindow ( pTaskInfo , & pBlock - > info ) ) ) {
2021-11-02 05:37:31 +00:00
( * status ) = BLK_DATA_ALL_NEEDED ;
}
// check if this data block is required to load
if ( ( * status ) ! = BLK_DATA_ALL_NEEDED ) {
bool needFilter = true ;
// the pCtx[i] result is belonged to previous time window since the outputBuf has not been set yet,
// the filter result may be incorrect. So in case of interval query, we need to set the correct time output buffer
if ( QUERY_IS_INTERVAL_QUERY ( pQueryAttr ) ) {
SResultRow * pResult = NULL ;
2022-01-08 14:59:24 +00:00
bool masterScan = IS_MAIN_SCAN ( pRuntimeEnv ) ;
2021-11-02 05:37:31 +00:00
TSKEY k = ascQuery ? pBlock - > info . window . skey : pBlock - > info . window . ekey ;
STimeWindow win = getActiveTimeWindow ( pTableScanInfo - > pResultRowInfo , k , pQueryAttr ) ;
if ( pQueryAttr - > pointInterpQuery ) {
needFilter = chkWindowOutputBufByKey ( pRuntimeEnv , pTableScanInfo - > pResultRowInfo , & win , masterScan , & pResult , groupId ,
pTableScanInfo - > pCtx , pTableScanInfo - > numOfOutput ,
pTableScanInfo - > rowCellInfoOffset ) ;
} else {
if ( setResultOutputBufByKey ( pRuntimeEnv , pTableScanInfo - > pResultRowInfo , pBlock - > info . uid , & win , masterScan , & pResult , groupId ,
pTableScanInfo - > pCtx , pTableScanInfo - > numOfOutput ,
pTableScanInfo - > rowCellInfoOffset ) ! = TSDB_CODE_SUCCESS ) {
longjmp ( pRuntimeEnv - > env , TSDB_CODE_QRY_OUT_OF_MEMORY ) ;
}
}
} else if ( pQueryAttr - > stableQuery & & ( ! pQueryAttr - > tsCompQuery ) & & ( ! pQueryAttr - > diffQuery ) ) { // stable aggregate, not interval aggregate or normal column aggregate
doSetTableGroupOutputBuf ( pRuntimeEnv , pTableScanInfo - > pResultRowInfo , pTableScanInfo - > pCtx ,
pTableScanInfo - > rowCellInfoOffset , pTableScanInfo - > numOfOutput ,
pRuntimeEnv - > current - > groupIndex ) ;
}
if ( needFilter ) {
( * status ) = doFilterByBlockTimeWindow ( pTableScanInfo , pBlock ) ;
} else {
( * status ) = BLK_DATA_ALL_NEEDED ;
}
}
SDataBlockInfo * pBlockInfo = & pBlock - > info ;
2022-01-08 14:59:24 +00:00
// *status = updateBlockLoadStatus(pRuntimeEnv->pQueryAttr, *status);
2021-11-02 05:37:31 +00:00
if ( ( * status ) = = BLK_DATA_NO_NEEDED | | ( * status ) = = BLK_DATA_DISCARD ) {
//qDebug("QInfo:0x%"PRIx64" data block discard, brange:%" PRId64 "-%" PRId64 ", rows:%d", pQInfo->qId, pBlockInfo->window.skey,
// pBlockInfo->window.ekey, pBlockInfo->rows);
pCost - > discardBlocks + = 1 ;
} else if ( ( * status ) = = BLK_DATA_STATIS_NEEDED ) {
// this function never returns error?
pCost - > loadBlockStatis + = 1 ;
2022-01-10 11:48:21 +00:00
// tsdbRetrieveDataBlockStatisInfo(pTableScanInfo->pTsdbReadHandle, &pBlock->pBlockAgg);
2021-11-02 05:37:31 +00:00
if ( pBlock - > pBlockAgg = = NULL ) { // data block statistics does not exist, load data block
2022-01-10 11:48:21 +00:00
// pBlock->pDataBlock = tsdbRetrieveDataBlock(pTableScanInfo->pTsdbReadHandle, NULL);
2021-11-02 05:37:31 +00:00
pCost - > totalCheckedRows + = pBlock - > info . rows ;
}
} else {
assert ( ( * status ) = = BLK_DATA_ALL_NEEDED ) ;
// load the data block statistics to perform further filter
pCost - > loadBlockStatis + = 1 ;
2022-01-10 11:48:21 +00:00
// tsdbRetrieveDataBlockStatisInfo(pTableScanInfo->pTsdbReadHandle, &pBlock->pBlockAgg);
2021-11-02 05:37:31 +00:00
if ( pQueryAttr - > topBotQuery & & pBlock - > pBlockAgg ! = NULL ) {
{ // set previous window
if ( QUERY_IS_INTERVAL_QUERY ( pQueryAttr ) ) {
SResultRow * pResult = NULL ;
2022-01-08 14:59:24 +00:00
bool masterScan = IS_MAIN_SCAN ( pRuntimeEnv ) ;
2021-11-02 05:37:31 +00:00
TSKEY k = ascQuery ? pBlock - > info . window . skey : pBlock - > info . window . ekey ;
STimeWindow win = getActiveTimeWindow ( pTableScanInfo - > pResultRowInfo , k , pQueryAttr ) ;
if ( setResultOutputBufByKey ( pRuntimeEnv , pTableScanInfo - > pResultRowInfo , pBlock - > info . uid , & win , masterScan , & pResult , groupId ,
pTableScanInfo - > pCtx , pTableScanInfo - > numOfOutput ,
pTableScanInfo - > rowCellInfoOffset ) ! = TSDB_CODE_SUCCESS ) {
longjmp ( pRuntimeEnv - > env , TSDB_CODE_QRY_OUT_OF_MEMORY ) ;
}
}
}
bool load = false ;
for ( int32_t i = 0 ; i < pQueryAttr - > numOfOutput ; + + i ) {
int32_t functionId = pTableScanInfo - > pCtx [ i ] . functionId ;
if ( functionId = = FUNCTION_TOP | | functionId = = FUNCTION_BOTTOM ) {
// load = topbot_datablock_filter(&pTableScanInfo->pCtx[i], (char*)&(pBlock->pBlockAgg[i].min),
// (char*)&(pBlock->pBlockAgg[i].max));
if ( ! load ) { // current block has been discard due to filter applied
pCost - > discardBlocks + = 1 ;
//qDebug("QInfo:0x%"PRIx64" data block discard, brange:%" PRId64 "-%" PRId64 ", rows:%d", pQInfo->qId,
// pBlockInfo->window.skey, pBlockInfo->window.ekey, pBlockInfo->rows);
( * status ) = BLK_DATA_DISCARD ;
return TSDB_CODE_SUCCESS ;
}
}
}
}
// current block has been discard due to filter applied
// if (!doFilterByBlockStatistics(pRuntimeEnv, pBlock->pBlockAgg, pTableScanInfo->pCtx, pBlockInfo->rows)) {
// pCost->discardBlocks += 1;
// qDebug("QInfo:0x%"PRIx64" data block discard, brange:%" PRId64 "-%" PRId64 ", rows:%d", pQInfo->qId, pBlockInfo->window.skey,
// pBlockInfo->window.ekey, pBlockInfo->rows);
// (*status) = BLK_DATA_DISCARD;
// return TSDB_CODE_SUCCESS;
// }
pCost - > totalCheckedRows + = pBlockInfo - > rows ;
pCost - > loadBlocks + = 1 ;
2022-01-10 11:48:21 +00:00
// pBlock->pDataBlock = tsdbRetrieveDataBlock(pTableScanInfo->pTsdbReadHandle, NULL);
2021-11-02 05:37:31 +00:00
// if (pBlock->pDataBlock == NULL) {
// return terrno;
// }
// if (pQueryAttr->pFilters != NULL) {
// filterSetColFieldData(pQueryAttr->pFilters, pBlock->info.numOfCols, pBlock->pDataBlock);
// }
// if (pQueryAttr->pFilters != NULL || pRuntimeEnv->pTsBuf != NULL) {
// filterColRowsInDataBlock(pRuntimeEnv, pBlock, ascQuery);
// }
}
2022-01-08 14:59:24 +00:00
# endif
2021-11-02 05:37:31 +00:00
return TSDB_CODE_SUCCESS ;
}
int32_t binarySearchForKey ( char * pValue , int num , TSKEY key , int order ) {
int32_t midPos = - 1 ;
int32_t numOfRows ;
if ( num < = 0 ) {
return - 1 ;
}
assert ( order = = TSDB_ORDER_ASC | | order = = TSDB_ORDER_DESC ) ;
TSKEY * keyList = ( TSKEY * ) pValue ;
int32_t firstPos = 0 ;
int32_t lastPos = num - 1 ;
if ( order = = TSDB_ORDER_DESC ) {
// find the first position which is smaller than the key
while ( 1 ) {
if ( key > = keyList [ lastPos ] ) return lastPos ;
if ( key = = keyList [ firstPos ] ) return firstPos ;
if ( key < keyList [ firstPos ] ) return firstPos - 1 ;
numOfRows = lastPos - firstPos + 1 ;
midPos = ( numOfRows > > 1 ) + firstPos ;
if ( key < keyList [ midPos ] ) {
lastPos = midPos - 1 ;
} else if ( key > keyList [ midPos ] ) {
firstPos = midPos + 1 ;
} else {
break ;
}
}
} else {
// find the first position which is bigger than the key
while ( 1 ) {
if ( key < = keyList [ firstPos ] ) return firstPos ;
if ( key = = keyList [ lastPos ] ) return lastPos ;
if ( key > keyList [ lastPos ] ) {
lastPos = lastPos + 1 ;
if ( lastPos > = num )
return - 1 ;
else
return lastPos ;
}
numOfRows = lastPos - firstPos + 1 ;
midPos = ( numOfRows > > 1u ) + firstPos ;
if ( key < keyList [ midPos ] ) {
lastPos = midPos - 1 ;
} else if ( key > keyList [ midPos ] ) {
firstPos = midPos + 1 ;
} else {
break ;
}
}
}
return midPos ;
}
/*
2022-01-28 02:44:02 +00:00
* set tag value in SqlFunctionCtx
2021-11-02 05:37:31 +00:00
* e . g . , tag information into input buffer
*/
static void doSetTagValueInParam ( void * pTable , int32_t tagColId , SVariant * tag , int16_t type , int16_t bytes ) {
taosVariantDestroy ( tag ) ;
char * val = NULL ;
// if (tagColId == TSDB_TBNAME_COLUMN_INDEX) {
// val = tsdbGetTableName(pTable);
// assert(val != NULL);
// } else {
// val = tsdbGetTableTagVal(pTable, tagColId, type, bytes);
// }
if ( val = = NULL | | isNull ( val , type ) ) {
tag - > nType = TSDB_DATA_TYPE_NULL ;
return ;
}
if ( type = = TSDB_DATA_TYPE_BINARY | | type = = TSDB_DATA_TYPE_NCHAR ) {
int32_t maxLen = bytes - VARSTR_HEADER_SIZE ;
int32_t len = ( varDataLen ( val ) > maxLen ) ? maxLen : varDataLen ( val ) ;
taosVariantCreateFromBinary ( tag , varDataVal ( val ) , len , type ) ;
//taosVariantCreateFromBinary(tag, varDataVal(val), varDataLen(val), type);
} else {
taosVariantCreateFromBinary ( tag , val , bytes , type ) ;
}
}
static SColumnInfo * doGetTagColumnInfoById ( SColumnInfo * pTagColList , int32_t numOfTags , int16_t colId ) {
assert ( pTagColList ! = NULL & & numOfTags > 0 ) ;
for ( int32_t i = 0 ; i < numOfTags ; + + i ) {
if ( pTagColList [ i ] . colId = = colId ) {
return & pTagColList [ i ] ;
}
}
return NULL ;
}
2022-01-28 02:44:02 +00:00
void setTagValue ( SOperatorInfo * pOperatorInfo , void * pTable , SqlFunctionCtx * pCtx , int32_t numOfOutput ) {
2022-01-08 08:28:44 +00:00
STaskRuntimeEnv * pRuntimeEnv = pOperatorInfo - > pRuntimeEnv ;
2021-11-02 05:37:31 +00:00
SExprInfo * pExpr = pOperatorInfo - > pExpr ;
2022-01-08 08:28:44 +00:00
STaskAttr * pQueryAttr = pRuntimeEnv - > pQueryAttr ;
2021-11-02 05:37:31 +00:00
SExprInfo * pExprInfo = & pExpr [ 0 ] ;
int32_t functionId = getExprFunctionId ( pExprInfo ) ;
if ( pQueryAttr - > numOfOutput = = 1 & & functionId = = FUNCTION_TS_COMP & & pQueryAttr - > stableQuery ) {
assert ( pExprInfo - > base . numOfParams = = 1 ) ;
int16_t tagColId = ( int16_t ) pExprInfo - > base . param [ 0 ] . i ;
SColumnInfo * pColInfo = doGetTagColumnInfoById ( pQueryAttr - > tagColList , pQueryAttr - > numOfTags , tagColId ) ;
doSetTagValueInParam ( pTable , tagColId , & pCtx [ 0 ] . tag , pColInfo - > type , pColInfo - > bytes ) ;
return ;
} else {
// set tag value, by which the results are aggregated.
int32_t offset = 0 ;
memset ( pRuntimeEnv - > tagVal , 0 , pQueryAttr - > tagLen ) ;
for ( int32_t idx = 0 ; idx < numOfOutput ; + + idx ) {
SExprInfo * pLocalExprInfo = & pExpr [ idx ] ;
// ts_comp column required the tag value for join filter
2021-11-04 05:24:19 +00:00
if ( ! TSDB_COL_IS_TAG ( pLocalExprInfo - > base . pColumns - > flag ) ) {
2021-11-02 05:37:31 +00:00
continue ;
}
// todo use tag column index to optimize performance
2021-11-05 02:35:50 +00:00
doSetTagValueInParam ( pTable , pLocalExprInfo - > base . pColumns - > info . colId , & pCtx [ idx ] . tag , pLocalExprInfo - > base . resSchema . type ,
2021-11-02 05:37:31 +00:00
pLocalExprInfo - > base . resSchema . bytes ) ;
if ( IS_NUMERIC_TYPE ( pLocalExprInfo - > base . resSchema . type )
| | pLocalExprInfo - > base . resSchema . type = = TSDB_DATA_TYPE_BOOL
| | pLocalExprInfo - > base . resSchema . type = = TSDB_DATA_TYPE_TIMESTAMP ) {
memcpy ( pRuntimeEnv - > tagVal + offset , & pCtx [ idx ] . tag . i , pLocalExprInfo - > base . resSchema . bytes ) ;
} else {
if ( pCtx [ idx ] . tag . pz ! = NULL ) {
memcpy ( pRuntimeEnv - > tagVal + offset , pCtx [ idx ] . tag . pz , pCtx [ idx ] . tag . nLen ) ;
}
}
offset + = pLocalExprInfo - > base . resSchema . bytes ;
}
//todo : use index to avoid iterator all possible output columns
if ( pQueryAttr - > stableQuery & & pQueryAttr - > stabledev & & ( pRuntimeEnv - > prevResult ! = NULL ) ) {
setParamForStableStddev ( pRuntimeEnv , pCtx , numOfOutput , pExprInfo ) ;
}
}
// set the tsBuf start position before check each data block
if ( pRuntimeEnv - > pTsBuf ! = NULL ) {
setCtxTagForJoin ( pRuntimeEnv , & pCtx [ 0 ] , pExprInfo , pTable ) ;
}
}
2022-01-08 08:28:44 +00:00
void copyToSDataBlock ( STaskRuntimeEnv * pRuntimeEnv , int32_t threshold , SSDataBlock * pBlock , int32_t * offset ) {
2021-11-02 05:37:31 +00:00
SGroupResInfo * pGroupResInfo = & pRuntimeEnv - > groupResInfo ;
pBlock - > info . rows = 0 ;
int32_t code = TSDB_CODE_SUCCESS ;
while ( pGroupResInfo - > currentGroup < pGroupResInfo - > totalGroup ) {
// all results in current group have been returned to client, try next group
if ( ( pGroupResInfo - > pRows = = NULL ) | | taosArrayGetSize ( pGroupResInfo - > pRows ) = = 0 ) {
assert ( pGroupResInfo - > index = = 0 ) ;
if ( ( code = mergeIntoGroupResult ( & pRuntimeEnv - > groupResInfo , pRuntimeEnv , offset ) ) ! = TSDB_CODE_SUCCESS ) {
return ;
}
}
doCopyToSDataBlock ( pRuntimeEnv , pGroupResInfo , TSDB_ORDER_ASC , pBlock ) ;
// current data are all dumped to result buffer, clear it
if ( ! hasRemainDataInCurrentGroup ( pGroupResInfo ) ) {
cleanupGroupResInfo ( pGroupResInfo ) ;
if ( ! incNextGroup ( pGroupResInfo ) ) {
break ;
}
}
// enough results in data buffer, return
if ( pBlock - > info . rows > = threshold ) {
break ;
}
}
}
static void updateTableQueryInfoForReverseScan ( STableQueryInfo * pTableQueryInfo ) {
if ( pTableQueryInfo = = NULL ) {
return ;
}
2022-01-24 04:53:17 +00:00
TSWAP ( pTableQueryInfo - > win . skey , pTableQueryInfo - > win . ekey , TSKEY ) ;
2021-11-02 05:37:31 +00:00
pTableQueryInfo - > lastKey = pTableQueryInfo - > win . skey ;
SWITCH_ORDER ( pTableQueryInfo - > cur . order ) ;
pTableQueryInfo - > cur . vgroupIndex = - 1 ;
// set the index to be the end slot of result rows array
SResultRowInfo * pResultRowInfo = & pTableQueryInfo - > resInfo ;
if ( pResultRowInfo - > size > 0 ) {
pResultRowInfo - > curPos = pResultRowInfo - > size - 1 ;
} else {
pResultRowInfo - > curPos = - 1 ;
}
}
2022-01-08 14:59:24 +00:00
static void setupQueryRangeForReverseScan ( STableScanInfo * pTableScanInfo ) {
#if 0
2021-11-02 05:37:31 +00:00
int32_t numOfGroups = ( int32_t ) ( GET_NUM_OF_TABLEGROUP ( pRuntimeEnv ) ) ;
for ( int32_t i = 0 ; i < numOfGroups ; + + i ) {
SArray * group = GET_TABLEGROUP ( pRuntimeEnv , i ) ;
SArray * tableKeyGroup = taosArrayGetP ( pQueryAttr - > tableGroupInfo . pGroupList , i ) ;
size_t t = taosArrayGetSize ( group ) ;
for ( int32_t j = 0 ; j < t ; + + j ) {
STableQueryInfo * pCheckInfo = taosArrayGetP ( group , j ) ;
updateTableQueryInfoForReverseScan ( pCheckInfo ) ;
// update the last key in tableKeyInfo list, the tableKeyInfo is used to build the tsdbQueryHandle and decide
// the start check timestamp of tsdbQueryHandle
// STableKeyInfo *pTableKeyInfo = taosArrayGet(tableKeyGroup, j);
// pTableKeyInfo->lastKey = pCheckInfo->lastKey;
//
// assert(pCheckInfo->pTable == pTableKeyInfo->pTable);
}
}
2022-01-08 14:59:24 +00:00
# endif
2021-11-02 05:37:31 +00:00
}
2022-01-28 02:44:02 +00:00
void switchCtxOrder ( SqlFunctionCtx * pCtx , int32_t numOfOutput ) {
2021-11-02 05:37:31 +00:00
for ( int32_t i = 0 ; i < numOfOutput ; + + i ) {
SWITCH_ORDER ( pCtx [ i ] . order ) ;
}
}
int32_t initResultRow ( SResultRow * pResultRow ) {
pResultRow - > pEntryInfo = ( struct SResultRowEntryInfo * ) ( ( char * ) pResultRow + sizeof ( SResultRow ) ) ;
pResultRow - > pageId = - 1 ;
pResultRow - > offset = - 1 ;
return TSDB_CODE_SUCCESS ;
}
/*
* The start of each column SResultRowEntryInfo is denote by RowCellInfoOffset .
* Note that in case of top / bottom query , the whole multiple rows of result is treated as only one row of results .
* + - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - result column 1 - - - - - - - - - - - + - - - - - - - - - - - - - - - - - result column 2 - - - - - - - - - - - +
* + SResultRow | SResultRowEntryInfo | intermediate buffer1 | SResultRowEntryInfo | intermediate buffer 2 |
* + - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
* offset [ 0 ] offset [ 1 ] offset [ 2 ]
*/
2022-01-08 08:28:44 +00:00
void setDefaultOutputBuf ( STaskRuntimeEnv * pRuntimeEnv , SOptrBasicInfo * pInfo , int64_t uid , int32_t stage ) {
2022-01-28 02:44:02 +00:00
SqlFunctionCtx * pCtx = pInfo - > pCtx ;
2021-11-02 05:37:31 +00:00
SSDataBlock * pDataBlock = pInfo - > pRes ;
int32_t * rowCellInfoOffset = pInfo - > rowCellInfoOffset ;
SResultRowInfo * pResultRowInfo = & pInfo - > resultRowInfo ;
int64_t tid = 0 ;
pRuntimeEnv - > keyBuf = realloc ( pRuntimeEnv - > keyBuf , sizeof ( tid ) + sizeof ( int64_t ) + POINTER_BYTES ) ;
SResultRow * pRow = doSetResultOutBufByKey ( pRuntimeEnv , pResultRowInfo , tid , ( char * ) & tid , sizeof ( tid ) , true , uid ) ;
for ( int32_t i = 0 ; i < pDataBlock - > info . numOfCols ; + + i ) {
SColumnInfoData * pData = taosArrayGet ( pDataBlock - > pDataBlock , i ) ;
/*
* set the output buffer information and intermediate buffer
* not all queries require the interResultBuf , such as COUNT / TAGPRJ / PRJ / TAG etc .
*/
struct SResultRowEntryInfo * pEntry = getResultCell ( pRow , i , rowCellInfoOffset ) ;
cleanupResultRowEntry ( pEntry ) ;
pCtx [ i ] . resultInfo = pEntry ;
pCtx [ i ] . pOutput = pData - > pData ;
pCtx [ i ] . currentStage = stage ;
assert ( pCtx [ i ] . pOutput ! = NULL ) ;
// set the timestamp output buffer for top/bottom/diff query
int32_t fid = pCtx [ i ] . functionId ;
if ( fid = = FUNCTION_TOP | | fid = = FUNCTION_BOTTOM | | fid = = FUNCTION_DIFF | | fid = = FUNCTION_DERIVATIVE ) {
if ( i > 0 ) pCtx [ i ] . ptsOutputBuf = pCtx [ i - 1 ] . pOutput ;
}
}
initCtxOutputBuffer ( pCtx , pDataBlock - > info . numOfCols ) ;
}
2022-01-20 05:52:46 +00:00
void setDefaultOutputBuf_rv ( SAggOperatorInfo * pAggInfo , int64_t uid , int32_t stage , SExecTaskInfo * pTaskInfo ) {
SOptrBasicInfo * pInfo = & pAggInfo - > binfo ;
2022-01-28 02:44:02 +00:00
SqlFunctionCtx * pCtx = pInfo - > pCtx ;
2022-01-20 05:52:46 +00:00
SSDataBlock * pDataBlock = pInfo - > pRes ;
int32_t * rowCellInfoOffset = pInfo - > rowCellInfoOffset ;
SResultRowInfo * pResultRowInfo = & pInfo - > resultRowInfo ;
int64_t tid = 0 ;
2022-01-20 14:57:29 +00:00
pAggInfo - > keyBuf = realloc ( pAggInfo - > keyBuf , sizeof ( tid ) + sizeof ( int64_t ) + POINTER_BYTES ) ;
2022-01-20 05:52:46 +00:00
SResultRow * pRow = doSetResultOutBufByKey_rv ( pResultRowInfo , tid , ( char * ) & tid , sizeof ( tid ) , true , uid , pTaskInfo , false , pAggInfo ) ;
for ( int32_t i = 0 ; i < pDataBlock - > info . numOfCols ; + + i ) {
SColumnInfoData * pData = taosArrayGet ( pDataBlock - > pDataBlock , i ) ;
/*
* set the output buffer information and intermediate buffer
* not all queries require the interResultBuf , such as COUNT / TAGPRJ / PRJ / TAG etc .
*/
struct SResultRowEntryInfo * pEntry = getResultCell ( pRow , i , rowCellInfoOffset ) ;
cleanupResultRowEntry ( pEntry ) ;
pCtx [ i ] . resultInfo = pEntry ;
pCtx [ i ] . pOutput = pData - > pData ;
pCtx [ i ] . currentStage = stage ;
assert ( pCtx [ i ] . pOutput ! = NULL ) ;
// set the timestamp output buffer for top/bottom/diff query
int32_t fid = pCtx [ i ] . functionId ;
if ( fid = = FUNCTION_TOP | | fid = = FUNCTION_BOTTOM | | fid = = FUNCTION_DIFF | | fid = = FUNCTION_DERIVATIVE ) {
if ( i > 0 ) pCtx [ i ] . ptsOutputBuf = pCtx [ i - 1 ] . pOutput ;
}
}
initCtxOutputBuffer ( pCtx , pDataBlock - > info . numOfCols ) ;
}
2021-11-02 05:37:31 +00:00
void updateOutputBuf ( SOptrBasicInfo * pBInfo , int32_t * bufCapacity , int32_t numOfInputRows ) {
SSDataBlock * pDataBlock = pBInfo - > pRes ;
int32_t newSize = pDataBlock - > info . rows + numOfInputRows + 5 ; // extra output buffer
if ( ( * bufCapacity ) < newSize ) {
for ( int32_t i = 0 ; i < pDataBlock - > info . numOfCols ; + + i ) {
SColumnInfoData * pColInfo = taosArrayGet ( pDataBlock - > pDataBlock , i ) ;
char * p = realloc ( pColInfo - > pData , newSize * pColInfo - > info . bytes ) ;
if ( p ! = NULL ) {
pColInfo - > pData = p ;
// it starts from the tail of the previously generated results.
pBInfo - > pCtx [ i ] . pOutput = pColInfo - > pData ;
( * bufCapacity ) = newSize ;
} else {
// longjmp
}
}
}
for ( int32_t i = 0 ; i < pDataBlock - > info . numOfCols ; + + i ) {
SColumnInfoData * pColInfo = taosArrayGet ( pDataBlock - > pDataBlock , i ) ;
pBInfo - > pCtx [ i ] . pOutput = pColInfo - > pData + pColInfo - > info . bytes * pDataBlock - > info . rows ;
// set the correct pointer after the memory buffer reallocated.
int32_t functionId = pBInfo - > pCtx [ i ] . functionId ;
if ( functionId = = FUNCTION_TOP | | functionId = = FUNCTION_BOTTOM | | functionId = = FUNCTION_DIFF | | functionId = = FUNCTION_DERIVATIVE ) {
if ( i > 0 ) pBInfo - > pCtx [ i ] . ptsOutputBuf = pBInfo - > pCtx [ i - 1 ] . pOutput ;
}
}
}
2022-01-28 02:44:02 +00:00
void copyTsColoum ( SSDataBlock * pRes , SqlFunctionCtx * pCtx , int32_t numOfOutput ) {
2021-11-02 05:37:31 +00:00
bool needCopyTs = false ;
int32_t tsNum = 0 ;
char * src = NULL ;
for ( int32_t i = 0 ; i < numOfOutput ; i + + ) {
int32_t functionId = pCtx [ i ] . functionId ;
if ( functionId = = FUNCTION_DIFF | | functionId = = FUNCTION_DERIVATIVE ) {
needCopyTs = true ;
if ( i > 0 & & pCtx [ i - 1 ] . functionId = = FUNCTION_TS_DUMMY ) {
SColumnInfoData * pColRes = taosArrayGet ( pRes - > pDataBlock , i - 1 ) ; // find ts data
src = pColRes - > pData ;
}
} else if ( functionId = = FUNCTION_TS_DUMMY ) {
tsNum + + ;
}
}
if ( ! needCopyTs ) return ;
if ( tsNum < 2 ) return ;
if ( src = = NULL ) return ;
for ( int32_t i = 0 ; i < numOfOutput ; i + + ) {
int32_t functionId = pCtx [ i ] . functionId ;
if ( functionId = = FUNCTION_TS_DUMMY ) {
SColumnInfoData * pColRes = taosArrayGet ( pRes - > pDataBlock , i ) ;
memcpy ( pColRes - > pData , src , pColRes - > info . bytes * pRes - > info . rows ) ;
}
}
}
void clearOutputBuf ( SOptrBasicInfo * pBInfo , int32_t * bufCapacity ) {
SSDataBlock * pDataBlock = pBInfo - > pRes ;
for ( int32_t i = 0 ; i < pDataBlock - > info . numOfCols ; + + i ) {
SColumnInfoData * pColInfo = taosArrayGet ( pDataBlock - > pDataBlock , i ) ;
int32_t functionId = pBInfo - > pCtx [ i ] . functionId ;
if ( functionId < 0 ) {
memset ( pBInfo - > pCtx [ i ] . pOutput , 0 , pColInfo - > info . bytes * ( * bufCapacity ) ) ;
}
}
}
2022-01-28 02:44:02 +00:00
void initCtxOutputBuffer ( SqlFunctionCtx * pCtx , int32_t size ) {
2021-11-02 05:37:31 +00:00
for ( int32_t j = 0 ; j < size ; + + j ) {
struct SResultRowEntryInfo * pResInfo = GET_RES_INFO ( & pCtx [ j ] ) ;
if ( isRowEntryInitialized ( pResInfo ) ) {
continue ;
}
2021-11-02 07:08:00 +00:00
pCtx [ j ] . fpSet - > init ( & pCtx [ j ] , pCtx [ j ] . resultInfo ) ;
2021-11-02 05:37:31 +00:00
}
}
2022-01-10 11:48:21 +00:00
void setTaskStatus ( SExecTaskInfo * pTaskInfo , int8_t status ) {
if ( status = = TASK_NOT_COMPLETED ) {
2022-01-08 14:59:24 +00:00
pTaskInfo - > status = status ;
2021-11-02 05:37:31 +00:00
} else {
// QUERY_NOT_COMPLETED is not compatible with any other status, so clear its position first
2022-01-10 11:48:21 +00:00
CLEAR_QUERY_STATUS ( pTaskInfo , TASK_NOT_COMPLETED ) ;
2022-01-08 14:59:24 +00:00
pTaskInfo - > status | = status ;
2021-11-02 05:37:31 +00:00
}
}
2022-01-28 02:44:02 +00:00
static void setupEnvForReverseScan ( STableScanInfo * pTableScanInfo , SqlFunctionCtx * pCtx , int32_t numOfOutput ) {
2022-01-08 14:59:24 +00:00
// if (pRuntimeEnv->pTsBuf) {
// SWITCH_ORDER(pRuntimeEnv->pTsBuf->cur.order);
// bool ret = tsBufNextPos(pRuntimeEnv->pTsBuf);
// assert(ret);
// }
2021-11-02 05:37:31 +00:00
// reverse order time range
2022-01-08 14:59:24 +00:00
SET_REVERSE_SCAN_FLAG ( pTableScanInfo ) ;
// setTaskStatus(pTableScanInfo, QUERY_NOT_COMPLETED);
2021-11-02 05:37:31 +00:00
switchCtxOrder ( pCtx , numOfOutput ) ;
2022-01-08 14:59:24 +00:00
SWITCH_ORDER ( pTableScanInfo - > order ) ;
setupQueryRangeForReverseScan ( pTableScanInfo ) ;
2022-01-10 11:48:21 +00:00
pTableScanInfo - > times = 1 ;
pTableScanInfo - > current = 0 ;
pTableScanInfo - > reverseTimes = 0 ;
2021-11-02 05:37:31 +00:00
}
2022-01-28 02:44:02 +00:00
void finalizeQueryResult ( SOperatorInfo * pOperator , SqlFunctionCtx * pCtx , SResultRowInfo * pResultRowInfo , int32_t * rowCellInfoOffset ) {
2022-01-08 08:28:44 +00:00
STaskRuntimeEnv * pRuntimeEnv = pOperator - > pRuntimeEnv ;
2022-01-20 09:10:28 +00:00
// STaskAttr *pQueryAttr = pRuntimeEnv->pQueryAttr;
2021-11-02 05:37:31 +00:00
int32_t numOfOutput = pOperator - > numOfOutput ;
2022-01-20 09:10:28 +00:00
// if (pQueryAttr->groupbyColumn || QUERY_IS_INTERVAL_QUERY(pQueryAttr) || pQueryAttr->sw.gap > 0 || pQueryAttr->stateWindow) {
// // for each group result, call the finalize function for each column
// if (pQueryAttr->groupbyColumn) {
// closeAllResultRows(pResultRowInfo);
// }
//
// for (int32_t i = 0; i < pResultRowInfo->size; ++i) {
// SResultRow *buf = pResultRowInfo->pResult[i];
// if (!isResultRowClosed(pResultRowInfo, i)) {
// continue;
// }
//
// setResultOutputBuf(pRuntimeEnv, buf, pCtx, numOfOutput, rowCellInfoOffset);
//
// for (int32_t j = 0; j < numOfOutput; ++j) {
//// pCtx[j].startTs = buf->win.skey;
//// if (pCtx[j].functionId < 0) {
//// doInvokeUdf(pRuntimeEnv->pUdfInfo, &pCtx[j], 0, TSDB_UDF_FUNC_FINALIZE);
//// } else {
//// aAggs[pCtx[j].functionId].xFinalize(&pCtx[j]);
//// }
// }
//
//
// /*
// * set the number of output results for group by normal columns, the number of output rows usually is 1 except
// * the top and bottom query
// */
// buf->numOfRows = (uint16_t)getNumOfResult(pCtx, numOfOutput);
// }
//
// } else {
2021-11-02 05:37:31 +00:00
for ( int32_t j = 0 ; j < numOfOutput ; + + j ) {
// if (pCtx[j].functionId < 0) {
// doInvokeUdf(pRuntimeEnv->pUdfInfo, &pCtx[j], 0, TSDB_UDF_FUNC_FINALIZE);
// } else {
2022-01-20 09:10:28 +00:00
pCtx [ j ] . fpSet - > finalize ( & pCtx [ j ] ) ;
2021-11-02 05:37:31 +00:00
// }
}
2022-01-20 09:10:28 +00:00
// }
2021-11-02 05:37:31 +00:00
}
2022-01-08 08:28:44 +00:00
static bool hasMainOutput ( STaskAttr * pQueryAttr ) {
2021-11-02 05:37:31 +00:00
for ( int32_t i = 0 ; i < pQueryAttr - > numOfOutput ; + + i ) {
int32_t functionId = getExprFunctionId ( & pQueryAttr - > pExpr1 [ i ] ) ;
if ( functionId ! = FUNCTION_TS & & functionId ! = FUNCTION_TAG & & functionId ! = FUNCTION_TAGPRJ ) {
return true ;
}
}
return false ;
}
2022-01-08 08:28:44 +00:00
STableQueryInfo * createTableQueryInfo ( STaskAttr * pQueryAttr , void * pTable , bool groupbyColumn , STimeWindow win , void * buf ) {
2021-11-02 05:37:31 +00:00
STableQueryInfo * pTableQueryInfo = buf ;
pTableQueryInfo - > win = win ;
pTableQueryInfo - > lastKey = win . skey ;
pTableQueryInfo - > pTable = pTable ;
pTableQueryInfo - > cur . vgroupIndex = - 1 ;
// set more initial size of interval/groupby query
if ( QUERY_IS_INTERVAL_QUERY ( pQueryAttr ) | | groupbyColumn ) {
int32_t initialSize = 128 ;
int32_t code = initResultRowInfo ( & pTableQueryInfo - > resInfo , initialSize , TSDB_DATA_TYPE_INT ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
return NULL ;
}
} else { // in other aggregate query, do not initialize the windowResInfo
}
return pTableQueryInfo ;
}
STableQueryInfo * createTmpTableQueryInfo ( STimeWindow win ) {
STableQueryInfo * pTableQueryInfo = calloc ( 1 , sizeof ( STableQueryInfo ) ) ;
pTableQueryInfo - > win = win ;
pTableQueryInfo - > lastKey = win . skey ;
pTableQueryInfo - > pTable = NULL ;
pTableQueryInfo - > cur . vgroupIndex = - 1 ;
// set more initial size of interval/groupby query
int32_t initialSize = 16 ;
int32_t code = initResultRowInfo ( & pTableQueryInfo - > resInfo , initialSize , TSDB_DATA_TYPE_INT ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
tfree ( pTableQueryInfo ) ;
return NULL ;
}
return pTableQueryInfo ;
}
void destroyTableQueryInfoImpl ( STableQueryInfo * pTableQueryInfo ) {
if ( pTableQueryInfo = = NULL ) {
return ;
}
taosVariantDestroy ( & pTableQueryInfo - > tag ) ;
cleanupResultRowInfo ( & pTableQueryInfo - > resInfo ) ;
}
2022-01-28 02:44:02 +00:00
void setResultRowOutputBufInitCtx ( STaskRuntimeEnv * pRuntimeEnv , SResultRow * pResult , SqlFunctionCtx * pCtx ,
2021-11-02 05:37:31 +00:00
int32_t numOfOutput , int32_t * rowCellInfoOffset ) {
// Note: pResult->pos[i]->num == 0, there is only fixed number of results for each group
2022-02-10 05:49:17 +00:00
SFilePage * bufPage = getBufPage ( pRuntimeEnv - > pResultBuf , pResult - > pageId ) ;
2021-11-02 05:37:31 +00:00
int32_t offset = 0 ;
for ( int32_t i = 0 ; i < numOfOutput ; + + i ) {
pCtx [ i ] . resultInfo = getResultCell ( pResult , i , rowCellInfoOffset ) ;
struct SResultRowEntryInfo * pResInfo = pCtx [ i ] . resultInfo ;
if ( isRowEntryCompleted ( pResInfo ) & & isRowEntryInitialized ( pResInfo ) ) {
2021-11-02 07:08:00 +00:00
offset + = pCtx [ i ] . resDataInfo . bytes ;
2021-11-02 05:37:31 +00:00
continue ;
}
pCtx [ i ] . pOutput = getPosInResultPage ( pRuntimeEnv - > pQueryAttr , bufPage , pResult - > offset , offset ) ;
2021-11-02 07:08:00 +00:00
offset + = pCtx [ i ] . resDataInfo . bytes ;
2021-11-02 05:37:31 +00:00
int32_t functionId = pCtx [ i ] . functionId ;
if ( functionId < 0 ) {
continue ;
}
if ( functionId = = FUNCTION_TOP | | functionId = = FUNCTION_BOTTOM | | functionId = = FUNCTION_DIFF ) {
if ( i > 0 ) pCtx [ i ] . ptsOutputBuf = pCtx [ i - 1 ] . pOutput ;
}
// if (!pResInfo->initialized) {
// aAggs[functionId].init(&pCtx[i], pResInfo);
// }
}
}
2022-01-28 02:44:02 +00:00
void doSetTableGroupOutputBuf ( STaskRuntimeEnv * pRuntimeEnv , SResultRowInfo * pResultRowInfo , SqlFunctionCtx * pCtx ,
2021-11-02 05:37:31 +00:00
int32_t * rowCellInfoOffset , int32_t numOfOutput , int32_t tableGroupId ) {
// for simple group by query without interval, all the tables belong to one group result.
int64_t uid = 0 ;
int64_t tid = 0 ;
SResultRow * pResultRow =
doSetResultOutBufByKey ( pRuntimeEnv , pResultRowInfo , tid , ( char * ) & tableGroupId , sizeof ( tableGroupId ) , true , uid ) ;
assert ( pResultRow ! = NULL ) ;
/*
* not assign result buffer yet , add new result buffer
* all group belong to one result set , and each group result has different group id so set the id to be one
*/
if ( pResultRow - > pageId = = - 1 ) {
int32_t ret = addNewWindowResultBuf ( pResultRow , pRuntimeEnv - > pResultBuf , tableGroupId , pRuntimeEnv - > pQueryAttr - > resultRowSize ) ;
if ( ret ! = TSDB_CODE_SUCCESS ) {
return ;
}
}
setResultRowOutputBufInitCtx ( pRuntimeEnv , pResultRow , pCtx , numOfOutput , rowCellInfoOffset ) ;
}
2022-01-08 08:28:44 +00:00
void setExecutionContext ( STaskRuntimeEnv * pRuntimeEnv , SOptrBasicInfo * pInfo , int32_t numOfOutput , int32_t tableGroupId ,
2021-11-02 05:37:31 +00:00
TSKEY nextKey ) {
STableQueryInfo * pTableQueryInfo = pRuntimeEnv - > current ;
// lastKey needs to be updated
pTableQueryInfo - > lastKey = nextKey ;
if ( pRuntimeEnv - > prevGroupId ! = INT32_MIN & & pRuntimeEnv - > prevGroupId = = tableGroupId ) {
return ;
}
doSetTableGroupOutputBuf ( pRuntimeEnv , & pInfo - > resultRowInfo , pInfo - > pCtx , pInfo - > rowCellInfoOffset , numOfOutput , tableGroupId ) ;
// record the current active group id
pRuntimeEnv - > prevGroupId = tableGroupId ;
}
2022-01-28 02:44:02 +00:00
void setResultOutputBuf ( STaskRuntimeEnv * pRuntimeEnv , SResultRow * pResult , SqlFunctionCtx * pCtx ,
2021-11-02 05:37:31 +00:00
int32_t numOfCols , int32_t * rowCellInfoOffset ) {
// Note: pResult->pos[i]->num == 0, there is only fixed number of results for each group
2022-02-10 05:49:17 +00:00
SFilePage * page = getBufPage ( pRuntimeEnv - > pResultBuf , pResult - > pageId ) ;
2021-11-02 05:37:31 +00:00
int16_t offset = 0 ;
for ( int32_t i = 0 ; i < numOfCols ; + + i ) {
pCtx [ i ] . pOutput = getPosInResultPage ( pRuntimeEnv - > pQueryAttr , page , pResult - > offset , offset ) ;
2021-11-02 07:08:00 +00:00
offset + = pCtx [ i ] . resDataInfo . bytes ;
2021-11-02 05:37:31 +00:00
int32_t functionId = pCtx [ i ] . functionId ;
if ( functionId = = FUNCTION_TOP | | functionId = = FUNCTION_BOTTOM | | functionId = = FUNCTION_DIFF | | functionId = = FUNCTION_DERIVATIVE ) {
if ( i > 0 ) pCtx [ i ] . ptsOutputBuf = pCtx [ i - 1 ] . pOutput ;
}
/*
* set the output buffer information and intermediate buffer ,
* not all queries require the interResultBuf , such as COUNT
*/
pCtx [ i ] . resultInfo = getResultCell ( pResult , i , rowCellInfoOffset ) ;
}
}
2022-01-28 02:44:02 +00:00
void setCtxTagForJoin ( STaskRuntimeEnv * pRuntimeEnv , SqlFunctionCtx * pCtx , SExprInfo * pExprInfo , void * pTable ) {
2022-01-08 08:28:44 +00:00
STaskAttr * pQueryAttr = pRuntimeEnv - > pQueryAttr ;
2021-11-02 05:37:31 +00:00
SSqlExpr * pExpr = & pExprInfo - > base ;
// if (pQueryAttr->stableQuery && (pRuntimeEnv->pTsBuf != NULL) &&
// (pExpr->functionId == FUNCTION_TS || pExpr->functionId == FUNCTION_PRJ) &&
// (pExpr->colInfo.colIndex == PRIMARYKEY_TIMESTAMP_COL_ID)) {
// assert(pExpr->numOfParams == 1);
//
// int16_t tagColId = (int16_t)pExprInfo->base.param[0].i;
// SColumnInfo* pColInfo = doGetTagColumnInfoById(pQueryAttr->tagColList, pQueryAttr->numOfTags, tagColId);
//
// doSetTagValueInParam(pTable, tagColId, &pCtx->tag, pColInfo->type, pColInfo->bytes);
//
// int16_t tagType = pCtx[0].tag.nType;
// if (tagType == TSDB_DATA_TYPE_BINARY || tagType == TSDB_DATA_TYPE_NCHAR) {
2022-01-10 11:48:21 +00:00
// //qDebug("QInfo:0x%"PRIx64" set tag value for join comparison, colId:%" PRId64 ", val:%s", GET_TASKID(pRuntimeEnv),
2021-11-02 05:37:31 +00:00
//// pExprInfo->base.param[0].i, pCtx[0].tag.pz);
// } else {
2022-01-10 11:48:21 +00:00
// //qDebug("QInfo:0x%"PRIx64" set tag value for join comparison, colId:%" PRId64 ", val:%" PRId64, GET_TASKID(pRuntimeEnv),
2021-11-02 05:37:31 +00:00
//// pExprInfo->base.param[0].i, pCtx[0].tag.i);
// }
// }
}
2022-01-08 08:28:44 +00:00
int32_t setTimestampListJoinInfo ( STaskRuntimeEnv * pRuntimeEnv , SVariant * pTag , STableQueryInfo * pTableQueryInfo ) {
STaskAttr * pQueryAttr = pRuntimeEnv - > pQueryAttr ;
2021-11-02 05:37:31 +00:00
assert ( pRuntimeEnv - > pTsBuf ! = NULL ) ;
// both the master and supplement scan needs to set the correct ts comp start position
if ( pTableQueryInfo - > cur . vgroupIndex = = - 1 ) {
taosVariantAssign ( & pTableQueryInfo - > tag , pTag ) ;
STSElem elem = tsBufGetElemStartPos ( pRuntimeEnv - > pTsBuf , pQueryAttr - > vgId , & pTableQueryInfo - > tag ) ;
// failed to find data with the specified tag value and vnodeId
if ( ! tsBufIsValidElem ( & elem ) ) {
if ( pTag - > nType = = TSDB_DATA_TYPE_BINARY | | pTag - > nType = = TSDB_DATA_TYPE_NCHAR ) {
2022-01-10 11:48:21 +00:00
//qError("QInfo:0x%"PRIx64" failed to find tag:%s in ts_comp", GET_TASKID(pRuntimeEnv), pTag->pz);
2021-11-02 05:37:31 +00:00
} else {
2022-01-10 11:48:21 +00:00
//qError("QInfo:0x%"PRIx64" failed to find tag:%" PRId64 " in ts_comp", GET_TASKID(pRuntimeEnv), pTag->i);
2021-11-02 05:37:31 +00:00
}
return - 1 ;
}
// Keep the cursor info of current table
pTableQueryInfo - > cur = tsBufGetCursor ( pRuntimeEnv - > pTsBuf ) ;
if ( pTag - > nType = = TSDB_DATA_TYPE_BINARY | | pTag - > nType = = TSDB_DATA_TYPE_NCHAR ) {
2022-01-10 11:48:21 +00:00
//qDebug("QInfo:0x%"PRIx64" find tag:%s start pos in ts_comp, blockIndex:%d, tsIndex:%d", GET_TASKID(pRuntimeEnv), pTag->pz, pTableQueryInfo->cur.blockIndex, pTableQueryInfo->cur.tsIndex);
2021-11-02 05:37:31 +00:00
} else {
2022-01-10 11:48:21 +00:00
//qDebug("QInfo:0x%"PRIx64" find tag:%"PRId64" start pos in ts_comp, blockIndex:%d, tsIndex:%d", GET_TASKID(pRuntimeEnv), pTag->i, pTableQueryInfo->cur.blockIndex, pTableQueryInfo->cur.tsIndex);
2021-11-02 05:37:31 +00:00
}
} else {
tsBufSetCursor ( pRuntimeEnv - > pTsBuf , & pTableQueryInfo - > cur ) ;
if ( pTag - > nType = = TSDB_DATA_TYPE_BINARY | | pTag - > nType = = TSDB_DATA_TYPE_NCHAR ) {
2022-01-10 11:48:21 +00:00
//qDebug("QInfo:0x%"PRIx64" find tag:%s start pos in ts_comp, blockIndex:%d, tsIndex:%d", GET_TASKID(pRuntimeEnv), pTag->pz, pTableQueryInfo->cur.blockIndex, pTableQueryInfo->cur.tsIndex);
2021-11-02 05:37:31 +00:00
} else {
2022-01-10 11:48:21 +00:00
//qDebug("QInfo:0x%"PRIx64" find tag:%"PRId64" start pos in ts_comp, blockIndex:%d, tsIndex:%d", GET_TASKID(pRuntimeEnv), pTag->i, pTableQueryInfo->cur.blockIndex, pTableQueryInfo->cur.tsIndex);
2021-11-02 05:37:31 +00:00
}
}
return 0 ;
}
// TODO refactor: this funciton should be merged with setparamForStableStddevColumnData function.
2022-01-28 02:44:02 +00:00
void setParamForStableStddev ( STaskRuntimeEnv * pRuntimeEnv , SqlFunctionCtx * pCtx , int32_t numOfOutput , SExprInfo * pExprInfo ) {
2021-11-02 05:37:31 +00:00
#if 0
2022-01-08 08:28:44 +00:00
STaskAttr * pQueryAttr = pRuntimeEnv - > pQueryAttr ;
2021-11-02 05:37:31 +00:00
int32_t numOfExprs = pQueryAttr - > numOfOutput ;
for ( int32_t i = 0 ; i < numOfExprs ; + + i ) {
SExprInfo * pExprInfo1 = & ( pExprInfo [ i ] ) ;
if ( pExprInfo1 - > base . functionId ! = FUNCTION_STDDEV_DST ) {
continue ;
}
SSqlExpr * pExpr = & pExprInfo1 - > base ;
pCtx [ i ] . param [ 0 ] . arr = NULL ;
pCtx [ i ] . param [ 0 ] . nType = TSDB_DATA_TYPE_INT ; // avoid freeing the memory by setting the type to be int
// TODO use hash to speedup this loop
int32_t numOfGroup = ( int32_t ) taosArrayGetSize ( pRuntimeEnv - > prevResult ) ;
for ( int32_t j = 0 ; j < numOfGroup ; + + j ) {
SInterResult * p = taosArrayGet ( pRuntimeEnv - > prevResult , j ) ;
if ( pQueryAttr - > tagLen = = 0 | | memcmp ( p - > tags , pRuntimeEnv - > tagVal , pQueryAttr - > tagLen ) = = 0 ) {
int32_t numOfCols = ( int32_t ) taosArrayGetSize ( p - > pResult ) ;
for ( int32_t k = 0 ; k < numOfCols ; + + k ) {
SStddevInterResult * pres = taosArrayGet ( p - > pResult , k ) ;
2021-11-05 02:35:50 +00:00
if ( pres - > info . colId = = pExpr - > colInfo . colId ) {
2021-11-02 05:37:31 +00:00
pCtx [ i ] . param [ 0 ] . arr = pres - > pResult ;
break ;
}
}
}
}
}
# endif
}
2022-01-28 02:44:02 +00:00
void setParamForStableStddevByColData ( STaskRuntimeEnv * pRuntimeEnv , SqlFunctionCtx * pCtx , int32_t numOfOutput , SExprInfo * pExpr , char * val , int16_t bytes ) {
2022-01-08 08:28:44 +00:00
STaskAttr * pQueryAttr = pRuntimeEnv - > pQueryAttr ;
2021-11-02 05:37:31 +00:00
#if 0
int32_t numOfExprs = pQueryAttr - > numOfOutput ;
for ( int32_t i = 0 ; i < numOfExprs ; + + i ) {
SSqlExpr * pExpr1 = & pExpr [ i ] . base ;
if ( pExpr1 - > functionId ! = FUNCTION_STDDEV_DST ) {
continue ;
}
pCtx [ i ] . param [ 0 ] . arr = NULL ;
pCtx [ i ] . param [ 0 ] . nType = TSDB_DATA_TYPE_INT ; // avoid freeing the memory by setting the type to be int
// TODO use hash to speedup this loop
int32_t numOfGroup = ( int32_t ) taosArrayGetSize ( pRuntimeEnv - > prevResult ) ;
for ( int32_t j = 0 ; j < numOfGroup ; + + j ) {
SInterResult * p = taosArrayGet ( pRuntimeEnv - > prevResult , j ) ;
if ( bytes = = 0 | | memcmp ( p - > tags , val , bytes ) = = 0 ) {
int32_t numOfCols = ( int32_t ) taosArrayGetSize ( p - > pResult ) ;
for ( int32_t k = 0 ; k < numOfCols ; + + k ) {
SStddevInterResult * pres = taosArrayGet ( p - > pResult , k ) ;
2021-11-05 02:35:50 +00:00
if ( pres - > info . colId = = pExpr1 - > colInfo . colId ) {
2021-11-02 05:37:31 +00:00
pCtx [ i ] . param [ 0 ] . arr = pres - > pResult ;
break ;
}
}
}
}
}
# endif
}
/*
* There are two cases to handle :
*
* 1. Query range is not set yet ( queryRangeSet = 0 ) . we need to set the query range info , including pQueryAttr - > lastKey ,
* pQueryAttr - > window . skey , and pQueryAttr - > eKey .
* 2. Query range is set and query is in progress . There may be another result with the same query ranges to be
* merged during merge stage . In this case , we need the pTableQueryInfo - > lastResRows to decide if there
* is a previous result generated or not .
*/
2022-01-08 08:28:44 +00:00
void setIntervalQueryRange ( STaskRuntimeEnv * pRuntimeEnv , TSKEY key ) {
STaskAttr * pQueryAttr = pRuntimeEnv - > pQueryAttr ;
2021-11-02 05:37:31 +00:00
STableQueryInfo * pTableQueryInfo = pRuntimeEnv - > current ;
SResultRowInfo * pResultRowInfo = & pTableQueryInfo - > resInfo ;
if ( pResultRowInfo - > curPos ! = - 1 ) {
return ;
}
pTableQueryInfo - > win . skey = key ;
STimeWindow win = { . skey = key , . ekey = pQueryAttr - > window . ekey } ;
/**
* In handling the both ascending and descending order super table query , we need to find the first qualified
* timestamp of this table , and then set the first qualified start timestamp .
* In ascending query , the key is the first qualified timestamp . However , in the descending order query , additional
* operations involve .
*/
STimeWindow w = TSWINDOW_INITIALIZER ;
2022-01-24 04:53:17 +00:00
TSKEY sk = TMIN ( win . skey , win . ekey ) ;
TSKEY ek = TMAX ( win . skey , win . ekey ) ;
2021-11-02 05:37:31 +00:00
getAlignQueryTimeWindow ( pQueryAttr , win . skey , sk , ek , & w ) ;
// if (pResultRowInfo->prevSKey == TSKEY_INITIAL_VAL) {
// if (!QUERY_IS_ASC_QUERY(pQueryAttr)) {
// assert(win.ekey == pQueryAttr->window.ekey);
// }
//
// pResultRowInfo->prevSKey = w.skey;
// }
pTableQueryInfo - > lastKey = pTableQueryInfo - > win . skey ;
}
/**
* copyToOutputBuf support copy data in ascending / descending order
* For interval query of both super table and table , copy the data in ascending order , since the output results are
* ordered in SWindowResutl already . While handling the group by query for both table and super table ,
* all group result are completed already .
*
* @ param pQInfo
* @ param result
*/
2022-01-08 08:28:44 +00:00
static int32_t doCopyToSDataBlock ( STaskRuntimeEnv * pRuntimeEnv , SGroupResInfo * pGroupResInfo , int32_t orderType , SSDataBlock * pBlock ) {
STaskAttr * pQueryAttr = pRuntimeEnv - > pQueryAttr ;
2021-11-02 05:37:31 +00:00
int32_t numOfRows = getNumOfTotalRes ( pGroupResInfo ) ;
int32_t numOfResult = pBlock - > info . rows ; // there are already exists result rows
int32_t start = 0 ;
int32_t step = - 1 ;
2022-01-10 11:48:21 +00:00
//qDebug("QInfo:0x%"PRIx64" start to copy data from windowResInfo to output buf", GET_TASKID(pRuntimeEnv));
2021-11-02 05:37:31 +00:00
assert ( orderType = = TSDB_ORDER_ASC | | orderType = = TSDB_ORDER_DESC ) ;
if ( orderType = = TSDB_ORDER_ASC ) {
start = pGroupResInfo - > index ;
step = 1 ;
} else { // desc order copy all data
start = numOfRows - pGroupResInfo - > index - 1 ;
step = - 1 ;
}
for ( int32_t i = start ; ( i < numOfRows ) & & ( i > = 0 ) ; i + = step ) {
SResultRow * pRow = taosArrayGetP ( pGroupResInfo - > pRows , i ) ;
if ( pRow - > numOfRows = = 0 ) {
pGroupResInfo - > index + = 1 ;
continue ;
}
int32_t numOfRowsToCopy = pRow - > numOfRows ;
if ( numOfResult + numOfRowsToCopy > = pRuntimeEnv - > resultInfo . capacity ) {
break ;
}
pGroupResInfo - > index + = 1 ;
2022-02-10 05:49:17 +00:00
SFilePage * page = getBufPage ( pRuntimeEnv - > pResultBuf , pRow - > pageId ) ;
2021-11-02 05:37:31 +00:00
int32_t offset = 0 ;
for ( int32_t j = 0 ; j < pBlock - > info . numOfCols ; + + j ) {
SColumnInfoData * pColInfoData = taosArrayGet ( pBlock - > pDataBlock , j ) ;
int32_t bytes = pColInfoData - > info . bytes ;
char * out = pColInfoData - > pData + numOfResult * bytes ;
char * in = getPosInResultPage ( pQueryAttr , page , pRow - > offset , offset ) ;
memcpy ( out , in , bytes * numOfRowsToCopy ) ;
offset + = bytes ;
}
numOfResult + = numOfRowsToCopy ;
if ( numOfResult = = pRuntimeEnv - > resultInfo . capacity ) { // output buffer is full
break ;
}
}
2022-01-10 11:48:21 +00:00
//qDebug("QInfo:0x%"PRIx64" copy data to query buf completed", GET_TASKID(pRuntimeEnv));
2021-11-02 05:37:31 +00:00
pBlock - > info . rows = numOfResult ;
return 0 ;
}
2022-01-08 08:28:44 +00:00
static void toSSDataBlock ( SGroupResInfo * pGroupResInfo , STaskRuntimeEnv * pRuntimeEnv , SSDataBlock * pBlock ) {
2021-11-02 05:37:31 +00:00
assert ( pGroupResInfo - > currentGroup < = pGroupResInfo - > totalGroup ) ;
pBlock - > info . rows = 0 ;
if ( ! hasRemainDataInCurrentGroup ( pGroupResInfo ) ) {
return ;
}
2022-01-08 08:28:44 +00:00
STaskAttr * pQueryAttr = pRuntimeEnv - > pQueryAttr ;
2021-11-10 15:31:35 +00:00
int32_t orderType = TSDB_ORDER_ASC ; //(pQueryAttr->pGroupbyExpr != NULL) ? pQueryAttr->pGroupbyExpr->orderType : TSDB_ORDER_ASC;
2021-11-02 05:37:31 +00:00
doCopyToSDataBlock ( pRuntimeEnv , pGroupResInfo , orderType , pBlock ) ;
// refactor : extract method
SColumnInfoData * pInfoData = taosArrayGet ( pBlock - > pDataBlock , 0 ) ;
//add condition (pBlock->info.rows >= 1) just to runtime happy
if ( pInfoData - > info . type = = TSDB_DATA_TYPE_TIMESTAMP & & pBlock - > info . rows > = 1 ) {
STimeWindow * w = & pBlock - > info . window ;
w - > skey = * ( int64_t * ) pInfoData - > pData ;
w - > ekey = * ( int64_t * ) ( ( ( char * ) pInfoData - > pData ) + TSDB_KEYSIZE * ( pBlock - > info . rows - 1 ) ) ;
}
}
2022-01-28 02:44:02 +00:00
static void updateNumOfRowsInResultRows ( STaskRuntimeEnv * pRuntimeEnv , SqlFunctionCtx * pCtx , int32_t numOfOutput ,
2021-11-02 05:37:31 +00:00
SResultRowInfo * pResultRowInfo , int32_t * rowCellInfoOffset ) {
2022-01-08 08:28:44 +00:00
STaskAttr * pQueryAttr = pRuntimeEnv - > pQueryAttr ;
2021-11-02 05:37:31 +00:00
// update the number of result for each, only update the number of rows for the corresponding window result.
if ( QUERY_IS_INTERVAL_QUERY ( pQueryAttr ) ) {
return ;
}
for ( int32_t i = 0 ; i < pResultRowInfo - > size ; + + i ) {
SResultRow * pResult = pResultRowInfo - > pResult [ i ] ;
for ( int32_t j = 0 ; j < numOfOutput ; + + j ) {
int32_t functionId = pCtx [ j ] . functionId ;
if ( functionId = = FUNCTION_TS | | functionId = = FUNCTION_TAG | | functionId = = FUNCTION_TAGPRJ ) {
continue ;
}
// SResultRowEntryInfo* pCell = getResultCell(pResult, j, rowCellInfoOffset);
2022-01-24 04:53:17 +00:00
// pResult->numOfRows = (uint16_t)(TMAX(pResult->numOfRows, pCell->numOfRes));
2021-11-02 05:37:31 +00:00
}
}
}
static int32_t compressQueryColData ( SColumnInfoData * pColRes , int32_t numOfRows , char * data , int8_t compressed ) {
int32_t colSize = pColRes - > info . bytes * numOfRows ;
return ( * ( tDataTypes [ pColRes - > info . type ] . compFunc ) ) ( pColRes - > pData , colSize , numOfRows , data ,
colSize + COMP_OVERFLOW_BYTES , compressed , NULL , 0 ) ;
}
static void doCopyQueryResultToMsg ( SQInfo * pQInfo , int32_t numOfRows , char * data , int8_t compressed , int32_t * compLen ) {
2022-01-08 08:28:44 +00:00
STaskRuntimeEnv * pRuntimeEnv = & pQInfo - > runtimeEnv ;
STaskAttr * pQueryAttr = pRuntimeEnv - > pQueryAttr ;
2021-11-02 05:37:31 +00:00
SSDataBlock * pRes = pRuntimeEnv - > outputBuf ;
int32_t * compSizes = NULL ;
int32_t numOfCols = pQueryAttr - > pExpr2 ? pQueryAttr - > numOfExpr2 : pQueryAttr - > numOfOutput ;
if ( compressed ) {
compSizes = calloc ( numOfCols , sizeof ( int32_t ) ) ;
}
if ( pQueryAttr - > pExpr2 = = NULL ) {
for ( int32_t col = 0 ; col < numOfCols ; + + col ) {
SColumnInfoData * pColRes = taosArrayGet ( pRes - > pDataBlock , col ) ;
if ( compressed ) {
compSizes [ col ] = compressQueryColData ( pColRes , pRes - > info . rows , data , compressed ) ;
data + = compSizes [ col ] ;
* compLen + = compSizes [ col ] ;
compSizes [ col ] = htonl ( compSizes [ col ] ) ;
} else {
memmove ( data , pColRes - > pData , pColRes - > info . bytes * pRes - > info . rows ) ;
data + = pColRes - > info . bytes * pRes - > info . rows ;
}
}
} else {
for ( int32_t col = 0 ; col < numOfCols ; + + col ) {
SColumnInfoData * pColRes = taosArrayGet ( pRes - > pDataBlock , col ) ;
if ( compressed ) {
compSizes [ col ] = htonl ( compressQueryColData ( pColRes , numOfRows , data , compressed ) ) ;
data + = compSizes [ col ] ;
* compLen + = compSizes [ col ] ;
compSizes [ col ] = htonl ( compSizes [ col ] ) ;
} else {
memmove ( data , pColRes - > pData , pColRes - > info . bytes * numOfRows ) ;
data + = pColRes - > info . bytes * numOfRows ;
}
}
}
if ( compressed ) {
memmove ( data , ( char * ) compSizes , numOfCols * sizeof ( int32_t ) ) ;
data + = numOfCols * sizeof ( int32_t ) ;
tfree ( compSizes ) ;
}
int32_t numOfTables = ( int32_t ) taosHashGetSize ( pRuntimeEnv - > pTableRetrieveTsMap ) ;
* ( int32_t * ) data = htonl ( numOfTables ) ;
data + = sizeof ( int32_t ) ;
int32_t total = 0 ;
STableIdInfo * item = taosHashIterate ( pRuntimeEnv - > pTableRetrieveTsMap , NULL ) ;
while ( item ) {
STableIdInfo * pDst = ( STableIdInfo * ) data ;
pDst - > uid = htobe64 ( item - > uid ) ;
pDst - > key = htobe64 ( item - > key ) ;
data + = sizeof ( STableIdInfo ) ;
total + + ;
//qDebug("QInfo:0x%"PRIx64" set subscribe info, tid:%d, uid:%"PRIu64", skey:%"PRId64, pQInfo->qId, item->tid, item->uid, item->key);
item = taosHashIterate ( pRuntimeEnv - > pTableRetrieveTsMap , item ) ;
}
//qDebug("QInfo:0x%"PRIx64" set %d subscribe info", pQInfo->qId, total);
// Check if query is completed or not for stable query or normal table query respectively.
2022-01-10 11:48:21 +00:00
if ( Q_STATUS_EQUAL ( pRuntimeEnv - > status , TASK_COMPLETED ) & & pRuntimeEnv - > proot - > status = = OP_EXEC_DONE ) {
2022-01-08 14:59:24 +00:00
// setTaskStatus(pOperator->pTaskInfo, QUERY_OVER);
2021-11-02 05:37:31 +00:00
}
}
int32_t doFillTimeIntervalGapsInResults ( struct SFillInfo * pFillInfo , SSDataBlock * pOutput , int32_t capacity , void * * p ) {
// for(int32_t i = 0; i < pFillInfo->numOfCols; ++i) {
// SColumnInfoData* pColInfoData = taosArrayGet(pOutput->pDataBlock, i);
// p[i] = pColInfoData->pData + (pColInfoData->info.bytes * pOutput->info.rows);
// }
int32_t numOfRows = ( int32_t ) taosFillResultDataBlock ( pFillInfo , p , capacity - pOutput - > info . rows ) ;
pOutput - > info . rows + = numOfRows ;
return pOutput - > info . rows ;
}
void publishOperatorProfEvent ( SOperatorInfo * operatorInfo , EQueryProfEventType eventType ) {
SQueryProfEvent event = { 0 } ;
event . eventType = eventType ;
event . eventTime = taosGetTimestampUs ( ) ;
event . operatorType = operatorInfo - > operatorType ;
if ( operatorInfo - > pRuntimeEnv ) {
SQInfo * pQInfo = operatorInfo - > pRuntimeEnv - > qinfo ;
if ( pQInfo - > summary . queryProfEvents ) {
taosArrayPush ( pQInfo - > summary . queryProfEvents , & event ) ;
}
}
}
2022-01-18 03:21:13 +00:00
void publishQueryAbortEvent ( SExecTaskInfo * pTaskInfo , int32_t code ) {
2021-11-02 05:37:31 +00:00
SQueryProfEvent event ;
event . eventType = QUERY_PROF_QUERY_ABORT ;
event . eventTime = taosGetTimestampUs ( ) ;
event . abortCode = code ;
2022-01-18 03:21:13 +00:00
if ( pTaskInfo - > cost . queryProfEvents ) {
taosArrayPush ( pTaskInfo - > cost . queryProfEvents , & event ) ;
2021-11-02 05:37:31 +00:00
}
}
typedef struct {
uint8_t operatorType ;
int64_t beginTime ;
int64_t endTime ;
int64_t selfTime ;
int64_t descendantsTime ;
} SOperatorStackItem ;
static void doOperatorExecProfOnce ( SOperatorStackItem * item , SQueryProfEvent * event , SArray * opStack , SHashObj * profResults ) {
item - > endTime = event - > eventTime ;
item - > selfTime = ( item - > endTime - item - > beginTime ) - ( item - > descendantsTime ) ;
for ( int32_t j = 0 ; j < taosArrayGetSize ( opStack ) ; + + j ) {
SOperatorStackItem * ancestor = taosArrayGet ( opStack , j ) ;
ancestor - > descendantsTime + = item - > selfTime ;
}
uint8_t operatorType = item - > operatorType ;
SOperatorProfResult * result = taosHashGet ( profResults , & operatorType , sizeof ( operatorType ) ) ;
if ( result ! = NULL ) {
result - > sumRunTimes + + ;
result - > sumSelfTime + = item - > selfTime ;
} else {
SOperatorProfResult opResult ;
opResult . operatorType = operatorType ;
opResult . sumSelfTime = item - > selfTime ;
opResult . sumRunTimes = 1 ;
taosHashPut ( profResults , & ( operatorType ) , sizeof ( operatorType ) ,
& opResult , sizeof ( opResult ) ) ;
}
}
void calculateOperatorProfResults ( SQInfo * pQInfo ) {
if ( pQInfo - > summary . queryProfEvents = = NULL ) {
//qDebug("QInfo:0x%"PRIx64" query prof events array is null", pQInfo->qId);
return ;
}
if ( pQInfo - > summary . operatorProfResults = = NULL ) {
//qDebug("QInfo:0x%"PRIx64" operator prof results hash is null", pQInfo->qId);
return ;
}
SArray * opStack = taosArrayInit ( 32 , sizeof ( SOperatorStackItem ) ) ;
if ( opStack = = NULL ) {
return ;
}
size_t size = taosArrayGetSize ( pQInfo - > summary . queryProfEvents ) ;
SHashObj * profResults = pQInfo - > summary . operatorProfResults ;
for ( int i = 0 ; i < size ; + + i ) {
SQueryProfEvent * event = taosArrayGet ( pQInfo - > summary . queryProfEvents , i ) ;
if ( event - > eventType = = QUERY_PROF_BEFORE_OPERATOR_EXEC ) {
SOperatorStackItem opItem ;
opItem . operatorType = event - > operatorType ;
opItem . beginTime = event - > eventTime ;
opItem . descendantsTime = 0 ;
taosArrayPush ( opStack , & opItem ) ;
} else if ( event - > eventType = = QUERY_PROF_AFTER_OPERATOR_EXEC ) {
SOperatorStackItem * item = taosArrayPop ( opStack ) ;
assert ( item - > operatorType = = event - > operatorType ) ;
doOperatorExecProfOnce ( item , event , opStack , profResults ) ;
} else if ( event - > eventType = = QUERY_PROF_QUERY_ABORT ) {
SOperatorStackItem * item ;
while ( ( item = taosArrayPop ( opStack ) ) ! = NULL ) {
doOperatorExecProfOnce ( item , event , opStack , profResults ) ;
}
}
}
taosArrayDestroy ( opStack ) ;
}
2022-01-25 02:41:35 +00:00
void queryCostStatis ( SExecTaskInfo * pTaskInfo ) {
STaskCostInfo * pSummary = & pTaskInfo - > cost ;
2021-11-02 05:37:31 +00:00
2022-01-25 02:41:35 +00:00
// uint64_t hashSize = taosHashGetMemSize(pQInfo->runtimeEnv.pResultRowHashTable);
// hashSize += taosHashGetMemSize(pRuntimeEnv->tableqinfoGroupInfo.map);
// pSummary->hashSize = hashSize;
2021-11-02 05:37:31 +00:00
// add the merge time
pSummary - > elapsedTime + = pSummary - > firstStageMergeTime ;
2022-01-25 02:41:35 +00:00
// SResultRowPool* p = pTaskInfo->pool;
// if (p != NULL) {
// pSummary->winInfoSize = getResultRowPoolMemSize(p);
// pSummary->numOfTimeWindows = getNumOfAllocatedResultRows(p);
// } else {
// pSummary->winInfoSize = 0;
// pSummary->numOfTimeWindows = 0;
// }
//
// calculateOperatorProfResults(pQInfo);
2021-11-02 05:37:31 +00:00
2022-01-25 05:42:33 +00:00
qDebug ( " %s :cost summary: elapsed time:% " PRId64 " us, first merge:% " PRId64 " us, total blocks:%d, "
2022-01-25 02:41:35 +00:00
" load block statis:%d, load data block:%d, total rows:% " PRId64 " , check rows:% " PRId64 ,
2022-01-25 05:42:33 +00:00
GET_TASKID ( pTaskInfo ) , pSummary - > elapsedTime , pSummary - > firstStageMergeTime , pSummary - > totalBlocks , pSummary - > loadBlockStatis ,
2022-01-25 02:41:35 +00:00
pSummary - > loadBlocks , pSummary - > totalRows , pSummary - > totalCheckedRows ) ;
//
2021-11-02 05:37:31 +00:00
//qDebug("QInfo:0x%"PRIx64" :cost summary: winResPool size:%.2f Kb, numOfWin:%"PRId64", tableInfoSize:%.2f Kb, hashTable:%.2f Kb", pQInfo->qId, pSummary->winInfoSize/1024.0,
// pSummary->numOfTimeWindows, pSummary->tableInfoSize/1024.0, pSummary->hashSize/1024.0);
if ( pSummary - > operatorProfResults ) {
SOperatorProfResult * opRes = taosHashIterate ( pSummary - > operatorProfResults , NULL ) ;
while ( opRes ! = NULL ) {
//qDebug("QInfo:0x%" PRIx64 " :cost summary: operator : %d, exec times: %" PRId64 ", self time: %" PRId64,
// pQInfo->qId, opRes->operatorType, opRes->sumRunTimes, opRes->sumSelfTime);
opRes = taosHashIterate ( pSummary - > operatorProfResults , opRes ) ;
}
}
}
2022-01-08 08:28:44 +00:00
//static void updateOffsetVal(STaskRuntimeEnv *pRuntimeEnv, SDataBlockInfo *pBlockInfo) {
// STaskAttr *pQueryAttr = pRuntimeEnv->pQueryAttr;
2021-11-02 05:37:31 +00:00
// STableQueryInfo* pTableQueryInfo = pRuntimeEnv->current;
//
// int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQueryAttr->order.order);
//
// if (pQueryAttr->limit.offset == pBlockInfo->rows) { // current block will ignore completed
// pTableQueryInfo->lastKey = QUERY_IS_ASC_QUERY(pQueryAttr) ? pBlockInfo->window.ekey + step : pBlockInfo->window.skey + step;
// pQueryAttr->limit.offset = 0;
// return;
// }
//
// if (QUERY_IS_ASC_QUERY(pQueryAttr)) {
// pQueryAttr->pos = (int32_t)pQueryAttr->limit.offset;
// } else {
// pQueryAttr->pos = pBlockInfo->rows - (int32_t)pQueryAttr->limit.offset - 1;
// }
//
// assert(pQueryAttr->pos >= 0 && pQueryAttr->pos <= pBlockInfo->rows - 1);
//
2022-01-10 11:48:21 +00:00
// SArray * pDataBlock = tsdbRetrieveDataBlock(pRuntimeEnv->pTsdbReadHandle, NULL);
2021-11-02 05:37:31 +00:00
// SColumnInfoData *pColInfoData = taosArrayGet(pDataBlock, 0);
//
// // update the pQueryAttr->limit.offset value, and pQueryAttr->pos value
// TSKEY *keys = (TSKEY *) pColInfoData->pData;
//
// // update the offset value
// pTableQueryInfo->lastKey = keys[pQueryAttr->pos];
// pQueryAttr->limit.offset = 0;
//
// int32_t numOfRes = tableApplyFunctionsOnBlock(pRuntimeEnv, pBlockInfo, NULL, binarySearchForKey, pDataBlock);
//
2022-01-10 11:48:21 +00:00
// //qDebug("QInfo:0x%"PRIx64" check data block, brange:%" PRId64 "-%" PRId64 ", numBlocksOfStep:%d, numOfRes:%d, lastKey:%"PRId64, GET_TASKID(pRuntimeEnv),
2021-11-02 05:37:31 +00:00
// pBlockInfo->window.skey, pBlockInfo->window.ekey, pBlockInfo->rows, numOfRes, pQuery->current->lastKey);
//}
2022-01-08 08:28:44 +00:00
//void skipBlocks(STaskRuntimeEnv *pRuntimeEnv) {
// STaskAttr *pQueryAttr = pRuntimeEnv->pQueryAttr;
2021-11-02 05:37:31 +00:00
//
// if (pQueryAttr->limit.offset <= 0 || pQueryAttr->numOfFilterCols > 0) {
// return;
// }
//
// pQueryAttr->pos = 0;
// int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQueryAttr->order.order);
//
// STableQueryInfo* pTableQueryInfo = pRuntimeEnv->current;
2022-01-10 11:48:21 +00:00
// TsdbQueryHandleT pTsdbReadHandle = pRuntimeEnv->pTsdbReadHandle;
2021-11-02 05:37:31 +00:00
//
// SDataBlockInfo blockInfo = SDATA_BLOCK_INITIALIZER;
2022-01-10 11:48:21 +00:00
// while (tsdbNextDataBlock(pTsdbReadHandle)) {
// if (isTaskKilled(pRuntimeEnv->qinfo)) {
2021-11-02 05:37:31 +00:00
// longjmp(pRuntimeEnv->env, TSDB_CODE_TSC_QUERY_CANCELLED);
// }
//
2022-01-10 11:48:21 +00:00
// tsdbRetrieveDataBlockInfo(pTsdbReadHandle, &blockInfo);
2021-11-02 05:37:31 +00:00
//
// if (pQueryAttr->limit.offset > blockInfo.rows) {
// pQueryAttr->limit.offset -= blockInfo.rows;
// pTableQueryInfo->lastKey = (QUERY_IS_ASC_QUERY(pQueryAttr)) ? blockInfo.window.ekey : blockInfo.window.skey;
// pTableQueryInfo->lastKey += step;
//
2022-01-10 11:48:21 +00:00
// //qDebug("QInfo:0x%"PRIx64" skip rows:%d, offset:%" PRId64, GET_TASKID(pRuntimeEnv), blockInfo.rows,
2021-11-02 05:37:31 +00:00
// pQuery->limit.offset);
// } else { // find the appropriated start position in current block
// updateOffsetVal(pRuntimeEnv, &blockInfo);
// break;
// }
// }
//
// if (terrno != TSDB_CODE_SUCCESS) {
// longjmp(pRuntimeEnv->env, terrno);
// }
//}
2022-01-08 08:28:44 +00:00
//static TSKEY doSkipIntervalProcess(STaskRuntimeEnv* pRuntimeEnv, STimeWindow* win, SDataBlockInfo* pBlockInfo, STableQueryInfo* pTableQueryInfo) {
// STaskAttr *pQueryAttr = pRuntimeEnv->pQueryAttr;
2021-11-02 05:37:31 +00:00
// SResultRowInfo *pWindowResInfo = &pRuntimeEnv->resultRowInfo;
//
// assert(pQueryAttr->limit.offset == 0);
// STimeWindow tw = *win;
// getNextTimeWindow(pQueryAttr, &tw);
//
// if ((tw.skey <= pBlockInfo->window.ekey && QUERY_IS_ASC_QUERY(pQueryAttr)) ||
// (tw.ekey >= pBlockInfo->window.skey && !QUERY_IS_ASC_QUERY(pQueryAttr))) {
//
// // load the data block and check data remaining in current data block
// // TODO optimize performance
2022-01-10 11:48:21 +00:00
// SArray * pDataBlock = tsdbRetrieveDataBlock(pRuntimeEnv->pTsdbReadHandle, NULL);
2021-11-02 05:37:31 +00:00
// SColumnInfoData *pColInfoData = taosArrayGet(pDataBlock, 0);
//
// tw = *win;
// int32_t startPos =
// getNextQualifiedWindow(pQueryAttr, &tw, pBlockInfo, pColInfoData->pData, binarySearchForKey, -1);
// assert(startPos >= 0);
//
// // set the abort info
// pQueryAttr->pos = startPos;
//
// // reset the query start timestamp
// pTableQueryInfo->win.skey = ((TSKEY *)pColInfoData->pData)[startPos];
// pQueryAttr->window.skey = pTableQueryInfo->win.skey;
// TSKEY key = pTableQueryInfo->win.skey;
//
// pWindowResInfo->prevSKey = tw.skey;
// int32_t index = pRuntimeEnv->resultRowInfo.curIndex;
//
// int32_t numOfRes = tableApplyFunctionsOnBlock(pRuntimeEnv, pBlockInfo, NULL, binarySearchForKey, pDataBlock);
// pRuntimeEnv->resultRowInfo.curIndex = index; // restore the window index
//
// //qDebug("QInfo:0x%"PRIx64" check data block, brange:%" PRId64 "-%" PRId64 ", numOfRows:%d, numOfRes:%d, lastKey:%" PRId64,
2022-01-10 11:48:21 +00:00
// GET_TASKID(pRuntimeEnv), pBlockInfo->window.skey, pBlockInfo->window.ekey, pBlockInfo->rows, numOfRes,
2021-11-02 05:37:31 +00:00
// pQueryAttr->current->lastKey);
//
// return key;
// } else { // do nothing
// pQueryAttr->window.skey = tw.skey;
// pWindowResInfo->prevSKey = tw.skey;
// pTableQueryInfo->lastKey = tw.skey;
//
// return tw.skey;
// }
//
// return true;
//}
2022-01-08 08:28:44 +00:00
//static bool skipTimeInterval(STaskRuntimeEnv *pRuntimeEnv, TSKEY* start) {
// STaskAttr *pQueryAttr = pRuntimeEnv->pQueryAttr;
2021-11-02 05:37:31 +00:00
// if (QUERY_IS_ASC_QUERY(pQueryAttr)) {
// assert(*start <= pRuntimeEnv->current->lastKey);
// } else {
// assert(*start >= pRuntimeEnv->current->lastKey);
// }
//
// // if queried with value filter, do NOT forward query start position
// if (pQueryAttr->limit.offset <= 0 || pQueryAttr->numOfFilterCols > 0 || pRuntimeEnv->pTsBuf != NULL || pRuntimeEnv->pFillInfo != NULL) {
// return true;
// }
//
// /*
// * 1. for interval without interpolation query we forward pQueryAttr->interval.interval at a time for
// * pQueryAttr->limit.offset times. Since hole exists, pQueryAttr->interval.interval*pQueryAttr->limit.offset value is
// * not valid. otherwise, we only forward pQueryAttr->limit.offset number of points
// */
// assert(pRuntimeEnv->resultRowInfo.prevSKey == TSKEY_INITIAL_VAL);
//
// STimeWindow w = TSWINDOW_INITIALIZER;
// bool ascQuery = QUERY_IS_ASC_QUERY(pQueryAttr);
//
// SResultRowInfo *pWindowResInfo = &pRuntimeEnv->resultRowInfo;
// STableQueryInfo *pTableQueryInfo = pRuntimeEnv->current;
//
// SDataBlockInfo blockInfo = SDATA_BLOCK_INITIALIZER;
2022-01-10 11:48:21 +00:00
// while (tsdbNextDataBlock(pRuntimeEnv->pTsdbReadHandle)) {
// tsdbRetrieveDataBlockInfo(pRuntimeEnv->pTsdbReadHandle, &blockInfo);
2021-11-02 05:37:31 +00:00
//
// if (QUERY_IS_ASC_QUERY(pQueryAttr)) {
// if (pWindowResInfo->prevSKey == TSKEY_INITIAL_VAL) {
// getAlignQueryTimeWindow(pQueryAttr, blockInfo.window.skey, blockInfo.window.skey, pQueryAttr->window.ekey, &w);
// pWindowResInfo->prevSKey = w.skey;
// }
// } else {
// getAlignQueryTimeWindow(pQueryAttr, blockInfo.window.ekey, pQueryAttr->window.ekey, blockInfo.window.ekey, &w);
// pWindowResInfo->prevSKey = w.skey;
// }
//
// // the first time window
// STimeWindow win = getActiveTimeWindow(pWindowResInfo, pWindowResInfo->prevSKey, pQueryAttr);
//
// while (pQueryAttr->limit.offset > 0) {
// STimeWindow tw = win;
//
// if ((win.ekey <= blockInfo.window.ekey && ascQuery) || (win.ekey >= blockInfo.window.skey && !ascQuery)) {
// pQueryAttr->limit.offset -= 1;
// pWindowResInfo->prevSKey = win.skey;
//
// // current time window is aligned with blockInfo.window.ekey
// // restart it from next data block by set prevSKey to be TSKEY_INITIAL_VAL;
// if ((win.ekey == blockInfo.window.ekey && ascQuery) || (win.ekey == blockInfo.window.skey && !ascQuery)) {
// pWindowResInfo->prevSKey = TSKEY_INITIAL_VAL;
// }
// }
//
// if (pQueryAttr->limit.offset == 0) {
// *start = doSkipIntervalProcess(pRuntimeEnv, &win, &blockInfo, pTableQueryInfo);
// return true;
// }
//
// // current window does not ended in current data block, try next data block
// getNextTimeWindow(pQueryAttr, &tw);
//
// /*
// * If the next time window still starts from current data block,
// * load the primary timestamp column first, and then find the start position for the next queried time window.
// * Note that only the primary timestamp column is required.
// * TODO: Optimize for this cases. All data blocks are not needed to be loaded, only if the first actually required
// * time window resides in current data block.
// */
// if ((tw.skey <= blockInfo.window.ekey && ascQuery) || (tw.ekey >= blockInfo.window.skey && !ascQuery)) {
//
2022-01-10 11:48:21 +00:00
// SArray *pDataBlock = tsdbRetrieveDataBlock(pRuntimeEnv->pTsdbReadHandle, NULL);
2021-11-02 05:37:31 +00:00
// SColumnInfoData *pColInfoData = taosArrayGet(pDataBlock, 0);
//
// if ((win.ekey > blockInfo.window.ekey && ascQuery) || (win.ekey < blockInfo.window.skey && !ascQuery)) {
// pQueryAttr->limit.offset -= 1;
// }
//
// if (pQueryAttr->limit.offset == 0) {
// *start = doSkipIntervalProcess(pRuntimeEnv, &win, &blockInfo, pTableQueryInfo);
// return true;
// } else {
// tw = win;
// int32_t startPos =
// getNextQualifiedWindow(pQueryAttr, &tw, &blockInfo, pColInfoData->pData, binarySearchForKey, -1);
// assert(startPos >= 0);
//
// // set the abort info
// pQueryAttr->pos = startPos;
// pTableQueryInfo->lastKey = ((TSKEY *)pColInfoData->pData)[startPos];
// pWindowResInfo->prevSKey = tw.skey;
// win = tw;
// }
// } else {
// break; // offset is not 0, and next time window begins or ends in the next block.
// }
// }
// }
//
// // check for error
// if (terrno != TSDB_CODE_SUCCESS) {
// longjmp(pRuntimeEnv->env, terrno);
// }
//
// return true;
//}
2022-01-14 02:20:55 +00:00
void appendDownstream ( SOperatorInfo * p , SOperatorInfo * pUpstream ) {
2022-01-08 08:28:44 +00:00
if ( p - > pDownstream = = NULL ) {
2022-01-08 14:59:24 +00:00
assert ( p - > numOfDownstream = = 0 ) ;
2021-11-02 05:37:31 +00:00
}
2022-01-08 14:59:24 +00:00
p - > pDownstream = realloc ( p - > pDownstream , POINTER_BYTES * ( p - > numOfDownstream + 1 ) ) ;
p - > pDownstream [ p - > numOfDownstream + + ] = pUpstream ;
2021-11-02 05:37:31 +00:00
}
static void doDestroyTableQueryInfo ( STableGroupInfo * pTableqinfoGroupInfo ) ;
2022-01-19 09:03:29 +00:00
void createResultBlock ( const SArray * pExprInfo , SExchangeInfo * pInfo , const SOperatorInfo * pOperator , size_t size ) ;
2022-01-08 08:28:44 +00:00
static int32_t setupQueryHandle ( void * tsdb , STaskRuntimeEnv * pRuntimeEnv , int64_t qId , bool isSTableQuery ) {
STaskAttr * pQueryAttr = pRuntimeEnv - > pQueryAttr ;
2021-11-02 05:37:31 +00:00
#if 0
// TODO set the tags scan handle
if ( onlyQueryTags ( pQueryAttr ) ) {
return TSDB_CODE_SUCCESS ;
}
STsdbQueryCond cond = createTsdbQueryCond ( pQueryAttr , & pQueryAttr - > window ) ;
if ( pQueryAttr - > tsCompQuery | | pQueryAttr - > pointInterpQuery ) {
cond . type = BLOCK_LOAD_TABLE_SEQ_ORDER ;
}
if ( ! isSTableQuery
& & ( pRuntimeEnv - > tableqinfoGroupInfo . numOfTables = = 1 )
& & ( cond . order = = TSDB_ORDER_ASC )
& & ( ! QUERY_IS_INTERVAL_QUERY ( pQueryAttr ) )
& & ( ! pQueryAttr - > groupbyColumn )
& & ( ! pQueryAttr - > simpleAgg )
) {
SArray * pa = GET_TABLEGROUP ( pRuntimeEnv , 0 ) ;
STableQueryInfo * pCheckInfo = taosArrayGetP ( pa , 0 ) ;
cond . twindow = pCheckInfo - > win ;
}
terrno = TSDB_CODE_SUCCESS ;
if ( isFirstLastRowQuery ( pQueryAttr ) ) {
2022-01-10 11:48:21 +00:00
pRuntimeEnv - > pTsdbReadHandle = tsdbQueryLastRow ( tsdb , & cond , & pQueryAttr - > tableGroupInfo , qId , & pQueryAttr - > memRef ) ;
2021-11-02 05:37:31 +00:00
// update the query time window
pQueryAttr - > window = cond . twindow ;
if ( pQueryAttr - > tableGroupInfo . numOfTables = = 0 ) {
pRuntimeEnv - > tableqinfoGroupInfo . numOfTables = 0 ;
} else {
size_t numOfGroups = GET_NUM_OF_TABLEGROUP ( pRuntimeEnv ) ;
for ( int32_t i = 0 ; i < numOfGroups ; + + i ) {
SArray * group = GET_TABLEGROUP ( pRuntimeEnv , i ) ;
size_t t = taosArrayGetSize ( group ) ;
for ( int32_t j = 0 ; j < t ; + + j ) {
STableQueryInfo * pCheckInfo = taosArrayGetP ( group , j ) ;
pCheckInfo - > win = pQueryAttr - > window ;
pCheckInfo - > lastKey = pCheckInfo - > win . skey ;
}
}
}
} else if ( isCachedLastQuery ( pQueryAttr ) ) {
2022-01-10 11:48:21 +00:00
pRuntimeEnv - > pTsdbReadHandle = tsdbQueryCacheLast ( tsdb , & cond , & pQueryAttr - > tableGroupInfo , qId , & pQueryAttr - > memRef ) ;
2021-11-02 05:37:31 +00:00
} else if ( pQueryAttr - > pointInterpQuery ) {
2022-01-10 11:48:21 +00:00
pRuntimeEnv - > pTsdbReadHandle = tsdbQueryRowsInExternalWindow ( tsdb , & cond , & pQueryAttr - > tableGroupInfo , qId , & pQueryAttr - > memRef ) ;
2021-11-02 05:37:31 +00:00
} else {
2022-01-10 11:48:21 +00:00
pRuntimeEnv - > pTsdbReadHandle = tsdbQueryTables ( tsdb , & cond , & pQueryAttr - > tableGroupInfo , qId , & pQueryAttr - > memRef ) ;
2021-11-02 05:37:31 +00:00
}
# endif
return terrno ;
}
int32_t doInitQInfo ( SQInfo * pQInfo , STSBuf * pTsBuf , void * tsdb , void * sourceOptr , int32_t tbScanner , SArray * pOperator ,
void * param ) {
2022-01-08 08:28:44 +00:00
STaskRuntimeEnv * pRuntimeEnv = & pQInfo - > runtimeEnv ;
2021-11-02 05:37:31 +00:00
2022-01-08 08:28:44 +00:00
STaskAttr * pQueryAttr = pQInfo - > runtimeEnv . pQueryAttr ;
2021-11-02 05:37:31 +00:00
pQueryAttr - > tsdb = tsdb ;
if ( tsdb ! = NULL ) {
int32_t code = setupQueryHandle ( tsdb , pRuntimeEnv , pQInfo - > qId , pQueryAttr - > stableQuery ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
return code ;
}
}
pQueryAttr - > interBufSize = getOutputInterResultBufSize ( pQueryAttr ) ;
pRuntimeEnv - > groupResInfo . totalGroup = ( int32_t ) ( pQueryAttr - > stableQuery ? GET_NUM_OF_TABLEGROUP ( pRuntimeEnv ) : 0 ) ;
pRuntimeEnv - > enableGroupData = false ;
pRuntimeEnv - > pQueryAttr = pQueryAttr ;
pRuntimeEnv - > pTsBuf = pTsBuf ;
pRuntimeEnv - > cur . vgroupIndex = - 1 ;
setResultBufSize ( pQueryAttr , & pRuntimeEnv - > resultInfo ) ;
if ( sourceOptr ! = NULL ) {
assert ( pRuntimeEnv - > proot = = NULL ) ;
pRuntimeEnv - > proot = sourceOptr ;
}
if ( pTsBuf ! = NULL ) {
int16_t order = ( pQueryAttr - > order . order = = pRuntimeEnv - > pTsBuf - > tsOrder ) ? TSDB_ORDER_ASC : TSDB_ORDER_DESC ;
tsBufSetTraverseOrder ( pRuntimeEnv - > pTsBuf , order ) ;
}
int32_t ps = DEFAULT_PAGE_SIZE ;
getIntermediateBufInfo ( pRuntimeEnv , & ps , & pQueryAttr - > intermediateResultRowSize ) ;
int32_t TENMB = 1024 * 1024 * 10 ;
2022-02-08 07:40:13 +00:00
int32_t code = createDiskbasedBuffer ( & pRuntimeEnv - > pResultBuf , ps , TENMB , pQInfo - > qId , tsTempDir ) ;
2021-11-02 05:37:31 +00:00
if ( code ! = TSDB_CODE_SUCCESS ) {
return code ;
}
// create runtime environment
int32_t numOfTables = ( int32_t ) pQueryAttr - > tableGroupInfo . numOfTables ;
pQInfo - > summary . tableInfoSize + = ( numOfTables * sizeof ( STableQueryInfo ) ) ;
pQInfo - > summary . queryProfEvents = taosArrayInit ( 512 , sizeof ( SQueryProfEvent ) ) ;
if ( pQInfo - > summary . queryProfEvents = = NULL ) {
//qDebug("QInfo:0x%"PRIx64" failed to allocate query prof events array", pQInfo->qId);
}
pQInfo - > summary . operatorProfResults =
taosHashInit ( 8 , taosGetDefaultHashFunction ( TSDB_DATA_TYPE_TINYINT ) , true , HASH_NO_LOCK ) ;
if ( pQInfo - > summary . operatorProfResults = = NULL ) {
//qDebug("QInfo:0x%"PRIx64" failed to allocate operator prof results hash", pQInfo->qId);
}
code = setupQueryRuntimeEnv ( pRuntimeEnv , ( int32_t ) pQueryAttr - > tableGroupInfo . numOfTables , pOperator , param ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
return code ;
}
2022-01-08 14:59:24 +00:00
// setTaskStatus(pOperator->pTaskInfo, QUERY_NOT_COMPLETED);
2021-11-02 05:37:31 +00:00
return TSDB_CODE_SUCCESS ;
}
2022-01-10 11:48:21 +00:00
static void doTableQueryInfoTimeWindowCheck ( SExecTaskInfo * pTaskInfo , STableQueryInfo * pTableQueryInfo , int32_t order ) {
2022-01-08 14:59:24 +00:00
if ( order = = TSDB_ORDER_ASC ) {
2021-11-02 05:37:31 +00:00
assert (
( pTableQueryInfo - > win . skey < = pTableQueryInfo - > win . ekey ) & &
2022-01-08 14:59:24 +00:00
( pTableQueryInfo - > lastKey > = pTaskInfo - > window . skey ) & &
( pTableQueryInfo - > win . skey > = pTaskInfo - > window . skey & & pTableQueryInfo - > win . ekey < = pTaskInfo - > window . ekey ) ) ;
2021-11-02 05:37:31 +00:00
} else {
assert (
( pTableQueryInfo - > win . skey > = pTableQueryInfo - > win . ekey ) & &
2022-01-08 14:59:24 +00:00
( pTableQueryInfo - > lastKey < = pTaskInfo - > window . skey ) & &
( pTableQueryInfo - > win . skey < = pTaskInfo - > window . skey & & pTableQueryInfo - > win . ekey > = pTaskInfo - > window . ekey ) ) ;
2021-11-02 05:37:31 +00:00
}
}
2022-01-08 08:28:44 +00:00
//STsdbQueryCond createTsdbQueryCond(STaskAttr* pQueryAttr, STimeWindow* win) {
2021-11-02 05:37:31 +00:00
// STsdbQueryCond cond = {
// .colList = pQueryAttr->tableCols,
// .order = pQueryAttr->order.order,
// .numOfCols = pQueryAttr->numOfCols,
// .type = BLOCK_LOAD_OFFSET_SEQ_ORDER,
// .loadExternalRows = false,
// };
//
// TIME_WINDOW_COPY(cond.twindow, *win);
// return cond;
//}
static STableIdInfo createTableIdInfo ( STableQueryInfo * pTableQueryInfo ) {
STableIdInfo tidInfo ;
// STableId* id = TSDB_TABLEID(pTableQueryInfo->pTable);
//
// tidInfo.uid = id->uid;
// tidInfo.tid = id->tid;
// tidInfo.key = pTableQueryInfo->lastKey;
return tidInfo ;
}
//static void updateTableIdInfo(STableQueryInfo* pTableQueryInfo, SSDataBlock* pBlock, SHashObj* pTableIdInfo, int32_t order) {
// int32_t step = GET_FORWARD_DIRECTION_FACTOR(order);
// pTableQueryInfo->lastKey = ((order == TSDB_ORDER_ASC)? pBlock->info.window.ekey:pBlock->info.window.skey) + step;
//
// if (pTableQueryInfo->pTable == NULL) {
// return;
// }
//
// STableIdInfo tidInfo = createTableIdInfo(pTableQueryInfo);
// STableIdInfo *idinfo = taosHashGet(pTableIdInfo, &tidInfo.tid, sizeof(tidInfo.tid));
// if (idinfo != NULL) {
// assert(idinfo->tid == tidInfo.tid && idinfo->uid == tidInfo.uid);
// idinfo->key = tidInfo.key;
// } else {
// taosHashPut(pTableIdInfo, &tidInfo.tid, sizeof(tidInfo.tid), &tidInfo, sizeof(STableIdInfo));
// }
//}
2022-01-08 08:28:44 +00:00
static void doCloseAllTimeWindow ( STaskRuntimeEnv * pRuntimeEnv ) {
2021-11-02 05:37:31 +00:00
size_t numOfGroup = GET_NUM_OF_TABLEGROUP ( pRuntimeEnv ) ;
for ( int32_t i = 0 ; i < numOfGroup ; + + i ) {
SArray * group = GET_TABLEGROUP ( pRuntimeEnv , i ) ;
size_t num = taosArrayGetSize ( group ) ;
for ( int32_t j = 0 ; j < num ; + + j ) {
STableQueryInfo * item = taosArrayGetP ( group , j ) ;
closeAllResultRows ( & item - > resInfo ) ;
}
}
}
static SSDataBlock * doTableScanImpl ( void * param , bool * newgroup ) {
SOperatorInfo * pOperator = ( SOperatorInfo * ) param ;
STableScanInfo * pTableScanInfo = pOperator - > info ;
2022-01-10 11:48:21 +00:00
SExecTaskInfo * pTaskInfo = pOperator - > pTaskInfo ;
2022-01-08 14:59:24 +00:00
2021-11-02 05:37:31 +00:00
SSDataBlock * pBlock = & pTableScanInfo - > block ;
2022-01-08 14:59:24 +00:00
STableGroupInfo * pTableGroupInfo = & pOperator - > pTaskInfo - > tableqinfoGroupInfo ;
2021-11-02 05:37:31 +00:00
* newgroup = false ;
2022-01-08 14:59:24 +00:00
2022-01-10 11:48:21 +00:00
while ( tsdbNextDataBlock ( pTableScanInfo - > pTsdbReadHandle ) ) {
if ( isTaskKilled ( pOperator - > pTaskInfo ) ) {
longjmp ( pOperator - > pTaskInfo - > env , TSDB_CODE_TSC_QUERY_CANCELLED ) ;
2021-11-02 05:37:31 +00:00
}
pTableScanInfo - > numOfBlocks + = 1 ;
2022-01-10 11:48:21 +00:00
tsdbRetrieveDataBlockInfo ( pTableScanInfo - > pTsdbReadHandle , & pBlock - > info ) ;
2021-11-02 05:37:31 +00:00
// todo opt
2022-01-08 14:59:24 +00:00
// if (pTableGroupInfo->numOfTables > 1 || (pRuntimeEnv->current == NULL && pTableGroupInfo->numOfTables == 1)) {
// STableQueryInfo** pTableQueryInfo =
// (STableQueryInfo**)taosHashGet(pTableGroupInfo->map, &pBlock->info.uid, sizeof(pBlock->info.uid));
// if (pTableQueryInfo == NULL) {
// break;
// }
//
// pRuntimeEnv->current = *pTableQueryInfo;
// doTableQueryInfoTimeWindowCheck(pTaskInfo, *pTableQueryInfo, pTableScanInfo->order);
// }
2021-11-02 05:37:31 +00:00
// this function never returns error?
uint32_t status ;
2022-01-08 14:59:24 +00:00
int32_t code = loadDataBlock ( pTaskInfo , pTableScanInfo , pBlock , & status ) ;
// int32_t code = loadDataBlockOnDemand(pOperator->pRuntimeEnv, pTableScanInfo, pBlock, &status);
2021-11-02 05:37:31 +00:00
if ( code ! = TSDB_CODE_SUCCESS ) {
2022-01-10 11:48:21 +00:00
longjmp ( pOperator - > pTaskInfo - > env , code ) ;
2021-11-02 05:37:31 +00:00
}
// current block is ignored according to filter result by block statistics data, continue load the next block
if ( status = = BLK_DATA_DISCARD | | pBlock - > info . rows = = 0 ) {
continue ;
}
return pBlock ;
}
return NULL ;
}
static SSDataBlock * doTableScan ( void * param , bool * newgroup ) {
SOperatorInfo * pOperator = ( SOperatorInfo * ) param ;
2022-01-08 14:59:24 +00:00
STableScanInfo * pTableScanInfo = pOperator - > info ;
2022-01-10 11:48:21 +00:00
SExecTaskInfo * pTaskInfo = pOperator - > pTaskInfo ;
2021-11-02 05:37:31 +00:00
2022-01-28 02:44:02 +00:00
// The read handle is not initialized yet, since no qualified tables exists
2022-01-22 14:51:48 +00:00
if ( pTableScanInfo - > pTsdbReadHandle = = NULL ) {
return NULL ;
}
2021-11-02 05:37:31 +00:00
SResultRowInfo * pResultRowInfo = pTableScanInfo - > pResultRowInfo ;
* newgroup = false ;
while ( pTableScanInfo - > current < pTableScanInfo - > times ) {
SSDataBlock * p = doTableScanImpl ( pOperator , newgroup ) ;
if ( p ! = NULL ) {
return p ;
}
if ( + + pTableScanInfo - > current > = pTableScanInfo - > times ) {
2022-01-10 11:48:21 +00:00
if ( pTableScanInfo - > reverseTimes < = 0 /* || isTsdbCacheLastRow(pTableScanInfo->pTsdbReadHandle)*/ ) {
2021-11-02 05:37:31 +00:00
return NULL ;
} else {
break ;
}
}
// do prepare for the next round table scan operation
// STsdbQueryCond cond = createTsdbQueryCond(pQueryAttr, &pQueryAttr->window);
2022-01-10 11:48:21 +00:00
// tsdbResetQueryHandle(pTableScanInfo->pTsdbReadHandle, &cond);
2021-11-02 05:37:31 +00:00
2022-01-10 11:48:21 +00:00
setTaskStatus ( pTaskInfo , TASK_NOT_COMPLETED ) ;
2022-01-08 14:59:24 +00:00
pTableScanInfo - > scanFlag = REPEAT_SCAN ;
2021-11-02 05:37:31 +00:00
2022-01-08 14:59:24 +00:00
// if (pTaskInfo->pTsBuf) {
// bool ret = tsBufNextPos(pRuntimeEnv->pTsBuf);
// assert(ret);
// }
//
2021-11-02 05:37:31 +00:00
if ( pResultRowInfo - > size > 0 ) {
pResultRowInfo - > curPos = 0 ;
}
2022-01-25 05:42:33 +00:00
qDebug ( " %s start to repeat scan data blocks due to query func required, qrange:% " PRId64 " -% " PRId64 ,
2022-01-10 11:48:21 +00:00
GET_TASKID ( pTaskInfo ) , pTaskInfo - > window . skey , pTaskInfo - > window . ekey ) ;
2021-11-02 05:37:31 +00:00
}
SSDataBlock * p = NULL ;
2022-01-08 14:59:24 +00:00
// todo refactor
2021-11-02 05:37:31 +00:00
if ( pTableScanInfo - > reverseTimes > 0 ) {
2022-01-08 14:59:24 +00:00
setupEnvForReverseScan ( pTableScanInfo , pTableScanInfo - > pCtx , pTableScanInfo - > numOfOutput ) ;
2021-11-02 05:37:31 +00:00
// STsdbQueryCond cond = createTsdbQueryCond(pQueryAttr, &pQueryAttr->window);
2022-01-10 11:48:21 +00:00
// tsdbResetQueryHandle(pTableScanInfo->pTsdbReadHandle, &cond);
2021-11-02 05:37:31 +00:00
2022-01-25 05:42:33 +00:00
qDebug ( " %s start to reverse scan data blocks due to query func required, qrange:% " PRId64 " -% " PRId64 ,
2022-01-10 11:48:21 +00:00
GET_TASKID ( pTaskInfo ) , pTaskInfo - > window . skey , pTaskInfo - > window . ekey ) ;
2021-11-02 05:37:31 +00:00
if ( pResultRowInfo - > size > 0 ) {
pResultRowInfo - > curPos = pResultRowInfo - > size - 1 ;
}
p = doTableScanImpl ( pOperator , newgroup ) ;
}
return p ;
}
static SSDataBlock * doBlockInfoScan ( void * param , bool * newgroup ) {
SOperatorInfo * pOperator = ( SOperatorInfo * ) param ;
if ( pOperator - > status = = OP_EXEC_DONE ) {
return NULL ;
}
STableScanInfo * pTableScanInfo = pOperator - > info ;
* newgroup = false ;
#if 0
STableBlockDist tableBlockDist = { 0 } ;
tableBlockDist . numOfTables = ( int32_t ) pOperator - > pRuntimeEnv - > tableqinfoGroupInfo . numOfTables ;
2021-12-15 09:49:55 +00:00
int32_t numRowSteps = TSDB_DEFAULT_MAX_ROW_FBLOCK / TSDB_BLOCK_DIST_STEP_ROWS ;
if ( TSDB_DEFAULT_MAX_ROW_FBLOCK % TSDB_BLOCK_DIST_STEP_ROWS ! = 0 ) {
2021-11-02 05:37:31 +00:00
+ + numRowSteps ;
}
tableBlockDist . dataBlockInfos = taosArrayInit ( numRowSteps , sizeof ( SFileBlockInfo ) ) ;
taosArraySetSize ( tableBlockDist . dataBlockInfos , numRowSteps ) ;
tableBlockDist . maxRows = INT_MIN ;
tableBlockDist . minRows = INT_MAX ;
2022-01-10 11:48:21 +00:00
tsdbGetFileBlocksDistInfo ( pTableScanInfo - > pTsdbReadHandle , & tableBlockDist ) ;
tableBlockDist . numOfRowsInMemTable = ( int32_t ) tsdbGetNumOfRowsInMemTable ( pTableScanInfo - > pTsdbReadHandle ) ;
2021-11-02 05:37:31 +00:00
SSDataBlock * pBlock = & pTableScanInfo - > block ;
pBlock - > info . rows = 1 ;
pBlock - > info . numOfCols = 1 ;
SBufferWriter bw = tbufInitWriter ( NULL , false ) ;
blockDistInfoToBinary ( & tableBlockDist , & bw ) ;
SColumnInfoData * pColInfo = taosArrayGet ( pBlock - > pDataBlock , 0 ) ;
int32_t len = ( int32_t ) tbufTell ( & bw ) ;
pColInfo - > pData = malloc ( len + sizeof ( int32_t ) ) ;
* ( int32_t * ) pColInfo - > pData = len ;
memcpy ( pColInfo - > pData + sizeof ( int32_t ) , tbufGetData ( & bw , false ) , len ) ;
tbufCloseWriter ( & bw ) ;
SArray * g = GET_TABLEGROUP ( pOperator - > pRuntimeEnv , 0 ) ;
pOperator - > pRuntimeEnv - > current = taosArrayGetP ( g , 0 ) ;
pOperator - > status = OP_EXEC_DONE ;
return pBlock ;
# endif
2022-01-16 07:56:48 +00:00
}
2022-01-20 14:57:29 +00:00
static SSDataBlock * doStreamBlockScan ( void * param , bool * newgroup ) {
SOperatorInfo * pOperator = ( SOperatorInfo * ) param ;
// NOTE: this operator never check if current status is done or not
SExecTaskInfo * pTaskInfo = pOperator - > pTaskInfo ;
SStreamBlockScanInfo * pInfo = pOperator - > info ;
SDataBlockInfo * pBlockInfo = & pInfo - > pRes - > info ;
2022-02-04 14:41:54 +00:00
pBlockInfo - > rows = 0 ;
2022-01-20 14:57:29 +00:00
while ( tqNextDataBlock ( pInfo - > readerHandle ) ) {
pTaskInfo - > code = tqRetrieveDataBlockInfo ( pInfo - > readerHandle , pBlockInfo ) ;
if ( pTaskInfo - > code ! = TSDB_CODE_SUCCESS ) {
terrno = pTaskInfo - > code ;
return NULL ;
}
if ( pBlockInfo - > rows = = 0 ) {
return NULL ;
}
pInfo - > pRes - > pDataBlock = tqRetrieveDataBlock ( pInfo - > readerHandle ) ;
if ( pInfo - > pRes - > pDataBlock = = NULL ) {
// TODO add log
pTaskInfo - > code = terrno ;
return NULL ;
}
break ;
}
// record the scan action.
pInfo - > numOfExec + + ;
pInfo - > numOfRows + = pBlockInfo - > rows ;
return ( pBlockInfo - > rows = = 0 ) ? NULL : pInfo - > pRes ;
}
2022-01-16 07:56:48 +00:00
int32_t loadRemoteDataCallback ( void * param , const SDataBuf * pMsg , int32_t code ) {
2022-02-11 06:33:57 +00:00
SSourceDataInfo * pSourceDataInfo = ( SSourceDataInfo * ) param ;
pSourceDataInfo - > pRsp = pMsg - > pData ;
2022-01-16 07:56:48 +00:00
2022-02-11 06:33:57 +00:00
SRetrieveTableRsp * pRsp = pSourceDataInfo - > pRsp ;
pRsp - > numOfRows = htonl ( pRsp - > numOfRows ) ;
pRsp - > useconds = htobe64 ( pRsp - > useconds ) ;
pRsp - > compLen = htonl ( pRsp - > compLen ) ;
2022-01-19 06:47:53 +00:00
2022-02-11 06:33:57 +00:00
pSourceDataInfo - > status = DATA_READY ;
tsem_post ( & pSourceDataInfo - > pEx - > ready ) ;
2022-01-19 06:47:53 +00:00
}
static void destroySendMsgInfo ( SMsgSendInfo * pMsgBody ) {
assert ( pMsgBody ! = NULL ) ;
tfree ( pMsgBody - > msgInfo . pData ) ;
tfree ( pMsgBody ) ;
}
2022-01-26 01:20:48 +00:00
void qProcessFetchRsp ( void * parent , SRpcMsg * pMsg , SEpSet * pEpSet ) {
2022-01-19 06:47:53 +00:00
SMsgSendInfo * pSendInfo = ( SMsgSendInfo * ) pMsg - > ahandle ;
assert ( pMsg - > ahandle ! = NULL ) ;
SDataBuf buf = { . len = pMsg - > contLen , . pData = NULL } ;
if ( pMsg - > contLen > 0 ) {
buf . pData = calloc ( 1 , pMsg - > contLen ) ;
if ( buf . pData = = NULL ) {
terrno = TSDB_CODE_OUT_OF_MEMORY ;
pMsg - > code = TSDB_CODE_OUT_OF_MEMORY ;
} else {
memcpy ( buf . pData , pMsg - > pCont , pMsg - > contLen ) ;
}
}
pSendInfo - > fp ( pSendInfo - > param , & buf , pMsg - > code ) ;
rpcFreeCont ( pMsg - > pCont ) ;
destroySendMsgInfo ( pSendInfo ) ;
2022-01-16 07:56:48 +00:00
}
2022-02-11 06:33:57 +00:00
static int32_t doSendFetchDataRequest ( SExchangeInfo * pExchangeInfo , SExecTaskInfo * pTaskInfo , int32_t sourceIndex ) {
size_t totalSources = taosArrayGetSize ( pExchangeInfo - > pSources ) ;
2022-01-16 07:56:48 +00:00
2022-02-11 06:33:57 +00:00
SResFetchReq * pMsg = calloc ( 1 , sizeof ( SResFetchReq ) ) ;
if ( NULL = = pMsg ) {
pTaskInfo - > code = TSDB_CODE_QRY_OUT_OF_MEMORY ;
return pTaskInfo - > code ;
}
2022-01-16 07:56:48 +00:00
2022-02-11 06:33:57 +00:00
SDownstreamSource * pSource = taosArrayGet ( pExchangeInfo - > pSources , sourceIndex ) ;
SSourceDataInfo * pDataInfo = taosArrayGet ( pExchangeInfo - > pSourceDataInfo , sourceIndex ) ;
2022-01-22 07:42:37 +00:00
2022-02-11 06:33:57 +00:00
qDebug ( " %s build fetch msg and send to vgId:%d, ep:%s, taskId:0x% " PRIx64 " , %d/% " PRIzu ,
GET_TASKID ( pTaskInfo ) , pSource - > addr . nodeId , pSource - > addr . epset . eps [ 0 ] . fqdn , pSource - > taskId , sourceIndex , totalSources ) ;
pMsg - > header . vgId = htonl ( pSource - > addr . nodeId ) ;
pMsg - > sId = htobe64 ( pSource - > schedId ) ;
pMsg - > taskId = htobe64 ( pSource - > taskId ) ;
pMsg - > queryId = htobe64 ( pTaskInfo - > id . queryId ) ;
// send the fetch remote task result reques
SMsgSendInfo * pMsgSendInfo = calloc ( 1 , sizeof ( SMsgSendInfo ) ) ;
if ( NULL = = pMsgSendInfo ) {
tfree ( pMsg ) ;
qError ( " %s prepare message %d failed " , GET_TASKID ( pTaskInfo ) , ( int32_t ) sizeof ( SMsgSendInfo ) ) ;
pTaskInfo - > code = TSDB_CODE_QRY_OUT_OF_MEMORY ;
return pTaskInfo - > code ;
2022-01-19 06:47:53 +00:00
}
2022-02-11 06:33:57 +00:00
pMsgSendInfo - > param = pDataInfo ;
pMsgSendInfo - > msgInfo . pData = pMsg ;
pMsgSendInfo - > msgInfo . len = sizeof ( SResFetchReq ) ;
pMsgSendInfo - > msgType = TDMT_VND_FETCH ;
pMsgSendInfo - > fp = loadRemoteDataCallback ;
2022-01-16 07:56:48 +00:00
2022-02-11 06:33:57 +00:00
int64_t transporterId = 0 ;
int32_t code = asyncSendMsgToServer ( pExchangeInfo - > pTransporter , & pSource - > addr . epset , & transporterId , pMsgSendInfo ) ;
return TSDB_CODE_SUCCESS ;
}
static int32_t setSDataBlockFromFetchRsp ( SSDataBlock * pRes , SExchangeInfo * pExchangeInfo , SSourceDataInfo * pDataInfo , int32_t numOfOutput , int64_t startTs ) {
char * pData = pDataInfo - > pRsp - > data ;
SRetrieveTableRsp * pRsp = pDataInfo - > pRsp ;
for ( int32_t i = 0 ; i < numOfOutput ; + + i ) {
SColumnInfoData * pColInfoData = taosArrayGet ( pRes - > pDataBlock , i ) ;
char * tmp = realloc ( pColInfoData - > pData , pColInfoData - > info . bytes * pRsp - > numOfRows ) ;
if ( tmp = = NULL ) {
return TSDB_CODE_QRY_OUT_OF_MEMORY ;
2022-01-22 07:42:37 +00:00
}
2022-01-16 07:56:48 +00:00
2022-02-11 06:33:57 +00:00
size_t len = pRsp - > numOfRows * pColInfoData - > info . bytes ;
memcpy ( tmp , pData , len ) ;
2022-01-16 07:56:48 +00:00
2022-02-11 06:33:57 +00:00
pColInfoData - > pData = tmp ;
pData + = len ;
}
2022-01-22 07:42:37 +00:00
2022-02-11 06:33:57 +00:00
pRes - > info . rows = pRsp - > numOfRows ;
2022-01-16 07:56:48 +00:00
2022-02-11 06:33:57 +00:00
int64_t el = taosGetTimestampUs ( ) - startTs ;
2022-01-16 07:56:48 +00:00
2022-02-11 06:33:57 +00:00
pExchangeInfo - > totalRows + = pRsp - > numOfRows ;
pExchangeInfo - > totalSize + = pRsp - > compLen ;
pDataInfo - > totalRows + = pRsp - > numOfRows ;
2022-01-16 07:56:48 +00:00
2022-02-11 06:33:57 +00:00
pExchangeInfo - > totalElapsed + = el ;
2021-11-02 05:37:31 +00:00
2022-02-11 06:33:57 +00:00
return TSDB_CODE_SUCCESS ;
}
2022-01-22 07:42:37 +00:00
2022-02-11 06:33:57 +00:00
static void * setAllSourcesCompleted ( SOperatorInfo * pOperator , int64_t startTs ) {
SExchangeInfo * pExchangeInfo = pOperator - > info ;
SExecTaskInfo * pTaskInfo = pOperator - > pTaskInfo ;
2022-01-22 14:51:48 +00:00
2022-02-11 06:33:57 +00:00
int64_t el = taosGetTimestampUs ( ) - startTs ;
pExchangeInfo - > totalElapsed + = el ;
2022-01-25 06:13:11 +00:00
2022-02-11 06:33:57 +00:00
size_t totalSources = taosArrayGetSize ( pExchangeInfo - > pSources ) ;
qDebug ( " %s all % " PRIzu " sources are exhausted, total rows: % " PRIu64 " bytes:% " PRIu64 " , elapsed:%.2f ms " , GET_TASKID ( pTaskInfo ) , totalSources ,
pExchangeInfo - > totalRows , pExchangeInfo - > totalSize , pExchangeInfo - > totalElapsed / 1000.0 ) ;
doSetOperatorCompleted ( pOperator ) ;
return NULL ;
}
static SSDataBlock * concurrentlyLoadRemoteDataImpl ( SOperatorInfo * pOperator , SExchangeInfo * pExchangeInfo , SExecTaskInfo * pTaskInfo ) {
int32_t code = 0 ;
int64_t startTs = taosGetTimestampUs ( ) ;
size_t totalSources = taosArrayGetSize ( pExchangeInfo - > pSources ) ;
while ( 1 ) {
int32_t completed = 0 ;
for ( int32_t i = 0 ; i < totalSources ; + + i ) {
SSourceDataInfo * pDataInfo = taosArrayGet ( pExchangeInfo - > pSourceDataInfo , i ) ;
if ( pDataInfo - > status = = DATA_EXHAUSTED ) {
completed + = 1 ;
2022-01-22 14:51:48 +00:00
continue ;
}
2021-11-02 05:37:31 +00:00
2022-02-11 06:33:57 +00:00
if ( pDataInfo - > status ! = DATA_READY ) {
continue ;
}
SRetrieveTableRsp * pRsp = pDataInfo - > pRsp ;
SDownstreamSource * pSource = taosArrayGet ( pExchangeInfo - > pSources , i ) ;
SSDataBlock * pRes = pExchangeInfo - > pResult ;
if ( pRsp - > numOfRows = = 0 ) {
qDebug ( " %s vgId:%d, taskID:0x% " PRIx64 " index:%d completed, rowsOfSource:% " PRIu64 " , totalRows:% " PRIu64 " try next " ,
GET_TASKID ( pTaskInfo ) , pSource - > addr . nodeId , pSource - > taskId , i + 1 , pDataInfo - > totalRows ,
pExchangeInfo - > totalRows ) ;
pDataInfo - > status = DATA_EXHAUSTED ;
completed + = 1 ;
continue ;
}
2022-01-19 08:20:13 +00:00
2022-02-11 06:33:57 +00:00
code = setSDataBlockFromFetchRsp ( pExchangeInfo - > pResult , pExchangeInfo , pDataInfo , pOperator - > numOfOutput , startTs ) ;
if ( code ! = 0 ) {
2022-01-22 07:42:37 +00:00
goto _error ;
}
2022-02-11 06:33:57 +00:00
if ( pRsp - > completed = = 1 ) {
qDebug ( " %s fetch msg rsp from vgId:%d, taskId:0x% " PRIx64 " numOfRows:%d, rowsOfSource:% " PRIu64
" , totalRows:% " PRIu64 " , totalBytes:% " PRIu64 " try next %d/% " PRIzu ,
GET_TASKID ( pTaskInfo ) , pSource - > addr . nodeId , pSource - > taskId , pRes - > info . rows ,
pDataInfo - > totalRows , pExchangeInfo - > totalRows , pExchangeInfo - > totalSize , i + 1 ,
totalSources ) ;
pDataInfo - > status = DATA_EXHAUSTED ;
} else {
qDebug ( " %s fetch msg rsp from vgId:%d, taskId:0x% " PRIx64 " numOfRows:%d, totalRows:% " PRIu64 " , totalBytes:% " PRIu64 ,
GET_TASKID ( pTaskInfo ) , pSource - > addr . nodeId , pSource - > taskId , pRes - > info . rows , pExchangeInfo - > totalRows ,
pExchangeInfo - > totalSize ) ;
}
if ( pDataInfo - > status ! = DATA_EXHAUSTED ) {
pDataInfo - > status = DATA_NOT_READY ;
code = doSendFetchDataRequest ( pExchangeInfo , pTaskInfo , i ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
goto _error ;
}
}
return pExchangeInfo - > pResult ;
}
if ( completed = = totalSources ) {
return setAllSourcesCompleted ( pOperator , startTs ) ;
}
}
_error :
pTaskInfo - > code = code ;
return NULL ;
}
static SSDataBlock * concurrentlyLoadRemoteData ( SOperatorInfo * pOperator ) {
SExchangeInfo * pExchangeInfo = pOperator - > info ;
SExecTaskInfo * pTaskInfo = pOperator - > pTaskInfo ;
if ( pOperator - > status = = OP_RES_TO_RETURN ) {
return concurrentlyLoadRemoteDataImpl ( pOperator , pExchangeInfo , pTaskInfo ) ;
}
size_t totalSources = taosArrayGetSize ( pExchangeInfo - > pSources ) ;
int64_t startTs = taosGetTimestampUs ( ) ;
// Asynchronously send all fetch requests to all sources.
for ( int32_t i = 0 ; i < totalSources ; + + i ) {
int32_t code = doSendFetchDataRequest ( pExchangeInfo , pTaskInfo , i ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
return NULL ;
}
}
int64_t endTs = taosGetTimestampUs ( ) ;
qDebug ( " %s send all fetch request to % " PRIzu " sources completed, elapsed:% " PRId64 , GET_TASKID ( pTaskInfo ) , totalSources , endTs - startTs ) ;
tsem_wait ( & pExchangeInfo - > ready ) ;
pOperator - > status = OP_RES_TO_RETURN ;
return concurrentlyLoadRemoteDataImpl ( pOperator , pExchangeInfo , pTaskInfo ) ;
}
static SSDataBlock * seqLoadRemoteData ( SOperatorInfo * pOperator ) {
SExchangeInfo * pExchangeInfo = pOperator - > info ;
SExecTaskInfo * pTaskInfo = pOperator - > pTaskInfo ;
size_t totalSources = taosArrayGetSize ( pExchangeInfo - > pSources ) ;
int64_t startTs = taosGetTimestampUs ( ) ;
2022-01-22 07:42:37 +00:00
2022-02-11 06:33:57 +00:00
while ( 1 ) {
if ( pExchangeInfo - > current > = totalSources ) {
return setAllSourcesCompleted ( pOperator , startTs ) ;
2022-01-22 07:42:37 +00:00
}
2022-01-16 07:56:48 +00:00
2022-02-11 06:33:57 +00:00
doSendFetchDataRequest ( pExchangeInfo , pTaskInfo , pExchangeInfo - > current ) ;
tsem_wait ( & pExchangeInfo - > ready ) ;
SSourceDataInfo * pDataInfo = taosArrayGet ( pExchangeInfo - > pSourceDataInfo , pExchangeInfo - > current ) ;
SDownstreamSource * pSource = taosArrayGet ( pExchangeInfo - > pSources , pExchangeInfo - > current ) ;
SRetrieveTableRsp * pRsp = pDataInfo - > pRsp ;
if ( pRsp - > numOfRows = = 0 ) {
qDebug ( " %s vgId:%d, taskID:0x% " PRIx64 " %d of total completed, rowsOfSource:% " PRIu64 " , totalRows:% " PRIu64 " try next " ,
GET_TASKID ( pTaskInfo ) , pSource - > addr . nodeId , pSource - > taskId , pExchangeInfo - > current + 1 ,
pDataInfo - > totalRows , pExchangeInfo - > totalRows ) ;
2022-01-19 08:20:13 +00:00
2022-02-11 06:33:57 +00:00
pDataInfo - > status = DATA_EXHAUSTED ;
pExchangeInfo - > current + = 1 ;
continue ;
}
2022-01-25 06:13:11 +00:00
2022-02-11 06:33:57 +00:00
SSDataBlock * pRes = pExchangeInfo - > pResult ;
setSDataBlockFromFetchRsp ( pExchangeInfo - > pResult , pExchangeInfo , pDataInfo , pOperator - > numOfOutput , startTs ) ;
2022-01-22 07:42:37 +00:00
if ( pRsp - > completed = = 1 ) {
2022-01-25 05:42:33 +00:00
qDebug ( " %s fetch msg rsp from vgId:%d, taskId:0x% " PRIx64 " numOfRows:%d, rowsOfSource:% " PRIu64
2022-02-11 06:33:57 +00:00
" , totalRows:% " PRIu64 " , totalBytes:% " PRIu64 " try next %d/% " PRIzu ,
GET_TASKID ( pTaskInfo ) , pSource - > addr . nodeId , pSource - > taskId , pRes - > info . rows ,
pDataInfo - > totalRows , pExchangeInfo - > totalRows , pExchangeInfo - > totalSize , pExchangeInfo - > current + 1 ,
totalSources ) ;
2022-01-22 07:42:37 +00:00
2022-02-11 06:33:57 +00:00
pDataInfo - > status = DATA_EXHAUSTED ;
2022-01-22 07:42:37 +00:00
pExchangeInfo - > current + = 1 ;
} else {
2022-01-25 05:42:33 +00:00
qDebug ( " %s fetch msg rsp from vgId:%d, taskId:0x% " PRIx64 " numOfRows:%d, totalRows:% " PRIu64 " , totalBytes:% " PRIu64 ,
2022-01-25 06:13:11 +00:00
GET_TASKID ( pTaskInfo ) , pSource - > addr . nodeId , pSource - > taskId , pRes - > info . rows , pExchangeInfo - > totalRows , pExchangeInfo - > totalSize ) ;
2022-01-22 07:42:37 +00:00
}
return pExchangeInfo - > pResult ;
}
2022-02-11 06:33:57 +00:00
}
static SSDataBlock * doLoadRemoteData ( void * param , bool * newgroup ) {
SOperatorInfo * pOperator = ( SOperatorInfo * ) param ;
SExchangeInfo * pExchangeInfo = pOperator - > info ;
SExecTaskInfo * pTaskInfo = pOperator - > pTaskInfo ;
size_t totalSources = taosArrayGetSize ( pExchangeInfo - > pSources ) ;
if ( pOperator - > status = = OP_EXEC_DONE ) {
qDebug ( " %s all % " PRIzu " source(s) are exhausted, total rows:% " PRIu64 " bytes:% " PRIu64 " , elapsed:%.2f ms " , GET_TASKID ( pTaskInfo ) , totalSources ,
pExchangeInfo - > totalRows , pExchangeInfo - > totalSize , pExchangeInfo - > totalElapsed / 1000.0 ) ;
return NULL ;
}
* newgroup = false ;
if ( pExchangeInfo - > seqLoadData ) {
return seqLoadRemoteData ( pOperator ) ;
} else {
return concurrentlyLoadRemoteData ( pOperator ) ;
}
2022-01-19 09:03:29 +00:00
2022-02-11 06:33:57 +00:00
#if 0
2022-01-19 09:03:29 +00:00
_error :
tfree ( pMsg ) ;
tfree ( pMsgSendInfo ) ;
terrno = pTaskInfo - > code ;
return NULL ;
2022-02-11 06:33:57 +00:00
# endif
2022-01-19 06:47:53 +00:00
}
2022-01-16 07:56:48 +00:00
2022-01-19 09:03:29 +00:00
static SSDataBlock * createResultDataBlock ( const SArray * pExprInfo ) ;
2022-01-19 06:47:53 +00:00
SOperatorInfo * createExchangeOperatorInfo ( const SArray * pSources , const SArray * pExprInfo , SExecTaskInfo * pTaskInfo ) {
2022-01-16 07:56:48 +00:00
SExchangeInfo * pInfo = calloc ( 1 , sizeof ( SExchangeInfo ) ) ;
SOperatorInfo * pOperator = calloc ( 1 , sizeof ( SOperatorInfo ) ) ;
if ( pInfo = = NULL | | pOperator = = NULL ) {
tfree ( pInfo ) ;
tfree ( pOperator ) ;
terrno = TSDB_CODE_QRY_OUT_OF_MEMORY ;
return NULL ;
}
2022-02-11 06:33:57 +00:00
size_t numOfSources = taosArrayGetSize ( pSources ) ;
2022-01-19 06:47:53 +00:00
pInfo - > pSources = taosArrayDup ( pSources ) ;
2022-02-11 06:33:57 +00:00
pInfo - > pSourceDataInfo = taosArrayInit ( numOfSources , sizeof ( SSourceDataInfo ) ) ;
if ( pInfo - > pSourceDataInfo = = NULL | | pInfo - > pSources = = NULL ) {
tfree ( pInfo ) ;
tfree ( pOperator ) ;
taosArrayDestroy ( pInfo - > pSources ) ;
taosArrayDestroy ( pInfo - > pSourceDataInfo ) ;
terrno = TSDB_CODE_QRY_OUT_OF_MEMORY ;
return NULL ;
}
for ( int32_t i = 0 ; i < numOfSources ; + + i ) {
SSourceDataInfo dataInfo = { 0 } ;
dataInfo . status = DATA_NOT_READY ;
dataInfo . pEx = pInfo ;
dataInfo . index = i ;
taosArrayPush ( pInfo - > pSourceDataInfo , & dataInfo ) ;
}
2022-01-19 06:47:53 +00:00
size_t size = taosArrayGetSize ( pExprInfo ) ;
2022-01-19 09:03:29 +00:00
pInfo - > pResult = createResultDataBlock ( pExprInfo ) ;
2022-02-11 06:33:57 +00:00
pInfo - > seqLoadData = true ;
tsem_init ( & pInfo - > ready , 0 , 0 ) ;
2022-01-16 07:56:48 +00:00
pOperator - > name = " ExchangeOperator " ;
pOperator - > operatorType = OP_Exchange ;
pOperator - > blockingOptr = false ;
pOperator - > status = OP_IN_EXECUTING ;
pOperator - > info = pInfo ;
2022-01-19 06:47:53 +00:00
pOperator - > numOfOutput = size ;
2022-01-16 07:56:48 +00:00
pOperator - > pRuntimeEnv = NULL ;
pOperator - > exec = doLoadRemoteData ;
pOperator - > pTaskInfo = pTaskInfo ;
2022-01-26 01:20:48 +00:00
# if 1
2022-01-19 09:03:29 +00:00
{ // todo refactor
2022-01-19 06:47:53 +00:00
SRpcInit rpcInit ;
memset ( & rpcInit , 0 , sizeof ( rpcInit ) ) ;
rpcInit . localPort = 0 ;
2022-01-25 06:13:11 +00:00
rpcInit . label = " EX " ;
2022-01-19 06:47:53 +00:00
rpcInit . numOfThreads = 1 ;
2022-01-26 01:20:48 +00:00
rpcInit . cfp = qProcessFetchRsp ;
2022-01-19 06:47:53 +00:00
rpcInit . sessions = tsMaxConnections ;
rpcInit . connType = TAOS_CONN_CLIENT ;
rpcInit . user = ( char * ) " root " ;
rpcInit . idleTime = tsShellActivityTimer * 1000 ;
rpcInit . ckey = " key " ;
2022-01-23 11:50:18 +00:00
rpcInit . spi = 1 ;
2022-01-19 06:47:53 +00:00
rpcInit . secret = ( char * ) " dcc5bed04851fec854c035b2e40263b6 " ;
pInfo - > pTransporter = rpcOpen ( & rpcInit ) ;
if ( pInfo - > pTransporter = = NULL ) {
return NULL ; // todo
}
}
2022-01-25 07:18:56 +00:00
# endif
2022-02-11 06:33:57 +00:00
2022-01-16 07:56:48 +00:00
return pOperator ;
}
2022-01-19 09:03:29 +00:00
SSDataBlock * createResultDataBlock ( const SArray * pExprInfo ) {
SSDataBlock * pResBlock = calloc ( 1 , sizeof ( SSDataBlock ) ) ;
if ( pResBlock = = NULL ) {
return NULL ;
}
size_t numOfCols = taosArrayGetSize ( pExprInfo ) ;
pResBlock - > pDataBlock = taosArrayInit ( numOfCols , sizeof ( SColumnInfoData ) ) ;
SArray * pResult = pResBlock - > pDataBlock ;
for ( int32_t i = 0 ; i < numOfCols ; + + i ) {
SColumnInfoData colInfoData = { 0 } ;
SExprInfo * p = taosArrayGetP ( pExprInfo , i ) ;
SSchema * pSchema = & p - > base . resSchema ;
colInfoData . info . type = pSchema - > type ;
colInfoData . info . colId = pSchema - > colId ;
colInfoData . info . bytes = pSchema - > bytes ;
taosArrayPush ( pResult , & colInfoData ) ;
}
return pResBlock ;
}
2022-01-14 02:20:55 +00:00
SOperatorInfo * createDataBlocksOptScanInfo ( void * pTsdbReadHandle , int32_t order , int32_t numOfOutput , int32_t repeatTime , int32_t reverseTime , SExecTaskInfo * pTaskInfo ) {
2022-01-13 11:01:28 +00:00
assert ( repeatTime > 0 ) ;
STableScanInfo * pInfo = calloc ( 1 , sizeof ( STableScanInfo ) ) ;
SOperatorInfo * pOperator = calloc ( 1 , sizeof ( SOperatorInfo ) ) ;
if ( pInfo = = NULL | | pOperator = = NULL ) {
tfree ( pInfo ) ;
tfree ( pOperator ) ;
terrno = TSDB_CODE_QRY_OUT_OF_MEMORY ;
return NULL ;
}
2022-01-14 02:20:55 +00:00
pInfo - > pTsdbReadHandle = pTsdbReadHandle ;
2022-01-13 11:01:28 +00:00
pInfo - > times = repeatTime ;
pInfo - > reverseTimes = reverseTime ;
pInfo - > order = order ;
pInfo - > current = 0 ;
pInfo - > scanFlag = MAIN_SCAN ;
pOperator - > name = " DataBlocksOptimizedScanOperator " ;
pOperator - > operatorType = OP_DataBlocksOptScan ;
pOperator - > blockingOptr = false ;
pOperator - > status = OP_IN_EXECUTING ;
pOperator - > info = pInfo ;
pOperator - > numOfOutput = numOfOutput ;
pOperator - > exec = doTableScan ;
pOperator - > pTaskInfo = pTaskInfo ;
return pOperator ;
}
2022-01-14 02:20:55 +00:00
SOperatorInfo * createTableSeqScanOperator ( void * pTsdbReadHandle , STaskRuntimeEnv * pRuntimeEnv ) {
2021-11-02 05:37:31 +00:00
STableScanInfo * pInfo = calloc ( 1 , sizeof ( STableScanInfo ) ) ;
2022-01-14 02:20:55 +00:00
pInfo - > pTsdbReadHandle = pTsdbReadHandle ;
2021-11-02 05:37:31 +00:00
pInfo - > times = 1 ;
pInfo - > reverseTimes = 0 ;
pInfo - > order = pRuntimeEnv - > pQueryAttr - > order . order ;
pInfo - > current = 0 ;
pInfo - > prevGroupId = - 1 ;
pRuntimeEnv - > enableGroupData = true ;
SOperatorInfo * pOperator = calloc ( 1 , sizeof ( SOperatorInfo ) ) ;
pOperator - > name = " TableSeqScanOperator " ;
2022-01-16 07:56:48 +00:00
pOperator - > operatorType = OP_TableSeqScan ;
2021-11-02 05:37:31 +00:00
pOperator - > blockingOptr = false ;
pOperator - > status = OP_IN_EXECUTING ;
pOperator - > info = pInfo ;
pOperator - > numOfOutput = pRuntimeEnv - > pQueryAttr - > numOfCols ;
pOperator - > pRuntimeEnv = pRuntimeEnv ;
pOperator - > exec = doTableScanImpl ;
return pOperator ;
}
2022-01-14 02:20:55 +00:00
SOperatorInfo * createTableBlockInfoScanOperator ( void * pTsdbReadHandle , STaskRuntimeEnv * pRuntimeEnv ) {
2021-11-02 05:37:31 +00:00
STableScanInfo * pInfo = calloc ( 1 , sizeof ( STableScanInfo ) ) ;
2022-01-14 02:20:55 +00:00
pInfo - > pTsdbReadHandle = pTsdbReadHandle ;
2021-11-02 05:37:31 +00:00
pInfo - > block . pDataBlock = taosArrayInit ( 1 , sizeof ( SColumnInfoData ) ) ;
SColumnInfoData infoData = { { 0 } } ;
infoData . info . type = TSDB_DATA_TYPE_BINARY ;
infoData . info . bytes = 1024 ;
infoData . info . colId = 0 ;
taosArrayPush ( pInfo - > block . pDataBlock , & infoData ) ;
SOperatorInfo * pOperator = calloc ( 1 , sizeof ( SOperatorInfo ) ) ;
pOperator - > name = " TableBlockInfoScanOperator " ;
2021-12-06 06:44:27 +00:00
// pOperator->operatorType = OP_TableBlockInfoScan;
2021-11-02 05:37:31 +00:00
pOperator - > blockingOptr = false ;
pOperator - > status = OP_IN_EXECUTING ;
pOperator - > info = pInfo ;
2022-01-28 02:44:02 +00:00
// pOperator->numOfOutput = pRuntimeEnv->pQueryAttr->numOfCols;
2021-11-02 05:37:31 +00:00
pOperator - > exec = doBlockInfoScan ;
return pOperator ;
}
2022-01-27 10:27:26 +00:00
SOperatorInfo * createStreamScanOperatorInfo ( void * streamReadHandle , SArray * pExprInfo , SArray * pTableIdList , SExecTaskInfo * pTaskInfo ) {
2022-01-20 14:57:29 +00:00
SStreamBlockScanInfo * pInfo = calloc ( 1 , sizeof ( SStreamBlockScanInfo ) ) ;
SOperatorInfo * pOperator = calloc ( 1 , sizeof ( SOperatorInfo ) ) ;
if ( pInfo = = NULL | | pOperator = = NULL ) {
tfree ( pInfo ) ;
tfree ( pOperator ) ;
terrno = TSDB_CODE_QRY_OUT_OF_MEMORY ;
return NULL ;
}
2022-01-26 02:16:59 +00:00
// todo dynamic set the value of 4096
pInfo - > pRes = createOutputBuf_rv ( pExprInfo , 4096 ) ;
2022-01-21 07:16:17 +00:00
int32_t numOfOutput = ( int32_t ) taosArrayGetSize ( pExprInfo ) ;
SArray * pColList = taosArrayInit ( numOfOutput , sizeof ( int32_t ) ) ;
for ( int32_t i = 0 ; i < numOfOutput ; + + i ) {
SExprInfo * pExpr = taosArrayGetP ( pExprInfo , i ) ;
taosArrayPush ( pColList , & pExpr - > pExpr - > pSchema [ 0 ] . colId ) ;
}
2022-01-21 08:12:02 +00:00
// set the extract column id to streamHandle
tqReadHandleSetColIdList ( ( STqReadHandle * ) streamReadHandle , pColList ) ;
2022-02-11 07:50:20 +00:00
tqReadHandleSetTbUidList ( streamReadHandle , pTableIdList ) ;
2022-01-21 07:16:17 +00:00
pInfo - > readerHandle = streamReadHandle ;
2022-01-20 09:10:28 +00:00
2022-01-20 14:57:29 +00:00
pOperator - > name = " StreamBlockScanOperator " ;
2022-01-21 07:16:17 +00:00
pOperator - > operatorType = OP_StreamScan ;
2022-01-20 14:57:29 +00:00
pOperator - > blockingOptr = false ;
pOperator - > status = OP_IN_EXECUTING ;
pOperator - > info = pInfo ;
pOperator - > numOfOutput = numOfOutput ;
pOperator - > exec = doStreamBlockScan ;
pOperator - > pTaskInfo = pTaskInfo ;
2022-01-21 08:12:02 +00:00
return pOperator ;
2022-01-20 09:10:28 +00:00
}
2021-11-02 05:37:31 +00:00
void setTableScanFilterOperatorInfo ( STableScanInfo * pTableScanInfo , SOperatorInfo * pDownstream ) {
assert ( pTableScanInfo ! = NULL & & pDownstream ! = NULL ) ;
pTableScanInfo - > pExpr = pDownstream - > pExpr ; // TODO refactor to use colId instead of pExpr
pTableScanInfo - > numOfOutput = pDownstream - > numOfOutput ;
2021-12-06 06:44:27 +00:00
#if 0
2021-11-02 05:37:31 +00:00
if ( pDownstream - > operatorType = = OP_Aggregate | | pDownstream - > operatorType = = OP_MultiTableAggregate ) {
SAggOperatorInfo * pAggInfo = pDownstream - > info ;
pTableScanInfo - > pCtx = pAggInfo - > binfo . pCtx ;
pTableScanInfo - > pResultRowInfo = & pAggInfo - > binfo . resultRowInfo ;
pTableScanInfo - > rowCellInfoOffset = pAggInfo - > binfo . rowCellInfoOffset ;
} else if ( pDownstream - > operatorType = = OP_TimeWindow | | pDownstream - > operatorType = = OP_AllTimeWindow ) {
STableIntervalOperatorInfo * pIntervalInfo = pDownstream - > info ;
pTableScanInfo - > pCtx = pIntervalInfo - > pCtx ;
pTableScanInfo - > pResultRowInfo = & pIntervalInfo - > resultRowInfo ;
pTableScanInfo - > rowCellInfoOffset = pIntervalInfo - > rowCellInfoOffset ;
} else if ( pDownstream - > operatorType = = OP_Groupby ) {
SGroupbyOperatorInfo * pGroupbyInfo = pDownstream - > info ;
pTableScanInfo - > pCtx = pGroupbyInfo - > binfo . pCtx ;
pTableScanInfo - > pResultRowInfo = & pGroupbyInfo - > binfo . resultRowInfo ;
pTableScanInfo - > rowCellInfoOffset = pGroupbyInfo - > binfo . rowCellInfoOffset ;
} else if ( pDownstream - > operatorType = = OP_MultiTableTimeInterval | | pDownstream - > operatorType = = OP_AllMultiTableTimeInterval ) {
STableIntervalOperatorInfo * pInfo = pDownstream - > info ;
pTableScanInfo - > pCtx = pInfo - > pCtx ;
pTableScanInfo - > pResultRowInfo = & pInfo - > resultRowInfo ;
pTableScanInfo - > rowCellInfoOffset = pInfo - > rowCellInfoOffset ;
} else if ( pDownstream - > operatorType = = OP_Project ) {
SProjectOperatorInfo * pInfo = pDownstream - > info ;
pTableScanInfo - > pCtx = pInfo - > binfo . pCtx ;
pTableScanInfo - > pResultRowInfo = & pInfo - > binfo . resultRowInfo ;
pTableScanInfo - > rowCellInfoOffset = pInfo - > binfo . rowCellInfoOffset ;
} else if ( pDownstream - > operatorType = = OP_SessionWindow ) {
SSWindowOperatorInfo * pInfo = pDownstream - > info ;
pTableScanInfo - > pCtx = pInfo - > binfo . pCtx ;
pTableScanInfo - > pResultRowInfo = & pInfo - > binfo . resultRowInfo ;
pTableScanInfo - > rowCellInfoOffset = pInfo - > binfo . rowCellInfoOffset ;
} else if ( pDownstream - > operatorType = = OP_StateWindow ) {
SStateWindowOperatorInfo * pInfo = pDownstream - > info ;
pTableScanInfo - > pCtx = pInfo - > binfo . pCtx ;
pTableScanInfo - > pResultRowInfo = & pInfo - > binfo . resultRowInfo ;
pTableScanInfo - > rowCellInfoOffset = pInfo - > binfo . rowCellInfoOffset ;
} else {
assert ( 0 ) ;
}
2021-12-06 06:44:27 +00:00
# endif
2021-11-02 05:37:31 +00:00
}
2022-01-08 08:28:44 +00:00
SArray * getOrderCheckColumns ( STaskAttr * pQuery ) {
2021-11-02 05:37:31 +00:00
int32_t numOfCols = ( pQuery - > pGroupbyExpr = = NULL ) ? 0 : taosArrayGetSize ( pQuery - > pGroupbyExpr - > columnInfo ) ;
SArray * pOrderColumns = NULL ;
if ( numOfCols > 0 ) {
pOrderColumns = taosArrayDup ( pQuery - > pGroupbyExpr - > columnInfo ) ;
} else {
pOrderColumns = taosArrayInit ( 4 , sizeof ( SColIndex ) ) ;
}
if ( pQuery - > interval . interval > 0 ) {
if ( pOrderColumns = = NULL ) {
pOrderColumns = taosArrayInit ( 1 , sizeof ( SColIndex ) ) ;
}
SColIndex colIndex = { . colIndex = 0 , . colId = 0 , . flag = TSDB_COL_NORMAL } ;
taosArrayPush ( pOrderColumns , & colIndex ) ;
}
{
numOfCols = ( int32_t ) taosArrayGetSize ( pOrderColumns ) ;
for ( int32_t i = 0 ; i < numOfCols ; + + i ) {
SColIndex * index = taosArrayGet ( pOrderColumns , i ) ;
for ( int32_t j = 0 ; j < pQuery - > numOfOutput ; + + j ) {
SSqlExpr * pExpr = & pQuery - > pExpr1 [ j ] . base ;
int32_t functionId = getExprFunctionId ( & pQuery - > pExpr1 [ j ] ) ;
2021-11-05 02:35:50 +00:00
if ( index - > colId = = pExpr - > pColumns - > info . colId & &
2021-11-02 05:37:31 +00:00
( functionId = = FUNCTION_PRJ | | functionId = = FUNCTION_TAG | | functionId = = FUNCTION_TS ) ) {
index - > colIndex = j ;
index - > colId = pExpr - > resSchema . colId ;
}
}
}
}
return pOrderColumns ;
}
2022-01-08 08:28:44 +00:00
SArray * getResultGroupCheckColumns ( STaskAttr * pQuery ) {
2021-11-02 05:37:31 +00:00
int32_t numOfCols = ( pQuery - > pGroupbyExpr = = NULL ) ? 0 : taosArrayGetSize ( pQuery - > pGroupbyExpr - > columnInfo ) ;
SArray * pOrderColumns = NULL ;
if ( numOfCols > 0 ) {
pOrderColumns = taosArrayDup ( pQuery - > pGroupbyExpr - > columnInfo ) ;
} else {
pOrderColumns = taosArrayInit ( 4 , sizeof ( SColIndex ) ) ;
}
for ( int32_t i = 0 ; i < numOfCols ; + + i ) {
SColIndex * index = taosArrayGet ( pOrderColumns , i ) ;
bool found = false ;
for ( int32_t j = 0 ; j < pQuery - > numOfOutput ; + + j ) {
SSqlExpr * pExpr = & pQuery - > pExpr1 [ j ] . base ;
int32_t functionId = getExprFunctionId ( & pQuery - > pExpr1 [ j ] ) ;
// FUNCTION_TAG_DUMMY function needs to be ignored
2021-11-04 05:24:19 +00:00
if ( index - > colId = = pExpr - > pColumns - > info . colId & &
2021-11-05 02:35:50 +00:00
( ( TSDB_COL_IS_TAG ( pExpr - > pColumns - > flag ) & & functionId = = FUNCTION_TAG ) | |
( TSDB_COL_IS_NORMAL_COL ( pExpr - > pColumns - > flag ) & & functionId = = FUNCTION_PRJ ) ) ) {
2021-11-02 05:37:31 +00:00
index - > colIndex = j ;
index - > colId = pExpr - > resSchema . colId ;
found = true ;
break ;
}
}
assert ( found & & index - > colIndex > = 0 & & index - > colIndex < pQuery - > numOfOutput ) ;
}
return pOrderColumns ;
}
static void destroyGlobalAggOperatorInfo ( void * param , int32_t numOfOutput ) {
SMultiwayMergeInfo * pInfo = ( SMultiwayMergeInfo * ) param ;
destroyBasicOperatorInfo ( & pInfo - > binfo , numOfOutput ) ;
taosArrayDestroy ( pInfo - > orderColumnList ) ;
taosArrayDestroy ( pInfo - > groupColumnList ) ;
tfree ( pInfo - > prevRow ) ;
tfree ( pInfo - > currentGroupColData ) ;
}
static void destroySlimitOperatorInfo ( void * param , int32_t numOfOutput ) {
SSLimitOperatorInfo * pInfo = ( SSLimitOperatorInfo * ) param ;
taosArrayDestroy ( pInfo - > orderColumnList ) ;
2022-02-08 10:01:21 +00:00
pInfo - > pRes = blockDataDestroy ( pInfo - > pRes ) ;
2021-11-02 05:37:31 +00:00
tfree ( pInfo - > prevRow ) ;
}
2022-01-08 14:59:24 +00:00
SOperatorInfo * createGlobalAggregateOperatorInfo ( STaskRuntimeEnv * pRuntimeEnv , SOperatorInfo * downstream ,
2021-11-02 05:37:31 +00:00
SExprInfo * pExpr , int32_t numOfOutput , void * param , SArray * pUdfInfo , bool groupResultMixedUp ) {
SMultiwayMergeInfo * pInfo = calloc ( 1 , sizeof ( SMultiwayMergeInfo ) ) ;
pInfo - > resultRowFactor =
( int32_t ) ( getRowNumForMultioutput ( pRuntimeEnv - > pQueryAttr , pRuntimeEnv - > pQueryAttr - > topBotQuery , false ) ) ;
pRuntimeEnv - > scanFlag = MERGE_STAGE ; // TODO init when creating pCtx
pInfo - > multiGroupResults = groupResultMixedUp ;
pInfo - > pMerge = param ;
pInfo - > bufCapacity = 4096 ;
pInfo - > udfInfo = pUdfInfo ;
pInfo - > binfo . pRes = createOutputBuf ( pExpr , numOfOutput , pInfo - > bufCapacity * pInfo - > resultRowFactor ) ;
2022-01-14 02:20:55 +00:00
pInfo - > binfo . pCtx = createSqlFunctionCtx ( pRuntimeEnv , pExpr , numOfOutput , & pInfo - > binfo . rowCellInfoOffset ) ;
2021-11-02 05:37:31 +00:00
pInfo - > orderColumnList = getOrderCheckColumns ( pRuntimeEnv - > pQueryAttr ) ;
pInfo - > groupColumnList = getResultGroupCheckColumns ( pRuntimeEnv - > pQueryAttr ) ;
// TODO refactor
int32_t len = 0 ;
for ( int32_t i = 0 ; i < numOfOutput ; + + i ) {
// len += pExpr[i].base.;
}
int32_t numOfCols = ( pInfo - > orderColumnList ! = NULL ) ? ( int32_t ) taosArrayGetSize ( pInfo - > orderColumnList ) : 0 ;
pInfo - > prevRow = calloc ( 1 , ( POINTER_BYTES * numOfCols + len ) ) ;
int32_t offset = POINTER_BYTES * numOfCols ;
for ( int32_t i = 0 ; i < numOfCols ; + + i ) {
pInfo - > prevRow [ i ] = ( char * ) pInfo - > prevRow + offset ;
SColIndex * index = taosArrayGet ( pInfo - > orderColumnList , i ) ;
offset + = pExpr [ index - > colIndex ] . base . resSchema . bytes ;
}
numOfCols = ( pInfo - > groupColumnList ! = NULL ) ? ( int32_t ) taosArrayGetSize ( pInfo - > groupColumnList ) : 0 ;
pInfo - > currentGroupColData = calloc ( 1 , ( POINTER_BYTES * numOfCols + len ) ) ;
offset = POINTER_BYTES * numOfCols ;
for ( int32_t i = 0 ; i < numOfCols ; + + i ) {
pInfo - > currentGroupColData [ i ] = ( char * ) pInfo - > currentGroupColData + offset ;
SColIndex * index = taosArrayGet ( pInfo - > groupColumnList , i ) ;
offset + = pExpr [ index - > colIndex ] . base . resSchema . bytes ;
}
initResultRowInfo ( & pInfo - > binfo . resultRowInfo , 8 , TSDB_DATA_TYPE_INT ) ;
pInfo - > seed = rand ( ) ;
setDefaultOutputBuf ( pRuntimeEnv , & pInfo - > binfo , pInfo - > seed , MERGE_STAGE ) ;
SOperatorInfo * pOperator = calloc ( 1 , sizeof ( SOperatorInfo ) ) ;
pOperator - > name = " GlobalAggregate " ;
2021-12-06 06:44:27 +00:00
// pOperator->operatorType = OP_GlobalAggregate;
2021-11-02 05:37:31 +00:00
pOperator - > blockingOptr = true ;
pOperator - > status = OP_IN_EXECUTING ;
pOperator - > info = pInfo ;
pOperator - > pExpr = pExpr ;
pOperator - > numOfOutput = numOfOutput ;
pOperator - > pRuntimeEnv = pRuntimeEnv ;
2022-01-10 11:48:21 +00:00
// pOperator->exec = doGlobalAggregate;
2022-01-28 02:44:02 +00:00
pOperator - > cleanupFn = destroyGlobalAggOperatorInfo ;
2022-01-14 02:20:55 +00:00
appendDownstream ( pOperator , downstream ) ;
2021-11-02 05:37:31 +00:00
return pOperator ;
}
2022-01-08 08:28:44 +00:00
SOperatorInfo * createMultiwaySortOperatorInfo ( STaskRuntimeEnv * pRuntimeEnv , SExprInfo * pExpr , int32_t numOfOutput ,
2021-11-02 05:37:31 +00:00
int32_t numOfRows , void * merger ) {
SMultiwayMergeInfo * pInfo = calloc ( 1 , sizeof ( SMultiwayMergeInfo ) ) ;
pInfo - > pMerge = merger ;
pInfo - > bufCapacity = numOfRows ;
pInfo - > orderColumnList = getResultGroupCheckColumns ( pRuntimeEnv - > pQueryAttr ) ;
pInfo - > binfo . pRes = createOutputBuf ( pExpr , numOfOutput , numOfRows ) ;
{ // todo extract method to create prev compare buffer
int32_t len = 0 ;
for ( int32_t i = 0 ; i < numOfOutput ; + + i ) {
// len += pExpr[i].base.colBytes;
}
int32_t numOfCols = ( pInfo - > orderColumnList ! = NULL ) ? ( int32_t ) taosArrayGetSize ( pInfo - > orderColumnList ) : 0 ;
pInfo - > prevRow = calloc ( 1 , ( POINTER_BYTES * numOfCols + len ) ) ;
int32_t offset = POINTER_BYTES * numOfCols ;
for ( int32_t i = 0 ; i < numOfCols ; + + i ) {
pInfo - > prevRow [ i ] = ( char * ) pInfo - > prevRow + offset ;
SColIndex * index = taosArrayGet ( pInfo - > orderColumnList , i ) ;
// offset += pExpr[index->colIndex].base.colBytes;
}
}
SOperatorInfo * pOperator = calloc ( 1 , sizeof ( SOperatorInfo ) ) ;
pOperator - > name = " MultiwaySortOperator " ;
2021-12-06 06:44:27 +00:00
// pOperator->operatorType = OP_MultiwayMergeSort;
2021-11-02 05:37:31 +00:00
pOperator - > blockingOptr = false ;
pOperator - > status = OP_IN_EXECUTING ;
pOperator - > info = pInfo ;
pOperator - > pRuntimeEnv = pRuntimeEnv ;
pOperator - > numOfOutput = numOfOutput ;
pOperator - > pExpr = pExpr ;
2022-01-10 11:48:21 +00:00
// pOperator->exec = doMultiwayMergeSort;
2022-01-28 02:44:02 +00:00
pOperator - > cleanupFn = destroyGlobalAggOperatorInfo ;
2021-11-02 05:37:31 +00:00
return pOperator ;
}
2022-02-08 02:21:00 +00:00
typedef struct SExternalMemSource {
SArray * pageIdList ;
int32_t pageIndex ;
int32_t sourceId ;
int32_t rowIndex ;
SSDataBlock * pBlock ;
} SExternalMemSource ;
2022-02-08 07:40:13 +00:00
int32_t msortComparFn ( const void * pLeft , const void * pRight , void * param ) {
2022-02-08 02:21:00 +00:00
int32_t pLeftIdx = * ( int32_t * ) pLeft ;
int32_t pRightIdx = * ( int32_t * ) pRight ;
2022-02-08 07:40:13 +00:00
SMsortComparParam * pParam = ( SMsortComparParam * ) param ;
2022-02-08 02:21:00 +00:00
SArray * pInfo = pParam - > orderInfo ;
2022-02-09 05:44:16 +00:00
SExternalMemSource * pLeftSource = pParam - > pSources [ pLeftIdx ] ;
SExternalMemSource * pRightSource = pParam - > pSources [ pRightIdx ] ;
2022-02-08 02:21:00 +00:00
// this input is exhausted, set the special value to denote this
2022-02-09 05:44:16 +00:00
if ( pLeftSource - > rowIndex = = - 1 ) {
2022-02-08 02:21:00 +00:00
return 1 ;
}
2022-02-09 05:44:16 +00:00
if ( pRightSource - > rowIndex = = - 1 ) {
2022-02-08 02:21:00 +00:00
return - 1 ;
}
2022-02-09 05:44:16 +00:00
SSDataBlock * pLeftBlock = pLeftSource - > pBlock ;
SSDataBlock * pRightBlock = pRightSource - > pBlock ;
2022-02-08 02:21:00 +00:00
2022-02-09 05:44:16 +00:00
for ( int32_t i = 0 ; i < pInfo - > size ; + + i ) {
SBlockOrderInfo * pOrder = TARRAY_GET_ELEM ( pInfo , i ) ;
2022-02-08 02:21:00 +00:00
2022-02-09 05:44:16 +00:00
SColumnInfoData * pLeftColInfoData = TARRAY_GET_ELEM ( pLeftBlock - > pDataBlock , pOrder - > colIndex ) ;
2022-02-08 02:21:00 +00:00
2022-02-09 05:44:16 +00:00
bool leftNull = false ;
if ( pLeftColInfoData - > hasNull ) {
leftNull = colDataIsNull ( pLeftColInfoData , pLeftBlock - > info . rows , pLeftSource - > rowIndex , pLeftBlock - > pBlockAgg ) ;
}
SColumnInfoData * pRightColInfoData = TARRAY_GET_ELEM ( pRightBlock - > pDataBlock , pOrder - > colIndex ) ;
bool rightNull = false ;
if ( pRightColInfoData - > hasNull ) {
rightNull = colDataIsNull ( pRightColInfoData , pRightBlock - > info . rows , pRightSource - > rowIndex , pRightBlock - > pBlockAgg ) ;
}
2022-02-08 02:21:00 +00:00
if ( leftNull & & rightNull ) {
continue ; // continue to next slot
}
if ( rightNull ) {
return pParam - > nullFirst ? 1 : - 1 ;
}
if ( leftNull ) {
return pParam - > nullFirst ? - 1 : 1 ;
}
2022-02-09 05:44:16 +00:00
void * left1 = colDataGet ( pLeftColInfoData , pLeftSource - > rowIndex ) ;
void * right1 = colDataGet ( pRightColInfoData , pRightSource - > rowIndex ) ;
2022-02-08 02:21:00 +00:00
switch ( pLeftColInfoData - > info . type ) {
2022-02-09 05:44:16 +00:00
case TSDB_DATA_TYPE_INT : {
int32_t leftv = * ( int32_t * ) left1 ;
int32_t rightv = * ( int32_t * ) right1 ;
if ( leftv = = rightv ) {
2022-02-08 02:21:00 +00:00
break ;
} else {
if ( pOrder - > order = = TSDB_ORDER_ASC ) {
2022-02-09 05:44:16 +00:00
return leftv < rightv ? - 1 : 1 ;
2022-02-08 02:21:00 +00:00
} else {
2022-02-09 05:44:16 +00:00
return leftv < rightv ? 1 : - 1 ;
2022-02-08 02:21:00 +00:00
}
}
2022-02-09 05:44:16 +00:00
}
2022-02-08 02:21:00 +00:00
default :
assert ( 0 ) ;
}
}
}
2022-02-08 07:40:13 +00:00
static int32_t adjustMergeTreeForNextTuple ( SExternalMemSource * pSource , SMultiwayMergeTreeInfo * pTree , SOrderOperatorInfo * pInfo ) {
2022-02-08 02:21:00 +00:00
/*
* load a new SDataBlock into memory of a given intermediate data - set source ,
* since it ' s last record in buffer has been chosen to be processed , as the winner of loser - tree
*/
if ( pSource - > rowIndex > = pSource - > pBlock - > info . rows ) {
2022-02-08 07:40:13 +00:00
pSource - > rowIndex = 0 ;
pSource - > pageIndex + = 1 ;
if ( pSource - > pageIndex > = taosArrayGetSize ( pSource - > pageIdList ) ) {
pInfo - > numOfCompleted + = 1 ;
pSource - > rowIndex = - 1 ;
pSource - > pageIndex = - 1 ;
} else {
SPageInfo * pPgInfo = * ( SPageInfo * * ) taosArrayGet ( pSource - > pageIdList , pSource - > pageIndex ) ;
2022-02-10 05:49:17 +00:00
SFilePage * pPage = getBufPage ( pInfo - > pSortInternalBuf , getPageId ( pPgInfo ) ) ;
2022-02-08 07:40:13 +00:00
int32_t code = blockDataFromBuf ( pSource - > pBlock , pPage - > data ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
return code ;
}
2022-02-10 05:38:40 +00:00
2022-02-10 05:49:17 +00:00
releaseBufPage ( pInfo - > pSortInternalBuf , pPage ) ;
2022-02-08 07:40:13 +00:00
}
2022-02-08 02:21:00 +00:00
}
/*
* Adjust loser tree otherwise , according to new candidate data
* if the loser tree is rebuild completed , we do not need to adjust
*/
2022-02-09 05:44:16 +00:00
int32_t leafNodeIndex = tMergeTreeGetAdjustIndex ( pTree ) ;
2022-02-08 02:21:00 +00:00
# ifdef _DEBUG_VIEW
2022-02-08 07:40:13 +00:00
printf ( " before adjust: \t " ) ;
tMergeTreePrint ( pTree ) ;
2022-02-08 02:21:00 +00:00
# endif
2022-02-08 07:40:13 +00:00
tMergeTreeAdjust ( pTree , leafNodeIndex ) ;
2022-02-08 02:21:00 +00:00
# ifdef _DEBUG_VIEW
2022-02-08 07:40:13 +00:00
printf ( " \n after adjust: \t " ) ;
tMergeTreePrint ( pTree ) ;
2022-02-08 02:21:00 +00:00
# endif
}
static void appendOneRowToDataBlock ( SSDataBlock * pBlock , const SSDataBlock * pSource , int32_t * rowIndex ) {
for ( int32_t i = 0 ; i < pBlock - > info . numOfCols ; + + i ) {
SColumnInfoData * pColInfo = taosArrayGet ( pBlock - > pDataBlock , i ) ;
SColumnInfoData * pSrcColInfo = taosArrayGet ( pSource - > pDataBlock , i ) ;
bool isNull = colDataIsNull ( pSrcColInfo , pSource - > info . rows , * rowIndex , NULL ) ;
char * pData = colDataGet ( pSrcColInfo , * rowIndex ) ;
colDataAppend ( pColInfo , pBlock - > info . rows , pData , isNull ) ;
}
pBlock - > info . rows + = 1 ;
* rowIndex + = 1 ;
}
2022-02-08 07:40:13 +00:00
static int32_t doAddNewSource ( SOrderOperatorInfo * pInfo , int32_t numOfCols ) {
SExternalMemSource * pSource = calloc ( 1 , sizeof ( SExternalMemSource ) ) ;
if ( pSource = = NULL ) {
return TSDB_CODE_QRY_OUT_OF_MEMORY ;
}
pSource - > pageIdList = getDataBufPagesIdList ( pInfo - > pSortInternalBuf , pInfo - > sourceId ) ;
pSource - > sourceId = pInfo - > sourceId ;
pSource - > pBlock = calloc ( 1 , sizeof ( SSDataBlock ) ) ;
pSource - > pBlock - > pDataBlock = taosArrayInit ( numOfCols , sizeof ( SColumnInfoData ) ) ;
pSource - > pBlock - > info . numOfCols = numOfCols ;
for ( int32_t i = 0 ; i < numOfCols ; + + i ) {
SColumnInfoData colInfo = { 0 } ;
SColumnInfoData * p = taosArrayGet ( pInfo - > pDataBlock - > pDataBlock , i ) ;
colInfo . info = p - > info ;
taosArrayPush ( pSource - > pBlock - > pDataBlock , & colInfo ) ;
}
taosArrayPush ( pInfo - > pSources , & pSource ) ;
2022-02-08 10:01:21 +00:00
2022-02-08 07:40:13 +00:00
pInfo - > sourceId + = 1 ;
2022-02-08 10:01:21 +00:00
pInfo - > cmpParam . numOfSources + = 1 ;
2022-02-08 07:40:13 +00:00
2022-02-08 10:01:21 +00:00
ASSERT ( pInfo - > cmpParam . numOfSources = = taosArrayGetSize ( pInfo - > pSources ) ) ;
2022-02-08 07:40:13 +00:00
return blockDataEnsureCapacity ( pSource - > pBlock , pInfo - > capacity ) ;
}
void addToDiskbasedBuf ( SOrderOperatorInfo * pInfo , jmp_buf env ) {
2022-02-08 02:21:00 +00:00
int32_t start = 0 ;
while ( start < pInfo - > pDataBlock - > info . rows ) {
int32_t stop = 0 ;
blockDataSplitRows ( pInfo - > pDataBlock , pInfo - > hasVarCol , start , & stop , getBufPageSize ( pInfo - > pSortInternalBuf ) ) ;
SSDataBlock * p = blockDataExtractBlock ( pInfo - > pDataBlock , start , stop - start + 1 ) ;
2022-02-08 07:40:13 +00:00
if ( p = = NULL ) {
longjmp ( env , TSDB_CODE_QRY_OUT_OF_MEMORY ) ;
}
2022-02-08 02:21:00 +00:00
int32_t pageId = - 1 ;
SFilePage * pPage = getNewDataBuf ( pInfo - > pSortInternalBuf , pInfo - > sourceId , & pageId ) ;
2022-02-09 11:03:47 +00:00
if ( pPage = = NULL ) {
assert ( 0 ) ;
longjmp ( env , terrno ) ;
}
2022-02-09 04:45:27 +00:00
int32_t size = blockDataGetSize ( p ) + sizeof ( int32_t ) + p - > info . numOfCols * sizeof ( int32_t ) ;
assert ( size < = getBufPageSize ( pInfo - > pSortInternalBuf ) ) ;
2022-02-08 02:21:00 +00:00
blockDataToBuf ( pPage - > data , p ) ;
2022-02-10 08:31:23 +00:00
setBufPageDirty ( pPage , true ) ;
2022-02-10 05:49:17 +00:00
releaseBufPage ( pInfo - > pSortInternalBuf , pPage ) ;
2022-02-08 02:21:00 +00:00
2022-02-08 10:01:21 +00:00
blockDataDestroy ( p ) ;
2022-02-08 02:21:00 +00:00
start = stop + 1 ;
}
int32_t numOfCols = pInfo - > pDataBlock - > info . numOfCols ;
2022-02-08 07:40:13 +00:00
blockDataClearup ( pInfo - > pDataBlock , pInfo - > hasVarCol ) ;
2022-02-08 02:21:00 +00:00
2022-02-08 07:40:13 +00:00
int32_t code = doAddNewSource ( pInfo , numOfCols ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
longjmp ( env , code ) ;
2022-02-08 02:21:00 +00:00
}
2022-02-08 07:40:13 +00:00
}
2022-02-08 02:21:00 +00:00
2022-02-08 07:40:13 +00:00
static int32_t sortComparInit ( SMsortComparParam * cmpParam , const SOrderOperatorInfo * pInfo ) {
cmpParam - > pSources = pInfo - > pSources - > pData ;
2022-02-08 02:21:00 +00:00
2022-02-08 10:01:21 +00:00
for ( int32_t i = 0 ; i < pInfo - > cmpParam . numOfSources ; + + i ) {
2022-02-08 07:40:13 +00:00
SExternalMemSource * pSource = cmpParam - > pSources [ i ] ;
SPageInfo * pPgInfo = * ( SPageInfo * * ) taosArrayGet ( pSource - > pageIdList , pSource - > pageIndex ) ;
2022-02-08 02:21:00 +00:00
2022-02-10 05:49:17 +00:00
SFilePage * pPage = getBufPage ( pInfo - > pSortInternalBuf , getPageId ( pPgInfo ) ) ;
2022-02-08 07:40:13 +00:00
int32_t code = blockDataFromBuf ( cmpParam - > pSources [ i ] - > pBlock , pPage - > data ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
return code ;
}
2022-02-10 05:38:40 +00:00
2022-02-10 05:49:17 +00:00
releaseBufPage ( pInfo - > pSortInternalBuf , pPage ) ;
2022-02-08 02:21:00 +00:00
}
2022-02-08 10:01:21 +00:00
return TSDB_CODE_SUCCESS ;
}
static SSDataBlock * getSortedBlockData ( SExecTaskInfo * pTaskInfo , SOrderOperatorInfo * pInfo , SMsortComparParam * cmpParam ) {
blockDataClearup ( pInfo - > pDataBlock , pInfo - > hasVarCol ) ;
while ( 1 ) {
if ( pInfo - > cmpParam . numOfSources = = pInfo - > numOfCompleted ) {
break ;
}
int32_t index = tMergeTreeGetChosenIndex ( pInfo - > pMergeTree ) ;
SExternalMemSource * pSource = ( * cmpParam ) . pSources [ index ] ;
appendOneRowToDataBlock ( pInfo - > pDataBlock , pSource - > pBlock , & pSource - > rowIndex ) ;
int32_t code = adjustMergeTreeForNextTuple ( pSource , pInfo - > pMergeTree , pInfo ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
longjmp ( pTaskInfo - > env , code ) ;
}
if ( pInfo - > pDataBlock - > info . rows > = pInfo - > capacity ) {
return pInfo - > pDataBlock ;
}
}
return ( pInfo - > pDataBlock - > info . rows > 0 ) ? pInfo - > pDataBlock : NULL ;
2022-02-08 02:21:00 +00:00
}
2021-11-02 05:37:31 +00:00
static SSDataBlock * doSort ( void * param , bool * newgroup ) {
SOperatorInfo * pOperator = ( SOperatorInfo * ) param ;
if ( pOperator - > status = = OP_EXEC_DONE ) {
return NULL ;
}
2022-02-08 07:40:13 +00:00
SExecTaskInfo * pTaskInfo = pOperator - > pTaskInfo ;
2021-11-02 05:37:31 +00:00
SOrderOperatorInfo * pInfo = pOperator - > info ;
SSDataBlock * pBlock = NULL ;
2022-02-08 02:21:00 +00:00
2022-02-08 10:01:21 +00:00
if ( pOperator - > status = = OP_RES_TO_RETURN ) {
return getSortedBlockData ( pTaskInfo , pInfo , & pInfo - > cmpParam ) ;
}
2021-11-02 05:37:31 +00:00
while ( 1 ) {
2022-01-08 08:28:44 +00:00
publishOperatorProfEvent ( pOperator - > pDownstream [ 0 ] , QUERY_PROF_BEFORE_OPERATOR_EXEC ) ;
pBlock = pOperator - > pDownstream [ 0 ] - > exec ( pOperator - > pDownstream [ 0 ] , newgroup ) ;
publishOperatorProfEvent ( pOperator - > pDownstream [ 0 ] , QUERY_PROF_AFTER_OPERATOR_EXEC ) ;
2021-11-02 05:37:31 +00:00
// start to flush data into disk and try do multiway merge sort
if ( pBlock = = NULL ) {
break ;
}
2022-02-04 14:41:54 +00:00
int32_t code = blockDataMerge ( pInfo - > pDataBlock , pBlock ) ;
2021-11-02 05:37:31 +00:00
if ( code ! = TSDB_CODE_SUCCESS ) {
2022-02-08 07:40:13 +00:00
longjmp ( pOperator - > pTaskInfo - > env , code ) ;
2021-11-02 05:37:31 +00:00
}
2022-02-04 14:41:54 +00:00
size_t size = blockDataGetSize ( pInfo - > pDataBlock ) ;
if ( size > pInfo - > sortBufSize ) {
// Perform the in-memory sort and then flush data in the buffer into disk.
2022-02-08 02:21:00 +00:00
int64_t p = taosGetTimestampUs ( ) ;
2022-02-08 10:01:21 +00:00
blockDataSort ( pInfo - > pDataBlock , pInfo - > cmpParam . orderInfo , pInfo - > cmpParam . nullFirst ) ;
2022-02-08 02:21:00 +00:00
printf ( " sort time:%ld \n " , taosGetTimestampUs ( ) - p ) ;
2021-11-02 05:37:31 +00:00
2022-02-08 07:40:13 +00:00
addToDiskbasedBuf ( pInfo , pTaskInfo - > env ) ;
2022-02-04 14:41:54 +00:00
}
2021-11-02 05:37:31 +00:00
}
2022-02-08 02:21:00 +00:00
if ( pInfo - > pDataBlock - > info . rows > 0 ) {
// Perform the in-memory sort and then flush data in the buffer into disk.
2022-02-08 10:01:21 +00:00
blockDataSort ( pInfo - > pDataBlock , pInfo - > cmpParam . orderInfo , pInfo - > cmpParam . nullFirst ) ;
2022-02-08 02:21:00 +00:00
// All sorted data are resident in memory, external memory sort is not needed.
// Return to the upstream operator directly
if ( isAllDataInMemBuf ( pInfo - > pSortInternalBuf ) ) {
2022-02-08 10:01:21 +00:00
pOperator - > status = OP_EXEC_DONE ;
2022-02-08 02:21:00 +00:00
return ( pInfo - > pDataBlock - > info . rows = = 0 ) ? NULL : pInfo - > pDataBlock ;
}
2022-02-08 07:40:13 +00:00
addToDiskbasedBuf ( pInfo , pTaskInfo - > env ) ;
2022-02-08 02:21:00 +00:00
}
2022-02-04 14:41:54 +00:00
2022-02-09 10:23:51 +00:00
blockDataEnsureCapacity ( pInfo - > pDataBlock , pInfo - > capacity ) ;
2022-02-08 10:01:21 +00:00
int32_t code = sortComparInit ( & pInfo - > cmpParam , pInfo ) ;
2022-02-08 07:40:13 +00:00
if ( code ! = TSDB_CODE_SUCCESS ) {
longjmp ( pTaskInfo - > env , code ) ;
2022-02-08 02:21:00 +00:00
}
2022-02-08 10:01:21 +00:00
code = tMergeTreeCreate ( & pInfo - > pMergeTree , pInfo - > cmpParam . numOfSources , & pInfo - > cmpParam , msortComparFn ) ;
2022-02-08 07:40:13 +00:00
if ( code ! = TSDB_CODE_SUCCESS ) {
longjmp ( pTaskInfo - > env , code ) ;
}
2022-02-08 02:21:00 +00:00
2022-02-08 10:01:21 +00:00
pOperator - > status = OP_RES_TO_RETURN ;
return getSortedBlockData ( pTaskInfo , pInfo , & pInfo - > cmpParam ) ;
2021-11-02 05:37:31 +00:00
}
2022-02-08 02:21:00 +00:00
static SArray * createBlockOrder ( SArray * pExprInfo , SArray * pOrderVal ) {
SArray * pOrderInfo = taosArrayInit ( 1 , sizeof ( SBlockOrderInfo ) ) ;
size_t numOfOrder = taosArrayGetSize ( pOrderVal ) ;
for ( int32_t j = 0 ; j < numOfOrder ; + + j ) {
SBlockOrderInfo orderInfo = { 0 } ;
SOrder * pOrder = taosArrayGet ( pOrderVal , j ) ;
orderInfo . order = pOrder - > order ;
for ( int32_t i = 0 ; i < taosArrayGetSize ( pExprInfo ) ; + + i ) {
SExprInfo * pExpr = taosArrayGet ( pExprInfo , i ) ;
if ( pExpr - > base . resSchema . colId = = pOrder - > col . info . colId ) {
orderInfo . colIndex = i ;
break ;
}
}
taosArrayPush ( pOrderInfo , & orderInfo ) ;
}
return pOrderInfo ;
}
SOperatorInfo * createOrderOperatorInfo ( SOperatorInfo * downstream , SArray * pExprInfo , SArray * pOrderVal ) {
2021-11-02 05:37:31 +00:00
SOrderOperatorInfo * pInfo = calloc ( 1 , sizeof ( SOrderOperatorInfo ) ) ;
2022-02-08 10:07:03 +00:00
SOperatorInfo * pOperator = calloc ( 1 , sizeof ( SOperatorInfo ) ) ;
if ( pInfo = = NULL | | pOperator = = NULL ) {
tfree ( pInfo ) ;
terrno = TSDB_CODE_QRY_OUT_OF_MEMORY ;
return NULL ;
}
2021-11-02 05:37:31 +00:00
2022-02-09 11:03:47 +00:00
pInfo - > sortBufSize = 1024 * 1024 * 50 ; // 1MB
2022-02-09 10:23:51 +00:00
pInfo - > capacity = 64 * 1024 ;
2022-02-08 10:01:21 +00:00
pInfo - > pDataBlock = createOutputBuf_rv ( pExprInfo , pInfo - > capacity ) ;
pInfo - > pSources = taosArrayInit ( 4 , POINTER_BYTES ) ;
pInfo - > cmpParam . orderInfo = createBlockOrder ( pExprInfo , pOrderVal ) ;
2022-02-08 02:21:00 +00:00
for ( int32_t i = 0 ; i < taosArrayGetSize ( pExprInfo ) ; + + i ) {
SExprInfo * pExpr = taosArrayGetP ( pExprInfo , i ) ;
if ( IS_VAR_DATA_TYPE ( pExpr - > base . resSchema . type ) ) {
pInfo - > hasVarCol = true ;
break ;
}
}
2022-02-09 10:23:51 +00:00
int32_t code = createDiskbasedBuffer ( & pInfo - > pSortInternalBuf , pInfo - > capacity , pInfo - > capacity * 1000 , 1 , " /tmp/ " ) ;
2022-02-08 10:07:03 +00:00
if ( pInfo - > pSources = = NULL | | code ! = 0 | | pInfo - > cmpParam . orderInfo = = NULL | | pInfo - > pDataBlock = = NULL ) {
tfree ( pOperator ) ;
destroyOrderOperatorInfo ( pInfo , taosArrayGetSize ( pExprInfo ) ) ;
tfree ( pInfo ) ;
terrno = TSDB_CODE_QRY_OUT_OF_MEMORY ;
return NULL ;
}
2021-11-02 05:37:31 +00:00
2022-02-04 14:41:54 +00:00
pOperator - > name = " Order " ;
pOperator - > operatorType = OP_Order ;
2021-11-02 05:37:31 +00:00
pOperator - > blockingOptr = true ;
pOperator - > status = OP_IN_EXECUTING ;
pOperator - > info = pInfo ;
pOperator - > exec = doSort ;
2022-02-04 14:41:54 +00:00
pOperator - > cleanupFn = destroyOrderOperatorInfo ;
2021-11-02 05:37:31 +00:00
2022-01-14 02:20:55 +00:00
appendDownstream ( pOperator , downstream ) ;
2021-11-02 05:37:31 +00:00
return pOperator ;
}
static int32_t getTableScanOrder ( STableScanInfo * pTableScanInfo ) {
return pTableScanInfo - > order ;
}
// this is a blocking operator
static SSDataBlock * doAggregate ( void * param , bool * newgroup ) {
SOperatorInfo * pOperator = ( SOperatorInfo * ) param ;
if ( pOperator - > status = = OP_EXEC_DONE ) {
return NULL ;
}
SAggOperatorInfo * pAggInfo = pOperator - > info ;
SOptrBasicInfo * pInfo = & pAggInfo - > binfo ;
2022-01-20 08:02:09 +00:00
int32_t order = TSDB_ORDER_ASC ;
2022-01-08 14:59:24 +00:00
SOperatorInfo * downstream = pOperator - > pDownstream [ 0 ] ;
2021-11-02 05:37:31 +00:00
while ( 1 ) {
2022-01-08 14:59:24 +00:00
publishOperatorProfEvent ( downstream , QUERY_PROF_BEFORE_OPERATOR_EXEC ) ;
SSDataBlock * pBlock = downstream - > exec ( downstream , newgroup ) ;
publishOperatorProfEvent ( downstream , QUERY_PROF_AFTER_OPERATOR_EXEC ) ;
2021-11-02 05:37:31 +00:00
if ( pBlock = = NULL ) {
break ;
}
2022-01-20 09:10:28 +00:00
// if (pAggInfo->current != NULL) {
2022-01-20 08:02:09 +00:00
// setTagValue(pOperator, pAggInfo->current->pTable, pInfo->pCtx, pOperator->numOfOutput);
2022-01-20 09:10:28 +00:00
// }
2021-11-02 05:37:31 +00:00
// the pDataBlock are always the same one, no need to call this again
setInputDataBlock ( pOperator , pInfo - > pCtx , pBlock , order ) ;
2022-01-20 08:02:09 +00:00
doAggregateImpl ( pOperator , 0 , pInfo - > pCtx , pBlock ) ;
2021-11-02 05:37:31 +00:00
}
doSetOperatorCompleted ( pOperator ) ;
finalizeQueryResult ( pOperator , pInfo - > pCtx , & pInfo - > resultRowInfo , pInfo - > rowCellInfoOffset ) ;
pInfo - > pRes - > info . rows = getNumOfResult ( pInfo - > pCtx , pOperator - > numOfOutput ) ;
2022-01-26 07:53:08 +00:00
return ( pInfo - > pRes - > info . rows ! = 0 ) ? pInfo - > pRes : NULL ;
2021-11-02 05:37:31 +00:00
}
static SSDataBlock * doSTableAggregate ( void * param , bool * newgroup ) {
SOperatorInfo * pOperator = ( SOperatorInfo * ) param ;
if ( pOperator - > status = = OP_EXEC_DONE ) {
return NULL ;
}
SAggOperatorInfo * pAggInfo = pOperator - > info ;
SOptrBasicInfo * pInfo = & pAggInfo - > binfo ;
2022-01-08 08:28:44 +00:00
STaskRuntimeEnv * pRuntimeEnv = pOperator - > pRuntimeEnv ;
2021-11-02 05:37:31 +00:00
if ( pOperator - > status = = OP_RES_TO_RETURN ) {
toSSDataBlock ( & pRuntimeEnv - > groupResInfo , pRuntimeEnv , pInfo - > pRes ) ;
if ( pInfo - > pRes - > info . rows = = 0 | | ! hasRemainDataInCurrentGroup ( & pRuntimeEnv - > groupResInfo ) ) {
pOperator - > status = OP_EXEC_DONE ;
}
return pInfo - > pRes ;
}
2022-01-08 08:28:44 +00:00
STaskAttr * pQueryAttr = pRuntimeEnv - > pQueryAttr ;
2021-11-02 05:37:31 +00:00
int32_t order = pQueryAttr - > order . order ;
2022-01-08 14:59:24 +00:00
SOperatorInfo * downstream = pOperator - > pDownstream [ 0 ] ;
2021-11-02 05:37:31 +00:00
while ( 1 ) {
2022-01-08 14:59:24 +00:00
publishOperatorProfEvent ( downstream , QUERY_PROF_BEFORE_OPERATOR_EXEC ) ;
SSDataBlock * pBlock = downstream - > exec ( downstream , newgroup ) ;
publishOperatorProfEvent ( downstream , QUERY_PROF_AFTER_OPERATOR_EXEC ) ;
2021-11-02 05:37:31 +00:00
if ( pBlock = = NULL ) {
break ;
}
setTagValue ( pOperator , pRuntimeEnv - > current - > pTable , pInfo - > pCtx , pOperator - > numOfOutput ) ;
2022-01-08 14:59:24 +00:00
// if (downstream->operatorType == OP_DataBlocksOptScan) {
// STableScanInfo* pScanInfo = downstream->info;
2021-12-06 06:44:27 +00:00
// order = getTableScanOrder(pScanInfo);
// }
2021-11-02 05:37:31 +00:00
// the pDataBlock are always the same one, no need to call this again
setInputDataBlock ( pOperator , pInfo - > pCtx , pBlock , order ) ;
TSKEY key = 0 ;
if ( QUERY_IS_ASC_QUERY ( pQueryAttr ) ) {
key = pBlock - > info . window . ekey ;
TSKEY_MAX_ADD ( key , 1 ) ;
} else {
key = pBlock - > info . window . skey ;
TSKEY_MIN_SUB ( key , - 1 ) ;
}
setExecutionContext ( pRuntimeEnv , pInfo , pOperator - > numOfOutput , pRuntimeEnv - > current - > groupIndex , key ) ;
doAggregateImpl ( pOperator , pQueryAttr - > window . skey , pInfo - > pCtx , pBlock ) ;
}
pOperator - > status = OP_RES_TO_RETURN ;
closeAllResultRows ( & pInfo - > resultRowInfo ) ;
updateNumOfRowsInResultRows ( pRuntimeEnv , pInfo - > pCtx , pOperator - > numOfOutput , & pInfo - > resultRowInfo ,
pInfo - > rowCellInfoOffset ) ;
initGroupResInfo ( & pRuntimeEnv - > groupResInfo , & pInfo - > resultRowInfo ) ;
toSSDataBlock ( & pRuntimeEnv - > groupResInfo , pRuntimeEnv , pInfo - > pRes ) ;
if ( pInfo - > pRes - > info . rows = = 0 | | ! hasRemainDataInCurrentGroup ( & pRuntimeEnv - > groupResInfo ) ) {
doSetOperatorCompleted ( pOperator ) ;
}
return pInfo - > pRes ;
}
static SSDataBlock * doProjectOperation ( void * param , bool * newgroup ) {
SOperatorInfo * pOperator = ( SOperatorInfo * ) param ;
SProjectOperatorInfo * pProjectInfo = pOperator - > info ;
2022-01-08 08:28:44 +00:00
STaskRuntimeEnv * pRuntimeEnv = pOperator - > pRuntimeEnv ;
2021-11-02 05:37:31 +00:00
SOptrBasicInfo * pInfo = & pProjectInfo - > binfo ;
SSDataBlock * pRes = pInfo - > pRes ;
int32_t order = pRuntimeEnv - > pQueryAttr - > order . order ;
pRes - > info . rows = 0 ;
if ( pProjectInfo - > existDataBlock ) { // TODO refactor
STableQueryInfo * pTableQueryInfo = pRuntimeEnv - > current ;
SSDataBlock * pBlock = pProjectInfo - > existDataBlock ;
pProjectInfo - > existDataBlock = NULL ;
* newgroup = true ;
// todo dynamic set tags
if ( pTableQueryInfo ! = NULL ) {
setTagValue ( pOperator , pTableQueryInfo - > pTable , pInfo - > pCtx , pOperator - > numOfOutput ) ;
}
// the pDataBlock are always the same one, no need to call this again
setInputDataBlock ( pOperator , pInfo - > pCtx , pBlock , order ) ;
updateOutputBuf ( & pProjectInfo - > binfo , & pProjectInfo - > bufCapacity , pBlock - > info . rows ) ;
projectApplyFunctions ( pRuntimeEnv , pInfo - > pCtx , pOperator - > numOfOutput ) ;
pRes - > info . rows = getNumOfResult ( pInfo - > pCtx , pOperator - > numOfOutput ) ;
if ( pRes - > info . rows > = pRuntimeEnv - > resultInfo . threshold ) {
copyTsColoum ( pRes , pInfo - > pCtx , pOperator - > numOfOutput ) ;
resetResultRowEntryResult ( pInfo - > pCtx , pOperator - > numOfOutput ) ;
return pRes ;
}
}
while ( 1 ) {
bool prevVal = * newgroup ;
2022-01-08 14:59:24 +00:00
// The downstream exec may change the value of the newgroup, so use a local variable instead.
2022-01-08 08:28:44 +00:00
publishOperatorProfEvent ( pOperator - > pDownstream [ 0 ] , QUERY_PROF_BEFORE_OPERATOR_EXEC ) ;
SSDataBlock * pBlock = pOperator - > pDownstream [ 0 ] - > exec ( pOperator - > pDownstream [ 0 ] , newgroup ) ;
publishOperatorProfEvent ( pOperator - > pDownstream [ 0 ] , QUERY_PROF_AFTER_OPERATOR_EXEC ) ;
2021-11-02 05:37:31 +00:00
if ( pBlock = = NULL ) {
assert ( * newgroup = = false ) ;
* newgroup = prevVal ;
2022-01-10 11:48:21 +00:00
setTaskStatus ( pOperator - > pTaskInfo , TASK_COMPLETED ) ;
2021-11-02 05:37:31 +00:00
break ;
}
// Return result of the previous group in the firstly.
if ( * newgroup ) {
if ( pRes - > info . rows > 0 ) {
pProjectInfo - > existDataBlock = pBlock ;
break ;
} else { // init output buffer for a new group data
// for (int32_t j = 0; j < pOperator->numOfOutput; ++j) {
// aAggs[pInfo->pCtx[j].functionId].xFinalize(&pInfo->pCtx[j]);
// }
initCtxOutputBuffer ( pInfo - > pCtx , pOperator - > numOfOutput ) ;
}
}
STableQueryInfo * pTableQueryInfo = pRuntimeEnv - > current ;
// todo dynamic set tags
if ( pTableQueryInfo ! = NULL ) {
setTagValue ( pOperator , pTableQueryInfo - > pTable , pInfo - > pCtx , pOperator - > numOfOutput ) ;
}
// the pDataBlock are always the same one, no need to call this again
setInputDataBlock ( pOperator , pInfo - > pCtx , pBlock , order ) ;
updateOutputBuf ( & pProjectInfo - > binfo , & pProjectInfo - > bufCapacity , pBlock - > info . rows ) ;
projectApplyFunctions ( pRuntimeEnv , pInfo - > pCtx , pOperator - > numOfOutput ) ;
pRes - > info . rows = getNumOfResult ( pInfo - > pCtx , pOperator - > numOfOutput ) ;
if ( pRes - > info . rows > = 1000 /*pRuntimeEnv->resultInfo.threshold*/ ) {
break ;
}
}
copyTsColoum ( pRes , pInfo - > pCtx , pOperator - > numOfOutput ) ;
resetResultRowEntryResult ( pInfo - > pCtx , pOperator - > numOfOutput ) ;
return ( pInfo - > pRes - > info . rows > 0 ) ? pInfo - > pRes : NULL ;
}
static SSDataBlock * doLimit ( void * param , bool * newgroup ) {
SOperatorInfo * pOperator = ( SOperatorInfo * ) param ;
if ( pOperator - > status = = OP_EXEC_DONE ) {
return NULL ;
}
SLimitOperatorInfo * pInfo = pOperator - > info ;
2022-01-08 08:28:44 +00:00
STaskRuntimeEnv * pRuntimeEnv = pOperator - > pRuntimeEnv ;
2021-11-02 05:37:31 +00:00
SSDataBlock * pBlock = NULL ;
while ( 1 ) {
2022-01-08 08:28:44 +00:00
publishOperatorProfEvent ( pOperator - > pDownstream [ 0 ] , QUERY_PROF_BEFORE_OPERATOR_EXEC ) ;
pBlock = pOperator - > pDownstream [ 0 ] - > exec ( pOperator - > pDownstream [ 0 ] , newgroup ) ;
publishOperatorProfEvent ( pOperator - > pDownstream [ 0 ] , QUERY_PROF_AFTER_OPERATOR_EXEC ) ;
2021-11-02 05:37:31 +00:00
if ( pBlock = = NULL ) {
doSetOperatorCompleted ( pOperator ) ;
return NULL ;
}
if ( pRuntimeEnv - > currentOffset = = 0 ) {
break ;
} else if ( pRuntimeEnv - > currentOffset > = pBlock - > info . rows ) {
pRuntimeEnv - > currentOffset - = pBlock - > info . rows ;
} else {
int32_t remain = ( int32_t ) ( pBlock - > info . rows - pRuntimeEnv - > currentOffset ) ;
pBlock - > info . rows = remain ;
for ( int32_t i = 0 ; i < pBlock - > info . numOfCols ; + + i ) {
SColumnInfoData * pColInfoData = taosArrayGet ( pBlock - > pDataBlock , i ) ;
int16_t bytes = pColInfoData - > info . bytes ;
memmove ( pColInfoData - > pData , pColInfoData - > pData + bytes * pRuntimeEnv - > currentOffset , remain * bytes ) ;
}
pRuntimeEnv - > currentOffset = 0 ;
break ;
}
}
if ( pInfo - > total + pBlock - > info . rows > = pInfo - > limit ) {
pBlock - > info . rows = ( int32_t ) ( pInfo - > limit - pInfo - > total ) ;
pInfo - > total = pInfo - > limit ;
doSetOperatorCompleted ( pOperator ) ;
} else {
pInfo - > total + = pBlock - > info . rows ;
}
return pBlock ;
}
static SSDataBlock * doFilter ( void * param , bool * newgroup ) {
SOperatorInfo * pOperator = ( SOperatorInfo * ) param ;
if ( pOperator - > status = = OP_EXEC_DONE ) {
return NULL ;
}
SFilterOperatorInfo * pCondInfo = pOperator - > info ;
2022-01-08 08:28:44 +00:00
STaskRuntimeEnv * pRuntimeEnv = pOperator - > pRuntimeEnv ;
2021-11-02 05:37:31 +00:00
while ( 1 ) {
2022-01-08 08:28:44 +00:00
publishOperatorProfEvent ( pOperator - > pDownstream [ 0 ] , QUERY_PROF_BEFORE_OPERATOR_EXEC ) ;
SSDataBlock * pBlock = pOperator - > pDownstream [ 0 ] - > exec ( pOperator - > pDownstream [ 0 ] , newgroup ) ;
publishOperatorProfEvent ( pOperator - > pDownstream [ 0 ] , QUERY_PROF_AFTER_OPERATOR_EXEC ) ;
2021-11-02 05:37:31 +00:00
if ( pBlock = = NULL ) {
break ;
}
doSetFilterColumnInfo ( pCondInfo - > pFilterInfo , pCondInfo - > numOfFilterCols , pBlock ) ;
assert ( pRuntimeEnv - > pTsBuf = = NULL ) ;
filterRowsInDataBlock ( pRuntimeEnv , pCondInfo - > pFilterInfo , pCondInfo - > numOfFilterCols , pBlock , true ) ;
if ( pBlock - > info . rows > 0 ) {
return pBlock ;
}
}
doSetOperatorCompleted ( pOperator ) ;
return NULL ;
}
static SSDataBlock * doIntervalAgg ( void * param , bool * newgroup ) {
SOperatorInfo * pOperator = ( SOperatorInfo * ) param ;
if ( pOperator - > status = = OP_EXEC_DONE ) {
return NULL ;
}
STableIntervalOperatorInfo * pIntervalInfo = pOperator - > info ;
2022-01-08 08:28:44 +00:00
STaskRuntimeEnv * pRuntimeEnv = pOperator - > pRuntimeEnv ;
2021-11-02 05:37:31 +00:00
if ( pOperator - > status = = OP_RES_TO_RETURN ) {
toSSDataBlock ( & pRuntimeEnv - > groupResInfo , pRuntimeEnv , pIntervalInfo - > pRes ) ;
if ( pIntervalInfo - > pRes - > info . rows = = 0 | | ! hasRemainDataInCurrentGroup ( & pRuntimeEnv - > groupResInfo ) ) {
doSetOperatorCompleted ( pOperator ) ;
}
return pIntervalInfo - > pRes ;
}
2022-01-08 08:28:44 +00:00
STaskAttr * pQueryAttr = pRuntimeEnv - > pQueryAttr ;
2021-11-02 05:37:31 +00:00
int32_t order = pQueryAttr - > order . order ;
STimeWindow win = pQueryAttr - > window ;
2022-01-08 14:59:24 +00:00
SOperatorInfo * downstream = pOperator - > pDownstream [ 0 ] ;
2021-11-02 05:37:31 +00:00
while ( 1 ) {
2022-01-08 14:59:24 +00:00
publishOperatorProfEvent ( downstream , QUERY_PROF_BEFORE_OPERATOR_EXEC ) ;
SSDataBlock * pBlock = downstream - > exec ( downstream , newgroup ) ;
publishOperatorProfEvent ( downstream , QUERY_PROF_AFTER_OPERATOR_EXEC ) ;
2021-11-02 05:37:31 +00:00
if ( pBlock = = NULL ) {
break ;
}
setTagValue ( pOperator , pRuntimeEnv - > current - > pTable , pIntervalInfo - > pCtx , pOperator - > numOfOutput ) ;
// the pDataBlock are always the same one, no need to call this again
setInputDataBlock ( pOperator , pIntervalInfo - > pCtx , pBlock , pQueryAttr - > order . order ) ;
hashIntervalAgg ( pOperator , & pIntervalInfo - > resultRowInfo , pBlock , 0 ) ;
}
// restore the value
pQueryAttr - > order . order = order ;
pQueryAttr - > window = win ;
pOperator - > status = OP_RES_TO_RETURN ;
closeAllResultRows ( & pIntervalInfo - > resultRowInfo ) ;
2022-01-10 11:48:21 +00:00
setTaskStatus ( pOperator - > pTaskInfo , TASK_COMPLETED ) ;
2021-11-02 05:37:31 +00:00
finalizeQueryResult ( pOperator , pIntervalInfo - > pCtx , & pIntervalInfo - > resultRowInfo , pIntervalInfo - > rowCellInfoOffset ) ;
initGroupResInfo ( & pRuntimeEnv - > groupResInfo , & pIntervalInfo - > resultRowInfo ) ;
toSSDataBlock ( & pRuntimeEnv - > groupResInfo , pRuntimeEnv , pIntervalInfo - > pRes ) ;
if ( pIntervalInfo - > pRes - > info . rows = = 0 | | ! hasRemainDataInCurrentGroup ( & pRuntimeEnv - > groupResInfo ) ) {
doSetOperatorCompleted ( pOperator ) ;
}
return pIntervalInfo - > pRes - > info . rows = = 0 ? NULL : pIntervalInfo - > pRes ;
}
static SSDataBlock * doAllIntervalAgg ( void * param , bool * newgroup ) {
SOperatorInfo * pOperator = ( SOperatorInfo * ) param ;
if ( pOperator - > status = = OP_EXEC_DONE ) {
return NULL ;
}
STableIntervalOperatorInfo * pIntervalInfo = pOperator - > info ;
2022-01-08 08:28:44 +00:00
STaskRuntimeEnv * pRuntimeEnv = pOperator - > pRuntimeEnv ;
2021-11-02 05:37:31 +00:00
if ( pOperator - > status = = OP_RES_TO_RETURN ) {
toSSDataBlock ( & pRuntimeEnv - > groupResInfo , pRuntimeEnv , pIntervalInfo - > pRes ) ;
if ( pIntervalInfo - > pRes - > info . rows = = 0 | | ! hasRemainDataInCurrentGroup ( & pRuntimeEnv - > groupResInfo ) ) {
doSetOperatorCompleted ( pOperator ) ;
}
return pIntervalInfo - > pRes ;
}
2022-01-08 08:28:44 +00:00
STaskAttr * pQueryAttr = pRuntimeEnv - > pQueryAttr ;
2021-11-02 05:37:31 +00:00
int32_t order = pQueryAttr - > order . order ;
STimeWindow win = pQueryAttr - > window ;
2022-01-08 14:59:24 +00:00
SOperatorInfo * downstream = pOperator - > pDownstream [ 0 ] ;
2021-11-02 05:37:31 +00:00
while ( 1 ) {
2022-01-08 14:59:24 +00:00
publishOperatorProfEvent ( downstream , QUERY_PROF_BEFORE_OPERATOR_EXEC ) ;
SSDataBlock * pBlock = downstream - > exec ( downstream , newgroup ) ;
publishOperatorProfEvent ( downstream , QUERY_PROF_AFTER_OPERATOR_EXEC ) ;
2021-11-02 05:37:31 +00:00
if ( pBlock = = NULL ) {
break ;
}
setTagValue ( pOperator , pRuntimeEnv - > current - > pTable , pIntervalInfo - > pCtx , pOperator - > numOfOutput ) ;
// the pDataBlock are always the same one, no need to call this again
setInputDataBlock ( pOperator , pIntervalInfo - > pCtx , pBlock , pQueryAttr - > order . order ) ;
hashAllIntervalAgg ( pOperator , & pIntervalInfo - > resultRowInfo , pBlock , 0 ) ;
}
// restore the value
pQueryAttr - > order . order = order ;
pQueryAttr - > window = win ;
pOperator - > status = OP_RES_TO_RETURN ;
closeAllResultRows ( & pIntervalInfo - > resultRowInfo ) ;
2022-01-10 11:48:21 +00:00
setTaskStatus ( pOperator - > pTaskInfo , TASK_COMPLETED ) ;
2021-11-02 05:37:31 +00:00
finalizeQueryResult ( pOperator , pIntervalInfo - > pCtx , & pIntervalInfo - > resultRowInfo , pIntervalInfo - > rowCellInfoOffset ) ;
initGroupResInfo ( & pRuntimeEnv - > groupResInfo , & pIntervalInfo - > resultRowInfo ) ;
toSSDataBlock ( & pRuntimeEnv - > groupResInfo , pRuntimeEnv , pIntervalInfo - > pRes ) ;
if ( pIntervalInfo - > pRes - > info . rows = = 0 | | ! hasRemainDataInCurrentGroup ( & pRuntimeEnv - > groupResInfo ) ) {
pOperator - > status = OP_EXEC_DONE ;
}
return pIntervalInfo - > pRes - > info . rows = = 0 ? NULL : pIntervalInfo - > pRes ;
}
static SSDataBlock * doSTableIntervalAgg ( void * param , bool * newgroup ) {
SOperatorInfo * pOperator = ( SOperatorInfo * ) param ;
if ( pOperator - > status = = OP_EXEC_DONE ) {
return NULL ;
}
STableIntervalOperatorInfo * pIntervalInfo = pOperator - > info ;
2022-01-08 08:28:44 +00:00
STaskRuntimeEnv * pRuntimeEnv = pOperator - > pRuntimeEnv ;
2021-11-02 05:37:31 +00:00
if ( pOperator - > status = = OP_RES_TO_RETURN ) {
int64_t st = taosGetTimestampUs ( ) ;
copyToSDataBlock ( pRuntimeEnv , 3000 , pIntervalInfo - > pRes , pIntervalInfo - > rowCellInfoOffset ) ;
if ( pIntervalInfo - > pRes - > info . rows = = 0 | | ! hasRemainData ( & pRuntimeEnv - > groupResInfo ) ) {
doSetOperatorCompleted ( pOperator ) ;
}
SQInfo * pQInfo = pRuntimeEnv - > qinfo ;
pQInfo - > summary . firstStageMergeTime + = ( taosGetTimestampUs ( ) - st ) ;
return pIntervalInfo - > pRes ;
}
2022-01-08 08:28:44 +00:00
STaskAttr * pQueryAttr = pRuntimeEnv - > pQueryAttr ;
2021-11-02 05:37:31 +00:00
int32_t order = pQueryAttr - > order . order ;
2022-01-08 14:59:24 +00:00
SOperatorInfo * downstream = pOperator - > pDownstream [ 0 ] ;
2021-11-02 05:37:31 +00:00
while ( 1 ) {
2022-01-08 14:59:24 +00:00
publishOperatorProfEvent ( downstream , QUERY_PROF_BEFORE_OPERATOR_EXEC ) ;
SSDataBlock * pBlock = downstream - > exec ( downstream , newgroup ) ;
publishOperatorProfEvent ( downstream , QUERY_PROF_AFTER_OPERATOR_EXEC ) ;
2021-11-02 05:37:31 +00:00
if ( pBlock = = NULL ) {
break ;
}
// the pDataBlock are always the same one, no need to call this again
STableQueryInfo * pTableQueryInfo = pRuntimeEnv - > current ;
setTagValue ( pOperator , pTableQueryInfo - > pTable , pIntervalInfo - > pCtx , pOperator - > numOfOutput ) ;
setInputDataBlock ( pOperator , pIntervalInfo - > pCtx , pBlock , pQueryAttr - > order . order ) ;
setIntervalQueryRange ( pRuntimeEnv , pBlock - > info . window . skey ) ;
hashIntervalAgg ( pOperator , & pTableQueryInfo - > resInfo , pBlock , pTableQueryInfo - > groupIndex ) ;
}
pOperator - > status = OP_RES_TO_RETURN ;
pQueryAttr - > order . order = order ; // TODO : restore the order
doCloseAllTimeWindow ( pRuntimeEnv ) ;
2022-01-10 11:48:21 +00:00
setTaskStatus ( pOperator - > pTaskInfo , TASK_COMPLETED ) ;
2021-11-02 05:37:31 +00:00
copyToSDataBlock ( pRuntimeEnv , 3000 , pIntervalInfo - > pRes , pIntervalInfo - > rowCellInfoOffset ) ;
if ( pIntervalInfo - > pRes - > info . rows = = 0 | | ! hasRemainData ( & pRuntimeEnv - > groupResInfo ) ) {
pOperator - > status = OP_EXEC_DONE ;
}
return pIntervalInfo - > pRes ;
}
static SSDataBlock * doAllSTableIntervalAgg ( void * param , bool * newgroup ) {
SOperatorInfo * pOperator = ( SOperatorInfo * ) param ;
if ( pOperator - > status = = OP_EXEC_DONE ) {
return NULL ;
}
STableIntervalOperatorInfo * pIntervalInfo = pOperator - > info ;
2022-01-08 08:28:44 +00:00
STaskRuntimeEnv * pRuntimeEnv = pOperator - > pRuntimeEnv ;
2021-11-02 05:37:31 +00:00
if ( pOperator - > status = = OP_RES_TO_RETURN ) {
copyToSDataBlock ( pRuntimeEnv , 3000 , pIntervalInfo - > pRes , pIntervalInfo - > rowCellInfoOffset ) ;
if ( pIntervalInfo - > pRes - > info . rows = = 0 | | ! hasRemainData ( & pRuntimeEnv - > groupResInfo ) ) {
pOperator - > status = OP_EXEC_DONE ;
}
return pIntervalInfo - > pRes ;
}
2022-01-08 08:28:44 +00:00
STaskAttr * pQueryAttr = pRuntimeEnv - > pQueryAttr ;
2021-11-02 05:37:31 +00:00
int32_t order = pQueryAttr - > order . order ;
2022-01-08 14:59:24 +00:00
SOperatorInfo * downstream = pOperator - > pDownstream [ 0 ] ;
2021-11-02 05:37:31 +00:00
while ( 1 ) {
2022-01-08 14:59:24 +00:00
publishOperatorProfEvent ( downstream , QUERY_PROF_BEFORE_OPERATOR_EXEC ) ;
SSDataBlock * pBlock = downstream - > exec ( downstream , newgroup ) ;
publishOperatorProfEvent ( downstream , QUERY_PROF_AFTER_OPERATOR_EXEC ) ;
2021-11-02 05:37:31 +00:00
if ( pBlock = = NULL ) {
break ;
}
// the pDataBlock are always the same one, no need to call this again
STableQueryInfo * pTableQueryInfo = pRuntimeEnv - > current ;
setTagValue ( pOperator , pTableQueryInfo - > pTable , pIntervalInfo - > pCtx , pOperator - > numOfOutput ) ;
setInputDataBlock ( pOperator , pIntervalInfo - > pCtx , pBlock , pQueryAttr - > order . order ) ;
setIntervalQueryRange ( pRuntimeEnv , pBlock - > info . window . skey ) ;
hashAllIntervalAgg ( pOperator , & pTableQueryInfo - > resInfo , pBlock , pTableQueryInfo - > groupIndex ) ;
}
pOperator - > status = OP_RES_TO_RETURN ;
pQueryAttr - > order . order = order ; // TODO : restore the order
doCloseAllTimeWindow ( pRuntimeEnv ) ;
2022-01-10 11:48:21 +00:00
setTaskStatus ( pOperator - > pTaskInfo , TASK_COMPLETED ) ;
2021-11-02 05:37:31 +00:00
int64_t st = taosGetTimestampUs ( ) ;
copyToSDataBlock ( pRuntimeEnv , 3000 , pIntervalInfo - > pRes , pIntervalInfo - > rowCellInfoOffset ) ;
if ( pIntervalInfo - > pRes - > info . rows = = 0 | | ! hasRemainData ( & pRuntimeEnv - > groupResInfo ) ) {
pOperator - > status = OP_EXEC_DONE ;
}
SQInfo * pQInfo = pRuntimeEnv - > qinfo ;
pQInfo - > summary . firstStageMergeTime + = ( taosGetTimestampUs ( ) - st ) ;
return pIntervalInfo - > pRes ;
}
static void doStateWindowAggImpl ( SOperatorInfo * pOperator , SStateWindowOperatorInfo * pInfo , SSDataBlock * pSDataBlock ) {
2022-01-08 08:28:44 +00:00
STaskRuntimeEnv * pRuntimeEnv = pOperator - > pRuntimeEnv ;
2021-11-02 05:37:31 +00:00
STableQueryInfo * item = pRuntimeEnv - > current ;
SColumnInfoData * pColInfoData = taosArrayGet ( pSDataBlock - > pDataBlock , pInfo - > colIndex ) ;
SOptrBasicInfo * pBInfo = & pInfo - > binfo ;
2022-01-08 14:59:24 +00:00
bool masterScan = IS_MAIN_SCAN ( pRuntimeEnv ) ;
2021-11-02 05:37:31 +00:00
int16_t bytes = pColInfoData - > info . bytes ;
int16_t type = pColInfoData - > info . type ;
SColumnInfoData * pTsColInfoData = taosArrayGet ( pSDataBlock - > pDataBlock , 0 ) ;
TSKEY * tsList = ( TSKEY * ) pTsColInfoData - > pData ;
if ( IS_REPEAT_SCAN ( pRuntimeEnv ) & & ! pInfo - > reptScan ) {
pInfo - > reptScan = true ;
tfree ( pInfo - > prevData ) ;
}
pInfo - > numOfRows = 0 ;
for ( int32_t j = 0 ; j < pSDataBlock - > info . rows ; + + j ) {
char * val = ( ( char * ) pColInfoData - > pData ) + bytes * j ;
if ( isNull ( val , type ) ) {
continue ;
}
if ( pInfo - > prevData = = NULL ) {
pInfo - > prevData = malloc ( bytes ) ;
memcpy ( pInfo - > prevData , val , bytes ) ;
pInfo - > numOfRows = 1 ;
pInfo - > curWindow . skey = tsList [ j ] ;
pInfo - > curWindow . ekey = tsList [ j ] ;
pInfo - > start = j ;
} else if ( memcmp ( pInfo - > prevData , val , bytes ) = = 0 ) {
pInfo - > curWindow . ekey = tsList [ j ] ;
pInfo - > numOfRows + = 1 ;
//pInfo->start = j;
if ( j = = 0 & & pInfo - > start ! = 0 ) {
pInfo - > numOfRows = 1 ;
pInfo - > start = 0 ;
}
} else {
SResultRow * pResult = NULL ;
pInfo - > curWindow . ekey = pInfo - > curWindow . skey ;
int32_t ret = setResultOutputBufByKey ( pRuntimeEnv , & pBInfo - > resultRowInfo , pSDataBlock - > info . uid , & pInfo - > curWindow , masterScan ,
& pResult , item - > groupIndex , pBInfo - > pCtx , pOperator - > numOfOutput ,
pBInfo - > rowCellInfoOffset ) ;
if ( ret ! = TSDB_CODE_SUCCESS ) { // null data, too many state code
longjmp ( pRuntimeEnv - > env , TSDB_CODE_QRY_APP_ERROR ) ;
}
doApplyFunctions ( pRuntimeEnv , pBInfo - > pCtx , & pInfo - > curWindow , pInfo - > start , pInfo - > numOfRows , tsList ,
pSDataBlock - > info . rows , pOperator - > numOfOutput ) ;
pInfo - > curWindow . skey = tsList [ j ] ;
pInfo - > curWindow . ekey = tsList [ j ] ;
memcpy ( pInfo - > prevData , val , bytes ) ;
pInfo - > numOfRows = 1 ;
pInfo - > start = j ;
}
}
SResultRow * pResult = NULL ;
pInfo - > curWindow . ekey = pInfo - > curWindow . skey ;
int32_t ret = setResultOutputBufByKey ( pRuntimeEnv , & pBInfo - > resultRowInfo , pSDataBlock - > info . uid , & pInfo - > curWindow , masterScan ,
& pResult , item - > groupIndex , pBInfo - > pCtx , pOperator - > numOfOutput ,
pBInfo - > rowCellInfoOffset ) ;
if ( ret ! = TSDB_CODE_SUCCESS ) { // null data, too many state code
longjmp ( pRuntimeEnv - > env , TSDB_CODE_QRY_APP_ERROR ) ;
}
doApplyFunctions ( pRuntimeEnv , pBInfo - > pCtx , & pInfo - > curWindow , pInfo - > start , pInfo - > numOfRows , tsList ,
pSDataBlock - > info . rows , pOperator - > numOfOutput ) ;
}
static SSDataBlock * doStateWindowAgg ( void * param , bool * newgroup ) {
SOperatorInfo * pOperator = ( SOperatorInfo * ) param ;
if ( pOperator - > status = = OP_EXEC_DONE ) {
return NULL ;
}
SStateWindowOperatorInfo * pWindowInfo = pOperator - > info ;
SOptrBasicInfo * pBInfo = & pWindowInfo - > binfo ;
2022-01-08 08:28:44 +00:00
STaskRuntimeEnv * pRuntimeEnv = pOperator - > pRuntimeEnv ;
2021-11-02 05:37:31 +00:00
if ( pOperator - > status = = OP_RES_TO_RETURN ) {
toSSDataBlock ( & pRuntimeEnv - > groupResInfo , pRuntimeEnv , pBInfo - > pRes ) ;
if ( pBInfo - > pRes - > info . rows = = 0 | | ! hasRemainDataInCurrentGroup ( & pRuntimeEnv - > groupResInfo ) ) {
pOperator - > status = OP_EXEC_DONE ;
}
return pBInfo - > pRes ;
}
2022-01-08 08:28:44 +00:00
STaskAttr * pQueryAttr = pRuntimeEnv - > pQueryAttr ;
2021-11-02 05:37:31 +00:00
int32_t order = pQueryAttr - > order . order ;
STimeWindow win = pQueryAttr - > window ;
2022-01-08 14:59:24 +00:00
SOperatorInfo * downstream = pOperator - > pDownstream [ 0 ] ;
2021-11-02 05:37:31 +00:00
while ( 1 ) {
2022-01-08 14:59:24 +00:00
publishOperatorProfEvent ( downstream , QUERY_PROF_BEFORE_OPERATOR_EXEC ) ;
SSDataBlock * pBlock = downstream - > exec ( downstream , newgroup ) ;
publishOperatorProfEvent ( downstream , QUERY_PROF_AFTER_OPERATOR_EXEC ) ;
2021-11-02 05:37:31 +00:00
if ( pBlock = = NULL ) {
break ;
}
setInputDataBlock ( pOperator , pBInfo - > pCtx , pBlock , pQueryAttr - > order . order ) ;
if ( pWindowInfo - > colIndex = = - 1 ) {
pWindowInfo - > colIndex = getGroupbyColumnIndex ( pRuntimeEnv - > pQueryAttr - > pGroupbyExpr , pBlock ) ;
}
doStateWindowAggImpl ( pOperator , pWindowInfo , pBlock ) ;
}
// restore the value
pQueryAttr - > order . order = order ;
pQueryAttr - > window = win ;
pOperator - > status = OP_RES_TO_RETURN ;
closeAllResultRows ( & pBInfo - > resultRowInfo ) ;
2022-01-10 11:48:21 +00:00
setTaskStatus ( pOperator - > pTaskInfo , TASK_COMPLETED ) ;
2021-11-02 05:37:31 +00:00
finalizeQueryResult ( pOperator , pBInfo - > pCtx , & pBInfo - > resultRowInfo , pBInfo - > rowCellInfoOffset ) ;
initGroupResInfo ( & pRuntimeEnv - > groupResInfo , & pBInfo - > resultRowInfo ) ;
toSSDataBlock ( & pRuntimeEnv - > groupResInfo , pRuntimeEnv , pBInfo - > pRes ) ;
if ( pBInfo - > pRes - > info . rows = = 0 | | ! hasRemainDataInCurrentGroup ( & pRuntimeEnv - > groupResInfo ) ) {
pOperator - > status = OP_EXEC_DONE ;
}
return pBInfo - > pRes - > info . rows = = 0 ? NULL : pBInfo - > pRes ;
}
static SSDataBlock * doSessionWindowAgg ( void * param , bool * newgroup ) {
SOperatorInfo * pOperator = ( SOperatorInfo * ) param ;
if ( pOperator - > status = = OP_EXEC_DONE ) {
return NULL ;
}
SSWindowOperatorInfo * pWindowInfo = pOperator - > info ;
SOptrBasicInfo * pBInfo = & pWindowInfo - > binfo ;
2022-01-08 08:28:44 +00:00
STaskRuntimeEnv * pRuntimeEnv = pOperator - > pRuntimeEnv ;
2021-11-02 05:37:31 +00:00
if ( pOperator - > status = = OP_RES_TO_RETURN ) {
toSSDataBlock ( & pRuntimeEnv - > groupResInfo , pRuntimeEnv , pBInfo - > pRes ) ;
if ( pBInfo - > pRes - > info . rows = = 0 | | ! hasRemainDataInCurrentGroup ( & pRuntimeEnv - > groupResInfo ) ) {
pOperator - > status = OP_EXEC_DONE ;
}
return pBInfo - > pRes ;
}
2022-01-08 08:28:44 +00:00
STaskAttr * pQueryAttr = pRuntimeEnv - > pQueryAttr ;
2021-11-02 05:37:31 +00:00
//pQueryAttr->order.order = TSDB_ORDER_ASC;
int32_t order = pQueryAttr - > order . order ;
STimeWindow win = pQueryAttr - > window ;
2022-01-08 14:59:24 +00:00
SOperatorInfo * downstream = pOperator - > pDownstream [ 0 ] ;
2021-11-02 05:37:31 +00:00
while ( 1 ) {
2022-01-08 14:59:24 +00:00
publishOperatorProfEvent ( downstream , QUERY_PROF_BEFORE_OPERATOR_EXEC ) ;
SSDataBlock * pBlock = downstream - > exec ( downstream , newgroup ) ;
publishOperatorProfEvent ( downstream , QUERY_PROF_AFTER_OPERATOR_EXEC ) ;
2021-11-02 05:37:31 +00:00
if ( pBlock = = NULL ) {
break ;
}
// the pDataBlock are always the same one, no need to call this again
setInputDataBlock ( pOperator , pBInfo - > pCtx , pBlock , pQueryAttr - > order . order ) ;
doSessionWindowAggImpl ( pOperator , pWindowInfo , pBlock ) ;
}
// restore the value
pQueryAttr - > order . order = order ;
pQueryAttr - > window = win ;
pOperator - > status = OP_RES_TO_RETURN ;
closeAllResultRows ( & pBInfo - > resultRowInfo ) ;
2022-01-08 14:59:24 +00:00
// setTaskStatus(pOperator->pTaskInfo, QUERY_COMPLETED);
2021-11-02 05:37:31 +00:00
finalizeQueryResult ( pOperator , pBInfo - > pCtx , & pBInfo - > resultRowInfo , pBInfo - > rowCellInfoOffset ) ;
initGroupResInfo ( & pRuntimeEnv - > groupResInfo , & pBInfo - > resultRowInfo ) ;
toSSDataBlock ( & pRuntimeEnv - > groupResInfo , pRuntimeEnv , pBInfo - > pRes ) ;
if ( pBInfo - > pRes - > info . rows = = 0 | | ! hasRemainDataInCurrentGroup ( & pRuntimeEnv - > groupResInfo ) ) {
pOperator - > status = OP_EXEC_DONE ;
}
return pBInfo - > pRes - > info . rows = = 0 ? NULL : pBInfo - > pRes ;
}
static SSDataBlock * hashGroupbyAggregate ( void * param , bool * newgroup ) {
SOperatorInfo * pOperator = ( SOperatorInfo * ) param ;
if ( pOperator - > status = = OP_EXEC_DONE ) {
return NULL ;
}
SGroupbyOperatorInfo * pInfo = pOperator - > info ;
2022-01-08 08:28:44 +00:00
STaskRuntimeEnv * pRuntimeEnv = pOperator - > pRuntimeEnv ;
2021-11-02 05:37:31 +00:00
if ( pOperator - > status = = OP_RES_TO_RETURN ) {
toSSDataBlock ( & pRuntimeEnv - > groupResInfo , pRuntimeEnv , pInfo - > binfo . pRes ) ;
if ( pInfo - > binfo . pRes - > info . rows = = 0 | | ! hasRemainDataInCurrentGroup ( & pRuntimeEnv - > groupResInfo ) ) {
pOperator - > status = OP_EXEC_DONE ;
}
return pInfo - > binfo . pRes ;
}
2022-01-08 14:59:24 +00:00
SOperatorInfo * downstream = pOperator - > pDownstream [ 0 ] ;
2021-11-02 05:37:31 +00:00
while ( 1 ) {
2022-01-08 14:59:24 +00:00
publishOperatorProfEvent ( downstream , QUERY_PROF_BEFORE_OPERATOR_EXEC ) ;
SSDataBlock * pBlock = downstream - > exec ( downstream , newgroup ) ;
publishOperatorProfEvent ( downstream , QUERY_PROF_AFTER_OPERATOR_EXEC ) ;
2021-11-02 05:37:31 +00:00
if ( pBlock = = NULL ) {
break ;
}
// the pDataBlock are always the same one, no need to call this again
setInputDataBlock ( pOperator , pInfo - > binfo . pCtx , pBlock , pRuntimeEnv - > pQueryAttr - > order . order ) ;
setTagValue ( pOperator , pRuntimeEnv - > current - > pTable , pInfo - > binfo . pCtx , pOperator - > numOfOutput ) ;
if ( pInfo - > colIndex = = - 1 ) {
pInfo - > colIndex = getGroupbyColumnIndex ( pRuntimeEnv - > pQueryAttr - > pGroupbyExpr , pBlock ) ;
}
doHashGroupbyAgg ( pOperator , pInfo , pBlock ) ;
}
pOperator - > status = OP_RES_TO_RETURN ;
closeAllResultRows ( & pInfo - > binfo . resultRowInfo ) ;
2022-01-08 14:59:24 +00:00
// setTaskStatus(pOperator->pTaskInfo, QUERY_COMPLETED);
2021-11-02 05:37:31 +00:00
if ( ! pRuntimeEnv - > pQueryAttr - > stableQuery ) { // finalize include the update of result rows
finalizeQueryResult ( pOperator , pInfo - > binfo . pCtx , & pInfo - > binfo . resultRowInfo , pInfo - > binfo . rowCellInfoOffset ) ;
} else {
updateNumOfRowsInResultRows ( pRuntimeEnv , pInfo - > binfo . pCtx , pOperator - > numOfOutput , & pInfo - > binfo . resultRowInfo , pInfo - > binfo . rowCellInfoOffset ) ;
}
initGroupResInfo ( & pRuntimeEnv - > groupResInfo , & pInfo - > binfo . resultRowInfo ) ;
if ( ! pRuntimeEnv - > pQueryAttr - > stableQuery ) {
sortGroupResByOrderList ( & pRuntimeEnv - > groupResInfo , pRuntimeEnv , pInfo - > binfo . pRes ) ;
}
toSSDataBlock ( & pRuntimeEnv - > groupResInfo , pRuntimeEnv , pInfo - > binfo . pRes ) ;
if ( pInfo - > binfo . pRes - > info . rows = = 0 | | ! hasRemainDataInCurrentGroup ( & pRuntimeEnv - > groupResInfo ) ) {
pOperator - > status = OP_EXEC_DONE ;
}
return pInfo - > binfo . pRes ;
}
2022-01-08 08:28:44 +00:00
static void doHandleRemainBlockForNewGroupImpl ( SFillOperatorInfo * pInfo , STaskRuntimeEnv * pRuntimeEnv , bool * newgroup ) {
2021-11-02 05:37:31 +00:00
pInfo - > totalInputRows = pInfo - > existNewGroupBlock - > info . rows ;
2022-01-10 11:48:21 +00:00
int64_t ekey = Q_STATUS_EQUAL ( pRuntimeEnv - > status , TASK_COMPLETED ) ? pRuntimeEnv - > pQueryAttr - > window . ekey : pInfo - > existNewGroupBlock - > info . window . ekey ;
2021-11-02 05:37:31 +00:00
taosResetFillInfo ( pInfo - > pFillInfo , getFillInfoStart ( pInfo - > pFillInfo ) ) ;
taosFillSetStartInfo ( pInfo - > pFillInfo , pInfo - > existNewGroupBlock - > info . rows , ekey ) ;
taosFillSetInputDataBlock ( pInfo - > pFillInfo , pInfo - > existNewGroupBlock ) ;
doFillTimeIntervalGapsInResults ( pInfo - > pFillInfo , pInfo - > pRes , pRuntimeEnv - > resultInfo . capacity , pInfo - > p ) ;
pInfo - > existNewGroupBlock = NULL ;
* newgroup = true ;
}
2022-01-08 08:28:44 +00:00
static void doHandleRemainBlockFromNewGroup ( SFillOperatorInfo * pInfo , STaskRuntimeEnv * pRuntimeEnv , bool * newgroup ) {
2021-11-02 05:37:31 +00:00
if ( taosFillHasMoreResults ( pInfo - > pFillInfo ) ) {
* newgroup = false ;
doFillTimeIntervalGapsInResults ( pInfo - > pFillInfo , pInfo - > pRes , ( int32_t ) pRuntimeEnv - > resultInfo . capacity , pInfo - > p ) ;
if ( pInfo - > pRes - > info . rows > pRuntimeEnv - > resultInfo . threshold | | ( ! pInfo - > multigroupResult ) ) {
return ;
}
}
// handle the cached new group data block
if ( pInfo - > existNewGroupBlock ) {
doHandleRemainBlockForNewGroupImpl ( pInfo , pRuntimeEnv , newgroup ) ;
}
}
static SSDataBlock * doFill ( void * param , bool * newgroup ) {
SOperatorInfo * pOperator = ( SOperatorInfo * ) param ;
SFillOperatorInfo * pInfo = pOperator - > info ;
pInfo - > pRes - > info . rows = 0 ;
if ( pOperator - > status = = OP_EXEC_DONE ) {
return NULL ;
}
2022-01-08 08:28:44 +00:00
STaskRuntimeEnv * pRuntimeEnv = pOperator - > pRuntimeEnv ;
2021-11-02 05:37:31 +00:00
doHandleRemainBlockFromNewGroup ( pInfo , pRuntimeEnv , newgroup ) ;
if ( pInfo - > pRes - > info . rows > pRuntimeEnv - > resultInfo . threshold | | ( ! pInfo - > multigroupResult & & pInfo - > pRes - > info . rows > 0 ) ) {
return pInfo - > pRes ;
}
while ( 1 ) {
2022-01-08 08:28:44 +00:00
publishOperatorProfEvent ( pOperator - > pDownstream [ 0 ] , QUERY_PROF_BEFORE_OPERATOR_EXEC ) ;
SSDataBlock * pBlock = pOperator - > pDownstream [ 0 ] - > exec ( pOperator - > pDownstream [ 0 ] , newgroup ) ;
publishOperatorProfEvent ( pOperator - > pDownstream [ 0 ] , QUERY_PROF_AFTER_OPERATOR_EXEC ) ;
2021-11-02 05:37:31 +00:00
if ( * newgroup ) {
assert ( pBlock ! = NULL ) ;
}
if ( * newgroup & & pInfo - > totalInputRows > 0 ) { // there are already processed current group data block
pInfo - > existNewGroupBlock = pBlock ;
* newgroup = false ;
// Fill the previous group data block, before handle the data block of new group.
// Close the fill operation for previous group data block
taosFillSetStartInfo ( pInfo - > pFillInfo , 0 , pRuntimeEnv - > pQueryAttr - > window . ekey ) ;
} else {
if ( pBlock = = NULL ) {
if ( pInfo - > totalInputRows = = 0 ) {
pOperator - > status = OP_EXEC_DONE ;
return NULL ;
}
taosFillSetStartInfo ( pInfo - > pFillInfo , 0 , pRuntimeEnv - > pQueryAttr - > window . ekey ) ;
} else {
pInfo - > totalInputRows + = pBlock - > info . rows ;
taosFillSetStartInfo ( pInfo - > pFillInfo , pBlock - > info . rows , pBlock - > info . window . ekey ) ;
taosFillSetInputDataBlock ( pInfo - > pFillInfo , pBlock ) ;
}
}
doFillTimeIntervalGapsInResults ( pInfo - > pFillInfo , pInfo - > pRes , pRuntimeEnv - > resultInfo . capacity , pInfo - > p ) ;
// current group has no more result to return
if ( pInfo - > pRes - > info . rows > 0 ) {
// 1. The result in current group not reach the threshold of output result, continue
// 2. If multiple group results existing in one SSDataBlock is not allowed, return immediately
if ( pInfo - > pRes - > info . rows > pRuntimeEnv - > resultInfo . threshold | | pBlock = = NULL | | ( ! pInfo - > multigroupResult ) ) {
return pInfo - > pRes ;
}
doHandleRemainBlockFromNewGroup ( pInfo , pRuntimeEnv , newgroup ) ;
if ( pInfo - > pRes - > info . rows > pRuntimeEnv - > resultInfo . threshold | | pBlock = = NULL ) {
return pInfo - > pRes ;
}
} else if ( pInfo - > existNewGroupBlock ) { // try next group
assert ( pBlock ! = NULL ) ;
doHandleRemainBlockForNewGroupImpl ( pInfo , pRuntimeEnv , newgroup ) ;
if ( pInfo - > pRes - > info . rows > pRuntimeEnv - > resultInfo . threshold ) {
return pInfo - > pRes ;
}
} else {
return NULL ;
}
}
}
// todo set the attribute of query scan count
2022-01-08 08:28:44 +00:00
static int32_t getNumOfScanTimes ( STaskAttr * pQueryAttr ) {
2021-11-02 05:37:31 +00:00
for ( int32_t i = 0 ; i < pQueryAttr - > numOfOutput ; + + i ) {
int32_t functionId = getExprFunctionId ( & pQueryAttr - > pExpr1 [ i ] ) ;
if ( functionId = = FUNCTION_STDDEV | | functionId = = FUNCTION_PERCT ) {
return 2 ;
}
}
return 1 ;
}
static void destroyOperatorInfo ( SOperatorInfo * pOperator ) {
if ( pOperator = = NULL ) {
return ;
}
2022-01-28 02:44:02 +00:00
if ( pOperator - > cleanupFn ! = NULL ) {
pOperator - > cleanupFn ( pOperator - > info , pOperator - > numOfOutput ) ;
2021-11-02 05:37:31 +00:00
}
2022-01-08 08:28:44 +00:00
if ( pOperator - > pDownstream ! = NULL ) {
2022-01-08 14:59:24 +00:00
for ( int32_t i = 0 ; i < pOperator - > numOfDownstream ; + + i ) {
2022-01-08 08:28:44 +00:00
destroyOperatorInfo ( pOperator - > pDownstream [ i ] ) ;
2021-11-02 05:37:31 +00:00
}
2022-01-08 08:28:44 +00:00
tfree ( pOperator - > pDownstream ) ;
2022-01-08 14:59:24 +00:00
pOperator - > numOfDownstream = 0 ;
2021-11-02 05:37:31 +00:00
}
tfree ( pOperator - > info ) ;
tfree ( pOperator ) ;
}
2022-01-20 05:52:46 +00:00
SOperatorInfo * createAggregateOperatorInfo ( SOperatorInfo * downstream , SArray * pExprInfo , SExecTaskInfo * pTaskInfo ) {
2021-11-02 05:37:31 +00:00
SAggOperatorInfo * pInfo = calloc ( 1 , sizeof ( SAggOperatorInfo ) ) ;
2022-01-14 02:20:55 +00:00
int32_t numOfRows = 1 ; //(int32_t)(getRowNumForMultioutput(pQueryAttr, pQueryAttr->topBotQuery, pQueryAttr->stableQuery));
2021-11-02 05:37:31 +00:00
2022-01-20 05:52:46 +00:00
size_t numOfOutput = taosArrayGetSize ( pExprInfo ) ;
pInfo - > binfo . pRes = createOutputBuf_rv ( pExprInfo , numOfRows ) ;
pInfo - > binfo . pCtx = createSqlFunctionCtx_rv ( pExprInfo , & pInfo - > binfo . rowCellInfoOffset ) ;
pInfo - > pResultRowHashTable = taosHashInit ( 10 , taosGetDefaultHashFunction ( TSDB_DATA_TYPE_BINARY ) , true , HASH_NO_LOCK ) ;
pInfo - > pResultRowListSet = taosHashInit ( 100 , taosGetDefaultHashFunction ( TSDB_DATA_TYPE_BINARY ) , false , HASH_NO_LOCK ) ;
2022-01-20 08:02:09 +00:00
pInfo - > keyBuf = malloc ( 1024 + sizeof ( int64_t ) + POINTER_BYTES ) ; // TODO:
2022-01-20 05:52:46 +00:00
pInfo - > pool = initResultRowPool ( getResultRowSize ( pExprInfo ) ) ;
pInfo - > pResultRowArrayList = taosArrayInit ( 10 , sizeof ( SResultRowCell ) ) ;
2021-11-02 05:37:31 +00:00
initResultRowInfo ( & pInfo - > binfo . resultRowInfo , 8 , TSDB_DATA_TYPE_INT ) ;
pInfo - > seed = rand ( ) ;
2022-01-20 05:52:46 +00:00
setDefaultOutputBuf_rv ( pInfo , pInfo - > seed , MAIN_SCAN , pTaskInfo ) ;
SExprInfo * p = calloc ( numOfOutput , sizeof ( SExprInfo ) ) ;
for ( int32_t i = 0 ; i < taosArrayGetSize ( pExprInfo ) ; + + i ) {
2022-01-20 09:10:28 +00:00
SExprInfo * pExpr = taosArrayGetP ( pExprInfo , i ) ;
assignExprInfo ( & p [ i ] , pExpr ) ;
2022-01-20 05:52:46 +00:00
}
2021-11-02 05:37:31 +00:00
SOperatorInfo * pOperator = calloc ( 1 , sizeof ( SOperatorInfo ) ) ;
pOperator - > name = " TableAggregate " ;
2022-01-14 02:20:55 +00:00
pOperator - > operatorType = OP_Aggregate ;
2021-11-02 05:37:31 +00:00
pOperator - > blockingOptr = true ;
pOperator - > status = OP_IN_EXECUTING ;
pOperator - > info = pInfo ;
2022-01-20 05:52:46 +00:00
pOperator - > pExpr = p ;
2021-11-02 05:37:31 +00:00
pOperator - > numOfOutput = numOfOutput ;
2022-01-14 02:20:55 +00:00
pOperator - > pRuntimeEnv = NULL ;
2021-11-02 05:37:31 +00:00
2022-01-20 05:52:46 +00:00
pOperator - > pTaskInfo = pTaskInfo ;
2021-11-02 05:37:31 +00:00
pOperator - > exec = doAggregate ;
2022-01-28 02:44:02 +00:00
pOperator - > cleanupFn = destroyAggOperatorInfo ;
2022-01-14 02:20:55 +00:00
appendDownstream ( pOperator , downstream ) ;
2021-11-02 05:37:31 +00:00
return pOperator ;
}
static void doDestroyBasicInfo ( SOptrBasicInfo * pInfo , int32_t numOfOutput ) {
assert ( pInfo ! = NULL ) ;
destroySQLFunctionCtx ( pInfo - > pCtx , numOfOutput ) ;
tfree ( pInfo - > rowCellInfoOffset ) ;
cleanupResultRowInfo ( & pInfo - > resultRowInfo ) ;
2022-02-08 10:01:21 +00:00
pInfo - > pRes = blockDataDestroy ( pInfo - > pRes ) ;
2021-11-02 05:37:31 +00:00
}
static void destroyBasicOperatorInfo ( void * param , int32_t numOfOutput ) {
SOptrBasicInfo * pInfo = ( SOptrBasicInfo * ) param ;
doDestroyBasicInfo ( pInfo , numOfOutput ) ;
}
static void destroyStateWindowOperatorInfo ( void * param , int32_t numOfOutput ) {
SStateWindowOperatorInfo * pInfo = ( SStateWindowOperatorInfo * ) param ;
doDestroyBasicInfo ( & pInfo - > binfo , numOfOutput ) ;
tfree ( pInfo - > prevData ) ;
}
static void destroyAggOperatorInfo ( void * param , int32_t numOfOutput ) {
SAggOperatorInfo * pInfo = ( SAggOperatorInfo * ) param ;
doDestroyBasicInfo ( & pInfo - > binfo , numOfOutput ) ;
}
static void destroySWindowOperatorInfo ( void * param , int32_t numOfOutput ) {
SSWindowOperatorInfo * pInfo = ( SSWindowOperatorInfo * ) param ;
doDestroyBasicInfo ( & pInfo - > binfo , numOfOutput ) ;
}
static void destroySFillOperatorInfo ( void * param , int32_t numOfOutput ) {
SFillOperatorInfo * pInfo = ( SFillOperatorInfo * ) param ;
pInfo - > pFillInfo = taosDestroyFillInfo ( pInfo - > pFillInfo ) ;
2022-02-08 10:01:21 +00:00
pInfo - > pRes = blockDataDestroy ( pInfo - > pRes ) ;
2021-11-02 05:37:31 +00:00
tfree ( pInfo - > p ) ;
}
static void destroyGroupbyOperatorInfo ( void * param , int32_t numOfOutput ) {
SGroupbyOperatorInfo * pInfo = ( SGroupbyOperatorInfo * ) param ;
doDestroyBasicInfo ( & pInfo - > binfo , numOfOutput ) ;
tfree ( pInfo - > prevData ) ;
}
static void destroyProjectOperatorInfo ( void * param , int32_t numOfOutput ) {
SProjectOperatorInfo * pInfo = ( SProjectOperatorInfo * ) param ;
doDestroyBasicInfo ( & pInfo - > binfo , numOfOutput ) ;
}
static void destroyTagScanOperatorInfo ( void * param , int32_t numOfOutput ) {
STagScanInfo * pInfo = ( STagScanInfo * ) param ;
2022-02-08 10:01:21 +00:00
pInfo - > pRes = blockDataDestroy ( pInfo - > pRes ) ;
2021-11-02 05:37:31 +00:00
}
static void destroyOrderOperatorInfo ( void * param , int32_t numOfOutput ) {
SOrderOperatorInfo * pInfo = ( SOrderOperatorInfo * ) param ;
2022-02-08 10:01:21 +00:00
pInfo - > pDataBlock = blockDataDestroy ( pInfo - > pDataBlock ) ;
taosArrayDestroy ( pInfo - > cmpParam . orderInfo ) ;
destroyResultBuf ( pInfo - > pSortInternalBuf ) ;
tMergeTreeDestroy ( pInfo - > pMergeTree ) ;
2021-11-02 05:37:31 +00:00
}
static void destroyConditionOperatorInfo ( void * param , int32_t numOfOutput ) {
SFilterOperatorInfo * pInfo = ( SFilterOperatorInfo * ) param ;
doDestroyFilterInfo ( pInfo - > pFilterInfo , pInfo - > numOfFilterCols ) ;
}
static void destroyDistinctOperatorInfo ( void * param , int32_t numOfOutput ) {
SDistinctOperatorInfo * pInfo = ( SDistinctOperatorInfo * ) param ;
taosHashCleanup ( pInfo - > pSet ) ;
tfree ( pInfo - > buf ) ;
taosArrayDestroy ( pInfo - > pDistinctDataInfo ) ;
2022-02-08 10:01:21 +00:00
pInfo - > pRes = blockDataDestroy ( pInfo - > pRes ) ;
2021-11-02 05:37:31 +00:00
}
2022-01-08 14:59:24 +00:00
SOperatorInfo * createMultiTableAggOperatorInfo ( STaskRuntimeEnv * pRuntimeEnv , SOperatorInfo * downstream , SExprInfo * pExpr , int32_t numOfOutput ) {
2021-11-02 05:37:31 +00:00
SAggOperatorInfo * pInfo = calloc ( 1 , sizeof ( SAggOperatorInfo ) ) ;
size_t tableGroup = GET_NUM_OF_TABLEGROUP ( pRuntimeEnv ) ;
pInfo - > binfo . pRes = createOutputBuf ( pExpr , numOfOutput , ( int32_t ) tableGroup ) ;
2022-01-14 02:20:55 +00:00
pInfo - > binfo . pCtx = createSqlFunctionCtx ( pRuntimeEnv , pExpr , numOfOutput , & pInfo - > binfo . rowCellInfoOffset ) ;
2021-11-02 05:37:31 +00:00
initResultRowInfo ( & pInfo - > binfo . resultRowInfo , ( int32_t ) tableGroup , TSDB_DATA_TYPE_INT ) ;
SOperatorInfo * pOperator = calloc ( 1 , sizeof ( SOperatorInfo ) ) ;
pOperator - > name = " MultiTableAggregate " ;
2021-12-06 06:44:27 +00:00
// pOperator->operatorType = OP_MultiTableAggregate;
2021-11-02 05:37:31 +00:00
pOperator - > blockingOptr = true ;
pOperator - > status = OP_IN_EXECUTING ;
pOperator - > info = pInfo ;
pOperator - > pExpr = pExpr ;
pOperator - > numOfOutput = numOfOutput ;
pOperator - > pRuntimeEnv = pRuntimeEnv ;
pOperator - > exec = doSTableAggregate ;
2022-01-28 02:44:02 +00:00
pOperator - > cleanupFn = destroyAggOperatorInfo ;
2022-01-14 02:20:55 +00:00
appendDownstream ( pOperator , downstream ) ;
2021-11-02 05:37:31 +00:00
return pOperator ;
}
2022-01-08 14:59:24 +00:00
SOperatorInfo * createProjectOperatorInfo ( STaskRuntimeEnv * pRuntimeEnv , SOperatorInfo * downstream , SExprInfo * pExpr , int32_t numOfOutput ) {
2021-11-02 05:37:31 +00:00
SProjectOperatorInfo * pInfo = calloc ( 1 , sizeof ( SProjectOperatorInfo ) ) ;
pInfo - > seed = rand ( ) ;
pInfo - > bufCapacity = pRuntimeEnv - > resultInfo . capacity ;
SOptrBasicInfo * pBInfo = & pInfo - > binfo ;
pBInfo - > pRes = createOutputBuf ( pExpr , numOfOutput , pInfo - > bufCapacity ) ;
2022-01-14 02:20:55 +00:00
pBInfo - > pCtx = createSqlFunctionCtx ( pRuntimeEnv , pExpr , numOfOutput , & pBInfo - > rowCellInfoOffset ) ;
2021-11-02 05:37:31 +00:00
initResultRowInfo ( & pBInfo - > resultRowInfo , 8 , TSDB_DATA_TYPE_INT ) ;
2022-01-08 14:59:24 +00:00
setDefaultOutputBuf ( pRuntimeEnv , pBInfo , pInfo - > seed , MAIN_SCAN ) ;
2021-11-02 05:37:31 +00:00
SOperatorInfo * pOperator = calloc ( 1 , sizeof ( SOperatorInfo ) ) ;
pOperator - > name = " ProjectOperator " ;
2021-12-06 06:44:27 +00:00
// pOperator->operatorType = OP_Project;
2021-11-02 05:37:31 +00:00
pOperator - > blockingOptr = false ;
pOperator - > status = OP_IN_EXECUTING ;
pOperator - > info = pInfo ;
pOperator - > pExpr = pExpr ;
pOperator - > numOfOutput = numOfOutput ;
pOperator - > pRuntimeEnv = pRuntimeEnv ;
pOperator - > exec = doProjectOperation ;
2022-01-28 02:44:02 +00:00
pOperator - > cleanupFn = destroyProjectOperatorInfo ;
2022-01-14 02:20:55 +00:00
appendDownstream ( pOperator , downstream ) ;
2021-11-02 05:37:31 +00:00
return pOperator ;
}
SColumnInfo * extractColumnFilterInfo ( SExprInfo * pExpr , int32_t numOfOutput , int32_t * numOfFilterCols ) {
#if 0
SColumnInfo * pCols = calloc ( numOfOutput , sizeof ( SColumnInfo ) ) ;
int32_t numOfFilter = 0 ;
for ( int32_t i = 0 ; i < numOfOutput ; + + i ) {
if ( pExpr [ i ] . base . flist . numOfFilters > 0 ) {
numOfFilter + = 1 ;
}
pCols [ i ] . type = pExpr [ i ] . base . resSchema . type ;
pCols [ i ] . bytes = pExpr [ i ] . base . resSchema . bytes ;
pCols [ i ] . colId = pExpr [ i ] . base . resSchema . colId ;
pCols [ i ] . flist . numOfFilters = pExpr [ i ] . base . flist . numOfFilters ;
if ( pCols [ i ] . flist . numOfFilters ! = 0 ) {
pCols [ i ] . flist . filterInfo = calloc ( pCols [ i ] . flist . numOfFilters , sizeof ( SColumnFilterInfo ) ) ;
memcpy ( pCols [ i ] . flist . filterInfo , pExpr [ i ] . base . flist . filterInfo , pCols [ i ] . flist . numOfFilters * sizeof ( SColumnFilterInfo ) ) ;
} else {
// avoid runtime error
pCols [ i ] . flist . filterInfo = NULL ;
}
}
assert ( numOfFilter > 0 ) ;
* numOfFilterCols = numOfFilter ;
return pCols ;
# endif
return 0 ;
}
2022-01-08 14:59:24 +00:00
SOperatorInfo * createFilterOperatorInfo ( STaskRuntimeEnv * pRuntimeEnv , SOperatorInfo * downstream , SExprInfo * pExpr ,
2021-11-02 05:37:31 +00:00
int32_t numOfOutput , SColumnInfo * pCols , int32_t numOfFilter ) {
SFilterOperatorInfo * pInfo = calloc ( 1 , sizeof ( SFilterOperatorInfo ) ) ;
assert ( numOfFilter > 0 & & pCols ! = NULL ) ;
2022-01-10 11:48:21 +00:00
// doCreateFilterInfo(pCols, numOfOutput, numOfFilter, &pInfo->pFilterInfo, 0);
2021-11-02 05:37:31 +00:00
pInfo - > numOfFilterCols = numOfFilter ;
SOperatorInfo * pOperator = calloc ( 1 , sizeof ( SOperatorInfo ) ) ;
pOperator - > name = " FilterOperator " ;
2021-12-06 06:44:27 +00:00
// pOperator->operatorType = OP_Filter;
2021-11-02 05:37:31 +00:00
pOperator - > blockingOptr = false ;
pOperator - > status = OP_IN_EXECUTING ;
pOperator - > numOfOutput = numOfOutput ;
pOperator - > pExpr = pExpr ;
pOperator - > exec = doFilter ;
pOperator - > info = pInfo ;
pOperator - > pRuntimeEnv = pRuntimeEnv ;
2022-01-28 02:44:02 +00:00
pOperator - > cleanupFn = destroyConditionOperatorInfo ;
2022-01-14 02:20:55 +00:00
appendDownstream ( pOperator , downstream ) ;
2021-11-02 05:37:31 +00:00
return pOperator ;
}
2022-01-08 14:59:24 +00:00
SOperatorInfo * createLimitOperatorInfo ( STaskRuntimeEnv * pRuntimeEnv , SOperatorInfo * downstream ) {
2021-11-02 05:37:31 +00:00
SLimitOperatorInfo * pInfo = calloc ( 1 , sizeof ( SLimitOperatorInfo ) ) ;
pInfo - > limit = pRuntimeEnv - > pQueryAttr - > limit . limit ;
SOperatorInfo * pOperator = calloc ( 1 , sizeof ( SOperatorInfo ) ) ;
pOperator - > name = " LimitOperator " ;
2021-12-06 06:44:27 +00:00
// pOperator->operatorType = OP_Limit;
2021-11-02 05:37:31 +00:00
pOperator - > blockingOptr = false ;
pOperator - > status = OP_IN_EXECUTING ;
pOperator - > exec = doLimit ;
pOperator - > info = pInfo ;
pOperator - > pRuntimeEnv = pRuntimeEnv ;
2022-01-14 02:20:55 +00:00
appendDownstream ( pOperator , downstream ) ;
2021-11-02 05:37:31 +00:00
return pOperator ;
}
2022-01-08 14:59:24 +00:00
SOperatorInfo * createTimeIntervalOperatorInfo ( STaskRuntimeEnv * pRuntimeEnv , SOperatorInfo * downstream , SExprInfo * pExpr , int32_t numOfOutput ) {
2021-11-02 05:37:31 +00:00
STableIntervalOperatorInfo * pInfo = calloc ( 1 , sizeof ( STableIntervalOperatorInfo ) ) ;
2022-01-14 02:20:55 +00:00
pInfo - > pCtx = createSqlFunctionCtx ( pRuntimeEnv , pExpr , numOfOutput , & pInfo - > rowCellInfoOffset ) ;
2021-11-02 05:37:31 +00:00
pInfo - > pRes = createOutputBuf ( pExpr , numOfOutput , pRuntimeEnv - > resultInfo . capacity ) ;
initResultRowInfo ( & pInfo - > resultRowInfo , 8 , TSDB_DATA_TYPE_INT ) ;
SOperatorInfo * pOperator = calloc ( 1 , sizeof ( SOperatorInfo ) ) ;
pOperator - > name = " TimeIntervalAggOperator " ;
2021-12-06 06:44:27 +00:00
// pOperator->operatorType = OP_TimeWindow;
2021-11-02 05:37:31 +00:00
pOperator - > blockingOptr = true ;
pOperator - > status = OP_IN_EXECUTING ;
pOperator - > pExpr = pExpr ;
pOperator - > numOfOutput = numOfOutput ;
pOperator - > info = pInfo ;
pOperator - > pRuntimeEnv = pRuntimeEnv ;
pOperator - > exec = doIntervalAgg ;
2022-01-28 02:44:02 +00:00
pOperator - > cleanupFn = destroyBasicOperatorInfo ;
2021-11-02 05:37:31 +00:00
2022-01-14 02:20:55 +00:00
appendDownstream ( pOperator , downstream ) ;
2021-11-02 05:37:31 +00:00
return pOperator ;
}
2022-01-08 14:59:24 +00:00
SOperatorInfo * createAllTimeIntervalOperatorInfo ( STaskRuntimeEnv * pRuntimeEnv , SOperatorInfo * downstream , SExprInfo * pExpr , int32_t numOfOutput ) {
2021-11-02 05:37:31 +00:00
STableIntervalOperatorInfo * pInfo = calloc ( 1 , sizeof ( STableIntervalOperatorInfo ) ) ;
2022-01-14 02:20:55 +00:00
pInfo - > pCtx = createSqlFunctionCtx ( pRuntimeEnv , pExpr , numOfOutput , & pInfo - > rowCellInfoOffset ) ;
2021-11-02 05:37:31 +00:00
pInfo - > pRes = createOutputBuf ( pExpr , numOfOutput , pRuntimeEnv - > resultInfo . capacity ) ;
initResultRowInfo ( & pInfo - > resultRowInfo , 8 , TSDB_DATA_TYPE_INT ) ;
SOperatorInfo * pOperator = calloc ( 1 , sizeof ( SOperatorInfo ) ) ;
pOperator - > name = " AllTimeIntervalAggOperator " ;
2021-12-06 06:44:27 +00:00
// pOperator->operatorType = OP_AllTimeWindow;
2021-11-02 05:37:31 +00:00
pOperator - > blockingOptr = true ;
pOperator - > status = OP_IN_EXECUTING ;
pOperator - > pExpr = pExpr ;
pOperator - > numOfOutput = numOfOutput ;
pOperator - > info = pInfo ;
pOperator - > pRuntimeEnv = pRuntimeEnv ;
pOperator - > exec = doAllIntervalAgg ;
2022-01-28 02:44:02 +00:00
pOperator - > cleanupFn = destroyBasicOperatorInfo ;
2021-11-02 05:37:31 +00:00
2022-01-14 02:20:55 +00:00
appendDownstream ( pOperator , downstream ) ;
2021-11-02 05:37:31 +00:00
return pOperator ;
}
2022-01-08 14:59:24 +00:00
SOperatorInfo * createStatewindowOperatorInfo ( STaskRuntimeEnv * pRuntimeEnv , SOperatorInfo * downstream , SExprInfo * pExpr , int32_t numOfOutput ) {
2021-11-02 05:37:31 +00:00
SStateWindowOperatorInfo * pInfo = calloc ( 1 , sizeof ( SStateWindowOperatorInfo ) ) ;
pInfo - > colIndex = - 1 ;
pInfo - > reptScan = false ;
2022-01-14 02:20:55 +00:00
pInfo - > binfo . pCtx = createSqlFunctionCtx ( pRuntimeEnv , pExpr , numOfOutput , & pInfo - > binfo . rowCellInfoOffset ) ;
2021-11-02 05:37:31 +00:00
pInfo - > binfo . pRes = createOutputBuf ( pExpr , numOfOutput , pRuntimeEnv - > resultInfo . capacity ) ;
initResultRowInfo ( & pInfo - > binfo . resultRowInfo , 8 , TSDB_DATA_TYPE_INT ) ;
SOperatorInfo * pOperator = calloc ( 1 , sizeof ( SOperatorInfo ) ) ;
pOperator - > name = " StateWindowOperator " ;
2021-12-06 06:44:27 +00:00
// pOperator->operatorType = OP_StateWindow;
2021-11-02 05:37:31 +00:00
pOperator - > blockingOptr = true ;
pOperator - > status = OP_IN_EXECUTING ;
pOperator - > pExpr = pExpr ;
pOperator - > numOfOutput = numOfOutput ;
pOperator - > info = pInfo ;
pOperator - > pRuntimeEnv = pRuntimeEnv ;
pOperator - > exec = doStateWindowAgg ;
2022-01-28 02:44:02 +00:00
pOperator - > cleanupFn = destroyStateWindowOperatorInfo ;
2021-11-02 05:37:31 +00:00
2022-01-14 02:20:55 +00:00
appendDownstream ( pOperator , downstream ) ;
2021-11-02 05:37:31 +00:00
return pOperator ;
}
2022-01-08 14:59:24 +00:00
SOperatorInfo * createSWindowOperatorInfo ( STaskRuntimeEnv * pRuntimeEnv , SOperatorInfo * downstream , SExprInfo * pExpr , int32_t numOfOutput ) {
2021-11-02 05:37:31 +00:00
SSWindowOperatorInfo * pInfo = calloc ( 1 , sizeof ( SSWindowOperatorInfo ) ) ;
2022-01-14 02:20:55 +00:00
pInfo - > binfo . pCtx = createSqlFunctionCtx ( pRuntimeEnv , pExpr , numOfOutput , & pInfo - > binfo . rowCellInfoOffset ) ;
2021-11-02 05:37:31 +00:00
pInfo - > binfo . pRes = createOutputBuf ( pExpr , numOfOutput , pRuntimeEnv - > resultInfo . capacity ) ;
initResultRowInfo ( & pInfo - > binfo . resultRowInfo , 8 , TSDB_DATA_TYPE_INT ) ;
pInfo - > prevTs = INT64_MIN ;
pInfo - > reptScan = false ;
SOperatorInfo * pOperator = calloc ( 1 , sizeof ( SOperatorInfo ) ) ;
pOperator - > name = " SessionWindowAggOperator " ;
2021-12-06 06:44:27 +00:00
// pOperator->operatorType = OP_SessionWindow;
2021-11-02 05:37:31 +00:00
pOperator - > blockingOptr = true ;
pOperator - > status = OP_IN_EXECUTING ;
pOperator - > pExpr = pExpr ;
pOperator - > numOfOutput = numOfOutput ;
pOperator - > info = pInfo ;
pOperator - > pRuntimeEnv = pRuntimeEnv ;
pOperator - > exec = doSessionWindowAgg ;
2022-01-28 02:44:02 +00:00
pOperator - > cleanupFn = destroySWindowOperatorInfo ;
2021-11-02 05:37:31 +00:00
2022-01-14 02:20:55 +00:00
appendDownstream ( pOperator , downstream ) ;
2021-11-02 05:37:31 +00:00
return pOperator ;
}
2022-01-08 14:59:24 +00:00
SOperatorInfo * createMultiTableTimeIntervalOperatorInfo ( STaskRuntimeEnv * pRuntimeEnv , SOperatorInfo * downstream , SExprInfo * pExpr , int32_t numOfOutput ) {
2021-11-02 05:37:31 +00:00
STableIntervalOperatorInfo * pInfo = calloc ( 1 , sizeof ( STableIntervalOperatorInfo ) ) ;
2022-01-14 02:20:55 +00:00
pInfo - > pCtx = createSqlFunctionCtx ( pRuntimeEnv , pExpr , numOfOutput , & pInfo - > rowCellInfoOffset ) ;
2021-11-02 05:37:31 +00:00
pInfo - > pRes = createOutputBuf ( pExpr , numOfOutput , pRuntimeEnv - > resultInfo . capacity ) ;
initResultRowInfo ( & pInfo - > resultRowInfo , 8 , TSDB_DATA_TYPE_INT ) ;
SOperatorInfo * pOperator = calloc ( 1 , sizeof ( SOperatorInfo ) ) ;
pOperator - > name = " MultiTableTimeIntervalOperator " ;
2021-12-06 06:44:27 +00:00
// pOperator->operatorType = OP_MultiTableTimeInterval;
2021-11-02 05:37:31 +00:00
pOperator - > blockingOptr = true ;
pOperator - > status = OP_IN_EXECUTING ;
pOperator - > pExpr = pExpr ;
pOperator - > numOfOutput = numOfOutput ;
pOperator - > info = pInfo ;
pOperator - > pRuntimeEnv = pRuntimeEnv ;
pOperator - > exec = doSTableIntervalAgg ;
2022-01-28 02:44:02 +00:00
pOperator - > cleanupFn = destroyBasicOperatorInfo ;
2021-11-02 05:37:31 +00:00
2022-01-14 02:20:55 +00:00
appendDownstream ( pOperator , downstream ) ;
2021-11-02 05:37:31 +00:00
return pOperator ;
}
2022-01-08 14:59:24 +00:00
SOperatorInfo * createAllMultiTableTimeIntervalOperatorInfo ( STaskRuntimeEnv * pRuntimeEnv , SOperatorInfo * downstream , SExprInfo * pExpr , int32_t numOfOutput ) {
2021-11-02 05:37:31 +00:00
STableIntervalOperatorInfo * pInfo = calloc ( 1 , sizeof ( STableIntervalOperatorInfo ) ) ;
2022-01-14 02:20:55 +00:00
pInfo - > pCtx = createSqlFunctionCtx ( pRuntimeEnv , pExpr , numOfOutput , & pInfo - > rowCellInfoOffset ) ;
2021-11-02 05:37:31 +00:00
pInfo - > pRes = createOutputBuf ( pExpr , numOfOutput , pRuntimeEnv - > resultInfo . capacity ) ;
initResultRowInfo ( & pInfo - > resultRowInfo , 8 , TSDB_DATA_TYPE_INT ) ;
SOperatorInfo * pOperator = calloc ( 1 , sizeof ( SOperatorInfo ) ) ;
pOperator - > name = " AllMultiTableTimeIntervalOperator " ;
2021-12-06 06:44:27 +00:00
// pOperator->operatorType = OP_AllMultiTableTimeInterval;
2021-11-02 05:37:31 +00:00
pOperator - > blockingOptr = true ;
pOperator - > status = OP_IN_EXECUTING ;
pOperator - > pExpr = pExpr ;
pOperator - > numOfOutput = numOfOutput ;
pOperator - > info = pInfo ;
pOperator - > pRuntimeEnv = pRuntimeEnv ;
pOperator - > exec = doAllSTableIntervalAgg ;
2022-01-28 02:44:02 +00:00
pOperator - > cleanupFn = destroyBasicOperatorInfo ;
2021-11-02 05:37:31 +00:00
2022-01-14 02:20:55 +00:00
appendDownstream ( pOperator , downstream ) ;
2021-11-02 05:37:31 +00:00
return pOperator ;
}
2022-01-08 14:59:24 +00:00
SOperatorInfo * createGroupbyOperatorInfo ( STaskRuntimeEnv * pRuntimeEnv , SOperatorInfo * downstream , SExprInfo * pExpr , int32_t numOfOutput ) {
2021-11-02 05:37:31 +00:00
SGroupbyOperatorInfo * pInfo = calloc ( 1 , sizeof ( SGroupbyOperatorInfo ) ) ;
pInfo - > colIndex = - 1 ; // group by column index
2022-01-14 02:20:55 +00:00
pInfo - > binfo . pCtx = createSqlFunctionCtx ( pRuntimeEnv , pExpr , numOfOutput , & pInfo - > binfo . rowCellInfoOffset ) ;
2021-11-02 05:37:31 +00:00
2022-01-08 08:28:44 +00:00
STaskAttr * pQueryAttr = pRuntimeEnv - > pQueryAttr ;
2021-11-02 05:37:31 +00:00
pQueryAttr - > resultRowSize = ( pQueryAttr - > resultRowSize *
( int32_t ) ( getRowNumForMultioutput ( pQueryAttr , pQueryAttr - > topBotQuery , pQueryAttr - > stableQuery ) ) ) ;
pInfo - > binfo . pRes = createOutputBuf ( pExpr , numOfOutput , pRuntimeEnv - > resultInfo . capacity ) ;
initResultRowInfo ( & pInfo - > binfo . resultRowInfo , 8 , TSDB_DATA_TYPE_INT ) ;
SOperatorInfo * pOperator = calloc ( 1 , sizeof ( SOperatorInfo ) ) ;
pOperator - > name = " GroupbyAggOperator " ;
pOperator - > blockingOptr = true ;
pOperator - > status = OP_IN_EXECUTING ;
2021-12-06 06:44:27 +00:00
// pOperator->operatorType = OP_Groupby;
2021-11-02 05:37:31 +00:00
pOperator - > pExpr = pExpr ;
pOperator - > numOfOutput = numOfOutput ;
pOperator - > info = pInfo ;
pOperator - > pRuntimeEnv = pRuntimeEnv ;
pOperator - > exec = hashGroupbyAggregate ;
2022-01-28 02:44:02 +00:00
pOperator - > cleanupFn = destroyGroupbyOperatorInfo ;
2021-11-02 05:37:31 +00:00
2022-01-14 02:20:55 +00:00
appendDownstream ( pOperator , downstream ) ;
2021-11-02 05:37:31 +00:00
return pOperator ;
}
2022-01-08 14:59:24 +00:00
SOperatorInfo * createFillOperatorInfo ( STaskRuntimeEnv * pRuntimeEnv , SOperatorInfo * downstream , SExprInfo * pExpr , int32_t numOfOutput , bool multigroupResult ) {
2021-11-02 05:37:31 +00:00
SFillOperatorInfo * pInfo = calloc ( 1 , sizeof ( SFillOperatorInfo ) ) ;
pInfo - > pRes = createOutputBuf ( pExpr , numOfOutput , pRuntimeEnv - > resultInfo . capacity ) ;
pInfo - > multigroupResult = multigroupResult ;
{
2022-01-08 08:28:44 +00:00
STaskAttr * pQueryAttr = pRuntimeEnv - > pQueryAttr ;
2021-11-02 05:37:31 +00:00
struct SFillColInfo * pColInfo = createFillColInfo ( pExpr , numOfOutput , pQueryAttr - > fillVal ) ;
STimeWindow w = TSWINDOW_INITIALIZER ;
2022-01-24 04:53:17 +00:00
TSKEY sk = TMIN ( pQueryAttr - > window . skey , pQueryAttr - > window . ekey ) ;
TSKEY ek = TMAX ( pQueryAttr - > window . skey , pQueryAttr - > window . ekey ) ;
2021-11-02 05:37:31 +00:00
getAlignQueryTimeWindow ( pQueryAttr , pQueryAttr - > window . skey , sk , ek , & w ) ;
pInfo - > pFillInfo =
taosCreateFillInfo ( pQueryAttr - > order . order , w . skey , 0 , ( int32_t ) pRuntimeEnv - > resultInfo . capacity , numOfOutput ,
pQueryAttr - > interval . sliding , pQueryAttr - > interval . slidingUnit ,
( int8_t ) pQueryAttr - > precision , pQueryAttr - > fillType , pColInfo , pRuntimeEnv - > qinfo ) ;
pInfo - > p = calloc ( numOfOutput , POINTER_BYTES ) ;
}
SOperatorInfo * pOperator = calloc ( 1 , sizeof ( SOperatorInfo ) ) ;
pOperator - > name = " FillOperator " ;
pOperator - > blockingOptr = false ;
pOperator - > status = OP_IN_EXECUTING ;
2021-12-06 06:44:27 +00:00
// pOperator->operatorType = OP_Fill;
2021-11-02 05:37:31 +00:00
pOperator - > pExpr = pExpr ;
pOperator - > numOfOutput = numOfOutput ;
pOperator - > info = pInfo ;
pOperator - > pRuntimeEnv = pRuntimeEnv ;
pOperator - > exec = doFill ;
2022-01-28 02:44:02 +00:00
pOperator - > cleanupFn = destroySFillOperatorInfo ;
2021-11-02 05:37:31 +00:00
2022-01-14 02:20:55 +00:00
appendDownstream ( pOperator , downstream ) ;
2021-11-02 05:37:31 +00:00
return pOperator ;
}
2022-01-08 14:59:24 +00:00
SOperatorInfo * createSLimitOperatorInfo ( STaskRuntimeEnv * pRuntimeEnv , SOperatorInfo * downstream , SExprInfo * pExpr , int32_t numOfOutput , void * pMerger , bool multigroupResult ) {
2021-11-02 05:37:31 +00:00
SSLimitOperatorInfo * pInfo = calloc ( 1 , sizeof ( SSLimitOperatorInfo ) ) ;
2022-01-08 08:28:44 +00:00
STaskAttr * pQueryAttr = pRuntimeEnv - > pQueryAttr ;
2021-11-02 05:37:31 +00:00
pInfo - > orderColumnList = getResultGroupCheckColumns ( pQueryAttr ) ;
pInfo - > slimit = pQueryAttr - > slimit ;
pInfo - > limit = pQueryAttr - > limit ;
pInfo - > capacity = pRuntimeEnv - > resultInfo . capacity ;
pInfo - > threshold = ( int64_t ) ( pInfo - > capacity * 0.8 ) ;
pInfo - > currentOffset = pQueryAttr - > limit . offset ;
pInfo - > currentGroupOffset = pQueryAttr - > slimit . offset ;
pInfo - > multigroupResult = multigroupResult ;
// TODO refactor
int32_t len = 0 ;
for ( int32_t i = 0 ; i < numOfOutput ; + + i ) {
len + = pExpr [ i ] . base . resSchema . bytes ;
}
int32_t numOfCols = ( pInfo - > orderColumnList ! = NULL ) ? ( int32_t ) taosArrayGetSize ( pInfo - > orderColumnList ) : 0 ;
pInfo - > prevRow = calloc ( 1 , ( POINTER_BYTES * numOfCols + len ) ) ;
int32_t offset = POINTER_BYTES * numOfCols ;
for ( int32_t i = 0 ; i < numOfCols ; + + i ) {
pInfo - > prevRow [ i ] = ( char * ) pInfo - > prevRow + offset ;
SColIndex * index = taosArrayGet ( pInfo - > orderColumnList , i ) ;
offset + = pExpr [ index - > colIndex ] . base . resSchema . bytes ;
}
pInfo - > pRes = createOutputBuf ( pExpr , numOfOutput , pRuntimeEnv - > resultInfo . capacity ) ;
SOperatorInfo * pOperator = calloc ( 1 , sizeof ( SOperatorInfo ) ) ;
pOperator - > name = " SLimitOperator " ;
2022-01-10 11:48:21 +00:00
pOperator - > operatorType = OP_SLimit ;
2021-11-02 05:37:31 +00:00
pOperator - > blockingOptr = false ;
pOperator - > status = OP_IN_EXECUTING ;
2022-01-10 11:48:21 +00:00
// pOperator->exec = doSLimit;
2021-11-02 05:37:31 +00:00
pOperator - > info = pInfo ;
pOperator - > pRuntimeEnv = pRuntimeEnv ;
2022-01-28 02:44:02 +00:00
pOperator - > cleanupFn = destroySlimitOperatorInfo ;
2021-11-02 05:37:31 +00:00
2022-01-14 02:20:55 +00:00
appendDownstream ( pOperator , downstream ) ;
2021-11-02 05:37:31 +00:00
return pOperator ;
}
static SSDataBlock * doTagScan ( void * param , bool * newgroup ) {
#if 0
SOperatorInfo * pOperator = ( SOperatorInfo * ) param ;
if ( pOperator - > status = = OP_EXEC_DONE ) {
return NULL ;
}
2022-01-08 08:28:44 +00:00
STaskRuntimeEnv * pRuntimeEnv = pOperator - > pRuntimeEnv ;
2021-11-02 05:37:31 +00:00
int32_t maxNumOfTables = ( int32_t ) pRuntimeEnv - > resultInfo . capacity ;
STagScanInfo * pInfo = pOperator - > info ;
SSDataBlock * pRes = pInfo - > pRes ;
* newgroup = false ;
int32_t count = 0 ;
SArray * pa = GET_TABLEGROUP ( pRuntimeEnv , 0 ) ;
int32_t functionId = getExprFunctionId ( & pOperator - > pExpr [ 0 ] ) ;
if ( functionId = = FUNCTION_TID_TAG ) { // return the tags & table Id
2022-01-08 08:28:44 +00:00
STaskAttr * pQueryAttr = pRuntimeEnv - > pQueryAttr ;
2021-11-02 05:37:31 +00:00
assert ( pQueryAttr - > numOfOutput = = 1 ) ;
SExprInfo * pExprInfo = & pOperator - > pExpr [ 0 ] ;
int32_t rsize = pExprInfo - > base . resSchema . bytes ;
count = 0 ;
int16_t bytes = pExprInfo - > base . resSchema . bytes ;
int16_t type = pExprInfo - > base . resSchema . type ;
for ( int32_t i = 0 ; i < pQueryAttr - > numOfTags ; + + i ) {
2021-11-05 02:35:50 +00:00
if ( pQueryAttr - > tagColList [ i ] . colId = = pExprInfo - > base . pColumns - > info . colId ) {
2021-11-02 05:37:31 +00:00
bytes = pQueryAttr - > tagColList [ i ] . bytes ;
type = pQueryAttr - > tagColList [ i ] . type ;
break ;
}
}
SColumnInfoData * pColInfo = taosArrayGet ( pRes - > pDataBlock , 0 ) ;
while ( pInfo - > curPos < pInfo - > totalTables & & count < maxNumOfTables ) {
int32_t i = pInfo - > curPos + + ;
STableQueryInfo * item = taosArrayGetP ( pa , i ) ;
char * output = pColInfo - > pData + count * rsize ;
varDataSetLen ( output , rsize - VARSTR_HEADER_SIZE ) ;
output = varDataVal ( output ) ;
STableId * id = TSDB_TABLEID ( item - > pTable ) ;
* ( int16_t * ) output = 0 ;
output + = sizeof ( int16_t ) ;
* ( int64_t * ) output = id - > uid ; // memory align problem, todo serialize
output + = sizeof ( id - > uid ) ;
* ( int32_t * ) output = id - > tid ;
output + = sizeof ( id - > tid ) ;
* ( int32_t * ) output = pQueryAttr - > vgId ;
output + = sizeof ( pQueryAttr - > vgId ) ;
char * data = NULL ;
2021-11-05 02:35:50 +00:00
if ( pExprInfo - > base . pColumns - > info . colId = = TSDB_TBNAME_COLUMN_INDEX ) {
2021-11-02 05:37:31 +00:00
data = tsdbGetTableName ( item - > pTable ) ;
} else {
2021-11-05 02:35:50 +00:00
data = tsdbGetTableTagVal ( item - > pTable , pExprInfo - > base . pColumns - > info . colId , type , bytes ) ;
2021-11-02 05:37:31 +00:00
}
doSetTagValueToResultBuf ( output , data , type , bytes ) ;
count + = 1 ;
}
2022-01-10 11:48:21 +00:00
//qDebug("QInfo:0x%"PRIx64" create (tableId, tag) info completed, rows:%d", GET_TASKID(pRuntimeEnv), count);
2021-11-02 05:37:31 +00:00
} else if ( functionId = = FUNCTION_COUNT ) { // handle the "count(tbname)" query
SColumnInfoData * pColInfo = taosArrayGet ( pRes - > pDataBlock , 0 ) ;
* ( int64_t * ) pColInfo - > pData = pInfo - > totalTables ;
count = 1 ;
pOperator - > status = OP_EXEC_DONE ;
2022-01-10 11:48:21 +00:00
//qDebug("QInfo:0x%"PRIx64" create count(tbname) query, res:%d rows:1", GET_TASKID(pRuntimeEnv), count);
2021-11-02 05:37:31 +00:00
} else { // return only the tags|table name etc.
SExprInfo * pExprInfo = & pOperator - > pExpr [ 0 ] ; // todo use the column list instead of exprinfo
count = 0 ;
while ( pInfo - > curPos < pInfo - > totalTables & & count < maxNumOfTables ) {
int32_t i = pInfo - > curPos + + ;
STableQueryInfo * item = taosArrayGetP ( pa , i ) ;
char * data = NULL , * dst = NULL ;
int16_t type = 0 , bytes = 0 ;
for ( int32_t j = 0 ; j < pOperator - > numOfOutput ; + + j ) {
// not assign value in case of user defined constant output column
2021-11-04 05:24:19 +00:00
if ( TSDB_COL_IS_UD_COL ( pExprInfo [ j ] . base . pColumns - > flag ) ) {
2021-11-02 05:37:31 +00:00
continue ;
}
SColumnInfoData * pColInfo = taosArrayGet ( pRes - > pDataBlock , j ) ;
type = pExprInfo [ j ] . base . resSchema . type ;
bytes = pExprInfo [ j ] . base . resSchema . bytes ;
2021-11-05 02:35:50 +00:00
if ( pExprInfo [ j ] . base . pColumns - > info . colId = = TSDB_TBNAME_COLUMN_INDEX ) {
2021-11-02 05:37:31 +00:00
data = tsdbGetTableName ( item - > pTable ) ;
} else {
2021-11-05 02:35:50 +00:00
data = tsdbGetTableTagVal ( item - > pTable , pExprInfo [ j ] . base . pColumns - > info . colId , type , bytes ) ;
2021-11-02 05:37:31 +00:00
}
dst = pColInfo - > pData + count * pExprInfo [ j ] . base . resSchema . bytes ;
doSetTagValueToResultBuf ( dst , data , type , bytes ) ;
}
count + = 1 ;
}
if ( pInfo - > curPos > = pInfo - > totalTables ) {
pOperator - > status = OP_EXEC_DONE ;
}
2022-01-10 11:48:21 +00:00
//qDebug("QInfo:0x%"PRIx64" create tag values results completed, rows:%d", GET_TASKID(pRuntimeEnv), count);
2021-11-02 05:37:31 +00:00
}
if ( pOperator - > status = = OP_EXEC_DONE ) {
2022-01-10 11:48:21 +00:00
setTaskStatus ( pOperator - > pRuntimeEnv , TASK_COMPLETED ) ;
2021-11-02 05:37:31 +00:00
}
pRes - > info . rows = count ;
return ( pRes - > info . rows = = 0 ) ? NULL : pInfo - > pRes ;
# endif
}
2022-01-08 08:28:44 +00:00
SOperatorInfo * createTagScanOperatorInfo ( STaskRuntimeEnv * pRuntimeEnv , SExprInfo * pExpr , int32_t numOfOutput ) {
2021-11-02 05:37:31 +00:00
STagScanInfo * pInfo = calloc ( 1 , sizeof ( STagScanInfo ) ) ;
pInfo - > pRes = createOutputBuf ( pExpr , numOfOutput , pRuntimeEnv - > resultInfo . capacity ) ;
size_t numOfGroup = GET_NUM_OF_TABLEGROUP ( pRuntimeEnv ) ;
assert ( numOfGroup = = 0 | | numOfGroup = = 1 ) ;
pInfo - > totalTables = pRuntimeEnv - > tableqinfoGroupInfo . numOfTables ;
pInfo - > curPos = 0 ;
SOperatorInfo * pOperator = calloc ( 1 , sizeof ( SOperatorInfo ) ) ;
pOperator - > name = " SeqTableTagScan " ;
2022-01-26 02:16:59 +00:00
pOperator - > operatorType = OP_TagScan ;
2021-11-02 05:37:31 +00:00
pOperator - > blockingOptr = false ;
pOperator - > status = OP_IN_EXECUTING ;
pOperator - > info = pInfo ;
pOperator - > exec = doTagScan ;
pOperator - > pExpr = pExpr ;
pOperator - > numOfOutput = numOfOutput ;
pOperator - > pRuntimeEnv = pRuntimeEnv ;
2022-01-28 02:44:02 +00:00
pOperator - > cleanupFn = destroyTagScanOperatorInfo ;
2021-11-02 05:37:31 +00:00
return pOperator ;
}
static bool initMultiDistinctInfo ( SDistinctOperatorInfo * pInfo , SOperatorInfo * pOperator , SSDataBlock * pBlock ) {
if ( taosArrayGetSize ( pInfo - > pDistinctDataInfo ) = = pOperator - > numOfOutput ) {
// distinct info already inited
return true ;
}
for ( int i = 0 ; i < pOperator - > numOfOutput ; i + + ) {
// pInfo->totalBytes += pOperator->pExpr[i].base.colBytes;
}
for ( int i = 0 ; i < pOperator - > numOfOutput ; i + + ) {
int numOfBlock = ( int ) ( taosArrayGetSize ( pBlock - > pDataBlock ) ) ;
assert ( i < numOfBlock ) ;
for ( int j = 0 ; j < numOfBlock ; j + + ) {
SColumnInfoData * pColDataInfo = taosArrayGet ( pBlock - > pDataBlock , j ) ;
if ( pColDataInfo - > info . colId = = pOperator - > pExpr [ i ] . base . resSchema . colId ) {
SDistinctDataInfo item = { . index = j , . type = pColDataInfo - > info . type , . bytes = pColDataInfo - > info . bytes } ;
taosArrayInsert ( pInfo - > pDistinctDataInfo , i , & item ) ;
}
}
}
pInfo - > totalBytes + = ( int32_t ) strlen ( MULTI_KEY_DELIM ) * ( pOperator - > numOfOutput ) ;
pInfo - > buf = calloc ( 1 , pInfo - > totalBytes ) ;
return taosArrayGetSize ( pInfo - > pDistinctDataInfo ) = = pOperator - > numOfOutput ? true : false ;
}
static void buildMultiDistinctKey ( SDistinctOperatorInfo * pInfo , SSDataBlock * pBlock , int32_t rowId ) {
char * p = pInfo - > buf ;
memset ( p , 0 , pInfo - > totalBytes ) ;
for ( int i = 0 ; i < taosArrayGetSize ( pInfo - > pDistinctDataInfo ) ; i + + ) {
SDistinctDataInfo * pDistDataInfo = ( SDistinctDataInfo * ) taosArrayGet ( pInfo - > pDistinctDataInfo , i ) ;
SColumnInfoData * pColDataInfo = taosArrayGet ( pBlock - > pDataBlock , pDistDataInfo - > index ) ;
char * val = ( ( char * ) pColDataInfo - > pData ) + pColDataInfo - > info . bytes * rowId ;
if ( isNull ( val , pDistDataInfo - > type ) ) {
p + = pDistDataInfo - > bytes ;
continue ;
}
if ( IS_VAR_DATA_TYPE ( pDistDataInfo - > type ) ) {
memcpy ( p , varDataVal ( val ) , varDataLen ( val ) ) ;
p + = varDataLen ( val ) ;
} else {
memcpy ( p , val , pDistDataInfo - > bytes ) ;
p + = pDistDataInfo - > bytes ;
}
memcpy ( p , MULTI_KEY_DELIM , strlen ( MULTI_KEY_DELIM ) ) ;
p + = strlen ( MULTI_KEY_DELIM ) ;
}
}
static SSDataBlock * hashDistinct ( void * param , bool * newgroup ) {
SOperatorInfo * pOperator = ( SOperatorInfo * ) param ;
if ( pOperator - > status = = OP_EXEC_DONE ) {
return NULL ;
}
SDistinctOperatorInfo * pInfo = pOperator - > info ;
SSDataBlock * pRes = pInfo - > pRes ;
pRes - > info . rows = 0 ;
SSDataBlock * pBlock = NULL ;
while ( 1 ) {
2022-01-08 08:28:44 +00:00
publishOperatorProfEvent ( pOperator - > pDownstream [ 0 ] , QUERY_PROF_BEFORE_OPERATOR_EXEC ) ;
pBlock = pOperator - > pDownstream [ 0 ] - > exec ( pOperator - > pDownstream [ 0 ] , newgroup ) ;
publishOperatorProfEvent ( pOperator - > pDownstream [ 0 ] , QUERY_PROF_AFTER_OPERATOR_EXEC ) ;
2021-11-02 05:37:31 +00:00
if ( pBlock = = NULL ) {
doSetOperatorCompleted ( pOperator ) ;
break ;
}
if ( ! initMultiDistinctInfo ( pInfo , pOperator , pBlock ) ) {
doSetOperatorCompleted ( pOperator ) ;
break ;
}
// ensure result output buf
if ( pRes - > info . rows + pBlock - > info . rows > pInfo - > outputCapacity ) {
int32_t newSize = pRes - > info . rows + pBlock - > info . rows ;
for ( int i = 0 ; i < taosArrayGetSize ( pRes - > pDataBlock ) ; i + + ) {
SColumnInfoData * pResultColInfoData = taosArrayGet ( pRes - > pDataBlock , i ) ;
SDistinctDataInfo * pDistDataInfo = taosArrayGet ( pInfo - > pDistinctDataInfo , i ) ;
char * tmp = realloc ( pResultColInfoData - > pData , newSize * pDistDataInfo - > bytes ) ;
if ( tmp = = NULL ) {
return NULL ;
} else {
pResultColInfoData - > pData = tmp ;
}
}
pInfo - > outputCapacity = newSize ;
}
for ( int32_t i = 0 ; i < pBlock - > info . rows ; i + + ) {
buildMultiDistinctKey ( pInfo , pBlock , i ) ;
if ( taosHashGet ( pInfo - > pSet , pInfo - > buf , pInfo - > totalBytes ) = = NULL ) {
int32_t dummy ;
taosHashPut ( pInfo - > pSet , pInfo - > buf , pInfo - > totalBytes , & dummy , sizeof ( dummy ) ) ;
for ( int j = 0 ; j < taosArrayGetSize ( pRes - > pDataBlock ) ; j + + ) {
SDistinctDataInfo * pDistDataInfo = taosArrayGet ( pInfo - > pDistinctDataInfo , j ) ; // distinct meta info
SColumnInfoData * pColInfoData = taosArrayGet ( pBlock - > pDataBlock , pDistDataInfo - > index ) ; //src
SColumnInfoData * pResultColInfoData = taosArrayGet ( pRes - > pDataBlock , j ) ; // dist
char * val = ( ( char * ) pColInfoData - > pData ) + pDistDataInfo - > bytes * i ;
char * start = pResultColInfoData - > pData + pDistDataInfo - > bytes * pInfo - > pRes - > info . rows ;
memcpy ( start , val , pDistDataInfo - > bytes ) ;
}
pRes - > info . rows + = 1 ;
}
}
if ( pRes - > info . rows > = pInfo - > threshold ) {
break ;
}
}
return ( pInfo - > pRes - > info . rows > 0 ) ? pInfo - > pRes : NULL ;
}
2022-01-08 14:59:24 +00:00
SOperatorInfo * createDistinctOperatorInfo ( STaskRuntimeEnv * pRuntimeEnv , SOperatorInfo * downstream , SExprInfo * pExpr , int32_t numOfOutput ) {
2021-11-02 05:37:31 +00:00
SDistinctOperatorInfo * pInfo = calloc ( 1 , sizeof ( SDistinctOperatorInfo ) ) ;
pInfo - > totalBytes = 0 ;
pInfo - > buf = NULL ;
pInfo - > threshold = tsMaxNumOfDistinctResults ; // distinct result threshold
pInfo - > outputCapacity = 4096 ;
pInfo - > pDistinctDataInfo = taosArrayInit ( numOfOutput , sizeof ( SDistinctDataInfo ) ) ;
pInfo - > pSet = taosHashInit ( 64 , taosGetDefaultHashFunction ( TSDB_DATA_TYPE_BINARY ) , false , HASH_NO_LOCK ) ;
pInfo - > pRes = createOutputBuf ( pExpr , numOfOutput , ( int32_t ) pInfo - > outputCapacity ) ;
SOperatorInfo * pOperator = calloc ( 1 , sizeof ( SOperatorInfo ) ) ;
pOperator - > name = " DistinctOperator " ;
pOperator - > blockingOptr = false ;
pOperator - > status = OP_IN_EXECUTING ;
2021-12-06 06:44:27 +00:00
// pOperator->operatorType = OP_Distinct;
2021-11-02 05:37:31 +00:00
pOperator - > pExpr = pExpr ;
pOperator - > numOfOutput = numOfOutput ;
pOperator - > info = pInfo ;
pOperator - > pRuntimeEnv = pRuntimeEnv ;
pOperator - > exec = hashDistinct ;
pOperator - > pExpr = pExpr ;
2022-01-28 02:44:02 +00:00
pOperator - > cleanupFn = destroyDistinctOperatorInfo ;
2021-11-02 05:37:31 +00:00
2022-01-14 02:20:55 +00:00
appendDownstream ( pOperator , downstream ) ;
2021-11-02 05:37:31 +00:00
return pOperator ;
}
static int32_t getColumnIndexInSource ( SQueriedTableInfo * pTableInfo , SSqlExpr * pExpr , SColumnInfo * pTagCols ) {
int32_t j = 0 ;
2021-11-05 02:35:50 +00:00
if ( TSDB_COL_IS_TAG ( pExpr - > pColumns - > flag ) ) {
if ( pExpr - > pColumns - > info . colId = = TSDB_TBNAME_COLUMN_INDEX ) {
2021-11-02 05:37:31 +00:00
return TSDB_TBNAME_COLUMN_INDEX ;
}
while ( j < pTableInfo - > numOfTags ) {
2021-11-05 02:35:50 +00:00
if ( pExpr - > pColumns - > info . colId = = pTagCols [ j ] . colId ) {
2021-11-02 05:37:31 +00:00
return j ;
}
j + = 1 ;
}
2021-11-05 02:35:50 +00:00
} /*else if (TSDB_COL_IS_UD_COL(pExpr->colInfo.flag)) { // user specified column data
2021-11-02 05:37:31 +00:00
return TSDB_UD_COLUMN_INDEX ;
} else {
while ( j < pTableInfo - > numOfCols ) {
if ( pExpr - > colInfo . colId = = pTableInfo - > colList [ j ] . colId ) {
return j ;
}
j + = 1 ;
}
2021-11-05 02:35:50 +00:00
} */
2021-11-02 05:37:31 +00:00
return INT32_MIN ; // return a less than TSDB_TBNAME_COLUMN_INDEX value
}
bool validateExprColumnInfo ( SQueriedTableInfo * pTableInfo , SSqlExpr * pExpr , SColumnInfo * pTagCols ) {
int32_t j = getColumnIndexInSource ( pTableInfo , pExpr , pTagCols ) ;
return j ! = INT32_MIN ;
}
2022-01-10 12:44:11 +00:00
static bool validateQueryMsg ( SQueryTableReq * pQueryMsg ) {
2021-11-02 05:37:31 +00:00
if ( pQueryMsg - > interval . interval < 0 ) {
//qError("qmsg:%p illegal value of interval time %" PRId64, pQueryMsg, pQueryMsg->interval.interval);
return false ;
}
2021-11-10 15:31:35 +00:00
// if (pQueryMsg->sw.gap < 0 || pQueryMsg->sw.primaryColId != PRIMARYKEY_TIMESTAMP_COL_ID) {
2021-11-02 05:37:31 +00:00
//qError("qmsg:%p illegal value of session window time %" PRId64, pQueryMsg, pQueryMsg->sw.gap);
2021-11-10 15:31:35 +00:00
// return false;
// }
2021-11-02 05:37:31 +00:00
2021-11-10 15:31:35 +00:00
// if (pQueryMsg->sw.gap > 0 && pQueryMsg->interval.interval > 0) {
2021-11-02 05:37:31 +00:00
//qError("qmsg:%p illegal value of session window time %" PRId64" and interval value %"PRId64, pQueryMsg,
// pQueryMsg->sw.gap, pQueryMsg->interval.interval);
2021-11-10 15:31:35 +00:00
// return false;
// }
2021-11-02 05:37:31 +00:00
if ( pQueryMsg - > numOfTables < = 0 ) {
//qError("qmsg:%p illegal value of numOfTables %d", pQueryMsg, pQueryMsg->numOfTables);
return false ;
}
if ( pQueryMsg - > numOfGroupCols < 0 ) {
//qError("qmsg:%p illegal value of numOfGroupbyCols %d", pQueryMsg, pQueryMsg->numOfGroupCols);
return false ;
}
if ( pQueryMsg - > numOfOutput > TSDB_MAX_COLUMNS | | pQueryMsg - > numOfOutput < = 0 ) {
//qError("qmsg:%p illegal value of output columns %d", pQueryMsg, pQueryMsg->numOfOutput);
return false ;
}
return true ;
}
static bool validateQueryTableCols ( SQueriedTableInfo * pTableInfo , SSqlExpr * * pExpr , int32_t numOfOutput ,
SColumnInfo * pTagCols , void * pMsg ) {
int32_t numOfTotal = pTableInfo - > numOfCols + pTableInfo - > numOfTags ;
if ( pTableInfo - > numOfCols < 0 | | pTableInfo - > numOfTags < 0 | | numOfTotal > TSDB_MAX_COLUMNS ) {
//qError("qmsg:%p illegal value of numOfCols %d numOfTags:%d", pMsg, pTableInfo->numOfCols, pTableInfo->numOfTags);
return false ;
}
if ( numOfTotal = = 0 ) { // table total columns are not required.
// for(int32_t i = 0; i < numOfOutput; ++i) {
// SSqlExpr* p = pExpr[i];
// if ((p->functionId == FUNCTION_TAGPRJ) ||
// (p->functionId == FUNCTION_TID_TAG && p->colInfo.colId == TSDB_TBNAME_COLUMN_INDEX) ||
// (p->functionId == FUNCTION_COUNT && p->colInfo.colId == TSDB_TBNAME_COLUMN_INDEX) ||
// (p->functionId == FUNCTION_BLKINFO)) {
// continue;
// }
//
// return false;
// }
}
for ( int32_t i = 0 ; i < numOfOutput ; + + i ) {
if ( ! validateExprColumnInfo ( pTableInfo , pExpr [ i ] , pTagCols ) ) {
return TSDB_CODE_QRY_INVALID_MSG ;
}
}
return true ;
}
2022-01-10 12:44:11 +00:00
static char * createTableIdList ( SQueryTableReq * pQueryMsg , char * pMsg , SArray * * pTableIdList ) {
2021-11-02 05:37:31 +00:00
assert ( pQueryMsg - > numOfTables > 0 ) ;
* pTableIdList = taosArrayInit ( pQueryMsg - > numOfTables , sizeof ( STableIdInfo ) ) ;
for ( int32_t j = 0 ; j < pQueryMsg - > numOfTables ; + + j ) {
STableIdInfo * pTableIdInfo = ( STableIdInfo * ) pMsg ;
pTableIdInfo - > uid = htobe64 ( pTableIdInfo - > uid ) ;
pTableIdInfo - > key = htobe64 ( pTableIdInfo - > key ) ;
taosArrayPush ( * pTableIdList , pTableIdInfo ) ;
pMsg + = sizeof ( STableIdInfo ) ;
}
return pMsg ;
}
static int32_t deserializeColFilterInfo ( SColumnFilterInfo * pColFilters , int16_t numOfFilters , char * * pMsg ) {
for ( int32_t f = 0 ; f < numOfFilters ; + + f ) {
SColumnFilterInfo * pFilterMsg = ( SColumnFilterInfo * ) ( * pMsg ) ;
SColumnFilterInfo * pColFilter = & pColFilters [ f ] ;
pColFilter - > filterstr = htons ( pFilterMsg - > filterstr ) ;
( * pMsg ) + = sizeof ( SColumnFilterInfo ) ;
if ( pColFilter - > filterstr ) {
pColFilter - > len = htobe64 ( pFilterMsg - > len ) ;
pColFilter - > pz = ( int64_t ) calloc ( 1 , ( size_t ) ( pColFilter - > len + 1 * TSDB_NCHAR_SIZE ) ) ; // note: null-terminator
if ( pColFilter - > pz = = 0 ) {
return TSDB_CODE_QRY_OUT_OF_MEMORY ;
}
memcpy ( ( void * ) pColFilter - > pz , ( * pMsg ) , ( size_t ) pColFilter - > len ) ;
( * pMsg ) + = ( pColFilter - > len + 1 ) ;
} else {
pColFilter - > lowerBndi = htobe64 ( pFilterMsg - > lowerBndi ) ;
pColFilter - > upperBndi = htobe64 ( pFilterMsg - > upperBndi ) ;
}
pColFilter - > lowerRelOptr = htons ( pFilterMsg - > lowerRelOptr ) ;
pColFilter - > upperRelOptr = htons ( pFilterMsg - > upperRelOptr ) ;
}
return TSDB_CODE_SUCCESS ;
}
2022-01-25 05:42:33 +00:00
static SExecTaskInfo * createExecTaskInfo ( uint64_t queryId , uint64_t taskId ) {
2022-01-10 11:48:21 +00:00
SExecTaskInfo * pTaskInfo = calloc ( 1 , sizeof ( SExecTaskInfo ) ) ;
setTaskStatus ( pTaskInfo , TASK_NOT_COMPLETED ) ;
2022-01-08 14:59:24 +00:00
2022-01-10 11:48:21 +00:00
pTaskInfo - > cost . created = taosGetTimestampMs ( ) ;
2022-01-11 02:51:23 +00:00
pTaskInfo - > id . queryId = queryId ;
2022-01-25 05:42:33 +00:00
char * p = calloc ( 1 , 128 ) ;
2022-01-25 07:34:52 +00:00
snprintf ( p , 128 , " TID:0x% " PRIx64 " QID:0x% " PRIx64 , taskId , queryId ) ;
2022-01-25 15:08:22 +00:00
pTaskInfo - > id . str = strdup ( p ) ;
2022-01-25 05:42:33 +00:00
2022-01-10 11:48:21 +00:00
return pTaskInfo ;
}
2022-01-08 14:59:24 +00:00
2022-01-28 02:44:02 +00:00
static tsdbReaderT doCreateDataReader ( STableScanPhyNode * pTableScanNode , SReadHandle * pHandle , uint64_t queryId , uint64_t taskId ) ;
2022-02-04 14:41:54 +00:00
2022-01-28 02:44:02 +00:00
static int32_t doCreateTableGroup ( void * metaHandle , int32_t tableType , uint64_t tableUid , STableGroupInfo * pGroupInfo , uint64_t queryId , uint64_t taskId ) ;
2022-01-20 08:02:09 +00:00
2022-01-28 02:44:02 +00:00
SOperatorInfo * doCreateOperatorTreeNode ( SPhyNode * pPhyNode , SExecTaskInfo * pTaskInfo , SReadHandle * pHandle , uint64_t queryId , uint64_t taskId ) {
2022-01-10 11:48:21 +00:00
if ( pPhyNode - > pChildren = = NULL | | taosArrayGetSize ( pPhyNode - > pChildren ) = = 0 ) {
2022-01-28 02:44:02 +00:00
if ( pPhyNode - > info . type = = OP_DataBlocksOptScan ) {
2022-01-27 10:27:26 +00:00
SScanPhyNode * pScanPhyNode = ( SScanPhyNode * ) pPhyNode ;
size_t numOfCols = taosArrayGetSize ( pPhyNode - > pTargets ) ;
2022-01-20 08:02:09 +00:00
2022-01-28 02:44:02 +00:00
tsdbReaderT pDataReader = doCreateDataReader ( ( STableScanPhyNode * ) pPhyNode , pHandle , ( uint64_t ) queryId , taskId ) ;
2022-01-20 08:02:09 +00:00
2022-01-28 02:44:02 +00:00
return createDataBlocksOptScanInfo ( pDataReader , pScanPhyNode - > order , numOfCols , pScanPhyNode - > count , pScanPhyNode - > reverse , pTaskInfo ) ;
2022-01-19 06:47:53 +00:00
} else if ( pPhyNode - > info . type = = OP_Exchange ) {
SExchangePhyNode * pEx = ( SExchangePhyNode * ) pPhyNode ;
return createExchangeOperatorInfo ( pEx - > pSrcEndPoints , pEx - > node . pTargets , pTaskInfo ) ;
2022-01-21 07:16:17 +00:00
} else if ( pPhyNode - > info . type = = OP_StreamScan ) {
2022-01-27 10:27:26 +00:00
SScanPhyNode * pScanPhyNode = ( SScanPhyNode * ) pPhyNode ; // simple child table.
STableGroupInfo groupInfo = { 0 } ;
2022-01-27 11:03:58 +00:00
2022-01-28 02:44:02 +00:00
int32_t code = doCreateTableGroup ( pHandle - > meta , pScanPhyNode - > tableType , pScanPhyNode - > uid , & groupInfo , queryId , taskId ) ;
2022-01-27 10:27:26 +00:00
SArray * pa = taosArrayGetP ( groupInfo . pGroupList , 0 ) ;
ASSERT ( taosArrayGetSize ( groupInfo . pGroupList ) = = 1 ) ;
2022-01-28 02:44:02 +00:00
2022-01-27 10:48:12 +00:00
// Transfer the Array of STableKeyInfo into uid list.
size_t numOfTables = taosArrayGetSize ( pa ) ;
SArray * idList = taosArrayInit ( numOfTables , sizeof ( uint64_t ) ) ;
for ( int32_t i = 0 ; i < numOfTables ; + + i ) {
STableKeyInfo * pkeyInfo = taosArrayGet ( pa , i ) ;
taosArrayPush ( idList , & pkeyInfo - > uid ) ;
}
2022-01-28 02:44:02 +00:00
SOperatorInfo * pOperator = createStreamScanOperatorInfo ( pHandle - > reader , pPhyNode - > pTargets , idList , pTaskInfo ) ;
2022-01-27 10:48:12 +00:00
taosArrayDestroy ( idList ) ;
//TODO destroy groupInfo
return pOperator ;
2022-01-20 05:52:46 +00:00
}
}
if ( pPhyNode - > info . type = = OP_Aggregate ) {
size_t size = taosArrayGetSize ( pPhyNode - > pChildren ) ;
assert ( size = = 1 ) ;
for ( int32_t i = 0 ; i < size ; + + i ) {
2022-01-20 08:02:09 +00:00
SPhyNode * pChildNode = taosArrayGetP ( pPhyNode - > pChildren , i ) ;
2022-01-28 02:44:02 +00:00
SOperatorInfo * op = doCreateOperatorTreeNode ( pChildNode , pTaskInfo , pHandle , queryId , taskId ) ;
2022-01-20 05:52:46 +00:00
return createAggregateOperatorInfo ( op , pPhyNode - > pTargets , pTaskInfo ) ;
2022-01-10 11:48:21 +00:00
}
2022-01-08 14:59:24 +00:00
}
2022-01-10 11:48:21 +00:00
}
2022-01-08 14:59:24 +00:00
2022-01-28 02:44:02 +00:00
static tsdbReaderT createDataReaderImpl ( STableScanPhyNode * pTableScanNode , STableGroupInfo * pGroupInfo , void * readHandle , uint64_t queryId , uint64_t taskId ) {
2022-01-11 15:16:45 +00:00
STsdbQueryCond cond = { . loadExternalRows = false } ;
2022-01-08 14:59:24 +00:00
2022-01-20 08:02:09 +00:00
cond . order = pTableScanNode - > scan . order ;
cond . numOfCols = taosArrayGetSize ( pTableScanNode - > scan . node . pTargets ) ;
cond . colList = calloc ( cond . numOfCols , sizeof ( SColumnInfo ) ) ;
2022-01-28 02:44:02 +00:00
if ( cond . colList = = NULL ) {
terrno = TSDB_CODE_QRY_OUT_OF_MEMORY ;
return NULL ;
}
2022-01-20 08:02:09 +00:00
cond . twindow = pTableScanNode - > window ;
cond . type = BLOCK_LOAD_OFFSET_SEQ_ORDER ;
2022-01-19 06:47:53 +00:00
2022-01-20 08:02:09 +00:00
for ( int32_t i = 0 ; i < cond . numOfCols ; + + i ) {
SExprInfo * pExprInfo = taosArrayGetP ( pTableScanNode - > scan . node . pTargets , i ) ;
assert ( pExprInfo - > pExpr - > nodeType = = TEXPR_COL_NODE ) ;
SSchema * pSchema = pExprInfo - > pExpr - > pSchema ;
cond . colList [ i ] . type = pSchema - > type ;
cond . colList [ i ] . bytes = pSchema - > bytes ;
cond . colList [ i ] . colId = pSchema - > colId ;
}
2022-01-28 02:44:02 +00:00
return tsdbQueryTables ( readHandle , & cond , pGroupInfo , queryId , taskId ) ;
2022-01-20 08:02:09 +00:00
}
2022-01-11 15:16:45 +00:00
2022-01-27 11:03:58 +00:00
static int32_t doCreateTableGroup ( void * metaHandle , int32_t tableType , uint64_t tableUid , STableGroupInfo * pGroupInfo , uint64_t queryId , uint64_t taskId ) {
2022-01-27 10:27:26 +00:00
int32_t code = 0 ;
2022-01-20 08:02:09 +00:00
if ( tableType = = TSDB_SUPER_TABLE ) {
2022-01-27 11:03:58 +00:00
code = tsdbQuerySTableByTagCond ( metaHandle , tableUid , 0 , NULL , 0 , 0 , NULL , pGroupInfo , NULL , 0 , queryId , taskId ) ;
2022-01-20 08:02:09 +00:00
} else { // Create one table group.
2022-01-27 11:03:58 +00:00
code = tsdbGetOneTableGroup ( metaHandle , tableUid , 0 , pGroupInfo ) ;
2022-01-27 10:27:26 +00:00
}
return code ;
}
2022-01-20 08:02:09 +00:00
2022-01-28 02:44:02 +00:00
static tsdbReaderT doCreateDataReader ( STableScanPhyNode * pTableScanNode , SReadHandle * pHandle , uint64_t queryId , uint64_t taskId ) {
2022-01-27 10:27:26 +00:00
STableGroupInfo groupInfo = { 0 } ;
2022-01-20 08:02:09 +00:00
2022-01-27 10:27:26 +00:00
uint64_t uid = pTableScanNode - > scan . uid ;
2022-01-28 02:44:02 +00:00
int32_t code = doCreateTableGroup ( pHandle - > meta , pTableScanNode - > scan . tableType , uid , & groupInfo , queryId , taskId ) ;
2022-01-27 10:27:26 +00:00
if ( code ! = TSDB_CODE_SUCCESS ) {
goto _error ;
2022-01-11 15:16:45 +00:00
}
2022-01-08 14:59:24 +00:00
2022-01-20 08:02:09 +00:00
if ( groupInfo . numOfTables = = 0 ) {
code = 0 ;
2022-01-25 05:42:33 +00:00
qDebug ( " no table qualified for query, TID:0x% " PRIx64 " , QID:0x% " PRIx64 , taskId , queryId ) ;
2022-01-20 08:02:09 +00:00
goto _error ;
}
2022-01-08 14:59:24 +00:00
2022-01-28 02:44:02 +00:00
return createDataReaderImpl ( pTableScanNode , & groupInfo , pHandle - > reader , queryId , taskId ) ;
2022-01-22 14:51:48 +00:00
2022-01-20 08:02:09 +00:00
_error :
terrno = code ;
return NULL ;
}
2022-01-28 02:44:02 +00:00
int32_t createExecTaskInfoImpl ( SSubplan * pPlan , SExecTaskInfo * * pTaskInfo , SReadHandle * pHandle , uint64_t taskId ) {
2022-01-20 08:02:09 +00:00
uint64_t queryId = pPlan - > id . queryId ;
2022-01-21 03:19:24 +00:00
int32_t code = TSDB_CODE_SUCCESS ;
2022-01-25 05:42:33 +00:00
* pTaskInfo = createExecTaskInfo ( queryId , taskId ) ;
2022-01-21 03:19:24 +00:00
if ( * pTaskInfo = = NULL ) {
code = TSDB_CODE_QRY_OUT_OF_MEMORY ;
goto _complete ;
}
2022-01-08 14:59:24 +00:00
2022-01-28 02:44:02 +00:00
( * pTaskInfo ) - > pRoot = doCreateOperatorTreeNode ( pPlan - > pNode , * pTaskInfo , pHandle , queryId , taskId ) ;
2022-01-13 11:01:28 +00:00
if ( ( * pTaskInfo ) - > pRoot = = NULL ) {
2022-01-21 03:19:24 +00:00
code = TSDB_CODE_QRY_OUT_OF_MEMORY ;
2022-01-21 03:55:13 +00:00
goto _complete ;
2022-01-13 11:01:28 +00:00
}
2022-01-21 03:55:13 +00:00
return code ;
2022-01-21 03:19:24 +00:00
_complete :
tfree ( * pTaskInfo ) ;
terrno = code ;
return code ;
2022-01-08 14:59:24 +00:00
}
2021-11-02 05:37:31 +00:00
int32_t cloneExprFilterInfo ( SColumnFilterInfo * * dst , SColumnFilterInfo * src , int32_t filterNum ) {
if ( filterNum < = 0 ) {
return TSDB_CODE_SUCCESS ;
}
* dst = calloc ( filterNum , sizeof ( * src ) ) ;
if ( * dst = = NULL ) {
return TSDB_CODE_QRY_OUT_OF_MEMORY ;
}
memcpy ( * dst , src , sizeof ( * src ) * filterNum ) ;
for ( int32_t i = 0 ; i < filterNum ; i + + ) {
if ( ( * dst ) [ i ] . filterstr & & dst [ i ] - > len > 0 ) {
void * pz = calloc ( 1 , ( size_t ) ( * dst ) [ i ] . len + 1 ) ;
if ( pz = = NULL ) {
if ( i = = 0 ) {
free ( * dst ) ;
} else {
freeColumnFilterInfo ( * dst , i ) ;
}
return TSDB_CODE_QRY_OUT_OF_MEMORY ;
}
memcpy ( pz , ( void * ) src - > pz , ( size_t ) src - > len + 1 ) ;
( * dst ) [ i ] . pz = ( int64_t ) pz ;
}
}
return TSDB_CODE_SUCCESS ;
}
int32_t buildArithmeticExprFromMsg ( SExprInfo * pExprInfo , void * pQueryMsg ) {
//qDebug("qmsg:%p create arithmetic expr from binary", pQueryMsg);
tExprNode * pExprNode = NULL ;
TRY ( TSDB_MAX_TAG_CONDITIONS ) {
pExprNode = exprTreeFromBinary ( pExprInfo - > base . param [ 0 ] . pz , pExprInfo - > base . param [ 0 ] . nLen ) ;
} CATCH ( code ) {
CLEANUP_EXECUTE ( ) ;
//qError("qmsg:%p failed to create arithmetic expression string from:%s, reason: %s", pQueryMsg, pExprInfo->base.param[0].pz, tstrerror(code));
return code ;
} END_TRY
if ( pExprNode = = NULL ) {
//qError("qmsg:%p failed to create arithmetic expression string from:%s", pQueryMsg, pExprInfo->base.param[0].pz);
return TSDB_CODE_QRY_APP_ERROR ;
}
pExprInfo - > pExpr = pExprNode ;
return TSDB_CODE_SUCCESS ;
}
static int32_t updateOutputBufForTopBotQuery ( SQueriedTableInfo * pTableInfo , SColumnInfo * pTagCols , SExprInfo * pExprs , int32_t numOfOutput , int32_t tagLen , bool superTable ) {
for ( int32_t i = 0 ; i < numOfOutput ; + + i ) {
int16_t functId = getExprFunctionId ( & pExprs [ i ] ) ;
if ( functId = = FUNCTION_TOP | | functId = = FUNCTION_BOTTOM ) {
int32_t j = getColumnIndexInSource ( pTableInfo , & pExprs [ i ] . base , pTagCols ) ;
if ( j < 0 | | j > = pTableInfo - > numOfCols ) {
return TSDB_CODE_QRY_INVALID_MSG ;
} else {
SColumnInfo * pCol = & pTableInfo - > colList [ j ] ;
// int32_t ret = getResultDataInfo(pCol->type, pCol->bytes, functId, (int32_t)pExprs[i].base.param[0].i,
// &pExprs[i].base.resSchema.type, &pExprs[i].base.resSchema.bytes, &pExprs[i].base.interBytes, tagLen, superTable, NULL);
// assert(ret == TSDB_CODE_SUCCESS);
}
}
}
return TSDB_CODE_SUCCESS ;
}
// TODO tag length should be passed from client, refactor
int32_t createQueryFunc ( SQueriedTableInfo * pTableInfo , int32_t numOfOutput , SExprInfo * * pExprInfo ,
SSqlExpr * * pExprMsg , SColumnInfo * pTagCols , int32_t queryType , void * pMsg , struct SUdfInfo * pUdfInfo ) {
* pExprInfo = NULL ;
int32_t code = TSDB_CODE_SUCCESS ;
2022-01-10 11:48:21 +00:00
// code = initUdfInfo(pUdfInfo);
2021-11-02 05:37:31 +00:00
if ( code ) {
return code ;
}
SExprInfo * pExprs = ( SExprInfo * ) calloc ( numOfOutput , sizeof ( SExprInfo ) ) ;
if ( pExprs = = NULL ) {
return TSDB_CODE_QRY_OUT_OF_MEMORY ;
}
bool isSuperTable = /*QUERY_IS_STABLE_QUERY(queryType);*/ true ;
int16_t tagLen = 0 ;
for ( int32_t i = 0 ; i < numOfOutput ; + + i ) {
pExprs [ i ] . base = * pExprMsg [ i ] ;
memset ( pExprs [ i ] . base . param , 0 , sizeof ( SVariant ) * tListLen ( pExprs [ i ] . base . param ) ) ;
for ( int32_t j = 0 ; j < pExprMsg [ i ] - > numOfParams ; + + j ) {
taosVariantAssign ( & pExprs [ i ] . base . param [ j ] , & pExprMsg [ i ] - > param [ j ] ) ;
}
int16_t type = 0 ;
int16_t bytes = 0 ;
// parse the arithmetic expression
int32_t functionId = getExprFunctionId ( & pExprs [ i ] ) ;
if ( functionId = = FUNCTION_ARITHM ) {
code = buildArithmeticExprFromMsg ( & pExprs [ i ] , pMsg ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
tfree ( pExprs ) ;
return code ;
}
type = TSDB_DATA_TYPE_DOUBLE ;
bytes = tDataTypes [ type ] . bytes ;
} else if ( functionId = = FUNCTION_BLKINFO ) {
SSchema s = { . type = TSDB_DATA_TYPE_BINARY , . bytes = TSDB_MAX_BINARY_LEN } ;
type = s . type ;
bytes = s . bytes ;
2021-11-04 05:24:19 +00:00
} else if ( pExprs [ i ] . base . pColumns - > info . colId = = TSDB_TBNAME_COLUMN_INDEX & & functionId = = FUNCTION_TAGPRJ ) { // parse the normal column
2021-12-27 08:10:39 +00:00
const SSchema * s = tGetTbnameColumnSchema ( ) ;
2021-11-02 05:37:31 +00:00
type = s - > type ;
bytes = s - > bytes ;
2021-11-04 05:24:19 +00:00
} else if ( pExprs [ i ] . base . pColumns - > info . colId < = TSDB_UD_COLUMN_INDEX & & pExprs [ i ] . base . pColumns - > info . colId > TSDB_RES_COL_ID ) {
2021-11-02 05:37:31 +00:00
// it is a user-defined constant value column
assert ( functionId = = FUNCTION_PRJ ) ;
type = pExprs [ i ] . base . param [ 1 ] . nType ;
bytes = pExprs [ i ] . base . param [ 1 ] . nLen ;
if ( type = = TSDB_DATA_TYPE_BINARY | | type = = TSDB_DATA_TYPE_NCHAR ) {
bytes + = VARSTR_HEADER_SIZE ;
}
} else {
int32_t j = getColumnIndexInSource ( pTableInfo , & pExprs [ i ] . base , pTagCols ) ;
2021-11-04 05:24:19 +00:00
if ( TSDB_COL_IS_TAG ( pExprs [ i ] . base . pColumns - > flag ) ) {
2021-11-02 05:37:31 +00:00
if ( j < TSDB_TBNAME_COLUMN_INDEX | | j > = pTableInfo - > numOfTags ) {
tfree ( pExprs ) ;
return TSDB_CODE_QRY_INVALID_MSG ;
}
} else {
if ( j < PRIMARYKEY_TIMESTAMP_COL_ID | | j > = pTableInfo - > numOfCols ) {
tfree ( pExprs ) ;
return TSDB_CODE_QRY_INVALID_MSG ;
}
}
2021-11-04 05:24:19 +00:00
if ( pExprs [ i ] . base . pColumns - > info . colId ! = TSDB_TBNAME_COLUMN_INDEX & & j > = 0 ) {
SColumnInfo * pCol = ( TSDB_COL_IS_TAG ( pExprs [ i ] . base . pColumns - > flag ) ) ? & pTagCols [ j ] : & pTableInfo - > colList [ j ] ;
2021-11-02 05:37:31 +00:00
type = pCol - > type ;
bytes = pCol - > bytes ;
} else {
2021-12-27 08:10:39 +00:00
const SSchema * s = tGetTbnameColumnSchema ( ) ;
2021-11-02 05:37:31 +00:00
type = s - > type ;
bytes = s - > bytes ;
}
// if (pExprs[i].base.flist.numOfFilters > 0) {
// int32_t ret = cloneExprFilterInfo(&pExprs[i].base.flist.filterInfo, pExprMsg[i]->flist.filterInfo,
// pExprMsg[i]->flist.numOfFilters);
// if (ret) {
// tfree(pExprs);
// return ret;
// }
// }
}
int32_t param = ( int32_t ) pExprs [ i ] . base . param [ 0 ] . i ;
// if (functionId != FUNCTION_ARITHM &&
// (type != pExprs[i].base.colType || bytes != pExprs[i].base.colBytes)) {
// tfree(pExprs);
// return TSDB_CODE_QRY_INVALID_MSG;
// }
// todo remove it
SResultDataInfo info ;
if ( getResultDataInfo ( type , bytes , functionId , param , & info , 0 , isSuperTable /*, pUdfInfo*/ ) ! = TSDB_CODE_SUCCESS ) {
tfree ( pExprs ) ;
return TSDB_CODE_QRY_INVALID_MSG ;
}
if ( functionId = = FUNCTION_TAG_DUMMY | | functionId = = FUNCTION_TS_DUMMY ) {
tagLen + = pExprs [ i ] . base . resSchema . bytes ;
}
assert ( isValidDataType ( pExprs [ i ] . base . resSchema . type ) ) ;
}
// the tag length is affected by other tag columns, so this should be update.
updateOutputBufForTopBotQuery ( pTableInfo , pTagCols , pExprs , numOfOutput , tagLen , isSuperTable ) ;
* pExprInfo = pExprs ;
return TSDB_CODE_SUCCESS ;
}
int32_t createQueryFilter ( char * data , uint16_t len , SFilterInfo * * pFilters ) {
tExprNode * expr = NULL ;
TRY ( TSDB_MAX_TAG_CONDITIONS ) {
expr = exprTreeFromBinary ( data , len ) ;
} CATCH ( code ) {
CLEANUP_EXECUTE ( ) ;
return code ;
} END_TRY
if ( expr = = NULL ) {
//qError("failed to create expr tree");
return TSDB_CODE_QRY_APP_ERROR ;
}
// int32_t ret = filterInitFromTree(expr, pFilters, 0);
// tExprTreeDestroy(expr, NULL);
// return ret;
}
// todo refactor
2022-01-10 12:44:11 +00:00
int32_t createIndirectQueryFuncExprFromMsg ( SQueryTableReq * pQueryMsg , int32_t numOfOutput , SExprInfo * * pExprInfo ,
2021-11-02 05:37:31 +00:00
SSqlExpr * * pExpr , SExprInfo * prevExpr , struct SUdfInfo * pUdfInfo ) {
// *pExprInfo = NULL;
// int32_t code = TSDB_CODE_SUCCESS;
//
// SExprInfo *pExprs = (SExprInfo *)calloc(numOfOutput, sizeof(SExprInfo));
// if (pExprs == NULL) {
// return TSDB_CODE_QRY_OUT_OF_MEMORY;
// }
//
// bool isSuperTable = QUERY_IS_STABLE_QUERY(pQueryMsg->queryType);
//
// for (int32_t i = 0; i < numOfOutput; ++i) {
// pExprs[i].base = *pExpr[i];
// memset(pExprs[i].base.param, 0, sizeof(SVariant) * tListLen(pExprs[i].base.param));
//
// for (int32_t j = 0; j < pExpr[i]->numOfParams; ++j) {
// taosVariantAssign(&pExprs[i].base.param[j], &pExpr[i]->param[j]);
// }
//
// pExprs[i].base.resSchema.type = 0;
//
// int16_t type = 0;
// int16_t bytes = 0;
//
// // parse the arithmetic expression
// if (pExprs[i].base.functionId == FUNCTION_ARITHM) {
// code = buildArithmeticExprFromMsg(&pExprs[i], pQueryMsg);
//
// if (code != TSDB_CODE_SUCCESS) {
// tfree(pExprs);
// return code;
// }
//
// type = TSDB_DATA_TYPE_DOUBLE;
// bytes = tDataTypes[type].bytes;
// } else {
// int32_t index = pExprs[i].base.colInfo.colIndex;
2021-11-05 02:35:50 +00:00
// assert(prevExpr[index].base.resSchema.colId == pExprs[i].base.pColumns->info.colId);
2021-11-02 05:37:31 +00:00
//
// type = prevExpr[index].base.resSchema.type;
// bytes = prevExpr[index].base.resSchema.bytes;
// }
//
// int32_t param = (int32_t)pExprs[i].base.param[0].i;
// if (getResultDataInfo(type, bytes, functionId, param, &pExprs[i].base.resSchema.type, &pExprs[i].base.resSchema.bytes,
// &pExprs[i].base.interBytes, 0, isSuperTable, pUdfInfo) != TSDB_CODE_SUCCESS) {
// tfree(pExprs);
// return TSDB_CODE_QRY_INVALID_MSG;
// }
//
// assert(isValidDataType(pExprs[i].base.resSchema.type));
// }
//
// *pExprInfo = pExprs;
return TSDB_CODE_SUCCESS ;
}
2022-01-10 12:44:11 +00:00
SGroupbyExpr * createGroupbyExprFromMsg ( SQueryTableReq * pQueryMsg , SColIndex * pColIndex , int32_t * code ) {
2021-11-02 05:37:31 +00:00
if ( pQueryMsg - > numOfGroupCols = = 0 ) {
return NULL ;
}
// using group by tag columns
SGroupbyExpr * pGroupbyExpr = ( SGroupbyExpr * ) calloc ( 1 , sizeof ( SGroupbyExpr ) ) ;
if ( pGroupbyExpr = = NULL ) {
* code = TSDB_CODE_QRY_OUT_OF_MEMORY ;
return NULL ;
}
pGroupbyExpr - > columnInfo = taosArrayInit ( pQueryMsg - > numOfGroupCols , sizeof ( SColIndex ) ) ;
for ( int32_t i = 0 ; i < pQueryMsg - > numOfGroupCols ; + + i ) {
taosArrayPush ( pGroupbyExpr - > columnInfo , & pColIndex [ i ] ) ;
}
return pGroupbyExpr ;
}
//int32_t doCreateFilterInfo(SColumnInfo* pCols, int32_t numOfCols, int32_t numOfFilterCols, SSingleColumnFilterInfo** pFilterInfo, uint64_t qId) {
// *pFilterInfo = calloc(1, sizeof(SSingleColumnFilterInfo) * numOfFilterCols);
// if (*pFilterInfo == NULL) {
// return TSDB_CODE_QRY_OUT_OF_MEMORY;
// }
//
// for (int32_t i = 0, j = 0; i < numOfCols; ++i) {
// if (pCols[i].flist.numOfFilters > 0) {
// SSingleColumnFilterInfo* pFilter = &((*pFilterInfo)[j]);
//
// memcpy(&pFilter->info, &pCols[i], sizeof(SColumnInfo));
// pFilter->info = pCols[i];
//
// pFilter->numOfFilters = pCols[i].flist.numOfFilters;
// pFilter->pFilters = calloc(pFilter->numOfFilters, sizeof(SColumnFilterElem));
// if (pFilter->pFilters == NULL) {
// return TSDB_CODE_QRY_OUT_OF_MEMORY;
// }
//
// for (int32_t f = 0; f < pFilter->numOfFilters; ++f) {
// SColumnFilterElem* pSingleColFilter = &pFilter->pFilters[f];
// pSingleColFilter->filterInfo = pCols[i].flist.filterInfo[f];
//
// int32_t lower = pSingleColFilter->filterInfo.lowerRelOptr;
// int32_t upper = pSingleColFilter->filterInfo.upperRelOptr;
// if (lower == TSDB_RELATION_INVALID && upper == TSDB_RELATION_INVALID) {
// //qError("QInfo:0x%"PRIx64" invalid filter info", qId);
// return TSDB_CODE_QRY_INVALID_MSG;
// }
//
// pSingleColFilter->fp = getFilterOperator(lower, upper);
// if (pSingleColFilter->fp == NULL) {
// //qError("QInfo:0x%"PRIx64" invalid filter info", qId);
// return TSDB_CODE_QRY_INVALID_MSG;
// }
//
// pSingleColFilter->bytes = pCols[i].bytes;
//
// if (lower == TSDB_RELATION_IN) {
//// buildFilterSetFromBinary(&pSingleColFilter->q, (char *)(pSingleColFilter->filterInfo.pz), (int32_t)(pSingleColFilter->filterInfo.len));
// }
// }
//
// j++;
// }
// }
//
// return TSDB_CODE_SUCCESS;
//}
void * doDestroyFilterInfo ( SSingleColumnFilterInfo * pFilterInfo , int32_t numOfFilterCols ) {
// for (int32_t i = 0; i < numOfFilterCols; ++i) {
// if (pFilterInfo[i].numOfFilters > 0) {
// if (pFilterInfo[i].pFilters->filterInfo.lowerRelOptr == TSDB_RELATION_IN) {
// taosHashCleanup((SHashObj *)(pFilterInfo[i].pFilters->q));
// }
// tfree(pFilterInfo[i].pFilters);
// }
// }
//
// tfree(pFilterInfo);
return NULL ;
}
2022-01-08 08:28:44 +00:00
int32_t createFilterInfo ( STaskAttr * pQueryAttr , uint64_t qId ) {
2021-11-02 05:37:31 +00:00
for ( int32_t i = 0 ; i < pQueryAttr - > numOfCols ; + + i ) {
// if (pQueryAttr->tableCols[i].flist.numOfFilters > 0 && pQueryAttr->tableCols[i].flist.filterInfo != NULL) {
// pQueryAttr->numOfFilterCols++;
// }
}
if ( pQueryAttr - > numOfFilterCols = = 0 ) {
return TSDB_CODE_SUCCESS ;
}
2022-01-10 11:48:21 +00:00
// doCreateFilterInfo(pQueryAttr->tableCols, pQueryAttr->numOfCols, pQueryAttr->numOfFilterCols,
// &pQueryAttr->pFilterInfo, qId);
2021-11-02 05:37:31 +00:00
pQueryAttr - > createFilterOperator = true ;
return TSDB_CODE_SUCCESS ;
}
2022-01-08 08:28:44 +00:00
static void doUpdateExprColumnIndex ( STaskAttr * pQueryAttr ) {
2021-11-02 05:37:31 +00:00
assert ( pQueryAttr - > pExpr1 ! = NULL & & pQueryAttr ! = NULL ) ;
for ( int32_t k = 0 ; k < pQueryAttr - > numOfOutput ; + + k ) {
SSqlExpr * pSqlExprMsg = & pQueryAttr - > pExpr1 [ k ] . base ;
// if (pSqlExprMsg->functionId == FUNCTION_ARITHM) {
// continue;
// }
// todo opt performance
2021-11-05 02:35:50 +00:00
SColIndex * pColIndex = NULL ; /*&pSqlExprMsg->colInfo;*/
2021-11-02 05:37:31 +00:00
if ( TSDB_COL_IS_NORMAL_COL ( pColIndex - > flag ) ) {
int32_t f = 0 ;
for ( f = 0 ; f < pQueryAttr - > numOfCols ; + + f ) {
if ( pColIndex - > colId = = pQueryAttr - > tableCols [ f ] . colId ) {
pColIndex - > colIndex = f ;
break ;
}
}
assert ( f < pQueryAttr - > numOfCols ) ;
} else if ( pColIndex - > colId < = TSDB_UD_COLUMN_INDEX ) {
// do nothing for user-defined constant value result columns
} else {
int32_t f = 0 ;
for ( f = 0 ; f < pQueryAttr - > numOfTags ; + + f ) {
if ( pColIndex - > colId = = pQueryAttr - > tagColList [ f ] . colId ) {
pColIndex - > colIndex = f ;
break ;
}
}
assert ( f < pQueryAttr - > numOfTags | | pColIndex - > colId = = TSDB_TBNAME_COLUMN_INDEX ) ;
}
}
}
2022-01-08 08:28:44 +00:00
void setResultBufSize ( STaskAttr * pQueryAttr , SRspResultInfo * pResultInfo ) {
2021-11-02 05:37:31 +00:00
const int32_t DEFAULT_RESULT_MSG_SIZE = 1024 * ( 1024 + 512 ) ;
// the minimum number of rows for projection query
const int32_t MIN_ROWS_FOR_PRJ_QUERY = 8192 ;
const int32_t DEFAULT_MIN_ROWS = 4096 ;
const float THRESHOLD_RATIO = 0.85f ;
if ( isProjQuery ( pQueryAttr ) ) {
int32_t numOfRes = DEFAULT_RESULT_MSG_SIZE / pQueryAttr - > resultRowSize ;
if ( numOfRes < MIN_ROWS_FOR_PRJ_QUERY ) {
numOfRes = MIN_ROWS_FOR_PRJ_QUERY ;
}
pResultInfo - > capacity = numOfRes ;
} else { // in case of non-prj query, a smaller output buffer will be used.
pResultInfo - > capacity = DEFAULT_MIN_ROWS ;
}
pResultInfo - > threshold = ( int32_t ) ( pResultInfo - > capacity * THRESHOLD_RATIO ) ;
pResultInfo - > total = 0 ;
}
FORCE_INLINE bool checkQIdEqual ( void * qHandle , uint64_t qId ) {
return ( ( SQInfo * ) qHandle ) - > qId = = qId ;
}
2022-01-08 08:28:44 +00:00
int32_t initQInfo ( STsBufInfo * pTsBufInfo , void * tsdb , void * sourceOptr , SQInfo * pQInfo , STaskParam * param , char * start ,
2021-11-02 05:37:31 +00:00
int32_t prevResultLen , void * merger ) {
int32_t code = TSDB_CODE_SUCCESS ;
2022-01-08 08:28:44 +00:00
STaskRuntimeEnv * pRuntimeEnv = & pQInfo - > runtimeEnv ;
2021-11-02 05:37:31 +00:00
pRuntimeEnv - > qinfo = pQInfo ;
2022-01-08 08:28:44 +00:00
STaskAttr * pQueryAttr = pRuntimeEnv - > pQueryAttr ;
2021-11-02 05:37:31 +00:00
STSBuf * pTsBuf = NULL ;
if ( pTsBufInfo - > tsLen > 0 ) { // open new file to save the result
char * tsBlock = start + pTsBufInfo - > tsOffset ;
pTsBuf = tsBufCreateFromCompBlocks ( tsBlock , pTsBufInfo - > tsNumOfBlocks , pTsBufInfo - > tsLen , pTsBufInfo - > tsOrder ,
pQueryAttr - > vgId ) ;
if ( pTsBuf = = NULL ) {
code = TSDB_CODE_QRY_NO_DISKSPACE ;
goto _error ;
}
tsBufResetPos ( pTsBuf ) ;
bool ret = tsBufNextPos ( pTsBuf ) ;
UNUSED ( ret ) ;
}
SArray * prevResult = NULL ;
if ( prevResultLen > 0 ) {
prevResult = interResFromBinary ( param - > prevResult , prevResultLen ) ;
pRuntimeEnv - > prevResult = prevResult ;
}
pRuntimeEnv - > currentOffset = pQueryAttr - > limit . offset ;
if ( tsdb ! = NULL ) {
// pQueryAttr->precision = tsdbGetCfg(tsdb)->precision;
}
if ( ( QUERY_IS_ASC_QUERY ( pQueryAttr ) & & ( pQueryAttr - > window . skey > pQueryAttr - > window . ekey ) ) | |
( ! QUERY_IS_ASC_QUERY ( pQueryAttr ) & & ( pQueryAttr - > window . ekey > pQueryAttr - > window . skey ) ) ) {
//qDebug("QInfo:0x%"PRIx64" no result in time range %" PRId64 "-%" PRId64 ", order %d", pQInfo->qId, pQueryAttr->window.skey,
// pQueryAttr->window.ekey, pQueryAttr->order.order);
2022-01-08 14:59:24 +00:00
// setTaskStatus(pOperator->pTaskInfo, QUERY_COMPLETED);
2021-11-02 05:37:31 +00:00
pRuntimeEnv - > tableqinfoGroupInfo . numOfTables = 0 ;
// todo free memory
return TSDB_CODE_SUCCESS ;
}
if ( pRuntimeEnv - > tableqinfoGroupInfo . numOfTables = = 0 ) {
//qDebug("QInfo:0x%"PRIx64" no table qualified for tag filter, abort query", pQInfo->qId);
2022-01-08 14:59:24 +00:00
// setTaskStatus(pOperator->pTaskInfo, QUERY_COMPLETED);
2021-11-02 05:37:31 +00:00
return TSDB_CODE_SUCCESS ;
}
// filter the qualified
if ( ( code = doInitQInfo ( pQInfo , pTsBuf , tsdb , sourceOptr , param - > tableScanOperator , param - > pOperator , merger ) ) ! = TSDB_CODE_SUCCESS ) {
goto _error ;
}
return code ;
_error :
// table query ref will be decrease during error handling
2022-01-25 02:41:35 +00:00
// doDestroyTask(pQInfo);
2021-11-02 05:37:31 +00:00
return code ;
}
//TODO refactor
void freeColumnFilterInfo ( SColumnFilterInfo * pFilter , int32_t numOfFilters ) {
if ( pFilter = = NULL | | numOfFilters = = 0 ) {
return ;
}
for ( int32_t i = 0 ; i < numOfFilters ; i + + ) {
if ( pFilter [ i ] . filterstr & & pFilter [ i ] . pz ) {
free ( ( void * ) ( pFilter [ i ] . pz ) ) ;
}
}
free ( pFilter ) ;
}
static void doDestroyTableQueryInfo ( STableGroupInfo * pTableqinfoGroupInfo ) {
if ( pTableqinfoGroupInfo - > pGroupList ! = NULL ) {
int32_t numOfGroups = ( int32_t ) taosArrayGetSize ( pTableqinfoGroupInfo - > pGroupList ) ;
for ( int32_t i = 0 ; i < numOfGroups ; + + i ) {
SArray * p = taosArrayGetP ( pTableqinfoGroupInfo - > pGroupList , i ) ;
size_t num = taosArrayGetSize ( p ) ;
for ( int32_t j = 0 ; j < num ; + + j ) {
STableQueryInfo * item = taosArrayGetP ( p , j ) ;
destroyTableQueryInfoImpl ( item ) ;
}
taosArrayDestroy ( p ) ;
}
}
taosArrayDestroy ( pTableqinfoGroupInfo - > pGroupList ) ;
taosHashCleanup ( pTableqinfoGroupInfo - > map ) ;
pTableqinfoGroupInfo - > pGroupList = NULL ;
pTableqinfoGroupInfo - > map = NULL ;
pTableqinfoGroupInfo - > numOfTables = 0 ;
}
void * destroyQueryFuncExpr ( SExprInfo * pExprInfo , int32_t numOfExpr ) {
if ( pExprInfo = = NULL ) {
assert ( numOfExpr = = 0 ) ;
return NULL ;
}
for ( int32_t i = 0 ; i < numOfExpr ; + + i ) {
if ( pExprInfo [ i ] . pExpr ! = NULL ) {
tExprTreeDestroy ( pExprInfo [ i ] . pExpr , NULL ) ;
}
// if (pExprInfo[i].base.flist.filterInfo) {
// freeColumnFilterInfo(pExprInfo[i].base.flist.filterInfo, pExprInfo[i].base.flist.numOfFilters);
// }
for ( int32_t j = 0 ; j < pExprInfo [ i ] . base . numOfParams ; + + j ) {
taosVariantDestroy ( & pExprInfo [ i ] . base . param [ j ] ) ;
}
}
tfree ( pExprInfo ) ;
return NULL ;
}
void * freeColumnInfo ( SColumnInfo * pColumnInfo , int32_t numOfCols ) {
if ( pColumnInfo ! = NULL ) {
assert ( numOfCols > = 0 ) ;
for ( int32_t i = 0 ; i < numOfCols ; i + + ) {
freeColumnFilterInfo ( pColumnInfo [ i ] . flist . filterInfo , pColumnInfo [ i ] . flist . numOfFilters ) ;
}
tfree ( pColumnInfo ) ;
}
return NULL ;
}
2022-01-25 02:41:35 +00:00
void doDestroyTask ( SExecTaskInfo * pTaskInfo ) {
2022-01-26 06:51:57 +00:00
qDebug ( " %s execTask is freed " , GET_TASKID ( pTaskInfo ) ) ;
2022-01-25 02:41:35 +00:00
doDestroyTableQueryInfo ( & pTaskInfo - > tableqinfoGroupInfo ) ;
// taosArrayDestroy(pTaskInfo->summary.queryProfEvents);
// taosHashCleanup(pTaskInfo->summary.operatorProfResults);
2021-11-02 05:37:31 +00:00
2022-01-25 15:08:22 +00:00
tfree ( pTaskInfo - > sql ) ;
tfree ( pTaskInfo - > id . str ) ;
tfree ( pTaskInfo ) ;
2021-11-02 05:37:31 +00:00
}
static void doSetTagValueToResultBuf ( char * output , const char * val , int16_t type , int16_t bytes ) {
if ( val = = NULL ) {
setNull ( output , type , bytes ) ;
return ;
}
if ( IS_VAR_DATA_TYPE ( type ) ) {
// Binary data overflows for sort of unknown reasons. Let trim the overflow data
if ( varDataTLen ( val ) > bytes ) {
int32_t maxLen = bytes - VARSTR_HEADER_SIZE ;
int32_t len = ( varDataLen ( val ) > maxLen ) ? maxLen : varDataLen ( val ) ;
memcpy ( varDataVal ( output ) , varDataVal ( val ) , len ) ;
varDataSetLen ( output , len ) ;
} else {
varDataCopy ( output , val ) ;
}
} else {
memcpy ( output , val , bytes ) ;
}
}
static int64_t getQuerySupportBufSize ( size_t numOfTables ) {
size_t s1 = sizeof ( STableQueryInfo ) ;
size_t s2 = sizeof ( SHashNode ) ;
// size_t s3 = sizeof(STableCheckInfo); buffer consumption in tsdb
return ( int64_t ) ( ( s1 + s2 ) * 1.5 * numOfTables ) ;
}
int32_t checkForQueryBuf ( size_t numOfTables ) {
int64_t t = getQuerySupportBufSize ( numOfTables ) ;
if ( tsQueryBufferSizeBytes < 0 ) {
return TSDB_CODE_SUCCESS ;
} else if ( tsQueryBufferSizeBytes > 0 ) {
while ( 1 ) {
int64_t s = tsQueryBufferSizeBytes ;
int64_t remain = s - t ;
if ( remain > = 0 ) {
if ( atomic_val_compare_exchange_64 ( & tsQueryBufferSizeBytes , s , remain ) = = s ) {
return TSDB_CODE_SUCCESS ;
}
} else {
return TSDB_CODE_QRY_NOT_ENOUGH_BUFFER ;
}
}
}
// disable query processing if the value of tsQueryBufferSize is zero.
return TSDB_CODE_QRY_NOT_ENOUGH_BUFFER ;
}
bool checkNeedToCompressQueryCol ( SQInfo * pQInfo ) {
2022-01-08 08:28:44 +00:00
STaskRuntimeEnv * pRuntimeEnv = & pQInfo - > runtimeEnv ;
STaskAttr * pQueryAttr = pRuntimeEnv - > pQueryAttr ;
2021-11-02 05:37:31 +00:00
SSDataBlock * pRes = pRuntimeEnv - > outputBuf ;
if ( GET_NUM_OF_RESULTS ( & ( pQInfo - > runtimeEnv ) ) < = 0 ) {
return false ;
}
int32_t numOfRows = pQueryAttr - > pExpr2 ? GET_NUM_OF_RESULTS ( pRuntimeEnv ) : pRes - > info . rows ;
int32_t numOfCols = pQueryAttr - > pExpr2 ? pQueryAttr - > numOfExpr2 : pQueryAttr - > numOfOutput ;
for ( int32_t col = 0 ; col < numOfCols ; + + col ) {
SColumnInfoData * pColRes = taosArrayGet ( pRes - > pDataBlock , col ) ;
int32_t colSize = pColRes - > info . bytes * numOfRows ;
if ( NEEDTO_COMPRESS_QUERY ( colSize ) ) {
return true ;
}
}
return false ;
}
void releaseQueryBuf ( size_t numOfTables ) {
if ( tsQueryBufferSizeBytes < 0 ) {
return ;
}
int64_t t = getQuerySupportBufSize ( numOfTables ) ;
// restore value is not enough buffer available
atomic_add_fetch_64 ( & tsQueryBufferSizeBytes , t ) ;
}
2022-01-08 08:28:44 +00:00
void freeQueryAttr ( STaskAttr * pQueryAttr ) {
2021-11-02 05:37:31 +00:00
if ( pQueryAttr ! = NULL ) {
if ( pQueryAttr - > fillVal ! = NULL ) {
tfree ( pQueryAttr - > fillVal ) ;
}
pQueryAttr - > pFilterInfo = doDestroyFilterInfo ( pQueryAttr - > pFilterInfo , pQueryAttr - > numOfFilterCols ) ;
pQueryAttr - > pExpr1 = destroyQueryFuncExpr ( pQueryAttr - > pExpr1 , pQueryAttr - > numOfOutput ) ;
pQueryAttr - > pExpr2 = destroyQueryFuncExpr ( pQueryAttr - > pExpr2 , pQueryAttr - > numOfExpr2 ) ;
pQueryAttr - > pExpr3 = destroyQueryFuncExpr ( pQueryAttr - > pExpr3 , pQueryAttr - > numOfExpr3 ) ;
tfree ( pQueryAttr - > tagColList ) ;
tfree ( pQueryAttr - > pFilterInfo ) ;
pQueryAttr - > tableCols = freeColumnInfo ( pQueryAttr - > tableCols , pQueryAttr - > numOfCols ) ;
if ( pQueryAttr - > pGroupbyExpr ! = NULL ) {
taosArrayDestroy ( pQueryAttr - > pGroupbyExpr - > columnInfo ) ;
tfree ( pQueryAttr - > pGroupbyExpr ) ;
}
// filterFreeInfo(pQueryAttr->pFilters);
}
}