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"
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-05-27 10:13:22 +00:00
# include "index.h"
2022-03-15 06:37:26 +00:00
# include "query.h"
2021-11-02 05:37:31 +00:00
# include "tcompare.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 SET_REVERSE_SCAN_FLAG(runtime) ((runtime)->scanFlag = REVERSE_SCAN)
# define GET_FORWARD_DIRECTION_FACTOR(ord) (((ord) == TSDB_ORDER_ASC) ? QUERY_ASC_FORWARD_STEP : QUERY_DESC_FORWARD_STEP)
#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
2022-06-16 01:31:22 +00:00
# define CLEAR_QUERY_STATUS(q, st) ((q)->status &= (~(st)))
2021-11-02 05:37:31 +00:00
# define QUERY_IS_INTERVAL_QUERY(_q) ((_q)->interval.interval > 0)
2022-11-27 16:27:49 +00:00
typedef struct SAggOperatorInfo {
SOptrBasicInfo binfo ;
SAggSupporter aggSup ;
STableQueryInfo * current ;
uint64_t groupId ;
SGroupResInfo groupResInfo ;
SExprSupp scalarExprSup ;
} SAggOperatorInfo ;
2022-03-29 07:24:25 +00:00
int32_t getMaximumIdleDurationSec ( ) { return tsShellActivityTimer * 2 ; }
2022-08-24 09:09:33 +00:00
static void setBlockSMAInfo ( SqlFunctionCtx * pCtx , SExprInfo * pExpr , SSDataBlock * pBlock ) ;
2021-11-02 05:37:31 +00:00
2022-05-23 11:50:08 +00:00
static void releaseQueryBuf ( size_t numOfTables ) ;
2021-11-02 05:37:31 +00:00
2022-11-25 10:22:09 +00:00
static void destroyAggOperatorInfo ( void * param ) ;
static void initCtxOutputBuffer ( SqlFunctionCtx * pCtx , int32_t size ) ;
static void doSetTableGroupOutputBuf ( SOperatorInfo * pOperator , int32_t numOfOutput , uint64_t groupId ) ;
static void doApplyScalarCalculation ( SOperatorInfo * pOperator , SSDataBlock * pBlock , int32_t order , int32_t scanFlag ) ;
static int32_t doInitAggInfoSup ( SAggSupporter * pAggSup , SqlFunctionCtx * pCtx , int32_t numOfOutput , size_t keyBufSize ,
const char * pKey ) ;
static void extractQualifiedTupleByFilterResult ( SSDataBlock * pBlock , const SColumnInfoData * p , bool keep ,
int32_t status ) ;
static int32_t doSetInputDataBlock ( SExprSupp * pExprSup , SSDataBlock * pBlock , int32_t order , int32_t scanFlag ,
bool createDummyCol ) ;
2022-03-04 07:53:30 +00:00
2022-11-09 11:14:27 +00:00
void setOperatorCompleted ( SOperatorInfo * pOperator ) {
2021-11-02 05:37:31 +00:00
pOperator - > status = OP_EXEC_DONE ;
2022-10-18 03:43:58 +00:00
ASSERT ( pOperator - > pTaskInfo ! = NULL ) ;
2022-05-24 03:29:51 +00:00
2022-05-26 08:29:52 +00:00
pOperator - > cost . totalCost = ( taosGetTimestampUs ( ) - pOperator - > pTaskInfo - > cost . start * 1000 ) / 1000.0 ;
2022-10-18 03:43:58 +00:00
setTaskStatus ( pOperator - > pTaskInfo , TASK_COMPLETED ) ;
2021-11-02 05:37:31 +00:00
}
2022-04-06 09:59:08 +00:00
2022-11-09 11:14:27 +00:00
void setOperatorInfo ( SOperatorInfo * pOperator , const char * name , int32_t type , bool blocking , int32_t status ,
void * pInfo , SExecTaskInfo * pTaskInfo ) {
pOperator - > name = ( char * ) name ;
pOperator - > operatorType = type ;
pOperator - > blocking = blocking ;
pOperator - > status = status ;
pOperator - > info = pInfo ;
pOperator - > pTaskInfo = pTaskInfo ;
}
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-05-03 15:23:49 +00:00
pOperator - > cost . openCost = 0 ;
2022-03-05 07:58:28 +00:00
return TSDB_CODE_SUCCESS ;
2022-03-04 07:53:30 +00:00
}
2022-11-09 05:45:46 +00:00
SOperatorFpSet createOperatorFpSet ( __optr_open_fn_t openFn , __optr_fn_t nextFn , __optr_fn_t cleanup ,
__optr_close_fn_t closeFn , __optr_explain_fn_t explain ) {
2022-04-26 12:26:32 +00:00
SOperatorFpSet fpSet = {
. _openFn = openFn ,
. getNextFn = nextFn ,
. cleanupFn = cleanup ,
. closeFn = closeFn ,
. getExplainFn = explain ,
} ;
return fpSet ;
}
2022-08-02 05:58:54 +00:00
static int32_t doCopyToSDataBlock ( SExecTaskInfo * pTaskInfo , SSDataBlock * pBlock , SExprSupp * pSup , SDiskbasedBuf * pBuf ,
SGroupResInfo * pGroupResInfo ) ;
2022-02-24 09:18:56 +00:00
2022-08-29 14:42:15 +00:00
SResultRow * getNewResultRow ( SDiskbasedBuf * pResultBuf , int32_t * currentPageId , 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 ;
2022-08-29 14:42:15 +00:00
if ( * currentPageId = = - 1 ) {
2022-08-29 10:47:46 +00:00
pData = getNewBufPage ( pResultBuf , & pageId ) ;
2022-03-15 06:37:26 +00:00
pData - > num = sizeof ( SFilePage ) ;
} else {
2022-08-29 14:42:15 +00:00
pData = getBufPage ( pResultBuf , * currentPageId ) ;
pageId = * currentPageId ;
2022-03-15 06:37:26 +00:00
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
2022-08-29 14:42:15 +00:00
releaseBufPage ( pResultBuf , pData ) ;
2022-03-15 06:37:26 +00:00
2022-08-29 10:47:46 +00:00
pData = getNewBufPage ( pResultBuf , & pageId ) ;
2022-03-15 06:37:26 +00:00
if ( pData ! = NULL ) {
pData - > num = sizeof ( SFilePage ) ;
}
}
}
if ( pData = = NULL ) {
return NULL ;
}
2022-05-20 15:59:17 +00:00
setBufPageDirty ( pData , true ) ;
2022-03-15 06:37:26 +00:00
// 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-08-29 14:42:15 +00:00
* currentPageId = pageId ;
2022-03-15 06:37:26 +00:00
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-05-03 06:43:53 +00:00
SResultRow * doSetResultOutBufByKey ( SDiskbasedBuf * pResultBuf , SResultRowInfo * pResultRowInfo , char * pData ,
int16_t bytes , bool masterscan , uint64_t groupId , 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 =
2022-08-26 08:52:12 +00:00
( SResultRowPosition * ) tSimpleHashGet ( 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.
2022-08-04 08:23:54 +00:00
pResult = getResultRowByPos ( pResultBuf , p1 , true ) ;
2022-05-20 15:59:17 +00:00
ASSERT ( pResult - > pageId = = p1 - > pageId & & pResult - > offset = = p1 - > offset ) ;
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-05-30 12:10:30 +00:00
// todo
2022-08-04 08:23:54 +00:00
pResult = getResultRowByPos ( pResultBuf , p1 , true ) ;
2022-05-20 15:59:17 +00:00
ASSERT ( pResult - > pageId = = p1 - > pageId & & pResult - > offset = = p1 - > offset ) ;
2022-01-20 05:52:46 +00:00
}
}
2022-04-28 08:31:35 +00:00
// 1. close current opened time window
2022-06-28 03:48:10 +00:00
if ( pResultRowInfo - > cur . pageId ! = - 1 & & ( ( pResult = = NULL ) | | ( pResult - > pageId ! = pResultRowInfo - > cur . pageId ) ) ) {
2022-04-25 08:44:48 +00:00
SResultRowPosition pos = pResultRowInfo - > cur ;
2022-06-04 11:54:55 +00:00
SFilePage * pPage = getBufPage ( pResultBuf , pos . pageId ) ;
2022-04-25 08:44:48 +00:00
releaseBufPage ( pResultBuf , pPage ) ;
}
// allocate a new buffer page
if ( pResult = = NULL ) {
2022-05-08 08:06:47 +00:00
ASSERT ( pSup - > resultRowSize > 0 ) ;
2022-08-29 14:42:15 +00:00
pResult = getNewResultRow ( pResultBuf , & pSup - > currentPageId , pSup - > resultRowSize ) ;
2022-05-29 04:35:11 +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 } ;
2022-08-26 08:52:12 +00:00
tSimpleHashPut ( pSup - > pResultRowHashTable , pSup - > keyBuf , GET_RES_WINDOW_KEY_LEN ( bytes ) , & pos ,
2022-08-31 03:35:25 +00:00
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 - > cur = ( SResultRowPosition ) { . pageId = pResult - > pageId , . offset = pResult - > offset } ;
2022-01-20 05:52:46 +00:00
// too many time window in query
2022-08-03 12:33:09 +00:00
if ( pTaskInfo - > execModel = = OPTR_EXEC_MODEL_BATCH & &
2022-08-26 08:52:12 +00:00
tSimpleHashGetSize ( pSup - > pResultRowHashTable ) > MAX_INTERVAL_TIME_WINDOW ) {
2022-08-24 09:09:33 +00:00
T_LONG_JMP ( pTaskInfo - > env , TSDB_CODE_QRY_TOO_MANY_TIMEWINDOW ) ;
2022-01-20 05:52:46 +00:00
}
2022-03-31 08:10:32 +00:00
return pResult ;
2022-01-20 05:52:46 +00:00
}
2021-11-02 05:37:31 +00:00
// 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 ;
2022-11-25 15:06:32 +00:00
SArray * list = getDataBufPagesIdList ( pResultBuf ) ;
2021-11-02 05:37:31 +00:00
if ( taosArrayGetSize ( list ) = = 0 ) {
2022-08-29 10:47:46 +00:00
pData = getNewBufPage ( pResultBuf , & 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-08-29 10:47:46 +00:00
pData = getNewBufPage ( pResultBuf , & 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-30 05:41:15 +00:00
// query_range_start, query_range_end, window_duration, window_start, window_end
2022-05-03 06:43:53 +00:00
void initExecTimeWindowInfo ( SColumnInfoData * pColData , STimeWindow * pQueryWindow ) {
2022-03-30 05:41:15 +00:00
pColData - > info . type = TSDB_DATA_TYPE_TIMESTAMP ;
pColData - > info . bytes = sizeof ( int64_t ) ;
2022-11-04 10:46:48 +00:00
colInfoDataEnsureCapacity ( pColData , 5 , false ) ;
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-08-22 03:09:12 +00:00
typedef struct {
bool hasAgg ;
int32_t numOfRows ;
int32_t startOffset ;
} SFunctionCtxStatus ;
static void functionCtxSave ( SqlFunctionCtx * pCtx , SFunctionCtxStatus * pStatus ) {
2022-11-14 06:14:24 +00:00
pStatus - > hasAgg = pCtx - > input . colDataSMAIsSet ;
2022-08-22 03:09:12 +00:00
pStatus - > numOfRows = pCtx - > input . numOfRows ;
pStatus - > startOffset = pCtx - > input . startRowIndex ;
}
static void functionCtxRestore ( SqlFunctionCtx * pCtx , SFunctionCtxStatus * pStatus ) {
2022-11-14 06:14:24 +00:00
pCtx - > input . colDataSMAIsSet = pStatus - > hasAgg ;
2022-08-25 03:01:36 +00:00
pCtx - > input . numOfRows = pStatus - > numOfRows ;
2022-08-22 03:09:12 +00:00
pCtx - > input . startRowIndex = pStatus - > startOffset ;
}
2022-11-27 16:27:49 +00:00
void applyAggFunctionOnPartialTuples ( SExecTaskInfo * taskInfo , SqlFunctionCtx * pCtx , SColumnInfoData * pTimeWindowData ,
int32_t offset , int32_t forwardStep , int32_t numOfTotal , int32_t numOfOutput ) {
2021-11-02 05:37:31 +00:00
for ( int32_t k = 0 ; k < numOfOutput ; + + k ) {
2022-04-06 11:46:38 +00:00
// keep it temporarily
2022-08-22 03:09:12 +00:00
SFunctionCtxStatus status = { 0 } ;
functionCtxSave ( & pCtx [ k ] , & status ) ;
2021-11-02 05:37:31 +00:00
2022-05-19 08:49:43 +00:00
pCtx [ k ] . input . startRowIndex = offset ;
2022-03-15 06:37:26 +00:00
pCtx [ k ] . input . numOfRows = forwardStep ;
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
2022-11-14 06:14:24 +00:00
if ( pCtx [ k ] . input . colDataSMAIsSet & & forwardStep < numOfTotal ) {
pCtx [ k ] . input . colDataSMAIsSet = false ;
2021-11-02 05:37:31 +00:00
}
2022-03-30 05:41:15 +00:00
if ( fmIsWindowPseudoColumnFunc ( pCtx [ k ] . functionId ) ) {
SResultRowEntryInfo * pEntryInfo = GET_RES_INFO ( & pCtx [ k ] ) ;
2022-05-30 12:10:30 +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 ;
2022-05-30 12:10:30 +00:00
} else {
int32_t code = TSDB_CODE_SUCCESS ;
if ( functionNeedToExecute ( & pCtx [ k ] ) & & pCtx [ k ] . fpSet . process ! = NULL ) {
code = pCtx [ k ] . fpSet . process ( & pCtx [ k ] ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
qError ( " %s apply functions error, code: %s " , GET_TASKID ( taskInfo ) , tstrerror ( code ) ) ;
taskInfo - > code = code ;
2022-08-24 09:09:33 +00:00
T_LONG_JMP ( taskInfo - > env , code ) ;
2022-05-30 12:10:30 +00:00
}
2022-05-12 01:57:43 +00:00
}
2021-11-02 05:37:31 +00:00
2022-05-30 12:10:30 +00:00
// restore it
2022-08-22 03:09:12 +00:00
functionCtxRestore ( & pCtx [ k ] , & status ) ;
2022-05-30 12:10:30 +00:00
}
2021-11-02 05:37:31 +00:00
}
}
2022-10-20 10:07:38 +00:00
static void doSetInputDataBlockInfo ( SExprSupp * pExprSup , SSDataBlock * pBlock , int32_t order ) {
SqlFunctionCtx * pCtx = pExprSup - > pCtx ;
for ( int32_t i = 0 ; i < pExprSup - > numOfExprs ; + + i ) {
2021-11-02 05:37:31 +00:00
pCtx [ i ] . order = order ;
2022-05-17 08:53:55 +00:00
pCtx [ i ] . input . numOfRows = pBlock - > info . rows ;
2022-10-20 10:07:38 +00:00
setBlockSMAInfo ( & pCtx [ i ] , & pExprSup - > pExprInfo [ i ] , pBlock ) ;
2022-08-06 08:13:18 +00:00
pCtx [ i ] . pSrcBlock = pBlock ;
2021-11-02 05:37:31 +00:00
}
}
2022-10-20 10:07:38 +00:00
void setInputDataBlock ( SExprSupp * pExprSup , SSDataBlock * pBlock , int32_t order , int32_t scanFlag , bool createDummyCol ) {
2022-04-16 03:47:50 +00:00
if ( pBlock - > pBlockAgg ! = NULL ) {
2022-10-20 10:07:38 +00:00
doSetInputDataBlockInfo ( pExprSup , pBlock , order ) ;
2022-04-16 03:47:50 +00:00
} else {
2022-10-20 10:07:38 +00:00
doSetInputDataBlock ( pExprSup , pBlock , order , scanFlag , createDummyCol ) ;
2022-03-09 02:22:53 +00:00
}
2021-11-02 05:37:31 +00:00
}
2022-04-28 08:31:35 +00:00
static int32_t doCreateConstantValColumnInfo ( SInputColumnInfoData * pInput , SFunctParam * pFuncParam , 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-11-04 10:46:48 +00:00
colInfoDataEnsureCapacity ( pColInfo , numOfRows , false ) ;
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 ) {
2022-04-28 08:31:35 +00:00
char * tmp = taosMemoryMalloc ( pFuncParam - > param . nLen + VARSTR_HEADER_SIZE ) ;
2022-04-27 02:11:32 +00:00
STR_WITH_SIZE_TO_VARSTR ( tmp , pFuncParam - > param . pz , pFuncParam - > param . nLen ) ;
2022-04-28 08:31:35 +00:00
for ( int32_t i = 0 ; i < numOfRows ; + + i ) {
2022-04-27 02:11:32 +00:00
colDataAppend ( pColInfo , i , tmp , false ) ;
}
2022-10-19 05:38:01 +00:00
taosMemoryFree ( tmp ) ;
2022-04-18 02:46:07 +00:00
}
return TSDB_CODE_SUCCESS ;
}
2022-10-20 10:07:38 +00:00
static int32_t doSetInputDataBlock ( SExprSupp * pExprSup , SSDataBlock * pBlock , int32_t order , int32_t scanFlag ,
bool createDummyCol ) {
2022-10-21 02:37:58 +00:00
int32_t code = TSDB_CODE_SUCCESS ;
2022-10-20 10:07:38 +00:00
SqlFunctionCtx * pCtx = pExprSup - > pCtx ;
2022-04-18 02:46:07 +00:00
2022-10-20 10:07:38 +00:00
for ( int32_t i = 0 ; i < pExprSup - > numOfExprs ; + + i ) {
2022-04-28 08:31:35 +00:00
pCtx [ i ] . order = order ;
2022-05-17 08:53:55 +00:00
pCtx [ i ] . input . numOfRows = pBlock - > info . rows ;
2022-04-28 08:31:35 +00:00
pCtx [ i ] . pSrcBlock = pBlock ;
2022-05-23 11:50:08 +00:00
pCtx [ i ] . scanFlag = scanFlag ;
2022-03-09 02:22:53 +00:00
2022-04-18 02:46:07 +00:00
SInputColumnInfoData * pInput = & pCtx [ i ] . input ;
2022-11-28 04:32:40 +00:00
pInput - > uid = pBlock - > info . id . uid ;
2022-11-14 06:14:24 +00:00
pInput - > colDataSMAIsSet = false ;
2022-04-18 02:46:07 +00:00
2022-10-20 10:07:38 +00:00
SExprInfo * pOneExpr = & pExprSup - > pExprInfo [ i ] ;
2022-04-12 09:55:17 +00:00
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-05-11 09:19:35 +00:00
// NOTE: the last parameter is the primary timestamp column
2022-07-15 05:25:15 +00:00
// todo: refactor this
2022-07-22 07:06:01 +00:00
if ( fmIsImplicitTsFunc ( pCtx [ i ] . functionId ) & & ( j = = pOneExpr - > base . numOfParams - 1 ) ) {
2022-07-21 13:46:55 +00:00
pInput - > pPTS = pInput - > pData [ j ] ; // in case of merge function, this is not always the ts column data.
2022-10-28 11:56:32 +00:00
// ASSERT(pInput->pPTS->info.type == TSDB_DATA_TYPE_TIMESTAMP);
2022-04-30 05:48:07 +00:00
}
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-04-18 02:46:07 +00:00
return code ;
2022-03-09 02:22:53 +00:00
}
2022-07-12 07:30:38 +00:00
static int32_t doAggregateImpl ( SOperatorInfo * pOperator , SqlFunctionCtx * pCtx ) {
2022-06-18 04:00:41 +00:00
for ( int32_t k = 0 ; k < pOperator - > exprSupp . numOfExprs ; + + k ) {
2022-02-24 09:18:56 +00:00
if ( functionNeedToExecute ( & pCtx [ k ] ) ) {
2022-05-10 10:21:54 +00:00
// todo add a dummy funtion to avoid process check
2022-05-30 12:10:30 +00:00
if ( pCtx [ k ] . fpSet . process = = NULL ) {
continue ;
}
2022-07-11 05:54:12 +00:00
2022-05-30 12:10:30 +00:00
int32_t code = pCtx [ k ] . fpSet . process ( & pCtx [ k ] ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
qError ( " %s aggregate function error happens, code: %s " , GET_TASKID ( pOperator - > pTaskInfo ) , tstrerror ( code ) ) ;
return code ;
2022-05-10 10:21:54 +00:00
}
2021-11-02 05:37:31 +00:00
}
}
2022-05-13 04:17:09 +00:00
return TSDB_CODE_SUCCESS ;
2021-11-02 05:37:31 +00:00
}
2022-05-20 11:34:39 +00:00
bool functionNeedToExecute ( SqlFunctionCtx * pCtx ) {
2022-05-03 06:43:53 +00:00
struct SResultRowEntryInfo * pResInfo = GET_RES_INFO ( pCtx ) ;
2021-11-02 05:37:31 +00:00
2022-05-03 06:43:53 +00:00
// in case of timestamp column, always generated results.
int32_t functionId = pCtx - > functionId ;
if ( functionId = = - 1 ) {
return false ;
}
2021-11-02 05:37:31 +00:00
2022-05-13 04:17:09 +00:00
if ( pCtx - > scanFlag = = REPEAT_SCAN ) {
return fmIsRepeatScanFunc ( pCtx - > functionId ) ;
2021-11-02 05:37:31 +00:00
}
2022-05-13 04:17:09 +00:00
if ( isRowEntryCompleted ( pResInfo ) ) {
return false ;
2022-05-03 06:43:53 +00:00
}
2021-11-02 05:37:31 +00:00
return true ;
}
2022-05-03 06:43:53 +00:00
static int32_t doCreateConstantValColumnAggInfo ( SInputColumnInfoData * pInput , SFunctParam * pFuncParam , int32_t type ,
int32_t paramIndex , int32_t numOfRows ) {
if ( pInput - > pData [ paramIndex ] = = NULL ) {
pInput - > pData [ paramIndex ] = taosMemoryCalloc ( 1 , sizeof ( SColumnInfoData ) ) ;
if ( pInput - > pData [ paramIndex ] = = NULL ) {
return TSDB_CODE_OUT_OF_MEMORY ;
}
2021-11-02 05:37:31 +00:00
2022-05-03 06:43:53 +00:00
// Set the correct column info (data type and bytes)
pInput - > pData [ paramIndex ] - > info . type = type ;
pInput - > pData [ paramIndex ] - > info . bytes = tDataTypes [ type ] . bytes ;
2021-11-02 05:37:31 +00:00
}
2022-02-24 09:18:56 +00:00
2022-05-03 06:43:53 +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 ;
2021-11-02 05:37:31 +00:00
}
} else {
2022-05-03 06:43:53 +00:00
da = pInput - > pColumnDataAgg [ paramIndex ] ;
2021-11-02 05:37:31 +00:00
}
2022-05-03 06:43:53 +00:00
ASSERT ( ! IS_VAR_DATA_TYPE ( type ) ) ;
2021-11-02 05:37:31 +00:00
2022-05-03 06:43:53 +00:00
if ( type = = TSDB_DATA_TYPE_BIGINT ) {
int64_t v = pFuncParam - > param . i ;
2022-07-07 09:23:54 +00:00
* da = ( SColumnDataAgg ) { . numOfNull = 0 , . min = v , . max = v , . sum = v * numOfRows } ;
2022-05-03 06:43:53 +00:00
} else if ( type = = TSDB_DATA_TYPE_DOUBLE ) {
double v = pFuncParam - > param . d ;
2022-07-07 09:23:54 +00:00
* da = ( SColumnDataAgg ) { . numOfNull = 0 } ;
2021-11-02 05:37:31 +00:00
2022-05-03 06:43:53 +00:00
* ( double * ) & da - > min = v ;
* ( double * ) & da - > max = v ;
* ( double * ) & da - > sum = v * numOfRows ;
} else if ( type = = TSDB_DATA_TYPE_BOOL ) { // todo validate this data type
bool v = pFuncParam - > param . i ;
2022-07-07 09:23:54 +00:00
* da = ( SColumnDataAgg ) { . numOfNull = 0 } ;
2022-05-03 06:43:53 +00:00
* ( bool * ) & da - > min = 0 ;
* ( bool * ) & da - > max = v ;
* ( bool * ) & da - > sum = v * numOfRows ;
} else if ( type = = TSDB_DATA_TYPE_TIMESTAMP ) {
// do nothing
2021-11-02 05:37:31 +00:00
} else {
2022-05-03 06:43:53 +00:00
ASSERT ( 0 ) ;
2021-11-02 05:37:31 +00:00
}
2022-05-03 06:43:53 +00:00
return TSDB_CODE_SUCCESS ;
}
2022-04-18 02:46:07 +00:00
2022-08-06 08:15:15 +00:00
void setBlockSMAInfo ( SqlFunctionCtx * pCtx , SExprInfo * pExprInfo , SSDataBlock * pBlock ) {
2022-04-18 02:46:07 +00:00
int32_t numOfRows = pBlock - > info . rows ;
SInputColumnInfoData * pInput = & pCtx - > input ;
pInput - > numOfRows = numOfRows ;
pInput - > totalRows = numOfRows ;
if ( pBlock - > pBlockAgg ! = NULL ) {
2022-11-14 06:14:24 +00:00
pInput - > colDataSMAIsSet = true ;
2022-04-18 02:46:07 +00:00
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 ;
2022-04-29 12:07:33 +00:00
pInput - > pColumnDataAgg [ j ] = pBlock - > pBlockAgg [ slotId ] ;
if ( pInput - > pColumnDataAgg [ j ] = = NULL ) {
2022-11-14 06:14:24 +00:00
pInput - > colDataSMAIsSet = false ;
2022-04-29 12:07:33 +00:00
}
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-11-14 06:14:24 +00:00
pInput - > colDataSMAIsSet = false ;
2021-11-02 05:37:31 +00:00
}
}
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-11-08 03:09:19 +00:00
/*(!needBuildResAfterQueryComplete(pTaskInfo))*/ ) {
2022-01-10 11:48:21 +00:00
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-07-20 07:30:52 +00:00
STimeWindow getAlignQueryTimeWindow ( SInterval * pInterval , int32_t precision , int64_t key ) {
2022-07-21 13:46:55 +00:00
STimeWindow win = { 0 } ;
2022-07-20 07:30:52 +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-07-20 07:30:52 +00:00
win . ekey = taosTimeAdd ( win . skey , pInterval - > interval , pInterval - > intervalUnit , precision ) - 1 ;
if ( win . ekey < win . skey ) {
win . ekey = INT64_MAX ;
2021-11-02 05:37:31 +00:00
}
2022-07-20 07:30:52 +00:00
return win ;
2021-11-02 05:37:31 +00:00
}
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
2022-05-03 15:52:17 +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 ,
2022-06-17 15:23:37 +00:00
pTableScanInfo - > rowEntryInfoOffset ) ;
2021-11-02 05:37:31 +00:00
} else {
2022-11-28 04:32:40 +00:00
if ( setResultOutputBufByKey ( pRuntimeEnv , pTableScanInfo - > pResultRowInfo , pBlock - > info . id . uid , & win , masterScan , & pResult , groupId ,
2021-11-02 05:37:31 +00:00
pTableScanInfo - > pCtx , pTableScanInfo - > numOfOutput ,
2022-06-17 15:23:37 +00:00
pTableScanInfo - > rowEntryInfoOffset ) ! = TSDB_CODE_SUCCESS ) {
2022-08-24 09:09:33 +00:00
T_LONG_JMP ( pRuntimeEnv - > env , TSDB_CODE_QRY_OUT_OF_MEMORY ) ;
2021-11-02 05:37:31 +00:00
}
}
} else if ( pQueryAttr - > stableQuery & & ( ! pQueryAttr - > tsCompQuery ) & & ( ! pQueryAttr - > diffQuery ) ) { // stable aggregate, not interval aggregate or normal column aggregate
doSetTableGroupOutputBuf ( pRuntimeEnv , pTableScanInfo - > pResultRowInfo , pTableScanInfo - > pCtx ,
2022-06-17 15:23:37 +00:00
pTableScanInfo - > rowEntryInfoOffset , pTableScanInfo - > numOfOutput ,
2021-11-02 05:37:31 +00:00
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-07-07 07:56:43 +00:00
// tsdbRetrieveDatablockSMA(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-07-07 07:56:43 +00:00
// tsdbRetrieveDatablockSMA(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 ) ;
2022-11-28 04:32:40 +00:00
if ( setResultOutputBufByKey ( pRuntimeEnv , pTableScanInfo - > pResultRowInfo , pBlock - > info . id . uid , & win , masterScan , & pResult , groupId ,
2021-11-02 05:37:31 +00:00
pTableScanInfo - > pCtx , pTableScanInfo - > numOfOutput ,
2022-06-17 15:23:37 +00:00
pTableScanInfo - > rowEntryInfoOffset ) ! = TSDB_CODE_SUCCESS ) {
2022-08-24 09:09:33 +00:00
T_LONG_JMP ( pRuntimeEnv - > env , TSDB_CODE_QRY_OUT_OF_MEMORY ) ;
2021-11-02 05:37:31 +00:00
}
}
}
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
2022-08-05 09:40:40 +00:00
// if (!doFilterByBlockSMA(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) {
2022-06-22 09:21:04 +00:00
// filterSetColFieldData(pQueryAttr->pFilters, taosArrayGetSize(pBlock->pDataBlock), pBlock->pDataBlock);
2021-11-02 05:37:31 +00:00
// }
2022-05-01 07:22:28 +00:00
2021-11-02 05:37:31 +00:00
// 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
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-06-17 15:23:37 +00:00
void setResultRowInitCtx ( SResultRow * pResult , SqlFunctionCtx * pCtx , int32_t numOfOutput , int32_t * rowEntryInfoOffset ) {
2022-08-11 02:19:06 +00:00
bool init = false ;
2022-02-14 02:58:58 +00:00
for ( int32_t i = 0 ; i < numOfOutput ; + + i ) {
2022-06-17 15:23:37 +00:00
pCtx [ i ] . resultInfo = getResultEntryInfo ( pResult , i , rowEntryInfoOffset ) ;
2022-08-11 02:19:06 +00:00
if ( init ) {
continue ;
}
2022-02-14 02:58:58 +00:00
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-08-11 02:19:06 +00:00
} else {
init = true ;
2022-02-14 02:58:58 +00:00
}
}
}
2022-11-04 14:13:40 +00:00
void doFilter ( SSDataBlock * pBlock , SFilterInfo * pFilterInfo , SColMatchInfo * pColMatchInfo ) {
if ( pFilterInfo = = NULL | | pBlock - > info . rows = = 0 ) {
2022-07-19 08:22:05 +00:00
return ;
}
2022-07-22 02:50:54 +00:00
2022-09-21 02:26:55 +00:00
SFilterColumnParam param1 = { . numOfCols = taosArrayGetSize ( pBlock - > pDataBlock ) , . pDataBlock = pBlock - > pDataBlock } ;
2022-11-18 09:21:50 +00:00
int32_t code = filterSetDataFromSlotId ( pFilterInfo , & param1 ) ;
2022-04-06 09:59:08 +00:00
2022-09-21 02:26:55 +00:00
SColumnInfoData * p = NULL ;
2022-09-26 10:39:47 +00:00
int32_t status = 0 ;
2022-09-20 02:41:35 +00:00
2022-05-14 08:28:34 +00:00
// todo the keep seems never to be True??
2022-11-04 14:13:40 +00:00
bool keep = filterExecute ( pFilterInfo , pBlock , & p , NULL , param1 . numOfCols , & status ) ;
2022-09-21 02:26:55 +00:00
extractQualifiedTupleByFilterResult ( pBlock , p , keep , status ) ;
2022-09-20 02:41:35 +00:00
2022-09-20 06:37:50 +00:00
if ( pColMatchInfo ! = NULL ) {
2022-11-18 09:21:50 +00:00
size_t size = taosArrayGetSize ( pColMatchInfo - > pList ) ;
2022-11-04 14:13:40 +00:00
for ( int32_t i = 0 ; i < size ; + + i ) {
2022-10-24 08:44:44 +00:00
SColMatchItem * pInfo = taosArrayGet ( pColMatchInfo - > pList , i ) ;
2022-07-22 15:52:48 +00:00
if ( pInfo - > colId = = PRIMARYKEY_TIMESTAMP_COL_ID ) {
2022-10-24 08:44:44 +00:00
SColumnInfoData * pColData = taosArrayGet ( pBlock - > pDataBlock , pInfo - > dstSlotId ) ;
2022-07-22 15:52:48 +00:00
if ( pColData - > info . type = = TSDB_DATA_TYPE_TIMESTAMP ) {
2022-10-24 08:44:44 +00:00
blockDataUpdateTsWindow ( pBlock , pInfo - > dstSlotId ) ;
2022-07-22 15:52:48 +00:00
break ;
}
}
}
}
2022-09-21 02:26:55 +00:00
colDataDestroy ( p ) ;
taosMemoryFree ( p ) ;
2022-05-14 08:28:34 +00:00
}
2022-09-21 02:26:55 +00:00
void extractQualifiedTupleByFilterResult ( SSDataBlock * pBlock , const SColumnInfoData * p , bool keep , int32_t status ) {
2022-05-14 08:28:34 +00:00
if ( keep ) {
return ;
}
2022-09-20 05:40:40 +00:00
int32_t totalRows = pBlock - > info . rows ;
if ( status = = FILTER_RESULT_ALL_QUALIFIED ) {
2022-09-21 02:26:55 +00:00
// here nothing needs to be done
2022-09-20 05:40:40 +00:00
} else if ( status = = FILTER_RESULT_NONE_QUALIFIED ) {
2022-09-20 06:37:50 +00:00
pBlock - > info . rows = 0 ;
2022-09-20 05:40:40 +00:00
} else {
2022-06-10 16:51:59 +00:00
SSDataBlock * px = createOneDataBlock ( pBlock , true ) ;
2022-05-14 08:28:34 +00:00
2022-06-22 09:21:04 +00:00
size_t numOfCols = taosArrayGetSize ( pBlock - > pDataBlock ) ;
for ( int32_t i = 0 ; i < numOfCols ; + + i ) {
2022-06-10 16:51:59 +00:00
SColumnInfoData * pSrc = taosArrayGet ( px - > pDataBlock , i ) ;
SColumnInfoData * pDst = taosArrayGet ( pBlock - > pDataBlock , i ) ;
2022-05-16 10:29:34 +00:00
// it is a reserved column for scalar function, and no data in this column yet.
2022-06-30 09:28:49 +00:00
if ( pDst - > pData = = NULL | | pSrc - > pData = = NULL ) {
2022-05-16 10:29:34 +00:00
continue ;
}
2022-06-11 03:28:59 +00:00
colInfoDataCleanup ( pDst , pBlock - > info . rows ) ;
2022-05-14 08:28:34 +00:00
int32_t numOfRows = 0 ;
2022-05-14 08:40:51 +00:00
for ( int32_t j = 0 ; j < totalRows ; + + j ) {
2022-09-21 02:26:55 +00:00
if ( ( ( int8_t * ) p - > pData ) [ j ] = = 0 ) {
2022-04-09 05:36:36 +00:00
continue ;
}
2022-04-06 09:59:08 +00:00
2022-04-09 05:36:36 +00:00
if ( colDataIsNull_s ( pSrc , j ) ) {
2022-05-14 08:28:34 +00:00
colDataAppendNULL ( pDst , numOfRows ) ;
2022-04-09 05:36:36 +00:00
} else {
2022-05-14 08:28:34 +00:00
colDataAppend ( pDst , numOfRows , colDataGetData ( pSrc , j ) , false ) ;
2022-04-09 05:36:36 +00:00
}
2022-05-14 08:28:34 +00:00
numOfRows + = 1 ;
2022-04-06 15:00:32 +00:00
}
2022-04-06 09:59:08 +00:00
2022-09-21 02:26:55 +00:00
// todo this value can be assigned directly
2022-05-14 08:40:51 +00:00
if ( pBlock - > info . rows = = totalRows ) {
pBlock - > info . rows = numOfRows ;
} else {
ASSERT ( pBlock - > info . rows = = numOfRows ) ;
}
2022-05-14 08:28:34 +00:00
}
2022-06-11 06:10:00 +00:00
2022-06-08 08:13:52 +00:00
blockDataDestroy ( px ) ; // fix memory leak
2022-04-06 09:59:08 +00:00
}
}
2022-09-26 10:39:47 +00:00
void doSetTableGroupOutputBuf ( SOperatorInfo * pOperator , int32_t numOfOutput , uint64_t groupId ) {
2021-11-02 05:37:31 +00:00
// for simple group by query without interval, all the tables belong to one group result.
2022-07-29 01:56:03 +00:00
SExecTaskInfo * pTaskInfo = pOperator - > pTaskInfo ;
SAggOperatorInfo * pAggInfo = pOperator - > info ;
2022-02-14 02:58:58 +00:00
SResultRowInfo * pResultRowInfo = & pAggInfo - > binfo . resultRowInfo ;
2022-06-18 04:00:41 +00:00
SqlFunctionCtx * pCtx = pOperator - > exprSupp . pCtx ;
int32_t * rowEntryInfoOffset = pOperator - > exprSupp . rowEntryInfoOffset ;
2022-02-14 02:58:58 +00:00
2022-05-03 06:43:53 +00:00
SResultRow * pResultRow = doSetResultOutBufByKey ( pAggInfo - > aggSup . pResultBuf , pResultRowInfo , ( char * ) & groupId ,
2022-04-28 08:31:35 +00:00
sizeof ( groupId ) , 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-06-17 15:23:37 +00:00
setResultRowInitCtx ( pResultRow , pCtx , numOfOutput , rowEntryInfoOffset ) ;
2021-11-02 05:37:31 +00:00
}
2022-07-29 01:56:03 +00:00
static void setExecutionContext ( SOperatorInfo * pOperator , int32_t numOfOutput , uint64_t groupId ) {
SAggOperatorInfo * pAggInfo = pOperator - > info ;
if ( pAggInfo - > groupId ! = UINT64_MAX & & pAggInfo - > groupId = = groupId ) {
2021-11-02 05:37:31 +00:00
return ;
}
2022-07-29 01:56:03 +00:00
doSetTableGroupOutputBuf ( pOperator , numOfOutput , groupId ) ;
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
}
2022-08-12 03:22:41 +00:00
static void doUpdateNumOfRows ( SqlFunctionCtx * pCtx , SResultRow * pRow , int32_t numOfExprs ,
const int32_t * rowCellOffset ) {
2022-08-06 13:39:53 +00:00
bool returnNotNull = false ;
2022-05-20 15:59:17 +00:00
for ( int32_t j = 0 ; j < numOfExprs ; + + j ) {
2022-06-17 11:01:45 +00:00
struct SResultRowEntryInfo * pResInfo = getResultEntryInfo ( pRow , j , rowCellOffset ) ;
2022-05-20 15:59:17 +00:00
if ( ! isRowEntryInitialized ( pResInfo ) ) {
continue ;
}
if ( pRow - > numOfRows < pResInfo - > numOfRes ) {
pRow - > numOfRows = pResInfo - > numOfRes ;
}
2022-08-06 13:39:53 +00:00
2022-08-06 22:39:26 +00:00
if ( fmIsNotNullOutputFunc ( pCtx [ j ] . functionId ) ) {
2022-08-06 13:39:53 +00:00
returnNotNull = true ;
}
2022-05-20 15:59:17 +00:00
}
2022-08-06 22:08:12 +00:00
// if all expr skips all blocks, e.g. all null inputs for max function, output one row in final result.
// except for first/last, which require not null output, output no rows
2022-08-06 13:39:53 +00:00
if ( pRow - > numOfRows = = 0 & & ! returnNotNull ) {
2022-08-06 12:11:12 +00:00
pRow - > numOfRows = 1 ;
2022-05-20 15:59:17 +00:00
}
}
2022-09-13 09:39:43 +00:00
static void doCopyResultToDataBlock ( SExprInfo * pExprInfo , int32_t numOfExprs , SResultRow * pRow , SqlFunctionCtx * pCtx ,
SSDataBlock * pBlock , const int32_t * rowEntryOffset , SExecTaskInfo * pTaskInfo ) {
2022-06-09 11:21:52 +00:00
for ( int32_t j = 0 ; j < numOfExprs ; + + j ) {
int32_t slotId = pExprInfo [ j ] . base . resSchema . slotId ;
2022-09-13 09:39:43 +00:00
pCtx [ j ] . resultInfo = getResultEntryInfo ( pRow , j , rowEntryOffset ) ;
2022-06-09 11:21:52 +00:00
if ( pCtx [ j ] . fpSet . finalize ) {
2022-09-29 08:59:20 +00:00
if ( strcmp ( pCtx [ j ] . pExpr - > pExpr - > _function . functionName , " _group_key " ) = = 0 ) {
2022-09-29 09:04:31 +00:00
// for groupkey along with functions that output multiple lines(e.g. Histogram)
// need to match groupkey result for each output row of that function.
2022-09-29 08:59:20 +00:00
if ( pCtx [ j ] . resultInfo - > numOfRes ! = 0 ) {
pCtx [ j ] . resultInfo - > numOfRes = pRow - > numOfRows ;
}
}
2022-06-09 11:21:52 +00:00
int32_t code = pCtx [ j ] . fpSet . finalize ( & pCtx [ j ] , pBlock ) ;
if ( TAOS_FAILED ( code ) ) {
qError ( " %s build result data block error, code %s " , GET_TASKID ( pTaskInfo ) , tstrerror ( code ) ) ;
2022-08-24 09:09:33 +00:00
T_LONG_JMP ( pTaskInfo - > env , code ) ;
2022-06-09 11:21:52 +00:00
}
} else if ( strcmp ( pCtx [ j ] . pExpr - > pExpr - > _function . functionName , " _select_value " ) = = 0 ) {
2022-09-13 09:39:43 +00:00
// do nothing
2022-06-09 11:21:52 +00:00
} else {
2022-07-13 07:13:01 +00:00
// expand the result into multiple rows. E.g., _wstart, top(k, 20)
// the _wstart needs to copy to 20 following rows, since the results of top-k expands to 20 different rows.
2022-06-09 11:21:52 +00:00
SColumnInfoData * pColInfoData = taosArrayGet ( pBlock - > pDataBlock , slotId ) ;
char * in = GET_ROWCELL_INTERBUF ( pCtx [ j ] . resultInfo ) ;
for ( int32_t k = 0 ; k < pRow - > numOfRows ; + + k ) {
colDataAppend ( pColInfoData , pBlock - > info . rows + k , in , pCtx [ j ] . resultInfo - > isNullRes ) ;
}
}
}
2022-09-13 09:39:43 +00:00
}
2022-09-14 03:00:44 +00:00
// todo refactor. SResultRow has direct pointer in miainfo
int32_t finalizeResultRows ( SDiskbasedBuf * pBuf , SResultRowPosition * resultRowPosition , SExprSupp * pSup ,
SSDataBlock * pBlock , SExecTaskInfo * pTaskInfo ) {
2022-09-13 09:39:43 +00:00
SFilePage * page = getBufPage ( pBuf , resultRowPosition - > pageId ) ;
SResultRow * pRow = ( SResultRow * ) ( ( char * ) page + resultRowPosition - > offset ) ;
SqlFunctionCtx * pCtx = pSup - > pCtx ;
SExprInfo * pExprInfo = pSup - > pExprInfo ;
const int32_t * rowEntryOffset = pSup - > rowEntryInfoOffset ;
doUpdateNumOfRows ( pCtx , pRow , pSup - > numOfExprs , rowEntryOffset ) ;
if ( pRow - > numOfRows = = 0 ) {
releaseBufPage ( pBuf , page ) ;
return 0 ;
}
int32_t size = pBlock - > info . capacity ;
while ( pBlock - > info . rows + pRow - > numOfRows > size ) {
size = size * 1.25 ;
}
int32_t code = blockDataEnsureCapacity ( pBlock , size ) ;
if ( TAOS_FAILED ( code ) ) {
releaseBufPage ( pBuf , page ) ;
qError ( " %s ensure result data capacity failed, code %s " , GET_TASKID ( pTaskInfo ) , tstrerror ( code ) ) ;
T_LONG_JMP ( pTaskInfo - > env , code ) ;
}
doCopyResultToDataBlock ( pExprInfo , pSup - > numOfExprs , pRow , pCtx , pBlock , rowEntryOffset , pTaskInfo ) ;
2022-06-09 11:21:52 +00:00
releaseBufPage ( pBuf , page ) ;
2022-06-10 10:33:24 +00:00
pBlock - > info . rows + = pRow - > numOfRows ;
2022-06-09 11:21:52 +00:00
return 0 ;
}
2022-08-02 05:58:54 +00:00
int32_t doCopyToSDataBlock ( SExecTaskInfo * pTaskInfo , SSDataBlock * pBlock , SExprSupp * pSup , SDiskbasedBuf * pBuf ,
SGroupResInfo * pGroupResInfo ) {
SExprInfo * pExprInfo = pSup - > pExprInfo ;
int32_t numOfExprs = pSup - > numOfExprs ;
int32_t * rowEntryOffset = pSup - > rowEntryInfoOffset ;
SqlFunctionCtx * pCtx = pSup - > pCtx ;
2021-11-02 05:37:31 +00:00
int32_t numOfRows = getNumOfTotalRes ( pGroupResInfo ) ;
2022-07-16 08:30:09 +00:00
2022-08-02 05:58:54 +00:00
for ( int32_t i = pGroupResInfo - > index ; i < numOfRows ; i + = 1 ) {
2022-04-28 08:31:35 +00:00
SResKeyPos * pPos = taosArrayGetP ( pGroupResInfo - > pRows , i ) ;
SFilePage * page = getBufPage ( pBuf , pPos - > pos . pageId ) ;
2022-07-16 08:30:09 +00:00
2022-04-24 12:48:42 +00:00
SResultRow * pRow = ( SResultRow * ) ( ( char * ) page + pPos - > pos . offset ) ;
2022-05-20 15:59:17 +00:00
2022-08-08 09:56:26 +00:00
doUpdateNumOfRows ( pCtx , pRow , numOfExprs , rowEntryOffset ) ;
2022-08-02 05:58:54 +00:00
// no results, continue to check the next one
2021-11-02 05:37:31 +00:00
if ( pRow - > numOfRows = = 0 ) {
pGroupResInfo - > index + = 1 ;
2022-05-20 15:59:17 +00:00
releaseBufPage ( pBuf , page ) ;
2021-11-02 05:37:31 +00:00
continue ;
}
2022-11-28 04:32:40 +00:00
if ( pBlock - > info . id . groupId = = 0 ) {
pBlock - > info . id . groupId = pPos - > groupId ;
2022-05-20 08:50:39 +00:00
} else {
// current value belongs to different group, it can't be packed into one datablock
2022-11-28 04:32:40 +00:00
if ( pBlock - > info . id . groupId ! = pPos - > groupId ) {
2022-05-20 15:59:17 +00:00
releaseBufPage ( pBuf , page ) ;
2022-05-20 08:50:39 +00:00
break ;
}
}
2022-05-17 04:36:32 +00:00
if ( pBlock - > info . rows + pRow - > numOfRows > pBlock - > info . capacity ) {
2022-08-02 05:58:54 +00:00
ASSERT ( pBlock - > info . rows > 0 ) ;
2022-05-20 15:59:17 +00:00
releaseBufPage ( pBuf , page ) ;
2021-11-02 05:37:31 +00:00
break ;
}
pGroupResInfo - > index + = 1 ;
2022-09-13 09:39:43 +00:00
doCopyResultToDataBlock ( pExprInfo , numOfExprs , pRow , pCtx , pBlock , rowEntryOffset , pTaskInfo ) ;
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 ;
2021-11-02 05:37:31 +00:00
}
2022-05-23 11:50:08 +00:00
qDebug ( " %s result generated, rows:%d, groupId:% " PRIu64 , GET_TASKID ( pTaskInfo ) , pBlock - > info . rows ,
2022-11-28 04:32:40 +00:00
pBlock - > info . id . groupId ) ;
2022-08-02 05:58:54 +00:00
2022-05-21 03:02:53 +00:00
blockDataUpdateTsWindow ( pBlock , 0 ) ;
2021-11-02 05:37:31 +00:00
return 0 ;
}
2022-10-11 07:27:56 +00:00
void doBuildStreamResBlock ( SOperatorInfo * pOperator , SOptrBasicInfo * pbInfo , SGroupResInfo * pGroupResInfo ,
SDiskbasedBuf * pBuf ) {
SExecTaskInfo * pTaskInfo = pOperator - > pTaskInfo ;
SSDataBlock * pBlock = pbInfo - > pRes ;
// set output datablock version
pBlock - > info . version = pTaskInfo - > version ;
blockDataCleanup ( pBlock ) ;
if ( ! hasRemainResults ( pGroupResInfo ) ) {
return ;
}
// clear the existed group id
2022-11-28 04:32:40 +00:00
pBlock - > info . id . groupId = 0 ;
2022-10-11 07:27:56 +00:00
ASSERT ( ! pbInfo - > mergeResultBlock ) ;
doCopyToSDataBlock ( pTaskInfo , pBlock , & pOperator - > exprSupp , pBuf , pGroupResInfo ) ;
2022-11-18 09:21:50 +00:00
void * tbname = NULL ;
2022-11-28 04:32:40 +00:00
if ( streamStateGetParName ( pTaskInfo - > streamInfo . pState , pBlock - > info . id . groupId , & tbname ) < 0 ) {
2022-11-18 09:21:50 +00:00
pBlock - > info . parTbName [ 0 ] = 0 ;
} else {
memcpy ( pBlock - > info . parTbName , tbname , TSDB_TABLE_NAME_LEN ) ;
2022-10-11 07:27:56 +00:00
}
2022-11-18 09:21:50 +00:00
tdbFree ( tbname ) ;
2022-10-11 07:27:56 +00:00
}
2022-05-23 11:50:08 +00:00
void doBuildResultDatablock ( SOperatorInfo * pOperator , SOptrBasicInfo * pbInfo , SGroupResInfo * pGroupResInfo ,
SDiskbasedBuf * pBuf ) {
2022-05-13 10:18:54 +00:00
SExecTaskInfo * pTaskInfo = pOperator - > pTaskInfo ;
2022-08-02 05:58:54 +00:00
SSDataBlock * pBlock = pbInfo - > pRes ;
2022-05-03 07:04:34 +00:00
2022-07-22 09:39:59 +00:00
// set output datablock version
pBlock - > info . version = pTaskInfo - > version ;
2022-03-17 05:11:06 +00:00
blockDataCleanup ( pBlock ) ;
2022-07-29 01:56:03 +00:00
if ( ! hasRemainResults ( pGroupResInfo ) ) {
2021-11-02 05:37:31 +00:00
return ;
}
2022-05-20 08:50:39 +00:00
// clear the existed group id
2022-11-28 04:32:40 +00:00
pBlock - > info . id . groupId = 0 ;
2022-08-02 05:58:54 +00:00
if ( ! pbInfo - > mergeResultBlock ) {
doCopyToSDataBlock ( pTaskInfo , pBlock , & pOperator - > exprSupp , pBuf , pGroupResInfo ) ;
} else {
2022-08-12 03:22:41 +00:00
while ( hasRemainResults ( pGroupResInfo ) ) {
2022-08-02 05:58:54 +00:00
doCopyToSDataBlock ( pTaskInfo , pBlock , & pOperator - > exprSupp , pBuf , pGroupResInfo ) ;
if ( pBlock - > info . rows > = pOperator - > resultInfo . threshold ) {
break ;
2021-11-02 05:37:31 +00:00
}
2022-08-02 05:58:54 +00:00
// clearing group id to continue to merge data that belong to different groups
2022-11-28 04:32:40 +00:00
pBlock - > info . id . groupId = 0 ;
2021-11-02 05:37:31 +00:00
}
2022-08-02 05:58:54 +00:00
// clear the group id info in SSDataBlock, since the client does not need it
2022-11-28 04:32:40 +00:00
pBlock - > info . id . groupId = 0 ;
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)) {
2022-08-24 09:09:33 +00:00
// T_LONG_JMP(pRuntimeEnv->env, TSDB_CODE_TSC_QUERY_CANCELLED);
2022-03-29 07:24:25 +00:00
// }
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) {
2022-08-24 09:09:33 +00:00
// T_LONG_JMP(pRuntimeEnv->env, terrno);
2022-03-29 07:24:25 +00:00
// }
// }
// 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) {
2022-08-24 09:09:33 +00:00
// T_LONG_JMP(pRuntimeEnv->env, terrno);
2022-03-29 07:24:25 +00:00
// }
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
}
2022-05-23 11:50:08 +00:00
int32_t getTableScanInfo ( SOperatorInfo * pOperator , int32_t * order , int32_t * scanFlag ) {
2022-05-12 15:10:23 +00:00
// todo add more information about exchange operation
2022-05-19 15:47:27 +00:00
int32_t type = pOperator - > operatorType ;
2022-05-23 11:50:08 +00:00
if ( type = = QUERY_NODE_PHYSICAL_PLAN_EXCHANGE | | type = = QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN | |
2022-06-20 04:54:46 +00:00
type = = QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN | | type = = QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN | |
2022-06-28 15:24:20 +00:00
type = = QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN | | type = = QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN ) {
2022-05-12 15:10:23 +00:00
* order = TSDB_ORDER_ASC ;
* scanFlag = MAIN_SCAN ;
return TSDB_CODE_SUCCESS ;
2022-07-25 07:17:53 +00:00
} else if ( type = = QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN ) {
2022-05-12 15:10:23 +00:00
STableScanInfo * pTableScanInfo = pOperator - > info ;
2022-11-18 01:47:26 +00:00
* order = pTableScanInfo - > base . cond . order ;
* scanFlag = pTableScanInfo - > base . scanFlag ;
2022-05-12 15:10:23 +00:00
return TSDB_CODE_SUCCESS ;
2022-07-25 07:17:53 +00:00
} else if ( type = = QUERY_NODE_PHYSICAL_PLAN_TABLE_MERGE_SCAN ) {
STableMergeScanInfo * pTableScanInfo = pOperator - > info ;
2022-11-18 01:47:26 +00:00
* order = pTableScanInfo - > base . cond . order ;
* scanFlag = pTableScanInfo - > base . scanFlag ;
2022-07-25 07:17:53 +00:00
return TSDB_CODE_SUCCESS ;
2022-05-12 15:10:23 +00:00
} else {
2022-04-26 06:10:25 +00:00
if ( pOperator - > pDownstream = = NULL | | pOperator - > pDownstream [ 0 ] = = NULL ) {
2022-05-12 09:33:36 +00:00
return TSDB_CODE_INVALID_PARA ;
2022-04-26 06:10:25 +00:00
} else {
2022-05-12 09:33:36 +00:00
return getTableScanInfo ( pOperator - > pDownstream [ 0 ] , order , scanFlag ) ;
2022-04-26 05:53:11 +00:00
}
}
}
2022-06-29 08:19:19 +00:00
2022-11-27 08:04:36 +00:00
static int32_t createDataBlockForEmptyInput ( SOperatorInfo * pOperator , SSDataBlock * * ppBlock ) {
if ( ! tsCountAlwaysReturnValue ) {
return TSDB_CODE_SUCCESS ;
}
2022-11-29 11:01:09 +00:00
SOperatorInfo * downstream = pOperator - > pDownstream [ 0 ] ;
2022-11-29 11:32:51 +00:00
if ( downstream - > operatorType = = QUERY_NODE_PHYSICAL_PLAN_PARTITION | |
2022-11-29 11:01:09 +00:00
( downstream - > operatorType = = QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN & &
( ( STableScanInfo * ) downstream - > info ) - > hasGroupByTag = = true ) ) {
return TSDB_CODE_SUCCESS ;
}
2022-11-27 08:04:36 +00:00
SqlFunctionCtx * pCtx = pOperator - > exprSupp . pCtx ;
bool hasCountFunc = false ;
for ( int32_t i = 0 ; i < pOperator - > exprSupp . numOfExprs ; + + i ) {
if ( ( strcmp ( pCtx [ i ] . pExpr - > pExpr - > _function . functionName , " count " ) = = 0 ) | |
2022-11-27 16:30:39 +00:00
( strcmp ( pCtx [ i ] . pExpr - > pExpr - > _function . functionName , " hyperloglog " ) = = 0 ) | |
( strcmp ( pCtx [ i ] . pExpr - > pExpr - > _function . functionName , " _hyperloglog_partial " ) = = 0 ) | |
( strcmp ( pCtx [ i ] . pExpr - > pExpr - > _function . functionName , " _hyperloglog_merge " ) = = 0 ) ) {
2022-11-27 08:04:36 +00:00
hasCountFunc = true ;
break ;
}
}
if ( ! hasCountFunc ) {
return TSDB_CODE_SUCCESS ;
}
SSDataBlock * pBlock = createDataBlock ( ) ;
2022-11-27 12:38:39 +00:00
pBlock - > info . rows = 1 ;
2022-11-27 08:04:36 +00:00
pBlock - > info . capacity = 0 ;
for ( int32_t i = 0 ; i < pOperator - > exprSupp . numOfExprs ; + + i ) {
2022-11-27 12:38:39 +00:00
SColumnInfoData colInfo = { 0 } ;
colInfo . hasNull = true ;
colInfo . info . type = TSDB_DATA_TYPE_NULL ;
colInfo . info . bytes = 1 ;
2022-11-27 08:04:36 +00:00
SExprInfo * pOneExpr = & pOperator - > exprSupp . pExprInfo [ i ] ;
for ( int32_t j = 0 ; j < pOneExpr - > base . numOfParams ; + + j ) {
SFunctParam * pFuncParam = & pOneExpr - > base . pParam [ j ] ;
if ( pFuncParam - > type = = FUNC_PARAM_TYPE_COLUMN ) {
int32_t slotId = pFuncParam - > pCol - > slotId ;
2022-11-27 12:38:39 +00:00
int32_t numOfCols = taosArrayGetSize ( pBlock - > pDataBlock ) ;
if ( slotId > = numOfCols ) {
taosArrayEnsureCap ( pBlock - > pDataBlock , slotId + 1 ) ;
for ( int32_t k = numOfCols ; k < slotId + 1 ; + + k ) {
taosArrayPush ( pBlock - > pDataBlock , & colInfo ) ;
}
}
2022-11-27 08:04:36 +00:00
} else if ( pFuncParam - > type = = FUNC_PARAM_TYPE_VALUE ) {
2022-11-27 12:38:39 +00:00
// do nothing
2022-11-27 08:04:36 +00:00
}
}
}
2022-11-27 12:38:39 +00:00
blockDataEnsureCapacity ( pBlock , pBlock - > info . rows ) ;
2022-11-27 08:04:36 +00:00
* ppBlock = pBlock ;
return TSDB_CODE_SUCCESS ;
}
static void destroyDataBlockForEmptyInput ( bool blockAllocated , SSDataBlock * * ppBlock ) {
if ( ! blockAllocated ) {
return ;
}
blockDataDestroy ( * ppBlock ) ;
* ppBlock = NULL ;
}
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-06-22 05:08:20 +00:00
SExprSupp * pSup = & pOperator - > exprSupp ;
SOperatorInfo * downstream = pOperator - > pDownstream [ 0 ] ;
2021-11-02 05:37:31 +00:00
2022-05-24 03:29:51 +00:00
int64_t st = taosGetTimestampUs ( ) ;
2022-05-12 09:33:36 +00:00
int32_t order = TSDB_ORDER_ASC ;
int32_t scanFlag = MAIN_SCAN ;
2022-11-27 08:04:36 +00:00
bool hasValidBlock = false ;
bool blockAllocated = false ;
2022-03-12 10:02:56 +00:00
while ( 1 ) {
2022-05-03 07:27:13 +00:00
SSDataBlock * pBlock = downstream - > fpSet . getNextFn ( downstream ) ;
2021-11-02 05:37:31 +00:00
if ( pBlock = = NULL ) {
2022-11-29 11:32:51 +00:00
if ( ! hasValidBlock ) {
2022-11-27 08:04:36 +00:00
createDataBlockForEmptyInput ( pOperator , & pBlock ) ;
if ( pBlock = = NULL ) {
break ;
}
blockAllocated = true ;
} else {
break ;
}
2021-11-02 05:37:31 +00:00
}
2022-11-27 08:04:36 +00:00
hasValidBlock = true ;
2021-11-02 05:37:31 +00:00
2022-05-12 09:33:36 +00:00
int32_t code = getTableScanInfo ( pOperator , & order , & scanFlag ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
2022-11-27 08:04:36 +00:00
destroyDataBlockForEmptyInput ( blockAllocated , & pBlock ) ;
2022-08-24 09:09:33 +00:00
T_LONG_JMP ( pTaskInfo - > env , code ) ;
2022-05-12 09:33:36 +00:00
}
2022-05-10 09:46:45 +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.
2022-11-28 14:54:27 +00:00
if ( pAggInfo - > scalarExprSup . pExprInfo ! = NULL & & ! blockAllocated ) {
2022-06-18 06:49:27 +00:00
SExprSupp * pSup1 = & pAggInfo - > scalarExprSup ;
code = projectApplyFunctions ( pSup1 - > pExprInfo , pBlock , pBlock , pSup1 - > pCtx , pSup1 - > numOfExprs , NULL ) ;
2022-04-28 10:08:56 +00:00
if ( code ! = TSDB_CODE_SUCCESS ) {
2022-11-27 08:04:36 +00:00
destroyDataBlockForEmptyInput ( blockAllocated , & pBlock ) ;
2022-08-24 09:09:33 +00:00
T_LONG_JMP ( pTaskInfo - > env , code ) ;
2022-04-28 10:08:56 +00:00
}
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-11-28 04:32:40 +00:00
setExecutionContext ( pOperator , pOperator - > exprSupp . numOfExprs , pBlock - > info . id . groupId ) ;
2022-10-20 10:07:38 +00:00
setInputDataBlock ( pSup , pBlock , order , scanFlag , true ) ;
2022-07-12 07:30:38 +00:00
code = doAggregateImpl ( pOperator , pSup - > pCtx ) ;
2022-05-13 04:17:09 +00:00
if ( code ! = 0 ) {
2022-11-27 08:04:36 +00:00
destroyDataBlockForEmptyInput ( blockAllocated , & pBlock ) ;
2022-08-24 09:09:33 +00:00
T_LONG_JMP ( pTaskInfo - > env , code ) ;
2022-05-13 04:17:09 +00:00
}
2022-11-27 08:04:36 +00:00
destroyDataBlockForEmptyInput ( blockAllocated , & pBlock ) ;
2021-11-02 05:37:31 +00:00
}
2022-11-25 10:16:27 +00:00
// the downstream operator may return with error code, so let's check the code before generating results.
if ( pTaskInfo - > code ! = TSDB_CODE_SUCCESS ) {
T_LONG_JMP ( pTaskInfo - > env , pTaskInfo - > code ) ;
}
2022-05-17 04:16:44 +00:00
initGroupedResultInfo ( & pAggInfo - > groupResInfo , pAggInfo - > aggSup . pResultRowHashTable , 0 ) ;
2022-03-12 10:02:56 +00:00
OPTR_SET_OPENED ( pOperator ) ;
2022-05-24 03:29:51 +00:00
2022-05-26 08:29:52 +00:00
pOperator - > cost . openCost = ( taosGetTimestampUs ( ) - st ) / 1000.0 ;
2022-11-25 10:16:27 +00:00
return pTaskInfo - > code ;
2022-03-12 10:02:56 +00:00
}
2022-05-03 07:27:13 +00:00
static SSDataBlock * getAggregateResult ( SOperatorInfo * pOperator ) {
2022-03-29 07:24:25 +00:00
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 ) {
2022-11-09 11:14:27 +00:00
setOperatorCompleted ( pOperator ) ;
2022-03-12 10:02:56 +00:00
return NULL ;
}
2022-04-16 11:10:21 +00:00
blockDataEnsureCapacity ( pInfo - > pRes , pOperator - > resultInfo . capacity ) ;
2022-07-06 05:54:11 +00:00
while ( 1 ) {
doBuildResultDatablock ( pOperator , pInfo , & pAggInfo - > groupResInfo , pAggInfo - > aggSup . pResultBuf ) ;
2022-11-04 14:13:40 +00:00
doFilter ( pInfo - > pRes , pOperator - > exprSupp . pFilterInfo , NULL ) ;
2022-07-06 05:54:11 +00:00
2022-07-29 01:56:03 +00:00
if ( ! hasRemainResults ( & pAggInfo - > groupResInfo ) ) {
2022-11-09 11:14:27 +00:00
setOperatorCompleted ( pOperator ) ;
2022-07-06 05:54:11 +00:00
break ;
}
2021-11-02 05:37:31 +00:00
2022-07-06 05:54:11 +00:00
if ( pInfo - > pRes - > info . rows > 0 ) {
break ;
}
}
2022-08-02 05:58:54 +00:00
2022-06-16 09:39:33 +00:00
size_t rows = blockDataGetNumOfRows ( pInfo - > pRes ) ;
2022-05-24 03:29:51 +00:00
pOperator - > resultInfo . totalRows + = rows ;
2022-05-26 08:29:52 +00:00
return ( rows = = 0 ) ? NULL : pInfo - > pRes ;
2021-11-02 05:37:31 +00:00
}
2022-08-03 02:58:01 +00:00
void destroyExprInfo ( SExprInfo * pExpr , int32_t numOfExprs ) {
2022-08-04 13:31:13 +00:00
for ( int32_t i = 0 ; i < numOfExprs ; + + i ) {
SExprInfo * pExprInfo = & pExpr [ i ] ;
for ( int32_t j = 0 ; j < pExprInfo - > base . numOfParams ; + + j ) {
if ( pExprInfo - > base . pParam [ j ] . type = = FUNC_PARAM_TYPE_COLUMN ) {
taosMemoryFreeClear ( pExprInfo - > base . pParam [ j ] . pCol ) ;
2022-11-20 02:15:26 +00:00
} else if ( pExprInfo - > base . pParam [ j ] . type = = FUNC_PARAM_TYPE_VALUE ) {
taosVariantDestroy ( & pExprInfo - > base . pParam [ j ] . param ) ;
2022-07-13 15:15:58 +00:00
}
2022-08-03 02:58:01 +00:00
}
2022-08-04 13:31:13 +00:00
taosMemoryFree ( pExprInfo - > base . pParam ) ;
taosMemoryFree ( pExprInfo - > pExpr ) ;
2022-06-04 11:19:49 +00:00
}
}
2022-11-10 07:47:07 +00:00
void destroyOperatorInfo ( SOperatorInfo * pOperator ) {
2021-11-02 05:37:31 +00:00
if ( pOperator = = NULL ) {
return ;
}
2022-04-26 12:26:32 +00:00
if ( pOperator - > fpSet . closeFn ! = NULL ) {
2022-08-25 02:55:28 +00:00
pOperator - > fpSet . closeFn ( pOperator - > info ) ;
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-07-11 11:36:19 +00:00
cleanupExprSupp ( & pOperator - > exprSupp ) ;
2022-03-25 16:29:53 +00:00
taosMemoryFreeClear ( pOperator ) ;
2021-11-02 05:37:31 +00:00
}
2022-05-26 09:48:07 +00:00
int32_t getBufferPgSize ( int32_t rowSize , uint32_t * defaultPgsz , uint32_t * defaultBufsz ) {
* defaultPgsz = 4096 ;
while ( * defaultPgsz < rowSize * 4 ) {
* defaultPgsz < < = 1u ;
}
2022-11-03 02:47:55 +00:00
// The default buffer for each operator in query is 10MB.
2022-05-26 09:48:07 +00:00
// at least four pages need to be in buffer
2022-11-03 02:47:55 +00:00
// TODO: make this variable to be configurable.
* defaultBufsz = 4096 * 2560 ;
2022-05-26 09:48:07 +00:00
if ( ( * defaultBufsz ) < = ( * defaultPgsz ) ) {
( * defaultBufsz ) = ( * defaultPgsz ) * 4 ;
}
return 0 ;
}
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-08-31 03:35:25 +00:00
int32_t code = 0 ;
2022-02-22 05:12:03 +00:00
_hash_fn_t hashFn = taosGetDefaultHashFunction ( TSDB_DATA_TYPE_BINARY ) ;
2022-08-29 14:42:15 +00:00
pAggSup - > currentPageId = - 1 ;
2022-04-23 10:29:45 +00:00
pAggSup - > resultRowSize = getResultRowSize ( pCtx , numOfOutput ) ;
pAggSup - > keyBuf = taosMemoryCalloc ( 1 , keyBufSize + POINTER_BYTES + sizeof ( int64_t ) ) ;
2022-08-26 08:52:12 +00:00
pAggSup - > pResultRowHashTable = tSimpleHashInit ( 10 , hashFn ) ;
2022-02-22 05:12:03 +00:00
2022-05-08 08:06:47 +00:00
if ( pAggSup - > keyBuf = = NULL | | pAggSup - > pResultRowHashTable = = NULL ) {
2022-02-22 05:12:03 +00:00
return TSDB_CODE_OUT_OF_MEMORY ;
}
2022-05-27 11:54:22 +00:00
uint32_t defaultPgsz = 0 ;
2022-05-26 09:48:07 +00:00
uint32_t defaultBufsz = 0 ;
getBufferPgSize ( pAggSup - > resultRowSize , & defaultPgsz , & defaultBufsz ) ;
2022-05-08 08:06:47 +00:00
2022-08-04 02:02:09 +00:00
if ( ! osTempSpaceAvailable ( ) ) {
2022-08-30 06:33:03 +00:00
code = TSDB_CODE_NO_AVAIL_DISK ;
qError ( " Init stream agg supporter failed since %s, %s " , terrstr ( code ) , pKey ) ;
return code ;
2022-08-04 02:02:09 +00:00
}
2022-08-23 09:28:08 +00:00
2022-08-30 06:33:03 +00:00
code = createDiskbasedBuf ( & pAggSup - > pResultBuf , defaultPgsz , defaultBufsz , pKey , tsTempDir ) ;
2022-03-15 08:51:50 +00:00
if ( code ! = TSDB_CODE_SUCCESS ) {
2022-08-30 06:33:03 +00:00
qError ( " Create agg result buf failed since %s, %s " , tstrerror ( code ) , pKey ) ;
2022-03-15 08:51:50 +00:00
return code ;
}
2022-08-30 06:33:03 +00:00
return code ;
2022-02-22 05:12:03 +00:00
}
2022-05-03 06:43:53 +00:00
void cleanupAggSup ( SAggSupporter * pAggSup ) {
2022-03-25 16:29:53 +00:00
taosMemoryFreeClear ( pAggSup - > keyBuf ) ;
2022-08-26 08:52:12 +00:00
tSimpleHashCleanup ( pAggSup - > pResultRowHashTable ) ;
2022-03-15 08:51:50 +00:00
destroyDiskbasedBuf ( pAggSup - > pResultBuf ) ;
2022-02-22 05:12:03 +00:00
}
2022-11-27 16:51:18 +00:00
int32_t initAggSup ( SExprSupp * pSup , SAggSupporter * pAggSup , SExprInfo * pExprInfo , int32_t numOfCols , size_t keyBufSize ,
2022-06-20 06:40:13 +00:00
const char * pkey ) {
2022-06-20 15:22:28 +00:00
int32_t code = initExprSupp ( pSup , pExprInfo , numOfCols ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
return code ;
}
2022-08-10 08:20:44 +00:00
code = doInitAggInfoSup ( pAggSup , pSup - > pCtx , numOfCols , keyBufSize , pkey ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
return code ;
}
2022-04-28 08:31:35 +00:00
for ( int32_t i = 0 ; i < numOfCols ; + + i ) {
2022-08-29 10:47:46 +00:00
pSup - > pCtx [ i ] . saveHandle . pBuf = pAggSup - > pResultBuf ;
2022-04-22 14:43:07 +00:00
}
2022-04-02 06:29:43 +00:00
return TSDB_CODE_SUCCESS ;
2022-03-14 08:09:26 +00:00
}
2022-07-21 13:46:55 +00:00
void initResultSizeInfo ( SResultInfo * pResultInfo , int32_t numOfRows ) {
2022-06-29 07:03:17 +00:00
ASSERT ( numOfRows ! = 0 ) ;
2022-07-20 06:07:48 +00:00
pResultInfo - > capacity = numOfRows ;
pResultInfo - > threshold = numOfRows * 0.75 ;
2022-04-18 10:47:59 +00:00
2022-07-20 06:07:48 +00:00
if ( pResultInfo - > threshold = = 0 ) {
pResultInfo - > threshold = numOfRows ;
2022-04-18 10:47:59 +00:00
}
}
2022-06-18 06:49:27 +00:00
void initBasicInfo ( SOptrBasicInfo * pInfo , SSDataBlock * pBlock ) {
pInfo - > pRes = pBlock ;
initResultRowInfo ( & pInfo - > resultRowInfo ) ;
}
2022-07-26 12:49:09 +00:00
void * destroySqlFunctionCtx ( SqlFunctionCtx * pCtx , int32_t numOfOutput ) {
2022-07-11 11:36:19 +00:00
if ( pCtx = = NULL ) {
return NULL ;
}
for ( int32_t i = 0 ; i < numOfOutput ; + + i ) {
for ( int32_t j = 0 ; j < pCtx [ i ] . numOfParams ; + + j ) {
taosVariantDestroy ( & pCtx [ i ] . param [ j ] . param ) ;
}
taosMemoryFreeClear ( pCtx [ i ] . subsidiaries . pCtx ) ;
2022-08-29 10:47:46 +00:00
taosMemoryFreeClear ( pCtx [ i ] . subsidiaries . buf ) ;
2022-07-11 11:36:19 +00:00
taosMemoryFree ( pCtx [ i ] . input . pData ) ;
taosMemoryFree ( pCtx [ i ] . input . pColumnDataAgg ) ;
}
taosMemoryFreeClear ( pCtx ) ;
return NULL ;
}
2022-06-20 15:22:28 +00:00
int32_t initExprSupp ( SExprSupp * pSup , SExprInfo * pExprInfo , int32_t numOfExpr ) {
2022-06-18 06:49:27 +00:00
pSup - > pExprInfo = pExprInfo ;
pSup - > numOfExprs = numOfExpr ;
if ( pSup - > pExprInfo ! = NULL ) {
pSup - > pCtx = createSqlFunctionCtx ( pExprInfo , numOfExpr , & pSup - > rowEntryInfoOffset ) ;
2022-06-20 15:22:28 +00:00
if ( pSup - > pCtx = = NULL ) {
return TSDB_CODE_OUT_OF_MEMORY ;
}
2022-06-18 06:49:27 +00:00
}
2022-06-20 15:22:28 +00:00
return TSDB_CODE_SUCCESS ;
2022-06-18 06:49:27 +00:00
}
2022-07-11 11:36:19 +00:00
void cleanupExprSupp ( SExprSupp * pSupp ) {
destroySqlFunctionCtx ( pSupp - > pCtx , pSupp - > numOfExprs ) ;
if ( pSupp - > pExprInfo ! = NULL ) {
destroyExprInfo ( pSupp - > pExprInfo , pSupp - > numOfExprs ) ;
2022-08-04 13:27:01 +00:00
taosMemoryFreeClear ( pSupp - > pExprInfo ) ;
2022-07-11 11:36:19 +00:00
}
2022-10-11 11:37:06 +00:00
if ( pSupp - > pFilterInfo ! = NULL ) {
filterFreeInfo ( pSupp - > pFilterInfo ) ;
pSupp - > pFilterInfo = NULL ;
}
2022-07-11 11:36:19 +00:00
taosMemoryFree ( pSupp - > rowEntryInfoOffset ) ;
}
2022-10-21 02:37:58 +00:00
SOperatorInfo * createAggregateOperatorInfo ( SOperatorInfo * downstream , SAggPhysiNode * pAggNode ,
SExecTaskInfo * pTaskInfo ) {
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-11-27 16:27:49 +00:00
SSDataBlock * pResBlock = createDataBlockFromDescNode ( pAggNode - > node . pOutputDataBlockDesc ) ;
2022-10-20 03:27:33 +00:00
initBasicInfo ( & pInfo - > binfo , pResBlock ) ;
size_t keyBufSize = sizeof ( int64_t ) + sizeof ( int64_t ) + POINTER_BYTES ;
2022-08-02 07:43:45 +00:00
initResultSizeInfo ( & pOperator - > resultInfo , 4096 ) ;
2022-10-20 03:27:33 +00:00
2022-10-21 02:37:58 +00:00
int32_t num = 0 ;
SExprInfo * pExprInfo = createExprInfo ( pAggNode - > pAggFuncs , pAggNode - > pGroupKeys , & num ) ;
2022-11-27 16:51:18 +00:00
int32_t code = initAggSup ( & pOperator - > exprSupp , & pInfo - > aggSup , pExprInfo , num , keyBufSize , pTaskInfo - > id . str ) ;
2022-04-28 08:31:35 +00:00
if ( code ! = TSDB_CODE_SUCCESS ) {
2022-03-14 06:15:26 +00:00
goto _error ;
}
2022-02-13 06:34:00 +00:00
2022-10-23 07:20:29 +00:00
int32_t numOfScalarExpr = 0 ;
SExprInfo * pScalarExprInfo = NULL ;
if ( pAggNode - > pExprs ! = NULL ) {
pScalarExprInfo = createExprInfo ( pAggNode - > pExprs , NULL , & numOfScalarExpr ) ;
}
2022-06-20 15:22:28 +00:00
code = initExprSupp ( & pInfo - > scalarExprSup , pScalarExprInfo , numOfScalarExpr ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
goto _error ;
}
2021-11-02 05:37:31 +00:00
2022-11-04 14:13:40 +00:00
code = filterInitFromNode ( ( SNode * ) pAggNode - > node . pConditions , & pOperator - > exprSupp . pFilterInfo , 0 ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
goto _error ;
}
2022-10-20 03:27:33 +00:00
pInfo - > binfo . mergeResultBlock = pAggNode - > mergeDataBlock ;
2022-07-29 01:56:03 +00:00
pInfo - > groupId = UINT64_MAX ;
2022-04-16 11:10:21 +00:00
2022-11-18 09:21:50 +00:00
setOperatorInfo ( pOperator , " TableAggregate " , QUERY_NODE_PHYSICAL_PLAN_HASH_AGG , true , OP_NOT_OPENED , pInfo ,
pTaskInfo ) ;
pOperator - > fpSet = createOperatorFpSet ( doOpenAggregateOptr , getAggregateResult , NULL , destroyAggOperatorInfo , NULL ) ;
2022-03-14 06:15:26 +00:00
2022-07-29 01:56:03 +00:00
if ( downstream - > operatorType = = QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN ) {
STableScanInfo * pTableScanInfo = downstream - > info ;
2022-11-18 01:47:26 +00:00
pTableScanInfo - > base . pdInfo . pExprSup = & pOperator - > exprSupp ;
pTableScanInfo - > base . pdInfo . pAggSup = & pInfo - > aggSup ;
2022-07-29 01:56:03 +00:00
}
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-10-18 03:43:58 +00:00
2022-11-03 11:00:13 +00:00
_error :
2022-10-18 03:43:58 +00:00
if ( pInfo ! = NULL ) {
destroyAggOperatorInfo ( pInfo ) ;
}
2022-10-24 07:02:17 +00:00
if ( pOperator ! = NULL ) {
cleanupExprSupp ( & pOperator - > exprSupp ) ;
}
2022-10-21 06:00:46 +00:00
2022-10-24 07:02:17 +00:00
taosMemoryFreeClear ( pOperator ) ;
2022-10-31 08:40:03 +00:00
pTaskInfo - > code = code ;
2022-03-14 06:15:26 +00:00
return NULL ;
2021-11-02 05:37:31 +00:00
}
2022-06-18 06:49:27 +00:00
void cleanupBasicInfo ( SOptrBasicInfo * pInfo ) {
2021-11-02 05:37:31 +00:00
assert ( pInfo ! = NULL ) ;
2022-02-08 10:01:21 +00:00
pInfo - > pRes = blockDataDestroy ( pInfo - > pRes ) ;
2021-11-02 05:37:31 +00:00
}
2022-07-13 15:15:58 +00:00
static void freeItem ( void * pItem ) {
void * * p = pItem ;
if ( * p ! = NULL ) {
taosMemoryFreeClear ( * p ) ;
}
}
2022-08-25 02:55:28 +00:00
void destroyAggOperatorInfo ( void * param ) {
2022-03-29 07:24:25 +00:00
SAggOperatorInfo * pInfo = ( SAggOperatorInfo * ) param ;
2022-07-10 06:48:16 +00:00
cleanupBasicInfo ( & pInfo - > binfo ) ;
2022-07-13 15:15:58 +00:00
cleanupAggSup ( & pInfo - > aggSup ) ;
2022-07-26 09:10:43 +00:00
cleanupExprSupp ( & pInfo - > scalarExprSup ) ;
2022-07-18 05:52:33 +00:00
cleanupGroupResInfo ( & pInfo - > groupResInfo ) ;
2022-07-08 06:26:53 +00:00
taosMemoryFreeClear ( param ) ;
2021-11-02 05:37:31 +00:00
}
2022-03-10 03:12:44 +00:00
2022-05-20 10:00:05 +00:00
static SExecTaskInfo * createExecTaskInfo ( uint64_t queryId , uint64_t taskId , EOPTR_EXEC_MODEL model , char * dbFName ) {
2022-03-25 16:29:53 +00:00
SExecTaskInfo * pTaskInfo = taosMemoryCalloc ( 1 , sizeof ( SExecTaskInfo ) ) ;
2022-11-01 07:00:02 +00:00
if ( pTaskInfo = = NULL ) {
terrno = TSDB_CODE_OUT_OF_MEMORY ;
return NULL ;
}
2022-01-10 11:48:21 +00:00
setTaskStatus ( pTaskInfo , TASK_NOT_COMPLETED ) ;
2022-01-08 14:59:24 +00:00
2022-07-19 09:37:40 +00:00
pTaskInfo - > schemaInfo . dbname = strdup ( dbFName ) ;
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-10-30 14:13:49 +00:00
pTaskInfo - > pTableInfoList = tableListCreate ( ) ;
2022-11-11 09:13:55 +00:00
pTaskInfo - > stopInfo . pStopInfo = taosArrayInit ( 4 , sizeof ( SExchangeOpStopInfo ) ) ;
2022-11-12 08:03:47 +00:00
pTaskInfo - > pResultBlockList = taosArrayInit ( 128 , POINTER_BYTES ) ;
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-05-07 07:11:49 +00:00
pTaskInfo - > id . str = 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-07-21 07:47:22 +00:00
SSchemaWrapper * extractQueriedColumnSchema ( SScanPhysiNode * pScanNode ) ;
2022-07-21 03:20:30 +00:00
int32_t extractTableSchemaInfo ( SReadHandle * pHandle , SScanPhysiNode * pScanNode , SExecTaskInfo * pTaskInfo ) {
2022-05-18 12:39:00 +00:00
SMetaReader mr = { 0 } ;
metaReaderInit ( & mr , pHandle - > meta , 0 ) ;
2022-11-26 13:13:34 +00:00
int32_t code = metaGetTableEntryByUidCache ( & mr , pScanNode - > uid ) ;
2022-07-06 05:33:21 +00:00
if ( code ! = TSDB_CODE_SUCCESS ) {
2022-07-21 13:46:55 +00:00
qError ( " failed to get the table meta, uid:0x% " PRIx64 " , suid:0x% " PRIx64 " , %s " , pScanNode - > uid , pScanNode - > suid ,
GET_TASKID ( pTaskInfo ) ) ;
2022-07-21 07:47:22 +00:00
2022-06-10 09:07:24 +00:00
metaReaderClear ( & mr ) ;
2022-07-06 05:33:21 +00:00
return terrno ;
2022-06-10 09:07:24 +00:00
}
2022-05-18 12:39:00 +00:00
2022-07-21 03:20:30 +00:00
SSchemaInfo * pSchemaInfo = & pTaskInfo - > schemaInfo ;
pSchemaInfo - > tablename = strdup ( mr . me . name ) ;
2022-05-18 12:39:00 +00:00
if ( mr . me . type = = TSDB_SUPER_TABLE ) {
2022-07-21 03:20:30 +00:00
pSchemaInfo - > sw = tCloneSSchemaWrapper ( & mr . me . stbEntry . schemaRow ) ;
pSchemaInfo - > tversion = mr . me . stbEntry . schemaTag . version ;
2022-05-18 12:39:00 +00:00
} else if ( mr . me . type = = TSDB_CHILD_TABLE ) {
2022-07-11 10:01:55 +00:00
tDecoderClear ( & mr . coder ) ;
2022-05-18 12:39:00 +00:00
tb_uid_t suid = mr . me . ctbEntry . suid ;
2022-11-26 13:13:34 +00:00
metaGetTableEntryByUidCache ( & mr , suid ) ;
2022-07-21 03:20:30 +00:00
pSchemaInfo - > sw = tCloneSSchemaWrapper ( & mr . me . stbEntry . schemaRow ) ;
pSchemaInfo - > tversion = mr . me . stbEntry . schemaTag . version ;
2022-05-18 12:39:00 +00:00
} else {
2022-07-21 03:20:30 +00:00
pSchemaInfo - > sw = tCloneSSchemaWrapper ( & mr . me . ntbEntry . schemaRow ) ;
2022-05-18 12:39:00 +00:00
}
2022-05-19 08:16:16 +00:00
metaReaderClear ( & mr ) ;
2022-07-21 03:20:30 +00:00
2022-07-21 07:47:22 +00:00
pSchemaInfo - > qsw = extractQueriedColumnSchema ( pScanNode ) ;
return TSDB_CODE_SUCCESS ;
}
SSchemaWrapper * extractQueriedColumnSchema ( SScanPhysiNode * pScanNode ) {
2022-07-23 02:40:58 +00:00
int32_t numOfCols = LIST_LENGTH ( pScanNode - > pScanCols ) ;
int32_t numOfTags = LIST_LENGTH ( pScanNode - > pScanPseudoCols ) ;
2022-07-21 03:20:30 +00:00
SSchemaWrapper * pqSw = taosMemoryCalloc ( 1 , sizeof ( SSchemaWrapper ) ) ;
2022-07-23 02:40:58 +00:00
pqSw - > pSchema = taosMemoryCalloc ( numOfCols + numOfTags , sizeof ( SSchema ) ) ;
2022-07-21 03:20:30 +00:00
2022-07-21 13:46:55 +00:00
for ( int32_t i = 0 ; i < numOfCols ; + + i ) {
2022-07-21 07:47:22 +00:00
STargetNode * pNode = ( STargetNode * ) nodesListGetNode ( pScanNode - > pScanCols , i ) ;
2022-07-21 03:20:30 +00:00
SColumnNode * pColNode = ( SColumnNode * ) pNode - > pExpr ;
2022-07-21 07:47:22 +00:00
SSchema * pSchema = & pqSw - > pSchema [ pqSw - > nCols + + ] ;
pSchema - > colId = pColNode - > colId ;
pSchema - > type = pColNode - > node . resType . type ;
2022-10-17 06:05:40 +00:00
pSchema - > bytes = pColNode - > node . resType . bytes ;
tstrncpy ( pSchema - > name , pColNode - > colName , tListLen ( pSchema - > name ) ) ;
2022-07-21 03:20:30 +00:00
}
2022-07-23 02:40:58 +00:00
// this the tags and pseudo function columns, we only keep the tag columns
2022-07-25 07:17:53 +00:00
for ( int32_t i = 0 ; i < numOfTags ; + + i ) {
2022-07-23 02:40:58 +00:00
STargetNode * pNode = ( STargetNode * ) nodesListGetNode ( pScanNode - > pScanPseudoCols , i ) ;
int32_t type = nodeType ( pNode - > pExpr ) ;
if ( type = = QUERY_NODE_COLUMN ) {
SColumnNode * pColNode = ( SColumnNode * ) pNode - > pExpr ;
SSchema * pSchema = & pqSw - > pSchema [ pqSw - > nCols + + ] ;
pSchema - > colId = pColNode - > colId ;
pSchema - > type = pColNode - > node . resType . type ;
2022-10-17 06:05:40 +00:00
pSchema - > bytes = pColNode - > node . resType . bytes ;
2022-10-18 03:43:58 +00:00
tstrncpy ( pSchema - > name , pColNode - > colName , tListLen ( pSchema - > name ) ) ;
2022-07-23 02:40:58 +00:00
}
}
2022-07-21 07:47:22 +00:00
return pqSw ;
2022-05-18 12:39:00 +00:00
}
2022-07-19 09:37:40 +00:00
static void cleanupTableSchemaInfo ( SSchemaInfo * pSchemaInfo ) {
taosMemoryFreeClear ( pSchemaInfo - > dbname ) ;
2022-08-03 02:58:01 +00:00
taosMemoryFreeClear ( pSchemaInfo - > tablename ) ;
2022-07-21 03:20:30 +00:00
tDeleteSSchemaWrapper ( pSchemaInfo - > sw ) ;
tDeleteSSchemaWrapper ( pSchemaInfo - > qsw ) ;
2022-07-10 09:34:21 +00:00
}
2022-09-26 10:39:47 +00:00
static void cleanupStreamInfo ( SStreamTaskInfo * pStreamInfo ) { tDeleteSSchemaWrapper ( pStreamInfo - > schema ) ; }
2022-09-16 09:01:41 +00:00
2022-08-03 12:33:09 +00:00
bool groupbyTbname ( SNodeList * pGroupList ) {
2022-07-29 05:54:14 +00:00
bool bytbname = false ;
2022-10-25 16:31:00 +00:00
if ( LIST_LENGTH ( pGroupList ) = = 1 ) {
2022-07-29 05:54:14 +00:00
SNode * p = nodesListGetNode ( pGroupList , 0 ) ;
if ( p - > type = = QUERY_NODE_FUNCTION ) {
// partition by tbname/group by tbname
bytbname = ( strcmp ( ( ( struct SFunctionNode * ) p ) - > functionName , " tbname " ) = = 0 ) ;
}
}
return bytbname ;
}
2022-10-31 02:41:25 +00:00
SOperatorInfo * createOperatorTree ( SPhysiNode * pPhyNode , SExecTaskInfo * pTaskInfo , SReadHandle * pHandle , SNode * pTagCond ,
SNode * pTagIndexCond , const char * pUser ) {
2022-11-08 03:09:19 +00:00
int32_t type = nodeType ( pPhyNode ) ;
2022-10-31 02:41:25 +00:00
STableListInfo * pTableListInfo = pTaskInfo - > pTableInfoList ;
2022-11-08 03:09:19 +00:00
const char * idstr = GET_TASKID ( pTaskInfo ) ;
2022-04-16 02:00:25 +00:00
2022-02-28 09:02:43 +00:00
if ( pPhyNode - > pChildren = = NULL | | LIST_LENGTH ( pPhyNode - > pChildren ) = = 0 ) {
2022-08-02 08:18:55 +00:00
SOperatorInfo * pOperator = NULL ;
2022-04-08 02:24:35 +00:00
if ( QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN = = type ) {
2022-04-23 10:29:45 +00:00
STableScanPhysiNode * pTableScanNode = ( STableScanPhysiNode * ) pPhyNode ;
2022-01-20 08:02:09 +00:00
2022-10-28 11:56:32 +00:00
// NOTE: this is an patch to fix the physical plan
// TODO remove it later
if ( pTableScanNode - > scan . node . pLimit ! = NULL ) {
pTableScanNode - > groupSort = true ;
}
2022-07-21 13:46:55 +00:00
int32_t code =
createScanTableListInfo ( & pTableScanNode - > scan , pTableScanNode - > pGroupTags , pTableScanNode - > groupSort , pHandle ,
2022-11-01 07:00:02 +00:00
pTableListInfo , pTagCond , pTagIndexCond , pTaskInfo ) ;
2022-06-28 05:59:49 +00:00
if ( code ) {
2022-06-24 05:51:33 +00:00
pTaskInfo - > code = code ;
2022-10-31 02:41:25 +00:00
qError ( " failed to createScanTableListInfo, code:%s, %s " , tstrerror ( code ) , idstr ) ;
2022-06-10 09:07:24 +00:00
return NULL ;
}
2022-06-13 11:59:30 +00:00
2022-07-21 03:20:30 +00:00
code = extractTableSchemaInfo ( pHandle , & pTableScanNode - > scan , pTaskInfo ) ;
2022-06-15 08:40:43 +00:00
if ( code ) {
2022-06-16 08:21:01 +00:00
pTaskInfo - > code = terrno ;
2022-06-13 11:59:30 +00:00
return NULL ;
}
2022-08-02 08:18:55 +00:00
pOperator = createTableScanOperatorInfo ( pTableScanNode , pHandle , pTaskInfo ) ;
2022-11-08 06:22:00 +00:00
if ( NULL = = pOperator ) {
pTaskInfo - > code = terrno ;
return NULL ;
}
2022-05-03 15:52:17 +00:00
STableScanInfo * pScanInfo = pOperator - > info ;
2022-11-18 01:47:26 +00:00
pTaskInfo - > cost . pRecoder = & pScanInfo - > base . readRecorder ;
2022-06-15 08:40:43 +00:00
} else if ( QUERY_NODE_PHYSICAL_PLAN_TABLE_MERGE_SCAN = = type ) {
STableMergeScanPhysiNode * pTableScanNode = ( STableMergeScanPhysiNode * ) pPhyNode ;
2022-11-01 07:00:02 +00:00
int32_t code = createScanTableListInfo ( & pTableScanNode - > scan , pTableScanNode - > pGroupTags , true , pHandle ,
pTableListInfo , pTagCond , pTagIndexCond , pTaskInfo ) ;
2022-07-02 12:18:40 +00:00
if ( code ) {
2022-06-27 08:17:58 +00:00
pTaskInfo - > code = code ;
2022-08-25 03:01:36 +00:00
qError ( " failed to createScanTableListInfo, code: %s " , tstrerror ( code ) ) ;
2022-06-23 11:58:12 +00:00
return NULL ;
}
2022-07-13 07:06:27 +00:00
2022-07-21 03:20:30 +00:00
code = extractTableSchemaInfo ( pHandle , & pTableScanNode - > scan , pTaskInfo ) ;
2022-06-23 11:58:12 +00:00
if ( code ) {
pTaskInfo - > code = terrno ;
return NULL ;
}
2022-06-23 06:26:26 +00:00
2022-11-18 03:24:56 +00:00
pOperator = createTableMergeScanOperatorInfo ( pTableScanNode , pHandle , pTaskInfo ) ;
2022-11-08 06:22:00 +00:00
if ( NULL = = pOperator ) {
pTaskInfo - > code = terrno ;
return NULL ;
}
2022-06-24 05:51:33 +00:00
2022-05-03 15:52:17 +00:00
STableScanInfo * pScanInfo = pOperator - > info ;
2022-11-18 01:47:26 +00:00
pTaskInfo - > cost . pRecoder = & pScanInfo - > base . readRecorder ;
2022-04-08 02:24:35 +00:00
} else if ( QUERY_NODE_PHYSICAL_PLAN_EXCHANGE = = type ) {
2022-09-26 10:39:47 +00:00
pOperator = createExchangeOperatorInfo ( pHandle ? pHandle - > pMsgCb - > clientRpc : NULL , ( SExchangePhysiNode * ) pPhyNode ,
pTaskInfo ) ;
2022-04-08 02:24:35 +00:00
} else if ( QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN = = type ) {
2022-05-10 07:34:41 +00:00
STableScanPhysiNode * pTableScanNode = ( STableScanPhysiNode * ) pPhyNode ;
2022-07-19 06:17:53 +00:00
if ( pHandle - > vnode ) {
2022-07-21 13:46:55 +00:00
int32_t code =
createScanTableListInfo ( & pTableScanNode - > scan , pTableScanNode - > pGroupTags , pTableScanNode - > groupSort ,
2022-11-01 07:00:02 +00:00
pHandle , pTableListInfo , pTagCond , pTagIndexCond , pTaskInfo ) ;
2022-07-02 12:18:40 +00:00
if ( code ) {
2022-06-27 08:17:58 +00:00
pTaskInfo - > code = code ;
2022-08-25 03:01:36 +00:00
qError ( " failed to createScanTableListInfo, code: %s " , tstrerror ( code ) ) ;
2022-06-27 08:17:58 +00:00
return NULL ;
}
2022-07-21 13:46:55 +00:00
# ifndef NDEBUG
2022-10-30 14:13:49 +00:00
int32_t sz = tableListGetSize ( pTableListInfo ) ;
2022-10-29 19:08:33 +00:00
qDebug ( " create stream task, total:%d " , sz ) ;
2022-07-21 13:46:55 +00:00
for ( int32_t i = 0 ; i < sz ; i + + ) {
2022-10-30 14:13:49 +00:00
STableKeyInfo * pKeyInfo = tableListGetInfo ( pTableListInfo , i ) ;
2022-11-08 03:09:19 +00:00
qDebug ( " add table uid:% " PRIu64 " , gid:% " PRIu64 , pKeyInfo - > uid , pKeyInfo - > groupId ) ;
2022-07-21 13:46:55 +00:00
}
# endif
2022-08-31 10:06:17 +00:00
}
2022-03-30 11:38:30 +00:00
2022-07-21 07:47:22 +00:00
pTaskInfo - > schemaInfo . qsw = extractQueriedColumnSchema ( & pTableScanNode - > scan ) ;
2022-08-02 08:18:55 +00:00
pOperator = createStreamScanOperatorInfo ( pHandle , pTableScanNode , pTagCond , pTaskInfo ) ;
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-08-02 08:18:55 +00:00
pOperator = createSysTableScanOperatorInfo ( pHandle , pSysScanPhyNode , pUser , pTaskInfo ) ;
2022-05-05 15:47:44 +00:00
} else if ( QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN = = type ) {
2022-05-10 00:55:32 +00:00
STagScanPhysiNode * pScanPhyNode = ( STagScanPhysiNode * ) pPhyNode ;
2022-10-31 01:48:23 +00:00
int32_t code = createScanTableListInfo ( pScanPhyNode , NULL , false , pHandle , pTableListInfo , pTagCond ,
2022-11-01 07:00:02 +00:00
pTagIndexCond , pTaskInfo ) ;
2022-05-05 15:47:44 +00:00
if ( code ! = TSDB_CODE_SUCCESS ) {
2022-09-13 10:33:45 +00:00
pTaskInfo - > code = code ;
2022-08-25 03:01:36 +00:00
qError ( " failed to getTableList, code: %s " , tstrerror ( code ) ) ;
2022-05-05 15:47:44 +00:00
return NULL ;
}
2022-11-27 16:27:49 +00:00
pOperator = createTagScanOperatorInfo ( pHandle , pScanPhyNode , pTaskInfo ) ;
2022-06-20 04:54:46 +00:00
} else if ( QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN = = type ) {
2022-06-22 05:08:20 +00:00
SBlockDistScanPhysiNode * pBlockNode = ( SBlockDistScanPhysiNode * ) pPhyNode ;
2022-06-20 04:54:46 +00:00
if ( pBlockNode - > tableType = = TSDB_SUPER_TABLE ) {
2022-10-29 12:47:14 +00:00
SArray * pList = taosArrayInit ( 4 , sizeof ( STableKeyInfo ) ) ;
int32_t code = vnodeGetAllTableList ( pHandle - > vnode , pBlockNode - > uid , pList ) ;
2022-06-20 04:54:46 +00:00
if ( code ! = TSDB_CODE_SUCCESS ) {
pTaskInfo - > code = terrno ;
return NULL ;
}
2022-10-29 12:47:14 +00:00
2022-11-28 08:13:18 +00:00
size_t num = taosArrayGetSize ( pList ) ;
for ( int32_t i = 0 ; i < num ; + + i ) {
2022-10-29 12:47:14 +00:00
STableKeyInfo * p = taosArrayGet ( pList , i ) ;
2022-10-30 14:13:49 +00:00
tableListAddTableInfo ( pTableListInfo , p - > uid , 0 ) ;
2022-10-29 12:47:14 +00:00
}
2022-11-28 08:13:18 +00:00
2022-10-29 12:47:14 +00:00
taosArrayDestroy ( pList ) ;
2022-10-31 02:41:25 +00:00
} else { // Create group with only one table
2022-10-30 14:13:49 +00:00
tableListAddTableInfo ( pTableListInfo , pBlockNode - > uid , 0 ) ;
2022-06-20 04:54:46 +00:00
}
2022-10-31 02:41:25 +00:00
pOperator = createDataBlockInfoScanOperator ( pHandle , pBlockNode , pTaskInfo ) ;
2022-06-28 07:22:32 +00:00
} else if ( QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN = = type ) {
SLastRowScanPhysiNode * pScanNode = ( SLastRowScanPhysiNode * ) pPhyNode ;
2022-07-21 13:46:55 +00:00
int32_t code = createScanTableListInfo ( & pScanNode - > scan , pScanNode - > pGroupTags , true , pHandle , pTableListInfo ,
2022-11-01 07:00:02 +00:00
pTagCond , pTagIndexCond , pTaskInfo ) ;
2022-07-06 05:33:21 +00:00
if ( code ! = TSDB_CODE_SUCCESS ) {
pTaskInfo - > code = code ;
return NULL ;
}
2022-06-28 15:24:20 +00:00
2022-07-21 03:20:30 +00:00
code = extractTableSchemaInfo ( pHandle , & pScanNode - > scan , pTaskInfo ) ;
2022-07-15 03:19:00 +00:00
if ( code ! = TSDB_CODE_SUCCESS ) {
pTaskInfo - > code = code ;
return NULL ;
2022-06-28 07:35:51 +00:00
}
2022-08-26 07:27:19 +00:00
pOperator = createCacherowsScanOperator ( pScanNode , pHandle , pTaskInfo ) ;
2022-07-25 06:15:49 +00:00
} else if ( QUERY_NODE_PHYSICAL_PLAN_PROJECT = = type ) {
2022-08-02 08:18:55 +00:00
pOperator = createProjectOperatorInfo ( NULL , ( SProjectPhysiNode * ) pPhyNode , pTaskInfo ) ;
2022-03-11 11:29:43 +00:00
} else {
ASSERT ( 0 ) ;
2022-01-20 05:52:46 +00:00
}
2022-08-08 08:34:11 +00:00
if ( pOperator ! = NULL ) {
pOperator - > resultDataBlockId = pPhyNode - > pOutputDataBlockDesc - > dataBlockId ;
}
2022-08-02 08:18:55 +00:00
return pOperator ;
2022-01-20 05:52:46 +00:00
}
2022-11-08 03:09:19 +00:00
size_t size = LIST_LENGTH ( pPhyNode - > pChildren ) ;
2022-04-14 14:12:10 +00:00
SOperatorInfo * * ops = taosMemoryCalloc ( size , POINTER_BYTES ) ;
2022-10-31 02:41:25 +00:00
if ( ops = = NULL ) {
return NULL ;
}
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 ) ;
2022-10-31 02:41:25 +00:00
ops [ i ] = createOperatorTree ( pChildNode , pTaskInfo , pHandle , pTagCond , pTagIndexCond , pUser ) ;
2022-04-25 02:22:48 +00:00
if ( ops [ i ] = = NULL ) {
2022-08-04 09:14:50 +00:00
taosMemoryFree ( ops ) ;
2022-04-25 02:22:48 +00:00
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-06-17 11:01:45 +00:00
pOptr = createProjectOperatorInfo ( ops [ 0 ] , ( SProjectPhysiNode * ) pPhyNode , pTaskInfo ) ;
2022-06-07 12:59:44 +00:00
} else if ( QUERY_NODE_PHYSICAL_PLAN_HASH_AGG = = type ) {
2022-04-08 02:24:35 +00:00
SAggPhysiNode * pAggNode = ( SAggPhysiNode * ) pPhyNode ;
if ( pAggNode - > pGroupKeys ! = NULL ) {
2022-10-20 03:27:33 +00:00
pOptr = createGroupOperatorInfo ( ops [ 0 ] , pAggNode , pTaskInfo ) ;
2022-04-08 02:24:35 +00:00
} else {
2022-10-20 03:27:33 +00:00
pOptr = createAggregateOperatorInfo ( ops [ 0 ] , pAggNode , pTaskInfo ) ;
2022-03-14 08:09:26 +00:00
}
2022-09-05 02:52:04 +00:00
} else if ( QUERY_NODE_PHYSICAL_PLAN_HASH_INTERVAL = = type ) {
2022-04-08 02:24:35 +00:00
SIntervalPhysiNode * pIntervalPhyNode = ( SIntervalPhysiNode * ) pPhyNode ;
2022-03-28 11:08:07 +00:00
2022-10-23 07:20:29 +00:00
bool isStream = ( QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL = = type ) ;
pOptr = createIntervalOperatorInfo ( ops [ 0 ] , pIntervalPhyNode , pTaskInfo , isStream ) ;
2022-09-07 05:59:25 +00:00
} else if ( QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL = = type ) {
2022-09-05 02:52:04 +00:00
pOptr = createStreamIntervalOperatorInfo ( ops [ 0 ] , pPhyNode , pTaskInfo ) ;
2022-06-22 02:53:22 +00:00
} else if ( QUERY_NODE_PHYSICAL_PLAN_MERGE_ALIGNED_INTERVAL = = type ) {
SMergeAlignedIntervalPhysiNode * pIntervalPhyNode = ( SMergeAlignedIntervalPhysiNode * ) pPhyNode ;
2022-08-25 07:31:48 +00:00
pOptr = createMergeAlignedIntervalOperatorInfo ( ops [ 0 ] , pIntervalPhyNode , pTaskInfo ) ;
2022-06-10 03:09:31 +00:00
} else if ( QUERY_NODE_PHYSICAL_PLAN_MERGE_INTERVAL = = type ) {
2022-06-15 11:08:25 +00:00
SMergeIntervalPhysiNode * pIntervalPhyNode = ( SMergeIntervalPhysiNode * ) pPhyNode ;
2022-08-25 07:31:48 +00:00
pOptr = createMergeIntervalOperatorInfo ( ops [ 0 ] , pIntervalPhyNode , pTaskInfo ) ;
2022-06-06 05:23:04 +00:00
} else if ( QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL = = type ) {
2022-06-10 07:54:20 +00:00
int32_t children = 0 ;
2022-06-06 05:23:04 +00:00
pOptr = createStreamFinalIntervalOperatorInfo ( ops [ 0 ] , pPhyNode , pTaskInfo , children ) ;
} else if ( QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_INTERVAL = = type ) {
2022-07-19 06:17:53 +00:00
int32_t children = pHandle - > numOfVgroups ;
2022-06-06 05:23:04 +00:00
pOptr = createStreamFinalIntervalOperatorInfo ( ops [ 0 ] , pPhyNode , pTaskInfo , children ) ;
2022-04-08 02:24:35 +00:00
} else if ( QUERY_NODE_PHYSICAL_PLAN_SORT = = type ) {
2022-06-17 11:01:45 +00:00
pOptr = createSortOperatorInfo ( ops [ 0 ] , ( SSortPhysiNode * ) pPhyNode , pTaskInfo ) ;
2022-06-22 15:01:55 +00:00
} else if ( QUERY_NODE_PHYSICAL_PLAN_GROUP_SORT = = type ) {
pOptr = createGroupSortOperatorInfo ( ops [ 0 ] , ( SGroupSortPhysiNode * ) pPhyNode , pTaskInfo ) ;
2022-06-06 10:07:34 +00:00
} else if ( QUERY_NODE_PHYSICAL_PLAN_MERGE = = type ) {
2022-06-06 06:37:00 +00:00
SMergePhysiNode * pMergePhyNode = ( SMergePhysiNode * ) pPhyNode ;
2022-06-27 09:51:50 +00:00
pOptr = createMultiwayMergeOperatorInfo ( ops , size , pMergePhyNode , pTaskInfo ) ;
2022-06-07 12:59:44 +00:00
} else if ( QUERY_NODE_PHYSICAL_PLAN_MERGE_SESSION = = type ) {
2022-03-28 12:11:02 +00:00
SSessionWinodwPhysiNode * pSessionNode = ( SSessionWinodwPhysiNode * ) pPhyNode ;
2022-08-01 12:41:03 +00:00
pOptr = createSessionAggOperatorInfo ( ops [ 0 ] , pSessionNode , pTaskInfo ) ;
2022-06-07 12:59:44 +00:00
} else if ( QUERY_NODE_PHYSICAL_PLAN_STREAM_SESSION = = type ) {
2022-06-17 06:13:45 +00:00
pOptr = createStreamSessionAggOperatorInfo ( ops [ 0 ] , pPhyNode , pTaskInfo ) ;
} else if ( QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_SESSION = = type ) {
int32_t children = 0 ;
pOptr = createStreamFinalSessionAggOperatorInfo ( ops [ 0 ] , pPhyNode , pTaskInfo , children ) ;
} else if ( QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_SESSION = = type ) {
2022-08-06 02:04:12 +00:00
int32_t children = pHandle - > numOfVgroups ;
2022-06-17 06:13:45 +00:00
pOptr = createStreamFinalSessionAggOperatorInfo ( ops [ 0 ] , pPhyNode , pTaskInfo , children ) ;
2022-04-08 02:24:35 +00:00
} else if ( QUERY_NODE_PHYSICAL_PLAN_PARTITION = = type ) {
2022-06-15 15:00:31 +00:00
pOptr = createPartitionOperatorInfo ( ops [ 0 ] , ( SPartitionPhysiNode * ) pPhyNode , pTaskInfo ) ;
2022-09-01 07:05:24 +00:00
} else if ( QUERY_NODE_PHYSICAL_PLAN_STREAM_PARTITION = = type ) {
2022-09-26 10:39:47 +00:00
pOptr = createStreamPartitionOperatorInfo ( ops [ 0 ] , ( SStreamPartitionPhysiNode * ) pPhyNode , pTaskInfo ) ;
2022-06-07 12:59:44 +00:00
} else if ( QUERY_NODE_PHYSICAL_PLAN_MERGE_STATE = = type ) {
2022-04-23 10:29:45 +00:00
SStateWinodwPhysiNode * pStateNode = ( SStateWinodwPhysiNode * ) pPhyNode ;
2022-08-25 07:31:48 +00:00
pOptr = createStatewindowOperatorInfo ( ops [ 0 ] , pStateNode , pTaskInfo ) ;
2022-06-07 12:59:44 +00:00
} else if ( QUERY_NODE_PHYSICAL_PLAN_STREAM_STATE = = type ) {
2022-06-04 12:06:07 +00:00
pOptr = createStreamStateAggOperatorInfo ( ops [ 0 ] , pPhyNode , pTaskInfo ) ;
2022-06-07 12:59:44 +00:00
} else if ( QUERY_NODE_PHYSICAL_PLAN_MERGE_JOIN = = type ) {
2022-07-25 07:17:53 +00:00
pOptr = createMergeJoinOperatorInfo ( ops , size , ( SSortMergeJoinPhysiNode * ) pPhyNode , pTaskInfo ) ;
2022-05-02 15:52:32 +00:00
} else if ( QUERY_NODE_PHYSICAL_PLAN_FILL = = type ) {
2022-07-14 11:09:40 +00:00
pOptr = createFillOperatorInfo ( ops [ 0 ] , ( SFillPhysiNode * ) pPhyNode , pTaskInfo ) ;
2022-09-27 10:11:44 +00:00
} else if ( QUERY_NODE_PHYSICAL_PLAN_STREAM_FILL = = type ) {
pOptr = createStreamFillOperatorInfo ( ops [ 0 ] , ( SStreamFillPhysiNode * ) pPhyNode , pTaskInfo ) ;
2022-06-04 11:19:49 +00:00
} else if ( QUERY_NODE_PHYSICAL_PLAN_INDEF_ROWS_FUNC = = type ) {
pOptr = createIndefinitOutputOperatorInfo ( ops [ 0 ] , pPhyNode , pTaskInfo ) ;
2022-06-20 15:22:28 +00:00
} else if ( QUERY_NODE_PHYSICAL_PLAN_INTERP_FUNC = = type ) {
pOptr = createTimeSliceOperatorInfo ( ops [ 0 ] , pPhyNode , pTaskInfo ) ;
2022-03-28 11:08:07 +00:00
} else {
ASSERT ( 0 ) ;
2022-04-16 11:10:21 +00:00
}
2022-08-25 07:31:48 +00:00
2022-04-15 04:09:27 +00:00
taosMemoryFree ( ops ) ;
2022-08-25 07:31:48 +00:00
if ( pOptr ) {
pOptr - > resultDataBlockId = pPhyNode - > pOutputDataBlockDesc - > dataBlockId ;
}
2022-04-15 04:09:27 +00:00
return pOptr ;
2022-01-10 11:48:21 +00:00
}
2022-01-08 14:59:24 +00:00
2022-06-24 08:50:11 +00:00
static int32_t extractTbscanInStreamOpTree ( SOperatorInfo * pOperator , STableScanInfo * * ppInfo ) {
if ( pOperator - > operatorType ! = QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN ) {
if ( pOperator - > numOfDownstream = = 0 ) {
qError ( " failed to find stream scan operator " ) ;
return TSDB_CODE_QRY_APP_ERROR ;
}
if ( pOperator - > numOfDownstream > 1 ) {
qError ( " join not supported for stream block scan " ) ;
return TSDB_CODE_QRY_APP_ERROR ;
}
return extractTbscanInStreamOpTree ( pOperator - > pDownstream [ 0 ] , ppInfo ) ;
} else {
2022-07-06 06:20:07 +00:00
SStreamScanInfo * pInfo = pOperator - > info ;
ASSERT ( pInfo - > pTableScanOp - > operatorType = = QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN ) ;
* ppInfo = pInfo - > pTableScanOp - > info ;
2022-06-24 08:50:11 +00:00
return 0 ;
}
}
2022-06-24 06:07:52 +00:00
int32_t extractTableScanNode ( SPhysiNode * pNode , STableScanPhysiNode * * ppNode ) {
if ( pNode - > pChildren = = NULL | | LIST_LENGTH ( pNode - > pChildren ) = = 0 ) {
if ( QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN = = pNode - > type ) {
* ppNode = ( STableScanPhysiNode * ) pNode ;
return 0 ;
} else {
ASSERT ( 0 ) ;
terrno = TSDB_CODE_QRY_APP_ERROR ;
return - 1 ;
}
} else {
if ( LIST_LENGTH ( pNode - > pChildren ) ! = 1 ) {
ASSERT ( 0 ) ;
terrno = TSDB_CODE_QRY_APP_ERROR ;
return - 1 ;
}
SPhysiNode * pChildNode = ( SPhysiNode * ) nodesListGetNode ( pNode - > pChildren , 0 ) ;
return extractTableScanNode ( pChildNode , ppNode ) ;
}
return - 1 ;
}
2022-07-18 07:31:39 +00:00
#if 0
2022-06-24 08:50:11 +00:00
int32_t rebuildReader ( SOperatorInfo * pOperator , SSubplan * plan , SReadHandle * pHandle , int64_t uid , int64_t ts ) {
STableScanInfo * pTableScanInfo = NULL ;
if ( extractTbscanInStreamOpTree ( pOperator , & pTableScanInfo ) < 0 ) {
return - 1 ;
}
2022-06-24 06:07:52 +00:00
2022-06-24 08:50:11 +00:00
STableScanPhysiNode * pNode = NULL ;
if ( extractTableScanNode ( plan - > pNode , & pNode ) < 0 ) {
ASSERT ( 0 ) ;
}
2022-06-24 06:07:52 +00:00
2022-06-28 07:22:32 +00:00
tsdbReaderClose ( pTableScanInfo - > dataReader ) ;
2022-06-24 06:07:52 +00:00
2022-06-24 08:50:11 +00:00
STableListInfo info = { 0 } ;
2022-06-28 07:22:32 +00:00
pTableScanInfo - > dataReader = doCreateDataReader ( pNode , pHandle , & info , NULL ) ;
2022-06-24 08:50:11 +00:00
if ( pTableScanInfo - > dataReader = = NULL ) {
ASSERT ( 0 ) ;
qError ( " failed to create data reader " ) ;
return TSDB_CODE_QRY_APP_ERROR ;
2022-06-24 06:07:52 +00:00
}
2022-06-24 08:50:11 +00:00
// TODO: set uid and ts to data reader
2022-06-24 06:07:52 +00:00
return 0 ;
}
2022-07-18 07:31:39 +00:00
# endif
2022-06-24 06:07:52 +00:00
2022-07-06 08:29:51 +00:00
int32_t createDataSinkParam ( SDataSinkNode * pNode , void * * pParam , qTaskInfo_t * pTaskInfo , SReadHandle * readHandle ) {
2022-06-07 01:11:53 +00:00
SExecTaskInfo * pTask = * ( SExecTaskInfo * * ) pTaskInfo ;
2022-06-07 12:59:44 +00:00
2022-06-06 12:59:36 +00:00
switch ( pNode - > type ) {
2022-07-06 08:29:51 +00:00
case QUERY_NODE_PHYSICAL_PLAN_QUERY_INSERT : {
SInserterParam * pInserterParam = taosMemoryCalloc ( 1 , sizeof ( SInserterParam ) ) ;
if ( NULL = = pInserterParam ) {
return TSDB_CODE_OUT_OF_MEMORY ;
}
pInserterParam - > readHandle = readHandle ;
2022-07-10 06:48:16 +00:00
2022-07-06 08:29:51 +00:00
* pParam = pInserterParam ;
break ;
}
2022-06-06 12:59:36 +00:00
case QUERY_NODE_PHYSICAL_PLAN_DELETE : {
2022-06-07 12:59:44 +00:00
SDeleterParam * pDeleterParam = taosMemoryCalloc ( 1 , sizeof ( SDeleterParam ) ) ;
2022-06-06 12:59:36 +00:00
if ( NULL = = pDeleterParam ) {
return TSDB_CODE_OUT_OF_MEMORY ;
}
2022-10-30 14:13:49 +00:00
int32_t tbNum = tableListGetSize ( pTask - > pTableInfoList ) ;
pDeleterParam - > suid = tableListGetSuid ( pTask - > pTableInfoList ) ;
// TODO extract uid list
2022-06-06 12:59:36 +00:00
pDeleterParam - > pUidList = taosArrayInit ( tbNum , sizeof ( uint64_t ) ) ;
if ( NULL = = pDeleterParam - > pUidList ) {
taosMemoryFree ( pDeleterParam ) ;
return TSDB_CODE_OUT_OF_MEMORY ;
}
2022-10-30 14:13:49 +00:00
2022-06-06 12:59:36 +00:00
for ( int32_t i = 0 ; i < tbNum ; + + i ) {
2022-10-30 14:13:49 +00:00
STableKeyInfo * pTable = tableListGetInfo ( pTask - > pTableInfoList , i ) ;
2022-06-06 12:59:36 +00:00
taosArrayPush ( pDeleterParam - > pUidList , & pTable - > uid ) ;
}
* pParam = pDeleterParam ;
break ;
}
default :
break ;
}
return TSDB_CODE_SUCCESS ;
}
2022-04-23 10:29:45 +00:00
int32_t createExecTaskInfoImpl ( SSubplan * pPlan , SExecTaskInfo * * pTaskInfo , SReadHandle * pHandle , uint64_t taskId ,
2022-08-06 10:00:26 +00:00
char * sql , EOPTR_EXEC_MODEL model ) {
2022-01-20 08:02:09 +00:00
uint64_t queryId = pPlan - > id . queryId ;
2022-05-20 10:00:05 +00:00
* pTaskInfo = createExecTaskInfo ( queryId , taskId , model , pPlan - > dbFName ) ;
2022-01-21 03:19:24 +00:00
if ( * pTaskInfo = = NULL ) {
goto _complete ;
}
2022-01-08 14:59:24 +00:00
2022-10-25 16:31:00 +00:00
if ( pHandle ) {
2022-10-25 16:36:25 +00:00
/*(*pTaskInfo)->streamInfo.fillHistoryVer1 = pHandle->fillHistoryVer1;*/
2022-10-25 16:31:00 +00:00
if ( pHandle - > pStateBackend ) {
( * pTaskInfo ) - > streamInfo . pState = pHandle - > pStateBackend ;
}
2022-08-25 03:01:36 +00:00
}
2022-06-16 03:43:11 +00:00
( * pTaskInfo ) - > sql = sql ;
2022-08-06 10:00:26 +00:00
sql = NULL ;
2022-10-20 03:27:33 +00:00
2022-07-19 09:37:40 +00:00
( * pTaskInfo ) - > pSubplan = pPlan ;
2022-10-31 02:41:25 +00:00
( * pTaskInfo ) - > pRoot =
createOperatorTree ( pPlan - > pNode , * pTaskInfo , pHandle , pPlan - > pTagCond , pPlan - > pTagIndexCond , pPlan - > user ) ;
2022-06-23 14:05:00 +00:00
2022-03-15 07:34:17 +00:00
if ( NULL = = ( * pTaskInfo ) - > pRoot ) {
2022-11-01 07:00:02 +00:00
terrno = ( * pTaskInfo ) - > code ;
2022-03-10 11:36:30 +00:00
goto _complete ;
2022-01-13 11:01:28 +00:00
}
2022-11-01 07:00:02 +00:00
return TSDB_CODE_SUCCESS ;
2022-01-21 03:55:13 +00:00
2022-11-01 07:00:02 +00:00
_complete :
2022-08-06 10:00:26 +00:00
taosMemoryFree ( sql ) ;
2022-08-04 09:14:50 +00:00
doDestroyTask ( * pTaskInfo ) ;
2022-11-01 07:00:02 +00:00
return terrno ;
2022-01-08 14:59:24 +00:00
}
2022-11-12 08:03:47 +00:00
static void freeBlock ( void * pParam ) {
SSDataBlock * pBlock = * ( SSDataBlock * * ) pParam ;
blockDataDestroy ( pBlock ) ;
}
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-10-30 14:13:49 +00:00
pTaskInfo - > pTableInfoList = tableListDestroy ( pTaskInfo - > pTableInfoList ) ;
2022-05-07 07:11:49 +00:00
destroyOperatorInfo ( pTaskInfo - > pRoot ) ;
2022-07-19 09:37:40 +00:00
cleanupTableSchemaInfo ( & pTaskInfo - > schemaInfo ) ;
2022-09-16 09:01:41 +00:00
cleanupStreamInfo ( & pTaskInfo - > streamInfo ) ;
2022-07-19 09:37:40 +00:00
2022-09-15 08:30:21 +00:00
if ( ! pTaskInfo - > localFetch . localExec ) {
2022-09-09 11:03:42 +00:00
nodesDestroyNode ( ( SNode * ) pTaskInfo - > pSubplan ) ;
}
2021-11-02 05:37:31 +00:00
2022-11-12 08:03:47 +00:00
taosArrayDestroyEx ( pTaskInfo - > pResultBlockList , freeBlock ) ;
2022-11-11 09:13:55 +00:00
taosArrayDestroy ( pTaskInfo - > stopInfo . pStopInfo ) ;
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 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-07-30 03:30:31 +00:00
int32_t getOperatorExplainExecInfo ( SOperatorInfo * operatorInfo , SArray * pExecInfoList ) {
2022-08-03 12:33:09 +00:00
SExplainExecInfo execInfo = { 0 } ;
2022-07-30 03:30:31 +00:00
SExplainExecInfo * pExplainInfo = taosArrayPush ( pExecInfoList , & execInfo ) ;
2022-05-24 03:29:51 +00:00
2022-07-30 03:30:31 +00:00
pExplainInfo - > numOfRows = operatorInfo - > resultInfo . totalRows ;
pExplainInfo - > startupCost = operatorInfo - > cost . openCost ;
pExplainInfo - > totalCost = operatorInfo - > cost . totalCost ;
pExplainInfo - > verboseLen = 0 ;
pExplainInfo - > verboseInfo = NULL ;
2022-04-06 03:32:21 +00:00
2022-04-26 12:26:32 +00:00
if ( operatorInfo - > fpSet . getExplainFn ) {
2022-08-03 12:33:09 +00:00
int32_t code =
operatorInfo - > fpSet . getExplainFn ( operatorInfo , & pExplainInfo - > verboseInfo , & pExplainInfo - > verboseLen ) ;
2022-04-06 03:32:21 +00:00
if ( code ) {
2022-05-24 03:29:51 +00:00
qError ( " %s operator getExplainFn failed, code:%s " , GET_TASKID ( operatorInfo - > pTaskInfo ) , tstrerror ( code ) ) ;
2022-04-06 03:32:21 +00:00
return code ;
}
}
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 ) {
2022-07-30 03:30:31 +00:00
code = getOperatorExplainExecInfo ( operatorInfo - > pDownstream [ i ] , pExecInfoList ) ;
if ( code ! = TSDB_CODE_SUCCESS ) {
2022-08-03 12:33:09 +00:00
// taosMemoryFreeClear(*pRes);
2022-04-02 11:31:52 +00:00
return TSDB_CODE_QRY_OUT_OF_MEMORY ;
}
}
return TSDB_CODE_SUCCESS ;
2022-04-01 11:45:45 +00:00
}
2022-05-17 09:38:21 +00:00
2022-09-29 10:52:11 +00:00
int32_t setOutputBuf ( SStreamState * pState , STimeWindow * win , SResultRow * * pResult , int64_t tableGroupId ,
SqlFunctionCtx * pCtx , int32_t numOfOutput , int32_t * rowEntryInfoOffset , SAggSupporter * pAggSup ) {
2022-09-07 05:59:25 +00:00
SWinKey key = {
. ts = win - > skey ,
. groupId = tableGroupId ,
} ;
char * value = NULL ;
int32_t size = pAggSup - > resultRowSize ;
2022-09-19 07:51:35 +00:00
2022-09-29 10:52:11 +00:00
if ( streamStateAddIfNotExist ( pState , & key , ( void * * ) & value , & size ) < 0 ) {
2022-09-07 05:59:25 +00:00
return TSDB_CODE_QRY_OUT_OF_MEMORY ;
}
* pResult = ( SResultRow * ) value ;
ASSERT ( * pResult ) ;
// set time window for current result
( * pResult ) - > win = ( * win ) ;
setResultRowInitCtx ( * pResult , pCtx , numOfOutput , rowEntryInfoOffset ) ;
return TSDB_CODE_SUCCESS ;
}
2022-09-29 10:52:11 +00:00
int32_t releaseOutputBuf ( SStreamState * pState , SWinKey * pKey , SResultRow * pResult ) {
streamStateReleaseBuf ( pState , pKey , pResult ) ;
2022-09-07 05:59:25 +00:00
return TSDB_CODE_SUCCESS ;
}
2022-09-29 10:52:11 +00:00
int32_t saveOutputBuf ( SStreamState * pState , SWinKey * pKey , SResultRow * pResult , int32_t resSize ) {
streamStatePut ( pState , pKey , pResult , resSize ) ;
2022-09-07 05:59:25 +00:00
return TSDB_CODE_SUCCESS ;
}
2022-10-09 08:54:27 +00:00
int32_t buildDataBlockFromGroupRes ( SOperatorInfo * pOperator , SStreamState * pState , SSDataBlock * pBlock , SExprSupp * pSup ,
2022-09-07 05:59:25 +00:00
SGroupResInfo * pGroupResInfo ) {
2022-10-09 08:54:27 +00:00
SExecTaskInfo * pTaskInfo = pOperator - > pTaskInfo ;
2022-09-07 05:59:25 +00:00
SExprInfo * pExprInfo = pSup - > pExprInfo ;
int32_t numOfExprs = pSup - > numOfExprs ;
int32_t * rowEntryOffset = pSup - > rowEntryInfoOffset ;
SqlFunctionCtx * pCtx = pSup - > pCtx ;
int32_t numOfRows = getNumOfTotalRes ( pGroupResInfo ) ;
for ( int32_t i = pGroupResInfo - > index ; i < numOfRows ; i + = 1 ) {
SResKeyPos * pPos = taosArrayGetP ( pGroupResInfo - > pRows , i ) ;
int32_t size = 0 ;
void * pVal = NULL ;
SWinKey key = {
2022-11-08 03:09:19 +00:00
. ts = * ( TSKEY * ) pPos - > key ,
. groupId = pPos - > groupId ,
2022-09-07 05:59:25 +00:00
} ;
2022-09-29 10:52:11 +00:00
int32_t code = streamStateGet ( pState , & key , & pVal , & size ) ;
2022-09-07 05:59:25 +00:00
ASSERT ( code = = 0 ) ;
SResultRow * pRow = ( SResultRow * ) pVal ;
doUpdateNumOfRows ( pCtx , pRow , numOfExprs , rowEntryOffset ) ;
// no results, continue to check the next one
if ( pRow - > numOfRows = = 0 ) {
pGroupResInfo - > index + = 1 ;
2022-09-29 10:52:11 +00:00
releaseOutputBuf ( pState , & key , pRow ) ;
2022-09-07 05:59:25 +00:00
continue ;
}
2022-11-28 04:32:40 +00:00
if ( pBlock - > info . id . groupId = = 0 ) {
pBlock - > info . id . groupId = pPos - > groupId ;
2022-11-18 09:21:50 +00:00
void * tbname = NULL ;
2022-11-28 04:32:40 +00:00
if ( streamStateGetParName ( pTaskInfo - > streamInfo . pState , pBlock - > info . id . groupId , & tbname ) < 0 ) {
2022-10-09 09:46:48 +00:00
pBlock - > info . parTbName [ 0 ] = 0 ;
2022-11-18 09:21:50 +00:00
} else {
memcpy ( pBlock - > info . parTbName , tbname , TSDB_TABLE_NAME_LEN ) ;
2022-10-09 08:54:27 +00:00
}
2022-11-18 09:21:50 +00:00
tdbFree ( tbname ) ;
2022-09-07 05:59:25 +00:00
} else {
// current value belongs to different group, it can't be packed into one datablock
2022-11-28 04:32:40 +00:00
if ( pBlock - > info . id . groupId ! = pPos - > groupId ) {
2022-09-29 10:52:11 +00:00
releaseOutputBuf ( pState , & key , pRow ) ;
2022-09-07 05:59:25 +00:00
break ;
}
}
if ( pBlock - > info . rows + pRow - > numOfRows > pBlock - > info . capacity ) {
ASSERT ( pBlock - > info . rows > 0 ) ;
2022-09-29 10:52:11 +00:00
releaseOutputBuf ( pState , & key , pRow ) ;
2022-09-07 05:59:25 +00:00
break ;
}
pGroupResInfo - > index + = 1 ;
for ( int32_t j = 0 ; j < numOfExprs ; + + j ) {
int32_t slotId = pExprInfo [ j ] . base . resSchema . slotId ;
pCtx [ j ] . resultInfo = getResultEntryInfo ( pRow , j , rowEntryOffset ) ;
if ( pCtx [ j ] . fpSet . finalize ) {
2022-09-21 02:26:55 +00:00
int32_t code1 = pCtx [ j ] . fpSet . finalize ( & pCtx [ j ] , pBlock ) ;
if ( TAOS_FAILED ( code1 ) ) {
qError ( " %s build result data block error, code %s " , GET_TASKID ( pTaskInfo ) , tstrerror ( code1 ) ) ;
T_LONG_JMP ( pTaskInfo - > env , code1 ) ;
2022-09-07 05:59:25 +00:00
}
} else if ( strcmp ( pCtx [ j ] . pExpr - > pExpr - > _function . functionName , " _select_value " ) = = 0 ) {
// do nothing, todo refactor
} else {
// expand the result into multiple rows. E.g., _wstart, top(k, 20)
// the _wstart needs to copy to 20 following rows, since the results of top-k expands to 20 different rows.
SColumnInfoData * pColInfoData = taosArrayGet ( pBlock - > pDataBlock , slotId ) ;
char * in = GET_ROWCELL_INTERBUF ( pCtx [ j ] . resultInfo ) ;
for ( int32_t k = 0 ; k < pRow - > numOfRows ; + + k ) {
colDataAppend ( pColInfoData , pBlock - > info . rows + k , in , pCtx [ j ] . resultInfo - > isNullRes ) ;
}
}
}
2022-09-19 07:51:35 +00:00
2022-09-07 05:59:25 +00:00
pBlock - > info . rows + = pRow - > numOfRows ;
2022-09-29 10:52:11 +00:00
releaseOutputBuf ( pState , & key , pRow ) ;
2022-09-07 05:59:25 +00:00
}
blockDataUpdateTsWindow ( pBlock , 0 ) ;
return TSDB_CODE_SUCCESS ;
}
2022-10-18 09:44:00 +00:00
int32_t saveSessionDiscBuf ( SStreamState * pState , SSessionKey * key , void * buf , int32_t size ) {
streamStateSessionPut ( pState , key , ( const void * ) buf , size ) ;
releaseOutputBuf ( pState , NULL , ( SResultRow * ) buf ) ;
return TSDB_CODE_SUCCESS ;
}
2022-10-19 03:05:00 +00:00
int32_t buildSessionResultDataBlock ( SOperatorInfo * pOperator , SStreamState * pState , SSDataBlock * pBlock ,
2022-10-18 09:44:00 +00:00
SExprSupp * pSup , SGroupResInfo * pGroupResInfo ) {
2022-10-19 03:05:00 +00:00
SExecTaskInfo * pTaskInfo = pOperator - > pTaskInfo ;
2022-10-18 09:44:00 +00:00
SExprInfo * pExprInfo = pSup - > pExprInfo ;
int32_t numOfExprs = pSup - > numOfExprs ;
int32_t * rowEntryOffset = pSup - > rowEntryInfoOffset ;
SqlFunctionCtx * pCtx = pSup - > pCtx ;
int32_t numOfRows = getNumOfTotalRes ( pGroupResInfo ) ;
for ( int32_t i = pGroupResInfo - > index ; i < numOfRows ; i + = 1 ) {
SSessionKey * pKey = taosArrayGet ( pGroupResInfo - > pRows , i ) ;
int32_t size = 0 ;
void * pVal = NULL ;
int32_t code = streamStateSessionGet ( pState , pKey , & pVal , & size ) ;
ASSERT ( code = = 0 ) ;
2022-10-21 02:37:58 +00:00
if ( code = = - 1 ) {
// coverity scan
2022-11-11 08:15:16 +00:00
pGroupResInfo - > index + = 1 ;
2022-10-21 02:37:58 +00:00
continue ;
}
2022-10-18 09:44:00 +00:00
SResultRow * pRow = ( SResultRow * ) pVal ;
doUpdateNumOfRows ( pCtx , pRow , numOfExprs , rowEntryOffset ) ;
// no results, continue to check the next one
if ( pRow - > numOfRows = = 0 ) {
pGroupResInfo - > index + = 1 ;
releaseOutputBuf ( pState , NULL , pRow ) ;
continue ;
}
2022-11-28 04:32:40 +00:00
if ( pBlock - > info . id . groupId = = 0 ) {
pBlock - > info . id . groupId = pKey - > groupId ;
2022-10-19 03:05:00 +00:00
2022-11-18 09:21:50 +00:00
void * tbname = NULL ;
2022-11-28 04:32:40 +00:00
if ( streamStateGetParName ( pTaskInfo - > streamInfo . pState , pBlock - > info . id . groupId , & tbname ) < 0 ) {
2022-11-18 09:21:50 +00:00
pBlock - > info . parTbName [ 0 ] = 0 ;
2022-10-19 03:05:00 +00:00
} else {
2022-11-18 09:21:50 +00:00
memcpy ( pBlock - > info . parTbName , tbname , TSDB_TABLE_NAME_LEN ) ;
2022-10-19 03:05:00 +00:00
}
2022-11-18 09:21:50 +00:00
tdbFree ( tbname ) ;
2022-10-18 09:44:00 +00:00
} else {
// current value belongs to different group, it can't be packed into one datablock
2022-11-28 04:32:40 +00:00
if ( pBlock - > info . id . groupId ! = pKey - > groupId ) {
2022-10-18 09:44:00 +00:00
releaseOutputBuf ( pState , NULL , pRow ) ;
break ;
}
}
if ( pBlock - > info . rows + pRow - > numOfRows > pBlock - > info . capacity ) {
ASSERT ( pBlock - > info . rows > 0 ) ;
releaseOutputBuf ( pState , NULL , pRow ) ;
break ;
}
pGroupResInfo - > index + = 1 ;
for ( int32_t j = 0 ; j < numOfExprs ; + + j ) {
int32_t slotId = pExprInfo [ j ] . base . resSchema . slotId ;
pCtx [ j ] . resultInfo = getResultEntryInfo ( pRow , j , rowEntryOffset ) ;
if ( pCtx [ j ] . fpSet . finalize ) {
int32_t code1 = pCtx [ j ] . fpSet . finalize ( & pCtx [ j ] , pBlock ) ;
if ( TAOS_FAILED ( code1 ) ) {
qError ( " %s build result data block error, code %s " , GET_TASKID ( pTaskInfo ) , tstrerror ( code1 ) ) ;
T_LONG_JMP ( pTaskInfo - > env , code1 ) ;
}
} else if ( strcmp ( pCtx [ j ] . pExpr - > pExpr - > _function . functionName , " _select_value " ) = = 0 ) {
// do nothing, todo refactor
} else {
// expand the result into multiple rows. E.g., _wstart, top(k, 20)
// the _wstart needs to copy to 20 following rows, since the results of top-k expands to 20 different rows.
SColumnInfoData * pColInfoData = taosArrayGet ( pBlock - > pDataBlock , slotId ) ;
char * in = GET_ROWCELL_INTERBUF ( pCtx [ j ] . resultInfo ) ;
for ( int32_t k = 0 ; k < pRow - > numOfRows ; + + k ) {
colDataAppend ( pColInfoData , pBlock - > info . rows + k , in , pCtx [ j ] . resultInfo - > isNullRes ) ;
}
}
}
pBlock - > info . rows + = pRow - > numOfRows ;
// saveSessionDiscBuf(pState, pKey, pVal, size);
releaseOutputBuf ( pState , NULL , pRow ) ;
}
blockDataUpdateTsWindow ( pBlock , 0 ) ;
return TSDB_CODE_SUCCESS ;
2022-10-19 03:05:00 +00:00
}