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-28 08:35:36 +00:00
2022-04-04 06:54:39 +00:00
# include "filter.h"
# include "function.h"
2022-04-20 06:59:06 +00:00
# include "functionMgt.h"
# include "os.h"
2022-04-04 06:54:39 +00:00
# include "querynodes.h"
2022-04-20 06:59:06 +00:00
# include "tfill.h"
2022-04-23 10:29:45 +00:00
# include "tname.h"
2022-02-22 05:12:03 +00:00
2022-03-04 05:25:39 +00:00
# include "tdatablock.h"
2021-11-02 05:37:31 +00:00
# include "tglobal.h"
2022-01-20 09:10:28 +00:00
# include "tmsg.h"
2022-03-04 05:25:39 +00:00
# include "tsort.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"
2022-03-15 06:37:26 +00:00
# include "query.h"
2021-11-02 05:37:31 +00:00
# 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-04-23 10:29:45 +00:00
# include "vnode.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-03-29 07:24:25 +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))
2022-03-29 07:24:25 +00:00
# define SDATA_BLOCK_INITIALIZER \
( SDataBlockInfo ) { { 0 } , 0 }
2021-11-02 05:37:31 +00:00
# define GET_FORWARD_DIRECTION_FACTOR(ord) (((ord) == TSDB_ORDER_ASC) ? QUERY_ASC_FORWARD_STEP : QUERY_DESC_FORWARD_STEP)
enum {
2022-03-29 07:24:25 +00:00
TS_JOIN_TS_EQUAL = 0 ,
TS_JOIN_TS_NOT_EQUALS = 1 ,
2021-11-02 05:37:31 +00:00
TS_JOIN_TAG_NOT_EQUALS = 2 ,
} ;
typedef enum SResultTsInterpType {
RESULT_ROW_START_INTERP = 1 ,
2022-03-29 07:24:25 +00:00
RESULT_ROW_END_INTERP = 2 ,
2021-11-02 05:37:31 +00:00
} SResultTsInterpType ;
#if 0
static UNUSED_FUNC void * u_malloc ( size_t __size ) {
2022-03-09 16:36:30 +00:00
uint32_t v = taosRand ( ) ;
2021-11-02 05:37:31 +00:00
if ( v % 1000 < = 0 ) {
return NULL ;
} else {
2022-03-25 16:29:53 +00:00
return taosMemoryMalloc ( __size ) ;
2021-11-02 05:37:31 +00:00
}
}
static UNUSED_FUNC void * u_calloc ( size_t num , size_t __size ) {
2022-03-09 16:36:30 +00:00
uint32_t v = taosRand ( ) ;
2021-11-02 05:37:31 +00:00
if ( v % 1000 < = 0 ) {
return NULL ;
} else {
2022-03-25 16:29:53 +00:00
return taosMemoryCalloc ( num , __size ) ;
2021-11-02 05:37:31 +00:00
}
}
static UNUSED_FUNC void * u_realloc ( void * p , size_t __size ) {
2022-03-09 16:36:30 +00:00
uint32_t v = taosRand ( ) ;
2021-11-02 05:37:31 +00:00
if ( v % 5 < = 1 ) {
return NULL ;
} else {
2022-03-25 16:29:53 +00:00
return taosMemoryRealloc ( p , __size ) ;
2021-11-02 05:37:31 +00:00
}
}
# 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)
2022-03-29 07:24:25 +00:00
# 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 ) {
2021-11-02 05:37:31 +00:00
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-02-24 09:18:56 +00:00
static void getNextTimeWindow ( SInterval * pInterval , int32_t precision , int32_t order , STimeWindow * tw ) {
int32_t factor = GET_FORWARD_DIRECTION_FACTOR ( order ) ;
if ( pInterval - > intervalUnit ! = ' n ' & & pInterval - > intervalUnit ! = ' y ' ) {
tw - > skey + = pInterval - > sliding * factor ;
tw - > ekey = tw - > skey + pInterval - > interval - 1 ;
2021-11-02 05:37:31 +00:00
return ;
}
2022-02-24 09:18:56 +00:00
int64_t key = tw - > skey , interval = pInterval - > interval ;
2022-03-29 07:24:25 +00:00
// convert key to second
2022-02-24 09:18:56 +00:00
key = convertTimePrecision ( key , precision , TSDB_TIME_PRECISION_MILLI ) / 1000 ;
2021-11-02 05:37:31 +00:00
2022-02-24 09:18:56 +00:00
if ( pInterval - > intervalUnit = = ' y ' ) {
2021-11-02 05:37:31 +00:00
interval * = 12 ;
}
struct tm tm ;
2022-03-29 07:24:25 +00:00
time_t t = ( time_t ) key ;
2022-03-11 08:49:07 +00:00
taosLocalTime ( & t , & tm ) ;
2021-11-02 05:37:31 +00:00
int mon = ( int ) ( tm . tm_year * 12 + tm . tm_mon + interval * factor ) ;
tm . tm_year = mon / 12 ;
tm . tm_mon = mon % 12 ;
2022-04-13 04:38:57 +00:00
tw - > skey = convertTimePrecision ( ( int64_t ) taosMktime ( & tm ) * 1000L , TSDB_TIME_PRECISION_MILLI , precision ) ;
2021-11-02 05:37:31 +00:00
mon = ( int ) ( mon + interval ) ;
tm . tm_year = mon / 12 ;
tm . tm_mon = mon % 12 ;
2022-04-13 04:38:57 +00:00
tw - > ekey = convertTimePrecision ( ( int64_t ) taosMktime ( & tm ) * 1000L , TSDB_TIME_PRECISION_MILLI , precision ) ;
2021-11-02 05:37:31 +00:00
tw - > ekey - = 1 ;
}
static void doSetTagValueToResultBuf ( char * output , const char * val , int16_t type , int16_t bytes ) ;
2022-03-29 07:24:25 +00:00
static bool functionNeedToExecute ( SqlFunctionCtx * pCtx ) ;
2021-11-02 05:37:31 +00:00
2022-04-18 02:46:07 +00:00
static void setBlockStatisInfo ( SqlFunctionCtx * pCtx , SExprInfo * pExpr , SSDataBlock * pSDataBlock ) ;
2021-11-02 05:37:31 +00:00
2022-03-29 07:24:25 +00:00
static void destroyTableQueryInfoImpl ( STableQueryInfo * pTableQueryInfo ) ;
2021-11-02 05:37:31 +00:00
static SColumnInfo * extractColumnFilterInfo ( SExprInfo * pExpr , int32_t numOfOutput , int32_t * numOfFilterCols ) ;
2022-03-29 07:24:25 +00:00
static int32_t setTimestampListJoinInfo ( STaskRuntimeEnv * pRuntimeEnv , SVariant * pTag , STableQueryInfo * pTableQueryInfo ) ;
static void releaseQueryBuf ( size_t numOfTables ) ;
static int32_t binarySearchForKey ( char * pValue , int num , TSKEY key , int order ) ;
2022-04-26 05:09:29 +00:00
// static SQueryTableDataCond createTsdbQueryCond(STaskAttr* pQueryAttr, STimeWindow* win);
2021-11-02 05:37:31 +00:00
static STableIdInfo createTableIdInfo ( STableQueryInfo * pTableQueryInfo ) ;
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 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 ) ;
2022-03-21 06:00:30 +00:00
2022-03-14 06:15:26 +00:00
static void destroyIntervalOperatorInfo ( void * param , int32_t numOfOutput ) ;
2022-03-04 07:53:30 +00:00
static void destroyExchangeOperatorInfo ( void * param , int32_t numOfOutput ) ;
2021-11-02 05:37:31 +00:00
static void destroyOperatorInfo ( SOperatorInfo * pOperator ) ;
2022-03-10 03:12:44 +00:00
static void destroySysTableScannerOperatorInfo ( void * param , int32_t numOfOutput ) ;
2021-11-02 05:37:31 +00:00
2022-04-06 09:59:08 +00:00
void doSetOperatorCompleted ( SOperatorInfo * pOperator ) {
2021-11-02 05:37:31 +00:00
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-04-06 09:59:08 +00:00
2022-03-12 07:28:15 +00:00
# define OPTR_IS_OPENED(_optr) (((_optr)->status & OP_OPENED) == OP_OPENED)
# define OPTR_SET_OPENED(_optr) ((_optr)->status |= OP_OPENED)
2022-04-04 06:54:39 +00:00
int32_t operatorDummyOpenFn ( SOperatorInfo * pOperator ) {
2022-03-12 07:28:15 +00:00
OPTR_SET_OPENED ( pOperator ) ;
2022-03-05 07:58:28 +00:00
return TSDB_CODE_SUCCESS ;
2022-03-04 07:53:30 +00:00
}
2022-04-26 12:26:32 +00:00
SOperatorFpSet createOperatorFpSet ( __optr_open_fn_t openFn , __optr_fn_t nextFn , __optr_fn_t streamFn ,
__optr_fn_t cleanup , __optr_close_fn_t closeFn , __optr_encode_fn_t encode ,
__optr_decode_fn_t decode , __optr_get_explain_fn_t explain ) {
SOperatorFpSet fpSet = {
. _openFn = openFn ,
. getNextFn = nextFn ,
. getStreamResFn = streamFn ,
. cleanupFn = cleanup ,
. closeFn = closeFn ,
. encodeResultRow = encode ,
. decodeResultRow = decode ,
. getExplainFn = explain ,
} ;
return fpSet ;
}
2022-04-04 06:54:39 +00:00
void operatorDummyCloseFn ( void * param , int32_t numOfCols ) { }
2022-03-05 07:58:28 +00:00
2022-04-23 10:29:45 +00:00
static int32_t doCopyToSDataBlock ( SSDataBlock * pBlock , SExprInfo * pExprInfo , SDiskbasedBuf * pBuf ,
SGroupResInfo * pGroupResInfo , int32_t orderType , int32_t * rowCellOffset ,
SqlFunctionCtx * pCtx ) ;
2022-02-24 09:18:56 +00:00
2022-04-22 07:07:20 +00:00
static void initCtxOutputBuffer ( SqlFunctionCtx * pCtx , int32_t size ) ;
2022-03-24 03:15:05 +00:00
static void setResultBufSize ( STaskAttr * pQueryAttr , SResultInfo * pResultInfo ) ;
2022-04-23 10:29:45 +00:00
static void doSetTableGroupOutputBuf ( SAggOperatorInfo * pAggInfo , int32_t numOfOutput , uint64_t groupId ,
SExecTaskInfo * pTaskInfo ) ;
2021-11-02 05:37:31 +00:00
2022-02-14 05:20:46 +00:00
SArray * getOrderCheckColumns ( STaskAttr * pQuery ) ;
2021-11-02 05:37:31 +00:00
typedef struct SRowCompSupporter {
2022-03-29 07:24:25 +00:00
STaskRuntimeEnv * pRuntimeEnv ;
int16_t dataOffset ;
__compar_fn_t comFunc ;
2021-11-02 05:37:31 +00:00
} SRowCompSupporter ;
2022-03-29 07:24:25 +00:00
static int compareRowData ( const void * a , const void * b , const void * userData ) {
const SResultRow * pRow1 = ( const SResultRow * ) a ;
const SResultRow * pRow2 = ( const SResultRow * ) b ;
2021-11-02 05:37:31 +00:00
2022-03-29 07:24:25 +00:00
SRowCompSupporter * supporter = ( SRowCompSupporter * ) userData ;
STaskRuntimeEnv * pRuntimeEnv = supporter - > pRuntimeEnv ;
2021-11-02 05:37:31 +00:00
2022-03-29 07:24:25 +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 ;
2022-03-29 07:24:25 +00:00
char * in1 = getPosInResultPage ( pRuntimeEnv - > pQueryAttr , page1 , pRow1 - > offset , offset ) ;
char * in2 = getPosInResultPage ( pRuntimeEnv - > pQueryAttr , page2 , pRow2 - > offset , offset ) ;
2021-11-02 05:37:31 +00:00
return ( in1 ! = NULL & & in2 ! = NULL ) ? supporter - > comFunc ( in1 , in2 ) : 0 ;
}
2022-03-29 07:24:25 +00:00
// setup the output buffer for each operator
2022-04-15 10:06:49 +00:00
SSDataBlock * createResDataBlock ( SDataBlockDescNode * pNode ) {
2022-03-04 11:21:30 +00:00
int32_t numOfCols = LIST_LENGTH ( pNode - > pSlots ) ;
2022-03-09 02:22:53 +00:00
2022-03-25 16:29:53 +00:00
SSDataBlock * pBlock = taosMemoryCalloc ( 1 , sizeof ( SSDataBlock ) ) ;
2022-03-04 11:21:30 +00:00
pBlock - > pDataBlock = taosArrayInit ( numOfCols , sizeof ( SColumnInfoData ) ) ;
2022-03-09 02:22:53 +00:00
pBlock - > info . blockId = pNode - > dataBlockId ;
2022-04-23 10:29:45 +00:00
pBlock - > info . rowSize = pNode - > totalRowSize ; // todo ??
2022-03-09 02:22:53 +00:00
2022-03-29 07:24:25 +00:00
for ( int32_t i = 0 ; i < numOfCols ; + + i ) {
2022-03-04 11:21:30 +00:00
SColumnInfoData idata = { { 0 } } ;
2022-03-29 07:24:25 +00:00
SSlotDescNode * pDescNode = nodesListGetNode ( pNode - > pSlots , i ) ;
2022-03-29 02:08:21 +00:00
if ( ! pDescNode - > output ) {
continue ;
2022-03-28 12:11:02 +00:00
}
2022-03-29 02:08:21 +00:00
2022-04-23 10:29:45 +00:00
idata . info . type = pDescNode - > dataType . type ;
2022-03-29 07:24:25 +00:00
idata . info . bytes = pDescNode - > dataType . bytes ;
idata . info . scale = pDescNode - > dataType . scale ;
2022-03-04 11:21:30 +00:00
idata . info . slotId = pDescNode - > slotId ;
2022-03-09 02:22:53 +00:00
idata . info . precision = pDescNode - > dataType . precision ;
2022-04-06 07:54:52 +00:00
if ( IS_VAR_DATA_TYPE ( idata . info . type ) ) {
pBlock - > info . hasVarCol = true ;
}
2022-03-09 02:22:53 +00:00
taosArrayPush ( pBlock - > pDataBlock , & idata ) ;
2022-03-04 11:21:30 +00:00
}
2022-03-09 02:22:53 +00:00
2022-04-25 09:12:28 +00:00
pBlock - > info . numOfCols = taosArrayGetSize ( pBlock - > pDataBlock ) ;
2022-03-09 02:22:53 +00:00
return pBlock ;
2022-03-04 11:21:30 +00:00
}
2022-03-29 07:24:25 +00:00
static bool hasNull ( SColumn * pColumn , SColumnDataAgg * pStatis ) {
2022-04-23 10:29:45 +00:00
if ( TSDB_COL_IS_TAG ( pColumn - > flag ) | | TSDB_COL_IS_UD_COL ( pColumn - > flag ) | |
pColumn - > 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 ) {
2022-02-22 05:12:03 +00:00
int64_t newCapacity = 0 ;
2021-11-02 05:37:31 +00:00
// more than the capacity, reallocate the resources
if ( pResultRowInfo - > size < pResultRowInfo - > capacity ) {
return ;
}
if ( pResultRowInfo - > capacity > 10000 ) {
newCapacity = ( int64_t ) ( pResultRowInfo - > capacity * 1.25 ) ;
} else {
newCapacity = ( int64_t ) ( pResultRowInfo - > capacity * 1.5 ) ;
}
2022-04-25 08:44:48 +00:00
if ( newCapacity < = pResultRowInfo - > capacity ) {
2022-02-24 09:18:56 +00:00
newCapacity + = 4 ;
}
2022-04-25 08:44:48 +00:00
char * p = taosMemoryRealloc ( pResultRowInfo - > pPosition , newCapacity * sizeof ( SResultRowPosition ) ) ;
if ( p = = NULL ) {
longjmp ( env , TSDB_CODE_OUT_OF_MEMORY ) ;
}
pResultRowInfo - > pPosition = ( SResultRowPosition * ) p ;
2021-11-02 05:37:31 +00:00
int32_t inc = ( int32_t ) newCapacity - pResultRowInfo - > capacity ;
2022-04-11 06:09:47 +00:00
memset ( & pResultRowInfo - > pPosition [ pResultRowInfo - > capacity ] , 0 , sizeof ( SResultRowPosition ) * inc ) ;
2021-11-02 05:37:31 +00:00
pResultRowInfo - > capacity = ( int32_t ) newCapacity ;
}
2022-03-29 07:24:25 +00:00
static bool chkResultRowFromKey ( STaskRuntimeEnv * pRuntimeEnv , SResultRowInfo * pResultRowInfo , char * pData ,
int16_t bytes , bool masterscan , uint64_t uid ) {
2021-11-02 05:37:31 +00:00
bool existed = false ;
SET_RES_WINDOW_KEY ( pRuntimeEnv - > keyBuf , pData , bytes , uid ) ;
2022-03-29 07:24:25 +00:00
SResultRow * * p1 =
( SResultRow * * ) taosHashGet ( pRuntimeEnv - > pResultRowHashTable , pRuntimeEnv - > keyBuf , GET_RES_WINDOW_KEY_LEN ( bytes ) ) ;
2021-11-02 05:37:31 +00:00
// 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 ;
} else if ( pResultRowInfo - > size = = 1 ) {
2022-04-23 10:29:45 +00:00
// existed = (pResultRowInfo->pResult[0] == (*p1));
2021-11-02 05:37:31 +00:00
} else { // check if current pResultRowInfo contains the existed pResultRow
SET_RES_EXT_WINDOW_KEY ( pRuntimeEnv - > keyBuf , pData , bytes , uid , pResultRowInfo ) ;
2022-03-29 07:24:25 +00:00
int64_t * index =
taosHashGet ( pRuntimeEnv - > pResultRowListSet , pRuntimeEnv - > keyBuf , GET_RES_EXT_WINDOW_KEY_LEN ( bytes ) ) ;
2021-11-02 05:37:31 +00:00
if ( index ! = NULL ) {
existed = true ;
} else {
existed = false ;
}
}
}
return existed ;
}
return p1 ! = NULL ;
}
2022-03-15 06:37:26 +00:00
SResultRow * getNewResultRow_rv ( SDiskbasedBuf * pResultBuf , int64_t tableGroupId , int32_t interBufSize ) {
2022-03-29 07:24:25 +00:00
SFilePage * pData = NULL ;
2022-03-15 06:37:26 +00:00
// in the first scan, new space needed for results
int32_t pageId = - 1 ;
SIDList list = getDataBufPagesIdList ( pResultBuf , tableGroupId ) ;
if ( taosArrayGetSize ( list ) = = 0 ) {
pData = getNewBufPage ( pResultBuf , tableGroupId , & pageId ) ;
pData - > num = sizeof ( SFilePage ) ;
} else {
SPageInfo * pi = getLastPageInfo ( list ) ;
pData = getBufPage ( pResultBuf , getPageId ( pi ) ) ;
pageId = getPageId ( pi ) ;
2022-04-11 06:09:47 +00:00
if ( pData - > num + interBufSize > getBufPageSize ( pResultBuf ) ) {
2022-03-15 06:37:26 +00:00
// release current page first, and prepare the next one
releaseBufPageInfo ( pResultBuf , pi ) ;
pData = getNewBufPage ( pResultBuf , tableGroupId , & pageId ) ;
if ( pData ! = NULL ) {
pData - > num = sizeof ( SFilePage ) ;
}
}
}
if ( pData = = NULL ) {
return NULL ;
}
// set the number of rows in current disk page
SResultRow * pResultRow = ( SResultRow * ) ( ( char * ) pData + pData - > num ) ;
pResultRow - > pageId = pageId ;
pResultRow - > offset = ( int32_t ) pData - > num ;
2022-04-11 06:09:47 +00:00
pData - > num + = interBufSize ;
2022-03-15 06:37:26 +00:00
return pResultRow ;
}
2022-04-24 12:48:42 +00:00
/**
* the struct of key in hash table
* + - - - - - - - - - - + - - - - - - - - - - - - - - - +
* | group id | key data |
* | 8 bytes | actual length |
* + - - - - - - - - - - + - - - - - - - - - - - - - - - +
*/
2022-04-25 08:44:48 +00:00
static SResultRow * doSetResultOutBufByKey ( SDiskbasedBuf * pResultBuf , SResultRowInfo * pResultRowInfo , int64_t uid ,
2022-04-16 02:00:25 +00:00
char * pData , int16_t bytes , bool masterscan , uint64_t groupId ,
2022-03-29 07:24:25 +00:00
SExecTaskInfo * pTaskInfo , bool isIntervalQuery , SAggSupporter * pSup ) {
2022-04-16 02:00:25 +00:00
SET_RES_WINDOW_KEY ( pSup - > keyBuf , pData , bytes , groupId ) ;
2022-01-20 05:52:46 +00:00
2022-04-23 10:29:45 +00:00
SResultRowPosition * p1 =
( SResultRowPosition * ) taosHashGet ( pSup - > pResultRowHashTable , pSup - > keyBuf , GET_RES_WINDOW_KEY_LEN ( bytes ) ) ;
2022-01-20 05:52:46 +00:00
2022-04-25 08:44:48 +00:00
SResultRow * pResult = NULL ;
2022-01-20 05:52:46 +00:00
// in case of repeat scan/reverse scan, no new time window added.
if ( isIntervalQuery ) {
2022-04-25 08:44:48 +00:00
if ( masterscan & & p1 ! = NULL ) { // the *p1 may be NULL in case of sliding+offset exists.
pResult = getResultRowByPos ( pResultBuf , p1 ) ;
2022-01-20 05:52:46 +00:00
}
} else {
2022-04-23 10:29:45 +00:00
// In case of group by column query, the required SResultRow object must be existInCurrentResusltRowInfo in the
// pResultRowInfo object.
2022-01-20 05:52:46 +00:00
if ( p1 ! = NULL ) {
2022-04-25 08:44:48 +00:00
pResult = getResultRowByPos ( pResultBuf , p1 ) ;
2022-01-20 05:52:46 +00:00
}
}
2022-03-31 08:10:32 +00:00
// 1. close current opened time window
2022-04-25 08:44:48 +00:00
if ( pResultRowInfo - > cur . pageId ! = - 1 & & ( ( pResult = = NULL ) | | ( pResult - > pageId ! = pResultRowInfo - > cur . pageId & &
pResult - > offset ! = pResultRowInfo - > cur . offset ) ) ) {
// todo extract function
SResultRowPosition pos = pResultRowInfo - > cur ;
SFilePage * pPage = getBufPage ( pResultBuf , pos . pageId ) ;
SResultRow * pRow = ( SResultRow * ) ( ( char * ) pPage + pos . offset ) ;
closeResultRow ( pRow ) ;
releaseBufPage ( pResultBuf , pPage ) ;
}
// allocate a new buffer page
prepareResultListBuffer ( pResultRowInfo , pTaskInfo - > env ) ;
if ( pResult = = NULL ) {
pResult = getNewResultRow_rv ( pResultBuf , groupId , pSup - > resultRowSize ) ;
initResultRow ( pResult ) ;
2022-01-20 05:52:46 +00:00
2022-04-25 08:44:48 +00:00
// add a new result set for a new group
SResultRowPosition pos = { . pageId = pResult - > pageId , . offset = pResult - > offset } ;
taosHashPut ( pSup - > pResultRowHashTable , pSup - > keyBuf , GET_RES_WINDOW_KEY_LEN ( bytes ) , & pos , sizeof ( SResultRowPosition ) ) ;
2022-01-20 05:52:46 +00:00
}
2022-04-25 08:44:48 +00:00
// 2. set the new time window to be the new active time window
pResultRowInfo - > pPosition [ pResultRowInfo - > size + + ] =
( SResultRowPosition ) { . pageId = pResult - > pageId , . offset = pResult - > offset } ;
pResultRowInfo - > cur = ( SResultRowPosition ) { . pageId = pResult - > pageId , . offset = pResult - > offset } ;
2022-01-20 05:52:46 +00:00
// too many time window in query
if ( pResultRowInfo - > size > MAX_INTERVAL_TIME_WINDOW ) {
longjmp ( pTaskInfo - > env , TSDB_CODE_QRY_TOO_MANY_TIMEWINDOW ) ;
}
2022-03-31 08:10:32 +00:00
return pResult ;
2022-01-20 05:52:46 +00:00
}
2022-04-23 10:29:45 +00:00
static void getInitialStartTimeWindow ( SInterval * pInterval , int32_t precision , TSKEY ts , STimeWindow * w ,
bool ascQuery ) {
2022-02-24 09:18:56 +00:00
if ( ascQuery ) {
2022-04-20 06:59:06 +00:00
getAlignQueryTimeWindow ( pInterval , precision , ts , w ) ;
2021-11-02 05:37:31 +00:00
} else {
// the start position of the first time window in the endpoint that spreads beyond the queried last timestamp
2022-04-20 06:59:06 +00:00
getAlignQueryTimeWindow ( pInterval , precision , ts , w ) ;
2021-11-02 05:37:31 +00:00
int64_t key = w - > skey ;
2022-03-29 07:24:25 +00:00
while ( key < ts ) { // moving towards end
2022-03-25 06:28:01 +00:00
key = taosTimeAdd ( key , pInterval - > sliding , pInterval - > slidingUnit , precision ) ;
2021-11-02 05:37:31 +00:00
if ( key > = ts ) {
break ;
}
w - > skey = key ;
}
}
}
// get the correct time window according to the handled timestamp
2022-04-23 10:29:45 +00:00
static STimeWindow getActiveTimeWindow ( SDiskbasedBuf * pBuf , SResultRowInfo * pResultRowInfo , int64_t ts ,
SInterval * pInterval , int32_t precision , STimeWindow * win ) {
2021-11-02 05:37:31 +00:00
STimeWindow w = { 0 } ;
2022-04-16 07:15:28 +00:00
if ( pResultRowInfo - > cur . pageId = = - 1 ) { // the first window, from the previous stored value
2022-04-20 06:59:06 +00:00
getInitialStartTimeWindow ( pInterval , precision , ts , & w , true ) ;
2022-03-25 06:28:01 +00:00
w . ekey = taosTimeAdd ( w . skey , pInterval - > interval , pInterval - > intervalUnit , precision ) - 1 ;
2021-11-02 05:37:31 +00:00
} else {
2022-04-16 07:15:28 +00:00
w = getResultRowByPos ( pBuf , & pResultRowInfo - > cur ) - > win ;
2021-11-02 05:37:31 +00:00
}
if ( w . skey > ts | | w . ekey < ts ) {
2022-02-24 09:18:56 +00:00
if ( pInterval - > intervalUnit = = ' n ' | | pInterval - > intervalUnit = = ' y ' ) {
w . skey = taosTimeTruncate ( ts , pInterval , precision ) ;
w . ekey = taosTimeAdd ( w . skey , pInterval - > interval , pInterval - > intervalUnit , precision ) - 1 ;
2021-11-02 05:37:31 +00:00
} else {
int64_t st = w . skey ;
if ( st > ts ) {
2022-02-24 09:18:56 +00:00
st - = ( ( st - ts + pInterval - > sliding - 1 ) / pInterval - > sliding ) * pInterval - > sliding ;
2021-11-02 05:37:31 +00:00
}
2022-02-24 09:18:56 +00:00
int64_t et = st + pInterval - > interval - 1 ;
2021-11-02 05:37:31 +00:00
if ( et < ts ) {
2022-02-24 09:18:56 +00:00
st + = ( ( ts - et + pInterval - > sliding - 1 ) / pInterval - > sliding ) * pInterval - > sliding ;
2021-11-02 05:37:31 +00:00
}
w . skey = st ;
2022-03-25 06:28:01 +00:00
w . ekey = taosTimeAdd ( w . skey , pInterval - > interval , pInterval - > intervalUnit , precision ) - 1 ;
2021-11-02 05:37:31 +00:00
}
}
return w ;
}
// get the correct time window according to the handled timestamp
2022-03-29 07:24:25 +00:00
static STimeWindow getCurrentActiveTimeWindow ( SResultRowInfo * pResultRowInfo , int64_t ts , STaskAttr * pQueryAttr ) {
2021-11-02 05:37:31 +00:00
STimeWindow w = { 0 } ;
2022-03-31 08:10:32 +00:00
#if 0
2022-03-29 07:24:25 +00:00
if ( pResultRowInfo - > curPos = = - 1 ) { // the first window, from the previous stored value
// getInitialStartTimeWindow(pQueryAttr, ts, &w);
2021-11-02 05:37:31 +00:00
if ( pQueryAttr - > interval . intervalUnit = = ' n ' | | pQueryAttr - > interval . intervalUnit = = ' y ' ) {
2022-03-29 07:24:25 +00:00
w . ekey =
taosTimeAdd ( w . skey , pQueryAttr - > interval . interval , pQueryAttr - > interval . intervalUnit , pQueryAttr - > precision ) -
1 ;
2021-11-02 05:37:31 +00:00
} else {
w . ekey = w . skey + pQueryAttr - > interval . interval - 1 ;
}
} else {
2022-03-31 08:10:32 +00:00
w = pRow - > win ;
2021-11-02 05:37:31 +00:00
}
/*
* 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 ;
}
2022-03-31 08:10:32 +00:00
# endif
2021-11-02 05:37:31 +00:00
return w ;
}
// a new buffer page for each table. Needs to opt this design
2022-03-29 07:24:25 +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 ;
}
2022-03-29 07:24:25 +00:00
SFilePage * pData = NULL ;
2021-11-02 05:37:31 +00:00
// in the first scan, new space needed for results
int32_t pageId = - 1 ;
SIDList list = getDataBufPagesIdList ( pResultBuf , tid ) ;
if ( taosArrayGetSize ( list ) = = 0 ) {
2022-02-23 07:10:15 +00:00
pData = getNewBufPage ( pResultBuf , tid , & pageId ) ;
2022-03-15 06:37:26 +00:00
pData - > num = sizeof ( SFilePage ) ;
2021-11-02 05:37:31 +00:00
} 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 ) ;
2022-03-15 06:37:26 +00:00
2022-02-23 07:10:15 +00:00
pData = getNewBufPage ( pResultBuf , tid , & pageId ) ;
2021-11-02 05:37:31 +00:00
if ( pData ! = NULL ) {
2022-03-15 06:37:26 +00:00
pData - > num = sizeof ( SFilePage ) ;
2021-11-02 05:37:31 +00:00
}
}
}
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-03-29 07:24:25 +00:00
static bool chkWindowOutputBufByKey ( STaskRuntimeEnv * pRuntimeEnv , SResultRowInfo * pResultRowInfo , STimeWindow * win ,
bool masterscan , SResultRow * * pResult , int64_t groupId , SqlFunctionCtx * pCtx ,
int32_t numOfOutput , int32_t * rowCellInfoOffset ) {
2021-11-02 05:37:31 +00:00
assert ( win - > skey < = win - > ekey ) ;
2022-03-29 07:24:25 +00:00
return chkResultRowFromKey ( pRuntimeEnv , pResultRowInfo , ( char * ) & win - > skey , TSDB_KEYSIZE , masterscan , groupId ) ;
2021-11-02 05:37:31 +00:00
}
2022-04-23 10:29:45 +00:00
static void setResultRowOutputBufInitCtx_rv ( SResultRow * pResult , SqlFunctionCtx * pCtx , int32_t numOfOutput ,
int32_t * rowCellInfoOffset ) ;
2022-02-24 09:18:56 +00:00
2022-03-29 07:24:25 +00:00
static int32_t setResultOutputBufByKey_rv ( SResultRowInfo * pResultRowInfo , int64_t id , STimeWindow * win , bool masterscan ,
SResultRow * * pResult , int64_t tableGroupId , SqlFunctionCtx * pCtx ,
int32_t numOfOutput , int32_t * rowCellInfoOffset , SAggSupporter * pAggSup ,
SExecTaskInfo * pTaskInfo ) {
2022-02-24 09:18:56 +00:00
assert ( win - > skey < = win - > ekey ) ;
2022-04-25 08:44:48 +00:00
SResultRow * pResultRow = doSetResultOutBufByKey ( pAggSup - > pResultBuf , pResultRowInfo , id , ( char * ) & win - > skey ,
2022-03-29 07:24:25 +00:00
TSDB_KEYSIZE , masterscan , tableGroupId , pTaskInfo , true , pAggSup ) ;
2022-02-24 09:18:56 +00:00
if ( pResultRow = = NULL ) {
* pResult = NULL ;
return TSDB_CODE_SUCCESS ;
}
// set time window for current result
pResultRow - > win = ( * win ) ;
* pResult = pResultRow ;
2022-04-01 02:44:34 +00:00
setResultRowOutputBufInitCtx_rv ( pResultRow , pCtx , numOfOutput , rowCellInfoOffset ) ;
2022-02-24 09:18:56 +00:00
return TSDB_CODE_SUCCESS ;
}
2021-11-02 05:37:31 +00:00
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 {
2022-03-29 07:24:25 +00:00
pResult - > endInterp = true ;
2021-11-02 05:37:31 +00:00
}
}
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 {
2022-03-29 07:24:25 +00:00
return pResult - > endInterp = = true ;
2021-11-02 05:37:31 +00:00
}
}
2022-03-29 07:24:25 +00:00
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 ) {
2021-11-02 05:37:31 +00:00
int32_t forwardStep = 0 ;
if ( order = = TSDB_ORDER_ASC ) {
2022-03-29 07:24:25 +00:00
int32_t end = searchFn ( ( char * ) & pData [ pos ] , numOfRows - pos , ekey , order ) ;
2021-11-02 05:37:31 +00:00
if ( end > = 0 ) {
forwardStep = end ;
if ( pData [ end + pos ] = = ekey ) {
forwardStep + = 1 ;
}
}
} else {
2022-03-29 07:24:25 +00:00
int32_t end = searchFn ( ( char * ) pData , pos + 1 , ekey , order ) ;
2021-11-02 05:37:31 +00:00
if ( end > = 0 ) {
forwardStep = pos - end ;
if ( pData [ end ] = = ekey ) {
forwardStep + = 1 ;
}
}
}
assert ( forwardStep > = 0 ) ;
return forwardStep ;
}
2022-04-23 10:29:45 +00:00
static void doUpdateResultRowIndex ( SResultRowInfo * pResultRowInfo , TSKEY lastKey , bool ascQuery ,
bool timeWindowInterpo ) {
2021-11-02 05:37:31 +00:00
int64_t skey = TSKEY_INITIAL_VAL ;
2022-03-31 08:10:32 +00:00
#if 0
2021-11-02 05:37:31 +00:00
int32_t i = 0 ;
for ( i = pResultRowInfo - > size - 1 ; i > = 0 ; - - i ) {
2022-03-29 07:24:25 +00:00
SResultRow * pResult = pResultRowInfo - > pResult [ i ] ;
2021-11-02 05:37:31 +00:00
if ( pResult - > closed ) {
break ;
}
// new closed result rows
if ( timeWindowInterpo ) {
2022-03-29 07:24:25 +00:00
if ( pResult - > endInterp & &
( ( pResult - > win . skey < = lastKey & & ascQuery ) | | ( pResult - > win . skey > = lastKey & & ! ascQuery ) ) ) {
if ( i > 0 ) { // the first time window, the startInterp is false.
2021-11-02 05:37:31 +00:00
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 ) {
2022-03-29 07:24:25 +00:00
// assert(pResultRowInfo->current == NULL);
2021-11-02 05:37:31 +00:00
assert ( pResultRowInfo - > curPos = = - 1 ) ;
pResultRowInfo - > curPos = - 1 ;
} else {
pResultRowInfo - > curPos = pResultRowInfo - > size - 1 ;
}
} else {
for ( i = pResultRowInfo - > size - 1 ; i > = 0 ; - - i ) {
2022-03-29 07:24:25 +00:00
SResultRow * pResult = pResultRowInfo - > pResult [ i ] ;
2021-11-02 05:37:31 +00:00
if ( pResult - > closed ) {
break ;
}
}
if ( i = = pResultRowInfo - > size - 1 ) {
pResultRowInfo - > curPos = i ;
} else {
pResultRowInfo - > curPos = i + 1 ; // current not closed result object
}
}
2022-03-31 08:10:32 +00:00
# endif
2021-11-02 05:37:31 +00:00
}
2022-04-16 07:15:28 +00:00
//
2022-04-23 10:29:45 +00:00
// static void updateResultRowInfoActiveIndex(SResultRowInfo* pResultRowInfo, const STimeWindow* pWin, TSKEY lastKey,
2022-04-16 07:15:28 +00:00
// bool ascQuery, bool interp) {
// if ((lastKey > pWin->ekey && ascQuery) || (lastKey < pWin->ekey && (!ascQuery))) {
// closeAllResultRows(pResultRowInfo);
// pResultRowInfo->curPos = pResultRowInfo->size - 1;
// } else {
// int32_t step = ascQuery ? 1 : -1;
// doUpdateResultRowIndex(pResultRowInfo, lastKey - step, ascQuery, interp);
// }
//}
2021-11-02 05:37:31 +00:00
2022-03-29 07:24:25 +00:00
static int32_t getNumOfRowsInTimeWindow ( SDataBlockInfo * pDataBlockInfo , TSKEY * pPrimaryColumn , int32_t startPos ,
TSKEY ekey , __block_search_fn_t searchFn , STableQueryInfo * item ,
int32_t order ) {
2021-11-02 05:37:31 +00:00
assert ( startPos > = 0 & & startPos < pDataBlockInfo - > rows ) ;
2022-03-29 07:24:25 +00:00
int32_t num = - 1 ;
int32_t step = GET_FORWARD_DIRECTION_FACTOR ( order ) ;
2021-11-02 05:37:31 +00:00
2022-02-24 09:18:56 +00:00
if ( order = = TSDB_ORDER_ASC ) {
2021-11-02 05:37:31 +00:00
if ( ekey < pDataBlockInfo - > window . ekey & & pPrimaryColumn ) {
num = getForwardStepsInBlock ( pDataBlockInfo - > rows , searchFn , ekey , startPos , order , pPrimaryColumn ) ;
2022-02-24 09:18:56 +00:00
if ( item ! = NULL ) {
2021-11-02 05:37:31 +00:00
item - > lastKey = pPrimaryColumn [ startPos + ( num - 1 ) ] + step ;
}
} else {
num = pDataBlockInfo - > rows - startPos ;
2022-02-24 09:18:56 +00:00
if ( item ! = NULL ) {
2021-11-02 05:37:31 +00:00
item - > lastKey = pDataBlockInfo - > window . ekey + step ;
}
}
} else { // desc
if ( ekey > pDataBlockInfo - > window . skey & & pPrimaryColumn ) {
num = getForwardStepsInBlock ( pDataBlockInfo - > rows , searchFn , ekey , startPos , order , pPrimaryColumn ) ;
2022-02-24 09:18:56 +00:00
if ( item ! = NULL ) {
2021-11-02 05:37:31 +00:00
item - > lastKey = pPrimaryColumn [ startPos - ( num - 1 ) ] + step ;
}
} else {
num = startPos + 1 ;
2022-02-24 09:18:56 +00:00
if ( item ! = NULL ) {
2021-11-02 05:37:31 +00:00
item - > lastKey = pDataBlockInfo - > window . skey + step ;
}
}
}
assert ( num > = 0 ) ;
return num ;
}
2022-03-30 05:41:15 +00:00
// query_range_start, query_range_end, window_duration, window_start, window_end
static void initExecTimeWindowInfo ( SColumnInfoData * pColData , STimeWindow * pQueryWindow ) {
pColData - > info . type = TSDB_DATA_TYPE_TIMESTAMP ;
pColData - > info . bytes = sizeof ( int64_t ) ;
2022-04-19 05:07:23 +00:00
colInfoDataEnsureCapacity ( pColData , 0 , 5 ) ;
2022-03-30 05:41:15 +00:00
colDataAppendInt64 ( pColData , 0 , & pQueryWindow - > skey ) ;
colDataAppendInt64 ( pColData , 1 , & pQueryWindow - > ekey ) ;
int64_t interval = 0 ;
colDataAppendInt64 ( pColData , 2 , & interval ) ; // this value may be variable in case of 'n' and 'y'.
colDataAppendInt64 ( pColData , 3 , & pQueryWindow - > skey ) ;
colDataAppendInt64 ( pColData , 4 , & pQueryWindow - > ekey ) ;
}
2022-04-02 05:32:26 +00:00
static void updateTimeWindowInfo ( SColumnInfoData * pColData , STimeWindow * pWin , bool includeEndpoint ) {
2022-03-30 05:41:15 +00:00
int64_t * ts = ( int64_t * ) pColData - > pData ;
2022-04-23 10:29:45 +00:00
int32_t delta = includeEndpoint ? 1 : 0 ;
2022-03-30 05:41:15 +00:00
2022-04-02 05:32:26 +00:00
int64_t duration = pWin - > ekey - pWin - > skey + delta ;
2022-04-23 10:29:45 +00:00
ts [ 2 ] = duration ; // set the duration
ts [ 3 ] = pWin - > skey ; // window start key
ts [ 4 ] = pWin - > ekey + delta ; // window end key
2022-03-30 05:41:15 +00:00
}
2022-04-23 10:29:45 +00:00
void doApplyFunctions ( SqlFunctionCtx * pCtx , STimeWindow * pWin , SColumnInfoData * pTimeWindowData , int32_t offset ,
int32_t forwardStep , TSKEY * tsCol , int32_t numOfTotal , int32_t numOfOutput , int32_t order ) {
2021-11-02 05:37:31 +00:00
for ( int32_t k = 0 ; k < numOfOutput ; + + k ) {
pCtx [ k ] . startTs = pWin - > skey ;
2022-04-06 11:46:38 +00:00
// keep it temporarily
2022-04-23 10:29:45 +00:00
bool hasAgg = pCtx [ k ] . input . colDataAggIsSet ;
int32_t numOfRows = pCtx [ k ] . input . numOfRows ;
2022-03-22 08:03:42 +00:00
int32_t startOffset = pCtx [ k ] . input . startRowIndex ;
2021-11-02 05:37:31 +00:00
2022-02-24 09:18:56 +00:00
int32_t pos = ( order = = TSDB_ORDER_ASC ) ? offset : offset - ( forwardStep - 1 ) ;
2022-03-15 06:37:26 +00:00
pCtx [ k ] . input . startRowIndex = pos ;
pCtx [ k ] . input . numOfRows = forwardStep ;
2021-11-02 05:37:31 +00:00
if ( tsCol ! = NULL ) {
2022-03-15 08:51:50 +00:00
pCtx [ k ] . ptsList = tsCol ;
2021-11-02 05:37:31 +00:00
}
// 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 ;
}
2022-03-30 05:41:15 +00:00
if ( fmIsWindowPseudoColumnFunc ( pCtx [ k ] . functionId ) ) {
SResultRowEntryInfo * pEntryInfo = GET_RES_INFO ( & pCtx [ k ] ) ;
2022-04-23 10:29:45 +00:00
char * p = GET_ROWCELL_INTERBUF ( pEntryInfo ) ;
2022-03-30 05:41:15 +00:00
2022-04-02 05:32:26 +00:00
SColumnInfoData idata = { 0 } ;
2022-04-23 10:29:45 +00:00
idata . info . type = TSDB_DATA_TYPE_BIGINT ;
2022-04-02 05:32:26 +00:00
idata . info . bytes = tDataTypes [ TSDB_DATA_TYPE_BIGINT ] . bytes ;
2022-04-23 10:29:45 +00:00
idata . pData = p ;
2022-04-02 05:32:26 +00:00
SScalarParam out = { . columnData = & idata } ;
SScalarParam tw = { . numOfRows = 5 , . columnData = pTimeWindowData } ;
pCtx [ k ] . sfp . process ( & tw , 1 , & out ) ;
2022-03-30 05:41:15 +00:00
pEntryInfo - > numOfRes = 1 ;
continue ;
}
2022-02-24 09:18:56 +00:00
if ( functionNeedToExecute ( & pCtx [ k ] ) ) {
2022-03-15 06:37:26 +00:00
pCtx [ k ] . fpSet . process ( & pCtx [ k ] ) ;
2021-11-02 05:37:31 +00:00
}
// restore it
2022-03-15 06:37:26 +00:00
pCtx [ k ] . input . colDataAggIsSet = hasAgg ;
pCtx [ k ] . input . startRowIndex = startOffset ;
pCtx [ k ] . input . numOfRows = numOfRows ;
2021-11-02 05:37:31 +00:00
}
}
2022-02-24 09:18:56 +00:00
static int32_t getNextQualifiedWindow ( SInterval * pInterval , STimeWindow * pNext , SDataBlockInfo * pDataBlockInfo ,
TSKEY * primaryKeys , int32_t prevPosition , STableIntervalOperatorInfo * pInfo ) {
int32_t order = pInfo - > order ;
2022-03-29 07:24:25 +00:00
bool ascQuery = ( order = = TSDB_ORDER_ASC ) ;
2022-02-24 09:18:56 +00:00
2022-03-29 12:07:38 +00:00
int32_t precision = pInterval - > precision ;
2022-02-24 09:18:56 +00:00
getNextTimeWindow ( pInterval , precision , order , pNext ) ;
2021-11-02 05:37:31 +00:00
// next time window is not in current block
2022-02-24 09:18:56 +00:00
if ( ( pNext - > skey > pDataBlockInfo - > window . ekey & & order = = TSDB_ORDER_ASC ) | |
( pNext - > ekey < pDataBlockInfo - > window . skey & & order = = TSDB_ORDER_DESC ) ) {
2021-11-02 05:37:31 +00:00
return - 1 ;
}
2022-03-29 07:24:25 +00:00
TSKEY startKey = ascQuery ? pNext - > skey : pNext - > ekey ;
2021-11-02 05:37:31 +00:00
int32_t startPos = 0 ;
// tumbling time window query, a special case of sliding time window query
2022-02-24 09:18:56 +00:00
if ( pInterval - > sliding = = pInterval - > interval & & prevPosition ! = - 1 ) {
int32_t factor = GET_FORWARD_DIRECTION_FACTOR ( order ) ;
2021-11-02 05:37:31 +00:00
startPos = prevPosition + factor ;
} else {
2022-02-24 09:18:56 +00:00
if ( startKey < = pDataBlockInfo - > window . skey & & ascQuery ) {
2021-11-02 05:37:31 +00:00
startPos = 0 ;
2022-02-24 09:18:56 +00:00
} else if ( startKey > = pDataBlockInfo - > window . ekey & & ! ascQuery ) {
2021-11-02 05:37:31 +00:00
startPos = pDataBlockInfo - > rows - 1 ;
} else {
2022-03-29 07:24:25 +00:00
startPos = binarySearchForKey ( ( char * ) primaryKeys , pDataBlockInfo - > rows , startKey , order ) ;
2021-11-02 05:37:31 +00:00
}
}
/* interp query with fill should not skip time window */
2022-03-29 07:24:25 +00:00
// if (pQueryAttr->pointInterpQuery && pQueryAttr->fillType != TSDB_FILL_NONE) {
// return startPos;
// }
2021-11-02 05:37:31 +00:00
/*
* 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 ) {
2022-02-24 09:18:56 +00:00
if ( ascQuery ) {
2021-11-02 05:37:31 +00:00
assert ( pDataBlockInfo - > window . skey < = pNext - > ekey ) ;
} else {
assert ( pDataBlockInfo - > window . ekey > = pNext - > skey ) ;
}
} else {
2022-02-24 09:18:56 +00:00
if ( ascQuery & & primaryKeys [ startPos ] > pNext - > ekey ) {
2021-11-02 05:37:31 +00:00
TSKEY next = primaryKeys [ startPos ] ;
2022-02-24 09:18:56 +00:00
if ( pInterval - > intervalUnit = = ' n ' | | pInterval - > intervalUnit = = ' y ' ) {
pNext - > skey = taosTimeTruncate ( next , pInterval , precision ) ;
pNext - > ekey = taosTimeAdd ( pNext - > skey , pInterval - > interval , pInterval - > intervalUnit , precision ) - 1 ;
2021-11-02 05:37:31 +00:00
} else {
2022-03-29 07:24:25 +00:00
pNext - > ekey + = ( ( next - pNext - > ekey + pInterval - > sliding - 1 ) / pInterval - > sliding ) * pInterval - > sliding ;
2022-02-24 09:18:56 +00:00
pNext - > skey = pNext - > ekey - pInterval - > interval + 1 ;
2021-11-02 05:37:31 +00:00
}
2022-02-24 09:18:56 +00:00
} else if ( ( ! ascQuery ) & & primaryKeys [ startPos ] < pNext - > skey ) {
2021-11-02 05:37:31 +00:00
TSKEY next = primaryKeys [ startPos ] ;
2022-02-24 09:18:56 +00:00
if ( pInterval - > intervalUnit = = ' n ' | | pInterval - > intervalUnit = = ' y ' ) {
pNext - > skey = taosTimeTruncate ( next , pInterval , precision ) ;
pNext - > ekey = taosTimeAdd ( pNext - > skey , pInterval - > interval , pInterval - > intervalUnit , precision ) - 1 ;
2021-11-02 05:37:31 +00:00
} else {
2022-02-24 09:18:56 +00:00
pNext - > skey - = ( ( pNext - > skey - next + pInterval - > sliding - 1 ) / pInterval - > sliding ) * pInterval - > sliding ;
pNext - > ekey = pNext - > skey + pInterval - > interval - 1 ;
2021-11-02 05:37:31 +00:00
}
}
}
return startPos ;
}
2022-03-29 07:24:25 +00:00
static FORCE_INLINE TSKEY reviseWindowEkey ( STaskAttr * pQueryAttr , STimeWindow * pWindow ) {
2022-04-23 10:29:45 +00:00
TSKEY ekey = - 1 ;
2022-04-14 06:39:28 +00:00
int32_t order = TSDB_ORDER_ASC ;
if ( order = = TSDB_ORDER_ASC ) {
2021-11-02 05:37:31 +00:00
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-02-24 09:18:56 +00:00
static void saveDataBlockLastRow ( char * * pRow , SArray * pDataBlock , int32_t rowIndex , int32_t numOfCols ) {
2021-11-02 05:37:31 +00:00
if ( pDataBlock = = NULL ) {
return ;
}
2022-02-24 09:18:56 +00:00
for ( int32_t k = 0 ; k < numOfCols ; + + k ) {
2022-03-29 07:24:25 +00:00
SColumnInfoData * pColInfo = taosArrayGet ( pDataBlock , k ) ;
2022-02-24 09:18:56 +00:00
memcpy ( pRow [ k ] , ( ( char * ) pColInfo - > pData ) + ( pColInfo - > info . bytes * rowIndex ) , pColInfo - > info . bytes ) ;
2021-11-02 05:37:31 +00:00
}
}
2022-02-24 09:18:56 +00:00
static TSKEY getStartTsKey ( STimeWindow * win , const TSKEY * tsCols , int32_t rows , bool ascQuery ) {
2021-11-02 05:37:31 +00:00
TSKEY ts = TSKEY_INITIAL_VAL ;
if ( tsCols = = NULL ) {
2022-03-29 07:24:25 +00:00
ts = ascQuery ? win - > skey : win - > ekey ;
2021-11-02 05:37:31 +00:00
} else {
2022-03-29 07:24:25 +00:00
int32_t offset = ascQuery ? 0 : rows - 1 ;
2021-11-02 05:37:31 +00:00
ts = tsCols [ offset ] ;
}
return ts ;
}
2022-04-23 10:29:45 +00:00
static int32_t doSetInputDataBlock ( SOperatorInfo * pOperator , SqlFunctionCtx * pCtx , SSDataBlock * pBlock , int32_t order ,
bool createDummyCol ) ;
2021-11-04 05:24:19 +00:00
2022-04-23 10:29:45 +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 ;
2022-03-29 07:24:25 +00:00
pCtx [ i ] . size = pBlock - > info . rows ;
2022-04-18 02:46:07 +00:00
setBlockStatisInfo ( & pCtx [ i ] , & pOperator - > pExpr [ i ] , pBlock ) ;
2021-11-02 05:37:31 +00:00
}
}
2022-04-23 10:29:45 +00:00
void setInputDataBlock ( SOperatorInfo * pOperator , SqlFunctionCtx * pCtx , SSDataBlock * pBlock , int32_t order ,
bool createDummyCol ) {
2022-04-16 03:47:50 +00:00
if ( pBlock - > pBlockAgg ! = NULL ) {
2022-03-09 02:22:53 +00:00
doSetInputDataBlockInfo ( pOperator , pCtx , pBlock , order ) ;
2022-04-16 03:47:50 +00:00
} else {
2022-04-18 04:07:04 +00:00
doSetInputDataBlock ( pOperator , pCtx , pBlock , order , createDummyCol ) ;
2022-03-09 02:22:53 +00:00
}
2021-11-02 05:37:31 +00:00
}
2022-04-27 02:11:32 +00:00
static int32_t doCreateConstantValColumnInfo ( SInputColumnInfoData * pInput , SFunctParam * pFuncParam ,
2022-04-23 10:29:45 +00:00
int32_t paramIndex , int32_t numOfRows ) {
2022-04-18 02:46:07 +00:00
SColumnInfoData * pColInfo = NULL ;
if ( pInput - > pData [ paramIndex ] = = NULL ) {
pColInfo = taosMemoryCalloc ( 1 , sizeof ( SColumnInfoData ) ) ;
if ( pColInfo = = NULL ) {
return TSDB_CODE_OUT_OF_MEMORY ;
}
// Set the correct column info (data type and bytes)
2022-04-27 02:11:32 +00:00
pColInfo - > info . type = pFuncParam - > param . nType ;
pColInfo - > info . bytes = pFuncParam - > param . nLen ;
2022-04-18 02:46:07 +00:00
pInput - > pData [ paramIndex ] = pColInfo ;
2022-04-25 09:12:28 +00:00
} else {
pColInfo = pInput - > pData [ paramIndex ] ;
2022-04-18 02:46:07 +00:00
}
2022-04-19 05:07:23 +00:00
colInfoDataEnsureCapacity ( pColInfo , 0 , numOfRows ) ;
2022-04-18 02:46:07 +00:00
2022-04-27 02:11:32 +00:00
int8_t type = pFuncParam - > param . nType ;
2022-04-18 02:46:07 +00:00
if ( type = = TSDB_DATA_TYPE_BIGINT | | type = = TSDB_DATA_TYPE_UBIGINT ) {
int64_t v = pFuncParam - > param . i ;
2022-04-23 10:29:45 +00:00
for ( int32_t i = 0 ; i < numOfRows ; + + i ) {
2022-04-18 02:46:07 +00:00
colDataAppendInt64 ( pColInfo , i , & v ) ;
}
} else if ( type = = TSDB_DATA_TYPE_DOUBLE ) {
double v = pFuncParam - > param . d ;
2022-04-23 10:29:45 +00:00
for ( int32_t i = 0 ; i < numOfRows ; + + i ) {
2022-04-18 02:46:07 +00:00
colDataAppendDouble ( pColInfo , i , & v ) ;
}
2022-04-27 02:11:32 +00:00
} else if ( type = = TSDB_DATA_TYPE_VARCHAR ) {
char * tmp = taosMemoryMalloc ( pFuncParam - > param . nLen + VARSTR_HEADER_SIZE ) ;
STR_WITH_SIZE_TO_VARSTR ( tmp , pFuncParam - > param . pz , pFuncParam - > param . nLen ) ;
for ( int32_t i = 0 ; i < numOfRows ; + + i ) {
colDataAppend ( pColInfo , i , tmp , false ) ;
}
2022-04-18 02:46:07 +00:00
}
return TSDB_CODE_SUCCESS ;
}
2022-04-23 10:29:45 +00:00
static int32_t doSetInputDataBlock ( SOperatorInfo * pOperator , SqlFunctionCtx * pCtx , SSDataBlock * pBlock , int32_t order ,
bool createDummyCol ) {
2022-04-18 02:46:07 +00:00
int32_t code = TSDB_CODE_SUCCESS ;
2021-11-02 05:37:31 +00:00
for ( int32_t i = 0 ; i < pOperator - > numOfOutput ; + + i ) {
2022-04-22 14:43:07 +00:00
pCtx [ i ] . order = order ;
pCtx [ i ] . size = pBlock - > info . rows ;
pCtx [ i ] . pSrcBlock = pBlock ;
2022-03-09 02:22:53 +00:00
pCtx [ i ] . currentStage = MAIN_SCAN ;
2022-04-18 02:46:07 +00:00
SInputColumnInfoData * pInput = & pCtx [ i ] . input ;
2022-04-21 09:44:08 +00:00
pInput - > uid = pBlock - > info . uid ;
2022-04-25 07:58:44 +00:00
pInput - > colDataAggIsSet = false ;
2022-04-18 02:46:07 +00:00
2022-04-12 09:55:17 +00:00
SExprInfo * pOneExpr = & pOperator - > pExpr [ i ] ;
for ( int32_t j = 0 ; j < pOneExpr - > base . numOfParams ; + + j ) {
2022-04-23 10:29:45 +00:00
SFunctParam * pFuncParam = & pOneExpr - > base . pParam [ j ] ;
2022-03-29 09:30:44 +00:00
if ( pFuncParam - > type = = FUNC_PARAM_TYPE_COLUMN ) {
int32_t slotId = pFuncParam - > pCol - > slotId ;
2022-04-23 10:29:45 +00:00
pInput - > pData [ j ] = taosArrayGet ( pBlock - > pDataBlock , slotId ) ;
2022-04-18 02:46:07 +00:00
pInput - > totalRows = pBlock - > info . rows ;
pInput - > numOfRows = pBlock - > info . rows ;
pInput - > startRowIndex = 0 ;
2022-04-19 02:12:30 +00:00
2022-04-23 10:29:45 +00:00
pInput - > pPTS = taosArrayGet ( pBlock - > pDataBlock , 0 ) ; // todo set the correct timestamp column
2022-04-18 02:46:07 +00:00
ASSERT ( pInput - > pData [ j ] ! = NULL ) ;
} else if ( pFuncParam - > type = = FUNC_PARAM_TYPE_VALUE ) {
2022-04-21 09:44:08 +00:00
// todo avoid case: top(k, 12), 12 is the value parameter.
// sum(11), 11 is also the value parameter.
if ( createDummyCol & & pOneExpr - > base . numOfParams = = 1 ) {
2022-04-24 11:20:05 +00:00
pInput - > totalRows = pBlock - > info . rows ;
pInput - > numOfRows = pBlock - > info . rows ;
pInput - > startRowIndex = 0 ;
2022-04-27 02:11:32 +00:00
code = doCreateConstantValColumnInfo ( pInput , pFuncParam , j , pBlock - > info . rows ) ;
2022-04-18 04:07:04 +00:00
if ( code ! = TSDB_CODE_SUCCESS ) {
return code ;
}
2022-04-18 02:46:07 +00:00
}
2022-03-29 09:30:44 +00:00
}
}
2022-03-09 02:22:53 +00:00
2022-03-31 09:36:51 +00:00
// setBlockStatisInfo(&pCtx[i], pBlock, pOperator->pExpr[i].base.pColumns);
2022-03-09 02:22:53 +00:00
// uint32_t flag = pOperator->pExpr[i].base.pParam[0].pCol->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.pParam[0].pCol;
// 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->colId) {
// pCtx[i].columnIndex = j;
// break;
// }
// }
// }
// uint32_t status = aAggs[pCtx[i].functionId].status;
// if ((status & (FUNCSTATE_SELECTIVITY | FUNCSTATE_NEED_TS)) != 0) {
// 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);
// }
// }
}
2022-04-18 02:46:07 +00:00
return code ;
2022-03-09 02:22:53 +00:00
}
static void doAggregateImpl ( SOperatorInfo * pOperator , TSKEY startTs , SqlFunctionCtx * pCtx ) {
2021-11-02 05:37:31 +00:00
for ( int32_t k = 0 ; k < pOperator - > numOfOutput ; + + k ) {
2022-02-24 09:18:56 +00:00
if ( functionNeedToExecute ( & pCtx [ k ] ) ) {
2022-03-29 07:24:25 +00:00
pCtx [ k ] . startTs = startTs ; // this can be set during create the struct
2022-03-09 02:22:53 +00:00
pCtx [ k ] . fpSet . process ( & pCtx [ k ] ) ;
2021-11-02 05:37:31 +00:00
}
}
}
2022-04-06 03:01:09 +00:00
static void setPseudoOutputColInfo ( SSDataBlock * pResult , SqlFunctionCtx * pCtx , SArray * pPseudoList ) {
2022-04-23 10:29:45 +00:00
size_t num = ( pPseudoList ! = NULL ) ? taosArrayGetSize ( pPseudoList ) : 0 ;
2022-04-06 03:01:09 +00:00
for ( int32_t i = 0 ; i < num ; + + i ) {
pCtx [ i ] . pOutput = taosArrayGet ( pResult - > pDataBlock , i ) ;
}
}
2022-04-23 10:29:45 +00:00
void projectApplyFunctions ( SExprInfo * pExpr , SSDataBlock * pResult , SSDataBlock * pSrcBlock , SqlFunctionCtx * pCtx ,
int32_t numOfOutput , SArray * pPseudoList ) {
2022-04-06 03:01:09 +00:00
setPseudoOutputColInfo ( pResult , pCtx , pPseudoList ) ;
2022-04-08 09:37:57 +00:00
pResult - > info . groupId = pSrcBlock - > info . groupId ;
2022-04-06 03:01:09 +00:00
2022-04-23 10:29:45 +00:00
// if the source equals to the destination, it is to create a new column as the result of scalar function or some
// operators.
2022-04-19 10:45:28 +00:00
bool createNewColModel = ( pResult = = pSrcBlock ) ;
2022-04-18 11:27:41 +00:00
int32_t numOfRows = 0 ;
2021-11-02 05:37:31 +00:00
for ( int32_t k = 0 ; k < numOfOutput ; + + k ) {
2022-04-23 10:29:45 +00:00
int32_t outputSlotId = pExpr [ k ] . base . resSchema . slotId ;
2022-04-12 09:55:17 +00:00
SqlFunctionCtx * pfCtx = & pCtx [ k ] ;
2022-03-29 07:24:25 +00:00
if ( pExpr [ k ] . pExpr - > nodeType = = QUERY_NODE_COLUMN ) { // it is a project query
2022-04-12 09:55:17 +00:00
SColumnInfoData * pColInfoData = taosArrayGet ( pResult - > pDataBlock , outputSlotId ) ;
2022-04-19 10:45:28 +00:00
if ( pResult - > info . rows > 0 & & ! createNewColModel ) {
2022-04-18 11:27:41 +00:00
colDataMergeCol ( pColInfoData , pResult - > info . rows , pfCtx - > input . pData [ 0 ] , pfCtx - > input . numOfRows ) ;
} else {
colDataAssign ( pColInfoData , pfCtx - > input . pData [ 0 ] , pfCtx - > input . numOfRows ) ;
}
2022-03-26 14:13:14 +00:00
2022-04-18 11:27:41 +00:00
numOfRows = pfCtx - > input . numOfRows ;
2022-04-07 02:26:18 +00:00
} else if ( pExpr [ k ] . pExpr - > nodeType = = QUERY_NODE_VALUE ) {
2022-04-12 09:55:17 +00:00
SColumnInfoData * pColInfoData = taosArrayGet ( pResult - > pDataBlock , outputSlotId ) ;
2022-04-18 11:27:41 +00:00
2022-04-23 10:29:45 +00:00
int32_t offset = createNewColModel ? 0 : pResult - > info . rows ;
2022-04-07 02:26:18 +00:00
for ( int32_t i = 0 ; i < pSrcBlock - > info . rows ; + + i ) {
2022-04-23 10:29:45 +00:00
colDataAppend ( pColInfoData , i + offset ,
taosVariantGet ( & pExpr [ k ] . base . pParam [ 0 ] . param , pExpr [ k ] . base . pParam [ 0 ] . param . nType ) ,
TSDB_DATA_TYPE_NULL = = pExpr [ k ] . base . pParam [ 0 ] . param . nType ) ;
2022-04-07 02:26:18 +00:00
}
2022-04-18 11:27:41 +00:00
numOfRows = pSrcBlock - > info . rows ;
2022-03-26 14:17:26 +00:00
} else if ( pExpr [ k ] . pExpr - > nodeType = = QUERY_NODE_OPERATOR ) {
2022-03-26 14:13:14 +00:00
SArray * pBlockList = taosArrayInit ( 4 , POINTER_BYTES ) ;
taosArrayPush ( pBlockList , & pSrcBlock ) ;
2022-04-18 11:27:41 +00:00
SColumnInfoData * pResColData = taosArrayGet ( pResult - > pDataBlock , outputSlotId ) ;
2022-04-23 10:29:45 +00:00
SColumnInfoData idata = { . info = pResColData - > info } ;
2022-03-27 14:43:07 +00:00
2022-04-18 11:27:41 +00:00
SScalarParam dest = { . columnData = & idata } ;
2022-03-27 14:43:07 +00:00
scalarCalculate ( pExpr [ k ] . pExpr - > _optrRoot . pRootNode , pBlockList , & dest ) ;
2022-04-23 10:29:45 +00:00
int32_t startOffset = createNewColModel ? 0 : pResult - > info . rows ;
2022-04-19 10:45:28 +00:00
colDataMergeCol ( pResColData , startOffset , & idata , dest . numOfRows ) ;
2022-04-18 11:27:41 +00:00
numOfRows = dest . numOfRows ;
2022-03-27 14:43:07 +00:00
taosArrayDestroy ( pBlockList ) ;
} else if ( pExpr [ k ] . pExpr - > nodeType = = QUERY_NODE_FUNCTION ) {
2022-04-12 09:55:17 +00:00
ASSERT ( ! fmIsAggFunc ( pfCtx - > functionId ) ) ;
2022-03-27 14:43:07 +00:00
2022-04-12 09:55:17 +00:00
if ( fmIsPseudoColumnFunc ( pfCtx - > functionId ) ) {
2022-04-06 03:01:09 +00:00
// do nothing
2022-04-12 09:55:17 +00:00
} else if ( fmIsNonstandardSQLFunc ( pfCtx - > functionId ) ) {
2022-04-06 03:01:09 +00:00
// todo set the correct timestamp column
2022-04-12 09:55:17 +00:00
pfCtx - > input . pPTS = taosArrayGet ( pSrcBlock - > pDataBlock , 1 ) ;
2022-03-27 14:43:07 +00:00
2022-04-23 10:29:45 +00:00
SResultRowEntryInfo * pResInfo = GET_RES_INFO ( & pCtx [ k ] ) ;
2022-04-12 09:55:17 +00:00
pfCtx - > fpSet . init ( & pCtx [ k ] , pResInfo ) ;
2022-03-27 14:43:07 +00:00
2022-04-12 09:55:17 +00:00
pfCtx - > pOutput = taosArrayGet ( pResult - > pDataBlock , outputSlotId ) ;
2022-04-23 10:29:45 +00:00
pfCtx - > offset = createNewColModel ? 0 : pResult - > info . rows ; // set the start offset
2022-04-06 03:01:09 +00:00
2022-04-18 11:27:41 +00:00
// set the timestamp(_rowts) output buffer
2022-04-06 09:59:08 +00:00
if ( taosArrayGetSize ( pPseudoList ) > 0 ) {
int32_t * outputColIndex = taosArrayGet ( pPseudoList , 0 ) ;
2022-04-12 09:55:17 +00:00
pfCtx - > pTsOutput = ( SColumnInfoData * ) pCtx [ * outputColIndex ] . pOutput ;
2022-04-06 09:59:08 +00:00
}
2022-04-06 03:01:09 +00:00
2022-04-18 11:27:41 +00:00
numOfRows = pfCtx - > fpSet . process ( pfCtx ) ;
2022-04-04 06:54:39 +00:00
} else {
SArray * pBlockList = taosArrayInit ( 4 , POINTER_BYTES ) ;
taosArrayPush ( pBlockList , & pSrcBlock ) ;
2022-03-29 09:30:44 +00:00
2022-04-18 11:27:41 +00:00
SColumnInfoData * pResColData = taosArrayGet ( pResult - > pDataBlock , outputSlotId ) ;
2022-04-23 10:29:45 +00:00
SColumnInfoData idata = { . info = pResColData - > info } ;
2022-04-04 06:54:39 +00:00
2022-04-18 11:27:41 +00:00
SScalarParam dest = { . columnData = & idata } ;
2022-04-04 06:54:39 +00:00
scalarCalculate ( ( SNode * ) pExpr [ k ] . pExpr - > _function . pFunctNode , pBlockList , & dest ) ;
2022-04-19 10:45:28 +00:00
2022-04-23 10:29:45 +00:00
int32_t startOffset = createNewColModel ? 0 : pResult - > info . rows ;
2022-04-19 10:45:28 +00:00
colDataMergeCol ( pResColData , startOffset , & idata , dest . numOfRows ) ;
2022-04-18 11:27:41 +00:00
numOfRows = dest . numOfRows ;
2022-04-04 06:54:39 +00:00
taosArrayDestroy ( pBlockList ) ;
}
2022-03-26 14:13:14 +00:00
} else {
2022-03-18 16:13:07 +00:00
ASSERT ( 0 ) ;
2021-11-02 05:37:31 +00:00
}
}
2022-04-18 11:27:41 +00:00
2022-04-19 10:45:28 +00:00
if ( ! createNewColModel ) {
pResult - > info . rows + = numOfRows ;
}
2021-11-02 05:37:31 +00:00
}
void doTimeWindowInterpolation ( SOperatorInfo * pOperator , SOptrBasicInfo * pInfo , SArray * pDataBlock , TSKEY prevTs ,
int32_t prevRowIndex , TSKEY curTs , int32_t curRowIndex , TSKEY windowKey , int32_t type ) {
2022-04-23 10:29:45 +00:00
SExprInfo * pExpr = pOperator - > pExpr ;
2021-11-02 05:37:31 +00:00
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 ;
}
2022-03-29 07:24:25 +00:00
SColIndex * pColIndex = NULL /*&pExpr[k].base.colInfo*/ ;
2021-11-02 05:37:31 +00:00
int16_t index = pColIndex - > colIndex ;
2022-03-29 07:24:25 +00:00
SColumnInfoData * pColInfo = taosArrayGet ( pDataBlock , index ) ;
2021-11-02 05:37:31 +00:00
2022-03-29 07:24:25 +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 ) {
2022-04-23 10:29:45 +00:00
// GET_TYPED_DATA(v1, double, pColInfo->info.type, (char*)pRuntimeEnv->prevRow[index]);
2021-11-02 05:37:31 +00:00
} else {
2022-03-29 07:24:25 +00:00
GET_TYPED_DATA ( v1 , double , pColInfo - > info . type , ( char * ) pColInfo - > pData + prevRowIndex * pColInfo - > info . bytes ) ;
2021-11-02 05:37:31 +00:00
}
2022-03-29 07:24:25 +00:00
GET_TYPED_DATA ( v2 , double , pColInfo - > info . type , ( char * ) pColInfo - > pData + curRowIndex * pColInfo - > info . bytes ) ;
2021-11-02 05:37:31 +00:00
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 ) {
2022-04-23 10:29:45 +00:00
// pCtx[k].start.ptr = (char*)pRuntimeEnv->prevRow[index];
2021-11-02 05:37:31 +00:00
} else {
2022-03-29 07:24:25 +00:00
pCtx [ k ] . start . ptr = ( char * ) pColInfo - > pData + prevRowIndex * pColInfo - > info . bytes ;
2021-11-02 05:37:31 +00:00
}
2022-03-29 07:24:25 +00:00
pCtx [ k ] . end . ptr = ( char * ) pColInfo - > pData + curRowIndex * pColInfo - > info . bytes ;
2021-11-02 05:37:31 +00:00
}
}
} else if ( functionId = = FUNCTION_TWA ) {
2022-03-29 07:24:25 +00:00
SPoint point1 = ( SPoint ) { . key = prevTs , . val = & v1 } ;
SPoint point2 = ( SPoint ) { . key = curTs , . val = & v2 } ;
SPoint point = ( SPoint ) { . key = windowKey , . val = & v } ;
2021-11-02 05:37:31 +00:00
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 ,
2022-04-23 10:29:45 +00:00
int32_t numOfRows , SArray * pDataBlock , const TSKEY * tsCols ,
STimeWindow * win ) {
2022-04-02 07:08:48 +00:00
bool ascQuery = true ;
2022-03-29 07:24:25 +00:00
TSKEY curTs = tsCols [ pos ] ;
2022-04-23 10:29:45 +00:00
TSKEY lastTs = 0 ; //*(TSKEY*)pRuntimeEnv->prevRow[0];
2021-11-02 05:37:31 +00:00
// 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
2022-03-29 07:24:25 +00:00
TSKEY key = ascQuery ? win - > skey : win - > ekey ;
2021-11-02 05:37:31 +00:00
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 ;
}
2022-04-23 10:29:45 +00:00
int32_t step = 1 ; // GET_FORWARD_DIRECTION_FACTOR(pQueryAttr->order.order);
2022-03-29 07:24:25 +00:00
TSKEY prevTs = ( ( pos = = 0 & & ascQuery ) | | ( pos = = ( numOfRows - 1 ) & & ! ascQuery ) ) ? lastTs : tsCols [ pos - step ] ;
2021-11-02 05:37:31 +00:00
2022-04-23 10:29:45 +00:00
doTimeWindowInterpolation ( pOperatorInfo , pOperatorInfo - > info , pDataBlock , prevTs , pos - step , curTs , pos , key ,
RESULT_ROW_START_INTERP ) ;
2021-11-02 05:37:31 +00:00
return true ;
}
2022-03-29 07:24:25 +00:00
static bool setTimeWindowInterpolationEndTs ( SOperatorInfo * pOperatorInfo , SqlFunctionCtx * pCtx , int32_t endRowIndex ,
SArray * pDataBlock , const TSKEY * tsCols , TSKEY blockEkey ,
STimeWindow * win ) {
2022-04-02 07:08:48 +00:00
int32_t order = TSDB_ORDER_ASC ;
int32_t numOfOutput = pOperatorInfo - > numOfOutput ;
2021-11-02 05:37:31 +00:00
2022-03-29 07:24:25 +00:00
TSKEY actualEndKey = tsCols [ endRowIndex ] ;
2022-04-02 07:08:48 +00:00
TSKEY key = order ? win - > ekey : win - > skey ;
2021-11-02 05:37:31 +00:00
// not ended in current data block, do not invoke interpolation
2022-04-23 10:29:45 +00:00
if ( ( key > blockEkey /*&& QUERY_IS_ASC_QUERY(pQueryAttr)*/ ) | |
( key < blockEkey /*&& !QUERY_IS_ASC_QUERY(pQueryAttr)*/ ) ) {
2021-11-02 05:37:31 +00:00
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 ;
}
2022-04-02 07:08:48 +00:00
int32_t step = GET_FORWARD_DIRECTION_FACTOR ( order ) ;
2021-11-02 05:37:31 +00:00
int32_t nextRowIndex = endRowIndex + step ;
assert ( nextRowIndex > = 0 ) ;
TSKEY nextKey = tsCols [ nextRowIndex ] ;
doTimeWindowInterpolation ( pOperatorInfo , pOperatorInfo - > info , pDataBlock , actualEndKey , endRowIndex , nextKey ,
2022-03-29 07:24:25 +00:00
nextRowIndex , key , RESULT_ROW_END_INTERP ) ;
2021-11-02 05:37:31 +00:00
return true ;
}
2022-01-28 02:44:02 +00:00
static void doWindowBorderInterpolation ( SOperatorInfo * pOperatorInfo , SSDataBlock * pBlock , SqlFunctionCtx * pCtx ,
2022-03-29 07:24:25 +00:00
SResultRow * pResult , STimeWindow * win , int32_t startPos , int32_t forwardStep ,
int32_t order , bool timeWindowInterpo ) {
2022-02-24 09:18:56 +00:00
if ( ! timeWindowInterpo ) {
2021-11-02 05:37:31 +00:00
return ;
}
assert ( pBlock ! = NULL ) ;
2022-02-24 09:18:56 +00:00
int32_t step = GET_FORWARD_DIRECTION_FACTOR ( order ) ;
2021-11-02 05:37:31 +00:00
2022-03-29 07:24:25 +00:00
if ( pBlock - > pDataBlock = = NULL ) {
// tscError("pBlock->pDataBlock == NULL");
2021-11-02 05:37:31 +00:00
return ;
}
2022-02-24 09:18:56 +00:00
2022-03-29 07:24:25 +00:00
SColumnInfoData * pColInfo = taosArrayGet ( pBlock - > pDataBlock , 0 ) ;
2021-11-02 05:37:31 +00:00
2022-03-29 07:24:25 +00:00
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
2021-11-02 05:37:31 +00:00
int32_t startRowIndex = startPos ;
2022-03-29 07:24:25 +00:00
bool interp = setTimeWindowInterpolationStartTs ( pOperatorInfo , pCtx , startRowIndex , pBlock - > info . rows ,
2022-04-23 10:29:45 +00:00
pBlock - > pDataBlock , tsCols , win ) ;
2021-11-02 05:37:31 +00:00
if ( interp ) {
setResultRowInterpo ( pResult , RESULT_ROW_START_INTERP ) ;
}
} else {
2022-02-24 09:18:56 +00:00
setNotInterpoWindowKey ( pCtx , pOperatorInfo - > numOfOutput , RESULT_ROW_START_INTERP ) ;
2021-11-02 05:37:31 +00:00
}
// point interpolation does not require the end key time window interpolation.
2022-03-29 07:24:25 +00:00
// if (pointInterpQuery) {
// return;
// }
2021-11-02 05:37:31 +00:00
// 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 ;
2022-03-29 07:24:25 +00:00
TSKEY endKey = ( order = = TSDB_ORDER_ASC ) ? pBlock - > info . window . ekey : pBlock - > info . window . skey ;
bool interp =
setTimeWindowInterpolationEndTs ( pOperatorInfo , pCtx , endRowIndex , pBlock - > pDataBlock , tsCols , endKey , win ) ;
2021-11-02 05:37:31 +00:00
if ( interp ) {
setResultRowInterpo ( pResult , RESULT_ROW_END_INTERP ) ;
}
} else {
2022-02-24 09:18:56 +00:00
setNotInterpoWindowKey ( pCtx , pOperatorInfo - > numOfOutput , RESULT_ROW_END_INTERP ) ;
2021-11-02 05:37:31 +00:00
}
}
2022-04-23 10:29:45 +00:00
static SArray * hashIntervalAgg ( SOperatorInfo * pOperatorInfo , SResultRowInfo * pResultRowInfo , SSDataBlock * pSDataBlock ,
int32_t tableGroupId ) {
2022-03-29 07:24:25 +00:00
STableIntervalOperatorInfo * pInfo = ( STableIntervalOperatorInfo * ) pOperatorInfo - > info ;
2021-11-02 05:37:31 +00:00
2022-02-24 09:18:56 +00:00
SExecTaskInfo * pTaskInfo = pOperatorInfo - > pTaskInfo ;
2022-03-29 07:24:25 +00:00
int32_t numOfOutput = pOperatorInfo - > numOfOutput ;
2021-11-02 05:37:31 +00:00
2022-03-29 12:07:38 +00:00
SArray * pUpdated = NULL ;
if ( pInfo - > execModel = = OPTR_EXEC_MODEL_STREAM ) {
2022-04-24 12:48:42 +00:00
pUpdated = taosArrayInit ( 4 , POINTER_BYTES ) ;
2022-03-29 12:07:38 +00:00
}
2022-02-24 09:18:56 +00:00
int32_t step = 1 ;
2022-03-29 12:07:38 +00:00
bool ascScan = true ;
2021-11-02 05:37:31 +00:00
2022-04-23 10:29:45 +00:00
// int32_t prevIndex = pResultRowInfo->curPos;
2021-11-02 05:37:31 +00:00
TSKEY * tsCols = NULL ;
if ( pSDataBlock - > pDataBlock ! = NULL ) {
2022-04-06 10:26:35 +00:00
SColumnInfoData * pColDataInfo = taosArrayGet ( pSDataBlock - > pDataBlock , pInfo - > primaryTsIndex ) ;
2022-03-29 07:24:25 +00:00
tsCols = ( int64_t * ) pColDataInfo - > pData ;
2021-11-02 05:37:31 +00:00
}
2022-04-23 10:29:45 +00:00
int32_t startPos = ascScan ? 0 : ( pSDataBlock - > info . rows - 1 ) ;
2022-03-29 12:07:38 +00:00
TSKEY ts = getStartTsKey ( & pSDataBlock - > info . window , tsCols , pSDataBlock - > info . rows , ascScan ) ;
2021-11-02 05:37:31 +00:00
2022-04-23 10:29:45 +00:00
STimeWindow win = getActiveTimeWindow ( pInfo - > aggSup . pResultBuf , pResultRowInfo , ts , & pInfo - > interval ,
pInfo - > interval . precision , & pInfo - > win ) ;
2022-03-29 07:24:25 +00:00
bool masterScan = true ;
2021-11-02 05:37:31 +00:00
SResultRow * pResult = NULL ;
2022-03-29 07:24:25 +00:00
int32_t ret = setResultOutputBufByKey_rv ( pResultRowInfo , pSDataBlock - > info . uid , & win , masterScan , & pResult ,
2022-04-23 10:29:45 +00:00
tableGroupId , pInfo - > binfo . pCtx , numOfOutput , pInfo - > binfo . rowCellInfoOffset ,
& pInfo - > aggSup , pTaskInfo ) ;
2021-11-02 05:37:31 +00:00
if ( ret ! = TSDB_CODE_SUCCESS | | pResult = = NULL ) {
2022-02-24 09:18:56 +00:00
longjmp ( pTaskInfo - > env , TSDB_CODE_QRY_OUT_OF_MEMORY ) ;
2021-11-02 05:37:31 +00:00
}
2022-03-29 12:07:38 +00:00
if ( pInfo - > execModel = = OPTR_EXEC_MODEL_STREAM ) {
2022-04-24 12:48:42 +00:00
SResKeyPos * pos = taosMemoryMalloc ( sizeof ( SResKeyPos ) + sizeof ( uint64_t ) ) ;
pos - > groupId = tableGroupId ;
pos - > pos = ( SResultRowPosition ) { . pageId = pResult - > pageId , . offset = pResult - > offset } ;
* ( int64_t * ) pos - > key = pResult - > win . skey ;
2022-03-29 12:07:38 +00:00
taosArrayPush ( pUpdated , & pos ) ;
}
2021-11-02 05:37:31 +00:00
int32_t forwardStep = 0 ;
2022-02-24 09:18:56 +00:00
TSKEY ekey = win . ekey ;
2021-11-02 05:37:31 +00:00
forwardStep =
2022-02-24 09:18:56 +00:00
getNumOfRowsInTimeWindow ( & pSDataBlock - > info , tsCols , startPos , ekey , binarySearchForKey , NULL , TSDB_ORDER_ASC ) ;
2021-11-02 05:37:31 +00:00
// prev time window not interpolation yet.
2022-04-23 10:29:45 +00:00
// int32_t curIndex = pResultRowInfo->curPos;
2022-03-31 08:10:32 +00:00
#if 0
2022-02-24 09:18:56 +00:00
if ( prevIndex ! = - 1 & & prevIndex < curIndex & & pInfo - > timeWindowInterpo ) {
2021-11-02 05:37:31 +00:00
for ( int32_t j = prevIndex ; j < curIndex ; + + j ) { // previous time window may be all closed already.
SResultRow * pRes = getResultRow ( pResultRowInfo , j ) ;
if ( pRes - > closed ) {
2022-03-29 12:07:38 +00:00
assert ( resultRowInterpolated ( pRes , RESULT_ROW_START_INTERP ) & & resultRowInterpolated ( pRes , RESULT_ROW_END_INTERP ) ) ;
2021-11-02 05:37:31 +00:00
continue ;
}
2022-03-29 07:24:25 +00:00
STimeWindow w = pRes - > win ;
ret = setResultOutputBufByKey_rv ( pResultRowInfo , pSDataBlock - > info . uid , & w , masterScan , & pResult , tableGroupId ,
pInfo - > binfo . pCtx , numOfOutput , pInfo - > binfo . rowCellInfoOffset , & pInfo - > aggSup ,
pTaskInfo ) ;
if ( ret ! = TSDB_CODE_SUCCESS ) {
longjmp ( pTaskInfo - > env , TSDB_CODE_QRY_OUT_OF_MEMORY ) ;
}
2021-11-02 05:37:31 +00:00
2022-03-29 07:24:25 +00:00
assert ( ! resultRowInterpolated ( pResult , RESULT_ROW_END_INTERP ) ) ;
doTimeWindowInterpolation ( pOperatorInfo , & pInfo - > binfo , pSDataBlock - > pDataBlock , * ( TSKEY * ) pInfo - > pRow [ 0 ] , - 1 ,
tsCols [ startPos ] , startPos , w . ekey , RESULT_ROW_END_INTERP ) ;
2021-11-02 05:37:31 +00:00
2022-03-29 07:24:25 +00:00
setResultRowInterpo ( pResult , RESULT_ROW_END_INTERP ) ;
setNotInterpoWindowKey ( pInfo - > binfo . pCtx , pOperatorInfo - > numOfOutput , RESULT_ROW_START_INTERP ) ;
2021-11-02 05:37:31 +00:00
2022-03-30 05:41:15 +00:00
doApplyFunctions ( pInfo - > binfo . pCtx , & w , & pInfo - > timeWindowData , startPos , 0 , tsCols , pSDataBlock - > info . rows , numOfOutput , TSDB_ORDER_ASC ) ;
2022-03-29 07:24:25 +00:00
}
2021-11-02 05:37:31 +00:00
// restore current time window
2022-03-29 07:24:25 +00:00
ret = setResultOutputBufByKey_rv ( pResultRowInfo , pSDataBlock - > info . uid , & win , masterScan , & pResult , tableGroupId ,
pInfo - > binfo . pCtx , numOfOutput , pInfo - > binfo . rowCellInfoOffset , & pInfo - > aggSup ,
pTaskInfo ) ;
2021-11-02 05:37:31 +00:00
if ( ret ! = TSDB_CODE_SUCCESS ) {
2022-02-24 09:18:56 +00:00
longjmp ( pTaskInfo - > env , TSDB_CODE_QRY_OUT_OF_MEMORY ) ;
2021-11-02 05:37:31 +00:00
}
}
2022-03-31 08:10:32 +00:00
# endif
2021-11-02 05:37:31 +00:00
// window start key interpolation
2022-04-23 10:29:45 +00:00
doWindowBorderInterpolation ( pOperatorInfo , pSDataBlock , pInfo - > binfo . pCtx , pResult , & win , startPos , forwardStep ,
pInfo - > order , false ) ;
2022-04-02 05:32:26 +00:00
2022-04-19 02:12:30 +00:00
updateTimeWindowInfo ( & pInfo - > twAggSup . timeWindowData , & win , true ) ;
2022-04-23 10:29:45 +00:00
doApplyFunctions ( pInfo - > binfo . pCtx , & win , & pInfo - > twAggSup . timeWindowData , startPos , forwardStep , tsCols ,
pSDataBlock - > info . rows , numOfOutput , TSDB_ORDER_ASC ) ;
2021-11-02 05:37:31 +00:00
STimeWindow nextWin = win ;
while ( 1 ) {
int32_t prevEndPos = ( forwardStep - 1 ) * step + startPos ;
2022-02-24 09:18:56 +00:00
startPos = getNextQualifiedWindow ( & pInfo - > interval , & nextWin , & pSDataBlock - > info , tsCols , prevEndPos , pInfo ) ;
2021-11-02 05:37:31 +00:00
if ( startPos < 0 ) {
break ;
}
// null data, failed to allocate more memory buffer
2022-03-29 07:24:25 +00:00
int32_t code = setResultOutputBufByKey_rv ( pResultRowInfo , pSDataBlock - > info . uid , & nextWin , masterScan , & pResult ,
tableGroupId , pInfo - > binfo . pCtx , numOfOutput ,
pInfo - > binfo . rowCellInfoOffset , & pInfo - > aggSup , pTaskInfo ) ;
2021-11-02 05:37:31 +00:00
if ( code ! = TSDB_CODE_SUCCESS | | pResult = = NULL ) {
2022-02-24 09:18:56 +00:00
longjmp ( pTaskInfo - > env , TSDB_CODE_QRY_OUT_OF_MEMORY ) ;
2021-11-02 05:37:31 +00:00
}
2022-03-29 12:07:38 +00:00
if ( pInfo - > execModel = = OPTR_EXEC_MODEL_STREAM ) {
2022-04-24 12:48:42 +00:00
SResKeyPos * pos = taosMemoryMalloc ( sizeof ( SResKeyPos ) + sizeof ( uint64_t ) ) ;
pos - > groupId = tableGroupId ;
pos - > pos = ( SResultRowPosition ) { . pageId = pResult - > pageId , . offset = pResult - > offset } ;
* ( int64_t * ) pos - > key = pResult - > win . skey ;
2022-03-29 12:07:38 +00:00
taosArrayPush ( pUpdated , & pos ) ;
}
2022-03-29 07:24:25 +00:00
ekey = nextWin . ekey ; // reviseWindowEkey(pQueryAttr, &nextWin);
forwardStep =
getNumOfRowsInTimeWindow ( & pSDataBlock - > info , tsCols , startPos , ekey , binarySearchForKey , NULL , TSDB_ORDER_ASC ) ;
2021-11-02 05:37:31 +00:00
// window start(end) key interpolation
2022-04-07 09:13:55 +00:00
doWindowBorderInterpolation ( pOperatorInfo , pSDataBlock , pInfo - > binfo . pCtx , pResult , & nextWin , startPos , forwardStep ,
pInfo - > order , false ) ;
2022-04-02 05:32:26 +00:00
2022-04-19 02:12:30 +00:00
updateTimeWindowInfo ( & pInfo - > twAggSup . timeWindowData , & nextWin , true ) ;
2022-04-23 10:29:45 +00:00
doApplyFunctions ( pInfo - > binfo . pCtx , & nextWin , & pInfo - > twAggSup . timeWindowData , startPos , forwardStep , tsCols ,
pSDataBlock - > info . rows , numOfOutput , TSDB_ORDER_ASC ) ;
2021-11-02 05:37:31 +00:00
}
2022-02-24 09:18:56 +00:00
if ( pInfo - > timeWindowInterpo ) {
2022-03-29 12:07:38 +00:00
int32_t rowIndex = ascScan ? ( pSDataBlock - > info . rows - 1 ) : 0 ;
2022-02-24 09:18:56 +00:00
saveDataBlockLastRow ( pInfo - > pRow , pSDataBlock - > pDataBlock , rowIndex , pSDataBlock - > info . numOfCols ) ;
2021-11-02 05:37:31 +00:00
}
2022-03-29 12:07:38 +00:00
return pUpdated ;
2022-03-29 07:24:25 +00:00
// updateResultRowInfoActiveIndex(pResultRowInfo, &pInfo->win, pRuntimeEnv->current->lastKey, true, false);
2021-11-02 05:37:31 +00:00
}
2022-04-09 07:01:28 +00:00
static void doKeepTuple ( SWindowRowsSup * pRowSup , int64_t ts ) {
2022-04-23 10:29:45 +00:00
pRowSup - > win . ekey = ts ;
pRowSup - > prevTs = ts ;
2022-04-09 07:01:28 +00:00
pRowSup - > numOfRows + = 1 ;
2022-04-02 05:32:26 +00:00
}
2022-04-09 07:01:28 +00:00
static void doKeepNewWindowStartInfo ( SWindowRowsSup * pRowSup , const int64_t * tsList , int32_t rowIndex ) {
pRowSup - > startRowIndex = rowIndex ;
2022-04-23 10:29:45 +00:00
pRowSup - > numOfRows = 0 ;
pRowSup - > win . skey = tsList [ rowIndex ] ;
2022-04-02 05:32:26 +00:00
}
2022-03-29 06:36:08 +00:00
// todo handle multiple tables cases.
2022-03-29 07:24:25 +00:00
static void doSessionWindowAggImpl ( SOperatorInfo * pOperator , SSessionAggOperatorInfo * pInfo , SSDataBlock * pBlock ) {
2022-03-28 12:11:02 +00:00
SExecTaskInfo * pTaskInfo = pOperator - > pTaskInfo ;
2021-11-02 05:37:31 +00:00
2022-04-09 07:01:28 +00:00
// todo find the correct time stamp column slot
2022-03-29 06:36:08 +00:00
SColumnInfoData * pColInfoData = taosArrayGet ( pBlock - > pDataBlock , 0 ) ;
2021-11-02 05:37:31 +00:00
2022-04-02 05:32:26 +00:00
bool masterScan = true ;
int32_t numOfOutput = pOperator - > numOfOutput ;
int64_t gid = pBlock - > info . groupId ;
2021-11-02 05:37:31 +00:00
2022-03-28 12:11:02 +00:00
int64_t gap = pInfo - > gap ;
2022-04-09 07:01:28 +00:00
2022-04-02 05:32:26 +00:00
if ( ! pInfo - > reptScan ) {
2021-11-02 05:37:31 +00:00
pInfo - > reptScan = true ;
2022-04-09 07:01:28 +00:00
pInfo - > winSup . prevTs = INT64_MIN ;
2021-11-02 05:37:31 +00:00
}
2022-04-09 07:01:28 +00:00
SWindowRowsSup * pRowSup = & pInfo - > winSup ;
pRowSup - > numOfRows = 0 ;
2022-04-02 05:32:26 +00:00
// In case of ascending or descending order scan data, only one time window needs to be kepted for each table.
2021-11-02 05:37:31 +00:00
TSKEY * tsList = ( TSKEY * ) pColInfoData - > pData ;
2022-03-29 06:36:08 +00:00
for ( int32_t j = 0 ; j < pBlock - > info . rows ; + + j ) {
2022-04-09 07:01:28 +00:00
if ( pInfo - > winSup . prevTs = = INT64_MIN ) {
doKeepNewWindowStartInfo ( pRowSup , tsList , j ) ;
doKeepTuple ( pRowSup , tsList [ j ] ) ;
} else if ( tsList [ j ] - pRowSup - > prevTs < = gap & & ( tsList [ j ] - pRowSup - > prevTs ) > = 0 ) {
2022-04-02 05:32:26 +00:00
// The gap is less than the threshold, so it belongs to current session window that has been opened already.
2022-04-09 07:01:28 +00:00
doKeepTuple ( pRowSup , tsList [ j ] ) ;
if ( j = = 0 & & pRowSup - > startRowIndex ! = 0 ) {
pRowSup - > startRowIndex = 0 ;
2021-11-02 05:37:31 +00:00
}
} else { // start a new session window
SResultRow * pResult = NULL ;
2022-04-02 05:32:26 +00:00
// keep the time window for the closed time window.
2022-04-09 07:01:28 +00:00
STimeWindow window = pRowSup - > win ;
2022-04-02 05:32:26 +00:00
2022-04-09 07:01:28 +00:00
pRowSup - > win . ekey = pRowSup - > win . skey ;
2022-03-29 07:24:25 +00:00
int32_t ret = setResultOutputBufByKey_rv ( & pInfo - > binfo . resultRowInfo , pBlock - > info . uid , & window , masterScan ,
2022-04-23 10:29:45 +00:00
& pResult , gid , pInfo - > binfo . pCtx , numOfOutput ,
pInfo - > binfo . rowCellInfoOffset , & pInfo - > aggSup , pTaskInfo ) ;
2021-11-02 05:37:31 +00:00
if ( ret ! = TSDB_CODE_SUCCESS ) { // null data, too many state code
2022-03-29 06:36:08 +00:00
longjmp ( pTaskInfo - > env , TSDB_CODE_QRY_APP_ERROR ) ;
2021-11-02 05:37:31 +00:00
}
2022-03-29 06:36:08 +00:00
// pInfo->numOfRows data belong to the current session window
2022-04-19 02:12:30 +00:00
updateTimeWindowInfo ( & pInfo - > twAggSup . timeWindowData , & window , false ) ;
2022-04-23 10:29:45 +00:00
doApplyFunctions ( pInfo - > binfo . pCtx , & window , & pInfo - > twAggSup . timeWindowData , pRowSup - > startRowIndex ,
pRowSup - > numOfRows , NULL , pBlock - > info . rows , numOfOutput , TSDB_ORDER_ASC ) ;
2021-11-02 05:37:31 +00:00
2022-04-02 05:32:26 +00:00
// here we start a new session window
2022-04-09 07:01:28 +00:00
doKeepNewWindowStartInfo ( pRowSup , tsList , j ) ;
doKeepTuple ( pRowSup , tsList [ j ] ) ;
2021-11-02 05:37:31 +00:00
}
}
SResultRow * pResult = NULL ;
2022-04-09 07:01:28 +00:00
pRowSup - > win . ekey = tsList [ pBlock - > info . rows - 1 ] ;
2022-04-23 10:29:45 +00:00
int32_t ret = setResultOutputBufByKey_rv ( & pInfo - > binfo . resultRowInfo , pBlock - > info . uid , & pRowSup - > win , masterScan ,
& pResult , gid , pInfo - > binfo . pCtx , numOfOutput ,
pInfo - > binfo . rowCellInfoOffset , & pInfo - > aggSup , pTaskInfo ) ;
2021-11-02 05:37:31 +00:00
if ( ret ! = TSDB_CODE_SUCCESS ) { // null data, too many state code
2022-03-29 06:36:08 +00:00
longjmp ( pTaskInfo - > env , TSDB_CODE_QRY_APP_ERROR ) ;
2021-11-02 05:37:31 +00:00
}
2022-04-19 02:12:30 +00:00
updateTimeWindowInfo ( & pInfo - > twAggSup . timeWindowData , & pRowSup - > win , false ) ;
2022-04-23 10:29:45 +00:00
doApplyFunctions ( pInfo - > binfo . pCtx , & pRowSup - > win , & pInfo - > twAggSup . timeWindowData , pRowSup - > startRowIndex ,
pRowSup - > numOfRows , NULL , pBlock - > info . rows , numOfOutput , TSDB_ORDER_ASC ) ;
2021-11-02 05:37:31 +00:00
}
static void setResultRowKey ( SResultRow * pResultRow , char * pData , int16_t type ) {
if ( IS_VAR_DATA_TYPE ( type ) ) {
2022-04-11 06:54:16 +00:00
// todo disable this
2022-04-23 10:29:45 +00:00
// if (pResultRow->key == NULL) {
// pResultRow->key = taosMemoryMalloc(varDataTLen(pData));
// varDataCopy(pResultRow->key, pData);
// } else {
// ASSERT(memcmp(pResultRow->key, pData, varDataTLen(pData)) == 0);
// }
2021-11-02 05:37:31 +00:00
} else {
int64_t v = - 1 ;
GET_TYPED_DATA ( v , int64_t , type , pData ) ;
pResultRow - > win . skey = v ;
pResultRow - > win . ekey = v ;
}
}
2022-04-14 07:33:37 +00:00
int32_t setGroupResultOutputBuf ( SOptrBasicInfo * binfo , int32_t numOfCols , char * pData , int16_t type , int16_t bytes ,
2022-04-23 10:29:45 +00:00
int32_t groupId , SDiskbasedBuf * pBuf , SExecTaskInfo * pTaskInfo ,
SAggSupporter * pAggSup ) {
2022-03-29 07:24:25 +00:00
SResultRowInfo * pResultRowInfo = & binfo - > resultRowInfo ;
SqlFunctionCtx * pCtx = binfo - > pCtx ;
2021-11-02 05:37:31 +00:00
2022-04-25 08:44:48 +00:00
SResultRow * pResultRow = doSetResultOutBufByKey ( pBuf , pResultRowInfo , groupId , ( char * ) pData , bytes , true , groupId ,
2022-04-01 02:44:34 +00:00
pTaskInfo , false , pAggSup ) ;
2022-03-29 07:24:25 +00:00
assert ( pResultRow ! = NULL ) ;
2021-11-02 05:37:31 +00:00
setResultRowKey ( pResultRow , pData , type ) ;
2022-04-01 02:44:34 +00:00
setResultRowOutputBufInitCtx_rv ( pResultRow , pCtx , numOfCols , binfo - > rowCellInfoOffset ) ;
2021-11-02 05:37:31 +00:00
return TSDB_CODE_SUCCESS ;
}
2022-03-29 07:24:25 +00:00
static bool functionNeedToExecute ( SqlFunctionCtx * pCtx ) {
struct SResultRowEntryInfo * pResInfo = GET_RES_INFO ( pCtx ) ;
2021-11-02 05:37:31 +00:00
// in case of timestamp column, always generated results.
int32_t functionId = pCtx - > functionId ;
2022-03-22 08:03:42 +00:00
if ( functionId = = - 1 ) {
return false ;
}
2022-03-30 05:41:15 +00:00
if ( isRowEntryCompleted ( pResInfo ) ) {
2021-11-02 05:37:31 +00:00
return false ;
}
if ( functionId = = FUNCTION_FIRST_DST | | functionId = = FUNCTION_FIRST ) {
2022-03-29 07:24:25 +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-03-29 07:24:25 +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-03-29 07:24:25 +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-04-23 10:29:45 +00:00
static int32_t doCreateConstantValColumnAggInfo ( SInputColumnInfoData * pInput , SFunctParam * pFuncParam , int32_t type ,
int32_t paramIndex , int32_t numOfRows ) {
2022-04-18 02:46:07 +00:00
if ( pInput - > pData [ paramIndex ] = = NULL ) {
pInput - > pData [ paramIndex ] = taosMemoryCalloc ( 1 , sizeof ( SColumnInfoData ) ) ;
if ( pInput - > pData [ paramIndex ] = = NULL ) {
return TSDB_CODE_OUT_OF_MEMORY ;
}
// Set the correct column info (data type and bytes)
2022-04-23 10:29:45 +00:00
pInput - > pData [ paramIndex ] - > info . type = type ;
pInput - > pData [ paramIndex ] - > info . bytes = tDataTypes [ type ] . bytes ;
2022-04-18 02:46:07 +00:00
}
SColumnDataAgg * da = NULL ;
if ( pInput - > pColumnDataAgg [ paramIndex ] = = NULL ) {
da = taosMemoryCalloc ( 1 , sizeof ( SColumnDataAgg ) ) ;
pInput - > pColumnDataAgg [ paramIndex ] = da ;
if ( da = = NULL ) {
return TSDB_CODE_OUT_OF_MEMORY ;
}
} else {
da = pInput - > pColumnDataAgg [ paramIndex ] ;
}
ASSERT ( ! IS_VAR_DATA_TYPE ( type ) ) ;
if ( type = = TSDB_DATA_TYPE_BIGINT ) {
int64_t v = pFuncParam - > param . i ;
2022-04-23 10:29:45 +00:00
* da = ( SColumnDataAgg ) { . numOfNull = 0 , . min = v , . max = v , . maxIndex = 0 , . minIndex = 0 , . sum = v * numOfRows } ;
2022-04-18 02:46:07 +00:00
} else if ( type = = TSDB_DATA_TYPE_DOUBLE ) {
double v = pFuncParam - > param . d ;
2022-04-23 10:29:45 +00:00
* da = ( SColumnDataAgg ) { . numOfNull = 0 , . maxIndex = 0 , . minIndex = 0 } ;
2022-04-18 02:46:07 +00:00
2022-04-23 10:29:45 +00:00
* ( double * ) & da - > min = v ;
* ( double * ) & da - > max = v ;
* ( double * ) & da - > sum = v * numOfRows ;
2022-04-18 02:46:07 +00:00
} else if ( type = = TSDB_DATA_TYPE_BOOL ) { // todo validate this data type
bool v = pFuncParam - > param . i ;
2022-04-23 10:29:45 +00:00
* da = ( SColumnDataAgg ) { . numOfNull = 0 , . maxIndex = 0 , . minIndex = 0 } ;
* ( bool * ) & da - > min = 0 ;
* ( bool * ) & da - > max = v ;
* ( bool * ) & da - > sum = v * numOfRows ;
2022-04-18 02:46:07 +00:00
} else if ( type = = TSDB_DATA_TYPE_TIMESTAMP ) {
// do nothing
} else {
ASSERT ( 0 ) ;
}
return TSDB_CODE_SUCCESS ;
}
void setBlockStatisInfo ( SqlFunctionCtx * pCtx , SExprInfo * pExprInfo , SSDataBlock * pBlock ) {
int32_t numOfRows = pBlock - > info . rows ;
SInputColumnInfoData * pInput = & pCtx - > input ;
pInput - > numOfRows = numOfRows ;
pInput - > totalRows = numOfRows ;
if ( pBlock - > pBlockAgg ! = NULL ) {
pInput - > colDataAggIsSet = true ;
2022-04-16 03:47:50 +00:00
for ( int32_t j = 0 ; j < pExprInfo - > base . numOfParams ; + + j ) {
SFunctParam * pFuncParam = & pExprInfo - > base . pParam [ j ] ;
2022-04-18 02:46:07 +00:00
2022-04-16 03:47:50 +00:00
if ( pFuncParam - > type = = FUNC_PARAM_TYPE_COLUMN ) {
int32_t slotId = pFuncParam - > pCol - > slotId ;
pInput - > pColumnDataAgg [ j ] = & pBlock - > pBlockAgg [ slotId ] ;
2022-04-16 08:06:48 +00:00
// Here we set the column info data since the data type for each column data is required, but
// the data in the corresponding SColumnInfoData will not be used.
pInput - > pData [ j ] = taosArrayGet ( pBlock - > pDataBlock , slotId ) ;
2022-04-18 02:46:07 +00:00
} else if ( pFuncParam - > type = = FUNC_PARAM_TYPE_VALUE ) {
doCreateConstantValColumnAggInfo ( pInput , pFuncParam , pFuncParam - > param . nType , j , pBlock - > info . rows ) ;
2022-04-16 03:47:50 +00:00
}
}
2021-11-02 05:37:31 +00:00
} else {
2022-04-18 02:46:07 +00:00
pInput - > colDataAggIsSet = false ;
2021-11-02 05:37:31 +00:00
}
// set the statistics data for primary time stamp column
2022-04-16 03:47:50 +00:00
// if (pCtx->functionId == FUNCTION_SPREAD && pColumn->colId == PRIMARYKEY_TIMESTAMP_COL_ID) {
// pCtx->isAggSet = true;
// pCtx->agg.min = pBlock->info.window.skey;
// pCtx->agg.max = pBlock->info.window.ekey;
// }
2021-11-02 05:37:31 +00:00
}
// set the output buffer for the selectivity + tag query
2022-03-29 07:24:25 +00:00
static int32_t setCtxTagColumnInfo ( SqlFunctionCtx * pCtx , int32_t numOfOutput ) {
2021-11-02 05:37:31 +00:00
int32_t num = 0 ;
int16_t tagLen = 0 ;
2022-01-28 02:44:02 +00:00
SqlFunctionCtx * p = NULL ;
2022-03-25 16:29:53 +00:00
SqlFunctionCtx * * pTagCtx = taosMemoryCalloc ( 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 ] ;
2022-03-29 07:24:25 +00:00
} else if ( 1 /*(aAggs[functionId].status & FUNCSTATE_SELECTIVITY) != 0*/ ) {
2021-11-02 05:37:31 +00:00
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 ) {
2022-04-22 14:43:07 +00:00
p - > subsidiaries . pCtx = pTagCtx ;
p - > subsidiaries . num = num ;
2021-11-02 05:37:31 +00:00
} else {
2022-03-25 16:29:53 +00:00
taosMemoryFreeClear ( pTagCtx ) ;
2021-11-02 05:37:31 +00:00
}
return TSDB_CODE_SUCCESS ;
}
2022-04-12 09:55:17 +00:00
SqlFunctionCtx * createSqlFunctionCtx ( SExprInfo * pExprInfo , int32_t numOfOutput , int32_t * * rowCellInfoOffset ) {
2022-03-29 07:24:25 +00:00
SqlFunctionCtx * pFuncCtx = ( SqlFunctionCtx * ) taosMemoryCalloc ( numOfOutput , sizeof ( SqlFunctionCtx ) ) ;
2022-01-14 02:20:55 +00:00
if ( pFuncCtx = = NULL ) {
return NULL ;
}
2022-03-25 16:29:53 +00:00
* rowCellInfoOffset = taosMemoryCalloc ( numOfOutput , sizeof ( int32_t ) ) ;
2022-01-14 02:20:55 +00:00
if ( * rowCellInfoOffset = = 0 ) {
2022-03-25 16:29:53 +00:00
taosMemoryFreeClear ( pFuncCtx ) ;
2022-01-14 02:20:55 +00:00
return NULL ;
}
for ( int32_t i = 0 ; i < numOfOutput ; + + i ) {
2022-03-12 14:59:12 +00:00
SExprInfo * pExpr = & pExprInfo [ i ] ;
2022-01-20 05:52:46 +00:00
2022-03-29 07:24:25 +00:00
SExprBasicInfo * pFunct = & pExpr - > base ;
2022-01-28 02:44:02 +00:00
SqlFunctionCtx * pCtx = & pFuncCtx [ i ] ;
2022-01-20 09:10:28 +00:00
2022-03-26 14:13:14 +00:00
pCtx - > functionId = - 1 ;
2022-04-22 14:43:07 +00:00
pCtx - > curBufPage = - 1 ;
pCtx - > pExpr = pExpr ;
2022-03-26 14:17:26 +00:00
if ( pExpr - > pExpr - > nodeType = = QUERY_NODE_FUNCTION ) {
2022-03-18 10:02:00 +00:00
SFuncExecEnv env = { 0 } ;
2022-03-22 08:03:42 +00:00
pCtx - > functionId = pExpr - > pExpr - > _function . pFunctNode - > funcId ;
2022-04-04 06:54:39 +00:00
if ( fmIsAggFunc ( pCtx - > functionId ) | | fmIsNonstandardSQLFunc ( pCtx - > functionId ) ) {
2022-03-27 14:43:07 +00:00
fmGetFuncExecFuncs ( pCtx - > functionId , & pCtx - > fpSet ) ;
pCtx - > fpSet . getEnv ( pExpr - > pExpr - > _function . pFunctNode , & env ) ;
} else {
fmGetScalarFuncExecFuncs ( pCtx - > functionId , & pCtx - > sfp ) ;
2022-03-30 05:41:15 +00:00
if ( pCtx - > sfp . getEnv ! = NULL ) {
pCtx - > sfp . getEnv ( pExpr - > pExpr - > _function . pFunctNode , & env ) ;
}
2022-03-27 14:43:07 +00:00
}
2022-03-18 10:02:00 +00:00
pCtx - > resDataInfo . interBufSize = env . calcMemSize ;
2022-04-21 09:44:08 +00:00
} else if ( pExpr - > pExpr - > nodeType = = QUERY_NODE_COLUMN | | pExpr - > pExpr - > nodeType = = QUERY_NODE_OPERATOR | |
pExpr - > pExpr - > nodeType = = QUERY_NODE_VALUE ) {
// for simple column, the intermediate buffer needs to hold one element.
pCtx - > resDataInfo . interBufSize = pFunct - > resSchema . bytes ;
2022-03-18 10:02:00 +00:00
}
2022-01-14 02:20:55 +00:00
2022-03-18 10:02:00 +00:00
pCtx - > input . numOfInputCols = pFunct - > numOfParams ;
2022-03-25 16:29:53 +00:00
pCtx - > input . pData = taosMemoryCalloc ( pFunct - > numOfParams , POINTER_BYTES ) ;
pCtx - > input . pColumnDataAgg = taosMemoryCalloc ( pFunct - > numOfParams , POINTER_BYTES ) ;
2022-01-14 02:20:55 +00:00
2022-04-21 09:44:08 +00:00
pCtx - > pTsOutput = NULL ;
2022-03-29 07:24:25 +00:00
pCtx - > resDataInfo . bytes = pFunct - > resSchema . bytes ;
2022-04-21 09:44:08 +00:00
pCtx - > resDataInfo . type = pFunct - > resSchema . type ;
2022-04-22 14:43:07 +00:00
pCtx - > order = TSDB_ORDER_ASC ;
2022-04-21 09:44:08 +00:00
pCtx - > start . key = INT64_MIN ;
2022-04-22 14:43:07 +00:00
pCtx - > end . key = INT64_MIN ;
2022-04-21 09:44:08 +00:00
pCtx - > numOfParams = pExpr - > base . numOfParams ;
2022-01-14 02:20:55 +00:00
2022-04-21 09:44:08 +00:00
pCtx - > param = pFunct - > pParam ;
2022-04-23 10:29:45 +00:00
// for (int32_t j = 0; j < pCtx->numOfParams; ++j) {
// // 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_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-14 02:20:55 +00:00
}
2022-03-29 07:24:25 +00:00
for ( int32_t i = 1 ; i < numOfOutput ; + + i ) {
( * rowCellInfoOffset ) [ i ] =
( int32_t ) ( ( * rowCellInfoOffset ) [ i - 1 ] + sizeof ( SResultRowEntryInfo ) + pFuncCtx [ i - 1 ] . resDataInfo . interBufSize ) ;
2022-01-20 09:10:28 +00:00
}
2022-01-14 02:20:55 +00:00
setCtxTagColumnInfo ( pFuncCtx , numOfOutput ) ;
return pFuncCtx ;
}
2022-03-10 03:12:44 +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 ) {
2022-04-21 09:44:08 +00:00
taosVariantDestroy ( & pCtx [ i ] . param [ j ] . param ) ;
2021-11-02 05:37:31 +00:00
}
taosVariantDestroy ( & pCtx [ i ] . tag ) ;
2022-04-22 14:43:07 +00:00
taosMemoryFreeClear ( pCtx [ i ] . subsidiaries . pCtx ) ;
2021-11-02 05:37:31 +00:00
}
2022-03-25 16:29:53 +00:00
taosMemoryFreeClear ( pCtx ) ;
2021-11-02 05:37:31 +00:00
return NULL ;
}
2022-03-29 07:24:25 +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-03-29 07:24:25 +00:00
if ( pTaskInfo - > owner ! = 0 & &
( ( taosGetTimestampSec ( ) - pTaskInfo - > cost . start / 1000 ) > 10 * getMaximumIdleDurationSec ( ) )
2022-01-10 11:48:21 +00:00
/*(!needBuildResAfterQueryComplete(pTaskInfo))*/ ) {
assert ( pTaskInfo - > cost . start ! = 0 ) ;
2022-03-29 07:24:25 +00:00
// qDebug("QInfo:%" PRIu64 " retrieve not arrive beyond %d ms, abort current query execution, start:%" PRId64
// ", current:%d", pQInfo->qId, 1, pQInfo->startExecTs, taosGetTimestampSec());
// return true;
2021-11-02 05:37:31 +00:00
}
return false ;
}
2022-03-29 07:24:25 +00:00
void setTaskKilled ( SExecTaskInfo * pTaskInfo ) { pTaskInfo - > code = TSDB_CODE_TSC_QUERY_CANCELLED ; }
2021-11-02 05:37:31 +00:00
2022-03-29 07:24:25 +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 ;
}
2022-04-14 06:39:28 +00:00
int32_t order = TSDB_ORDER_ASC ;
if ( order ! = TSDB_ORDER_DESC | | ! TSWINDOW_IS_EQUAL ( pQueryAttr - > window , TSWINDOW_DESC_INITIALIZER ) ) {
2021-11-02 05:37:31 +00:00
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 ;
}
/////////////////////////////////////////////////////////////////////////////////////////////
2022-03-29 07:24:25 +00:00
// todo refactor : return window
2022-04-20 06:59:06 +00:00
void getAlignQueryTimeWindow ( SInterval * pInterval , int32_t precision , int64_t key , STimeWindow * win ) {
2022-02-24 09:18:56 +00:00
win - > skey = taosTimeTruncate ( key , pInterval , precision ) ;
2021-11-02 05:37:31 +00:00
/*
2022-02-24 09:18:56 +00:00
* if the realSkey > INT64_MAX - pInterval - > interval , the query duration between
2021-11-02 05:37:31 +00:00
* realSkey and realEkey must be less than one interval . Therefore , no need to adjust the query ranges .
*/
2022-04-20 06:59:06 +00:00
win - > ekey = taosTimeAdd ( win - > skey , pInterval - > interval , pInterval - > intervalUnit , precision ) - 1 ;
if ( win - > ekey < win - > skey ) {
2021-11-02 05:37:31 +00:00
win - > ekey = INT64_MAX ;
}
}
2022-03-29 07:24:25 +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 ;
2022-04-15 06:01:43 +00:00
if ( status = = BLK_DATA_DATA_LOAD | | status = = BLK_DATA_FILTEROUT ) {
2021-11-02 05:37:31 +00:00
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 ;
}
}
2022-04-15 06:01:43 +00:00
if ( hasFirstLastFunc & & status = = BLK_DATA_NOT_LOAD ) {
2022-03-29 07:24:25 +00:00
if ( ! hasOtherFunc ) {
2022-04-15 06:01:43 +00:00
return BLK_DATA_FILTEROUT ;
2021-11-02 05:37:31 +00:00
} else {
2022-04-15 06:01:43 +00:00
return BLK_DATA_DATA_LOAD ;
2021-11-02 05:37:31 +00:00
}
}
return status ;
}
2022-03-29 07:24:25 +00:00
// static void updateDataCheckOrder(SQInfo *pQInfo, SQueryTableReq* pQueryMsg, bool stableQuery) {
// STaskAttr* pQueryAttr = pQInfo->runtimeEnv.pQueryAttr;
2022-03-09 02:22:53 +00:00
//
2022-03-29 07:24:25 +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;
2022-03-09 02:22:53 +00:00
//
2022-03-29 07:24:25 +00:00
// // 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);
2022-03-09 02:22:53 +00:00
//
2022-03-29 07:24:25 +00:00
// pQueryAttr->order.order = TSDB_ORDER_ASC;
// if (pQueryAttr->window.skey > pQueryAttr->window.ekey) {
2022-04-27 09:39:54 +00:00
// TSWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey);
2022-03-29 07:24:25 +00:00
// }
2022-03-09 02:22:53 +00:00
//
2022-03-29 07:24:25 +00:00
// pQueryAttr->needReverseScan = false;
// return;
// }
2022-03-09 02:22:53 +00:00
//
2022-03-29 07:24:25 +00:00
// if (pQueryAttr->groupbyColumn && pQueryAttr->order.order == TSDB_ORDER_DESC) {
// pQueryAttr->order.order = TSDB_ORDER_ASC;
// if (pQueryAttr->window.skey > pQueryAttr->window.ekey) {
2022-04-27 09:39:54 +00:00
// TSWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey);
2022-03-29 07:24:25 +00:00
// }
2022-03-09 02:22:53 +00:00
//
2022-03-29 07:24:25 +00:00
// pQueryAttr->needReverseScan = false;
// doUpdateLastKey(pQueryAttr);
// return;
// }
2022-03-09 02:22:53 +00:00
//
2022-03-29 07:24:25 +00:00
// 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); TSWAP(pQueryAttr->window.skey,
// pQueryAttr->window.ekey, TSKEY);
// }
2022-03-09 02:22:53 +00:00
//
2022-03-29 07:24:25 +00:00
// pQueryAttr->order.order = TSDB_ORDER_ASC;
// return;
// }
2022-03-09 02:22:53 +00:00
//
2022-03-29 07:24:25 +00:00
// 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,
2022-03-09 02:22:53 +00:00
//// pQueryAttr->window.ekey, pQueryAttr->window.ekey, pQueryAttr->window.skey);
//
2022-04-27 09:39:54 +00:00
// TSWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey);
2022-03-09 02:22:53 +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-04-27 09:39:54 +00:00
// TSWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey);
2022-03-09 02:22:53 +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,
2022-03-29 07:24:25 +00:00
//// pQueryAttr->window.skey, pQueryAttr->window.ekey, pQueryAttr->window.ekey,
/// pQueryAttr->window.skey);
2022-03-09 02:22:53 +00:00
//
2022-04-27 09:39:54 +00:00
// TSWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey);
2022-03-09 02:22:53 +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,
2022-03-29 07:24:25 +00:00
//// pQueryAttr->window.skey, pQueryAttr->window.ekey, pQueryAttr->window.ekey,
/// pQueryAttr->window.skey);
2022-03-09 02:22:53 +00:00
//
2022-04-27 09:39:54 +00:00
// TSWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey);
2022-03-09 02:22:53 +00:00
// doUpdateLastKey(pQueryAttr);
// }
//
// pQueryAttr->order.order = TSDB_ORDER_DESC;
// pQueryAttr->needReverseScan = false;
// }
// }
// }
//}
2021-11-02 05:37:31 +00:00
2022-01-08 08:28:44 +00:00
static void getIntermediateBufInfo ( STaskRuntimeEnv * pRuntimeEnv , int32_t * ps , int32_t * rowsize ) {
STaskAttr * pQueryAttr = pRuntimeEnv - > pQueryAttr ;
2022-03-29 07:24:25 +00:00
int32_t MIN_ROWS_PER_PAGE = 4 ;
2021-11-02 05:37:31 +00:00
2022-03-29 07:24:25 +00:00
* rowsize = ( int32_t ) ( pQueryAttr - > resultRowSize *
getRowNumForMultioutput ( pQueryAttr , pQueryAttr - > topBotQuery , pQueryAttr - > stableQuery ) ) ;
2021-11-02 05:37:31 +00:00
int32_t overhead = sizeof ( SFilePage ) ;
// one page contains at least two rows
* ps = DEFAULT_INTERN_BUF_PAGE_SIZE ;
2022-03-29 07:24:25 +00:00
while ( ( ( * rowsize ) * MIN_ROWS_PER_PAGE ) > ( * ps ) - overhead ) {
2021-11-02 05:37:31 +00:00
* ps = ( ( * ps ) < < 1u ) ;
}
}
# define IS_PREFILTER_TYPE(_t) ((_t) != TSDB_DATA_TYPE_BINARY && (_t) != TSDB_DATA_TYPE_NCHAR)
2022-03-29 07:24:25 +00:00
// static FORCE_INLINE bool doFilterByBlockStatistics(STaskRuntimeEnv* pRuntimeEnv, SDataStatis *pDataStatis,
// SqlFunctionCtx *pCtx, int32_t numOfRows) {
// STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr;
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// if (pDataStatis == NULL || pQueryAttr->pFilters == NULL) {
// return true;
// }
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// return filterRangeExecute(pQueryAttr->pFilters, pDataStatis, pQueryAttr->numOfCols, numOfRows);
// }
2021-11-02 05:37:31 +00:00
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
2022-04-14 06:39:28 +00:00
if ( true ) {
2022-03-29 07:24:25 +00:00
// getAlignQueryTimeWindow(pQueryAttr, pBlockInfo->window.skey, sk, ek, &w);
2021-11-02 05:37:31 +00:00
assert ( w . ekey > = pBlockInfo - > window . skey ) ;
if ( w . ekey < pBlockInfo - > window . ekey ) {
return true ;
}
2022-03-29 07:24:25 +00:00
while ( 1 ) {
// getNextTimeWindow(pQueryAttr, &w);
2021-11-02 05:37:31 +00:00
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 {
2022-03-29 07:24:25 +00:00
// getAlignQueryTimeWindow(pQueryAttr, pBlockInfo->window.ekey, sk, ek, &w);
2021-11-02 05:37:31 +00:00
assert ( w . skey < = pBlockInfo - > window . ekey ) ;
if ( w . skey > pBlockInfo - > window . skey ) {
return true ;
}
2022-03-29 07:24:25 +00:00
while ( 1 ) {
// getNextTimeWindow(pQueryAttr, &w);
2021-11-02 05:37:31 +00:00
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 ;
}
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 ) ) ;
}
}
}
static SColumnInfo * doGetTagColumnInfoById ( SColumnInfo * pTagColList , int32_t numOfTags , int16_t colId ) ;
2022-03-29 07:24:25 +00:00
static void doSetTagValueInParam ( void * pTable , int32_t tagColId , SVariant * tag , int16_t type , int16_t bytes ) ;
2021-11-02 05:37:31 +00:00
static uint32_t doFilterByBlockTimeWindow ( STableScanInfo * pTableScanInfo , SSDataBlock * pBlock ) {
2022-01-28 02:44:02 +00:00
SqlFunctionCtx * pCtx = pTableScanInfo - > pCtx ;
2022-04-15 06:01:43 +00:00
uint32_t status = BLK_DATA_NOT_LOAD ;
2021-11-02 05:37:31 +00:00
int32_t numOfOutput = pTableScanInfo - > numOfOutput ;
for ( int32_t i = 0 ; i < numOfOutput ; + + i ) {
int32_t functionId = pCtx [ i ] . functionId ;
2022-03-09 02:22:53 +00:00
int32_t colId = pTableScanInfo - > pExpr [ i ] . base . pParam [ 0 ] . pCol - > colId ;
2021-11-02 05:37:31 +00:00
// group by + first/last should not apply the first/last block filter
if ( functionId < 0 ) {
2022-04-15 06:01:43 +00:00
status | = BLK_DATA_DATA_LOAD ;
2021-11-02 05:37:31 +00:00
return status ;
} else {
2022-03-29 07:24:25 +00:00
// status |= aAggs[functionId].dataReqFunc(&pTableScanInfo->pCtx[i], &pBlock->info.window, colId);
2022-04-15 06:01:43 +00:00
// if ((status & BLK_DATA_DATA_LOAD) == BLK_DATA_DATA_LOAD) {
2022-03-29 07:24:25 +00:00
// return status;
// }
2021-11-02 05:37:31 +00:00
}
}
return status ;
}
2022-03-29 07:24:25 +00:00
int32_t loadDataBlockOnDemand ( SExecTaskInfo * pTaskInfo , STableScanInfo * pTableScanInfo , SSDataBlock * pBlock ,
uint32_t * status ) {
2022-04-15 06:01:43 +00:00
* status = BLK_DATA_NOT_LOAD ;
2021-11-02 05:37:31 +00:00
2022-01-08 14:59:24 +00:00
pBlock - > pDataBlock = NULL ;
2022-03-29 07:24:25 +00:00
pBlock - > pBlockAgg = NULL ;
2022-01-08 14:59:24 +00:00
2022-03-29 07:24:25 +00:00
// 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
// 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 ) ) ) {
2022-04-15 06:01:43 +00:00
( * status ) = BLK_DATA_DATA_LOAD ;
2021-11-02 05:37:31 +00:00
}
// check if this data block is required to load
2022-04-15 06:01:43 +00:00
if ( ( * status ) ! = BLK_DATA_DATA_LOAD ) {
2021-11-02 05:37:31 +00:00
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 {
2022-04-15 06:01:43 +00:00
( * status ) = BLK_DATA_DATA_LOAD ;
2021-11-02 05:37:31 +00:00
}
}
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
2022-04-15 06:01:43 +00:00
if ( ( * status ) = = BLK_DATA_NOT_LOAD | | ( * status ) = = BLK_DATA_FILTEROUT ) {
2021-11-02 05:37:31 +00:00
//qDebug("QInfo:0x%"PRIx64" data block discard, brange:%" PRId64 "-%" PRId64 ", rows:%d", pQInfo->qId, pBlockInfo->window.skey,
// pBlockInfo->window.ekey, pBlockInfo->rows);
2022-04-15 12:06:27 +00:00
pCost - > skipBlocks + = 1 ;
2022-04-15 06:01:43 +00:00
} else if ( ( * status ) = = BLK_DATA_SMA_LOAD ) {
2021-11-02 05:37:31 +00:00
// 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 {
2022-04-15 06:01:43 +00:00
assert ( ( * status ) = = BLK_DATA_DATA_LOAD ) ;
2021-11-02 05:37:31 +00:00
// 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
2022-04-15 12:06:27 +00:00
pCost - > skipBlocks + = 1 ;
2021-11-02 05:37:31 +00:00
//qDebug("QInfo:0x%"PRIx64" data block discard, brange:%" PRId64 "-%" PRId64 ", rows:%d", pQInfo->qId,
// pBlockInfo->window.skey, pBlockInfo->window.ekey, pBlockInfo->rows);
2022-04-15 06:01:43 +00:00
( * status ) = BLK_DATA_FILTEROUT ;
2021-11-02 05:37:31 +00:00
return TSDB_CODE_SUCCESS ;
}
}
}
}
// current block has been discard due to filter applied
// if (!doFilterByBlockStatistics(pRuntimeEnv, pBlock->pBlockAgg, pTableScanInfo->pCtx, pBlockInfo->rows)) {
2022-04-15 12:06:27 +00:00
// pCost->skipBlocks += 1;
2021-11-02 05:37:31 +00:00
// qDebug("QInfo:0x%"PRIx64" data block discard, brange:%" PRId64 "-%" PRId64 ", rows:%d", pQInfo->qId, pBlockInfo->window.skey,
// pBlockInfo->window.ekey, pBlockInfo->rows);
2022-04-15 06:01:43 +00:00
// (*status) = BLK_DATA_FILTEROUT;
2021-11-02 05:37:31 +00:00
// 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 ;
}
2022-03-29 07:24:25 +00:00
int32_t binarySearchForKey ( char * pValue , int num , TSKEY key , int order ) {
2021-11-02 05:37:31 +00:00
int32_t midPos = - 1 ;
int32_t numOfRows ;
if ( num < = 0 ) {
return - 1 ;
}
assert ( order = = TSDB_ORDER_ASC | | order = = TSDB_ORDER_DESC ) ;
2022-03-29 07:24:25 +00:00
TSKEY * keyList = ( TSKEY * ) pValue ;
2021-11-02 05:37:31 +00:00
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
*/
2022-03-29 07:24:25 +00:00
static void doSetTagValueInParam ( void * pTable , int32_t tagColId , SVariant * tag , int16_t type , int16_t bytes ) {
2021-11-02 05:37:31 +00:00
taosVariantDestroy ( tag ) ;
char * val = NULL ;
2022-03-29 07:24:25 +00:00
// if (tagColId == TSDB_TBNAME_COLUMN_INDEX) {
// val = tsdbGetTableName(pTable);
// assert(val != NULL);
// } else {
// val = tsdbGetTableTagVal(pTable, tagColId, type, bytes);
// }
2021-11-02 05:37:31 +00:00
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 ;
2022-03-29 07:24:25 +00:00
int32_t len = ( varDataLen ( val ) > maxLen ) ? maxLen : varDataLen ( val ) ;
2021-11-02 05:37:31 +00:00
taosVariantCreateFromBinary ( tag , varDataVal ( val ) , len , type ) ;
2022-03-29 07:24:25 +00:00
// taosVariantCreateFromBinary(tag, varDataVal(val), varDataLen(val), type);
2021-11-02 05:37:31 +00:00
} else {
taosVariantCreateFromBinary ( tag , val , bytes , type ) ;
}
}
static SColumnInfo * doGetTagColumnInfoById ( SColumnInfo * pTagColList , int32_t numOfTags , int16_t colId ) {
assert ( pTagColList ! = NULL & & numOfTags > 0 ) ;
2022-03-29 07:24:25 +00:00
for ( int32_t i = 0 ; i < numOfTags ; + + i ) {
2021-11-02 05:37:31 +00:00
if ( pTagColList [ i ] . colId = = colId ) {
return & pTagColList [ i ] ;
}
}
return NULL ;
}
2022-03-29 07:24:25 +00:00
void setTagValue ( SOperatorInfo * pOperatorInfo , void * pTable , SqlFunctionCtx * pCtx , int32_t numOfOutput ) {
SExprInfo * pExpr = pOperatorInfo - > pExpr ;
2021-11-02 05:37:31 +00:00
SExprInfo * pExprInfo = & pExpr [ 0 ] ;
2022-03-29 07:24:25 +00:00
int32_t functionId = getExprFunctionId ( pExprInfo ) ;
2022-04-09 08:19:08 +00:00
#if 0
2021-11-02 05:37:31 +00:00
if ( pQueryAttr - > numOfOutput = = 1 & & functionId = = FUNCTION_TS_COMP & & pQueryAttr - > stableQuery ) {
assert ( pExprInfo - > base . numOfParams = = 1 ) ;
2022-03-29 07:24:25 +00:00
// int16_t tagColId = (int16_t)pExprInfo->base.param[0].i;
2022-03-09 02:22:53 +00:00
int16_t tagColId = - 1 ;
2021-11-02 05:37:31 +00:00
SColumnInfo * pColInfo = doGetTagColumnInfoById ( pQueryAttr - > tagColList , pQueryAttr - > numOfTags , tagColId ) ;
doSetTagValueInParam ( pTable , tagColId , & pCtx [ 0 ] . tag , pColInfo - > type , pColInfo - > bytes ) ;
2022-03-09 02:22:53 +00:00
2021-11-02 05:37:31 +00:00
} 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
2022-03-09 02:22:53 +00:00
if ( ! TSDB_COL_IS_TAG ( pLocalExprInfo - > base . pParam [ 0 ] . pCol - > flag ) ) {
2021-11-02 05:37:31 +00:00
continue ;
}
// todo use tag column index to optimize performance
2022-03-29 07:24:25 +00:00
doSetTagValueInParam ( pTable , pLocalExprInfo - > base . pParam [ 0 ] . pCol - > colId , & pCtx [ idx ] . tag ,
pLocalExprInfo - > base . resSchema . type , pLocalExprInfo - > base . resSchema . bytes ) ;
2021-11-02 05:37:31 +00:00
2022-03-29 07:24:25 +00:00
if ( IS_NUMERIC_TYPE ( pLocalExprInfo - > base . resSchema . type ) | |
pLocalExprInfo - > base . resSchema . type = = TSDB_DATA_TYPE_BOOL | |
pLocalExprInfo - > base . resSchema . type = = TSDB_DATA_TYPE_TIMESTAMP ) {
2021-11-02 05:37:31 +00:00
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 ) ;
2022-03-29 07:24:25 +00:00
}
2021-11-02 05:37:31 +00:00
}
offset + = pLocalExprInfo - > base . resSchema . bytes ;
}
}
// set the tsBuf start position before check each data block
if ( pRuntimeEnv - > pTsBuf ! = NULL ) {
setCtxTagForJoin ( pRuntimeEnv , & pCtx [ 0 ] , pExprInfo , pTable ) ;
}
2022-04-09 08:19:08 +00:00
# endif
2021-11-02 05:37:31 +00:00
}
2022-02-14 05:20:46 +00:00
void copyToSDataBlock ( SSDataBlock * pBlock , int32_t * offset , SGroupResInfo * pGroupResInfo , SDiskbasedBuf * pResBuf ) {
2021-11-02 05:37:31 +00:00
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 ) ;
2022-03-29 07:24:25 +00:00
// if ((code = mergeIntoGroupResult(&pGroupResInfo, pRuntimeEnv, offset)) != TSDB_CODE_SUCCESS) {
return ;
// }
2021-11-02 05:37:31 +00:00
}
2022-03-29 07:24:25 +00:00
// doCopyToSDataBlock(pResBuf, pGroupResInfo, TSDB_ORDER_ASC, pBlock, );
2021-11-02 05:37:31 +00:00
// 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
2022-03-29 07:24:25 +00:00
// if (pBlock->info.rows >= threshold) {
// break;
// }
2021-11-02 05:37:31 +00:00
}
}
2022-03-29 07:24:25 +00:00
static void updateTableQueryInfoForReverseScan ( STableQueryInfo * pTableQueryInfo ) {
2021-11-02 05:37:31 +00:00
if ( pTableQueryInfo = = NULL ) {
return ;
}
2022-04-27 09:39:54 +00:00
// TSWAP(pTableQueryInfo->win.skey, pTableQueryInfo->win.ekey);
2022-03-29 07:24:25 +00:00
// pTableQueryInfo->lastKey = pTableQueryInfo->win.skey;
2021-11-02 05:37:31 +00:00
2022-03-29 07:24:25 +00:00
// SWITCH_ORDER(pTableQueryInfo->cur.order);
// pTableQueryInfo->cur.vgroupIndex = -1;
2021-11-02 05:37:31 +00:00
// set the index to be the end slot of result rows array
2022-04-23 10:29:45 +00:00
// SResultRowInfo* pResultRowInfo = &pTableQueryInfo->resInfo;
// if (pResultRowInfo->size > 0) {
// pResultRowInfo->curPos = pResultRowInfo->size - 1;
// } else {
// pResultRowInfo->curPos = -1;
// }
2021-11-02 05:37:31 +00:00
}
2022-03-31 08:10:32 +00:00
void initResultRow ( SResultRow * pResultRow ) {
2021-11-02 05:37:31 +00:00
pResultRow - > pEntryInfo = ( struct SResultRowEntryInfo * ) ( ( char * ) pResultRow + sizeof ( SResultRow ) ) ;
}
/*
* 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 .
2022-03-09 02:22:53 +00:00
* + - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - result column 1 - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - result column 2 - - - - - - - - - - - +
* | SResultRow | SResultRowEntryInfo | intermediate buffer1 | SResultRowEntryInfo | intermediate buffer 2 |
* + - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2021-11-02 05:37:31 +00:00
* offset [ 0 ] offset [ 1 ] offset [ 2 ]
*/
2022-02-22 05:12:03 +00:00
// TODO refactor: some function move away
2022-03-09 02:22:53 +00:00
void setFunctionResultOutput ( SOptrBasicInfo * pInfo , SAggSupporter * pSup , int32_t stage , SExecTaskInfo * pTaskInfo ) {
2022-03-29 07:24:25 +00:00
SqlFunctionCtx * pCtx = pInfo - > pCtx ;
SSDataBlock * pDataBlock = pInfo - > pRes ;
int32_t * rowCellInfoOffset = pInfo - > rowCellInfoOffset ;
2022-03-31 09:59:41 +00:00
2022-01-20 05:52:46 +00:00
SResultRowInfo * pResultRowInfo = & pInfo - > resultRowInfo ;
2022-03-31 09:59:41 +00:00
initResultRowInfo ( pResultRowInfo , 16 ) ;
2022-01-20 05:52:46 +00:00
2022-03-29 07:24:25 +00:00
int64_t tid = 0 ;
int64_t groupId = 0 ;
2022-04-25 08:44:48 +00:00
SResultRow * pRow = doSetResultOutBufByKey ( pSup - > pResultBuf , pResultRowInfo , tid , ( char * ) & tid , sizeof ( tid ) , true ,
2022-03-29 07:24:25 +00:00
groupId , pTaskInfo , false , pSup ) ;
2022-01-20 05:52:46 +00:00
for ( int32_t i = 0 ; i < pDataBlock - > info . numOfCols ; + + i ) {
struct SResultRowEntryInfo * pEntry = getResultCell ( pRow , i , rowCellInfoOffset ) ;
cleanupResultRowEntry ( pEntry ) ;
2022-03-29 07:24:25 +00:00
pCtx [ i ] . resultInfo = pEntry ;
2022-01-20 05:52:46 +00:00
pCtx [ i ] . currentStage = stage ;
// set the timestamp output buffer for top/bottom/diff query
2022-03-29 07:24:25 +00:00
// int32_t fid = pCtx[i].functionId;
// if (fid == FUNCTION_TOP || fid == FUNCTION_BOTTOM || fid == FUNCTION_DIFF || fid == FUNCTION_DERIVATIVE) {
2022-04-06 02:09:14 +00:00
// if (i > 0) pCtx[i].pTsOutput = pCtx[i-1].pOutput;
2022-03-29 07:24:25 +00:00
// }
2022-01-20 05:52:46 +00:00
}
initCtxOutputBuffer ( pCtx , pDataBlock - > info . numOfCols ) ;
}
2022-03-29 07:24:25 +00:00
void updateOutputBuf ( SOptrBasicInfo * pBInfo , int32_t * bufCapacity , int32_t numOfInputRows ) {
2021-11-02 05:37:31 +00:00
SSDataBlock * pDataBlock = pBInfo - > pRes ;
2022-03-29 07:24:25 +00:00
int32_t newSize = pDataBlock - > info . rows + numOfInputRows + 5 ; // extra output buffer
2021-11-02 05:37:31 +00:00
if ( ( * bufCapacity ) < newSize ) {
2022-03-29 07:24:25 +00:00
for ( int32_t i = 0 ; i < pDataBlock - > info . numOfCols ; + + i ) {
SColumnInfoData * pColInfo = taosArrayGet ( pDataBlock - > pDataBlock , i ) ;
2021-11-02 05:37:31 +00:00
2022-03-25 16:29:53 +00:00
char * p = taosMemoryRealloc ( pColInfo - > pData , newSize * pColInfo - > info . bytes ) ;
2021-11-02 05:37:31 +00:00
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 ) {
2022-03-29 07:24:25 +00:00
SColumnInfoData * pColInfo = taosArrayGet ( pDataBlock - > pDataBlock , i ) ;
2021-11-02 05:37:31 +00:00
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 ;
2022-03-29 07:24:25 +00:00
if ( functionId = = FUNCTION_TOP | | functionId = = FUNCTION_BOTTOM | | functionId = = FUNCTION_DIFF | |
functionId = = FUNCTION_DERIVATIVE ) {
2022-04-23 10:29:45 +00:00
// if (i > 0) pBInfo->pCtx[i].pTsOutput = pBInfo->pCtx[i - 1].pOutput;
2021-11-02 05:37:31 +00:00
}
}
}
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 ;
2022-03-29 07:24:25 +00:00
char * src = NULL ;
2021-11-02 05:37:31 +00:00
for ( int32_t i = 0 ; i < numOfOutput ; i + + ) {
int32_t functionId = pCtx [ i ] . functionId ;
if ( functionId = = FUNCTION_DIFF | | functionId = = FUNCTION_DERIVATIVE ) {
needCopyTs = true ;
2022-03-29 07:24:25 +00:00
if ( i > 0 & & pCtx [ i - 1 ] . functionId = = FUNCTION_TS_DUMMY ) {
SColumnInfoData * pColRes = taosArrayGet ( pRes - > pDataBlock , i - 1 ) ; // find ts data
2021-11-02 05:37:31 +00:00
src = pColRes - > pData ;
}
2022-03-29 07:24:25 +00:00
} else if ( functionId = = FUNCTION_TS_DUMMY ) {
2021-11-02 05:37:31 +00:00
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 ;
2022-03-29 07:24:25 +00:00
if ( functionId = = FUNCTION_TS_DUMMY ) {
2021-11-02 05:37:31 +00:00
SColumnInfoData * pColRes = taosArrayGet ( pRes - > pDataBlock , i ) ;
memcpy ( pColRes - > pData , src , pColRes - > info . bytes * pRes - > info . rows ) ;
}
}
}
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 ] ) ;
2022-04-23 10:29:45 +00:00
if ( isRowEntryInitialized ( pResInfo ) | | fmIsPseudoColumnFunc ( pCtx [ j ] . functionId ) | | pCtx [ j ] . functionId = = - 1 | |
fmIsScalarFunc ( pCtx [ j ] . functionId ) ) {
2021-11-02 05:37:31 +00:00
continue ;
}
2022-03-09 02:22:53 +00:00
pCtx [ j ] . fpSet . init ( & pCtx [ j ] , pCtx [ j ] . resultInfo ) ;
2021-11-02 05:37:31 +00:00
}
}
2022-03-29 07:24:25 +00:00
void setTaskStatus ( SExecTaskInfo * pTaskInfo , int8_t status ) {
2022-01-10 11:48:21 +00:00
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-04-24 12:48:42 +00:00
// todo merged with the build group result.
2022-03-29 07:24:25 +00:00
void finalizeMultiTupleQueryResult ( SqlFunctionCtx * pCtx , int32_t numOfOutput , SDiskbasedBuf * pBuf ,
SResultRowInfo * pResultRowInfo , int32_t * rowCellInfoOffset ) {
2022-03-15 06:37:26 +00:00
for ( int32_t i = 0 ; i < pResultRowInfo - > size ; + + i ) {
SResultRowPosition * pPos = & pResultRowInfo - > pPosition [ i ] ;
2022-03-29 07:24:25 +00:00
SFilePage * bufPage = getBufPage ( pBuf , pPos - > pageId ) ;
2022-03-15 06:37:26 +00:00
SResultRow * pRow = ( SResultRow * ) ( ( char * ) bufPage + pPos - > offset ) ;
2022-03-31 08:10:32 +00:00
// TODO ignore the close status anyway.
2022-04-23 10:29:45 +00:00
// if (!isResultRowClosed(pRow)) {
// continue;
// }
2022-03-15 06:37:26 +00:00
2021-11-02 05:37:31 +00:00
for ( int32_t j = 0 ; j < numOfOutput ; + + j ) {
2022-03-15 06:37:26 +00:00
pCtx [ j ] . resultInfo = getResultCell ( pRow , j , rowCellInfoOffset ) ;
2022-03-15 08:51:50 +00:00
struct SResultRowEntryInfo * pResInfo = pCtx [ j ] . resultInfo ;
2022-04-16 11:10:21 +00:00
if ( ! isRowEntryInitialized ( pResInfo ) ) {
2022-03-15 06:37:26 +00:00
continue ;
}
2022-03-31 08:10:32 +00:00
if ( pCtx [ j ] . fpSet . process ) { // TODO set the dummy function, to avoid the check for null ptr.
2022-04-23 10:29:45 +00:00
// pCtx[j].fpSet.finalize(&pCtx[j]);
2022-03-22 08:03:42 +00:00
}
2022-03-15 06:37:26 +00:00
if ( pRow - > numOfRows < pResInfo - > numOfRes ) {
pRow - > numOfRows = pResInfo - > numOfRes ;
}
2021-11-02 05:37:31 +00:00
}
2022-03-15 06:37:26 +00:00
releaseBufPage ( pBuf , bufPage ) ;
}
2021-11-02 05:37:31 +00:00
}
2022-04-24 12:48:42 +00:00
// todo merged with the build group result.
2022-03-29 12:07:38 +00:00
void finalizeUpdatedResult ( SqlFunctionCtx * pCtx , int32_t numOfOutput , SDiskbasedBuf * pBuf , SArray * pUpdateList ,
int32_t * rowCellInfoOffset ) {
size_t num = taosArrayGetSize ( pUpdateList ) ;
for ( int32_t i = 0 ; i < num ; + + i ) {
2022-04-24 12:48:42 +00:00
SResKeyPos * pPos = taosArrayGetP ( pUpdateList , i ) ;
2022-03-29 12:07:38 +00:00
2022-04-24 12:48:42 +00:00
SFilePage * bufPage = getBufPage ( pBuf , pPos - > pos . pageId ) ;
SResultRow * pRow = ( SResultRow * ) ( ( char * ) bufPage + pPos - > pos . offset ) ;
//
2022-03-29 12:07:38 +00:00
for ( int32_t j = 0 ; j < numOfOutput ; + + j ) {
pCtx [ j ] . resultInfo = getResultCell ( pRow , j , rowCellInfoOffset ) ;
2022-04-24 12:48:42 +00:00
//
2022-03-29 12:07:38 +00:00
struct SResultRowEntryInfo * pResInfo = pCtx [ j ] . resultInfo ;
2022-04-24 12:48:42 +00:00
// if (isRowEntryCompleted(pResInfo) && isRowEntryInitialized(pResInfo)) {
// continue;
// }
//
// if (pCtx[j].fpSet.process) { // TODO set the dummy function.
//// pCtx[j].fpSet.finalize(&pCtx[j]);
// pResInfo->initialized = true;
// }
//
2022-03-29 12:07:38 +00:00
if ( pRow - > numOfRows < pResInfo - > numOfRes ) {
pRow - > numOfRows = pResInfo - > numOfRes ;
}
}
releaseBufPage ( pBuf , bufPage ) ;
}
}
2022-03-29 07:24:25 +00:00
STableQueryInfo * createTableQueryInfo ( void * buf , bool groupbyColumn , STimeWindow win ) {
STableQueryInfo * pTableQueryInfo = buf ;
2021-11-02 05:37:31 +00:00
pTableQueryInfo - > lastKey = win . skey ;
// set more initial size of interval/groupby query
2022-03-29 07:24:25 +00:00
// if (/*QUERY_IS_INTERVAL_QUERY(pQueryAttr) || */groupbyColumn) {
int32_t initialSize = 128 ;
2022-04-23 10:29:45 +00:00
// int32_t code = initResultRowInfo(&pTableQueryInfo->resInfo, initialSize);
// if (code != TSDB_CODE_SUCCESS) {
// return NULL;
// }
2022-03-29 07:24:25 +00:00
// } else { // in other aggregate query, do not initialize the windowResInfo
// }
2021-11-02 05:37:31 +00:00
return pTableQueryInfo ;
}
2022-03-29 07:24:25 +00:00
void destroyTableQueryInfoImpl ( STableQueryInfo * pTableQueryInfo ) {
2021-11-02 05:37:31 +00:00
if ( pTableQueryInfo = = NULL ) {
return ;
}
2022-03-29 07:24:25 +00:00
// taosVariantDestroy(&pTableQueryInfo->tag);
2022-04-23 10:29:45 +00:00
// cleanupResultRowInfo(&pTableQueryInfo->resInfo);
2021-11-02 05:37:31 +00:00
}
2022-04-23 10:29:45 +00:00
void setResultRowOutputBufInitCtx_rv ( SResultRow * pResult , SqlFunctionCtx * pCtx , int32_t numOfOutput ,
int32_t * rowCellInfoOffset ) {
2022-02-14 02:58:58 +00:00
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 ) ) {
continue ;
}
2022-03-30 05:41:15 +00:00
if ( fmIsWindowPseudoColumnFunc ( pCtx [ i ] . functionId ) ) {
continue ;
}
2022-04-18 03:01:07 +00:00
if ( ! pResInfo - > initialized ) {
if ( pCtx [ i ] . functionId ! = - 1 ) {
pCtx [ i ] . fpSet . init ( & pCtx [ i ] , pResInfo ) ;
} else {
pResInfo - > initialized = true ;
}
2022-02-14 02:58:58 +00:00
}
}
}
2022-04-06 09:59:08 +00:00
void doFilter ( const SNode * pFilterNode , SSDataBlock * pBlock ) {
if ( pFilterNode = = NULL ) {
return ;
}
SFilterInfo * filter = NULL ;
2022-04-06 15:00:32 +00:00
2022-04-07 05:57:47 +00:00
// todo move to the initialization function
2022-04-06 15:00:32 +00:00
int32_t code = filterInitFromNode ( ( SNode * ) pFilterNode , & filter , 0 ) ;
2022-04-06 09:59:08 +00:00
SFilterColumnParam param1 = { . numOfCols = pBlock - > info . numOfCols , . pDataBlock = pBlock - > pDataBlock } ;
code = filterSetDataFromSlotId ( filter , & param1 ) ;
int8_t * rowRes = NULL ;
bool keep = filterExecute ( filter , pBlock , & rowRes , NULL , param1 . numOfCols ) ;
2022-04-09 05:36:36 +00:00
filterFreeInfo ( filter ) ;
2022-04-06 09:59:08 +00:00
2022-04-14 07:33:37 +00:00
SSDataBlock * px = createOneDataBlock ( pBlock , false ) ;
2022-04-06 09:59:08 +00:00
blockDataEnsureCapacity ( px , pBlock - > info . rows ) ;
2022-04-06 15:00:32 +00:00
// todo extract method
2022-04-06 09:59:08 +00:00
int32_t numOfRow = 0 ;
for ( int32_t i = 0 ; i < pBlock - > info . numOfCols ; + + i ) {
SColumnInfoData * pDst = taosArrayGet ( px - > pDataBlock , i ) ;
SColumnInfoData * pSrc = taosArrayGet ( pBlock - > pDataBlock , i ) ;
2022-04-09 05:36:36 +00:00
if ( keep ) {
colDataAssign ( pDst , pSrc , pBlock - > info . rows ) ;
numOfRow = pBlock - > info . rows ;
} else if ( NULL ! = rowRes ) {
numOfRow = 0 ;
for ( int32_t j = 0 ; j < pBlock - > info . rows ; + + j ) {
if ( rowRes [ j ] = = 0 ) {
continue ;
}
2022-04-06 09:59:08 +00:00
2022-04-09 05:36:36 +00:00
if ( colDataIsNull_s ( pSrc , j ) ) {
colDataAppendNULL ( pDst , numOfRow ) ;
} else {
colDataAppend ( pDst , numOfRow , colDataGetData ( pSrc , j ) , false ) ;
}
numOfRow + = 1 ;
2022-04-06 15:00:32 +00:00
}
2022-04-09 05:36:36 +00:00
} else {
numOfRow = 0 ;
2022-04-06 09:59:08 +00:00
}
* pSrc = * pDst ;
}
pBlock - > info . rows = numOfRow ;
2022-04-09 15:28:16 +00:00
blockDataUpdateTsWindow ( pBlock ) ;
2022-04-06 09:59:08 +00:00
}
2022-04-23 10:29:45 +00:00
void doSetTableGroupOutputBuf ( SAggOperatorInfo * pAggInfo , int32_t numOfOutput , uint64_t groupId ,
SExecTaskInfo * pTaskInfo ) {
2021-11-02 05:37:31 +00:00
// for simple group by query without interval, all the tables belong to one group result.
int64_t uid = 0 ;
2022-02-14 02:58:58 +00:00
SResultRowInfo * pResultRowInfo = & pAggInfo - > binfo . resultRowInfo ;
SqlFunctionCtx * pCtx = pAggInfo - > binfo . pCtx ;
2022-03-29 07:24:25 +00:00
int32_t * rowCellInfoOffset = pAggInfo - > binfo . rowCellInfoOffset ;
2022-02-14 02:58:58 +00:00
2021-11-02 05:37:31 +00:00
SResultRow * pResultRow =
2022-04-25 08:44:48 +00:00
doSetResultOutBufByKey ( pAggInfo - > aggSup . pResultBuf , pResultRowInfo , uid , ( char * ) & groupId , sizeof ( groupId ) ,
2022-04-16 11:10:21 +00:00
true , groupId , pTaskInfo , false , & pAggInfo - > aggSup ) ;
2022-03-29 07:24:25 +00:00
assert ( pResultRow ! = NULL ) ;
2021-11-02 05:37:31 +00:00
/*
* 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 ) {
2022-04-23 10:29:45 +00:00
int32_t ret =
addNewWindowResultBuf ( pResultRow , pAggInfo - > aggSup . pResultBuf , groupId , pAggInfo - > binfo . pRes - > info . rowSize ) ;
2021-11-02 05:37:31 +00:00
if ( ret ! = TSDB_CODE_SUCCESS ) {
return ;
}
}
2022-04-01 02:44:34 +00:00
setResultRowOutputBufInitCtx_rv ( pResultRow , pCtx , numOfOutput , rowCellInfoOffset ) ;
2021-11-02 05:37:31 +00:00
}
2022-04-16 11:10:21 +00:00
void setExecutionContext ( int32_t numOfOutput , uint64_t groupId , SExecTaskInfo * pTaskInfo , SAggOperatorInfo * pAggInfo ) {
if ( pAggInfo - > groupId ! = INT32_MIN & & pAggInfo - > groupId = = groupId ) {
2021-11-02 05:37:31 +00:00
return ;
}
2022-04-16 11:10:21 +00:00
doSetTableGroupOutputBuf ( pAggInfo , numOfOutput , groupId , pTaskInfo ) ;
2021-11-02 05:37:31 +00:00
// record the current active group id
2022-04-16 11:10:21 +00:00
pAggInfo - > groupId = groupId ;
2021-11-02 05:37:31 +00:00
}
/*
* There are two cases to handle :
*
2022-03-29 07:24:25 +00:00
* 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 .
2021-11-02 05:37:31 +00:00
* 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-04-15 15:02:26 +00:00
void setIntervalQueryRange ( STableQueryInfo * pTableQueryInfo , TSKEY key , STimeWindow * pQRange ) {
2022-04-23 10:29:45 +00:00
// SResultRowInfo* pResultRowInfo = &pTableQueryInfo->resInfo;
// if (pResultRowInfo->curPos != -1) {
// return;
// }
2021-11-02 05:37:31 +00:00
2022-04-23 10:29:45 +00:00
// pTableQueryInfo->win.skey = key;
// STimeWindow win = {.skey = key, .ekey = pQRange->ekey};
2021-11-02 05:37:31 +00:00
/**
* 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 .
*/
2022-04-23 10:29:45 +00:00
// STimeWindow w = TSWINDOW_INITIALIZER;
//
// TSKEY sk = TMIN(win.skey, win.ekey);
// TSKEY ek = TMAX(win.skey, win.ekey);
2022-03-29 07:24:25 +00:00
// getAlignQueryTimeWindow(pQueryAttr, win.skey, sk, ek, &w);
2021-11-02 05:37:31 +00:00
2022-03-29 07:24:25 +00:00
// if (pResultRowInfo->prevSKey == TSKEY_INITIAL_VAL) {
// if (!QUERY_IS_ASC_QUERY(pQueryAttr)) {
// assert(win.ekey == pQueryAttr->window.ekey);
// }
//
// pResultRowInfo->prevSKey = w.skey;
// }
2021-11-02 05:37:31 +00:00
2022-03-29 07:24:25 +00:00
// pTableQueryInfo->lastKey = pTableQueryInfo->win.skey;
2021-11-02 05:37:31 +00:00
}
/**
* 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-04-22 07:07:20 +00:00
int32_t doCopyToSDataBlock ( SSDataBlock * pBlock , SExprInfo * pExprInfo , SDiskbasedBuf * pBuf , SGroupResInfo * pGroupResInfo ,
2022-04-24 12:48:42 +00:00
int32_t orderType , int32_t * rowCellOffset , SqlFunctionCtx * pCtx ) {
2021-11-02 05:37:31 +00:00
int32_t numOfRows = getNumOfTotalRes ( pGroupResInfo ) ;
2022-03-29 07:24:25 +00:00
int32_t numOfResult = pBlock - > info . rows ; // there are already exists result rows
2021-11-02 05:37:31 +00:00
int32_t start = 0 ;
int32_t step = - 1 ;
2022-03-29 07:24:25 +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 ) {
2022-04-24 12:48:42 +00:00
SResKeyPos * pPos = taosArrayGetP ( pGroupResInfo - > pRows , i ) ;
SFilePage * page = getBufPage ( pBuf , pPos - > pos . pageId ) ;
2022-03-15 06:37:26 +00:00
2022-04-24 12:48:42 +00:00
SResultRow * pRow = ( SResultRow * ) ( ( char * ) page + pPos - > pos . offset ) ;
2021-11-02 05:37:31 +00:00
if ( pRow - > numOfRows = = 0 ) {
pGroupResInfo - > index + = 1 ;
continue ;
}
2022-03-15 06:37:26 +00:00
// TODO copy multiple rows?
2021-11-02 05:37:31 +00:00
int32_t numOfRowsToCopy = pRow - > numOfRows ;
2022-04-22 07:07:20 +00:00
if ( numOfResult + numOfRowsToCopy > = pBlock - > info . capacity ) {
2021-11-02 05:37:31 +00:00
break ;
}
pGroupResInfo - > index + = 1 ;
for ( int32_t j = 0 ; j < pBlock - > info . numOfCols ; + + j ) {
2022-04-12 09:55:17 +00:00
int32_t slotId = pExprInfo [ j ] . base . resSchema . slotId ;
2022-04-22 07:07:20 +00:00
pCtx [ j ] . resultInfo = getResultCell ( pRow , j , rowCellOffset ) ;
if ( pCtx [ j ] . fpSet . process ) {
2022-04-22 14:43:07 +00:00
pCtx [ j ] . fpSet . finalize ( & pCtx [ j ] , pBlock ) ;
2022-04-22 07:07:20 +00:00
} else {
SColumnInfoData * pColInfoData = taosArrayGet ( pBlock - > pDataBlock , slotId ) ;
2021-11-02 05:37:31 +00:00
2022-04-22 07:07:20 +00:00
char * in = GET_ROWCELL_INTERBUF ( pCtx [ j ] . resultInfo ) ;
colDataAppend ( pColInfoData , pBlock - > info . rows , in , pCtx [ j ] . resultInfo - > isNullRes ) ;
}
2021-11-02 05:37:31 +00:00
}
2022-03-15 06:37:26 +00:00
releaseBufPage ( pBuf , page ) ;
2022-04-22 07:07:20 +00:00
pBlock - > info . rows + = pRow - > numOfRows ;
if ( pBlock - > info . rows > = pBlock - > info . capacity ) { // output buffer is full
2021-11-02 05:37:31 +00:00
break ;
}
}
2022-03-29 07:24:25 +00:00
// qDebug("QInfo:0x%"PRIx64" copy data to query buf completed", GET_TASKID(pRuntimeEnv));
2022-04-20 06:59:06 +00:00
blockDataUpdateTsWindow ( pBlock ) ;
2021-11-02 05:37:31 +00:00
return 0 ;
}
2022-04-23 10:29:45 +00:00
void doBuildResultDatablock ( SSDataBlock * pBlock , SGroupResInfo * pGroupResInfo , SExprInfo * pExprInfo ,
SDiskbasedBuf * pBuf , int32_t * rowCellOffset , SqlFunctionCtx * pCtx ) {
2021-11-02 05:37:31 +00:00
assert ( pGroupResInfo - > currentGroup < = pGroupResInfo - > totalGroup ) ;
2022-03-17 05:11:06 +00:00
blockDataCleanup ( pBlock ) ;
2021-11-02 05:37:31 +00:00
if ( ! hasRemainDataInCurrentGroup ( pGroupResInfo ) ) {
return ;
}
2022-03-30 05:41:15 +00:00
int32_t orderType = TSDB_ORDER_ASC ;
2022-04-22 07:07:20 +00:00
doCopyToSDataBlock ( pBlock , pExprInfo , pBuf , pGroupResInfo , orderType , rowCellOffset , pCtx ) ;
2021-11-02 05:37:31 +00:00
2022-02-14 06:39:42 +00:00
// add condition (pBlock->info.rows >= 1) just to runtime happy
blockDataUpdateTsWindow ( pBlock ) ;
2021-11-02 05:37:31 +00:00
}
2022-03-29 07:24:25 +00:00
static void updateNumOfRowsInResultRows ( SqlFunctionCtx * pCtx , int32_t numOfOutput , SResultRowInfo * pResultRowInfo ,
int32_t * rowCellInfoOffset ) {
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.
2022-03-29 07:24:25 +00:00
// if (QUERY_IS_INTERVAL_QUERY(pQueryAttr)) {
// return;
// }
2022-03-31 08:10:32 +00:00
#if 0
2021-11-02 05:37:31 +00:00
for ( int32_t i = 0 ; i < pResultRowInfo - > size ; + + i ) {
2022-03-29 07:24:25 +00:00
SResultRow * pResult = pResultRowInfo - > pResult [ i ] ;
2021-11-02 05:37:31 +00:00
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 ;
}
2022-02-14 02:58:58 +00:00
SResultRowEntryInfo * pCell = getResultCell ( pResult , j , rowCellInfoOffset ) ;
pResult - > numOfRows = ( uint16_t ) ( TMAX ( pResult - > numOfRows , pCell - > numOfRes ) ) ;
2021-11-02 05:37:31 +00:00
}
}
2022-03-31 08:10:32 +00:00
# endif
2021-11-02 05:37:31 +00:00
}
2022-03-29 07:24:25 +00:00
static int32_t compressQueryColData ( SColumnInfoData * pColRes , int32_t numOfRows , char * data , int8_t compressed ) {
2021-11-02 05:37:31 +00:00
int32_t colSize = pColRes - > info . bytes * numOfRows ;
return ( * ( tDataTypes [ pColRes - > info . type ] . compFunc ) ) ( pColRes - > pData , colSize , numOfRows , data ,
2022-03-29 07:24:25 +00:00
colSize + COMP_OVERFLOW_BYTES , compressed , NULL , 0 ) ;
2021-11-02 05:37:31 +00:00
}
2022-03-29 07:24:25 +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);
// }
2021-11-02 05:37:31 +00:00
int32_t numOfRows = ( int32_t ) taosFillResultDataBlock ( pFillInfo , p , capacity - pOutput - > info . rows ) ;
pOutput - > info . rows + = numOfRows ;
return pOutput - > info . rows ;
}
2022-04-18 02:46:07 +00:00
void publishOperatorProfEvent ( SOperatorInfo * pOperator , EQueryProfEventType eventType ) {
2021-11-02 05:37:31 +00:00
SQueryProfEvent event = { 0 } ;
2022-03-29 07:24:25 +00:00
event . eventType = eventType ;
event . eventTime = taosGetTimestampUs ( ) ;
2022-04-18 02:46:07 +00:00
event . operatorType = pOperator - > operatorType ;
2022-04-23 10:29:45 +00:00
// if (pQInfo->summary.queryProfEvents) {
// taosArrayPush(pQInfo->summary.queryProfEvents, &event);
// }
2021-11-02 05:37:31 +00:00
}
2022-03-29 07:24:25 +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
}
}
2022-03-29 07:24:25 +00:00
typedef struct {
2021-11-02 05:37:31 +00:00
uint8_t operatorType ;
int64_t beginTime ;
int64_t endTime ;
int64_t selfTime ;
int64_t descendantsTime ;
} SOperatorStackItem ;
2022-03-29 07:24:25 +00:00
static void doOperatorExecProfOnce ( SOperatorStackItem * item , SQueryProfEvent * event , SArray * opStack ,
SHashObj * profResults ) {
2021-11-02 05:37:31 +00:00
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 ;
}
2022-03-29 07:24:25 +00:00
uint8_t operatorType = item - > operatorType ;
2021-11-02 05:37:31 +00:00
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 ;
2022-03-29 07:24:25 +00:00
taosHashPut ( profResults , & ( operatorType ) , sizeof ( operatorType ) , & opResult , sizeof ( opResult ) ) ;
2021-11-02 05:37:31 +00:00
}
}
2022-04-14 06:34:02 +00:00
void calculateOperatorProfResults ( void ) {
2022-04-23 10:29:45 +00:00
// 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;
// }
2021-11-02 05:37:31 +00:00
SArray * opStack = taosArrayInit ( 32 , sizeof ( SOperatorStackItem ) ) ;
if ( opStack = = NULL ) {
return ;
}
2022-04-14 06:34:02 +00:00
#if 0
2022-03-29 07:24:25 +00:00
size_t size = taosArrayGetSize ( pQInfo - > summary . queryProfEvents ) ;
2021-11-02 05:37:31 +00:00
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 ) ;
}
}
}
2022-04-14 06:34:02 +00:00
# endif
2021-11-02 05:37:31 +00:00
taosArrayDestroy ( opStack ) ;
}
2022-03-29 07:24:25 +00:00
void queryCostStatis ( SExecTaskInfo * pTaskInfo ) {
STaskCostInfo * pSummary = & pTaskInfo - > cost ;
2021-11-02 05:37:31 +00:00
2022-03-29 07:24:25 +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-03-29 07:24:25 +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);
qDebug ( " %s :cost summary: elapsed time:% " PRId64 " us, first merge:% " PRId64
" us, total blocks:%d, "
" load block statis:%d, load data block:%d, total rows:% " PRId64 " , check rows:% " PRId64 ,
GET_TASKID ( pTaskInfo ) , pSummary - > elapsedTime , pSummary - > firstStageMergeTime , pSummary - > totalBlocks ,
pSummary - > loadBlockStatis , pSummary - > loadBlocks , pSummary - > totalRows , pSummary - > totalCheckedRows ) ;
//
// 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);
2021-11-02 05:37:31 +00:00
if ( pSummary - > operatorProfResults ) {
SOperatorProfResult * opRes = taosHashIterate ( pSummary - > operatorProfResults , NULL ) ;
while ( opRes ! = NULL ) {
2022-03-29 07:24:25 +00:00
// qDebug("QInfo:0x%" PRIx64 " :cost summary: operator : %d, exec times: %" PRId64 ", self time: %" PRId64,
// pQInfo->qId, opRes->operatorType, opRes->sumRunTimes, opRes->sumSelfTime);
2021-11-02 05:37:31 +00:00
opRes = taosHashIterate ( pSummary - > operatorProfResults , opRes ) ;
}
}
}
2022-03-29 07:24:25 +00:00
// static void updateOffsetVal(STaskRuntimeEnv *pRuntimeEnv, SDataBlockInfo *pBlockInfo) {
// STaskAttr *pQueryAttr = pRuntimeEnv->pQueryAttr;
// STableQueryInfo* pTableQueryInfo = pRuntimeEnv->current;
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQueryAttr->order.order);
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// 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;
// }
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// if (QUERY_IS_ASC_QUERY(pQueryAttr)) {
// pQueryAttr->pos = (int32_t)pQueryAttr->limit.offset;
// } else {
// pQueryAttr->pos = pBlockInfo->rows - (int32_t)pQueryAttr->limit.offset - 1;
// }
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// assert(pQueryAttr->pos >= 0 && pQueryAttr->pos <= pBlockInfo->rows - 1);
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// SArray * pDataBlock = tsdbRetrieveDataBlock(pRuntimeEnv->pTsdbReadHandle, NULL);
// SColumnInfoData *pColInfoData = taosArrayGet(pDataBlock, 0);
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// // update the pQueryAttr->limit.offset value, and pQueryAttr->pos value
// TSKEY *keys = (TSKEY *) pColInfoData->pData;
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// // update the offset value
// pTableQueryInfo->lastKey = keys[pQueryAttr->pos];
// pQueryAttr->limit.offset = 0;
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// int32_t numOfRes = tableApplyFunctionsOnBlock(pRuntimeEnv, pBlockInfo, NULL, binarySearchForKey, pDataBlock);
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// //qDebug("QInfo:0x%"PRIx64" check data block, brange:%" PRId64 "-%" PRId64 ", numBlocksOfStep:%d, numOfRes:%d,
// lastKey:%"PRId64, GET_TASKID(pRuntimeEnv),
// pBlockInfo->window.skey, pBlockInfo->window.ekey, pBlockInfo->rows, numOfRes, pQuery->current->lastKey);
// }
2021-11-02 05:37:31 +00:00
2022-03-29 07:24:25 +00:00
// void skipBlocks(STaskRuntimeEnv *pRuntimeEnv) {
// STaskAttr *pQueryAttr = pRuntimeEnv->pQueryAttr;
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// if (pQueryAttr->limit.offset <= 0 || pQueryAttr->numOfFilterCols > 0) {
// return;
// }
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// pQueryAttr->pos = 0;
// int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQueryAttr->order.order);
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// STableQueryInfo* pTableQueryInfo = pRuntimeEnv->current;
// TsdbQueryHandleT pTsdbReadHandle = pRuntimeEnv->pTsdbReadHandle;
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// SDataBlockInfo blockInfo = SDATA_BLOCK_INITIALIZER;
// while (tsdbNextDataBlock(pTsdbReadHandle)) {
// if (isTaskKilled(pRuntimeEnv->qinfo)) {
// longjmp(pRuntimeEnv->env, TSDB_CODE_TSC_QUERY_CANCELLED);
// }
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// tsdbRetrieveDataBlockInfo(pTsdbReadHandle, &blockInfo);
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +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;
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// //qDebug("QInfo:0x%"PRIx64" skip rows:%d, offset:%" PRId64, GET_TASKID(pRuntimeEnv), blockInfo.rows,
// pQuery->limit.offset);
// } else { // find the appropriated start position in current block
// updateOffsetVal(pRuntimeEnv, &blockInfo);
// break;
// }
// }
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// if (terrno != TSDB_CODE_SUCCESS) {
// longjmp(pRuntimeEnv->env, terrno);
// }
// }
// static TSKEY doSkipIntervalProcess(STaskRuntimeEnv* pRuntimeEnv, STimeWindow* win, SDataBlockInfo* pBlockInfo,
// STableQueryInfo* pTableQueryInfo) {
// STaskAttr *pQueryAttr = pRuntimeEnv->pQueryAttr;
// SResultRowInfo *pWindowResInfo = &pRuntimeEnv->resultRowInfo;
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// assert(pQueryAttr->limit.offset == 0);
// STimeWindow tw = *win;
// getNextTimeWindow(pQueryAttr, &tw);
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// if ((tw.skey <= pBlockInfo->window.ekey && QUERY_IS_ASC_QUERY(pQueryAttr)) ||
// (tw.ekey >= pBlockInfo->window.skey && !QUERY_IS_ASC_QUERY(pQueryAttr))) {
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// // load the data block and check data remaining in current data block
// // TODO optimize performance
// SArray * pDataBlock = tsdbRetrieveDataBlock(pRuntimeEnv->pTsdbReadHandle, NULL);
// SColumnInfoData *pColInfoData = taosArrayGet(pDataBlock, 0);
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// tw = *win;
// int32_t startPos =
// getNextQualifiedWindow(pQueryAttr, &tw, pBlockInfo, pColInfoData->pData, binarySearchForKey, -1);
// assert(startPos >= 0);
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// // set the abort info
// pQueryAttr->pos = startPos;
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// // reset the query start timestamp
// pTableQueryInfo->win.skey = ((TSKEY *)pColInfoData->pData)[startPos];
// pQueryAttr->window.skey = pTableQueryInfo->win.skey;
// TSKEY key = pTableQueryInfo->win.skey;
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// pWindowResInfo->prevSKey = tw.skey;
// int32_t index = pRuntimeEnv->resultRowInfo.curIndex;
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// int32_t numOfRes = tableApplyFunctionsOnBlock(pRuntimeEnv, pBlockInfo, NULL, binarySearchForKey, pDataBlock);
// pRuntimeEnv->resultRowInfo.curIndex = index; // restore the window index
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// //qDebug("QInfo:0x%"PRIx64" check data block, brange:%" PRId64 "-%" PRId64 ", numOfRows:%d, numOfRes:%d,
// lastKey:%" PRId64,
// GET_TASKID(pRuntimeEnv), pBlockInfo->window.skey, pBlockInfo->window.ekey, pBlockInfo->rows, numOfRes,
// pQueryAttr->current->lastKey);
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// return key;
// } else { // do nothing
// pQueryAttr->window.skey = tw.skey;
// pWindowResInfo->prevSKey = tw.skey;
// pTableQueryInfo->lastKey = tw.skey;
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// return tw.skey;
// }
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// return true;
// }
// static bool skipTimeInterval(STaskRuntimeEnv *pRuntimeEnv, TSKEY* start) {
// STaskAttr *pQueryAttr = pRuntimeEnv->pQueryAttr;
// if (QUERY_IS_ASC_QUERY(pQueryAttr)) {
// assert(*start <= pRuntimeEnv->current->lastKey);
// } else {
// assert(*start >= pRuntimeEnv->current->lastKey);
// }
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// // 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;
// }
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// /*
// * 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);
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// STimeWindow w = TSWINDOW_INITIALIZER;
// bool ascQuery = QUERY_IS_ASC_QUERY(pQueryAttr);
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// SResultRowInfo *pWindowResInfo = &pRuntimeEnv->resultRowInfo;
// STableQueryInfo *pTableQueryInfo = pRuntimeEnv->current;
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// SDataBlockInfo blockInfo = SDATA_BLOCK_INITIALIZER;
// while (tsdbNextDataBlock(pRuntimeEnv->pTsdbReadHandle)) {
// tsdbRetrieveDataBlockInfo(pRuntimeEnv->pTsdbReadHandle, &blockInfo);
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +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;
// }
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// // the first time window
// STimeWindow win = getActiveTimeWindow(pWindowResInfo, pWindowResInfo->prevSKey, pQueryAttr);
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// while (pQueryAttr->limit.offset > 0) {
// STimeWindow tw = win;
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// if ((win.ekey <= blockInfo.window.ekey && ascQuery) || (win.ekey >= blockInfo.window.skey && !ascQuery)) {
// pQueryAttr->limit.offset -= 1;
// pWindowResInfo->prevSKey = win.skey;
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// // 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;
// }
// }
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// if (pQueryAttr->limit.offset == 0) {
// *start = doSkipIntervalProcess(pRuntimeEnv, &win, &blockInfo, pTableQueryInfo);
// return true;
// }
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// // current window does not ended in current data block, try next data block
// getNextTimeWindow(pQueryAttr, &tw);
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// /*
// * 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)) {
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// SArray *pDataBlock = tsdbRetrieveDataBlock(pRuntimeEnv->pTsdbReadHandle, NULL);
// SColumnInfoData *pColInfoData = taosArrayGet(pDataBlock, 0);
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// if ((win.ekey > blockInfo.window.ekey && ascQuery) || (win.ekey < blockInfo.window.skey && !ascQuery)) {
// pQueryAttr->limit.offset -= 1;
// }
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// 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);
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// // 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.
// }
// }
// }
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// // check for error
// if (terrno != TSDB_CODE_SUCCESS) {
// longjmp(pRuntimeEnv->env, terrno);
// }
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// return true;
// }
2021-11-02 05:37:31 +00:00
2022-02-22 05:12:03 +00:00
int32_t appendDownstream ( SOperatorInfo * p , SOperatorInfo * * pDownstream , int32_t num ) {
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-03-25 16:29:53 +00:00
p - > pDownstream = taosMemoryCalloc ( 1 , num * POINTER_BYTES ) ;
2022-02-22 05:12:03 +00:00
if ( p - > pDownstream = = NULL ) {
return TSDB_CODE_OUT_OF_MEMORY ;
}
memcpy ( p - > pDownstream , pDownstream , num * POINTER_BYTES ) ;
p - > numOfDownstream = num ;
return TSDB_CODE_SUCCESS ;
2021-11-02 05:37:31 +00:00
}
static void doDestroyTableQueryInfo ( STableGroupInfo * pTableqinfoGroupInfo ) ;
2022-01-10 11:48:21 +00:00
static void doTableQueryInfoTimeWindowCheck ( SExecTaskInfo * pTaskInfo , STableQueryInfo * pTableQueryInfo , int32_t order ) {
2022-02-13 06:34:00 +00:00
#if 0
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-02-13 06:34:00 +00:00
# endif
2021-11-02 05:37:31 +00:00
}
2022-04-26 05:09:29 +00:00
// SQueryTableDataCond createTsdbQueryCond(STaskAttr* pQueryAttr, STimeWindow* win) {
// SQueryTableDataCond cond = {
2022-03-29 07:24:25 +00:00
// .colList = pQueryAttr->tableCols,
// .order = pQueryAttr->order.order,
// .numOfCols = pQueryAttr->numOfCols,
// .type = BLOCK_LOAD_OFFSET_SEQ_ORDER,
// .loadExternalRows = false,
// };
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// TIME_WINDOW_COPY(cond.twindow, *win);
// return cond;
// }
2021-11-02 05:37:31 +00:00
static STableIdInfo createTableIdInfo ( STableQueryInfo * pTableQueryInfo ) {
STableIdInfo tidInfo ;
2022-03-29 07:24:25 +00:00
// STableId* id = TSDB_TABLEID(pTableQueryInfo->pTable);
//
// tidInfo.uid = id->uid;
// tidInfo.tid = id->tid;
// tidInfo.key = pTableQueryInfo->lastKey;
2021-11-02 05:37:31 +00:00
return tidInfo ;
}
2022-03-29 07:24:25 +00:00
// 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;
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// if (pTableQueryInfo->pTable == NULL) {
// return;
// }
2021-11-02 05:37:31 +00:00
//
2022-03-29 07:24:25 +00:00
// 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));
// }
// }
2021-11-02 05:37:31 +00:00
2022-01-16 07:56:48 +00:00
int32_t loadRemoteDataCallback ( void * param , const SDataBuf * pMsg , int32_t code ) {
2022-03-29 07:24:25 +00:00
SSourceDataInfo * pSourceDataInfo = ( SSourceDataInfo * ) param ;
2022-04-01 08:09:00 +00:00
if ( code = = TSDB_CODE_SUCCESS ) {
pSourceDataInfo - > pRsp = pMsg - > pData ;
2022-01-16 07:56:48 +00:00
2022-04-01 08:09:00 +00:00
SRetrieveTableRsp * pRsp = pSourceDataInfo - > pRsp ;
pRsp - > numOfRows = htonl ( pRsp - > numOfRows ) ;
2022-04-23 10:29:45 +00:00
pRsp - > compLen = htonl ( pRsp - > compLen ) ;
pRsp - > useconds = htobe64 ( pRsp - > useconds ) ;
2022-04-01 08:09:00 +00:00
} else {
pSourceDataInfo - > code = code ;
}
2022-01-19 06:47:53 +00:00
2022-03-05 07:58:28 +00:00
pSourceDataInfo - > status = EX_SOURCE_DATA_READY ;
2022-02-11 06:33:57 +00:00
tsem_post ( & pSourceDataInfo - > pEx - > ready ) ;
2022-04-06 11:50:24 +00:00
return TSDB_CODE_SUCCESS ;
2022-01-19 06:47:53 +00:00
}
static void destroySendMsgInfo ( SMsgSendInfo * pMsgBody ) {
assert ( pMsgBody ! = NULL ) ;
2022-03-25 16:29:53 +00:00
taosMemoryFreeClear ( pMsgBody - > msgInfo . pData ) ;
taosMemoryFreeClear ( pMsgBody ) ;
2022-01-19 06:47:53 +00:00
}
2022-01-26 01:20:48 +00:00
void qProcessFetchRsp ( void * parent , SRpcMsg * pMsg , SEpSet * pEpSet ) {
2022-03-29 07:24:25 +00:00
SMsgSendInfo * pSendInfo = ( SMsgSendInfo * ) pMsg - > ahandle ;
2022-01-19 06:47:53 +00:00
assert ( pMsg - > ahandle ! = NULL ) ;
SDataBuf buf = { . len = pMsg - > contLen , . pData = NULL } ;
if ( pMsg - > contLen > 0 ) {
2022-03-25 16:29:53 +00:00
buf . pData = taosMemoryCalloc ( 1 , pMsg - > contLen ) ;
2022-01-19 06:47:53 +00:00
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-03-29 07:24:25 +00:00
static int32_t doSendFetchDataRequest ( SExchangeInfo * pExchangeInfo , SExecTaskInfo * pTaskInfo , int32_t sourceIndex ) {
2022-02-11 06:33:57 +00:00
size_t totalSources = taosArrayGetSize ( pExchangeInfo - > pSources ) ;
2022-01-16 07:56:48 +00:00
2022-03-25 16:29:53 +00:00
SResFetchReq * pMsg = taosMemoryCalloc ( 1 , sizeof ( SResFetchReq ) ) ;
2022-02-11 06:33:57 +00:00
if ( NULL = = pMsg ) {
pTaskInfo - > code = TSDB_CODE_QRY_OUT_OF_MEMORY ;
return pTaskInfo - > code ;
}
2022-01-16 07:56:48 +00:00
2022-03-29 07:24:25 +00:00
SDownstreamSourceNode * pSource = taosArrayGet ( pExchangeInfo - > pSources , sourceIndex ) ;
SSourceDataInfo * pDataInfo = taosArrayGet ( pExchangeInfo - > pSourceDataInfo , sourceIndex ) ;
2022-01-22 07:42:37 +00:00
2022-03-29 07:24:25 +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 ) ;
2022-02-11 06:33:57 +00:00
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
2022-03-25 16:29:53 +00:00
SMsgSendInfo * pMsgSendInfo = taosMemoryCalloc ( 1 , sizeof ( SMsgSendInfo ) ) ;
2022-02-11 06:33:57 +00:00
if ( NULL = = pMsgSendInfo ) {
2022-03-25 16:29:53 +00:00
taosMemoryFreeClear ( pMsg ) ;
2022-02-11 06:33:57 +00:00
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 ;
2022-03-08 09:22:21 +00:00
int32_t code = asyncSendMsgToServer ( pExchangeInfo - > pTransporter , & pSource - > addr . epSet , & transporterId , pMsgSendInfo ) ;
2022-02-11 06:33:57 +00:00
return TSDB_CODE_SUCCESS ;
}
2022-04-27 08:37:19 +00:00
// NOTE: sources columns are more than the destination SSDatablock columns.
static void relocateColumnData ( SSDataBlock * pBlock , const SArray * pColMatchInfo , SArray * pCols ) {
size_t numOfSrcCols = taosArrayGetSize ( pCols ) ;
ASSERT ( numOfSrcCols > = pBlock - > info . numOfCols ) ;
int32_t i = 0 , j = 0 ;
while ( i < numOfSrcCols & & j < taosArrayGetSize ( pColMatchInfo ) ) {
SColumnInfoData * p = taosArrayGet ( pCols , i ) ;
SColMatchInfo * pmInfo = taosArrayGet ( pColMatchInfo , j ) ;
if ( ! pmInfo - > output ) {
j + + ;
continue ;
}
if ( p - > info . colId = = pmInfo - > colId ) {
taosArraySet ( pBlock - > pDataBlock , pmInfo - > targetSlotId , p ) ;
i + + ;
j + + ;
} else if ( p - > info . colId < pmInfo - > colId ) {
i + + ;
} else {
ASSERT ( 0 ) ;
}
}
}
2022-04-13 11:27:47 +00:00
int32_t setSDataBlockFromFetchRsp ( SSDataBlock * pRes , SLoadRemoteDataInfo * pLoadInfo , int32_t numOfRows , char * pData ,
2022-04-23 10:29:45 +00:00
int32_t compLen , int32_t numOfOutput , int64_t startTs , uint64_t * total ,
SArray * pColList ) {
2022-03-18 03:12:49 +00:00
blockDataEnsureCapacity ( pRes , numOfRows ) ;
2022-02-11 06:33:57 +00:00
2022-03-22 15:29:38 +00:00
if ( pColList = = NULL ) { // data from other sources
2022-04-24 12:48:42 +00:00
int32_t dataLen = * ( int32_t * ) pData ;
pData + = sizeof ( int32_t ) ;
pRes - > info . groupId = * ( uint64_t * ) pData ;
pData + = sizeof ( uint64_t ) ;
2022-03-22 15:29:38 +00:00
int32_t * colLen = ( int32_t * ) pData ;
2022-04-24 12:48:42 +00:00
char * pStart = pData + sizeof ( int32_t ) * numOfOutput ;
2022-03-18 16:13:07 +00:00
for ( int32_t i = 0 ; i < numOfOutput ; + + i ) {
2022-03-22 15:29:38 +00:00
colLen [ i ] = htonl ( colLen [ i ] ) ;
2022-04-27 08:37:19 +00:00
ASSERT ( colLen [ i ] > = 0 ) ;
2022-03-22 15:29:38 +00:00
2022-03-18 16:13:07 +00:00
SColumnInfoData * pColInfoData = taosArrayGet ( pRes - > pDataBlock , i ) ;
2022-03-22 15:29:38 +00:00
if ( IS_VAR_DATA_TYPE ( pColInfoData - > info . type ) ) {
pColInfoData - > varmeta . length = colLen [ i ] ;
pColInfoData - > varmeta . allocLen = colLen [ i ] ;
2022-02-11 06:33:57 +00:00
2022-03-29 07:24:25 +00:00
memcpy ( pColInfoData - > varmeta . offset , pStart , sizeof ( int32_t ) * numOfRows ) ;
pStart + = sizeof ( int32_t ) * numOfRows ;
2022-03-22 15:29:38 +00:00
2022-04-27 08:37:19 +00:00
if ( colLen [ i ] > 0 ) {
pColInfoData - > pData = taosMemoryMalloc ( colLen [ i ] ) ;
}
2022-03-22 15:29:38 +00:00
} else {
memcpy ( pColInfoData - > nullbitmap , pStart , BitmapLen ( numOfRows ) ) ;
pStart + = BitmapLen ( numOfRows ) ;
2022-03-18 16:13:07 +00:00
}
2022-03-22 15:29:38 +00:00
2022-04-27 08:37:19 +00:00
if ( colLen [ i ] > 0 ) {
memcpy ( pColInfoData - > pData , pStart , colLen [ i ] ) ;
}
2022-04-25 06:47:54 +00:00
//TODO setting this flag to true temporarily so aggregate function on stable will
//examine NULL value for non-primary key column
pColInfoData - > hasNull = true ;
2022-03-22 15:29:38 +00:00
pStart + = colLen [ i ] ;
2022-01-22 07:42:37 +00:00
}
2022-03-22 15:29:38 +00:00
} else { // extract data according to pColList
2022-03-18 16:13:07 +00:00
ASSERT ( numOfOutput = = taosArrayGetSize ( pColList ) ) ;
2022-04-13 11:27:47 +00:00
char * pStart = pData ;
int32_t numOfCols = htonl ( * ( int32_t * ) pStart ) ;
pStart + = sizeof ( int32_t ) ;
2022-04-27 08:37:19 +00:00
// todo refactor:extract method
2022-04-13 11:27:47 +00:00
SSysTableSchema * pSchema = ( SSysTableSchema * ) pStart ;
2022-04-23 10:29:45 +00:00
for ( int32_t i = 0 ; i < numOfCols ; + + i ) {
2022-04-13 11:27:47 +00:00
SSysTableSchema * p = ( SSysTableSchema * ) pStart ;
p - > colId = htons ( p - > colId ) ;
p - > bytes = htonl ( p - > bytes ) ;
pStart + = sizeof ( SSysTableSchema ) ;
}
SSDataBlock block = { . pDataBlock = taosArrayInit ( numOfCols , sizeof ( SColumnInfoData ) ) , . info . numOfCols = numOfCols } ;
2022-04-23 10:29:45 +00:00
for ( int32_t i = 0 ; i < numOfCols ; + + i ) {
2022-04-13 11:27:47 +00:00
SColumnInfoData idata = { 0 } ;
idata . info . type = pSchema [ i ] . type ;
idata . info . bytes = pSchema [ i ] . bytes ;
idata . info . colId = pSchema [ i ] . colId ;
taosArrayPush ( block . pDataBlock , & idata ) ;
if ( IS_VAR_DATA_TYPE ( idata . info . type ) ) {
block . info . hasVarCol = true ;
}
}
blockDataEnsureCapacity ( & block , numOfRows ) ;
2022-04-24 12:48:42 +00:00
int32_t dataLen = * ( int32_t * ) pStart ;
uint64_t groupId = * ( uint64_t * ) ( pStart + sizeof ( int32_t ) ) ;
pStart + = sizeof ( int32_t ) + sizeof ( uint64_t ) ;
int32_t * colLen = ( int32_t * ) ( pStart ) ;
2022-04-13 11:27:47 +00:00
pStart + = sizeof ( int32_t ) * numOfCols ;
for ( int32_t i = 0 ; i < numOfCols ; + + i ) {
colLen [ i ] = htonl ( colLen [ i ] ) ;
2022-04-14 03:36:06 +00:00
ASSERT ( colLen [ i ] > = 0 ) ;
2022-04-13 11:27:47 +00:00
SColumnInfoData * pColInfoData = taosArrayGet ( block . pDataBlock , i ) ;
if ( IS_VAR_DATA_TYPE ( pColInfoData - > info . type ) ) {
pColInfoData - > varmeta . length = colLen [ i ] ;
pColInfoData - > varmeta . allocLen = colLen [ i ] ;
memcpy ( pColInfoData - > varmeta . offset , pStart , sizeof ( int32_t ) * numOfRows ) ;
pStart + = sizeof ( int32_t ) * numOfRows ;
pColInfoData - > pData = taosMemoryMalloc ( colLen [ i ] ) ;
} else {
memcpy ( pColInfoData - > nullbitmap , pStart , BitmapLen ( numOfRows ) ) ;
pStart + = BitmapLen ( numOfRows ) ;
}
memcpy ( pColInfoData - > pData , pStart , colLen [ i ] ) ;
pStart + = colLen [ i ] ;
}
2022-03-22 15:29:38 +00:00
// data from mnode
2022-04-27 08:37:19 +00:00
relocateColumnData ( pRes , pColList , block . pDataBlock ) ;
2022-02-11 06:33:57 +00:00
}
2022-01-22 07:42:37 +00:00
2022-03-11 11:29:43 +00:00
pRes - > info . rows = numOfRows ;
2022-04-22 14:40:19 +00:00
blockDataUpdateTsWindow ( pRes ) ;
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-03-11 11:29:43 +00:00
pLoadInfo - > totalRows + = numOfRows ;
pLoadInfo - > totalSize + = compLen ;
2022-01-16 07:56:48 +00:00
2022-03-11 11:29:43 +00:00
if ( total ! = NULL ) {
* total + = numOfRows ;
}
2021-11-02 05:37:31 +00:00
2022-03-11 11:29:43 +00:00
pLoadInfo - > totalElapsed + = el ;
2022-02-11 06:33:57 +00:00
return TSDB_CODE_SUCCESS ;
}
2022-01-22 07:42:37 +00:00
2022-03-29 07:24:25 +00:00
static void * setAllSourcesCompleted ( SOperatorInfo * pOperator , int64_t startTs ) {
SExchangeInfo * pExchangeInfo = pOperator - > info ;
2022-02-11 06:33:57 +00:00
SExecTaskInfo * pTaskInfo = pOperator - > pTaskInfo ;
2022-01-22 14:51:48 +00:00
2022-03-29 07:24:25 +00:00
int64_t el = taosGetTimestampUs ( ) - startTs ;
2022-03-11 11:29:43 +00:00
SLoadRemoteDataInfo * pLoadInfo = & pExchangeInfo - > loadInfo ;
pLoadInfo - > totalElapsed + = el ;
2022-01-25 06:13:11 +00:00
2022-02-11 06:33:57 +00:00
size_t totalSources = taosArrayGetSize ( pExchangeInfo - > pSources ) ;
2022-03-29 07:24:25 +00:00
qDebug ( " %s all % " PRIzu " sources are exhausted, total rows: % " PRIu64 " bytes:% " PRIu64 " , elapsed:%.2f ms " ,
GET_TASKID ( pTaskInfo ) , totalSources , pLoadInfo - > totalRows , pLoadInfo - > totalSize ,
pLoadInfo - > totalElapsed / 1000.0 ) ;
2022-02-11 06:33:57 +00:00
doSetOperatorCompleted ( pOperator ) ;
return NULL ;
}
2022-03-29 07:24:25 +00:00
static SSDataBlock * concurrentlyLoadRemoteDataImpl ( SOperatorInfo * pOperator , SExchangeInfo * pExchangeInfo ,
SExecTaskInfo * pTaskInfo ) {
2022-02-11 06:33:57 +00:00
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 ) ;
2022-03-29 12:07:38 +00:00
if ( pDataInfo - > status = = EX_SOURCE_DATA_EXHAUSTED ) {
2022-02-11 06:33:57 +00:00
completed + = 1 ;
2022-01-22 14:51:48 +00:00
continue ;
}
2021-11-02 05:37:31 +00:00
2022-03-29 12:07:38 +00:00
if ( pDataInfo - > status ! = EX_SOURCE_DATA_READY ) {
2022-02-11 06:33:57 +00:00
continue ;
}
2022-03-29 07:24:25 +00:00
SRetrieveTableRsp * pRsp = pDataInfo - > pRsp ;
2022-03-09 09:32:12 +00:00
SDownstreamSourceNode * pSource = taosArrayGet ( pExchangeInfo - > pSources , i ) ;
2022-02-11 06:33:57 +00:00
2022-03-29 07:24:25 +00:00
SSDataBlock * pRes = pExchangeInfo - > pResult ;
2022-03-11 11:29:43 +00:00
SLoadRemoteDataInfo * pLoadInfo = & pExchangeInfo - > loadInfo ;
2022-02-11 06:33:57 +00:00
if ( pRsp - > numOfRows = = 0 ) {
2022-03-29 07:24:25 +00:00
qDebug ( " %s vgId:%d, taskID:0x% " PRIx64 " index:%d completed, rowsOfSource:% " PRIu64 " , totalRows:% " PRIu64
" try next " ,
2022-02-11 06:33:57 +00:00
GET_TASKID ( pTaskInfo ) , pSource - > addr . nodeId , pSource - > taskId , i + 1 , pDataInfo - > totalRows ,
2022-03-11 11:29:43 +00:00
pExchangeInfo - > loadInfo . totalRows ) ;
2022-03-29 12:07:38 +00:00
pDataInfo - > status = EX_SOURCE_DATA_EXHAUSTED ;
2022-02-11 06:33:57 +00:00
completed + = 1 ;
continue ;
}
2022-01-19 08:20:13 +00:00
2022-03-11 11:29:43 +00:00
SRetrieveTableRsp * pTableRsp = pDataInfo - > pRsp ;
2022-03-29 07:24:25 +00:00
code =
setSDataBlockFromFetchRsp ( pExchangeInfo - > pResult , pLoadInfo , pTableRsp - > numOfRows , pTableRsp - > data ,
pTableRsp - > compLen , pOperator - > numOfOutput , startTs , & pDataInfo - > totalRows , NULL ) ;
2022-02-11 06:33:57 +00:00
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 ,
2022-03-29 07:24:25 +00:00
GET_TASKID ( pTaskInfo ) , pSource - > addr . nodeId , pSource - > taskId , pRes - > info . rows , pDataInfo - > totalRows ,
pLoadInfo - > totalRows , pLoadInfo - > totalSize , i + 1 , totalSources ) ;
2022-03-29 12:07:38 +00:00
pDataInfo - > status = EX_SOURCE_DATA_EXHAUSTED ;
2022-02-11 06:33:57 +00:00
} else {
2022-04-23 10:29:45 +00:00
qDebug ( " %s fetch msg rsp from vgId:%d, taskId:0x% " PRIx64 " numOfRows:%d, totalRows:% " PRIu64
" , totalBytes:% " PRIu64 ,
2022-03-11 11:29:43 +00:00
GET_TASKID ( pTaskInfo ) , pSource - > addr . nodeId , pSource - > taskId , pRes - > info . rows , pLoadInfo - > totalRows ,
pLoadInfo - > totalSize ) ;
2022-02-11 06:33:57 +00:00
}
2022-03-29 12:07:38 +00:00
if ( pDataInfo - > status ! = EX_SOURCE_DATA_EXHAUSTED ) {
pDataInfo - > status = EX_SOURCE_DATA_NOT_READY ;
2022-02-11 06:33:57 +00:00
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 ;
}
2022-03-29 07:24:25 +00:00
static SSDataBlock * concurrentlyLoadRemoteData ( SOperatorInfo * pOperator ) {
SExchangeInfo * pExchangeInfo = pOperator - > info ;
SExecTaskInfo * pTaskInfo = pOperator - > pTaskInfo ;
2022-03-21 10:34:42 +00:00
2022-03-18 03:12:49 +00:00
if ( pOperator - > status = = OP_RES_TO_RETURN ) {
return concurrentlyLoadRemoteDataImpl ( pOperator , pExchangeInfo , pTaskInfo ) ;
}
2022-02-11 06:33:57 +00:00
2022-03-29 07:24:25 +00:00
size_t totalSources = taosArrayGetSize ( pExchangeInfo - > pSources ) ;
2022-02-11 06:33:57 +00:00
int64_t startTs = taosGetTimestampUs ( ) ;
// Asynchronously send all fetch requests to all sources.
2022-03-29 07:24:25 +00:00
for ( int32_t i = 0 ; i < totalSources ; + + i ) {
2022-02-11 06:33:57 +00:00
int32_t code = doSendFetchDataRequest ( pExchangeInfo , pTaskInfo , i ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
2022-03-18 03:12:49 +00:00
return NULL ;
2022-02-11 06:33:57 +00:00
}
}
int64_t endTs = taosGetTimestampUs ( ) ;
2022-03-29 07:24:25 +00:00
qDebug ( " %s send all fetch request to % " PRIzu " sources completed, elapsed:% " PRId64 , GET_TASKID ( pTaskInfo ) ,
totalSources , endTs - startTs ) ;
2022-02-11 06:33:57 +00:00
tsem_wait ( & pExchangeInfo - > ready ) ;
2022-03-18 03:12:49 +00:00
pOperator - > status = OP_RES_TO_RETURN ;
return concurrentlyLoadRemoteDataImpl ( pOperator , pExchangeInfo , pTaskInfo ) ;
2022-02-11 06:33:57 +00:00
}
2022-03-29 07:24:25 +00:00
static int32_t prepareConcurrentlyLoad ( SOperatorInfo * pOperator ) {
SExchangeInfo * pExchangeInfo = pOperator - > info ;
SExecTaskInfo * pTaskInfo = pOperator - > pTaskInfo ;
2022-02-11 06:33:57 +00:00
2022-03-29 07:24:25 +00:00
size_t totalSources = taosArrayGetSize ( pExchangeInfo - > pSources ) ;
2022-02-11 06:33:57 +00:00
int64_t startTs = taosGetTimestampUs ( ) ;
// Asynchronously send all fetch requests to all sources.
2022-03-29 07:24:25 +00:00
for ( int32_t i = 0 ; i < totalSources ; + + i ) {
2022-02-11 06:33:57 +00:00
int32_t code = doSendFetchDataRequest ( pExchangeInfo , pTaskInfo , i ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
2022-03-05 07:58:28 +00:00
pTaskInfo - > code = code ;
return code ;
2022-02-11 06:33:57 +00:00
}
}
int64_t endTs = taosGetTimestampUs ( ) ;
2022-03-29 07:24:25 +00:00
qDebug ( " %s send all fetch request to % " PRIzu " sources completed, elapsed:% " PRId64 , GET_TASKID ( pTaskInfo ) ,
totalSources , endTs - startTs ) ;
2022-02-11 06:33:57 +00:00
tsem_wait ( & pExchangeInfo - > ready ) ;
2022-03-05 07:58:28 +00:00
pOperator - > cost . openCost = taosGetTimestampUs ( ) - startTs ;
2022-02-11 06:33:57 +00:00
2022-03-05 07:58:28 +00:00
return TSDB_CODE_SUCCESS ;
2022-02-11 06:33:57 +00:00
}
2022-03-29 07:24:25 +00:00
static SSDataBlock * seqLoadRemoteData ( SOperatorInfo * pOperator ) {
SExchangeInfo * pExchangeInfo = pOperator - > info ;
SExecTaskInfo * pTaskInfo = pOperator - > pTaskInfo ;
2022-02-11 06:33:57 +00:00
2022-03-29 07:24:25 +00:00
size_t totalSources = taosArrayGetSize ( pExchangeInfo - > pSources ) ;
2022-02-11 06:33:57 +00:00
int64_t startTs = taosGetTimestampUs ( ) ;
2022-01-22 07:42:37 +00:00
2022-03-29 07:24:25 +00:00
while ( 1 ) {
2022-02-11 06:33:57 +00:00
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 ) ;
2022-04-23 10:29:45 +00:00
SSourceDataInfo * pDataInfo = taosArrayGet ( pExchangeInfo - > pSourceDataInfo , pExchangeInfo - > current ) ;
2022-03-09 09:32:12 +00:00
SDownstreamSourceNode * pSource = taosArrayGet ( pExchangeInfo - > pSources , pExchangeInfo - > current ) ;
2022-02-11 06:33:57 +00:00
2022-04-01 08:09:00 +00:00
if ( pDataInfo - > code ! = TSDB_CODE_SUCCESS ) {
2022-04-23 10:29:45 +00:00
qError ( " %s vgId:%d, taskID:0x% " PRIx64 " error happens, code:%s " , GET_TASKID ( pTaskInfo ) , pSource - > addr . nodeId ,
pSource - > taskId , tstrerror ( pDataInfo - > code ) ) ;
2022-04-01 08:09:00 +00:00
pOperator - > pTaskInfo - > code = pDataInfo - > code ;
return NULL ;
}
2022-03-29 07:24:25 +00:00
SRetrieveTableRsp * pRsp = pDataInfo - > pRsp ;
2022-03-11 11:29:43 +00:00
SLoadRemoteDataInfo * pLoadInfo = & pExchangeInfo - > loadInfo ;
2022-02-11 06:33:57 +00:00
if ( pRsp - > numOfRows = = 0 ) {
2022-04-23 10:29:45 +00:00
qDebug ( " %s vgId:%d, taskID:0x% " PRIx64 " %d of total completed, rowsOfSource:% " PRIu64 " , totalRows:% " PRIu64
" try next " ,
2022-02-11 06:33:57 +00:00
GET_TASKID ( pTaskInfo ) , pSource - > addr . nodeId , pSource - > taskId , pExchangeInfo - > current + 1 ,
2022-03-11 11:29:43 +00:00
pDataInfo - > totalRows , pLoadInfo - > totalRows ) ;
2022-01-19 08:20:13 +00:00
2022-03-29 12:07:38 +00:00
pDataInfo - > status = EX_SOURCE_DATA_EXHAUSTED ;
2022-02-11 06:33:57 +00:00
pExchangeInfo - > current + = 1 ;
continue ;
}
2022-01-25 06:13:11 +00:00
2022-03-29 07:24:25 +00:00
SSDataBlock * pRes = pExchangeInfo - > pResult ;
2022-03-11 11:29:43 +00:00
SRetrieveTableRsp * pTableRsp = pDataInfo - > pRsp ;
2022-03-29 07:24:25 +00:00
int32_t code =
setSDataBlockFromFetchRsp ( pExchangeInfo - > pResult , pLoadInfo , pTableRsp - > numOfRows , pTableRsp - > data ,
pTableRsp - > compLen , pOperator - > numOfOutput , startTs , & pDataInfo - > totalRows , NULL ) ;
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-03-29 07:24:25 +00:00
" , totalRows:% " PRIu64 " , totalBytes:% " PRIu64 " try next %d/% " PRIzu ,
GET_TASKID ( pTaskInfo ) , pSource - > addr . nodeId , pSource - > taskId , pRes - > info . rows , pDataInfo - > totalRows ,
pLoadInfo - > totalRows , pLoadInfo - > totalSize , pExchangeInfo - > current + 1 , totalSources ) ;
2022-01-22 07:42:37 +00:00
2022-03-29 12:07:38 +00:00
pDataInfo - > status = EX_SOURCE_DATA_EXHAUSTED ;
2022-01-22 07:42:37 +00:00
pExchangeInfo - > current + = 1 ;
} else {
2022-03-29 07:24:25 +00:00
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 , pLoadInfo - > totalRows ,
pLoadInfo - > totalSize ) ;
2022-01-22 07:42:37 +00:00
}
return pExchangeInfo - > pResult ;
}
2022-02-11 06:33:57 +00:00
}
2022-03-29 07:24:25 +00:00
static int32_t prepareLoadRemoteData ( SOperatorInfo * pOperator ) {
2022-03-12 07:28:15 +00:00
if ( OPTR_IS_OPENED ( pOperator ) ) {
2022-03-05 07:58:28 +00:00
return TSDB_CODE_SUCCESS ;
}
2022-03-29 07:24:25 +00:00
SExchangeInfo * pExchangeInfo = pOperator - > info ;
2022-03-05 07:58:28 +00:00
if ( pExchangeInfo - > seqLoadData ) {
// do nothing for sequentially load data
} else {
int32_t code = prepareConcurrentlyLoad ( pOperator ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
return code ;
}
}
2022-03-12 07:28:15 +00:00
OPTR_SET_OPENED ( pOperator ) ;
2022-03-05 07:58:28 +00:00
return TSDB_CODE_SUCCESS ;
}
2022-03-29 07:24:25 +00:00
static SSDataBlock * doLoadRemoteData ( SOperatorInfo * pOperator , bool * newgroup ) {
SExchangeInfo * pExchangeInfo = pOperator - > info ;
SExecTaskInfo * pTaskInfo = pOperator - > pTaskInfo ;
2022-02-11 06:33:57 +00:00
2022-04-26 12:26:32 +00:00
pTaskInfo - > code = pOperator - > fpSet . _openFn ( pOperator ) ;
2022-03-15 06:37:26 +00:00
if ( pTaskInfo - > code ! = TSDB_CODE_SUCCESS ) {
2022-03-05 07:58:28 +00:00
return NULL ;
}
2022-02-11 06:33:57 +00:00
2022-03-29 07:24:25 +00:00
size_t totalSources = taosArrayGetSize ( pExchangeInfo - > pSources ) ;
2022-03-11 11:29:43 +00:00
SLoadRemoteDataInfo * pLoadInfo = & pExchangeInfo - > loadInfo ;
2022-03-18 03:12:49 +00:00
2022-02-11 06:33:57 +00:00
if ( pOperator - > status = = OP_EXEC_DONE ) {
2022-03-29 07:24:25 +00:00
qDebug ( " %s all % " PRIzu " source(s) are exhausted, total rows:% " PRIu64 " bytes:% " PRIu64 " , elapsed:%.2f ms " ,
GET_TASKID ( pTaskInfo ) , totalSources , pLoadInfo - > totalRows , pLoadInfo - > totalSize ,
pLoadInfo - > totalElapsed / 1000.0 ) ;
2022-02-11 06:33:57 +00:00
return NULL ;
}
* newgroup = false ;
2022-03-18 03:12:49 +00:00
2022-02-11 06:33:57 +00:00
if ( pExchangeInfo - > seqLoadData ) {
return seqLoadRemoteData ( pOperator ) ;
} else {
2022-03-18 03:12:49 +00:00
return concurrentlyLoadRemoteData ( pOperator ) ;
2022-02-11 06:33:57 +00:00
}
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 :
2022-03-25 16:29:53 +00:00
taosMemoryFreeClear ( pMsg ) ;
taosMemoryFreeClear ( pMsgSendInfo ) ;
2022-01-19 09:03:29 +00:00
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-03-04 07:53:30 +00:00
static int32_t initDataSource ( int32_t numOfSources , SExchangeInfo * pInfo ) {
2022-02-11 06:33:57 +00:00
pInfo - > pSourceDataInfo = taosArrayInit ( numOfSources , sizeof ( SSourceDataInfo ) ) ;
2022-03-04 07:53:30 +00:00
if ( pInfo - > pSourceDataInfo = = NULL ) {
return TSDB_CODE_OUT_OF_MEMORY ;
2022-02-11 06:33:57 +00:00
}
2022-03-29 07:24:25 +00:00
for ( int32_t i = 0 ; i < numOfSources ; + + i ) {
2022-02-11 06:33:57 +00:00
SSourceDataInfo dataInfo = { 0 } ;
2022-03-05 07:58:28 +00:00
dataInfo . status = EX_SOURCE_DATA_NOT_READY ;
2022-03-29 07:24:25 +00:00
dataInfo . pEx = pInfo ;
dataInfo . index = i ;
2022-02-11 06:33:57 +00:00
2022-03-04 07:53:30 +00:00
void * ret = taosArrayPush ( pInfo - > pSourceDataInfo , & dataInfo ) ;
if ( ret = = NULL ) {
taosArrayDestroy ( pInfo - > pSourceDataInfo ) ;
return TSDB_CODE_OUT_OF_MEMORY ;
}
}
return TSDB_CODE_SUCCESS ;
}
2022-03-10 10:07:07 +00:00
SOperatorInfo * createExchangeOperatorInfo ( const SNodeList * pSources , SSDataBlock * pBlock , SExecTaskInfo * pTaskInfo ) {
2022-03-29 07:24:25 +00:00
SExchangeInfo * pInfo = taosMemoryCalloc ( 1 , sizeof ( SExchangeInfo ) ) ;
2022-03-25 16:29:53 +00:00
SOperatorInfo * pOperator = taosMemoryCalloc ( 1 , sizeof ( SOperatorInfo ) ) ;
2022-03-04 07:53:30 +00:00
if ( pInfo = = NULL | | pOperator = = NULL ) {
2022-03-25 16:29:53 +00:00
taosMemoryFreeClear ( pInfo ) ;
taosMemoryFreeClear ( pOperator ) ;
2022-03-18 03:12:49 +00:00
terrno = TSDB_CODE_QRY_OUT_OF_MEMORY ;
return NULL ;
2022-03-04 07:53:30 +00:00
}
2022-03-10 08:18:35 +00:00
size_t numOfSources = LIST_LENGTH ( pSources ) ;
2022-03-10 10:07:07 +00:00
pInfo - > pSources = taosArrayInit ( numOfSources , sizeof ( SDownstreamSourceNode ) ) ;
2022-03-14 06:15:26 +00:00
pInfo - > pSourceDataInfo = taosArrayInit ( numOfSources , sizeof ( SSourceDataInfo ) ) ;
if ( pInfo - > pSourceDataInfo = = NULL | | pInfo - > pSources = = NULL ) {
goto _error ;
2022-03-10 10:07:07 +00:00
}
2022-03-29 07:24:25 +00:00
for ( int32_t i = 0 ; i < numOfSources ; + + i ) {
SNodeListNode * pNode = nodesListGetNode ( ( SNodeList * ) pSources , i ) ;
2022-03-10 10:07:07 +00:00
taosArrayPush ( pInfo - > pSources , pNode ) ;
}
2022-02-11 06:33:57 +00:00
2022-03-04 07:53:30 +00:00
int32_t code = initDataSource ( numOfSources , pInfo ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
goto _error ;
2022-02-11 06:33:57 +00:00
}
2022-01-19 06:47:53 +00:00
2022-04-23 10:29:45 +00:00
pInfo - > pResult = pBlock ;
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
2022-04-23 10:29:45 +00:00
pOperator - > name = " ExchangeOperator " ;
2022-02-28 09:02:43 +00:00
pOperator - > operatorType = QUERY_NODE_PHYSICAL_PLAN_EXCHANGE ;
2022-01-16 07:56:48 +00:00
pOperator - > blockingOptr = false ;
2022-04-23 10:29:45 +00:00
pOperator - > status = OP_NOT_OPENED ;
pOperator - > info = pInfo ;
pOperator - > numOfOutput = pBlock - > info . numOfCols ;
pOperator - > pTaskInfo = pTaskInfo ;
2022-04-26 12:26:32 +00:00
pOperator - > fpSet = createOperatorFpSet ( prepareLoadRemoteData , doLoadRemoteData , NULL , NULL , destroyExchangeOperatorInfo ,
NULL , NULL , NULL ) ;
2022-01-16 07:56:48 +00:00
2022-01-26 01:20:48 +00:00
# if 1
2022-03-29 07:24:25 +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-02-24 10:35:25 +00:00
rpcInit . sessions = tsMaxConnections ;
2022-01-19 06:47:53 +00:00
rpcInit . connType = TAOS_CONN_CLIENT ;
2022-03-29 07:24:25 +00:00
rpcInit . user = ( char * ) " root " ;
2022-02-24 10:35:25 +00:00
rpcInit . idleTime = tsShellActivityTimer * 1000 ;
2022-01-19 06:47:53 +00:00
rpcInit . ckey = " key " ;
2022-01-23 11:50:18 +00:00
rpcInit . spi = 1 ;
2022-03-29 07:24:25 +00:00
rpcInit . secret = ( char * ) " dcc5bed04851fec854c035b2e40263b6 " ;
2022-01-19 06:47:53 +00:00
pInfo - > pTransporter = rpcOpen ( & rpcInit ) ;
if ( pInfo - > pTransporter = = NULL ) {
2022-03-29 07:24:25 +00:00
return NULL ; // todo
2022-01-19 06:47:53 +00:00
}
}
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-03-04 07:53:30 +00:00
2022-03-29 07:24:25 +00:00
_error :
2022-03-04 07:53:30 +00:00
if ( pInfo ! = NULL ) {
2022-03-14 06:15:26 +00:00
destroyExchangeOperatorInfo ( pInfo , numOfSources ) ;
2022-03-04 07:53:30 +00:00
}
2022-03-25 16:29:53 +00:00
taosMemoryFreeClear ( pInfo ) ;
taosMemoryFreeClear ( pOperator ) ;
2022-03-14 06:15:26 +00:00
pTaskInfo - > code = TSDB_CODE_OUT_OF_MEMORY ;
2022-03-04 07:53:30 +00:00
return NULL ;
2022-01-16 07:56:48 +00:00
}
2022-04-23 10:29:45 +00:00
static int32_t doInitAggInfoSup ( SAggSupporter * pAggSup , SqlFunctionCtx * pCtx , int32_t numOfOutput , size_t keyBufSize ,
const char * pKey ) ;
2022-04-04 06:54:39 +00:00
static void cleanupAggSup ( SAggSupporter * pAggSup ) ;
2021-11-02 05:37:31 +00:00
2022-02-19 08:15:09 +00:00
static void destroySortedMergeOperatorInfo ( void * param , int32_t numOfOutput ) {
2022-03-29 07:24:25 +00:00
SSortedMergeOperatorInfo * pInfo = ( SSortedMergeOperatorInfo * ) param ;
2022-03-28 11:08:07 +00:00
taosArrayDestroy ( pInfo - > pSortInfo ) ;
2022-02-22 05:12:03 +00:00
taosArrayDestroy ( pInfo - > groupInfo ) ;
if ( pInfo - > pSortHandle ! = NULL ) {
2022-02-22 05:16:46 +00:00
tsortDestroySortHandle ( pInfo - > pSortHandle ) ;
2022-02-22 05:12:03 +00:00
}
2022-03-28 11:08:07 +00:00
blockDataDestroy ( pInfo - > binfo . pRes ) ;
2022-03-14 06:15:26 +00:00
cleanupAggSup ( & pInfo - > aggSup ) ;
2021-11-02 05:37:31 +00:00
}
2022-02-15 06:40:29 +00:00
2022-03-01 02:40:50 +00:00
static void assignExprInfo ( SExprInfo * dst , const SExprInfo * src ) {
assert ( dst ! = NULL & & src ! = NULL ) ;
2021-11-02 05:37:31 +00:00
2022-03-01 02:40:50 +00:00
* dst = * src ;
2021-11-02 05:37:31 +00:00
2022-03-01 02:40:50 +00:00
dst - > pExpr = exprdup ( src - > pExpr ) ;
2022-03-25 16:29:53 +00:00
dst - > base . pParam = taosMemoryCalloc ( src - > base . numOfParams , sizeof ( SColumn ) ) ;
2022-03-09 02:22:53 +00:00
memcpy ( dst - > base . pParam , src - > base . pParam , sizeof ( SColumn ) * src - > base . numOfParams ) ;
2021-11-02 05:37:31 +00:00
2022-03-29 07:24:25 +00:00
// memset(dst->base.param, 0, sizeof(SVariant) * tListLen(dst->base.param));
// for (int32_t j = 0; j < src->base.numOfParams; ++j) {
// taosVariantAssign(&dst->base.param[j], &src->base.param[j]);
// }
2022-03-01 02:40:50 +00:00
}
2021-11-02 05:37:31 +00:00
2022-02-21 05:28:20 +00:00
// TODO merge aggregate super table
2022-03-29 07:24:25 +00:00
static void appendOneRowToDataBlock ( SSDataBlock * pBlock , STupleHandle * pTupleHandle ) {
2022-02-08 02:21:00 +00:00
for ( int32_t i = 0 ; i < pBlock - > info . numOfCols ; + + i ) {
SColumnInfoData * pColInfo = taosArrayGet ( pBlock - > pDataBlock , i ) ;
2021-11-02 05:37:31 +00:00
2022-02-22 05:16:46 +00:00
bool isNull = tsortIsNullVal ( pTupleHandle , i ) ;
2022-02-15 06:40:29 +00:00
if ( isNull ) {
colDataAppend ( pColInfo , pBlock - > info . rows , NULL , true ) ;
} else {
2022-02-22 05:16:46 +00:00
char * pData = tsortGetValue ( pTupleHandle , i ) ;
2022-02-15 06:40:29 +00:00
colDataAppend ( pColInfo , pBlock - > info . rows , pData , false ) ;
}
2021-11-02 05:37:31 +00:00
}
2022-02-08 02:21:00 +00:00
pBlock - > info . rows + = 1 ;
}
2021-11-02 05:37:31 +00:00
2022-04-07 06:51:52 +00:00
SSDataBlock * getSortedBlockData ( SSortHandle * pHandle , SSDataBlock * pDataBlock , int32_t capacity ) {
2022-03-17 05:11:06 +00:00
blockDataCleanup ( pDataBlock ) ;
2022-04-09 08:14:01 +00:00
blockDataEnsureCapacity ( pDataBlock , capacity ) ;
2021-11-02 05:37:31 +00:00
2022-04-06 03:43:17 +00:00
blockDataEnsureCapacity ( pDataBlock , capacity ) ;
2022-03-29 07:24:25 +00:00
while ( 1 ) {
2022-02-22 05:16:46 +00:00
STupleHandle * pTupleHandle = tsortNextTuple ( pHandle ) ;
2022-02-19 08:15:09 +00:00
if ( pTupleHandle = = NULL ) {
break ;
}
2021-11-02 05:37:31 +00:00
2022-02-19 08:15:09 +00:00
appendOneRowToDataBlock ( pDataBlock , pTupleHandle ) ;
if ( pDataBlock - > info . rows > = capacity ) {
return pDataBlock ;
2022-02-08 10:01:21 +00:00
}
}
2021-11-02 05:37:31 +00:00
2022-03-29 07:24:25 +00:00
return ( pDataBlock - > info . rows > 0 ) ? pDataBlock : NULL ;
2022-02-08 02:21:00 +00:00
}
2021-11-02 05:37:31 +00:00
2022-02-19 08:15:09 +00:00
SSDataBlock * loadNextDataBlock ( void * param ) {
2022-03-29 07:24:25 +00:00
SOperatorInfo * pOperator = ( SOperatorInfo * ) param ;
bool newgroup = false ;
2022-04-26 12:26:32 +00:00
return pOperator - > fpSet . getNextFn ( pOperator , & newgroup ) ;
2021-11-02 05:37:31 +00:00
}
2022-03-29 07:24:25 +00:00
static bool needToMerge ( SSDataBlock * pBlock , SArray * groupInfo , char * * buf , int32_t rowIndex ) {
2022-02-22 05:12:03 +00:00
size_t size = taosArrayGetSize ( groupInfo ) ;
if ( size = = 0 ) {
return true ;
}
2021-11-02 05:37:31 +00:00
2022-02-22 05:12:03 +00:00
for ( int32_t i = 0 ; i < size ; + + i ) {
int32_t * index = taosArrayGet ( groupInfo , i ) ;
2021-11-02 05:37:31 +00:00
2022-02-22 05:12:03 +00:00
SColumnInfoData * pColInfo = taosArrayGet ( pBlock - > pDataBlock , * index ) ;
2022-03-29 07:24:25 +00:00
bool isNull = colDataIsNull ( pColInfo , rowIndex , pBlock - > info . rows , NULL ) ;
2021-11-02 05:37:31 +00:00
2022-02-22 05:12:03 +00:00
if ( ( isNull & & buf [ i ] ! = NULL ) | | ( ! isNull & & buf [ i ] = = NULL ) ) {
return false ;
}
2021-11-02 05:37:31 +00:00
2022-02-22 05:12:03 +00:00
char * pCell = colDataGetData ( pColInfo , rowIndex ) ;
if ( IS_VAR_DATA_TYPE ( pColInfo - > info . type ) ) {
if ( varDataLen ( pCell ) ! = varDataLen ( buf [ i ] ) ) {
return false ;
} else {
if ( memcmp ( varDataVal ( pCell ) , varDataVal ( buf [ i ] ) , varDataLen ( pCell ) ) ! = 0 ) {
return false ;
}
}
} else {
if ( memcmp ( pCell , buf [ i ] , pColInfo - > info . bytes ) ! = 0 ) {
return false ;
}
2021-11-02 05:37:31 +00:00
}
}
2022-02-22 05:12:03 +00:00
return 0 ;
2021-11-02 05:37:31 +00:00
}
2022-03-29 07:24:25 +00:00
static void doMergeResultImpl ( SSortedMergeOperatorInfo * pInfo , SqlFunctionCtx * pCtx , int32_t numOfExpr ,
int32_t rowIndex ) {
for ( int32_t j = 0 ; j < numOfExpr ; + + j ) { // TODO set row index
2022-02-22 05:12:03 +00:00
pCtx [ j ] . startRow = rowIndex ;
2022-02-08 02:21:00 +00:00
}
2022-02-22 05:12:03 +00:00
for ( int32_t j = 0 ; j < numOfExpr ; + + j ) {
int32_t functionId = pCtx [ j ] . functionId ;
2022-03-29 07:24:25 +00:00
// pCtx[j].fpSet->addInput(&pCtx[j]);
// if (functionId < 0) {
// SUdfInfo* pUdfInfo = taosArrayGet(pInfo->udfInfo, -1 * functionId - 1);
// doInvokeUdf(pUdfInfo, &pCtx[j], 0, TSDB_UDF_FUNC_MERGE);
// } else {
// assert(!TSDB_FUNC_IS_SCALAR(functionId));
// aAggs[functionId].mergeFunc(&pCtx[j]);
// }
2022-02-08 02:21:00 +00:00
}
2022-02-22 05:12:03 +00:00
}
2022-02-08 02:21:00 +00:00
2022-03-29 07:24:25 +00:00
static void doFinalizeResultImpl ( SqlFunctionCtx * pCtx , int32_t numOfExpr ) {
for ( int32_t j = 0 ; j < numOfExpr ; + + j ) {
2022-02-22 05:12:03 +00:00
int32_t functionId = pCtx [ j ] . functionId ;
// if (functionId == FUNC_TAG_DUMMY || functionId == FUNC_TS_DUMMY) {
// continue;
// }
2022-02-08 02:21:00 +00:00
2022-02-22 05:12:03 +00:00
// if (functionId < 0) {
// SUdfInfo* pUdfInfo = taosArrayGet(pInfo->udfInfo, -1 * functionId - 1);
// doInvokeUdf(pUdfInfo, &pCtx[j], 0, TSDB_UDF_FUNC_FINALIZE);
// } else {
2022-04-23 10:29:45 +00:00
// pCtx[j].fpSet.finalize(&pCtx[j]);
2022-02-22 05:12:03 +00:00
}
}
2022-02-08 02:21:00 +00:00
2022-02-22 05:12:03 +00:00
static bool saveCurrentTuple ( char * * rowColData , SArray * pColumnList , SSDataBlock * pBlock , int32_t rowIndex ) {
2022-03-29 07:24:25 +00:00
int32_t size = ( int32_t ) taosArrayGetSize ( pColumnList ) ;
2022-02-08 02:21:00 +00:00
2022-03-29 07:24:25 +00:00
for ( int32_t i = 0 ; i < size ; + + i ) {
int32_t * index = taosArrayGet ( pColumnList , i ) ;
2022-02-22 05:12:03 +00:00
SColumnInfoData * pColInfo = taosArrayGet ( pBlock - > pDataBlock , * index ) ;
2022-02-09 05:44:16 +00:00
2022-02-22 05:12:03 +00:00
char * data = colDataGetData ( pColInfo , rowIndex ) ;
memcpy ( rowColData [ i ] , data , colDataGetLength ( pColInfo , rowIndex ) ) ;
}
2022-02-08 02:21:00 +00:00
2022-02-22 05:12:03 +00:00
return true ;
}
2022-02-08 02:21:00 +00:00
2022-02-22 05:12:03 +00:00
static void doMergeImpl ( SOperatorInfo * pOperator , int32_t numOfExpr , SSDataBlock * pBlock ) {
SSortedMergeOperatorInfo * pInfo = pOperator - > info ;
2022-02-08 02:21:00 +00:00
2022-02-22 05:12:03 +00:00
SqlFunctionCtx * pCtx = pInfo - > binfo . pCtx ;
2022-03-29 07:24:25 +00:00
for ( int32_t i = 0 ; i < pBlock - > info . numOfCols ; + + i ) {
2022-02-22 05:12:03 +00:00
pCtx [ i ] . size = 1 ;
}
2022-02-08 02:21:00 +00:00
2022-03-29 07:24:25 +00:00
for ( int32_t i = 0 ; i < pBlock - > info . rows ; + + i ) {
2022-02-22 05:12:03 +00:00
if ( ! pInfo - > hasGroupVal ) {
ASSERT ( i = = 0 ) ;
doMergeResultImpl ( pInfo , pCtx , numOfExpr , i ) ;
pInfo - > hasGroupVal = saveCurrentTuple ( pInfo - > groupVal , pInfo - > groupInfo , pBlock , i ) ;
} else {
if ( needToMerge ( pBlock , pInfo - > groupInfo , pInfo - > groupVal , i ) ) {
doMergeResultImpl ( pInfo , pCtx , numOfExpr , i ) ;
} else {
doFinalizeResultImpl ( pCtx , numOfExpr ) ;
2022-03-09 02:22:53 +00:00
int32_t numOfRows = getNumOfResult ( pInfo - > binfo . pCtx , pOperator - > numOfOutput , NULL ) ;
2022-02-22 05:12:03 +00:00
// setTagValueForMultipleRows(pCtx, pOperator->numOfOutput, numOfRows);
2022-02-08 02:21:00 +00:00
2022-02-22 05:12:03 +00:00
// TODO check for available buffer;
2022-02-09 05:44:16 +00:00
2022-02-22 05:12:03 +00:00
// next group info data
pInfo - > binfo . pRes - > info . rows + = numOfRows ;
for ( int32_t j = 0 ; j < numOfExpr ; + + j ) {
if ( pCtx [ j ] . functionId < 0 ) {
continue ;
2022-02-08 02:21:00 +00:00
}
2022-02-22 05:12:03 +00:00
2022-03-09 02:22:53 +00:00
pCtx [ j ] . fpSet . process ( & pCtx [ j ] ) ;
2022-02-08 02:21:00 +00:00
}
2022-02-22 05:12:03 +00:00
doMergeResultImpl ( pInfo , pCtx , numOfExpr , i ) ;
pInfo - > hasGroupVal = saveCurrentTuple ( pInfo - > groupVal , pInfo - > groupInfo , pBlock , i ) ;
2022-02-09 05:44:16 +00:00
}
2022-02-08 02:21:00 +00:00
}
}
}
2022-02-22 05:12:03 +00:00
static SSDataBlock * doMerge ( SOperatorInfo * pOperator ) {
SSortedMergeOperatorInfo * pInfo = pOperator - > info ;
2022-03-29 07:24:25 +00:00
SSortHandle * pHandle = pInfo - > pSortHandle ;
2022-02-08 07:40:13 +00:00
2022-04-14 07:33:37 +00:00
SSDataBlock * pDataBlock = createOneDataBlock ( pInfo - > binfo . pRes , false ) ;
2022-04-18 10:47:59 +00:00
blockDataEnsureCapacity ( pDataBlock , pOperator - > resultInfo . capacity ) ;
2022-02-22 05:12:03 +00:00
2022-03-29 07:24:25 +00:00
while ( 1 ) {
2022-03-17 05:11:06 +00:00
blockDataCleanup ( pDataBlock ) ;
2022-02-22 05:12:03 +00:00
while ( 1 ) {
2022-02-22 05:16:46 +00:00
STupleHandle * pTupleHandle = tsortNextTuple ( pHandle ) ;
2022-02-22 05:12:03 +00:00
if ( pTupleHandle = = NULL ) {
break ;
2022-02-08 07:40:13 +00:00
}
2022-02-10 05:38:40 +00:00
2022-02-22 05:12:03 +00:00
// build datablock for merge for one group
appendOneRowToDataBlock ( pDataBlock , pTupleHandle ) ;
2022-04-18 10:47:59 +00:00
if ( pDataBlock - > info . rows > = pOperator - > resultInfo . capacity ) {
2022-02-22 05:12:03 +00:00
break ;
}
2022-02-08 07:40:13 +00:00
}
2022-02-08 02:21:00 +00:00
2022-02-22 05:12:03 +00:00
if ( pDataBlock - > info . rows = = 0 ) {
break ;
}
2022-02-08 02:21:00 +00:00
2022-04-18 04:07:04 +00:00
setInputDataBlock ( pOperator , pInfo - > binfo . pCtx , pDataBlock , TSDB_ORDER_ASC , true ) ;
2022-03-29 07:24:25 +00:00
// updateOutputBuf(&pInfo->binfo, &pAggInfo->bufCapacity, pBlock->info.rows * pAggInfo->resultRowFactor,
// pOperator->pRuntimeEnv, true);
2022-02-22 05:12:03 +00:00
doMergeImpl ( pOperator , pOperator - > numOfOutput , pDataBlock ) ;
// flush to tuple store, and after all data have been handled, return to upstream node or sink node
}
2022-02-08 02:21:00 +00:00
2022-02-22 05:12:03 +00:00
doFinalizeResultImpl ( pInfo - > binfo . pCtx , pOperator - > numOfOutput ) ;
2022-03-09 02:22:53 +00:00
int32_t numOfRows = getNumOfResult ( pInfo - > binfo . pCtx , pOperator - > numOfOutput , NULL ) ;
2022-02-22 05:12:03 +00:00
// setTagValueForMultipleRows(pCtx, pOperator->numOfOutput, numOfRows);
2022-02-08 02:21:00 +00:00
2022-02-22 05:12:03 +00:00
// TODO check for available buffer;
2022-02-08 02:21:00 +00:00
2022-02-22 05:12:03 +00:00
// next group info data
pInfo - > binfo . pRes - > info . rows + = numOfRows ;
2022-03-29 07:24:25 +00:00
return ( pInfo - > binfo . pRes - > info . rows > 0 ) ? pInfo - > binfo . pRes : NULL ;
2022-02-22 05:12:03 +00:00
}
2022-02-08 02:21:00 +00:00
2022-03-29 07:24:25 +00:00
static SSDataBlock * doSortedMerge ( SOperatorInfo * pOperator , bool * newgroup ) {
2021-11-02 05:37:31 +00:00
if ( pOperator - > status = = OP_EXEC_DONE ) {
return NULL ;
2022-02-08 02:21:00 +00:00
}
2022-03-29 07:24:25 +00:00
SExecTaskInfo * pTaskInfo = pOperator - > pTaskInfo ;
2022-02-19 08:15:09 +00:00
SSortedMergeOperatorInfo * pInfo = pOperator - > info ;
2022-02-08 10:01:21 +00:00
if ( pOperator - > status = = OP_RES_TO_RETURN ) {
2022-04-18 10:47:59 +00:00
return getSortedBlockData ( pInfo - > pSortHandle , pInfo - > binfo . pRes , pOperator - > resultInfo . capacity ) ;
2022-02-08 07:40:13 +00:00
}
2022-02-19 08:15:09 +00:00
int32_t numOfBufPage = pInfo - > sortBufSize / pInfo - > bufPageSize ;
2022-04-23 10:29:45 +00:00
pInfo - > pSortHandle = tsortCreateSortHandle ( pInfo - > pSortInfo , NULL , SORT_MULTISOURCE_MERGE , pInfo - > bufPageSize ,
numOfBufPage , pInfo - > binfo . pRes , " GET_TASKID(pTaskInfo) " ) ;
2022-02-13 06:34:00 +00:00
2022-02-22 05:16:46 +00:00
tsortSetFetchRawDataFp ( pInfo - > pSortHandle , loadNextDataBlock ) ;
2022-02-08 02:21:00 +00:00
2022-03-29 07:24:25 +00:00
for ( int32_t i = 0 ; i < pOperator - > numOfDownstream ; + + i ) {
2022-04-06 10:30:25 +00:00
SSortSource * ps = taosMemoryCalloc ( 1 , sizeof ( SSortSource ) ) ;
2022-02-19 15:11:23 +00:00
ps - > param = pOperator - > pDownstream [ i ] ;
2022-02-22 05:16:46 +00:00
tsortAddSource ( pInfo - > pSortHandle , ps ) ;
2022-02-08 02:21:00 +00:00
}
2022-02-22 05:16:46 +00:00
int32_t code = tsortOpen ( pInfo - > pSortHandle ) ;
2022-02-08 07:40:13 +00:00
if ( code ! = TSDB_CODE_SUCCESS ) {
2022-02-19 07:20:20 +00:00
longjmp ( pTaskInfo - > env , terrno ) ;
2022-02-08 02:21:00 +00:00
}
2022-02-08 10:01:21 +00:00
pOperator - > status = OP_RES_TO_RETURN ;
2022-02-22 05:12:03 +00:00
return doMerge ( pOperator ) ;
2022-02-08 07:40:13 +00:00
}
2022-02-08 02:21:00 +00:00
2022-03-29 07:24:25 +00:00
static int32_t initGroupCol ( SExprInfo * pExprInfo , int32_t numOfCols , SArray * pGroupInfo ,
SSortedMergeOperatorInfo * pInfo ) {
2022-02-22 05:12:03 +00:00
if ( pGroupInfo = = NULL | | taosArrayGetSize ( pGroupInfo ) = = 0 ) {
return 0 ;
2022-02-15 06:40:29 +00:00
}
2022-02-22 05:12:03 +00:00
int32_t len = 0 ;
SArray * plist = taosArrayInit ( 3 , sizeof ( SColumn ) ) ;
pInfo - > groupInfo = taosArrayInit ( 3 , sizeof ( int32_t ) ) ;
if ( plist = = NULL | | pInfo - > groupInfo = = NULL ) {
return TSDB_CODE_OUT_OF_MEMORY ;
}
2022-03-29 07:24:25 +00:00
size_t numOfGroupCol = taosArrayGetSize ( pInfo - > groupInfo ) ;
for ( int32_t i = 0 ; i < numOfGroupCol ; + + i ) {
2022-02-22 05:12:03 +00:00
SColumn * pCol = taosArrayGet ( pGroupInfo , i ) ;
2022-03-29 07:24:25 +00:00
for ( int32_t j = 0 ; j < numOfCols ; + + j ) {
2022-03-12 14:59:12 +00:00
SExprInfo * pe = & pExprInfo [ j ] ;
2022-04-12 09:55:17 +00:00
if ( pe - > base . resSchema . slotId = = pCol - > colId ) {
2022-02-22 05:12:03 +00:00
taosArrayPush ( plist , pCol ) ;
taosArrayPush ( pInfo - > groupInfo , & j ) ;
2022-03-09 02:22:53 +00:00
len + = pCol - > bytes ;
2022-02-22 05:12:03 +00:00
break ;
}
2022-02-08 10:01:21 +00:00
}
}
2022-02-22 05:12:03 +00:00
ASSERT ( taosArrayGetSize ( pGroupInfo ) = = taosArrayGetSize ( plist ) ) ;
2022-02-15 06:40:29 +00:00
2022-03-25 16:29:53 +00:00
pInfo - > groupVal = taosMemoryCalloc ( 1 , ( POINTER_BYTES * numOfGroupCol + len ) ) ;
2022-02-22 05:12:03 +00:00
if ( pInfo - > groupVal = = NULL ) {
taosArrayDestroy ( plist ) ;
return TSDB_CODE_OUT_OF_MEMORY ;
}
2022-02-15 06:40:29 +00:00
2022-02-22 05:12:03 +00:00
int32_t offset = 0 ;
2022-03-29 07:24:25 +00:00
char * start = ( char * ) ( pInfo - > groupVal + ( POINTER_BYTES * numOfGroupCol ) ) ;
for ( int32_t i = 0 ; i < numOfGroupCol ; + + i ) {
2022-02-22 05:12:03 +00:00
pInfo - > groupVal [ i ] = start + offset ;
SColumn * pCol = taosArrayGet ( plist , i ) ;
2022-03-09 02:22:53 +00:00
offset + = pCol - > bytes ;
2022-02-22 05:12:03 +00:00
}
2022-02-15 06:40:29 +00:00
2022-02-22 05:12:03 +00:00
taosArrayDestroy ( plist ) ;
2022-02-15 06:40:29 +00:00
2022-02-22 05:12:03 +00:00
return TSDB_CODE_SUCCESS ;
}
2022-02-15 06:40:29 +00:00
2022-03-29 07:24:25 +00:00
SOperatorInfo * createSortedMergeOperatorInfo ( SOperatorInfo * * downstream , int32_t numOfDownstream , SExprInfo * pExprInfo ,
int32_t num , SArray * pSortInfo , SArray * pGroupInfo ,
SExecTaskInfo * pTaskInfo ) {
2022-03-25 16:29:53 +00:00
SSortedMergeOperatorInfo * pInfo = taosMemoryCalloc ( 1 , sizeof ( SSortedMergeOperatorInfo ) ) ;
2022-03-29 07:24:25 +00:00
SOperatorInfo * pOperator = taosMemoryCalloc ( 1 , sizeof ( SOperatorInfo ) ) ;
2022-02-19 08:15:09 +00:00
if ( pInfo = = NULL | | pOperator = = NULL ) {
2022-02-22 05:12:03 +00:00
goto _error ;
2022-02-19 08:15:09 +00:00
}
2022-02-15 06:40:29 +00:00
2022-04-12 09:55:17 +00:00
pInfo - > binfo . pCtx = createSqlFunctionCtx ( pExprInfo , num , & pInfo - > binfo . rowCellInfoOffset ) ;
2022-02-22 05:12:03 +00:00
initResultRowInfo ( & pInfo - > binfo . resultRowInfo , ( int32_t ) 1 ) ;
2022-02-15 06:40:29 +00:00
2022-02-22 05:12:03 +00:00
if ( pInfo - > binfo . pCtx = = NULL | | pInfo - > binfo . pRes = = NULL ) {
goto _error ;
}
2022-02-15 06:40:29 +00:00
2022-04-23 10:29:45 +00:00
size_t keyBufSize = sizeof ( int64_t ) + sizeof ( int64_t ) + POINTER_BYTES ;
2022-04-11 06:54:16 +00:00
int32_t code = doInitAggInfoSup ( & pInfo - > aggSup , pInfo - > binfo . pCtx , num , keyBufSize , pTaskInfo - > id . str ) ;
2022-02-22 05:12:03 +00:00
if ( code ! = TSDB_CODE_SUCCESS ) {
goto _error ;
}
2022-02-15 06:40:29 +00:00
2022-03-09 02:22:53 +00:00
setFunctionResultOutput ( & pInfo - > binfo , & pInfo - > aggSup , MAIN_SCAN , pTaskInfo ) ;
2022-03-12 14:59:12 +00:00
code = initGroupCol ( pExprInfo , num , pGroupInfo , pInfo ) ;
2022-02-22 05:12:03 +00:00
if ( code ! = TSDB_CODE_SUCCESS ) {
goto _error ;
}
2022-02-15 06:40:29 +00:00
2022-03-29 07:24:25 +00:00
// pInfo->resultRowFactor = (int32_t)(getRowNumForMultioutput(pRuntimeEnv->pQueryAttr,
// pRuntimeEnv->pQueryAttr->topBotQuery, false));
pInfo - > sortBufSize = 1024 * 16 ; // 1MB
pInfo - > bufPageSize = 1024 ;
pInfo - > pSortInfo = pSortInfo ;
2022-02-15 06:40:29 +00:00
2022-04-18 10:47:59 +00:00
pOperator - > resultInfo . capacity = blockDataGetCapacityInRow ( pInfo - > binfo . pRes , pInfo - > bufPageSize ) ;
2022-02-15 06:40:29 +00:00
2022-03-29 07:24:25 +00:00
pOperator - > name = " SortedMerge " ;
2022-03-01 02:40:50 +00:00
// pOperator->operatorType = OP_SortedMerge;
2022-02-19 08:15:09 +00:00
pOperator - > blockingOptr = true ;
2022-03-29 07:24:25 +00:00
pOperator - > status = OP_NOT_OPENED ;
pOperator - > info = pInfo ;
pOperator - > numOfOutput = num ;
pOperator - > pExpr = pExprInfo ;
2022-02-15 06:40:29 +00:00
2022-03-29 07:24:25 +00:00
pOperator - > pTaskInfo = pTaskInfo ;
2022-02-15 06:40:29 +00:00
2022-04-26 12:26:32 +00:00
pOperator - > fpSet = createOperatorFpSet ( operatorDummyOpenFn , doSortedMerge , NULL , NULL , destroySortedMergeOperatorInfo ,
NULL , NULL , NULL ) ;
2022-02-22 05:12:03 +00:00
code = appendDownstream ( pOperator , downstream , numOfDownstream ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
goto _error ;
2022-02-19 08:15:09 +00:00
}
2022-02-15 06:40:29 +00:00
2022-02-19 08:15:09 +00:00
return pOperator ;
2022-02-15 06:40:29 +00:00
2022-03-29 07:24:25 +00:00
_error :
2022-02-22 05:12:03 +00:00
if ( pInfo ! = NULL ) {
2022-03-12 14:59:12 +00:00
destroySortedMergeOperatorInfo ( pInfo , num ) ;
2022-02-15 06:40:29 +00:00
}
2022-03-25 16:29:53 +00:00
taosMemoryFreeClear ( pInfo ) ;
taosMemoryFreeClear ( pOperator ) ;
2022-02-22 05:12:03 +00:00
terrno = TSDB_CODE_QRY_OUT_OF_MEMORY ;
return NULL ;
2022-02-15 06:40:29 +00:00
}
2022-03-29 07:24:25 +00:00
static SSDataBlock * doSort ( SOperatorInfo * pOperator , bool * newgroup ) {
2021-11-02 05:37:31 +00:00
if ( pOperator - > status = = OP_EXEC_DONE ) {
return NULL ;
}
2022-03-29 07:24:25 +00:00
SExecTaskInfo * pTaskInfo = pOperator - > pTaskInfo ;
2022-03-28 11:08:07 +00:00
SSortOperatorInfo * pInfo = pOperator - > info ;
2022-02-08 10:01:21 +00:00
if ( pOperator - > status = = OP_RES_TO_RETURN ) {
2022-04-07 06:51:52 +00:00
return getSortedBlockData ( pInfo - > pSortHandle , pInfo - > pDataBlock , pInfo - > numOfRowsInRes ) ;
2022-02-08 10:01:21 +00:00
}
2022-02-19 08:15:09 +00:00
int32_t numOfBufPage = pInfo - > sortBufSize / pInfo - > bufPageSize ;
2022-04-23 10:29:45 +00:00
pInfo - > pSortHandle = tsortCreateSortHandle ( pInfo - > pSortInfo , pInfo - > inputSlotMap , SORT_SINGLESOURCE_SORT ,
pInfo - > bufPageSize , numOfBufPage , pInfo - > pDataBlock , pTaskInfo - > id . str ) ;
2021-11-02 05:37:31 +00:00
2022-02-22 05:16:46 +00:00
tsortSetFetchRawDataFp ( pInfo - > pSortHandle , loadNextDataBlock ) ;
2022-02-09 10:23:51 +00:00
2022-04-06 10:30:25 +00:00
SSortSource * ps = taosMemoryCalloc ( 1 , sizeof ( SSortSource ) ) ;
2022-03-28 11:08:07 +00:00
ps - > param = pOperator - > pDownstream [ 0 ] ;
2022-02-22 05:16:46 +00:00
tsortAddSource ( pInfo - > pSortHandle , ps ) ;
2022-02-08 02:21:00 +00:00
2022-02-22 05:16:46 +00:00
int32_t code = tsortOpen ( pInfo - > pSortHandle ) ;
2022-04-02 06:29:43 +00:00
taosMemoryFreeClear ( ps ) ;
2022-02-08 07:40:13 +00:00
if ( code ! = TSDB_CODE_SUCCESS ) {
2022-02-19 08:15:09 +00:00
longjmp ( pTaskInfo - > env , terrno ) ;
2022-02-08 07:40:13 +00:00
}
2022-02-08 02:21:00 +00:00
2022-02-08 10:01:21 +00:00
pOperator - > status = OP_RES_TO_RETURN ;
2022-04-07 06:51:52 +00:00
return getSortedBlockData ( pInfo - > pSortHandle , pInfo - > pDataBlock , pInfo - > numOfRowsInRes ) ;
2021-11-02 05:37:31 +00:00
}
2022-04-23 10:29:45 +00:00
SOperatorInfo * createSortOperatorInfo ( SOperatorInfo * downstream , SSDataBlock * pResBlock , SArray * pSortInfo ,
SArray * pIndexMap , SExecTaskInfo * pTaskInfo ) {
2022-03-28 11:08:07 +00:00
SSortOperatorInfo * pInfo = taosMemoryCalloc ( 1 , sizeof ( SSortOperatorInfo ) ) ;
2022-03-29 07:24:25 +00:00
SOperatorInfo * pOperator = taosMemoryCalloc ( 1 , sizeof ( SOperatorInfo ) ) ;
2022-04-23 10:29:45 +00:00
int32_t rowSize = pResBlock - > info . rowSize ;
2022-04-02 06:29:43 +00:00
if ( pInfo = = NULL | | pOperator = = NULL | | rowSize > 100 * 1024 * 1024 ) {
2022-03-25 16:29:53 +00:00
taosMemoryFreeClear ( pInfo ) ;
taosMemoryFreeClear ( pOperator ) ;
2022-02-08 10:07:03 +00:00
terrno = TSDB_CODE_QRY_OUT_OF_MEMORY ;
return NULL ;
}
2021-11-02 05:37:31 +00:00
2022-04-23 10:29:45 +00:00
pInfo - > bufPageSize = rowSize < 1024 ? 1024 * 2 : rowSize * 2 ; // there are headers, so pageSize = rowSize + header
2022-04-02 06:29:43 +00:00
2022-04-02 10:52:41 +00:00
pInfo - > sortBufSize = pInfo - > bufPageSize * 16 ; // TODO dynamic set the available sort buffer
2022-03-29 07:24:25 +00:00
pInfo - > numOfRowsInRes = 1024 ;
pInfo - > pDataBlock = pResBlock ;
pInfo - > pSortInfo = pSortInfo ;
2022-04-08 06:17:32 +00:00
pInfo - > inputSlotMap = pIndexMap ;
2022-02-08 10:07:03 +00:00
2022-04-23 10:29:45 +00:00
pOperator - > name = " SortOperator " ;
2022-03-29 07:24:25 +00:00
pOperator - > operatorType = QUERY_NODE_PHYSICAL_PLAN_SORT ;
pOperator - > blockingOptr = true ;
2022-04-23 10:29:45 +00:00
pOperator - > status = OP_NOT_OPENED ;
pOperator - > info = pInfo ;
2022-02-19 08:15:09 +00:00
2022-04-23 10:29:45 +00:00
pOperator - > pTaskInfo = pTaskInfo ;
2022-04-26 12:26:32 +00:00
pOperator - > fpSet = createOperatorFpSet ( operatorDummyOpenFn , doSort , NULL , NULL , destroyOrderOperatorInfo ,
NULL , NULL , NULL ) ;
2021-11-02 05:37:31 +00:00
2022-02-22 05:12:03 +00:00
int32_t code = appendDownstream ( pOperator , & downstream , 1 ) ;
2021-11-02 05:37:31 +00:00
return pOperator ;
2022-04-07 06:51:52 +00:00
2022-04-23 10:29:45 +00:00
_error :
2022-04-07 06:51:52 +00:00
pTaskInfo - > code = TSDB_CODE_OUT_OF_MEMORY ;
taosMemoryFree ( pInfo ) ;
taosMemoryFree ( pOperator ) ;
return NULL ;
2021-11-02 05:37:31 +00:00
}
2022-04-26 05:53:11 +00:00
int32_t getTableScanOrder ( SOperatorInfo * pOperator ) {
if ( pOperator - > operatorType ! = QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN ) {
2022-04-26 06:10:25 +00:00
if ( pOperator - > pDownstream = = NULL | | pOperator - > pDownstream [ 0 ] = = NULL ) {
2022-04-26 05:53:11 +00:00
return TSDB_ORDER_ASC ;
2022-04-26 06:10:25 +00:00
} else {
return getTableScanOrder ( pOperator - > pDownstream [ 0 ] ) ;
2022-04-26 05:53:11 +00:00
}
}
STableScanInfo * pTableScanInfo = pOperator - > info ;
return pTableScanInfo - > cond . order ;
}
2021-11-02 05:37:31 +00:00
// this is a blocking operator
2022-03-29 07:24:25 +00:00
static int32_t doOpenAggregateOptr ( SOperatorInfo * pOperator ) {
2022-03-12 10:02:56 +00:00
if ( OPTR_IS_OPENED ( pOperator ) ) {
return TSDB_CODE_SUCCESS ;
2021-11-02 05:37:31 +00:00
}
2022-04-16 11:10:21 +00:00
SExecTaskInfo * pTaskInfo = pOperator - > pTaskInfo ;
2021-11-02 05:37:31 +00:00
SAggOperatorInfo * pAggInfo = pOperator - > info ;
2022-04-16 11:10:21 +00:00
2022-04-23 10:29:45 +00:00
SOptrBasicInfo * pInfo = & pAggInfo - > binfo ;
2021-11-02 05:37:31 +00:00
2022-03-12 10:02:56 +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
2022-03-12 10:02:56 +00:00
bool newgroup = true ;
while ( 1 ) {
2022-01-08 14:59:24 +00:00
publishOperatorProfEvent ( downstream , QUERY_PROF_BEFORE_OPERATOR_EXEC ) ;
2022-04-26 12:26:32 +00:00
SSDataBlock * pBlock = downstream - > fpSet . getNextFn ( downstream , & newgroup ) ;
2022-01-08 14:59:24 +00:00
publishOperatorProfEvent ( downstream , QUERY_PROF_AFTER_OPERATOR_EXEC ) ;
2021-11-02 05:37:31 +00:00
if ( pBlock = = NULL ) {
break ;
}
2022-03-12 10:02:56 +00:00
// if (pAggInfo->current != NULL) {
// setTagValue(pOperator, pAggInfo->current->pTable, pInfo->pCtx, pOperator->numOfOutput);
// }
2021-11-02 05:37:31 +00:00
2022-04-16 02:00:25 +00:00
// there is an scalar expression that needs to be calculated before apply the group aggregation.
if ( pAggInfo - > pScalarExprInfo ! = NULL ) {
2022-04-23 10:29:45 +00:00
projectApplyFunctions ( pAggInfo - > pScalarExprInfo , pBlock , pBlock , pAggInfo - > pScalarCtx , pAggInfo - > numOfScalarExpr ,
NULL ) ;
2022-04-16 02:00:25 +00:00
}
2021-11-02 05:37:31 +00:00
// the pDataBlock are always the same one, no need to call this again
2022-04-16 11:10:21 +00:00
setExecutionContext ( pOperator - > numOfOutput , pBlock - > info . groupId , pTaskInfo , pAggInfo ) ;
2022-04-18 04:07:04 +00:00
setInputDataBlock ( pOperator , pInfo - > pCtx , pBlock , order , true ) ;
2022-03-09 02:22:53 +00:00
doAggregateImpl ( pOperator , 0 , pInfo - > pCtx ) ;
2022-03-28 03:13:59 +00:00
2022-04-23 10:29:45 +00:00
#if 0 // test for encode/decode result info
2022-04-11 09:08:13 +00:00
if ( pOperator - > encodeResultRow ) {
char * result = NULL ;
int32_t length = 0 ;
SAggSupporter * pSup = & pAggInfo - > aggSup ;
pOperator - > encodeResultRow ( pOperator , pSup , pInfo , & result , & length ) ;
taosHashClear ( pSup - > pResultRowHashTable ) ;
pInfo - > resultRowInfo . size = 0 ;
pOperator - > decodeResultRow ( pOperator , pSup , pInfo , result , length ) ;
if ( result ) {
taosMemoryFree ( result ) ;
}
2022-03-28 03:13:59 +00:00
}
2022-04-11 09:30:27 +00:00
# endif
2021-11-02 05:37:31 +00:00
}
2022-04-16 11:10:21 +00:00
closeAllResultRows ( & pAggInfo - > binfo . resultRowInfo ) ;
finalizeMultiTupleQueryResult ( pAggInfo - > binfo . pCtx , pOperator - > numOfOutput , pAggInfo - > aggSup . pResultBuf ,
& pAggInfo - > binfo . resultRowInfo , pAggInfo - > binfo . rowCellInfoOffset ) ;
2022-03-12 10:02:56 +00:00
2022-04-24 12:48:42 +00:00
initGroupedResultInfo ( & pAggInfo - > groupResInfo , pAggInfo - > aggSup . pResultRowHashTable , false ) ;
2022-03-12 10:02:56 +00:00
OPTR_SET_OPENED ( pOperator ) ;
return TSDB_CODE_SUCCESS ;
}
2022-03-29 07:24:25 +00:00
static SSDataBlock * getAggregateResult ( SOperatorInfo * pOperator , bool * newgroup ) {
SAggOperatorInfo * pAggInfo = pOperator - > info ;
2022-03-12 10:02:56 +00:00
SOptrBasicInfo * pInfo = & pAggInfo - > binfo ;
if ( pOperator - > status = = OP_EXEC_DONE ) {
return NULL ;
}
2022-03-29 07:24:25 +00:00
SExecTaskInfo * pTaskInfo = pOperator - > pTaskInfo ;
2022-04-26 12:26:32 +00:00
pTaskInfo - > code = pOperator - > fpSet . _openFn ( pOperator ) ;
2022-03-12 10:02:56 +00:00
if ( pTaskInfo - > code ! = TSDB_CODE_SUCCESS ) {
return NULL ;
}
2022-04-16 11:10:21 +00:00
blockDataEnsureCapacity ( pInfo - > pRes , pOperator - > resultInfo . capacity ) ;
2022-04-23 10:29:45 +00:00
doBuildResultDatablock ( pInfo - > pRes , & pAggInfo - > groupResInfo , pOperator - > pExpr , pAggInfo - > aggSup . pResultBuf ,
pInfo - > rowCellInfoOffset , pInfo - > pCtx ) ;
2022-04-16 11:10:21 +00:00
if ( pInfo - > pRes - > info . rows = = 0 | | ! hasRemainDataInCurrentGroup ( & pAggInfo - > groupResInfo ) ) {
doSetOperatorCompleted ( pOperator ) ;
}
2021-11-02 05:37:31 +00:00
2022-04-16 11:10:21 +00:00
doSetOperatorCompleted ( pOperator ) ;
2022-03-29 07:24:25 +00:00
return ( blockDataGetNumOfRows ( pInfo - > pRes ) ! = 0 ) ? pInfo - > pRes : NULL ;
2021-11-02 05:37:31 +00:00
}
2022-04-23 10:29:45 +00:00
void aggEncodeResultRow ( SOperatorInfo * pOperator , SAggSupporter * pSup , SOptrBasicInfo * pInfo , char * * result ,
int32_t * length ) {
2022-03-24 09:24:01 +00:00
int32_t size = taosHashGetSize ( pSup - > pResultRowHashTable ) ;
2022-04-11 09:08:13 +00:00
size_t keyLen = sizeof ( uint64_t ) * 2 ; // estimate the key length
2022-03-24 09:24:01 +00:00
int32_t totalSize = sizeof ( int32_t ) + size * ( sizeof ( int32_t ) + keyLen + sizeof ( int32_t ) + pSup - > resultRowSize ) ;
2022-03-25 16:29:53 +00:00
* result = taosMemoryCalloc ( 1 , totalSize ) ;
2022-03-29 07:24:25 +00:00
if ( * result = = NULL ) {
2022-04-11 09:08:13 +00:00
longjmp ( pOperator - > pTaskInfo - > env , TSDB_CODE_OUT_OF_MEMORY ) ;
2022-03-24 09:24:01 +00:00
}
* ( int32_t * ) ( * result ) = size ;
int32_t offset = sizeof ( int32_t ) ;
2022-04-11 09:08:13 +00:00
// prepare memory
2022-04-16 07:15:28 +00:00
SResultRowPosition * pos = & pInfo - > resultRowInfo . cur ;
2022-04-23 10:29:45 +00:00
void * pPage = getBufPage ( pSup - > pResultBuf , pos - > pageId ) ;
SResultRow * pRow = ( SResultRow * ) ( ( char * ) pPage + pos - > offset ) ;
2022-04-11 09:08:13 +00:00
setBufPageDirty ( pPage , true ) ;
releaseBufPage ( pSup - > pResultBuf , pPage ) ;
2022-04-23 10:29:45 +00:00
void * pIter = taosHashIterate ( pSup - > pResultRowHashTable , NULL ) ;
2022-03-24 09:24:01 +00:00
while ( pIter ) {
2022-04-23 10:29:45 +00:00
void * key = taosHashGetKey ( pIter , & keyLen ) ;
2022-04-11 09:30:27 +00:00
SResultRowPosition * p1 = ( SResultRowPosition * ) pIter ;
2022-04-11 09:08:13 +00:00
2022-04-23 10:29:45 +00:00
pPage = ( SFilePage * ) getBufPage ( pSup - > pResultBuf , p1 - > pageId ) ;
2022-04-11 09:30:27 +00:00
pRow = ( SResultRow * ) ( ( char * ) pPage + p1 - > offset ) ;
2022-04-11 09:08:13 +00:00
setBufPageDirty ( pPage , true ) ;
releaseBufPage ( pSup - > pResultBuf , pPage ) ;
2022-03-24 09:24:01 +00:00
// recalculate the result size
int32_t realTotalSize = offset + sizeof ( int32_t ) + keyLen + sizeof ( int32_t ) + pSup - > resultRowSize ;
2022-03-29 07:24:25 +00:00
if ( realTotalSize > totalSize ) {
char * tmp = taosMemoryRealloc ( * result , realTotalSize ) ;
if ( tmp = = NULL ) {
2022-03-24 09:24:01 +00:00
terrno = TSDB_CODE_OUT_OF_MEMORY ;
2022-03-25 16:29:53 +00:00
taosMemoryFree ( * result ) ;
2022-03-24 09:24:01 +00:00
* result = NULL ;
2022-04-11 09:08:13 +00:00
longjmp ( pOperator - > pTaskInfo - > env , TSDB_CODE_OUT_OF_MEMORY ) ;
2022-03-29 07:24:25 +00:00
} else {
2022-03-24 09:24:01 +00:00
* result = tmp ;
}
}
// save key
* ( int32_t * ) ( * result + offset ) = keyLen ;
offset + = sizeof ( int32_t ) ;
memcpy ( * result + offset , key , keyLen ) ;
offset + = keyLen ;
// save value
* ( int32_t * ) ( * result + offset ) = pSup - > resultRowSize ;
offset + = sizeof ( int32_t ) ;
2022-04-11 09:08:13 +00:00
memcpy ( * result + offset , pRow , pSup - > resultRowSize ) ;
2022-03-24 09:24:01 +00:00
offset + = pSup - > resultRowSize ;
pIter = taosHashIterate ( pSup - > pResultRowHashTable , pIter ) ;
}
2022-03-29 07:24:25 +00:00
if ( length ) {
2022-03-24 09:24:01 +00:00
* length = offset ;
}
return ;
}
2022-04-23 10:29:45 +00:00
bool aggDecodeResultRow ( SOperatorInfo * pOperator , SAggSupporter * pSup , SOptrBasicInfo * pInfo , char * result ,
int32_t length ) {
2022-03-29 07:24:25 +00:00
if ( ! result | | length < = 0 ) {
2022-03-24 09:24:01 +00:00
return false ;
}
// int32_t size = taosHashGetSize(pSup->pResultRowHashTable);
int32_t count = * ( int32_t * ) ( result ) ;
int32_t offset = sizeof ( int32_t ) ;
2022-03-29 07:24:25 +00:00
while ( count - - > 0 & & length > offset ) {
2022-03-24 09:24:01 +00:00
int32_t keyLen = * ( int32_t * ) ( result + offset ) ;
offset + = sizeof ( int32_t ) ;
2022-03-29 07:24:25 +00:00
uint64_t tableGroupId = * ( uint64_t * ) ( result + offset ) ;
SResultRow * resultRow = getNewResultRow_rv ( pSup - > pResultBuf , tableGroupId , pSup - > resultRowSize ) ;
if ( ! resultRow ) {
2022-04-11 09:08:13 +00:00
longjmp ( pOperator - > pTaskInfo - > env , TSDB_CODE_TSC_INVALID_INPUT ) ;
2022-03-24 09:24:01 +00:00
}
2022-04-18 09:32:50 +00:00
2022-03-24 09:24:01 +00:00
// add a new result set for a new group
2022-04-11 09:08:13 +00:00
SResultRowPosition pos = { . pageId = resultRow - > pageId , . offset = resultRow - > offset } ;
taosHashPut ( pSup - > pResultRowHashTable , result + offset , keyLen , & pos , sizeof ( SResultRowPosition ) ) ;
2022-03-24 09:24:01 +00:00
offset + = keyLen ;
int32_t valueLen = * ( int32_t * ) ( result + offset ) ;
2022-03-29 07:24:25 +00:00
if ( valueLen ! = pSup - > resultRowSize ) {
2022-04-11 09:08:13 +00:00
longjmp ( pOperator - > pTaskInfo - > env , TSDB_CODE_TSC_INVALID_INPUT ) ;
2022-03-24 09:24:01 +00:00
}
offset + = sizeof ( int32_t ) ;
int32_t pageId = resultRow - > pageId ;
int32_t pOffset = resultRow - > offset ;
memcpy ( resultRow , result + offset , valueLen ) ;
resultRow - > pageId = pageId ;
resultRow - > offset = pOffset ;
offset + = valueLen ;
initResultRow ( resultRow ) ;
2022-04-11 09:08:13 +00:00
prepareResultListBuffer ( & pInfo - > resultRowInfo , pOperator - > pTaskInfo - > env ) ;
2022-04-23 10:29:45 +00:00
// pInfo->resultRowInfo.cur = pInfo->resultRowInfo.size;
2022-04-25 08:44:48 +00:00
// pInfo->resultRowInfo.pPosition[pInfo->resultRowInfo.size++] =
// (SResultRowPosition){.pageId = resultRow->pageId, .offset = resultRow->offset};
2022-04-23 10:29:45 +00:00
pInfo - > resultRowInfo . cur = ( SResultRowPosition ) { . pageId = resultRow - > pageId , . offset = resultRow - > offset } ;
2022-03-24 09:24:01 +00:00
}
2022-03-29 07:24:25 +00:00
if ( offset ! = length ) {
2022-04-11 09:08:13 +00:00
longjmp ( pOperator - > pTaskInfo - > env , TSDB_CODE_TSC_INVALID_INPUT ) ;
2022-03-24 09:24:01 +00:00
}
return true ;
}
2022-04-26 05:53:11 +00:00
enum {
PROJECT_RETRIEVE_CONTINUE = 0x1 ,
PROJECT_RETRIEVE_DONE = 0x2 ,
} ;
static int32_t handleLimitOffset ( SOperatorInfo * pOperator , SSDataBlock * pBlock ) {
SProjectOperatorInfo * pProjectInfo = pOperator - > info ;
SOptrBasicInfo * pInfo = & pProjectInfo - > binfo ;
SSDataBlock * pRes = pInfo - > pRes ;
if ( pProjectInfo - > curSOffset > 0 ) {
if ( pProjectInfo - > groupId = = 0 ) { // it is the first group
pProjectInfo - > groupId = pBlock - > info . groupId ;
blockDataCleanup ( pInfo - > pRes ) ;
return PROJECT_RETRIEVE_CONTINUE ;
} else if ( pProjectInfo - > groupId ! = pBlock - > info . groupId ) {
pProjectInfo - > curSOffset - = 1 ;
// ignore data block in current group
if ( pProjectInfo - > curSOffset > 0 ) {
blockDataCleanup ( pInfo - > pRes ) ;
return PROJECT_RETRIEVE_CONTINUE ;
}
}
// set current group id of the project operator
pProjectInfo - > groupId = pBlock - > info . groupId ;
}
if ( pProjectInfo - > groupId ! = 0 & & pProjectInfo - > groupId ! = pBlock - > info . groupId ) {
pProjectInfo - > curGroupOutput + = 1 ;
if ( ( pProjectInfo - > slimit . limit > 0 ) & & ( pProjectInfo - > slimit . limit < = pProjectInfo - > curGroupOutput ) ) {
pOperator - > status = OP_EXEC_DONE ;
blockDataCleanup ( pRes ) ;
return PROJECT_RETRIEVE_DONE ;
}
// reset the value for a new group data
pProjectInfo - > curOffset = 0 ;
pProjectInfo - > curOutput = 0 ;
}
// here we reach the start position, according to the limit/offset requirements.
// set current group id
pProjectInfo - > groupId = pBlock - > info . groupId ;
if ( pProjectInfo - > curOffset > = pRes - > info . rows ) {
pProjectInfo - > curOffset - = pRes - > info . rows ;
blockDataCleanup ( pRes ) ;
return PROJECT_RETRIEVE_CONTINUE ;
} else if ( pProjectInfo - > curOffset < pRes - > info . rows & & pProjectInfo - > curOffset > 0 ) {
blockDataTrimFirstNRows ( pRes , pProjectInfo - > curOffset ) ;
pProjectInfo - > curOffset = 0 ;
}
2022-04-27 09:52:39 +00:00
// check for the limitation in each group
if ( pProjectInfo - > limit . limit > 0 & & pProjectInfo - > curOutput + pRes - > info . rows > = pProjectInfo - > limit . limit ) {
pRes - > info . rows = ( int32_t ) ( pProjectInfo - > limit . limit - pProjectInfo - > curOutput ) ;
2022-04-26 05:53:11 +00:00
2022-04-27 10:43:46 +00:00
if ( pProjectInfo - > slimit . limit = = - 1 | | pProjectInfo - > slimit . limit < = pProjectInfo - > curGroupOutput ) {
pOperator - > status = OP_EXEC_DONE ;
2022-04-26 05:53:11 +00:00
}
2022-04-27 10:12:26 +00:00
return PROJECT_RETRIEVE_DONE ;
2022-04-27 09:52:39 +00:00
}
2022-04-26 05:53:11 +00:00
2022-04-27 11:59:50 +00:00
// todo optimize performance
2022-04-27 10:43:46 +00:00
// If there are slimit/soffset value exists, multi-round result can not be packed into one group, since the
// they may not belong to the same group the limit/offset value is not valid in this case.
if ( pRes - > info . rows > = pOperator - > resultInfo . threshold | | pProjectInfo - > slimit . offset ! = - 1 | | pProjectInfo - > slimit . limit ! = - 1 ) {
2022-04-26 05:53:11 +00:00
return PROJECT_RETRIEVE_DONE ;
} else { // not full enough, continue to accumulate the output data in the buffer.
return PROJECT_RETRIEVE_CONTINUE ;
}
}
2022-03-29 07:24:25 +00:00
static SSDataBlock * doProjectOperation ( SOperatorInfo * pOperator , bool * newgroup ) {
2021-11-02 05:37:31 +00:00
SProjectOperatorInfo * pProjectInfo = pOperator - > info ;
2022-03-29 07:24:25 +00:00
SOptrBasicInfo * pInfo = & pProjectInfo - > binfo ;
2021-11-02 05:37:31 +00:00
SSDataBlock * pRes = pInfo - > pRes ;
2022-03-17 05:11:06 +00:00
blockDataCleanup ( pRes ) ;
2022-04-19 08:11:16 +00:00
if ( pOperator - > status = = OP_EXEC_DONE ) {
return NULL ;
}
2022-04-23 10:29:45 +00:00
2022-04-01 09:21:24 +00:00
#if 0
2021-11-02 05:37:31 +00:00
if ( pProjectInfo - > existDataBlock ) { // TODO refactor
SSDataBlock * pBlock = pProjectInfo - > existDataBlock ;
pProjectInfo - > existDataBlock = NULL ;
* newgroup = true ;
// todo dynamic set tags
2022-03-29 07:24:25 +00:00
// if (pTableQueryInfo != NULL) {
// setTagValue(pOperator, pTableQueryInfo->pTable, pInfo->pCtx, pOperator->numOfOutput);
// }
2021-11-02 05:37:31 +00:00
// the pDataBlock are always the same one, no need to call this again
2022-03-12 14:59:12 +00:00
setInputDataBlock ( pOperator , pInfo - > pCtx , pBlock , TSDB_ORDER_ASC ) ;
2021-11-02 05:37:31 +00:00
2022-03-18 10:02:00 +00:00
blockDataEnsureCapacity ( pInfo - > pRes , pBlock - > info . rows ) ;
2022-03-26 14:13:14 +00:00
projectApplyFunctions ( pOperator - > pExpr , pInfo - > pRes , pBlock , pInfo - > pCtx , pOperator - > numOfOutput ) ;
2022-03-29 07:24:25 +00:00
if ( pRes - > info . rows > = pProjectInfo - > binfo . capacity * 0.8 ) {
2021-11-02 05:37:31 +00:00
copyTsColoum ( pRes , pInfo - > pCtx , pOperator - > numOfOutput ) ;
resetResultRowEntryResult ( pInfo - > pCtx , pOperator - > numOfOutput ) ;
return pRes ;
}
}
2022-04-01 09:21:24 +00:00
# endif
2021-11-02 05:37:31 +00:00
2022-03-12 14:59:12 +00:00
SOperatorInfo * downstream = pOperator - > pDownstream [ 0 ] ;
2022-03-29 07:24:25 +00:00
while ( 1 ) {
2021-11-02 05:37:31 +00:00
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-03-12 14:59:12 +00:00
publishOperatorProfEvent ( downstream , QUERY_PROF_BEFORE_OPERATOR_EXEC ) ;
2022-04-26 12:26:32 +00:00
SSDataBlock * pBlock = downstream - > fpSet . getNextFn ( downstream , newgroup ) ;
2022-03-12 14:59:12 +00:00
publishOperatorProfEvent ( downstream , QUERY_PROF_AFTER_OPERATOR_EXEC ) ;
2021-11-02 05:37:31 +00:00
if ( pBlock = = NULL ) {
* 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 ;
2022-03-29 07:24:25 +00:00
} else { // init output buffer for a new group data
2021-11-02 05:37:31 +00:00
initCtxOutputBuffer ( pInfo - > pCtx , pOperator - > numOfOutput ) ;
}
}
// todo dynamic set tags
2022-03-12 14:59:12 +00:00
// STableQueryInfo* pTableQueryInfo = pRuntimeEnv->current;
// if (pTableQueryInfo != NULL) {
// setTagValue(pOperator, pTableQueryInfo->pTable, pInfo->pCtx, pOperator->numOfOutput);
// }
2021-11-02 05:37:31 +00:00
// the pDataBlock are always the same one, no need to call this again
2022-04-26 05:53:11 +00:00
int32_t order = getTableScanOrder ( pOperator - > pDownstream [ 0 ] ) ;
setInputDataBlock ( pOperator , pInfo - > pCtx , pBlock , order , false ) ;
2022-03-27 14:43:07 +00:00
blockDataEnsureCapacity ( pInfo - > pRes , pInfo - > pRes - > info . rows + pBlock - > info . rows ) ;
2022-04-23 10:29:45 +00:00
projectApplyFunctions ( pOperator - > pExpr , pInfo - > pRes , pBlock , pInfo - > pCtx , pOperator - > numOfOutput ,
pProjectInfo - > pPseudoColInfo ) ;
2022-04-01 09:21:24 +00:00
2022-04-26 05:53:11 +00:00
int32_t status = handleLimitOffset ( pOperator , pBlock ) ;
if ( status = = PROJECT_RETRIEVE_CONTINUE ) {
2022-04-01 09:21:24 +00:00
continue ;
2022-04-26 05:53:11 +00:00
} else if ( status = = PROJECT_RETRIEVE_DONE ) {
2021-11-02 05:37:31 +00:00
break ;
}
}
2022-04-23 10:29:45 +00:00
2022-04-01 09:21:24 +00:00
pProjectInfo - > curOutput + = pInfo - > pRes - > info . rows ;
2022-03-12 14:59:12 +00:00
2022-03-29 07:24:25 +00:00
// copyTsColoum(pRes, pInfo->pCtx, pOperator->numOfOutput);
return ( pInfo - > pRes - > info . rows > 0 ) ? pInfo - > pRes : NULL ;
2021-11-02 05:37:31 +00:00
}
2022-03-29 07:24:25 +00:00
static int32_t doOpenIntervalAgg ( SOperatorInfo * pOperator ) {
2022-03-15 06:37:26 +00:00
if ( OPTR_IS_OPENED ( pOperator ) ) {
return TSDB_CODE_SUCCESS ;
2021-11-02 05:37:31 +00:00
}
2022-04-23 10:29:45 +00:00
SExecTaskInfo * pTaskInfo = pOperator - > pTaskInfo ;
2022-02-24 09:18:56 +00:00
STableIntervalOperatorInfo * pInfo = pOperator - > info ;
2021-11-02 05:37:31 +00:00
2022-03-29 06:36:08 +00:00
int32_t order = TSDB_ORDER_ASC ;
2022-03-29 12:07:38 +00:00
// STimeWindow win = {0};
2022-04-23 10:29:45 +00:00
bool newgroup = false ;
2022-01-08 14:59:24 +00:00
SOperatorInfo * downstream = pOperator - > pDownstream [ 0 ] ;
2021-11-02 05:37:31 +00:00
2022-03-15 06:37:26 +00:00
while ( 1 ) {
2022-01-08 14:59:24 +00:00
publishOperatorProfEvent ( downstream , QUERY_PROF_BEFORE_OPERATOR_EXEC ) ;
2022-04-26 12:26:32 +00:00
SSDataBlock * pBlock = downstream - > fpSet . getNextFn ( downstream , & newgroup ) ;
2022-01-08 14:59:24 +00:00
publishOperatorProfEvent ( downstream , QUERY_PROF_AFTER_OPERATOR_EXEC ) ;
2021-11-02 05:37:31 +00:00
if ( pBlock = = NULL ) {
break ;
}
2022-03-15 06:37:26 +00:00
// setTagValue(pOperator, pRuntimeEnv->current->pTable, pInfo->pCtx, pOperator->numOfOutput);
2021-11-02 05:37:31 +00:00
// the pDataBlock are always the same one, no need to call this again
2022-04-18 04:07:04 +00:00
setInputDataBlock ( pOperator , pInfo - > binfo . pCtx , pBlock , order , true ) ;
2022-04-16 02:00:25 +00:00
STableQueryInfo * pTableQueryInfo = pInfo - > pCurrent ;
setIntervalQueryRange ( pTableQueryInfo , pBlock - > info . window . skey , & pTaskInfo - > window ) ;
2022-04-24 12:48:42 +00:00
hashIntervalAgg ( pOperator , & pInfo - > binfo . resultRowInfo , pBlock , pBlock - > info . groupId ) ;
2022-03-29 10:16:40 +00:00
2022-04-23 10:29:45 +00:00
#if 0 // test for encode/decode result info
2022-04-11 09:08:13 +00:00
if ( pOperator - > encodeResultRow ) {
char * result = NULL ;
int32_t length = 0 ;
SAggSupporter * pSup = & pInfo - > aggSup ;
pOperator - > encodeResultRow ( pOperator , pSup , & pInfo - > binfo , & result , & length ) ;
taosHashClear ( pSup - > pResultRowHashTable ) ;
pInfo - > binfo . resultRowInfo . size = 0 ;
pOperator - > decodeResultRow ( pOperator , pSup , & pInfo - > binfo , result , length ) ;
if ( result ) {
taosMemoryFree ( result ) ;
}
2022-03-29 10:16:40 +00:00
}
2022-04-11 09:08:13 +00:00
# endif
2021-11-02 05:37:31 +00:00
}
2022-02-24 09:18:56 +00:00
closeAllResultRows ( & pInfo - > binfo . resultRowInfo ) ;
2022-03-29 07:24:25 +00:00
finalizeMultiTupleQueryResult ( pInfo - > binfo . pCtx , pOperator - > numOfOutput , pInfo - > aggSup . pResultBuf ,
& pInfo - > binfo . resultRowInfo , pInfo - > binfo . rowCellInfoOffset ) ;
2021-11-02 05:37:31 +00:00
2022-04-24 12:48:42 +00:00
initGroupedResultInfo ( & pInfo - > groupResInfo , pInfo - > aggSup . pResultRowHashTable , true ) ;
2022-03-15 06:37:26 +00:00
OPTR_SET_OPENED ( pOperator ) ;
return TSDB_CODE_SUCCESS ;
}
2022-03-29 07:24:25 +00:00
static SSDataBlock * doBuildIntervalResult ( SOperatorInfo * pOperator , bool * newgroup ) {
2022-03-15 06:37:26 +00:00
STableIntervalOperatorInfo * pInfo = pOperator - > info ;
2022-03-29 07:24:25 +00:00
SExecTaskInfo * pTaskInfo = pOperator - > pTaskInfo ;
2022-03-15 06:37:26 +00:00
if ( pOperator - > status = = OP_EXEC_DONE ) {
return NULL ;
}
2022-04-20 06:59:06 +00:00
SSDataBlock * pBlock = pInfo - > binfo . pRes ;
2022-03-30 06:54:00 +00:00
if ( pInfo - > execModel = = OPTR_EXEC_MODEL_STREAM ) {
2022-04-26 12:26:32 +00:00
return pOperator - > fpSet . getStreamResFn ( pOperator , newgroup ) ;
2022-04-15 15:02:26 +00:00
} else {
2022-04-26 12:26:32 +00:00
pTaskInfo - > code = pOperator - > fpSet . _openFn ( pOperator ) ;
2022-04-15 15:02:26 +00:00
if ( pTaskInfo - > code ! = TSDB_CODE_SUCCESS ) {
return NULL ;
}
2022-03-30 06:54:00 +00:00
2022-04-20 06:59:06 +00:00
blockDataEnsureCapacity ( pBlock , pOperator - > resultInfo . capacity ) ;
2022-04-23 10:29:45 +00:00
doBuildResultDatablock ( pBlock , & pInfo - > groupResInfo , pOperator - > pExpr , pInfo - > aggSup . pResultBuf ,
pInfo - > binfo . rowCellInfoOffset , pInfo - > binfo . pCtx ) ;
2022-03-15 06:37:26 +00:00
2022-04-20 06:59:06 +00:00
if ( pBlock - > info . rows = = 0 | | ! hasRemainDataInCurrentGroup ( & pInfo - > groupResInfo ) ) {
2022-04-15 15:02:26 +00:00
doSetOperatorCompleted ( pOperator ) ;
}
2021-11-02 05:37:31 +00:00
2022-04-20 06:59:06 +00:00
return pBlock - > info . rows = = 0 ? NULL : pBlock ;
2021-11-02 05:37:31 +00:00
}
}
2022-04-23 10:29:45 +00:00
static SSDataBlock * doStreamIntervalAgg ( SOperatorInfo * pOperator , bool * newgroup ) {
2022-03-29 12:07:38 +00:00
STableIntervalOperatorInfo * pInfo = pOperator - > info ;
2022-04-23 10:29:45 +00:00
int32_t order = TSDB_ORDER_ASC ;
2022-03-29 12:07:38 +00:00
if ( pOperator - > status = = OP_EXEC_DONE ) {
return NULL ;
}
if ( pOperator - > status = = OP_RES_TO_RETURN ) {
2022-04-23 10:29:45 +00:00
doBuildResultDatablock ( pInfo - > binfo . pRes , & pInfo - > groupResInfo , pOperator - > pExpr , pInfo - > aggSup . pResultBuf ,
pInfo - > binfo . rowCellInfoOffset , pInfo - > binfo . pCtx ) ;
2022-03-29 12:07:38 +00:00
if ( pInfo - > binfo . pRes - > info . rows = = 0 | | ! hasRemainDataInCurrentGroup ( & pInfo - > groupResInfo ) ) {
pOperator - > status = OP_EXEC_DONE ;
}
2022-03-30 11:38:30 +00:00
return pInfo - > binfo . pRes - > info . rows = = 0 ? NULL : pInfo - > binfo . pRes ;
2022-03-29 12:07:38 +00:00
}
// STimeWindow win = {0};
2022-03-30 06:54:00 +00:00
* newgroup = false ;
2022-03-29 12:07:38 +00:00
SOperatorInfo * downstream = pOperator - > pDownstream [ 0 ] ;
SArray * pUpdated = NULL ;
while ( 1 ) {
publishOperatorProfEvent ( downstream , QUERY_PROF_BEFORE_OPERATOR_EXEC ) ;
2022-04-26 12:26:32 +00:00
SSDataBlock * pBlock = downstream - > fpSet . getNextFn ( downstream , newgroup ) ;
2022-03-29 12:07:38 +00:00
publishOperatorProfEvent ( downstream , QUERY_PROF_AFTER_OPERATOR_EXEC ) ;
if ( pBlock = = NULL ) {
break ;
}
2022-04-23 10:29:45 +00:00
// The timewindows that overlaps the timestamps of the input pBlock need to be recalculated and return to the
// caller. Note that all the time window are not close till now.
2022-03-29 12:07:38 +00:00
// setTagValue(pOperator, pRuntimeEnv->current->pTable, pInfo->pCtx, pOperator->numOfOutput);
// the pDataBlock are always the same one, no need to call this again
2022-04-18 04:07:04 +00:00
setInputDataBlock ( pOperator , pInfo - > binfo . pCtx , pBlock , order , true ) ;
2022-03-29 12:07:38 +00:00
pUpdated = hashIntervalAgg ( pOperator , & pInfo - > binfo . resultRowInfo , pBlock , 0 ) ;
}
2022-04-23 10:29:45 +00:00
finalizeUpdatedResult ( pInfo - > binfo . pCtx , pOperator - > numOfOutput , pInfo - > aggSup . pResultBuf , pUpdated ,
pInfo - > binfo . rowCellInfoOffset ) ;
2022-03-29 12:07:38 +00:00
2022-03-30 09:09:06 +00:00
initMultiResInfoFromArrayList ( & pInfo - > groupResInfo , pUpdated ) ;
2022-04-18 10:47:59 +00:00
blockDataEnsureCapacity ( pInfo - > binfo . pRes , pOperator - > resultInfo . capacity ) ;
2022-04-23 10:29:45 +00:00
doBuildResultDatablock ( pInfo - > binfo . pRes , & pInfo - > groupResInfo , pOperator - > pExpr , pInfo - > aggSup . pResultBuf ,
pInfo - > binfo . rowCellInfoOffset , pInfo - > binfo . pCtx ) ;
2022-03-29 12:07:38 +00:00
ASSERT ( pInfo - > binfo . pRes - > info . rows > 0 ) ;
pOperator - > status = OP_RES_TO_RETURN ;
return pInfo - > binfo . pRes - > info . rows = = 0 ? NULL : pInfo - > binfo . pRes ;
}
2022-04-23 10:29:45 +00:00
static SSDataBlock * doAllIntervalAgg ( SOperatorInfo * pOperator , bool * newgroup ) {
2021-11-02 05:37:31 +00:00
if ( pOperator - > status = = OP_EXEC_DONE ) {
return NULL ;
}
2022-04-10 07:35:09 +00:00
STimeSliceOperatorInfo * pSliceInfo = pOperator - > info ;
2021-11-02 05:37:31 +00:00
if ( pOperator - > status = = OP_RES_TO_RETURN ) {
2022-04-20 06:59:06 +00:00
// doBuildResultDatablock(&pRuntimeEnv->groupResInfo, pRuntimeEnv, pIntervalInfo->pRes);
2022-04-10 07:35:09 +00:00
if ( pSliceInfo - > binfo . pRes - > info . rows = = 0 | | ! hasRemainDataInCurrentGroup ( & pSliceInfo - > groupResInfo ) ) {
2021-11-02 05:37:31 +00:00
doSetOperatorCompleted ( pOperator ) ;
}
2022-04-10 07:35:09 +00:00
return pSliceInfo - > binfo . pRes ;
2021-11-02 05:37:31 +00:00
}
2022-04-23 10:29:45 +00:00
int32_t order = TSDB_ORDER_ASC ;
// 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
2022-03-29 07:24:25 +00:00
while ( 1 ) {
2022-01-08 14:59:24 +00:00
publishOperatorProfEvent ( downstream , QUERY_PROF_BEFORE_OPERATOR_EXEC ) ;
2022-04-26 12:26:32 +00:00
SSDataBlock * pBlock = downstream - > fpSet . getNextFn ( downstream , newgroup ) ;
2022-01-08 14:59:24 +00:00
publishOperatorProfEvent ( downstream , QUERY_PROF_AFTER_OPERATOR_EXEC ) ;
2021-11-02 05:37:31 +00:00
if ( pBlock = = NULL ) {
break ;
}
2022-03-29 07:24:25 +00:00
// setTagValue(pOperator, pRuntimeEnv->current->pTable, pIntervalInfo->pCtx, pOperator->numOfOutput);
2021-11-02 05:37:31 +00:00
// the pDataBlock are always the same one, no need to call this again
2022-04-18 04:07:04 +00:00
setInputDataBlock ( pOperator , pSliceInfo - > binfo . pCtx , pBlock , order , true ) ;
2022-04-23 10:29:45 +00:00
// hashAllIntervalAgg(pOperator, &pSliceInfo->binfo.resultRowInfo, pBlock, 0);
2021-11-02 05:37:31 +00:00
}
// restore the value
pOperator - > status = OP_RES_TO_RETURN ;
2022-04-10 07:35:09 +00:00
closeAllResultRows ( & pSliceInfo - > binfo . resultRowInfo ) ;
2022-01-10 11:48:21 +00:00
setTaskStatus ( pOperator - > pTaskInfo , TASK_COMPLETED ) ;
2022-04-23 10:29:45 +00:00
// finalizeQueryResult(pSliceInfo->binfo.pCtx, pOperator->numOfOutput);
2021-11-02 05:37:31 +00:00
2022-04-24 12:48:42 +00:00
// initGroupedResultInfo(&pSliceInfo->groupResInfo, &pSliceInfo->binfo.resultRowInfo);
2022-04-20 06:59:06 +00:00
// doBuildResultDatablock(&pRuntimeEnv->groupResInfo, pRuntimeEnv, pSliceInfo->pRes);
2021-11-02 05:37:31 +00:00
2022-04-10 07:35:09 +00:00
if ( pSliceInfo - > binfo . pRes - > info . rows = = 0 | | ! hasRemainDataInCurrentGroup ( & pSliceInfo - > groupResInfo ) ) {
2021-11-02 05:37:31 +00:00
pOperator - > status = OP_EXEC_DONE ;
}
2022-04-10 07:35:09 +00:00
return pSliceInfo - > binfo . pRes - > info . rows = = 0 ? NULL : pSliceInfo - > binfo . pRes ;
2021-11-02 05:37:31 +00:00
}
2022-03-29 07:24:25 +00:00
static SSDataBlock * doSTableIntervalAgg ( SOperatorInfo * pOperator , bool * newgroup ) {
2021-11-02 05:37:31 +00:00
if ( pOperator - > status = = OP_EXEC_DONE ) {
return NULL ;
}
2022-04-15 15:02:26 +00:00
SExecTaskInfo * pTaskInfo = pOperator - > pTaskInfo ;
2021-11-02 05:37:31 +00:00
2022-04-15 15:02:26 +00:00
STableIntervalOperatorInfo * pInfo = pOperator - > info ;
2021-11-02 05:37:31 +00:00
if ( pOperator - > status = = OP_RES_TO_RETURN ) {
int64_t st = taosGetTimestampUs ( ) ;
2022-04-15 15:02:26 +00:00
if ( pInfo - > binfo . pRes - > info . rows = = 0 | | ! hasRemainDataInCurrentGroup ( & pInfo - > groupResInfo ) ) {
2021-11-02 05:37:31 +00:00
doSetOperatorCompleted ( pOperator ) ;
}
2022-04-15 15:02:26 +00:00
return pInfo - > binfo . pRes - > info . rows = = 0 ? NULL : pInfo - > binfo . pRes ;
2021-11-02 05:37:31 +00:00
}
2022-01-08 14:59:24 +00:00
SOperatorInfo * downstream = pOperator - > pDownstream [ 0 ] ;
2021-11-02 05:37:31 +00:00
2022-03-29 07:24:25 +00:00
while ( 1 ) {
2022-01-08 14:59:24 +00:00
publishOperatorProfEvent ( downstream , QUERY_PROF_BEFORE_OPERATOR_EXEC ) ;
2022-04-26 12:26:32 +00:00
SSDataBlock * pBlock = downstream - > fpSet . getNextFn ( downstream , newgroup ) ;
2022-01-08 14:59:24 +00:00
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
2022-03-29 07:24:25 +00:00
// setTagValue(pOperator, pTableQueryInfo->pTable, pIntervalInfo->pCtx, pOperator->numOfOutput);
2022-04-18 04:07:04 +00:00
setInputDataBlock ( pOperator , pInfo - > binfo . pCtx , pBlock , TSDB_ORDER_ASC , true ) ;
2022-04-15 15:02:26 +00:00
STableQueryInfo * pTableQueryInfo = pInfo - > pCurrent ;
2021-11-02 05:37:31 +00:00
2022-04-15 15:02:26 +00:00
setIntervalQueryRange ( pTableQueryInfo , pBlock - > info . window . skey , & pTaskInfo - > window ) ;
2022-04-23 10:29:45 +00:00
// hashIntervalAgg(pOperator, &pTableQueryInfo->resInfo, pBlock, pBlock->info.groupId);
2021-11-02 05:37:31 +00:00
}
2022-04-15 15:02:26 +00:00
closeAllResultRows ( & pInfo - > binfo . resultRowInfo ) ;
finalizeMultiTupleQueryResult ( pInfo - > binfo . pCtx , pOperator - > numOfOutput , pInfo - > aggSup . pResultBuf ,
& pInfo - > binfo . resultRowInfo , pInfo - > binfo . rowCellInfoOffset ) ;
2021-11-02 05:37:31 +00:00
2022-04-24 12:48:42 +00:00
// initGroupedResultInfo(&pInfo->groupResInfo, &pInfo->binfo.resultRowInfo);
2022-04-15 15:02:26 +00:00
OPTR_SET_OPENED ( pOperator ) ;
2022-04-18 10:47:59 +00:00
blockDataEnsureCapacity ( pInfo - > binfo . pRes , pOperator - > resultInfo . capacity ) ;
2022-04-23 10:29:45 +00:00
doBuildResultDatablock ( pInfo - > binfo . pRes , & pInfo - > groupResInfo , pOperator - > pExpr , pInfo - > aggSup . pResultBuf ,
pInfo - > binfo . rowCellInfoOffset , pInfo - > binfo . pCtx ) ;
2022-04-15 15:02:26 +00:00
if ( pInfo - > binfo . pRes - > info . rows = = 0 | | ! hasRemainDataInCurrentGroup ( & pInfo - > groupResInfo ) ) {
doSetOperatorCompleted ( pOperator ) ;
2021-11-02 05:37:31 +00:00
}
2022-04-15 15:02:26 +00:00
return pInfo - > binfo . pRes - > info . rows = = 0 ? NULL : pInfo - > binfo . pRes ;
2021-11-02 05:37:31 +00:00
}
2022-04-09 07:01:28 +00:00
static void doStateWindowAggImpl ( SOperatorInfo * pOperator , SStateWindowOperatorInfo * pInfo , SSDataBlock * pBlock ) {
2022-04-23 10:29:45 +00:00
SExecTaskInfo * pTaskInfo = pOperator - > pTaskInfo ;
2021-11-02 05:37:31 +00:00
SOptrBasicInfo * pBInfo = & pInfo - > binfo ;
2022-04-09 07:01:28 +00:00
SColumnInfoData * pStateColInfoData = taosArrayGet ( pBlock - > pDataBlock , pInfo - > colIndex ) ;
2022-04-23 10:29:45 +00:00
int64_t gid = pBlock - > info . groupId ;
2021-11-02 05:37:31 +00:00
2022-04-09 07:01:28 +00:00
bool masterScan = true ;
int32_t numOfOutput = pOperator - > numOfOutput ;
int16_t bytes = pStateColInfoData - > info . bytes ;
int16_t type = pStateColInfoData - > info . type ;
SColumnInfoData * pColInfoData = taosArrayGet ( pBlock - > pDataBlock , 0 ) ;
TSKEY * tsList = ( TSKEY * ) pColInfoData - > pData ;
2021-11-02 05:37:31 +00:00
2022-04-09 07:01:28 +00:00
SWindowRowsSup * pRowSup = & pInfo - > winSup ;
pRowSup - > numOfRows = 0 ;
2022-04-23 10:29:45 +00:00
2022-04-09 07:01:28 +00:00
for ( int32_t j = 0 ; j < pBlock - > info . rows ; + + j ) {
if ( colDataIsNull ( pStateColInfoData , pBlock - > info . rows , j , pBlock - > pBlockAgg ) ) {
2021-11-02 05:37:31 +00:00
continue ;
}
2022-04-09 07:01:28 +00:00
char * val = colDataGetData ( pStateColInfoData , j ) ;
if ( ! pInfo - > hasKey ) {
memcpy ( pInfo - > stateKey . pData , val , bytes ) ;
pInfo - > hasKey = true ;
doKeepNewWindowStartInfo ( pRowSup , tsList , j ) ;
doKeepTuple ( pRowSup , tsList [ j ] ) ;
} else if ( memcmp ( pInfo - > stateKey . pData , val , bytes ) = = 0 ) {
doKeepTuple ( pRowSup , tsList [ j ] ) ;
if ( j = = 0 & & pRowSup - > startRowIndex ! = 0 ) {
pRowSup - > startRowIndex = 0 ;
2021-11-02 05:37:31 +00:00
}
2022-04-09 07:01:28 +00:00
} else { // a new state window started
2021-11-02 05:37:31 +00:00
SResultRow * pResult = NULL ;
2022-04-09 07:01:28 +00:00
// keep the time window for the closed time window.
STimeWindow window = pRowSup - > win ;
pRowSup - > win . ekey = pRowSup - > win . skey ;
int32_t ret = setResultOutputBufByKey_rv ( & pInfo - > binfo . resultRowInfo , pBlock - > info . uid , & window , masterScan ,
2022-04-23 10:29:45 +00:00
& pResult , gid , pInfo - > binfo . pCtx , numOfOutput ,
pInfo - > binfo . rowCellInfoOffset , & pInfo - > aggSup , pTaskInfo ) ;
2021-11-02 05:37:31 +00:00
if ( ret ! = TSDB_CODE_SUCCESS ) { // null data, too many state code
2022-04-09 07:01:28 +00:00
longjmp ( pTaskInfo - > env , TSDB_CODE_QRY_APP_ERROR ) ;
2021-11-02 05:37:31 +00:00
}
2022-04-19 02:12:30 +00:00
updateTimeWindowInfo ( & pInfo - > twAggSup . timeWindowData , & window , false ) ;
2022-04-23 10:29:45 +00:00
doApplyFunctions ( pInfo - > binfo . pCtx , & window , & pInfo - > twAggSup . timeWindowData , pRowSup - > startRowIndex ,
pRowSup - > numOfRows , NULL , pBlock - > info . rows , numOfOutput , TSDB_ORDER_ASC ) ;
2022-04-09 07:01:28 +00:00
// here we start a new session window
doKeepNewWindowStartInfo ( pRowSup , tsList , j ) ;
doKeepTuple ( pRowSup , tsList [ j ] ) ;
2021-11-02 05:37:31 +00:00
}
}
SResultRow * pResult = NULL ;
2022-04-09 07:01:28 +00:00
pRowSup - > win . ekey = tsList [ pBlock - > info . rows - 1 ] ;
2022-04-23 10:29:45 +00:00
int32_t ret = setResultOutputBufByKey_rv ( & pInfo - > binfo . resultRowInfo , pBlock - > info . uid , & pRowSup - > win , masterScan ,
& pResult , gid , pInfo - > binfo . pCtx , numOfOutput ,
pInfo - > binfo . rowCellInfoOffset , & pInfo - > aggSup , pTaskInfo ) ;
2021-11-02 05:37:31 +00:00
if ( ret ! = TSDB_CODE_SUCCESS ) { // null data, too many state code
2022-04-09 07:01:28 +00:00
longjmp ( pTaskInfo - > env , TSDB_CODE_QRY_APP_ERROR ) ;
2021-11-02 05:37:31 +00:00
}
2022-04-19 02:12:30 +00:00
updateTimeWindowInfo ( & pInfo - > twAggSup . timeWindowData , & pRowSup - > win , false ) ;
2022-04-23 10:29:45 +00:00
doApplyFunctions ( pInfo - > binfo . pCtx , & pRowSup - > win , & pInfo - > twAggSup . timeWindowData , pRowSup - > startRowIndex ,
pRowSup - > numOfRows , NULL , pBlock - > info . rows , numOfOutput , TSDB_ORDER_ASC ) ;
2021-11-02 05:37:31 +00:00
}
2022-03-29 07:24:25 +00:00
static SSDataBlock * doStateWindowAgg ( SOperatorInfo * pOperator , bool * newgroup ) {
2021-11-02 05:37:31 +00:00
if ( pOperator - > status = = OP_EXEC_DONE ) {
return NULL ;
}
2022-04-09 07:01:28 +00:00
SStateWindowOperatorInfo * pInfo = pOperator - > info ;
2022-04-23 10:29:45 +00:00
SExecTaskInfo * pTaskInfo = pOperator - > pTaskInfo ;
SOptrBasicInfo * pBInfo = & pInfo - > binfo ;
2021-11-02 05:37:31 +00:00
if ( pOperator - > status = = OP_RES_TO_RETURN ) {
2022-04-23 10:29:45 +00:00
doBuildResultDatablock ( pBInfo - > pRes , & pInfo - > groupResInfo , pOperator - > pExpr , pInfo - > aggSup . pResultBuf ,
pBInfo - > rowCellInfoOffset , pInfo - > binfo . pCtx ) ;
2022-04-09 07:01:28 +00:00
if ( pBInfo - > pRes - > info . rows = = 0 | | ! hasRemainDataInCurrentGroup ( & pInfo - > groupResInfo ) ) {
doSetOperatorCompleted ( pOperator ) ;
return NULL ;
}
2021-11-02 05:37:31 +00:00
return pBInfo - > pRes ;
}
2022-04-23 10:29:45 +00:00
int32_t order = TSDB_ORDER_ASC ;
STimeWindow win = pTaskInfo - > window ;
2022-04-01 10:08:36 +00:00
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 ) ;
2022-04-26 12:26:32 +00:00
SSDataBlock * pBlock = downstream - > fpSet . getNextFn ( downstream , newgroup ) ;
2022-01-08 14:59:24 +00:00
publishOperatorProfEvent ( downstream , QUERY_PROF_AFTER_OPERATOR_EXEC ) ;
2021-11-02 05:37:31 +00:00
if ( pBlock = = NULL ) {
break ;
}
2022-04-01 10:08:36 +00:00
2022-04-18 04:07:04 +00:00
setInputDataBlock ( pOperator , pBInfo - > pCtx , pBlock , order , true ) ;
2022-04-09 07:01:28 +00:00
doStateWindowAggImpl ( pOperator , pInfo , pBlock ) ;
2021-11-02 05:37:31 +00:00
}
pOperator - > status = OP_RES_TO_RETURN ;
closeAllResultRows ( & pBInfo - > resultRowInfo ) ;
2022-04-23 10:29:45 +00:00
finalizeMultiTupleQueryResult ( pBInfo - > pCtx , pOperator - > numOfOutput , pInfo - > aggSup . pResultBuf , & pBInfo - > resultRowInfo ,
pBInfo - > rowCellInfoOffset ) ;
2021-11-02 05:37:31 +00:00
2022-04-24 12:48:42 +00:00
initGroupedResultInfo ( & pInfo - > groupResInfo , pInfo - > aggSup . pResultRowHashTable , true ) ;
2022-04-18 10:47:59 +00:00
blockDataEnsureCapacity ( pBInfo - > pRes , pOperator - > resultInfo . capacity ) ;
2022-04-23 10:29:45 +00:00
doBuildResultDatablock ( pBInfo - > pRes , & pInfo - > groupResInfo , pOperator - > pExpr , pInfo - > aggSup . pResultBuf ,
pBInfo - > rowCellInfoOffset , pInfo - > binfo . pCtx ) ;
2022-04-09 07:01:28 +00:00
if ( pBInfo - > pRes - > info . rows = = 0 | | ! hasRemainDataInCurrentGroup ( & pInfo - > groupResInfo ) ) {
doSetOperatorCompleted ( pOperator ) ;
}
2021-11-02 05:37:31 +00:00
2022-03-29 07:24:25 +00:00
return pBInfo - > pRes - > info . rows = = 0 ? NULL : pBInfo - > pRes ;
2021-11-02 05:37:31 +00:00
}
2022-03-29 07:24:25 +00:00
static SSDataBlock * doSessionWindowAgg ( SOperatorInfo * pOperator , bool * newgroup ) {
2021-11-02 05:37:31 +00:00
if ( pOperator - > status = = OP_EXEC_DONE ) {
return NULL ;
}
2022-03-29 06:36:08 +00:00
SSessionAggOperatorInfo * pInfo = pOperator - > info ;
2022-03-29 07:24:25 +00:00
SOptrBasicInfo * pBInfo = & pInfo - > binfo ;
2021-11-02 05:37:31 +00:00
if ( pOperator - > status = = OP_RES_TO_RETURN ) {
2022-04-23 10:29:45 +00:00
doBuildResultDatablock ( pBInfo - > pRes , & pInfo - > groupResInfo , pOperator - > pExpr , pInfo - > aggSup . pResultBuf ,
pBInfo - > rowCellInfoOffset , pInfo - > binfo . pCtx ) ;
2022-03-29 06:36:08 +00:00
if ( pBInfo - > pRes - > info . rows = = 0 | | ! hasRemainDataInCurrentGroup ( & pInfo - > groupResInfo ) ) {
doSetOperatorCompleted ( pOperator ) ;
return NULL ;
2021-11-02 05:37:31 +00:00
}
return pBInfo - > pRes ;
}
2022-03-29 07:24:25 +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
2022-03-29 07:24:25 +00:00
while ( 1 ) {
2022-01-08 14:59:24 +00:00
publishOperatorProfEvent ( downstream , QUERY_PROF_BEFORE_OPERATOR_EXEC ) ;
2022-04-26 12:26:32 +00:00
SSDataBlock * pBlock = downstream - > fpSet . getNextFn ( downstream , newgroup ) ;
2022-01-08 14:59:24 +00:00
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
2022-04-18 04:07:04 +00:00
setInputDataBlock ( pOperator , pBInfo - > pCtx , pBlock , order , true ) ;
2022-03-29 06:36:08 +00:00
doSessionWindowAggImpl ( pOperator , pInfo , pBlock ) ;
2021-11-02 05:37:31 +00:00
}
// restore the value
pOperator - > status = OP_RES_TO_RETURN ;
closeAllResultRows ( & pBInfo - > resultRowInfo ) ;
2022-04-23 10:29:45 +00:00
finalizeMultiTupleQueryResult ( pBInfo - > pCtx , pOperator - > numOfOutput , pInfo - > aggSup . pResultBuf , & pBInfo - > resultRowInfo ,
pBInfo - > rowCellInfoOffset ) ;
2021-11-02 05:37:31 +00:00
2022-04-24 12:48:42 +00:00
initGroupedResultInfo ( & pInfo - > groupResInfo , pInfo - > aggSup . pResultRowHashTable , true ) ;
2022-04-18 10:47:59 +00:00
blockDataEnsureCapacity ( pBInfo - > pRes , pOperator - > resultInfo . capacity ) ;
2022-04-23 10:29:45 +00:00
doBuildResultDatablock ( pBInfo - > pRes , & pInfo - > groupResInfo , pOperator - > pExpr , pInfo - > aggSup . pResultBuf ,
pBInfo - > rowCellInfoOffset , pInfo - > binfo . pCtx ) ;
2022-03-29 06:36:08 +00:00
if ( pBInfo - > pRes - > info . rows = = 0 | | ! hasRemainDataInCurrentGroup ( & pInfo - > groupResInfo ) ) {
doSetOperatorCompleted ( pOperator ) ;
2021-11-02 05:37:31 +00:00
}
2022-03-29 07:24:25 +00:00
return pBInfo - > pRes - > info . rows = = 0 ? NULL : pBInfo - > pRes ;
2021-11-02 05:37:31 +00:00
}
2022-03-29 07:24:25 +00:00
static void doHandleRemainBlockForNewGroupImpl ( SFillOperatorInfo * pInfo , SResultInfo * pResultInfo , bool * newgroup ,
SExecTaskInfo * pTaskInfo ) {
2021-11-02 05:37:31 +00:00
pInfo - > totalInputRows = pInfo - > existNewGroupBlock - > info . rows ;
2022-03-24 06:21:14 +00:00
2022-03-29 07:24:25 +00:00
int64_t ekey = Q_STATUS_EQUAL ( pTaskInfo - > status , TASK_COMPLETED ) ? pTaskInfo - > window . ekey
: pInfo - > existNewGroupBlock - > info . window . ekey ;
2021-11-02 05:37:31 +00:00
taosResetFillInfo ( pInfo - > pFillInfo , getFillInfoStart ( pInfo - > pFillInfo ) ) ;
2022-03-24 09:26:04 +00:00
taosFillSetStartInfo ( pInfo - > pFillInfo , pInfo - > existNewGroupBlock - > info . rows , ekey ) ;
2021-11-02 05:37:31 +00:00
taosFillSetInputDataBlock ( pInfo - > pFillInfo , pInfo - > existNewGroupBlock ) ;
2022-03-24 06:21:14 +00:00
doFillTimeIntervalGapsInResults ( pInfo - > pFillInfo , pInfo - > pRes , pResultInfo - > capacity , pInfo - > p ) ;
2021-11-02 05:37:31 +00:00
pInfo - > existNewGroupBlock = NULL ;
* newgroup = true ;
}
2022-03-29 07:24:25 +00:00
static void doHandleRemainBlockFromNewGroup ( SFillOperatorInfo * pInfo , SResultInfo * pResultInfo , bool * newgroup ,
SExecTaskInfo * pTaskInfo ) {
2021-11-02 05:37:31 +00:00
if ( taosFillHasMoreResults ( pInfo - > pFillInfo ) ) {
* newgroup = false ;
2022-03-24 06:21:14 +00:00
doFillTimeIntervalGapsInResults ( pInfo - > pFillInfo , pInfo - > pRes , ( int32_t ) pResultInfo - > capacity , pInfo - > p ) ;
if ( pInfo - > pRes - > info . rows > pResultInfo - > threshold | | ( ! pInfo - > multigroupResult ) ) {
2021-11-02 05:37:31 +00:00
return ;
}
}
// handle the cached new group data block
if ( pInfo - > existNewGroupBlock ) {
2022-03-24 09:26:04 +00:00
doHandleRemainBlockForNewGroupImpl ( pInfo , pResultInfo , newgroup , pTaskInfo ) ;
2021-11-02 05:37:31 +00:00
}
}
2022-03-29 07:24:25 +00:00
static SSDataBlock * doFill ( SOperatorInfo * pOperator , bool * newgroup ) {
SFillOperatorInfo * pInfo = pOperator - > info ;
SExecTaskInfo * pTaskInfo = pOperator - > pTaskInfo ;
2021-11-02 05:37:31 +00:00
2022-03-24 03:15:05 +00:00
SResultInfo * pResultInfo = & pOperator - > resultInfo ;
2022-04-20 06:59:06 +00:00
SSDataBlock * pResBlock = pInfo - > pRes ;
blockDataCleanup ( pResBlock ) ;
2021-11-02 05:37:31 +00:00
if ( pOperator - > status = = OP_EXEC_DONE ) {
return NULL ;
}
2022-03-24 09:26:04 +00:00
doHandleRemainBlockFromNewGroup ( pInfo , pResultInfo , newgroup , pTaskInfo ) ;
2022-04-20 06:59:06 +00:00
if ( pResBlock - > info . rows > pResultInfo - > threshold | | ( ! pInfo - > multigroupResult & & pResBlock - > info . rows > 0 ) ) {
return pResBlock ;
2022-03-24 06:21:14 +00:00
}
2021-11-02 05:37:31 +00:00
2022-03-24 03:15:05 +00:00
SOperatorInfo * pDownstream = pOperator - > pDownstream [ 0 ] ;
2022-03-29 07:24:25 +00:00
while ( 1 ) {
2022-03-24 03:15:05 +00:00
publishOperatorProfEvent ( pDownstream , QUERY_PROF_BEFORE_OPERATOR_EXEC ) ;
2022-04-26 12:26:32 +00:00
SSDataBlock * pBlock = pDownstream - > fpSet . getNextFn ( pDownstream , newgroup ) ;
2022-03-24 03:15:05 +00:00
publishOperatorProfEvent ( pDownstream , 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
2022-03-24 09:26:04 +00:00
taosFillSetStartInfo ( pInfo - > pFillInfo , 0 , pTaskInfo - > window . ekey ) ;
2021-11-02 05:37:31 +00:00
} else {
if ( pBlock = = NULL ) {
if ( pInfo - > totalInputRows = = 0 ) {
pOperator - > status = OP_EXEC_DONE ;
return NULL ;
}
2022-03-24 09:26:04 +00:00
taosFillSetStartInfo ( pInfo - > pFillInfo , 0 , pTaskInfo - > window . ekey ) ;
2021-11-02 05:37:31 +00:00
} else {
pInfo - > totalInputRows + = pBlock - > info . rows ;
taosFillSetStartInfo ( pInfo - > pFillInfo , pBlock - > info . rows , pBlock - > info . window . ekey ) ;
taosFillSetInputDataBlock ( pInfo - > pFillInfo , pBlock ) ;
}
}
2022-04-20 06:59:06 +00:00
doFillTimeIntervalGapsInResults ( pInfo - > pFillInfo , pResBlock , pOperator - > resultInfo . capacity , pInfo - > p ) ;
2021-11-02 05:37:31 +00:00
// current group has no more result to return
2022-04-20 06:59:06 +00:00
if ( pResBlock - > info . rows > 0 ) {
2021-11-02 05:37:31 +00:00
// 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
2022-04-20 06:59:06 +00:00
if ( pResBlock - > info . rows > pResultInfo - > threshold | | pBlock = = NULL | | ( ! pInfo - > multigroupResult ) ) {
return pResBlock ;
2021-11-02 05:37:31 +00:00
}
2022-03-24 09:26:04 +00:00
doHandleRemainBlockFromNewGroup ( pInfo , pResultInfo , newgroup , pTaskInfo ) ;
2022-04-20 06:59:06 +00:00
if ( pResBlock - > info . rows > pOperator - > resultInfo . threshold | | pBlock = = NULL ) {
return pResBlock ;
2021-11-02 05:37:31 +00:00
}
} else if ( pInfo - > existNewGroupBlock ) { // try next group
assert ( pBlock ! = NULL ) ;
2022-03-24 09:26:04 +00:00
doHandleRemainBlockForNewGroupImpl ( pInfo , pResultInfo , newgroup , pTaskInfo ) ;
2022-04-20 06:59:06 +00:00
if ( pResBlock - > info . rows > pResultInfo - > threshold ) {
return pResBlock ;
2021-11-02 05:37:31 +00:00
}
} 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 ) {
2022-03-29 07:24:25 +00:00
for ( int32_t i = 0 ; i < pQueryAttr - > numOfOutput ; + + i ) {
2021-11-02 05:37:31 +00:00
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-04-26 12:26:32 +00:00
if ( pOperator - > fpSet . closeFn ! = NULL ) {
pOperator - > fpSet . closeFn ( 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-03-29 07:24:25 +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-03-25 16:29:53 +00:00
taosMemoryFreeClear ( pOperator - > pDownstream ) ;
2022-01-08 14:59:24 +00:00
pOperator - > numOfDownstream = 0 ;
2021-11-02 05:37:31 +00:00
}
2022-03-25 16:29:53 +00:00
taosMemoryFreeClear ( pOperator - > info ) ;
taosMemoryFreeClear ( pOperator ) ;
2021-11-02 05:37:31 +00:00
}
2022-04-23 10:29:45 +00:00
int32_t doInitAggInfoSup ( SAggSupporter * pAggSup , SqlFunctionCtx * pCtx , int32_t numOfOutput , size_t keyBufSize ,
const char * pKey ) {
2022-02-22 05:12:03 +00:00
_hash_fn_t hashFn = taosGetDefaultHashFunction ( TSDB_DATA_TYPE_BINARY ) ;
2022-04-23 10:29:45 +00:00
pAggSup - > resultRowSize = getResultRowSize ( pCtx , numOfOutput ) ;
pAggSup - > keyBuf = taosMemoryCalloc ( 1 , keyBufSize + POINTER_BYTES + sizeof ( int64_t ) ) ;
2022-02-22 05:12:03 +00:00
pAggSup - > pResultRowHashTable = taosHashInit ( 10 , hashFn , true , HASH_NO_LOCK ) ;
2022-04-25 08:44:48 +00:00
// pAggSup->pResultRowListSet = taosHashInit(100, hashFn, false, HASH_NO_LOCK);
// pAggSup->pResultRowArrayList = taosArrayInit(10, sizeof(SResultRowCell));
2022-02-22 05:12:03 +00:00
2022-04-25 08:44:48 +00:00
if ( pAggSup - > keyBuf = = NULL /*|| pAggSup->pResultRowArrayList == NULL || pAggSup->pResultRowListSet == NULL*/ | |
2022-03-15 06:37:26 +00:00
pAggSup - > pResultRowHashTable = = NULL ) {
2022-02-22 05:12:03 +00:00
return TSDB_CODE_OUT_OF_MEMORY ;
}
2022-03-15 08:51:50 +00:00
int32_t code = createDiskbasedBuf ( & pAggSup - > pResultBuf , 4096 , 4096 * 256 , pKey , " /tmp/ " ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
return code ;
}
2022-02-22 05:12:03 +00:00
return TSDB_CODE_SUCCESS ;
}
2022-03-14 06:15:26 +00:00
static void cleanupAggSup ( SAggSupporter * pAggSup ) {
2022-03-25 16:29:53 +00:00
taosMemoryFreeClear ( pAggSup - > keyBuf ) ;
2022-02-22 05:12:03 +00:00
taosHashCleanup ( pAggSup - > pResultRowHashTable ) ;
2022-04-25 08:44:48 +00:00
// taosHashCleanup(pAggSup->pResultRowListSet);
// taosArrayDestroy(pAggSup->pResultRowArrayList);
2022-03-15 08:51:50 +00:00
destroyDiskbasedBuf ( pAggSup - > pResultBuf ) ;
2022-02-22 05:12:03 +00:00
}
2022-04-04 06:54:39 +00:00
int32_t initAggInfo ( SOptrBasicInfo * pBasicInfo , SAggSupporter * pAggSup , SExprInfo * pExprInfo , int32_t numOfCols ,
2022-04-18 10:47:59 +00:00
SSDataBlock * pResultBlock , size_t keyBufSize , const char * pkey ) {
2022-04-12 09:55:17 +00:00
pBasicInfo - > pCtx = createSqlFunctionCtx ( pExprInfo , numOfCols , & pBasicInfo - > rowCellInfoOffset ) ;
2022-03-14 08:09:26 +00:00
pBasicInfo - > pRes = pResultBlock ;
2022-04-11 06:54:16 +00:00
doInitAggInfoSup ( pAggSup , pBasicInfo - > pCtx , numOfCols , keyBufSize , pkey ) ;
2022-04-22 14:43:07 +00:00
for ( int32_t i = 0 ; i < numOfCols ; + + i ) {
pBasicInfo - > pCtx [ i ] . pBuf = pAggSup - > pResultBuf ;
}
2022-04-02 06:29:43 +00:00
return TSDB_CODE_SUCCESS ;
2022-03-14 08:09:26 +00:00
}
2022-04-18 10:47:59 +00:00
void initResultSizeInfo ( SOperatorInfo * pOperator , int32_t numOfRows ) {
pOperator - > resultInfo . capacity = numOfRows ;
pOperator - > resultInfo . threshold = numOfRows * 0.75 ;
if ( pOperator - > resultInfo . threshold = = 0 ) {
pOperator - > resultInfo . capacity = numOfRows ;
}
}
2022-03-14 08:09:26 +00:00
static STableQueryInfo * initTableQueryInfo ( const STableGroupInfo * pTableGroupInfo ) {
2022-03-25 16:29:53 +00:00
STableQueryInfo * pTableQueryInfo = taosMemoryCalloc ( pTableGroupInfo - > numOfTables , sizeof ( STableQueryInfo ) ) ;
2022-03-14 08:09:26 +00:00
if ( pTableQueryInfo = = NULL ) {
return NULL ;
2022-03-14 06:15:26 +00:00
}
2022-02-14 06:39:42 +00:00
int32_t index = 0 ;
2022-03-29 07:24:25 +00:00
for ( int32_t i = 0 ; i < taosArrayGetSize ( pTableGroupInfo - > pGroupList ) ; + + i ) {
2022-02-14 06:39:42 +00:00
SArray * pa = taosArrayGetP ( pTableGroupInfo - > pGroupList , i ) ;
2022-03-29 07:24:25 +00:00
for ( int32_t j = 0 ; j < taosArrayGetSize ( pa ) ; + + j ) {
2022-02-14 06:39:42 +00:00
STableKeyInfo * pk = taosArrayGet ( pa , j ) ;
2022-03-14 08:09:26 +00:00
STableQueryInfo * pTQueryInfo = & pTableQueryInfo [ index + + ] ;
2022-04-23 10:29:45 +00:00
// pTQueryInfo->uid = pk->uid;
2022-03-29 07:24:25 +00:00
pTQueryInfo - > lastKey = pk - > lastKey ;
2022-04-23 10:29:45 +00:00
// pTQueryInfo->groupIndex = i;
2022-02-14 06:39:42 +00:00
}
}
2022-02-14 05:20:46 +00:00
STimeWindow win = { 0 , INT64_MAX } ;
2022-03-14 08:09:26 +00:00
createTableQueryInfo ( pTableQueryInfo , false , win ) ;
return pTableQueryInfo ;
2022-02-13 06:34:00 +00:00
}
2022-03-29 07:24:25 +00:00
SOperatorInfo * createAggregateOperatorInfo ( SOperatorInfo * downstream , SExprInfo * pExprInfo , int32_t numOfCols ,
2022-04-16 02:00:25 +00:00
SSDataBlock * pResultBlock , SExprInfo * pScalarExprInfo ,
2022-04-26 05:09:29 +00:00
int32_t numOfScalarExpr , SExecTaskInfo * pTaskInfo , const STableGroupInfo * pTableGroupInfo ) {
2022-03-25 16:29:53 +00:00
SAggOperatorInfo * pInfo = taosMemoryCalloc ( 1 , sizeof ( SAggOperatorInfo ) ) ;
2022-03-29 07:24:25 +00:00
SOperatorInfo * pOperator = taosMemoryCalloc ( 1 , sizeof ( SOperatorInfo ) ) ;
2022-03-14 06:15:26 +00:00
if ( pInfo = = NULL | | pOperator = = NULL ) {
goto _error ;
}
2022-02-13 06:34:00 +00:00
2022-03-14 06:15:26 +00:00
int32_t numOfRows = 1 ;
2022-04-23 10:29:45 +00:00
size_t keyBufSize = sizeof ( int64_t ) + sizeof ( int64_t ) + POINTER_BYTES ;
2022-04-18 10:47:59 +00:00
initResultSizeInfo ( pOperator , numOfRows ) ;
2022-04-23 10:29:45 +00:00
int32_t code =
initAggInfo ( & pInfo - > binfo , & pInfo - > aggSup , pExprInfo , numOfCols , pResultBlock , keyBufSize , pTaskInfo - > id . str ) ;
2022-03-14 08:09:26 +00:00
pInfo - > pTableQueryInfo = initTableQueryInfo ( pTableGroupInfo ) ;
if ( code ! = TSDB_CODE_SUCCESS | | pInfo - > pTableQueryInfo = = NULL ) {
2022-03-14 06:15:26 +00:00
goto _error ;
}
2022-02-13 06:34:00 +00:00
2022-04-16 11:10:21 +00:00
pOperator - > resultInfo . capacity = 4096 ;
pOperator - > resultInfo . threshold = 4096 * 0.75 ;
int32_t numOfGroup = 10 ; // todo replaced with true value
pInfo - > groupId = INT32_MIN ;
initResultRowInfo ( & pInfo - > binfo . resultRowInfo , numOfGroup ) ;
2022-04-16 02:00:25 +00:00
pInfo - > pScalarExprInfo = pScalarExprInfo ;
pInfo - > numOfScalarExpr = numOfScalarExpr ;
2022-04-16 02:04:33 +00:00
if ( pInfo - > pScalarExprInfo ! = NULL ) {
pInfo - > pScalarCtx = createSqlFunctionCtx ( pScalarExprInfo , numOfCols , & pInfo - > rowCellInfoOffset ) ;
}
2021-11-02 05:37:31 +00:00
2022-04-23 10:29:45 +00:00
pOperator - > name = " TableAggregate " ;
2022-02-28 09:02:43 +00:00
pOperator - > operatorType = QUERY_NODE_PHYSICAL_PLAN_AGG ;
2021-11-02 05:37:31 +00:00
pOperator - > blockingOptr = true ;
2022-04-23 10:29:45 +00:00
pOperator - > status = OP_NOT_OPENED ;
pOperator - > info = pInfo ;
pOperator - > pExpr = pExprInfo ;
pOperator - > numOfOutput = numOfCols ;
pOperator - > pTaskInfo = pTaskInfo ;
2022-04-16 11:10:21 +00:00
2022-04-26 12:26:32 +00:00
pOperator - > fpSet = createOperatorFpSet ( doOpenAggregateOptr , getAggregateResult , NULL , NULL , destroyAggOperatorInfo ,
aggEncodeResultRow , aggDecodeResultRow , NULL ) ;
2022-03-14 06:15:26 +00:00
code = appendDownstream ( pOperator , & downstream , 1 ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
goto _error ;
}
2021-11-02 05:37:31 +00:00
return pOperator ;
2022-03-29 07:24:25 +00:00
_error :
2022-03-14 06:15:26 +00:00
destroyAggOperatorInfo ( pInfo , numOfCols ) ;
2022-03-25 16:29:53 +00:00
taosMemoryFreeClear ( pInfo ) ;
taosMemoryFreeClear ( pOperator ) ;
2022-03-14 06:15:26 +00:00
pTaskInfo - > code = TSDB_CODE_OUT_OF_MEMORY ;
return NULL ;
2021-11-02 05:37:31 +00:00
}
2022-04-04 06:54:39 +00:00
void doDestroyBasicInfo ( SOptrBasicInfo * pInfo , int32_t numOfOutput ) {
2021-11-02 05:37:31 +00:00
assert ( pInfo ! = NULL ) ;
2022-03-10 03:12:44 +00:00
destroySqlFunctionCtx ( pInfo - > pCtx , numOfOutput ) ;
2022-03-25 16:29:53 +00:00
taosMemoryFreeClear ( pInfo - > rowCellInfoOffset ) ;
2021-11-02 05:37:31 +00:00
cleanupResultRowInfo ( & pInfo - > resultRowInfo ) ;
2022-02-08 10:01:21 +00:00
pInfo - > pRes = blockDataDestroy ( pInfo - > pRes ) ;
2021-11-02 05:37:31 +00:00
}
2022-03-14 06:15:26 +00:00
void destroyBasicOperatorInfo ( void * param , int32_t numOfOutput ) {
2022-03-29 07:24:25 +00:00
SOptrBasicInfo * pInfo = ( SOptrBasicInfo * ) param ;
2021-11-02 05:37:31 +00:00
doDestroyBasicInfo ( pInfo , numOfOutput ) ;
}
2022-03-14 06:15:26 +00:00
void destroyStateWindowOperatorInfo ( void * param , int32_t numOfOutput ) {
2022-03-29 07:24:25 +00:00
SStateWindowOperatorInfo * pInfo = ( SStateWindowOperatorInfo * ) param ;
2021-11-02 05:37:31 +00:00
doDestroyBasicInfo ( & pInfo - > binfo , numOfOutput ) ;
2022-04-09 07:01:28 +00:00
taosMemoryFreeClear ( pInfo - > stateKey . pData ) ;
2021-11-02 05:37:31 +00:00
}
2022-03-14 06:15:26 +00:00
void destroyAggOperatorInfo ( void * param , int32_t numOfOutput ) {
2022-03-29 07:24:25 +00:00
SAggOperatorInfo * pInfo = ( SAggOperatorInfo * ) param ;
2021-11-02 05:37:31 +00:00
doDestroyBasicInfo ( & pInfo - > binfo , numOfOutput ) ;
}
2022-03-10 03:12:44 +00:00
2022-03-14 06:15:26 +00:00
void destroyIntervalOperatorInfo ( void * param , int32_t numOfOutput ) {
2022-03-29 07:24:25 +00:00
STableIntervalOperatorInfo * pInfo = ( STableIntervalOperatorInfo * ) param ;
2022-03-14 06:15:26 +00:00
doDestroyBasicInfo ( & pInfo - > binfo , numOfOutput ) ;
cleanupAggSup ( & pInfo - > aggSup ) ;
}
void destroySWindowOperatorInfo ( void * param , int32_t numOfOutput ) {
2022-03-29 07:24:25 +00:00
SSessionAggOperatorInfo * pInfo = ( SSessionAggOperatorInfo * ) param ;
2021-11-02 05:37:31 +00:00
doDestroyBasicInfo ( & pInfo - > binfo , numOfOutput ) ;
}
2022-03-14 06:15:26 +00:00
void destroySFillOperatorInfo ( void * param , int32_t numOfOutput ) {
2022-03-29 07:24:25 +00:00
SFillOperatorInfo * pInfo = ( SFillOperatorInfo * ) param ;
2021-11-02 05:37:31 +00:00
pInfo - > pFillInfo = taosDestroyFillInfo ( pInfo - > pFillInfo ) ;
2022-02-08 10:01:21 +00:00
pInfo - > pRes = blockDataDestroy ( pInfo - > pRes ) ;
2022-03-25 16:29:53 +00:00
taosMemoryFreeClear ( pInfo - > p ) ;
2021-11-02 05:37:31 +00:00
}
2022-03-18 03:12:49 +00:00
static void destroyProjectOperatorInfo ( void * param , int32_t numOfOutput ) {
2022-03-29 07:24:25 +00:00
SProjectOperatorInfo * pInfo = ( SProjectOperatorInfo * ) param ;
2021-11-02 05:37:31 +00:00
doDestroyBasicInfo ( & pInfo - > binfo , numOfOutput ) ;
}
2022-03-18 03:12:49 +00:00
static void destroyOrderOperatorInfo ( void * param , int32_t numOfOutput ) {
2022-03-29 07:24:25 +00:00
SSortOperatorInfo * pInfo = ( SSortOperatorInfo * ) param ;
2022-02-08 10:01:21 +00:00
pInfo - > pDataBlock = blockDataDestroy ( pInfo - > pDataBlock ) ;
2022-03-28 11:08:07 +00:00
taosArrayDestroy ( pInfo - > pSortInfo ) ;
2022-04-08 06:17:32 +00:00
taosArrayDestroy ( pInfo - > inputSlotMap ) ;
2021-11-02 05:37:31 +00:00
}
2022-03-04 07:53:30 +00:00
void destroyExchangeOperatorInfo ( void * param , int32_t numOfOutput ) {
2022-03-29 07:24:25 +00:00
SExchangeInfo * pExInfo = ( SExchangeInfo * ) param ;
2022-03-04 07:53:30 +00:00
taosArrayDestroy ( pExInfo - > pSources ) ;
taosArrayDestroy ( pExInfo - > pSourceDataInfo ) ;
if ( pExInfo - > pResult ! = NULL ) {
blockDataDestroy ( pExInfo - > pResult ) ;
}
tsem_destroy ( & pExInfo - > ready ) ;
}
2022-04-06 03:01:09 +00:00
static SArray * setRowTsColumnOutputInfo ( SqlFunctionCtx * pCtx , int32_t numOfCols ) {
SArray * pList = taosArrayInit ( 4 , sizeof ( int32_t ) ) ;
2022-04-23 10:29:45 +00:00
for ( int32_t i = 0 ; i < numOfCols ; + + i ) {
2022-04-06 03:01:09 +00:00
if ( fmIsPseudoColumnFunc ( pCtx [ i ] . functionId ) ) {
taosArrayPush ( pList , & i ) ;
}
}
return pList ;
}
2022-03-29 07:24:25 +00:00
SOperatorInfo * createProjectOperatorInfo ( SOperatorInfo * downstream , SExprInfo * pExprInfo , int32_t num ,
2022-04-23 10:29:45 +00:00
SSDataBlock * pResBlock , SLimit * pLimit , SLimit * pSlimit ,
SExecTaskInfo * pTaskInfo ) {
2022-03-25 16:29:53 +00:00
SProjectOperatorInfo * pInfo = taosMemoryCalloc ( 1 , sizeof ( SProjectOperatorInfo ) ) ;
2022-03-29 07:24:25 +00:00
SOperatorInfo * pOperator = taosMemoryCalloc ( 1 , sizeof ( SOperatorInfo ) ) ;
2022-03-14 06:15:26 +00:00
if ( pInfo = = NULL | | pOperator = = NULL ) {
goto _error ;
}
2021-11-02 05:37:31 +00:00
2022-04-23 10:29:45 +00:00
pInfo - > limit = * pLimit ;
pInfo - > slimit = * pSlimit ;
pInfo - > curOffset = pLimit - > offset ;
2022-04-08 09:37:57 +00:00
pInfo - > curSOffset = pSlimit - > offset ;
2022-03-12 14:59:12 +00:00
pInfo - > binfo . pRes = pResBlock ;
2022-04-04 06:54:39 +00:00
int32_t numOfCols = num ;
int32_t numOfRows = 4096 ;
2022-04-23 10:29:45 +00:00
size_t keyBufSize = sizeof ( int64_t ) + sizeof ( int64_t ) + POINTER_BYTES ;
2022-04-18 10:47:59 +00:00
initResultSizeInfo ( pOperator , numOfRows ) ;
initAggInfo ( & pInfo - > binfo , & pInfo - > aggSup , pExprInfo , numOfCols , pResBlock , keyBufSize , pTaskInfo - > id . str ) ;
2022-04-04 06:54:39 +00:00
setFunctionResultOutput ( & pInfo - > binfo , & pInfo - > aggSup , MAIN_SCAN , pTaskInfo ) ;
2022-04-06 03:01:09 +00:00
pInfo - > pPseudoColInfo = setRowTsColumnOutputInfo ( pInfo - > binfo . pCtx , numOfCols ) ;
2021-11-02 05:37:31 +00:00
2022-04-23 10:29:45 +00:00
pOperator - > name = " ProjectOperator " ;
2022-03-12 10:02:56 +00:00
pOperator - > operatorType = QUERY_NODE_PHYSICAL_PLAN_PROJECT ;
2021-11-02 05:37:31 +00:00
pOperator - > blockingOptr = false ;
2022-04-23 10:29:45 +00:00
pOperator - > status = OP_NOT_OPENED ;
pOperator - > info = pInfo ;
pOperator - > pExpr = pExprInfo ;
pOperator - > numOfOutput = num ;
2022-04-26 12:26:32 +00:00
pOperator - > fpSet = createOperatorFpSet ( operatorDummyOpenFn , doProjectOperation , NULL , NULL , destroyProjectOperatorInfo ,
NULL , NULL , NULL ) ;
2022-03-29 07:24:25 +00:00
pOperator - > pTaskInfo = pTaskInfo ;
2022-02-22 05:12:03 +00:00
int32_t code = appendDownstream ( pOperator , & downstream , 1 ) ;
2022-03-18 10:02:00 +00:00
if ( code ! = TSDB_CODE_SUCCESS ) {
2022-03-14 06:15:26 +00:00
goto _error ;
}
2021-11-02 05:37:31 +00:00
return pOperator ;
2022-03-14 06:15:26 +00:00
2022-03-29 07:24:25 +00:00
_error :
2022-03-14 06:15:26 +00:00
pTaskInfo - > code = TSDB_CODE_OUT_OF_MEMORY ;
return NULL ;
2021-11-02 05:37:31 +00:00
}
2022-03-29 07:24:25 +00:00
SOperatorInfo * createIntervalOperatorInfo ( SOperatorInfo * downstream , SExprInfo * pExprInfo , int32_t numOfCols ,
2022-04-19 02:12:30 +00:00
SSDataBlock * pResBlock , SInterval * pInterval , int32_t primaryTsSlotId ,
2022-04-23 10:29:45 +00:00
STimeWindowAggSupp * pTwAggSupp , const STableGroupInfo * pTableGroupInfo ,
SExecTaskInfo * pTaskInfo ) {
2022-03-25 16:29:53 +00:00
STableIntervalOperatorInfo * pInfo = taosMemoryCalloc ( 1 , sizeof ( STableIntervalOperatorInfo ) ) ;
2022-03-29 07:24:25 +00:00
SOperatorInfo * pOperator = taosMemoryCalloc ( 1 , sizeof ( SOperatorInfo ) ) ;
2022-03-14 08:09:26 +00:00
if ( pInfo = = NULL | | pOperator = = NULL ) {
goto _error ;
}
2022-02-24 09:18:56 +00:00
2022-04-19 02:12:30 +00:00
pInfo - > order = TSDB_ORDER_ASC ;
pInfo - > interval = * pInterval ;
2022-04-25 01:16:37 +00:00
// pInfo->execModel = OPTR_EXEC_MODEL_STREAM;
pInfo - > execModel = pTaskInfo - > execModel ;
2022-04-19 02:12:30 +00:00
pInfo - > win = pTaskInfo - > window ;
pInfo - > twAggSup = * pTwAggSupp ;
2022-04-20 06:59:06 +00:00
pInfo - > primaryTsIndex = primaryTsSlotId ;
2022-04-06 10:26:35 +00:00
2022-03-15 06:37:26 +00:00
int32_t numOfRows = 4096 ;
2022-04-23 10:29:45 +00:00
size_t keyBufSize = sizeof ( int64_t ) + sizeof ( int64_t ) + POINTER_BYTES ;
2022-04-18 10:47:59 +00:00
initResultSizeInfo ( pOperator , numOfRows ) ;
2022-04-23 10:29:45 +00:00
int32_t code =
initAggInfo ( & pInfo - > binfo , & pInfo - > aggSup , pExprInfo , numOfCols , pResBlock , keyBufSize , pTaskInfo - > id . str ) ;
2022-04-19 02:12:30 +00:00
initExecTimeWindowInfo ( & pInfo - > twAggSup . timeWindowData , & pInfo - > win ) ;
2022-03-30 05:41:15 +00:00
2022-03-29 07:24:25 +00:00
// pInfo->pTableQueryInfo = initTableQueryInfo(pTableGroupInfo);
if ( code ! = TSDB_CODE_SUCCESS /* || pInfo->pTableQueryInfo == NULL*/ ) {
2022-03-14 08:09:26 +00:00
goto _error ;
}
2022-02-24 09:18:56 +00:00
initResultRowInfo ( & pInfo - > binfo . resultRowInfo , ( int32_t ) 1 ) ;
2021-11-02 05:37:31 +00:00
2022-04-23 10:29:45 +00:00
pOperator - > name = " TimeIntervalAggOperator " ;
2022-03-14 08:09:26 +00:00
pOperator - > operatorType = QUERY_NODE_PHYSICAL_PLAN_INTERVAL ;
2021-11-02 05:37:31 +00:00
pOperator - > blockingOptr = true ;
2022-04-23 10:29:45 +00:00
pOperator - > status = OP_NOT_OPENED ;
pOperator - > pExpr = pExprInfo ;
pOperator - > pTaskInfo = pTaskInfo ;
pOperator - > numOfOutput = numOfCols ;
pOperator - > info = pInfo ;
2022-04-26 12:26:32 +00:00
pOperator - > fpSet = createOperatorFpSet ( doOpenIntervalAgg , doBuildIntervalResult , doStreamIntervalAgg , NULL , destroyIntervalOperatorInfo ,
aggEncodeResultRow , aggDecodeResultRow , NULL ) ;
2021-11-02 05:37:31 +00:00
2022-02-24 09:18:56 +00:00
code = appendDownstream ( pOperator , & downstream , 1 ) ;
2022-03-14 08:09:26 +00:00
if ( code ! = TSDB_CODE_SUCCESS ) {
goto _error ;
}
2021-11-02 05:37:31 +00:00
return pOperator ;
2022-03-14 06:15:26 +00:00
2022-03-29 07:24:25 +00:00
_error :
2022-03-14 06:15:26 +00:00
destroyIntervalOperatorInfo ( pInfo , numOfCols ) ;
2022-03-25 16:29:53 +00:00
taosMemoryFreeClear ( pInfo ) ;
taosMemoryFreeClear ( pOperator ) ;
2022-03-14 06:15:26 +00:00
pTaskInfo - > code = code ;
return NULL ;
2021-11-02 05:37:31 +00:00
}
2022-04-26 12:26:32 +00:00
SOperatorInfo * createStreamIntervalOperatorInfo ( SOperatorInfo * downstream , SExprInfo * pExprInfo , int32_t numOfCols ,
SSDataBlock * pResBlock , SInterval * pInterval , int32_t primaryTsSlotId ,
STimeWindowAggSupp * pTwAggSupp , const STableGroupInfo * pTableGroupInfo , SExecTaskInfo * pTaskInfo ) {
STableIntervalOperatorInfo * pInfo = taosMemoryCalloc ( 1 , sizeof ( STableIntervalOperatorInfo ) ) ;
SOperatorInfo * pOperator = taosMemoryCalloc ( 1 , sizeof ( SOperatorInfo ) ) ;
if ( pInfo = = NULL | | pOperator = = NULL ) {
goto _error ;
}
pInfo - > order = TSDB_ORDER_ASC ;
pInfo - > interval = * pInterval ;
pInfo - > execModel = OPTR_EXEC_MODEL_STREAM ;
pInfo - > win = pTaskInfo - > window ;
pInfo - > twAggSup = * pTwAggSupp ;
pInfo - > primaryTsIndex = primaryTsSlotId ;
int32_t numOfRows = 4096 ;
size_t keyBufSize = sizeof ( int64_t ) + sizeof ( int64_t ) + POINTER_BYTES ;
initResultSizeInfo ( pOperator , numOfRows ) ;
int32_t code =
initAggInfo ( & pInfo - > binfo , & pInfo - > aggSup , pExprInfo , numOfCols , pResBlock , keyBufSize , pTaskInfo - > id . str ) ;
initExecTimeWindowInfo ( & pInfo - > twAggSup . timeWindowData , & pInfo - > win ) ;
// pInfo->pTableQueryInfo = initTableQueryInfo(pTableGroupInfo);
if ( code ! = TSDB_CODE_SUCCESS /* || pInfo->pTableQueryInfo == NULL*/ ) {
goto _error ;
}
initResultRowInfo ( & pInfo - > binfo . resultRowInfo , ( int32_t ) 1 ) ;
pOperator - > name = " StreamTimeIntervalAggOperator " ;
pOperator - > operatorType = QUERY_NODE_PHYSICAL_PLAN_INTERVAL ;
pOperator - > blockingOptr = true ;
pOperator - > status = OP_NOT_OPENED ;
pOperator - > pExpr = pExprInfo ;
pOperator - > pTaskInfo = pTaskInfo ;
pOperator - > numOfOutput = numOfCols ;
pOperator - > info = pInfo ;
pOperator - > fpSet = createOperatorFpSet ( doOpenIntervalAgg , doStreamIntervalAgg , doStreamIntervalAgg , NULL , destroyIntervalOperatorInfo ,
aggEncodeResultRow , aggDecodeResultRow , NULL ) ;
code = appendDownstream ( pOperator , & downstream , 1 ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
goto _error ;
}
return pOperator ;
_error :
destroyIntervalOperatorInfo ( pInfo , numOfCols ) ;
taosMemoryFreeClear ( pInfo ) ;
taosMemoryFreeClear ( pOperator ) ;
pTaskInfo - > code = code ;
return NULL ;
}
2022-04-23 10:29:45 +00:00
SOperatorInfo * createTimeSliceOperatorInfo ( SOperatorInfo * downstream , SExprInfo * pExprInfo , int32_t numOfCols ,
SSDataBlock * pResultBlock , SExecTaskInfo * pTaskInfo ) {
2022-04-10 07:35:09 +00:00
STimeSliceOperatorInfo * pInfo = taosMemoryCalloc ( 1 , sizeof ( STimeSliceOperatorInfo ) ) ;
2022-04-23 10:29:45 +00:00
SOperatorInfo * pOperator = taosMemoryCalloc ( 1 , sizeof ( SOperatorInfo ) ) ;
2022-04-10 07:35:09 +00:00
if ( pOperator = = NULL | | pInfo = = NULL ) {
goto _error ;
}
2021-11-02 05:37:31 +00:00
2022-02-24 09:18:56 +00:00
initResultRowInfo ( & pInfo - > binfo . resultRowInfo , 8 ) ;
2021-11-02 05:37:31 +00:00
2022-04-23 10:29:45 +00:00
pOperator - > name = " TimeSliceOperator " ;
2022-03-29 07:24:25 +00:00
// pOperator->operatorType = OP_AllTimeWindow;
2021-11-02 05:37:31 +00:00
pOperator - > blockingOptr = true ;
2022-04-23 10:29:45 +00:00
pOperator - > status = OP_NOT_OPENED ;
pOperator - > pExpr = pExprInfo ;
pOperator - > numOfOutput = numOfCols ;
pOperator - > info = pInfo ;
pOperator - > pTaskInfo = pTaskInfo ;
2022-04-26 12:26:32 +00:00
pOperator - > fpSet = createOperatorFpSet ( operatorDummyOpenFn , doAllIntervalAgg , NULL , NULL , destroyBasicOperatorInfo ,
NULL , NULL , NULL ) ;
2021-11-02 05:37:31 +00:00
2022-03-29 07:24:25 +00:00
int32_t code = appendDownstream ( pOperator , & downstream , 1 ) ;
2021-11-02 05:37:31 +00:00
return pOperator ;
2022-04-10 07:35:09 +00:00
2022-04-23 10:29:45 +00:00
_error :
2022-04-10 07:35:09 +00:00
taosMemoryFree ( pInfo ) ;
taosMemoryFree ( pOperator ) ;
pTaskInfo - > code = TSDB_CODE_OUT_OF_MEMORY ;
return NULL ;
2021-11-02 05:37:31 +00:00
}
2022-04-23 10:29:45 +00:00
SOperatorInfo * createStatewindowOperatorInfo ( SOperatorInfo * downstream , SExprInfo * pExpr , int32_t numOfCols ,
SSDataBlock * pResBlock , STimeWindowAggSupp * pTwAggSup ,
SExecTaskInfo * pTaskInfo ) {
2022-03-25 16:29:53 +00:00
SStateWindowOperatorInfo * pInfo = taosMemoryCalloc ( 1 , sizeof ( SStateWindowOperatorInfo ) ) ;
2022-04-23 10:29:45 +00:00
SOperatorInfo * pOperator = taosMemoryCalloc ( 1 , sizeof ( SOperatorInfo ) ) ;
2022-04-09 07:01:28 +00:00
if ( pInfo = = NULL | | pOperator = = NULL ) {
goto _error ;
}
2022-04-01 10:08:36 +00:00
2022-03-29 07:24:25 +00:00
pInfo - > colIndex = - 1 ;
2022-04-11 06:54:16 +00:00
size_t keyBufSize = sizeof ( int64_t ) + sizeof ( int64_t ) + POINTER_BYTES ;
2022-04-18 10:47:59 +00:00
initResultSizeInfo ( pOperator , 4096 ) ;
initAggInfo ( & pInfo - > binfo , & pInfo - > aggSup , pExpr , numOfCols , pResBlock , keyBufSize , pTaskInfo - > id . str ) ;
2022-02-22 05:12:03 +00:00
initResultRowInfo ( & pInfo - > binfo . resultRowInfo , 8 ) ;
2021-11-02 05:37:31 +00:00
2022-04-19 02:12:30 +00:00
pInfo - > twAggSup = * pTwAggSup ;
initExecTimeWindowInfo ( & pInfo - > twAggSup . timeWindowData , & pTaskInfo - > window ) ;
2022-04-23 10:29:45 +00:00
pOperator - > name = " StateWindowOperator " ;
2022-04-09 07:01:28 +00:00
pOperator - > operatorType = QUERY_NODE_PHYSICAL_PLAN_STATE_WINDOW ;
2021-11-02 05:37:31 +00:00
pOperator - > blockingOptr = true ;
2022-04-23 10:29:45 +00:00
pOperator - > status = OP_NOT_OPENED ;
pOperator - > pExpr = pExpr ;
pOperator - > numOfOutput = numOfCols ;
pOperator - > pTaskInfo = pTaskInfo ;
pOperator - > info = pInfo ;
2022-04-26 12:26:32 +00:00
pOperator - > fpSet = createOperatorFpSet ( operatorDummyOpenFn , doStateWindowAgg , NULL , NULL , destroyStateWindowOperatorInfo ,
aggEncodeResultRow , aggDecodeResultRow , NULL ) ;
2021-11-02 05:37:31 +00:00
2022-03-12 15:40:04 +00:00
int32_t code = appendDownstream ( pOperator , & downstream , 1 ) ;
2021-11-02 05:37:31 +00:00
return pOperator ;
2022-04-09 07:01:28 +00:00
2022-04-23 10:29:45 +00:00
_error :
2022-04-09 07:01:28 +00:00
pTaskInfo - > code = TSDB_CODE_SUCCESS ;
return NULL ;
2021-11-02 05:37:31 +00:00
}
2022-03-29 07:24:25 +00:00
SOperatorInfo * createSessionAggOperatorInfo ( SOperatorInfo * downstream , SExprInfo * pExprInfo , int32_t numOfCols ,
2022-04-23 10:29:45 +00:00
SSDataBlock * pResBlock , int64_t gap , STimeWindowAggSupp * pTwAggSupp ,
SExecTaskInfo * pTaskInfo ) {
2022-03-25 16:29:53 +00:00
SSessionAggOperatorInfo * pInfo = taosMemoryCalloc ( 1 , sizeof ( SSessionAggOperatorInfo ) ) ;
2022-03-29 07:24:25 +00:00
SOperatorInfo * pOperator = taosMemoryCalloc ( 1 , sizeof ( SOperatorInfo ) ) ;
2022-03-14 06:15:26 +00:00
if ( pInfo = = NULL | | pOperator = = NULL ) {
goto _error ;
}
2022-03-12 15:40:04 +00:00
2022-03-28 12:11:02 +00:00
int32_t numOfRows = 4096 ;
2022-04-23 10:29:45 +00:00
size_t keyBufSize = sizeof ( int64_t ) + sizeof ( int64_t ) + POINTER_BYTES ;
2022-04-18 10:47:59 +00:00
initResultSizeInfo ( pOperator , numOfRows ) ;
2022-04-23 10:29:45 +00:00
int32_t code =
initAggInfo ( & pInfo - > binfo , & pInfo - > aggSup , pExprInfo , numOfCols , pResBlock , keyBufSize , pTaskInfo - > id . str ) ;
2022-03-14 06:15:26 +00:00
if ( code ! = TSDB_CODE_SUCCESS ) {
goto _error ;
}
2021-11-02 05:37:31 +00:00
2022-04-19 02:12:30 +00:00
pInfo - > twAggSup = * pTwAggSupp ;
2022-03-14 06:15:26 +00:00
initResultRowInfo ( & pInfo - > binfo . resultRowInfo , 8 ) ;
2022-04-19 02:12:30 +00:00
initExecTimeWindowInfo ( & pInfo - > twAggSup . timeWindowData , & pTaskInfo - > window ) ;
2021-11-02 05:37:31 +00:00
2022-04-23 10:29:45 +00:00
pInfo - > gap = gap ;
pInfo - > binfo . pRes = pResBlock ;
pInfo - > winSup . prevTs = INT64_MIN ;
pInfo - > reptScan = false ;
pOperator - > name = " SessionWindowAggOperator " ;
2022-03-28 12:11:02 +00:00
pOperator - > operatorType = QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW ;
2021-11-02 05:37:31 +00:00
pOperator - > blockingOptr = true ;
2022-04-23 10:29:45 +00:00
pOperator - > status = OP_NOT_OPENED ;
pOperator - > pExpr = pExprInfo ;
pOperator - > numOfOutput = numOfCols ;
pOperator - > info = pInfo ;
2022-04-26 12:26:32 +00:00
pOperator - > fpSet = createOperatorFpSet ( operatorDummyOpenFn , doSessionWindowAgg , NULL , NULL , destroySWindowOperatorInfo ,
aggEncodeResultRow , aggDecodeResultRow , NULL ) ;
2022-04-23 10:29:45 +00:00
pOperator - > pTaskInfo = pTaskInfo ;
2021-11-02 05:37:31 +00:00
2022-03-14 06:15:26 +00:00
code = appendDownstream ( pOperator , & downstream , 1 ) ;
2021-11-02 05:37:31 +00:00
return pOperator ;
2022-03-14 06:15:26 +00:00
2022-03-29 07:24:25 +00:00
_error :
2022-03-14 06:15:26 +00:00
if ( pInfo ! = NULL ) {
destroySWindowOperatorInfo ( pInfo , numOfCols ) ;
}
2022-03-25 16:29:53 +00:00
taosMemoryFreeClear ( pInfo ) ;
taosMemoryFreeClear ( pOperator ) ;
2022-03-14 06:15:26 +00:00
pTaskInfo - > code = code ;
return NULL ;
2021-11-02 05:37:31 +00:00
}
2022-03-24 06:21:14 +00:00
static int32_t initFillInfo ( SFillOperatorInfo * pInfo , SExprInfo * pExpr , int32_t numOfCols , int64_t * fillVal ,
2022-03-29 07:24:25 +00:00
STimeWindow win , int32_t capacity , const char * id , SInterval * pInterval , int32_t fillType ) {
2022-04-20 06:59:06 +00:00
SFillColInfo * pColInfo = createFillColInfo ( pExpr , numOfCols , NULL ) ;
2022-03-24 06:21:14 +00:00
// TODO set correct time precision
STimeWindow w = TSWINDOW_INITIALIZER ;
2022-04-20 06:59:06 +00:00
getAlignQueryTimeWindow ( pInterval , TSDB_TIME_PRECISION_MILLI , win . skey , & w ) ;
2022-03-24 06:21:14 +00:00
int32_t order = TSDB_ORDER_ASC ;
2022-04-20 06:59:06 +00:00
pInfo - > pFillInfo = taosCreateFillInfo ( order , w . skey , 0 , capacity , numOfCols , pInterval , fillType , pColInfo , id ) ;
2022-03-24 06:21:14 +00:00
2022-03-25 16:29:53 +00:00
pInfo - > p = taosMemoryCalloc ( numOfCols , POINTER_BYTES ) ;
2022-03-24 06:21:14 +00:00
if ( pInfo - > pFillInfo = = NULL | | pInfo - > p = = NULL ) {
return TSDB_CODE_OUT_OF_MEMORY ;
} else {
return TSDB_CODE_SUCCESS ;
}
}
2022-03-29 07:24:25 +00:00
SOperatorInfo * createFillOperatorInfo ( SOperatorInfo * downstream , SExprInfo * pExpr , int32_t numOfCols ,
SInterval * pInterval , SSDataBlock * pResBlock , int32_t fillType , char * fillVal ,
bool multigroupResult , SExecTaskInfo * pTaskInfo ) {
2022-03-25 16:29:53 +00:00
SFillOperatorInfo * pInfo = taosMemoryCalloc ( 1 , sizeof ( SFillOperatorInfo ) ) ;
2022-03-29 07:24:25 +00:00
SOperatorInfo * pOperator = taosMemoryCalloc ( 1 , sizeof ( SOperatorInfo ) ) ;
2022-03-24 03:15:05 +00:00
2022-03-29 07:24:25 +00:00
pInfo - > pRes = pResBlock ;
2021-11-02 05:37:31 +00:00
pInfo - > multigroupResult = multigroupResult ;
2022-03-29 07:24:25 +00:00
pInfo - > intervalInfo = * pInterval ;
2021-11-02 05:37:31 +00:00
2022-04-20 06:59:06 +00:00
int32_t type = TSDB_FILL_NONE ;
switch ( fillType ) {
2022-04-23 10:29:45 +00:00
case FILL_MODE_PREV :
type = TSDB_FILL_PREV ;
break ;
case FILL_MODE_NONE :
type = TSDB_FILL_NONE ;
break ;
case FILL_MODE_NULL :
type = TSDB_FILL_NULL ;
break ;
case FILL_MODE_NEXT :
type = TSDB_FILL_NEXT ;
break ;
case FILL_MODE_VALUE :
type = TSDB_FILL_SET_VALUE ;
break ;
case FILL_MODE_LINEAR :
type = TSDB_FILL_LINEAR ;
break ;
2022-04-20 06:59:06 +00:00
default :
type = TSDB_FILL_NONE ;
}
2022-03-24 03:15:05 +00:00
SResultInfo * pResultInfo = & pOperator - > resultInfo ;
2022-04-20 06:59:06 +00:00
initResultSizeInfo ( pOperator , 4096 ) ;
int32_t code = initFillInfo ( pInfo , pExpr , numOfCols , ( int64_t * ) fillVal , pTaskInfo - > window , pResultInfo - > capacity ,
pTaskInfo - > id . str , pInterval , type ) ;
2022-03-24 09:26:04 +00:00
if ( code ! = TSDB_CODE_SUCCESS ) {
goto _error ;
}
2021-11-02 05:37:31 +00:00
2022-04-23 10:29:45 +00:00
pOperator - > name = " FillOperator " ;
2021-11-02 05:37:31 +00:00
pOperator - > blockingOptr = false ;
2022-04-23 10:29:45 +00:00
pOperator - > status = OP_NOT_OPENED ;
2022-03-29 07:24:25 +00:00
// pOperator->operatorType = OP_Fill;
2022-04-23 10:29:45 +00:00
pOperator - > pExpr = pExpr ;
pOperator - > numOfOutput = numOfCols ;
pOperator - > info = pInfo ;
2022-03-24 03:15:05 +00:00
2022-04-26 12:26:32 +00:00
pOperator - > fpSet = createOperatorFpSet ( operatorDummyOpenFn , doFill , NULL , NULL , destroySFillOperatorInfo ,
NULL , NULL , NULL ) ;
pOperator - > pTaskInfo = pTaskInfo ;
2022-03-24 09:26:04 +00:00
code = appendDownstream ( pOperator , & downstream , 1 ) ;
2021-11-02 05:37:31 +00:00
return pOperator ;
2022-03-24 06:21:14 +00:00
2022-03-29 07:24:25 +00:00
_error :
2022-03-25 16:29:53 +00:00
taosMemoryFreeClear ( pOperator ) ;
taosMemoryFreeClear ( pInfo ) ;
2022-03-24 06:21:14 +00:00
return NULL ;
2021-11-02 05:37:31 +00:00
}
2022-04-04 06:54:39 +00:00
2022-03-29 07:24:25 +00:00
static int32_t getColumnIndexInSource ( SQueriedTableInfo * pTableInfo , SExprBasicInfo * pExpr , SColumnInfo * pTagCols ) {
2021-11-02 05:37:31 +00:00
int32_t j = 0 ;
2022-03-09 02:22:53 +00:00
if ( TSDB_COL_IS_TAG ( pExpr - > pParam [ 0 ] . pCol - > type ) ) {
if ( pExpr - > pParam [ 0 ] . pCol - > colId = = TSDB_TBNAME_COLUMN_INDEX ) {
2021-11-02 05:37:31 +00:00
return TSDB_TBNAME_COLUMN_INDEX ;
}
2022-03-29 07:24:25 +00:00
while ( j < pTableInfo - > numOfTags ) {
2022-03-09 02:22:53 +00:00
if ( pExpr - > pParam [ 0 ] . pCol - > 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
}
2022-03-29 07:24:25 +00:00
bool validateExprColumnInfo ( SQueriedTableInfo * pTableInfo , SExprBasicInfo * pExpr , SColumnInfo * pTagCols ) {
2021-11-02 05:37:31 +00:00
int32_t j = getColumnIndexInSource ( pTableInfo , pExpr , pTagCols ) ;
return j ! = INT32_MIN ;
}
2022-03-29 07:24:25 +00:00
static SResSchema createResSchema ( int32_t type , int32_t bytes , int32_t slotId , int32_t scale , int32_t precision ,
const char * name ) {
2022-03-10 08:18:35 +00:00
SResSchema s = { 0 } ;
2022-04-23 10:29:45 +00:00
s . scale = scale ;
s . type = type ;
s . bytes = bytes ;
s . slotId = slotId ;
2022-03-11 15:28:43 +00:00
s . precision = precision ;
2022-03-10 08:18:35 +00:00
strncpy ( s . name , name , tListLen ( s . name ) ) ;
return s ;
}
2022-03-09 02:22:53 +00:00
2022-03-29 12:05:04 +00:00
static SColumn * createColumn ( int32_t blockId , int32_t slotId , SDataType * pType ) {
SColumn * pCol = taosMemoryCalloc ( 1 , sizeof ( SColumn ) ) ;
if ( pCol = = NULL ) {
terrno = TSDB_CODE_OUT_OF_MEMORY ;
return NULL ;
}
2022-04-23 10:29:45 +00:00
pCol - > slotId = slotId ;
pCol - > bytes = pType - > bytes ;
pCol - > type = pType - > type ;
pCol - > scale = pType - > scale ;
pCol - > precision = pType - > precision ;
2022-03-29 12:05:04 +00:00
pCol - > dataBlockId = blockId ;
return pCol ;
}
2022-03-22 08:03:42 +00:00
SExprInfo * createExprInfo ( SNodeList * pNodeList , SNodeList * pGroupKeys , int32_t * numOfExprs ) {
2022-03-12 14:59:12 +00:00
int32_t numOfFuncs = LIST_LENGTH ( pNodeList ) ;
2022-03-22 08:03:42 +00:00
int32_t numOfGroupKeys = 0 ;
if ( pGroupKeys ! = NULL ) {
numOfGroupKeys = LIST_LENGTH ( pGroupKeys ) ;
}
2022-03-09 02:22:53 +00:00
2022-03-22 08:03:42 +00:00
* numOfExprs = numOfFuncs + numOfGroupKeys ;
2022-03-25 16:29:53 +00:00
SExprInfo * pExprs = taosMemoryCalloc ( * numOfExprs , sizeof ( SExprInfo ) ) ;
2022-03-12 14:59:12 +00:00
2022-03-29 07:24:25 +00:00
for ( int32_t i = 0 ; i < ( * numOfExprs ) ; + + i ) {
2022-03-22 08:03:42 +00:00
STargetNode * pTargetNode = NULL ;
if ( i < numOfFuncs ) {
pTargetNode = ( STargetNode * ) nodesListGetNode ( pNodeList , i ) ;
} else {
pTargetNode = ( STargetNode * ) nodesListGetNode ( pGroupKeys , i - numOfFuncs ) ;
}
2022-03-09 02:22:53 +00:00
2022-04-12 09:55:17 +00:00
SExprInfo * pExp = & pExprs [ i ] ;
2022-03-09 02:22:53 +00:00
2022-03-25 16:29:53 +00:00
pExp - > pExpr = taosMemoryCalloc ( 1 , sizeof ( tExprNode ) ) ;
2022-03-09 02:22:53 +00:00
pExp - > pExpr - > _function . num = 1 ;
2022-03-22 08:03:42 +00:00
pExp - > pExpr - > _function . functionId = - 1 ;
2022-03-09 02:22:53 +00:00
2022-04-18 02:46:07 +00:00
int32_t type = nodeType ( pTargetNode - > pExpr ) ;
2022-03-22 08:03:42 +00:00
// it is a project query, or group by column
2022-04-18 02:46:07 +00:00
if ( type = = QUERY_NODE_COLUMN ) {
2022-03-26 14:17:26 +00:00
pExp - > pExpr - > nodeType = QUERY_NODE_COLUMN ;
2022-03-29 07:24:25 +00:00
SColumnNode * pColNode = ( SColumnNode * ) pTargetNode - > pExpr ;
2022-03-18 10:02:00 +00:00
2022-03-29 09:30:44 +00:00
pExp - > base . pParam = taosMemoryCalloc ( 1 , sizeof ( SFunctParam ) ) ;
pExp - > base . numOfParams = 1 ;
2022-03-18 10:02:00 +00:00
SDataType * pType = & pColNode - > node . resType ;
2022-04-23 10:29:45 +00:00
pExp - > base . resSchema = createResSchema ( pType - > type , pType - > bytes , pTargetNode - > slotId , pType - > scale ,
pType - > precision , pColNode - > colName ) ;
2022-03-29 12:05:04 +00:00
pExp - > base . pParam [ 0 ] . pCol = createColumn ( pColNode - > dataBlockId , pColNode - > slotId , pType ) ;
pExp - > base . pParam [ 0 ] . type = FUNC_PARAM_TYPE_COLUMN ;
2022-04-18 02:46:07 +00:00
} else if ( type = = QUERY_NODE_VALUE ) {
2022-04-07 10:49:33 +00:00
pExp - > pExpr - > nodeType = QUERY_NODE_VALUE ;
SValueNode * pValNode = ( SValueNode * ) pTargetNode - > pExpr ;
pExp - > base . pParam = taosMemoryCalloc ( 1 , sizeof ( SFunctParam ) ) ;
pExp - > base . numOfParams = 1 ;
SDataType * pType = & pValNode - > node . resType ;
2022-04-23 10:29:45 +00:00
pExp - > base . resSchema = createResSchema ( pType - > type , pType - > bytes , pTargetNode - > slotId , pType - > scale ,
pType - > precision , pValNode - > node . aliasName ) ;
2022-04-07 10:49:33 +00:00
pExp - > base . pParam [ 0 ] . type = FUNC_PARAM_TYPE_VALUE ;
valueNodeToVariant ( pValNode , & pExp - > base . pParam [ 0 ] . param ) ;
2022-04-18 02:46:07 +00:00
} else if ( type = = QUERY_NODE_FUNCTION ) {
2022-03-26 14:17:26 +00:00
pExp - > pExpr - > nodeType = QUERY_NODE_FUNCTION ;
2022-03-18 10:02:00 +00:00
SFunctionNode * pFuncNode = ( SFunctionNode * ) pTargetNode - > pExpr ;
SDataType * pType = & pFuncNode - > node . resType ;
2022-04-23 10:29:45 +00:00
pExp - > base . resSchema = createResSchema ( pType - > type , pType - > bytes , pTargetNode - > slotId , pType - > scale ,
pType - > precision , pFuncNode - > node . aliasName ) ;
2022-03-18 10:02:00 +00:00
2022-03-22 08:03:42 +00:00
pExp - > pExpr - > _function . functionId = pFuncNode - > funcId ;
2022-03-18 10:02:00 +00:00
pExp - > pExpr - > _function . pFunctNode = pFuncNode ;
2022-04-23 10:29:45 +00:00
strncpy ( pExp - > pExpr - > _function . functionName , pFuncNode - > functionName ,
tListLen ( pExp - > pExpr - > _function . functionName ) ) ;
2022-03-18 10:02:00 +00:00
int32_t numOfParam = LIST_LENGTH ( pFuncNode - > pParameterList ) ;
2022-03-29 09:30:44 +00:00
pExp - > base . pParam = taosMemoryCalloc ( numOfParam , sizeof ( SFunctParam ) ) ;
pExp - > base . numOfParams = numOfParam ;
2022-03-18 10:02:00 +00:00
for ( int32_t j = 0 ; j < numOfParam ; + + j ) {
2022-04-18 02:46:07 +00:00
SNode * p1 = nodesListGetNode ( pFuncNode - > pParameterList , j ) ;
2022-03-29 09:30:44 +00:00
if ( p1 - > type = = QUERY_NODE_COLUMN ) {
2022-04-23 10:29:45 +00:00
SColumnNode * pcn = ( SColumnNode * ) p1 ;
2022-03-29 09:30:44 +00:00
pExp - > base . pParam [ j ] . type = FUNC_PARAM_TYPE_COLUMN ;
2022-03-29 12:05:04 +00:00
pExp - > base . pParam [ j ] . pCol = createColumn ( pcn - > dataBlockId , pcn - > slotId , & pcn - > node . resType ) ;
2022-03-29 09:30:44 +00:00
} else if ( p1 - > type = = QUERY_NODE_VALUE ) {
SValueNode * pvn = ( SValueNode * ) p1 ;
pExp - > base . pParam [ j ] . type = FUNC_PARAM_TYPE_VALUE ;
2022-04-18 02:46:07 +00:00
valueNodeToVariant ( pvn , & pExp - > base . pParam [ j ] . param ) ;
2022-03-29 09:30:44 +00:00
}
2022-03-18 10:02:00 +00:00
}
2022-04-18 02:46:07 +00:00
} else if ( type = = QUERY_NODE_OPERATOR ) {
2022-03-26 14:17:26 +00:00
pExp - > pExpr - > nodeType = QUERY_NODE_OPERATOR ;
2022-03-29 07:24:25 +00:00
SOperatorNode * pNode = ( SOperatorNode * ) pTargetNode - > pExpr ;
2022-03-26 14:13:14 +00:00
2022-03-29 09:30:44 +00:00
pExp - > base . pParam = taosMemoryCalloc ( 1 , sizeof ( SFunctParam ) ) ;
pExp - > base . numOfParams = 1 ;
2022-03-26 14:13:14 +00:00
SDataType * pType = & pNode - > node . resType ;
2022-04-23 10:29:45 +00:00
pExp - > base . resSchema = createResSchema ( pType - > type , pType - > bytes , pTargetNode - > slotId , pType - > scale ,
pType - > precision , pNode - > node . aliasName ) ;
2022-03-26 14:13:14 +00:00
pExp - > pExpr - > _optrRoot . pRootNode = pTargetNode - > pExpr ;
} else {
ASSERT ( 0 ) ;
2022-03-09 02:22:53 +00:00
}
}
2022-03-12 14:59:12 +00:00
return pExprs ;
2022-03-09 02:22:53 +00:00
}
2022-03-30 06:54:00 +00:00
static SExecTaskInfo * createExecTaskInfo ( uint64_t queryId , uint64_t taskId , EOPTR_EXEC_MODEL model ) {
2022-03-25 16:29:53 +00:00
SExecTaskInfo * pTaskInfo = taosMemoryCalloc ( 1 , sizeof ( SExecTaskInfo ) ) ;
2022-01-10 11:48:21 +00:00
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-04-23 10:29:45 +00:00
pTaskInfo - > execModel = model ;
2022-01-25 05:42:33 +00:00
2022-03-25 16:29:53 +00:00
char * p = taosMemoryCalloc ( 1 , 128 ) ;
2022-03-29 07:24:25 +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-03-29 07:24:25 +00:00
static tsdbReaderT doCreateDataReader ( STableScanPhysiNode * pTableScanNode , SReadHandle * pHandle ,
STableGroupInfo * pTableGroupInfo , uint64_t queryId , uint64_t taskId ) ;
2022-02-04 14:41:54 +00:00
2022-03-29 07:24:25 +00:00
static int32_t doCreateTableGroup ( void * metaHandle , int32_t tableType , uint64_t tableUid , STableGroupInfo * pGroupInfo ,
uint64_t queryId , uint64_t taskId ) ;
2022-03-10 15:12:34 +00:00
static SArray * extractTableIdList ( const STableGroupInfo * pTableGroupInfo ) ;
2022-03-22 08:03:42 +00:00
static SArray * extractColumnInfo ( SNodeList * pNodeList ) ;
2022-03-29 02:08:21 +00:00
static SArray * extractColMatchInfo ( SNodeList * pNodeList , SDataBlockDescNode * pOutputNodeList , int32_t * numOfOutputCols ) ;
2022-04-09 02:18:52 +00:00
2022-04-08 06:40:02 +00:00
static SArray * createSortInfo ( SNodeList * pNodeList , SNodeList * pNodeListTarget ) ;
2022-04-08 06:17:32 +00:00
static SArray * createIndexMap ( SNodeList * pNodeList ) ;
2022-04-08 07:31:03 +00:00
static SArray * extractPartitionColInfo ( SNodeList * pNodeList ) ;
2022-04-26 05:09:29 +00:00
static int32_t initQueryTableDataCond ( SQueryTableDataCond * pCond , const STableScanPhysiNode * pTableScanNode ) ;
static SInterval extractIntervalInfo ( const STableScanPhysiNode * pTableScanNode ) {
SInterval interval = {
. interval = pTableScanNode - > interval ,
. sliding = pTableScanNode - > sliding ,
. intervalUnit = pTableScanNode - > intervalUnit ,
. slidingUnit = pTableScanNode - > slidingUnit ,
. offset = pTableScanNode - > offset ,
} ;
return interval ;
}
2022-01-20 08:02:09 +00:00
2022-03-29 12:05:04 +00:00
SOperatorInfo * createOperatorTree ( SPhysiNode * pPhyNode , SExecTaskInfo * pTaskInfo , SReadHandle * pHandle ,
2022-04-14 14:12:10 +00:00
uint64_t queryId , uint64_t taskId , STableGroupInfo * pTableGroupInfo ) {
2022-04-16 02:00:25 +00:00
int32_t type = nodeType ( pPhyNode ) ;
2022-02-28 09:02:43 +00:00
if ( pPhyNode - > pChildren = = NULL | | LIST_LENGTH ( pPhyNode - > pChildren ) = = 0 ) {
2022-04-08 02:24:35 +00:00
if ( QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN = = type ) {
2022-04-23 10:29:45 +00:00
SScanPhysiNode * pScanPhyNode = ( SScanPhysiNode * ) pPhyNode ;
STableScanPhysiNode * pTableScanNode = ( STableScanPhysiNode * ) pPhyNode ;
2022-01-20 08:02:09 +00:00
2022-04-26 05:09:29 +00:00
int32_t numOfCols = 0 ;
2022-04-15 10:25:24 +00:00
tsdbReaderT pDataReader = doCreateDataReader ( pTableScanNode , pHandle , pTableGroupInfo , ( uint64_t ) queryId , taskId ) ;
2022-04-25 08:44:48 +00:00
if ( pDataReader = = NULL & & terrno ! = 0 ) {
2022-04-25 02:22:48 +00:00
return NULL ;
}
2022-04-14 14:12:10 +00:00
2022-04-23 10:29:45 +00:00
SArray * pColList =
extractColMatchInfo ( pScanPhyNode - > pScanCols , pScanPhyNode - > node . pOutputDataBlockDesc , & numOfCols ) ;
2022-04-15 10:06:49 +00:00
SSDataBlock * pResBlock = createResDataBlock ( pScanPhyNode - > node . pOutputDataBlockDesc ) ;
2022-04-12 09:55:17 +00:00
2022-04-26 05:09:29 +00:00
SQueryTableDataCond cond = { 0 } ;
int32_t code = initQueryTableDataCond ( & cond , pTableScanNode ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
return NULL ;
}
2022-04-16 14:50:08 +00:00
2022-04-26 05:09:29 +00:00
SInterval interval = extractIntervalInfo ( pTableScanNode ) ;
return createTableScanOperatorInfo ( pDataReader , & cond , numOfCols , pTableScanNode - > dataRequired , pTableScanNode - > scanSeq , pColList ,
2022-04-25 01:16:37 +00:00
pResBlock , pScanPhyNode - > node . pConditions , & interval , pTableScanNode - > ratio , pTaskInfo ) ;
2022-04-08 02:24:35 +00:00
} else if ( QUERY_NODE_PHYSICAL_PLAN_EXCHANGE = = type ) {
2022-03-10 10:07:07 +00:00
SExchangePhysiNode * pExchange = ( SExchangePhysiNode * ) pPhyNode ;
2022-04-15 10:06:49 +00:00
SSDataBlock * pResBlock = createResDataBlock ( pExchange - > node . pOutputDataBlockDesc ) ;
2022-03-10 10:07:07 +00:00
return createExchangeOperatorInfo ( pExchange - > pSrcEndPoints , pResBlock , pTaskInfo ) ;
2022-04-08 02:24:35 +00:00
} else if ( QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN = = type ) {
2022-03-10 08:18:35 +00:00
SScanPhysiNode * pScanPhyNode = ( SScanPhysiNode * ) pPhyNode ; // simple child table.
2022-03-10 15:12:34 +00:00
2022-04-25 02:22:48 +00:00
int32_t code = doCreateTableGroup ( pHandle - > meta , pScanPhyNode - > tableType , pScanPhyNode - > uid , pTableGroupInfo , queryId , taskId ) ;
2022-03-24 06:21:14 +00:00
SArray * tableIdList = extractTableIdList ( pTableGroupInfo ) ;
2022-02-17 10:16:50 +00:00
2022-04-15 10:06:49 +00:00
SSDataBlock * pResBlock = createResDataBlock ( pScanPhyNode - > node . pOutputDataBlockDesc ) ;
2022-03-30 11:38:30 +00:00
int32_t numOfCols = 0 ;
2022-04-25 02:22:48 +00:00
SArray * pCols = extractColMatchInfo ( pScanPhyNode - > pScanCols , pScanPhyNode - > node . pOutputDataBlockDesc , & numOfCols ) ;
SOperatorInfo * pOperator = createStreamScanOperatorInfo ( pHandle - > reader , pResBlock , pCols , tableIdList , pTaskInfo ) ;
2022-03-10 15:12:34 +00:00
taosArrayDestroy ( tableIdList ) ;
2022-01-27 10:48:12 +00:00
return pOperator ;
2022-04-08 02:24:35 +00:00
} else if ( QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN = = type ) {
2022-03-29 07:24:25 +00:00
SSystemTableScanPhysiNode * pSysScanPhyNode = ( SSystemTableScanPhysiNode * ) pPhyNode ;
2022-04-26 05:09:29 +00:00
SScanPhysiNode * pScanNode = & pSysScanPhyNode - > scan ;
2022-03-11 11:29:43 +00:00
2022-04-26 05:09:29 +00:00
SSDataBlock * pResBlock = createResDataBlock ( pScanNode - > node . pOutputDataBlockDesc ) ;
2022-03-18 16:13:07 +00:00
2022-04-27 08:37:19 +00:00
int32_t numOfOutputCols = 0 ;
SArray * colList = extractColMatchInfo ( pScanNode - > pScanCols , pScanNode - > node . pOutputDataBlockDesc , & numOfOutputCols ) ;
2022-03-29 07:24:25 +00:00
SOperatorInfo * pOperator = createSysTableScanOperatorInfo (
2022-04-27 07:17:15 +00:00
pHandle , pResBlock , & pScanNode - > tableName , pScanNode - > node . pConditions , pSysScanPhyNode - > mgmtEpSet ,
2022-03-29 07:24:25 +00:00
colList , pTaskInfo , pSysScanPhyNode - > showRewrite , pSysScanPhyNode - > accountId ) ;
2022-03-11 11:29:43 +00:00
return pOperator ;
} else {
ASSERT ( 0 ) ;
2022-01-20 05:52:46 +00:00
}
}
2022-04-14 14:12:10 +00:00
int32_t num = 0 ;
size_t size = LIST_LENGTH ( pPhyNode - > pChildren ) ;
2022-03-12 14:59:12 +00:00
2022-04-14 14:12:10 +00:00
SOperatorInfo * * ops = taosMemoryCalloc ( size , POINTER_BYTES ) ;
2022-04-23 10:29:45 +00:00
for ( int32_t i = 0 ; i < size ; + + i ) {
2022-04-14 14:12:10 +00:00
SPhysiNode * pChildNode = ( SPhysiNode * ) nodesListGetNode ( pPhyNode - > pChildren , i ) ;
ops [ i ] = createOperatorTree ( pChildNode , pTaskInfo , pHandle , queryId , taskId , pTableGroupInfo ) ;
2022-04-25 02:22:48 +00:00
if ( ops [ i ] = = NULL ) {
return NULL ;
}
2022-04-14 14:12:10 +00:00
}
2022-03-12 14:59:12 +00:00
2022-04-15 04:09:27 +00:00
SOperatorInfo * pOptr = NULL ;
2022-04-08 02:24:35 +00:00
if ( QUERY_NODE_PHYSICAL_PLAN_PROJECT = = type ) {
2022-04-23 10:29:45 +00:00
SProjectPhysiNode * pProjPhyNode = ( SProjectPhysiNode * ) pPhyNode ;
SExprInfo * pExprInfo = createExprInfo ( pProjPhyNode - > pProjections , NULL , & num ) ;
2022-04-01 09:21:24 +00:00
2022-04-15 10:06:49 +00:00
SSDataBlock * pResBlock = createResDataBlock ( pPhyNode - > pOutputDataBlockDesc ) ;
2022-04-23 10:29:45 +00:00
SLimit limit = { . limit = pProjPhyNode - > limit , . offset = pProjPhyNode - > offset } ;
SLimit slimit = { . limit = pProjPhyNode - > slimit , . offset = pProjPhyNode - > soffset } ;
2022-04-15 04:09:27 +00:00
pOptr = createProjectOperatorInfo ( ops [ 0 ] , pExprInfo , num , pResBlock , & limit , & slimit , pTaskInfo ) ;
2022-04-08 02:24:35 +00:00
} else if ( QUERY_NODE_PHYSICAL_PLAN_AGG = = type ) {
SAggPhysiNode * pAggNode = ( SAggPhysiNode * ) pPhyNode ;
SExprInfo * pExprInfo = createExprInfo ( pAggNode - > pAggFuncs , pAggNode - > pGroupKeys , & num ) ;
2022-04-15 10:06:49 +00:00
SSDataBlock * pResBlock = createResDataBlock ( pPhyNode - > pOutputDataBlockDesc ) ;
2022-03-09 02:22:53 +00:00
2022-04-23 10:29:45 +00:00
int32_t numOfScalarExpr = 0 ;
2022-04-16 02:00:25 +00:00
SExprInfo * pScalarExprInfo = NULL ;
if ( pAggNode - > pExprs ! = NULL ) {
pScalarExprInfo = createExprInfo ( pAggNode - > pExprs , NULL , & numOfScalarExpr ) ;
}
2022-04-08 02:24:35 +00:00
if ( pAggNode - > pGroupKeys ! = NULL ) {
SArray * pColList = extractColumnInfo ( pAggNode - > pGroupKeys ) ;
2022-04-23 10:29:45 +00:00
pOptr = createGroupOperatorInfo ( ops [ 0 ] , pExprInfo , num , pResBlock , pColList , pAggNode - > node . pConditions ,
pScalarExprInfo , numOfScalarExpr , pTaskInfo , NULL ) ;
2022-04-08 02:24:35 +00:00
} else {
2022-04-23 10:29:45 +00:00
pOptr = createAggregateOperatorInfo ( ops [ 0 ] , pExprInfo , num , pResBlock , pScalarExprInfo , numOfScalarExpr ,
pTaskInfo , pTableGroupInfo ) ;
2022-03-14 08:09:26 +00:00
}
2022-04-08 02:24:35 +00:00
} else if ( QUERY_NODE_PHYSICAL_PLAN_INTERVAL = = type ) {
SIntervalPhysiNode * pIntervalPhyNode = ( SIntervalPhysiNode * ) pPhyNode ;
2022-03-28 11:08:07 +00:00
2022-04-08 02:24:35 +00:00
SExprInfo * pExprInfo = createExprInfo ( pIntervalPhyNode - > window . pFuncs , NULL , & num ) ;
2022-04-15 10:06:49 +00:00
SSDataBlock * pResBlock = createResDataBlock ( pPhyNode - > pOutputDataBlockDesc ) ;
2022-03-28 11:08:07 +00:00
2022-04-23 10:29:45 +00:00
SInterval interval = { . interval = pIntervalPhyNode - > interval ,
. sliding = pIntervalPhyNode - > sliding ,
. intervalUnit = pIntervalPhyNode - > intervalUnit ,
. slidingUnit = pIntervalPhyNode - > slidingUnit ,
. offset = pIntervalPhyNode - > offset ,
. precision = ( ( SColumnNode * ) pIntervalPhyNode - > window . pTspk ) - > node . resType . precision } ;
2022-04-08 02:24:35 +00:00
2022-04-23 10:29:45 +00:00
STimeWindowAggSupp as = { . waterMark = pIntervalPhyNode - > window . watermark ,
. calTrigger = pIntervalPhyNode - > window . triggerType } ;
2022-04-19 02:12:30 +00:00
2022-04-23 10:29:45 +00:00
int32_t primaryTsSlotId = ( ( SColumnNode * ) pIntervalPhyNode - > window . pTspk ) - > slotId ;
pOptr = createIntervalOperatorInfo ( ops [ 0 ] , pExprInfo , num , pResBlock , & interval , primaryTsSlotId , & as ,
pTableGroupInfo , pTaskInfo ) ;
2022-04-20 06:59:06 +00:00
if ( pIntervalPhyNode - > pFill ! = NULL ) {
2022-04-23 10:29:45 +00:00
pOptr = createFillOperatorInfo ( pOptr , pExprInfo , num , & interval , pResBlock , pIntervalPhyNode - > pFill - > mode , NULL ,
false , pTaskInfo ) ;
2022-04-20 06:59:06 +00:00
}
2022-04-08 02:24:35 +00:00
} else if ( QUERY_NODE_PHYSICAL_PLAN_SORT = = type ) {
2022-03-28 12:11:02 +00:00
SSortPhysiNode * pSortPhyNode = ( SSortPhysiNode * ) pPhyNode ;
2022-03-28 11:08:07 +00:00
2022-04-15 10:06:49 +00:00
SSDataBlock * pResBlock = createResDataBlock ( pPhyNode - > pOutputDataBlockDesc ) ;
2022-04-08 06:40:02 +00:00
SArray * info = createSortInfo ( pSortPhyNode - > pSortKeys , pSortPhyNode - > pTargets ) ;
2022-04-08 06:17:32 +00:00
SArray * slotMap = createIndexMap ( pSortPhyNode - > pTargets ) ;
2022-04-15 04:09:27 +00:00
pOptr = createSortOperatorInfo ( ops [ 0 ] , pResBlock , info , slotMap , pTaskInfo ) ;
2022-04-08 02:24:35 +00:00
} else if ( QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW = = type ) {
2022-03-28 12:11:02 +00:00
SSessionWinodwPhysiNode * pSessionNode = ( SSessionWinodwPhysiNode * ) pPhyNode ;
2022-04-23 10:29:45 +00:00
STimeWindowAggSupp as = { . waterMark = pSessionNode - > window . watermark ,
. calTrigger = pSessionNode - > window . triggerType } ;
2022-04-19 02:12:30 +00:00
2022-03-28 12:11:02 +00:00
SExprInfo * pExprInfo = createExprInfo ( pSessionNode - > window . pFuncs , NULL , & num ) ;
2022-04-15 10:06:49 +00:00
SSDataBlock * pResBlock = createResDataBlock ( pPhyNode - > pOutputDataBlockDesc ) ;
2022-04-19 02:12:30 +00:00
pOptr = createSessionAggOperatorInfo ( ops [ 0 ] , pExprInfo , num , pResBlock , pSessionNode - > gap , & as , pTaskInfo ) ;
2022-04-08 02:24:35 +00:00
} else if ( QUERY_NODE_PHYSICAL_PLAN_PARTITION = = type ) {
2022-04-23 10:29:45 +00:00
SPartitionPhysiNode * pPartNode = ( SPartitionPhysiNode * ) pPhyNode ;
SArray * pColList = extractPartitionColInfo ( pPartNode - > pPartitionKeys ) ;
SSDataBlock * pResBlock = createResDataBlock ( pPhyNode - > pOutputDataBlockDesc ) ;
2022-04-08 07:31:03 +00:00
SExprInfo * pExprInfo = createExprInfo ( pPartNode - > pTargets , NULL , & num ) ;
2022-04-15 04:09:27 +00:00
pOptr = createPartitionOperatorInfo ( ops [ 0 ] , pExprInfo , num , pResBlock , pColList , pTaskInfo , NULL ) ;
2022-04-14 14:12:10 +00:00
} else if ( QUERY_NODE_PHYSICAL_PLAN_STATE_WINDOW = = type ) {
2022-04-23 10:29:45 +00:00
SStateWinodwPhysiNode * pStateNode = ( SStateWinodwPhysiNode * ) pPhyNode ;
2022-04-09 07:01:28 +00:00
2022-04-19 02:12:30 +00:00
STimeWindowAggSupp as = { . waterMark = pStateNode - > window . watermark , . calTrigger = pStateNode - > window . triggerType } ;
2022-04-23 10:29:45 +00:00
SExprInfo * pExprInfo = createExprInfo ( pStateNode - > window . pFuncs , NULL , & num ) ;
2022-04-15 10:06:49 +00:00
SSDataBlock * pResBlock = createResDataBlock ( pPhyNode - > pOutputDataBlockDesc ) ;
2022-04-19 02:12:30 +00:00
pOptr = createStatewindowOperatorInfo ( ops [ 0 ] , pExprInfo , num , pResBlock , & as , pTaskInfo ) ;
2022-04-14 14:12:10 +00:00
} else if ( QUERY_NODE_PHYSICAL_PLAN_JOIN = = type ) {
2022-04-23 10:29:45 +00:00
SJoinPhysiNode * pJoinNode = ( SJoinPhysiNode * ) pPhyNode ;
SSDataBlock * pResBlock = createResDataBlock ( pPhyNode - > pOutputDataBlockDesc ) ;
2022-04-14 14:12:10 +00:00
SExprInfo * pExprInfo = createExprInfo ( pJoinNode - > pTargets , NULL , & num ) ;
2022-04-15 04:09:27 +00:00
pOptr = createJoinOperatorInfo ( ops , size , pExprInfo , num , pResBlock , pJoinNode - > pOnConditions , pTaskInfo ) ;
2022-03-28 11:08:07 +00:00
} else {
ASSERT ( 0 ) ;
2022-04-16 11:10:21 +00:00
}
2022-04-15 04:09:27 +00:00
taosMemoryFree ( ops ) ;
return pOptr ;
2022-01-10 11:48:21 +00:00
}
2022-01-08 14:59:24 +00:00
2022-04-26 05:09:29 +00:00
static int32_t initQueryTableDataCond ( SQueryTableDataCond * pCond , const STableScanPhysiNode * pTableScanNode ) {
pCond - > loadExternalRows = false ;
pCond - > order = pTableScanNode - > scanSeq [ 0 ] > 0 ? TSDB_ORDER_ASC : TSDB_ORDER_DESC ;
pCond - > numOfCols = LIST_LENGTH ( pTableScanNode - > scan . pScanCols ) ;
pCond - > colList = taosMemoryCalloc ( pCond - > numOfCols , sizeof ( SColumnInfo ) ) ;
if ( pCond - > colList = = NULL ) {
2022-01-28 02:44:02 +00:00
terrno = TSDB_CODE_QRY_OUT_OF_MEMORY ;
2022-04-26 05:09:29 +00:00
return terrno ;
}
pCond - > twindow = pTableScanNode - > scanRange ;
# if 1
//todo work around a problem, remove it later
if ( ( pCond - > order = = TSDB_ORDER_ASC & & pCond - > twindow . skey > pCond - > twindow . ekey ) | |
( pCond - > order = = TSDB_ORDER_DESC & & pCond - > twindow . skey < pCond - > twindow . ekey ) ) {
2022-04-27 09:39:54 +00:00
TSWAP ( pCond - > twindow . skey , pCond - > twindow . ekey ) ;
2022-01-28 02:44:02 +00:00
}
2022-04-26 05:09:29 +00:00
# endif
2022-01-28 02:44:02 +00:00
2022-04-26 05:09:29 +00:00
pCond - > type = BLOCK_LOAD_OFFSET_SEQ_ORDER ;
// pCond->type = pTableScanNode->scanFlag;
2022-01-19 06:47:53 +00:00
2022-03-10 11:14:36 +00:00
int32_t j = 0 ;
2022-04-26 05:09:29 +00:00
for ( int32_t i = 0 ; i < pCond - > numOfCols ; + + i ) {
2022-03-04 11:21:30 +00:00
STargetNode * pNode = ( STargetNode * ) nodesListGetNode ( pTableScanNode - > scan . pScanCols , i ) ;
SColumnNode * pColNode = ( SColumnNode * ) pNode - > pExpr ;
2022-03-10 11:14:36 +00:00
if ( pColNode - > colType = = COLUMN_TYPE_TAG ) {
continue ;
}
2022-01-20 08:02:09 +00:00
2022-04-26 05:09:29 +00:00
pCond - > colList [ j ] . type = pColNode - > node . resType . type ;
pCond - > colList [ j ] . bytes = pColNode - > node . resType . bytes ;
pCond - > colList [ j ] . colId = pColNode - > colId ;
2022-03-10 11:14:36 +00:00
j + = 1 ;
2022-01-20 08:02:09 +00:00
}
2022-04-26 05:09:29 +00:00
pCond - > numOfCols = j ;
return TSDB_CODE_SUCCESS ;
2022-01-20 08:02:09 +00:00
}
2022-01-11 15:16:45 +00:00
2022-03-22 08:03:42 +00:00
SArray * extractColumnInfo ( SNodeList * pNodeList ) {
2022-03-29 07:24:25 +00:00
size_t numOfCols = LIST_LENGTH ( pNodeList ) ;
2022-03-22 08:03:42 +00:00
SArray * pList = taosArrayInit ( numOfCols , sizeof ( SColumn ) ) ;
if ( pList = = NULL ) {
terrno = TSDB_CODE_OUT_OF_MEMORY ;
return NULL ;
}
2022-03-29 07:24:25 +00:00
for ( int32_t i = 0 ; i < numOfCols ; + + i ) {
STargetNode * pNode = ( STargetNode * ) nodesListGetNode ( pNodeList , i ) ;
2022-03-22 08:03:42 +00:00
2022-04-27 02:11:32 +00:00
if ( nodeType ( pNode - > pExpr ) = = QUERY_NODE_COLUMN ) {
SColumnNode * pColNode = ( SColumnNode * ) pNode - > pExpr ;
// todo extract method
SColumn c = { 0 } ;
c . slotId = pColNode - > slotId ;
c . colId = pColNode - > colId ;
c . type = pColNode - > node . resType . type ;
c . bytes = pColNode - > node . resType . bytes ;
c . scale = pColNode - > node . resType . scale ;
c . precision = pColNode - > node . resType . precision ;
taosArrayPush ( pList , & c ) ;
} else if ( nodeType ( pNode - > pExpr ) = = QUERY_NODE_VALUE ) {
SValueNode * pValNode = ( SValueNode * ) pNode - > pExpr ;
SColumn c = { 0 } ;
c . slotId = pNode - > slotId ;
c . colId = pNode - > slotId ;
c . type = pValNode - > node . type ;
c . bytes = pValNode - > node . resType . bytes ;
c . scale = pValNode - > node . resType . scale ;
c . precision = pValNode - > node . resType . precision ;
taosArrayPush ( pList , & c ) ;
}
2022-03-22 08:03:42 +00:00
}
return pList ;
}
2022-04-08 07:31:03 +00:00
SArray * extractPartitionColInfo ( SNodeList * pNodeList ) {
size_t numOfCols = LIST_LENGTH ( pNodeList ) ;
SArray * pList = taosArrayInit ( numOfCols , sizeof ( SColumn ) ) ;
if ( pList = = NULL ) {
terrno = TSDB_CODE_OUT_OF_MEMORY ;
return NULL ;
}
for ( int32_t i = 0 ; i < numOfCols ; + + i ) {
SColumnNode * pColNode = ( SColumnNode * ) nodesListGetNode ( pNodeList , i ) ;
// todo extract method
SColumn c = { 0 } ;
c . slotId = pColNode - > slotId ;
2022-04-23 10:29:45 +00:00
c . colId = pColNode - > colId ;
c . type = pColNode - > node . resType . type ;
c . bytes = pColNode - > node . resType . bytes ;
2022-04-08 07:31:03 +00:00
c . precision = pColNode - > node . resType . precision ;
c . scale = pColNode - > node . resType . scale ;
taosArrayPush ( pList , & c ) ;
}
return pList ;
}
2022-04-08 06:40:02 +00:00
SArray * createSortInfo ( SNodeList * pNodeList , SNodeList * pNodeListTarget ) {
2022-03-29 07:24:25 +00:00
size_t numOfCols = LIST_LENGTH ( pNodeList ) ;
2022-03-28 11:08:07 +00:00
SArray * pList = taosArrayInit ( numOfCols , sizeof ( SBlockOrderInfo ) ) ;
if ( pList = = NULL ) {
terrno = TSDB_CODE_OUT_OF_MEMORY ;
return pList ;
}
2022-03-29 07:24:25 +00:00
for ( int32_t i = 0 ; i < numOfCols ; + + i ) {
2022-04-08 06:17:32 +00:00
SOrderByExprNode * pSortKey = ( SOrderByExprNode * ) nodesListGetNode ( pNodeList , i ) ;
2022-03-29 07:24:25 +00:00
SBlockOrderInfo bi = { 0 } ;
bi . order = ( pSortKey - > order = = ORDER_ASC ) ? TSDB_ORDER_ASC : TSDB_ORDER_DESC ;
2022-03-28 11:08:07 +00:00
bi . nullFirst = ( pSortKey - > nullOrder = = NULL_ORDER_FIRST ) ;
SColumnNode * pColNode = ( SColumnNode * ) pSortKey - > pExpr ;
2022-04-08 06:40:02 +00:00
bool found = false ;
for ( int32_t j = 0 ; j < LIST_LENGTH ( pNodeListTarget ) ; + + j ) {
STargetNode * pTarget = ( STargetNode * ) nodesListGetNode ( pNodeListTarget , j ) ;
SColumnNode * pColNodeT = ( SColumnNode * ) pTarget - > pExpr ;
2022-04-23 10:29:45 +00:00
if ( pColNode - > slotId = = pColNodeT - > slotId ) { // to find slotId in PhysiSort OutputDataBlockDesc
2022-04-08 06:40:02 +00:00
bi . slotId = pTarget - > slotId ;
found = true ;
break ;
}
}
2022-04-23 10:29:45 +00:00
if ( ! found ) {
2022-04-08 06:40:02 +00:00
qError ( " sort slot id does not found " ) ;
}
2022-03-28 11:08:07 +00:00
taosArrayPush ( pList , & bi ) ;
}
return pList ;
}
2022-04-08 06:17:32 +00:00
SArray * createIndexMap ( SNodeList * pNodeList ) {
size_t numOfCols = LIST_LENGTH ( pNodeList ) ;
SArray * pList = taosArrayInit ( numOfCols , sizeof ( int32_t ) ) ;
if ( pList = = NULL ) {
terrno = TSDB_CODE_OUT_OF_MEMORY ;
return pList ;
}
for ( int32_t i = 0 ; i < numOfCols ; + + i ) {
STargetNode * pTarget = ( STargetNode * ) nodesListGetNode ( pNodeList , i ) ;
SColumnNode * pColNode = ( SColumnNode * ) pTarget - > pExpr ;
taosArrayPush ( pList , & pColNode - > slotId ) ;
}
return pList ;
}
2022-03-29 02:08:21 +00:00
SArray * extractColMatchInfo ( SNodeList * pNodeList , SDataBlockDescNode * pOutputNodeList , int32_t * numOfOutputCols ) {
2022-03-29 07:24:25 +00:00
size_t numOfCols = LIST_LENGTH ( pNodeList ) ;
2022-03-26 07:02:29 +00:00
SArray * pList = taosArrayInit ( numOfCols , sizeof ( SColMatchInfo ) ) ;
if ( pList = = NULL ) {
terrno = TSDB_CODE_OUT_OF_MEMORY ;
return NULL ;
}
2022-03-29 07:24:25 +00:00
for ( int32_t i = 0 ; i < numOfCols ; + + i ) {
STargetNode * pNode = ( STargetNode * ) nodesListGetNode ( pNodeList , i ) ;
SColumnNode * pColNode = ( SColumnNode * ) pNode - > pExpr ;
2022-03-26 07:02:29 +00:00
SColMatchInfo c = { 0 } ;
2022-04-27 08:37:19 +00:00
c . output = true ;
2022-03-29 07:24:25 +00:00
c . colId = pColNode - > colId ;
2022-03-26 07:02:29 +00:00
c . targetSlotId = pNode - > slotId ;
taosArrayPush ( pList , & c ) ;
}
2022-03-29 02:08:21 +00:00
* numOfOutputCols = 0 ;
int32_t num = LIST_LENGTH ( pOutputNodeList - > pSlots ) ;
2022-03-29 07:24:25 +00:00
for ( int32_t i = 0 ; i < num ; + + i ) {
SSlotDescNode * pNode = ( SSlotDescNode * ) nodesListGetNode ( pOutputNodeList - > pSlots , i ) ;
2022-04-27 08:37:19 +00:00
2022-04-12 09:55:17 +00:00
// todo: add reserve flag check
2022-04-27 08:37:19 +00:00
// it is a column reserved for the arithmetic expression calculation
if ( pNode - > slotId > = numOfCols ) {
2022-04-12 09:55:17 +00:00
( * numOfOutputCols ) + = 1 ;
continue ;
}
2022-03-29 02:08:21 +00:00
SColMatchInfo * info = taosArrayGet ( pList , pNode - > slotId ) ;
2022-03-29 12:05:04 +00:00
if ( pNode - > output ) {
( * numOfOutputCols ) + = 1 ;
} else {
info - > output = false ;
}
2022-03-29 02:08:21 +00:00
}
2022-03-26 07:02:29 +00:00
return pList ;
}
2022-04-23 10:29:45 +00:00
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-03-10 15:12:34 +00:00
SArray * extractTableIdList ( const STableGroupInfo * pTableGroupInfo ) {
SArray * tableIdList = taosArrayInit ( 4 , sizeof ( uint64_t ) ) ;
if ( pTableGroupInfo - > numOfTables > 0 ) {
SArray * pa = taosArrayGetP ( pTableGroupInfo - > pGroupList , 0 ) ;
ASSERT ( taosArrayGetSize ( pTableGroupInfo - > pGroupList ) = = 1 ) ;
// Transfer the Array of STableKeyInfo into uid list.
size_t numOfTables = taosArrayGetSize ( pa ) ;
for ( int32_t i = 0 ; i < numOfTables ; + + i ) {
STableKeyInfo * pkeyInfo = taosArrayGet ( pa , i ) ;
taosArrayPush ( tableIdList , & pkeyInfo - > uid ) ;
}
}
return tableIdList ;
}
2022-03-29 07:24:25 +00:00
tsdbReaderT doCreateDataReader ( STableScanPhysiNode * pTableScanNode , SReadHandle * pHandle ,
STableGroupInfo * pTableGroupInfo , uint64_t queryId , uint64_t taskId ) {
2022-01-27 10:27:26 +00:00
uint64_t uid = pTableScanNode - > scan . uid ;
2022-03-29 07:24:25 +00:00
int32_t code =
doCreateTableGroup ( pHandle - > meta , pTableScanNode - > scan . tableType , uid , pTableGroupInfo , 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-03-24 06:21:14 +00:00
if ( pTableGroupInfo - > numOfTables = = 0 ) {
2022-01-20 08:02:09 +00:00
code = 0 ;
2022-03-29 07:24:25 +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-04-26 05:09:29 +00:00
SQueryTableDataCond cond = { 0 } ;
code = initQueryTableDataCond ( & cond , pTableScanNode ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
goto _error ;
}
return tsdbQueryTables ( pHandle - > reader , & cond , pTableGroupInfo , queryId , taskId ) ;
2022-01-22 14:51:48 +00:00
2022-03-29 07:24:25 +00:00
_error :
2022-01-20 08:02:09 +00:00
terrno = code ;
return NULL ;
}
2022-04-23 10:29:45 +00:00
int32_t createExecTaskInfoImpl ( SSubplan * pPlan , SExecTaskInfo * * pTaskInfo , SReadHandle * pHandle , uint64_t taskId ,
EOPTR_EXEC_MODEL model ) {
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-03-30 06:54:00 +00:00
* pTaskInfo = createExecTaskInfo ( queryId , taskId , model ) ;
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-04-24 12:48:42 +00:00
( * pTaskInfo ) - > pRoot = createOperatorTree ( pPlan - > pNode , * pTaskInfo , pHandle , queryId , taskId , & ( * pTaskInfo ) - > tableqinfoGroupInfo ) ;
2022-03-15 07:34:17 +00:00
if ( NULL = = ( * pTaskInfo ) - > pRoot ) {
2022-03-29 07:24:25 +00:00
code = terrno ;
2022-03-10 11:36:30 +00:00
goto _complete ;
}
2022-03-21 10:34:42 +00:00
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 :
2022-03-25 16:29:53 +00:00
taosMemoryFreeClear ( * pTaskInfo ) ;
2022-01-21 03:19:24 +00:00
terrno = code ;
return code ;
2022-01-08 14:59:24 +00:00
}
2022-03-29 07:24:25 +00:00
static int32_t updateOutputBufForTopBotQuery ( SQueriedTableInfo * pTableInfo , SColumnInfo * pTagCols , SExprInfo * pExprs ,
int32_t numOfOutput , int32_t tagLen , bool superTable ) {
2021-11-02 05:37:31 +00:00
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 ] ;
2022-03-29 07:24:25 +00:00
// 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);
2021-11-02 05:37:31 +00:00
}
}
}
return TSDB_CODE_SUCCESS ;
}
2022-03-24 03:15:05 +00:00
void setResultBufSize ( STaskAttr * pQueryAttr , SResultInfo * 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 ;
2022-04-23 10:29:45 +00:00
// 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;
// }
2021-11-02 05:37:31 +00:00
pResultInfo - > threshold = ( int32_t ) ( pResultInfo - > capacity * THRESHOLD_RATIO ) ;
2022-03-24 03:15:05 +00:00
pResultInfo - > totalRows = 0 ;
2021-11-02 05:37:31 +00:00
}
2022-03-29 07:24:25 +00:00
// TODO refactor
2021-11-02 05:37:31 +00:00
void freeColumnFilterInfo ( SColumnFilterInfo * pFilter , int32_t numOfFilters ) {
2022-03-29 07:24:25 +00:00
if ( pFilter = = NULL | | numOfFilters = = 0 ) {
return ;
}
2021-11-02 05:37:31 +00:00
2022-03-29 07:24:25 +00:00
for ( int32_t i = 0 ; i < numOfFilters ; i + + ) {
if ( pFilter [ i ] . filterstr & & pFilter [ i ] . pz ) {
taosMemoryFree ( ( void * ) ( pFilter [ i ] . pz ) ) ;
2021-11-02 05:37:31 +00:00
}
2022-03-29 07:24:25 +00:00
}
2021-11-02 05:37:31 +00:00
2022-03-29 07:24:25 +00:00
taosMemoryFree ( pFilter ) ;
2021-11-02 05:37:31 +00:00
}
static void doDestroyTableQueryInfo ( STableGroupInfo * pTableqinfoGroupInfo ) {
if ( pTableqinfoGroupInfo - > pGroupList ! = NULL ) {
2022-03-29 07:24:25 +00:00
int32_t numOfGroups = ( int32_t ) taosArrayGetSize ( pTableqinfoGroupInfo - > pGroupList ) ;
2021-11-02 05:37:31 +00:00
for ( int32_t i = 0 ; i < numOfGroups ; + + i ) {
2022-03-29 07:24:25 +00:00
SArray * p = taosArrayGetP ( pTableqinfoGroupInfo - > pGroupList , i ) ;
2021-11-02 05:37:31 +00:00
size_t num = taosArrayGetSize ( p ) ;
2022-03-29 07:24:25 +00:00
for ( int32_t j = 0 ; j < num ; + + j ) {
2021-11-02 05:37:31 +00:00
STableQueryInfo * item = taosArrayGetP ( p , j ) ;
destroyTableQueryInfoImpl ( item ) ;
}
taosArrayDestroy ( p ) ;
}
}
taosArrayDestroy ( pTableqinfoGroupInfo - > pGroupList ) ;
taosHashCleanup ( pTableqinfoGroupInfo - > map ) ;
pTableqinfoGroupInfo - > pGroupList = NULL ;
pTableqinfoGroupInfo - > map = NULL ;
pTableqinfoGroupInfo - > numOfTables = 0 ;
}
2022-03-29 07:24:25 +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 ) ;
2022-03-29 07:24:25 +00:00
// taosArrayDestroy(pTaskInfo->summary.queryProfEvents);
// taosHashCleanup(pTaskInfo->summary.operatorProfResults);
2021-11-02 05:37:31 +00:00
2022-03-25 16:29:53 +00:00
taosMemoryFreeClear ( pTaskInfo - > sql ) ;
taosMemoryFreeClear ( pTaskInfo - > id . str ) ;
taosMemoryFreeClear ( 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 ;
2022-03-29 07:24:25 +00:00
int32_t len = ( varDataLen ( val ) > maxLen ) ? maxLen : varDataLen ( val ) ;
2021-11-02 05:37:31 +00:00
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 ) ;
2022-03-29 07:24:25 +00:00
// size_t s3 = sizeof(STableCheckInfo); buffer consumption in tsdb
return ( int64_t ) ( s1 * 1.5 * numOfTables ) ;
2021-11-02 05:37:31 +00:00
}
int32_t checkForQueryBuf ( size_t numOfTables ) {
int64_t t = getQuerySupportBufSize ( numOfTables ) ;
if ( tsQueryBufferSizeBytes < 0 ) {
return TSDB_CODE_SUCCESS ;
} else if ( tsQueryBufferSizeBytes > 0 ) {
2022-03-29 07:24:25 +00:00
while ( 1 ) {
2021-11-02 05:37:31 +00:00
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 ;
}
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-04-01 11:45:45 +00:00
2022-04-23 10:29:45 +00:00
int32_t getOperatorExplainExecInfo ( SOperatorInfo * operatorInfo , SExplainExecInfo * * pRes , int32_t * capacity ,
int32_t * resNum ) {
2022-04-01 11:45:45 +00:00
if ( * resNum > = * capacity ) {
* capacity + = 10 ;
2022-04-23 10:29:45 +00:00
2022-04-01 11:45:45 +00:00
* pRes = taosMemoryRealloc ( * pRes , ( * capacity ) * sizeof ( SExplainExecInfo ) ) ;
if ( NULL = = * pRes ) {
2022-04-02 11:31:52 +00:00
qError ( " malloc %d failed " , ( * capacity ) * ( int32_t ) sizeof ( SExplainExecInfo ) ) ;
2022-04-01 11:45:45 +00:00
return TSDB_CODE_QRY_OUT_OF_MEMORY ;
}
}
2022-04-06 03:32:21 +00:00
( * pRes ) [ * resNum ] . numOfRows = operatorInfo - > resultInfo . totalRows ;
( * pRes ) [ * resNum ] . startupCost = operatorInfo - > cost . openCost ;
( * pRes ) [ * resNum ] . totalCost = operatorInfo - > cost . totalCost ;
2022-04-26 12:26:32 +00:00
if ( operatorInfo - > fpSet . getExplainFn ) {
int32_t code = ( * operatorInfo - > fpSet . getExplainFn ) ( operatorInfo , & ( * pRes ) - > verboseInfo ) ;
2022-04-06 03:32:21 +00:00
if ( code ) {
qError ( " operator getExplainFn failed, error:%s " , tstrerror ( code ) ) ;
return code ;
}
}
2022-04-23 10:29:45 +00:00
2022-04-02 11:31:52 +00:00
+ + ( * resNum ) ;
2022-04-23 10:29:45 +00:00
2022-04-02 11:31:52 +00:00
int32_t code = 0 ;
2022-04-06 03:32:21 +00:00
for ( int32_t i = 0 ; i < operatorInfo - > numOfDownstream ; + + i ) {
code = getOperatorExplainExecInfo ( operatorInfo - > pDownstream [ i ] , pRes , capacity , resNum ) ;
2022-04-02 11:31:52 +00:00
if ( code ) {
taosMemoryFreeClear ( * pRes ) ;
return TSDB_CODE_QRY_OUT_OF_MEMORY ;
}
}
return TSDB_CODE_SUCCESS ;
2022-04-01 11:45:45 +00:00
}
2022-04-14 14:12:10 +00:00
static SSDataBlock * doMergeJoin ( struct SOperatorInfo * pOperator , bool * newgroup ) {
SJoinOperatorInfo * pJoinInfo = pOperator - > info ;
2022-04-23 10:29:45 +00:00
// SOptrBasicInfo* pInfo = &pJoinInfo->binfo;
2022-04-14 14:12:10 +00:00
SSDataBlock * pRes = pJoinInfo - > pRes ;
blockDataCleanup ( pRes ) ;
blockDataEnsureCapacity ( pRes , 4096 ) ;
int32_t nrows = 0 ;
while ( 1 ) {
bool prevVal = * newgroup ;
if ( pJoinInfo - > pLeft = = NULL | | pJoinInfo - > leftPos > = pJoinInfo - > pLeft - > info . rows ) {
SOperatorInfo * ds1 = pOperator - > pDownstream [ 0 ] ;
publishOperatorProfEvent ( ds1 , QUERY_PROF_BEFORE_OPERATOR_EXEC ) ;
2022-04-26 12:26:32 +00:00
pJoinInfo - > pLeft = ds1 - > fpSet . getNextFn ( ds1 , newgroup ) ;
2022-04-14 14:12:10 +00:00
publishOperatorProfEvent ( ds1 , QUERY_PROF_AFTER_OPERATOR_EXEC ) ;
pJoinInfo - > leftPos = 0 ;
if ( pJoinInfo - > pLeft = = NULL ) {
setTaskStatus ( pOperator - > pTaskInfo , TASK_COMPLETED ) ;
break ;
}
}
if ( pJoinInfo - > pRight = = NULL | | pJoinInfo - > rightPos > = pJoinInfo - > pRight - > info . rows ) {
SOperatorInfo * ds2 = pOperator - > pDownstream [ 1 ] ;
publishOperatorProfEvent ( ds2 , QUERY_PROF_BEFORE_OPERATOR_EXEC ) ;
2022-04-26 12:26:32 +00:00
pJoinInfo - > pRight = ds2 - > fpSet . getNextFn ( ds2 , newgroup ) ;
2022-04-14 14:12:10 +00:00
publishOperatorProfEvent ( ds2 , QUERY_PROF_AFTER_OPERATOR_EXEC ) ;
pJoinInfo - > rightPos = 0 ;
if ( pJoinInfo - > pRight = = NULL ) {
setTaskStatus ( pOperator - > pTaskInfo , TASK_COMPLETED ) ;
break ;
}
}
SColumnInfoData * pLeftCol = taosArrayGet ( pJoinInfo - > pLeft - > pDataBlock , pJoinInfo - > leftCol . slotId ) ;
2022-04-23 10:29:45 +00:00
char * pLeftVal = colDataGetData ( pLeftCol , pJoinInfo - > leftPos ) ;
2022-04-14 14:12:10 +00:00
SColumnInfoData * pRightCol = taosArrayGet ( pJoinInfo - > pRight - > pDataBlock , pJoinInfo - > rightCol . slotId ) ;
2022-04-23 10:29:45 +00:00
char * pRightVal = colDataGetData ( pRightCol , pJoinInfo - > rightPos ) ;
2022-04-14 14:12:10 +00:00
// only the timestamp match support for ordinary table
2022-04-23 10:29:45 +00:00
ASSERT ( pLeftCol - > info . type = = TSDB_DATA_TYPE_TIMESTAMP ) ;
if ( * ( int64_t * ) pLeftVal = = * ( int64_t * ) pRightVal ) {
for ( int32_t i = 0 ; i < pOperator - > numOfOutput ; + + i ) {
SColumnInfoData * pDst = taosArrayGet ( pRes - > pDataBlock , i ) ;
2022-04-14 14:12:10 +00:00
2022-04-23 10:29:45 +00:00
SExprInfo * pExprInfo = & pOperator - > pExpr [ i ] ;
2022-04-14 14:12:10 +00:00
2022-04-23 10:29:45 +00:00
int32_t blockId = pExprInfo - > base . pParam [ 0 ] . pCol - > dataBlockId ;
int32_t slotId = pExprInfo - > base . pParam [ 0 ] . pCol - > slotId ;
2022-04-14 14:12:10 +00:00
2022-04-23 10:29:45 +00:00
SColumnInfoData * pSrc = NULL ;
if ( pJoinInfo - > pLeft - > info . blockId = = blockId ) {
pSrc = taosArrayGet ( pJoinInfo - > pLeft - > pDataBlock , slotId ) ;
} else {
pSrc = taosArrayGet ( pJoinInfo - > pRight - > pDataBlock , slotId ) ;
}
2022-04-14 14:12:10 +00:00
2022-04-23 10:29:45 +00:00
if ( colDataIsNull_s ( pSrc , pJoinInfo - > leftPos ) ) {
colDataAppendNULL ( pDst , nrows ) ;
} else {
char * p = colDataGetData ( pSrc , pJoinInfo - > leftPos ) ;
colDataAppend ( pDst , nrows , p , false ) ;
2022-04-14 14:12:10 +00:00
}
2022-04-23 10:29:45 +00:00
}
2022-04-14 14:12:10 +00:00
2022-04-23 10:29:45 +00:00
pJoinInfo - > leftPos + = 1 ;
pJoinInfo - > rightPos + = 1 ;
2022-04-14 14:12:10 +00:00
2022-04-23 10:29:45 +00:00
nrows + = 1 ;
} else if ( * ( int64_t * ) pLeftVal < * ( int64_t * ) pRightVal ) {
pJoinInfo - > leftPos + = 1 ;
2022-04-01 11:45:45 +00:00
2022-04-23 10:29:45 +00:00
if ( pJoinInfo - > leftPos > = pJoinInfo - > pLeft - > info . rows ) {
continue ;
2022-04-14 14:12:10 +00:00
}
2022-04-23 10:29:45 +00:00
} else if ( * ( int64_t * ) pLeftVal > * ( int64_t * ) pRightVal ) {
pJoinInfo - > rightPos + = 1 ;
if ( pJoinInfo - > rightPos > = pJoinInfo - > pRight - > info . rows ) {
continue ;
2022-04-14 14:12:10 +00:00
}
2022-04-23 10:29:45 +00:00
}
2022-04-14 14:12:10 +00:00
// the pDataBlock are always the same one, no need to call this again
pRes - > info . rows = nrows ;
if ( pRes - > info . rows > = pOperator - > resultInfo . threshold ) {
break ;
}
}
return ( pRes - > info . rows > 0 ) ? pRes : NULL ;
}
2022-04-23 10:29:45 +00:00
SOperatorInfo * createJoinOperatorInfo ( SOperatorInfo * * pDownstream , int32_t numOfDownstream , SExprInfo * pExprInfo ,
int32_t numOfCols , SSDataBlock * pResBlock , SNode * pOnCondition ,
SExecTaskInfo * pTaskInfo ) {
2022-04-14 14:12:10 +00:00
SJoinOperatorInfo * pInfo = taosMemoryCalloc ( 1 , sizeof ( SJoinOperatorInfo ) ) ;
2022-04-23 10:29:45 +00:00
SOperatorInfo * pOperator = taosMemoryCalloc ( 1 , sizeof ( SOperatorInfo ) ) ;
2022-04-14 14:12:10 +00:00
if ( pOperator = = NULL | | pInfo = = NULL ) {
goto _error ;
}
pOperator - > resultInfo . capacity = 4096 ;
pOperator - > resultInfo . threshold = 4096 * 0.75 ;
2022-04-23 10:29:45 +00:00
// initResultRowInf
// o(&pInfo->binfo.resultRowInfo, 8);
pInfo - > pRes = pResBlock ;
2022-04-14 14:12:10 +00:00
2022-04-23 10:29:45 +00:00
pOperator - > name = " JoinOperator " ;
2022-04-14 14:12:10 +00:00
pOperator - > operatorType = QUERY_NODE_PHYSICAL_PLAN_JOIN ;
2022-04-15 15:02:26 +00:00
pOperator - > blockingOptr = false ;
2022-04-23 10:29:45 +00:00
pOperator - > status = OP_NOT_OPENED ;
pOperator - > pExpr = pExprInfo ;
pOperator - > numOfOutput = numOfCols ;
pOperator - > info = pInfo ;
pOperator - > pTaskInfo = pTaskInfo ;
2022-04-14 14:12:10 +00:00
2022-04-26 12:26:32 +00:00
pOperator - > fpSet = createOperatorFpSet ( operatorDummyOpenFn , doMergeJoin , NULL , NULL , destroyBasicOperatorInfo ,
NULL , NULL , NULL ) ;
2022-04-14 14:12:10 +00:00
int32_t code = appendDownstream ( pOperator , pDownstream , numOfDownstream ) ;
return pOperator ;
2022-04-23 10:29:45 +00:00
_error :
2022-04-14 14:12:10 +00:00
taosMemoryFree ( pInfo ) ;
taosMemoryFree ( pOperator ) ;
pTaskInfo - > code = TSDB_CODE_OUT_OF_MEMORY ;
return NULL ;
2022-04-23 10:29:45 +00:00
}