Merge branch '3.0' of github.com:taosdata/TDengine into test/chr/TD-14699
This commit is contained in:
commit
f8c74fd29a
|
@ -81,9 +81,10 @@ int32_t create_stream() {
|
||||||
/*const char* sql = "select min(k), max(k), sum(k) as sum_of_k from st1";*/
|
/*const char* sql = "select min(k), max(k), sum(k) as sum_of_k from st1";*/
|
||||||
/*const char* sql = "select sum(k) from tu1 interval(10m)";*/
|
/*const char* sql = "select sum(k) from tu1 interval(10m)";*/
|
||||||
/*pRes = tmq_create_stream(pConn, "stream1", "out1", sql);*/
|
/*pRes = tmq_create_stream(pConn, "stream1", "out1", sql);*/
|
||||||
pRes = taos_query(
|
pRes =
|
||||||
pConn,
|
taos_query(pConn,
|
||||||
"create stream stream1 trigger window_close as select min(k), max(k), sum(k) as sum_of_k from tu1 interval(10m)");
|
"create stream stream1 trigger window_close as select _wstartts, min(k), max(k), sum(k) as sum_of_k "
|
||||||
|
"from tu1 interval(10m)");
|
||||||
if (taos_errno(pRes) != 0) {
|
if (taos_errno(pRes) != 0) {
|
||||||
printf("failed to create stream stream1, reason:%s\n", taos_errstr(pRes));
|
printf("failed to create stream stream1, reason:%s\n", taos_errstr(pRes));
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -54,6 +54,11 @@ SEpSet getEpSet_s(SCorEpSet* pEpSet);
|
||||||
BMCharPos(bm_, r_) |= (1u << (7u - BitPos(r_))); \
|
BMCharPos(bm_, r_) |= (1u << (7u - BitPos(r_))); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define colDataSetNotNull_f(bm_, r_) \
|
||||||
|
do { \
|
||||||
|
BMCharPos(bm_, r_) &= ~(1u << (7u - BitPos(r_))); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define colDataIsNull_var(pColumnInfoData, row) (pColumnInfoData->varmeta.offset[row] == -1)
|
#define colDataIsNull_var(pColumnInfoData, row) (pColumnInfoData->varmeta.offset[row] == -1)
|
||||||
#define colDataSetNull_var(pColumnInfoData, row) (pColumnInfoData->varmeta.offset[row] = -1)
|
#define colDataSetNull_var(pColumnInfoData, row) (pColumnInfoData->varmeta.offset[row] = -1)
|
||||||
|
|
||||||
|
@ -63,16 +68,15 @@ SEpSet getEpSet_s(SCorEpSet* pEpSet);
|
||||||
|
|
||||||
#define colDataGetNumData(p1_, r_) ((p1_)->pData + ((r_) * (p1_)->info.bytes))
|
#define colDataGetNumData(p1_, r_) ((p1_)->pData + ((r_) * (p1_)->info.bytes))
|
||||||
// SColumnInfoData, rowNumber
|
// SColumnInfoData, rowNumber
|
||||||
#define colDataGetData(p1_, r_) \
|
#define colDataGetData(p1_, r_) \
|
||||||
((IS_VAR_DATA_TYPE((p1_)->info.type)) ? colDataGetVarData(p1_, r_) \
|
((IS_VAR_DATA_TYPE((p1_)->info.type)) ? colDataGetVarData(p1_, r_) : colDataGetNumData(p1_, r_))
|
||||||
: colDataGetNumData(p1_, r_))
|
|
||||||
|
|
||||||
static FORCE_INLINE bool colDataIsNull_s(const SColumnInfoData* pColumnInfoData, uint32_t row) {
|
static FORCE_INLINE bool colDataIsNull_s(const SColumnInfoData* pColumnInfoData, uint32_t row) {
|
||||||
if (pColumnInfoData->info.type == TSDB_DATA_TYPE_JSON){
|
if (pColumnInfoData->info.type == TSDB_DATA_TYPE_JSON) {
|
||||||
if(colDataIsNull_var(pColumnInfoData, row)){
|
if (colDataIsNull_var(pColumnInfoData, row)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
char *data = colDataGetVarData(pColumnInfoData, row);
|
char* data = colDataGetVarData(pColumnInfoData, row);
|
||||||
return (*data == TSDB_DATA_TYPE_NULL);
|
return (*data == TSDB_DATA_TYPE_NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,7 +84,7 @@ static FORCE_INLINE bool colDataIsNull_s(const SColumnInfoData* pColumnInfoData,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pColumnInfoData->info.type== TSDB_DATA_TYPE_VARCHAR || pColumnInfoData->info.type == TSDB_DATA_TYPE_NCHAR) {
|
if (pColumnInfoData->info.type == TSDB_DATA_TYPE_VARCHAR || pColumnInfoData->info.type == TSDB_DATA_TYPE_NCHAR) {
|
||||||
return colDataIsNull_var(pColumnInfoData, row);
|
return colDataIsNull_var(pColumnInfoData, row);
|
||||||
} else {
|
} else {
|
||||||
if (pColumnInfoData->nullbitmap == NULL) {
|
if (pColumnInfoData->nullbitmap == NULL) {
|
||||||
|
@ -132,7 +136,7 @@ static FORCE_INLINE void colDataAppendNULL(SColumnInfoData* pColumnInfoData, uin
|
||||||
static FORCE_INLINE void colDataAppendNNULL(SColumnInfoData* pColumnInfoData, uint32_t start, size_t nRows) {
|
static FORCE_INLINE void colDataAppendNNULL(SColumnInfoData* pColumnInfoData, uint32_t start, size_t nRows) {
|
||||||
if (IS_VAR_DATA_TYPE(pColumnInfoData->info.type)) {
|
if (IS_VAR_DATA_TYPE(pColumnInfoData->info.type)) {
|
||||||
for (int32_t i = start; i < start + nRows; ++i) {
|
for (int32_t i = start; i < start + nRows; ++i) {
|
||||||
colDataSetNull_var(pColumnInfoData,i); // it is a null value of VAR type.
|
colDataSetNull_var(pColumnInfoData, i); // it is a null value of VAR type.
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int32_t i = start; i < start + nRows; ++i) {
|
for (int32_t i = start; i < start + nRows; ++i) {
|
||||||
|
@ -228,6 +232,8 @@ void blockDebugShowData(const SArray* dataBlocks);
|
||||||
int32_t buildSubmitReqFromDataBlock(SSubmitReq** pReq, const SArray* pDataBlocks, STSchema* pTSchema, int32_t vgId,
|
int32_t buildSubmitReqFromDataBlock(SSubmitReq** pReq, const SArray* pDataBlocks, STSchema* pTSchema, int32_t vgId,
|
||||||
tb_uid_t uid, tb_uid_t suid);
|
tb_uid_t uid, tb_uid_t suid);
|
||||||
|
|
||||||
|
SSubmitReq* tdBlockToSubmit(const SArray* pBlocks, const STSchema* pSchema);
|
||||||
|
|
||||||
static FORCE_INLINE int32_t blockGetEncodeSize(const SSDataBlock* pBlock) {
|
static FORCE_INLINE int32_t blockGetEncodeSize(const SSDataBlock* pBlock) {
|
||||||
return blockDataGetSerialMetaSize(pBlock) + blockDataGetSize(pBlock);
|
return blockDataGetSerialMetaSize(pBlock) + blockDataGetSize(pBlock);
|
||||||
}
|
}
|
||||||
|
@ -241,10 +247,10 @@ static FORCE_INLINE int32_t blockCompressColData(SColumnInfoData* pColRes, int32
|
||||||
|
|
||||||
static FORCE_INLINE void blockCompressEncode(const SSDataBlock* pBlock, char* data, int32_t* dataLen, int32_t numOfCols,
|
static FORCE_INLINE void blockCompressEncode(const SSDataBlock* pBlock, char* data, int32_t* dataLen, int32_t numOfCols,
|
||||||
int8_t needCompress) {
|
int8_t needCompress) {
|
||||||
int32_t* actualLen = (int32_t*) data;
|
int32_t* actualLen = (int32_t*)data;
|
||||||
data += sizeof(int32_t);
|
data += sizeof(int32_t);
|
||||||
|
|
||||||
uint64_t* groupId = (uint64_t*) data;
|
uint64_t* groupId = (uint64_t*)data;
|
||||||
data += sizeof(uint64_t);
|
data += sizeof(uint64_t);
|
||||||
|
|
||||||
int32_t* colSizes = (int32_t*)data;
|
int32_t* colSizes = (int32_t*)data;
|
||||||
|
|
|
@ -61,11 +61,11 @@ extern "C" {
|
||||||
// ----------------- TSDB COLUMN DEFINITION
|
// ----------------- TSDB COLUMN DEFINITION
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
typedef struct {
|
typedef struct {
|
||||||
col_id_t colId; // column ID(start from PRIMARYKEY_TIMESTAMP_COL_ID(1))
|
col_id_t colId; // column ID(start from PRIMARYKEY_TIMESTAMP_COL_ID(1))
|
||||||
int32_t type : 8; // column type
|
int8_t type; // column type
|
||||||
int32_t bytes : 24; // column bytes (0~16M)
|
int8_t flags; // flags: 0 no index, 1 SCHEMA_SMA_ON, 2 SCHEMA_IDX_ON
|
||||||
int32_t flags : 8; // flags: 0 no index, 1 SCHEMA_SMA_ON, 2 SCHEMA_IDX_ON
|
int32_t bytes; // column bytes (0~16M)
|
||||||
int32_t offset : 24; // point offset in STpRow after the header part.
|
int32_t offset; // point offset in STpRow after the header part.
|
||||||
} STColumn;
|
} STColumn;
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
|
|
@ -245,6 +245,8 @@ int32_t tInitSubmitMsgIter(const SSubmitReq* pMsg, SSubmitMsgIter* pIter);
|
||||||
int32_t tGetSubmitMsgNext(SSubmitMsgIter* pIter, SSubmitBlk** pPBlock);
|
int32_t tGetSubmitMsgNext(SSubmitMsgIter* pIter, SSubmitBlk** pPBlock);
|
||||||
int32_t tInitSubmitBlkIter(SSubmitMsgIter* pMsgIter, SSubmitBlk* pBlock, SSubmitBlkIter* pIter);
|
int32_t tInitSubmitBlkIter(SSubmitMsgIter* pMsgIter, SSubmitBlk* pBlock, SSubmitBlkIter* pIter);
|
||||||
STSRow* tGetSubmitBlkNext(SSubmitBlkIter* pIter);
|
STSRow* tGetSubmitBlkNext(SSubmitBlkIter* pIter);
|
||||||
|
// for debug
|
||||||
|
int32_t tPrintFixedSchemaSubmitReq(const SSubmitReq* pReq, STSchema* pSchema);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int32_t index; // index of failed block in submit blocks
|
int32_t index; // index of failed block in submit blocks
|
||||||
|
@ -2130,7 +2132,7 @@ static FORCE_INLINE int32_t tDecodeSSchemaWrapper(SCoder* pDecoder, SSchemaWrapp
|
||||||
if (tDecodeI32v(pDecoder, &pSW->nCols) < 0) return -1;
|
if (tDecodeI32v(pDecoder, &pSW->nCols) < 0) return -1;
|
||||||
if (tDecodeI32v(pDecoder, &pSW->sver) < 0) return -1;
|
if (tDecodeI32v(pDecoder, &pSW->sver) < 0) return -1;
|
||||||
|
|
||||||
pSW->pSchema = (SSchema*)tCoderMalloc(pDecoder, sizeof(SSchema) * pSW->nCols);
|
pSW->pSchema = (SSchema*)taosMemoryCalloc(pSW->nCols, sizeof(SSchema));
|
||||||
if (pSW->pSchema == NULL) return -1;
|
if (pSW->pSchema == NULL) return -1;
|
||||||
for (int32_t i = 0; i < pSW->nCols; i++) {
|
for (int32_t i = 0; i < pSW->nCols; i++) {
|
||||||
if (tDecodeSSchema(pDecoder, &pSW->pSchema[i]) < 0) return -1;
|
if (tDecodeSSchema(pDecoder, &pSW->pSchema[i]) < 0) return -1;
|
||||||
|
|
|
@ -622,7 +622,6 @@ static FORCE_INLINE int32_t tdSRowSetTpInfo(SRowBuilder *pBuilder, int32_t nCols
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief To judge row type: STpRow/SKvRow
|
* @brief To judge row type: STpRow/SKvRow
|
||||||
*
|
*
|
||||||
|
@ -758,7 +757,6 @@ static int32_t tdSRowGetBuf(SRowBuilder *pBuilder, void *pBuf) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 由调用方管理存储空间的分配及释放,一次输入多个参数
|
* @brief 由调用方管理存储空间的分配及释放,一次输入多个参数
|
||||||
*
|
*
|
||||||
|
@ -1397,14 +1395,14 @@ static void tdSCellValPrint(SCellVal *pVal, int8_t colType) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tdSRowPrint(STSRow *row, STSchema *pSchema, const char* tag) {
|
static void tdSRowPrint(STSRow *row, STSchema *pSchema, const char *tag) {
|
||||||
STSRowIter iter = {0};
|
STSRowIter iter = {0};
|
||||||
tdSTSRowIterInit(&iter, pSchema);
|
tdSTSRowIterInit(&iter, pSchema);
|
||||||
tdSTSRowIterReset(&iter, row);
|
tdSTSRowIterReset(&iter, row);
|
||||||
printf("%s >>>", tag);
|
printf("%s >>>", tag);
|
||||||
for (int i = 0; i < pSchema->numOfCols; ++i) {
|
for (int i = 0; i < pSchema->numOfCols; ++i) {
|
||||||
STColumn *stCol = pSchema->columns + i;
|
STColumn *stCol = pSchema->columns + i;
|
||||||
SCellVal sVal = { 255, NULL};
|
SCellVal sVal = {255, NULL};
|
||||||
if (!tdSTSRowIterNext(&iter, stCol->colId, stCol->type, &sVal)) {
|
if (!tdSTSRowIterNext(&iter, stCol->colId, stCol->type, &sVal)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "tmsg.h"
|
#include "tmsg.h"
|
||||||
#include "tcommon.h"
|
#include "tcommon.h"
|
||||||
#include "function.h"
|
#include "function.h"
|
||||||
|
#include "tdatablock.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -54,14 +55,14 @@ int32_t setupUdf(char udfName[], UdfcFuncHandle *handle);
|
||||||
|
|
||||||
typedef struct SUdfColumnMeta {
|
typedef struct SUdfColumnMeta {
|
||||||
int16_t type;
|
int16_t type;
|
||||||
int32_t bytes; // <0 var length, others fixed length bytes
|
int32_t bytes;
|
||||||
uint8_t precision;
|
uint8_t precision;
|
||||||
uint8_t scale;
|
uint8_t scale;
|
||||||
} SUdfColumnMeta;
|
} SUdfColumnMeta;
|
||||||
|
|
||||||
typedef struct SUdfColumnData {
|
typedef struct SUdfColumnData {
|
||||||
int32_t numOfRows;
|
int32_t numOfRows;
|
||||||
bool varLengthColumn;
|
int32_t rowsAlloc;
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
int32_t nullBitmapLen;
|
int32_t nullBitmapLen;
|
||||||
|
@ -72,9 +73,10 @@ typedef struct SUdfColumnData {
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
int32_t varOffsetsLen;
|
int32_t varOffsetsLen;
|
||||||
char *varOffsets;
|
int32_t *varOffsets;
|
||||||
int32_t payloadLen;
|
int32_t payloadLen;
|
||||||
char *payload;
|
char *payload;
|
||||||
|
int32_t payloadAllocLen;
|
||||||
} varLenCol;
|
} varLenCol;
|
||||||
};
|
};
|
||||||
} SUdfColumnData;
|
} SUdfColumnData;
|
||||||
|
@ -131,10 +133,114 @@ typedef int32_t (*TUdfSetupFunc)();
|
||||||
typedef int32_t (*TUdfTeardownFunc)();
|
typedef int32_t (*TUdfTeardownFunc)();
|
||||||
|
|
||||||
//TODO: add API to check function arguments type, number etc.
|
//TODO: add API to check function arguments type, number etc.
|
||||||
//TODO: another way to manage memory is provide api for UDF to add data to SUdfColumnData and UDF framework will allocate memory.
|
|
||||||
// then UDF framework will free the memory
|
#define UDF_MEMORY_EXP_GROWTH 1.5
|
||||||
//typedef int32_t addFixedLengthColumnData(SColumnData *columnData, int rowIndex, bool isNull, int32_t colBytes, char* data);
|
|
||||||
//typedef int32_t addVariableLengthColumnData(SColumnData *columnData, int rowIndex, bool isNull, int32_t dataLen, char * data);
|
static FORCE_INLINE int32_t udfColEnsureCapacity(SUdfColumn* pColumn, int32_t newCapacity) {
|
||||||
|
SUdfColumnMeta *meta = &pColumn->colMeta;
|
||||||
|
SUdfColumnData *data = &pColumn->colData;
|
||||||
|
|
||||||
|
if (newCapacity== 0 || newCapacity <= data->rowsAlloc) {
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int allocCapacity = MAX(data->rowsAlloc, 8);
|
||||||
|
while (allocCapacity < newCapacity) {
|
||||||
|
allocCapacity *= UDF_MEMORY_EXP_GROWTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IS_VAR_DATA_TYPE(meta->type)) {
|
||||||
|
char* tmp = taosMemoryRealloc(data->varLenCol.varOffsets, sizeof(int32_t) * allocCapacity);
|
||||||
|
if (tmp == NULL) {
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
data->varLenCol.varOffsets = (int32_t*)tmp;
|
||||||
|
data->varLenCol.varOffsetsLen = sizeof(int32_t) * allocCapacity;
|
||||||
|
// for payload, add data in udfColDataAppend
|
||||||
|
} else {
|
||||||
|
char* tmp = taosMemoryRealloc(data->fixLenCol.nullBitmap, BitmapLen(allocCapacity));
|
||||||
|
if (tmp == NULL) {
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
data->fixLenCol.nullBitmap = tmp;
|
||||||
|
data->fixLenCol.nullBitmapLen = BitmapLen(allocCapacity);
|
||||||
|
if (meta->type == TSDB_DATA_TYPE_NULL) {
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = taosMemoryRealloc(data->fixLenCol.data, allocCapacity* meta->bytes);
|
||||||
|
if (tmp == NULL) {
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
data->fixLenCol.data = tmp;
|
||||||
|
data->fixLenCol.dataLen = allocCapacity* meta->bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
data->rowsAlloc = allocCapacity;
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static FORCE_INLINE int32_t udfColSetRow(SUdfColumn* pColumn, uint32_t currentRow, const char* pData, bool isNull) {
|
||||||
|
SUdfColumnMeta *meta = &pColumn->colMeta;
|
||||||
|
SUdfColumnData *data = &pColumn->colData;
|
||||||
|
udfColEnsureCapacity(pColumn, currentRow+1);
|
||||||
|
bool isVarCol = IS_VAR_DATA_TYPE(meta->type);
|
||||||
|
if (isNull) {
|
||||||
|
if (isVarCol) {
|
||||||
|
data->varLenCol.varOffsets[currentRow] = -1;
|
||||||
|
} else {
|
||||||
|
colDataSetNull_f(data->fixLenCol.nullBitmap, currentRow);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!isVarCol) {
|
||||||
|
colDataSetNotNull_f(data->fixLenCol.nullBitmap, currentRow);
|
||||||
|
memcpy(data->fixLenCol.data + meta->bytes * currentRow, pData, meta->bytes);
|
||||||
|
} else {
|
||||||
|
int32_t dataLen = varDataTLen(pData);
|
||||||
|
if (meta->type == TSDB_DATA_TYPE_JSON) {
|
||||||
|
if (*pData == TSDB_DATA_TYPE_NULL) {
|
||||||
|
dataLen = 0;
|
||||||
|
} else if (*pData == TSDB_DATA_TYPE_NCHAR) {
|
||||||
|
dataLen = varDataTLen(pData + CHAR_BYTES);
|
||||||
|
} else if (*pData == TSDB_DATA_TYPE_BIGINT || *pData == TSDB_DATA_TYPE_DOUBLE) {
|
||||||
|
dataLen = LONG_BYTES;
|
||||||
|
} else if (*pData == TSDB_DATA_TYPE_BOOL) {
|
||||||
|
dataLen = CHAR_BYTES;
|
||||||
|
}
|
||||||
|
dataLen += CHAR_BYTES;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data->varLenCol.payloadAllocLen < data->varLenCol.payloadLen + dataLen) {
|
||||||
|
uint32_t newSize = data->varLenCol.payloadAllocLen;
|
||||||
|
if (newSize <= 1) {
|
||||||
|
newSize = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (newSize < data->varLenCol.payloadLen + dataLen) {
|
||||||
|
newSize = newSize * UDF_MEMORY_EXP_GROWTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *buf = taosMemoryRealloc(data->varLenCol.payload, newSize);
|
||||||
|
if (buf == NULL) {
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
data->varLenCol.payload = buf;
|
||||||
|
data->varLenCol.payloadAllocLen = newSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t len = data->varLenCol.payloadLen;
|
||||||
|
data->varLenCol.varOffsets[currentRow] = len;
|
||||||
|
|
||||||
|
memcpy(data->varLenCol.payload + len, pData, dataLen);
|
||||||
|
data->varLenCol.payloadLen += dataLen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data->numOfRows = MAX(currentRow + 1, data->numOfRows);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
typedef int32_t (*TUdfFreeUdfColumnFunc)(SUdfColumn* column);
|
typedef int32_t (*TUdfFreeUdfColumnFunc)(SUdfColumn* column);
|
||||||
typedef int32_t (*TUdfScalarProcFunc)(SUdfDataBlock* block, SUdfColumn *resultCol);
|
typedef int32_t (*TUdfScalarProcFunc)(SUdfDataBlock* block, SUdfColumn *resultCol);
|
||||||
|
|
|
@ -70,8 +70,10 @@ typedef struct {
|
||||||
} STaskDispatcherShuffle;
|
} STaskDispatcherShuffle;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int8_t reserved;
|
int8_t reserved;
|
||||||
|
SSchemaWrapper* pSchemaWrapper;
|
||||||
// not applicable to encoder and decoder
|
// not applicable to encoder and decoder
|
||||||
|
STSchema* pTSchema;
|
||||||
SHashObj* pHash; // groupId to tbuid
|
SHashObj* pHash; // groupId to tbuid
|
||||||
} STaskSinkTb;
|
} STaskSinkTb;
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,8 @@ bool taosMbsToUcs4(const char *mbs, size_t mbs_len, TdUcs4 *ucs4, int32_t ucs
|
||||||
int32_t tasoUcs4Compare(TdUcs4 *f1_ucs4, TdUcs4 *f2_ucs4, int32_t bytes);
|
int32_t tasoUcs4Compare(TdUcs4 *f1_ucs4, TdUcs4 *f2_ucs4, int32_t bytes);
|
||||||
TdUcs4* tasoUcs4Copy(TdUcs4 *target_ucs4, TdUcs4 *source_ucs4, int32_t len_ucs4);
|
TdUcs4* tasoUcs4Copy(TdUcs4 *target_ucs4, TdUcs4 *source_ucs4, int32_t len_ucs4);
|
||||||
bool taosValidateEncodec(const char *encodec);
|
bool taosValidateEncodec(const char *encodec);
|
||||||
|
int32_t taosHexEncode(const char *src, char *dst, int32_t len);
|
||||||
|
int32_t taosHexDecode(const char *src, char *dst, int32_t len);
|
||||||
|
|
||||||
int32_t taosWcharWidth(TdWchar wchar);
|
int32_t taosWcharWidth(TdWchar wchar);
|
||||||
int32_t taosWcharsWidth(TdWchar *pWchar, int32_t size);
|
int32_t taosWcharsWidth(TdWchar *pWchar, int32_t size);
|
||||||
|
|
|
@ -491,7 +491,12 @@ SSDataBlock* blockDataExtractBlock(SSDataBlock* pBlock, int32_t startIndex, int3
|
||||||
SColumnInfoData* pDstCol = taosArrayGet(pDst->pDataBlock, i);
|
SColumnInfoData* pDstCol = taosArrayGet(pDst->pDataBlock, i);
|
||||||
|
|
||||||
for (int32_t j = startIndex; j < (startIndex + rowCount); ++j) {
|
for (int32_t j = startIndex; j < (startIndex + rowCount); ++j) {
|
||||||
bool isNull = colDataIsNull(pColData, pBlock->info.rows, j, pBlock->pBlockAgg[i]);
|
bool isNull = false;
|
||||||
|
if (pBlock->pBlockAgg == NULL) {
|
||||||
|
isNull = colDataIsNull(pColData, pBlock->info.rows, j, NULL);
|
||||||
|
} else {
|
||||||
|
isNull = colDataIsNull(pColData, pBlock->info.rows, j, pBlock->pBlockAgg[i]);
|
||||||
|
}
|
||||||
char* p = colDataGetData(pColData, j);
|
char* p = colDataGetData(pColData, j);
|
||||||
|
|
||||||
colDataAppend(pDstCol, j - startIndex, p, isNull);
|
colDataAppend(pDstCol, j - startIndex, p, isNull);
|
||||||
|
@ -1589,3 +1594,68 @@ int32_t buildSubmitReqFromDataBlock(SSubmitReq** pReq, const SArray* pDataBlocks
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SSubmitReq* tdBlockToSubmit(const SArray* pBlocks, const STSchema* pTSchema) {
|
||||||
|
SSubmitReq* ret = NULL;
|
||||||
|
|
||||||
|
// cal size
|
||||||
|
int32_t cap = sizeof(SSubmitReq);
|
||||||
|
int32_t sz = taosArrayGetSize(pBlocks);
|
||||||
|
for (int32_t i = 0; i < sz; i++) {
|
||||||
|
SSDataBlock* pDataBlock = taosArrayGet(pBlocks, i);
|
||||||
|
int32_t rows = pDataBlock->info.rows;
|
||||||
|
// TODO min
|
||||||
|
int32_t rowSize = pDataBlock->info.rowSize;
|
||||||
|
int32_t maxLen = TD_ROW_MAX_BYTES_FROM_SCHEMA(pTSchema);
|
||||||
|
cap += sizeof(SSubmitBlk) + rows * maxLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
// assign data
|
||||||
|
ret = taosMemoryCalloc(1, cap);
|
||||||
|
ret->version = htonl(1);
|
||||||
|
ret->length = htonl(cap - sizeof(SSubmitReq));
|
||||||
|
ret->numOfBlocks = htonl(sz);
|
||||||
|
|
||||||
|
void* submitBlk = POINTER_SHIFT(ret, sizeof(SSubmitReq));
|
||||||
|
for (int32_t i = 0; i < sz; i++) {
|
||||||
|
SSDataBlock* pDataBlock = taosArrayGet(pBlocks, i);
|
||||||
|
|
||||||
|
SSubmitBlk* blkHead = submitBlk;
|
||||||
|
blkHead->numOfRows = htons(pDataBlock->info.rows);
|
||||||
|
blkHead->schemaLen = 0;
|
||||||
|
blkHead->sversion = htonl(pTSchema->version);
|
||||||
|
// TODO
|
||||||
|
blkHead->suid = 0;
|
||||||
|
blkHead->uid = htobe64(pDataBlock->info.uid);
|
||||||
|
|
||||||
|
int32_t rows = pDataBlock->info.rows;
|
||||||
|
int32_t maxLen = TD_ROW_MAX_BYTES_FROM_SCHEMA(pTSchema);
|
||||||
|
/*blkHead->dataLen = htonl(rows * maxLen);*/
|
||||||
|
blkHead->dataLen = 0;
|
||||||
|
|
||||||
|
void* blockData = POINTER_SHIFT(submitBlk, sizeof(SSubmitBlk));
|
||||||
|
STSRow* rowData = blockData;
|
||||||
|
|
||||||
|
for (int32_t j = 0; j < pDataBlock->info.rows; j++) {
|
||||||
|
SRowBuilder rb = {0};
|
||||||
|
tdSRowInit(&rb, pTSchema->version);
|
||||||
|
tdSRowSetTpInfo(&rb, pTSchema->numOfCols, pTSchema->flen);
|
||||||
|
tdSRowResetBuf(&rb, rowData);
|
||||||
|
|
||||||
|
for (int32_t k = 0; k < pTSchema->numOfCols; k++) {
|
||||||
|
const STColumn* pColumn = &pTSchema->columns[k];
|
||||||
|
SColumnInfoData* pColData = taosArrayGet(pDataBlock->pDataBlock, k);
|
||||||
|
void* data = colDataGetData(pColData, j);
|
||||||
|
tdAppendColValToRow(&rb, pColumn->colId, pColumn->type, TD_VTYPE_NORM, data, true, pColumn->offset, k);
|
||||||
|
}
|
||||||
|
int32_t rowLen = TD_ROW_LEN(rowData);
|
||||||
|
rowData = POINTER_SHIFT(rowData, rowLen);
|
||||||
|
blkHead->dataLen += rowLen;
|
||||||
|
}
|
||||||
|
int32_t len = blkHead->dataLen;
|
||||||
|
blkHead->dataLen = htonl(len);
|
||||||
|
blkHead = POINTER_SHIFT(blkHead, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#define _DEFAULT_SOURCE
|
#define _DEFAULT_SOURCE
|
||||||
#include "tdataformat.h"
|
#include "tdataformat.h"
|
||||||
#include "tcoding.h"
|
#include "tcoding.h"
|
||||||
|
#include "tdatablock.h"
|
||||||
#include "tlog.h"
|
#include "tlog.h"
|
||||||
|
|
||||||
static void dataColSetNEleNull(SDataCol *pCol, int nEle);
|
static void dataColSetNEleNull(SDataCol *pCol, int nEle);
|
||||||
|
@ -128,6 +129,50 @@ void *tdDecodeSchema(void *buf, STSchema **pRSchema) {
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
int32_t tEncodeSTColumn(SCoder *pEncoder, const STColumn *pCol) {
|
||||||
|
if (tEncodeI16(pEncoder, pCol->colId) < 0) return -1;
|
||||||
|
if (tEncodeI8(pEncoder, pCol->type) < 0) return -1;
|
||||||
|
if (tEncodeI8(pEncoder, pCol->sma) < 0) return -1;
|
||||||
|
if (tEncodeI32(pEncoder, pCol->bytes) < 0) return -1;
|
||||||
|
if (tEncodeI32(pEncoder, pCol->offset) < 0) return -1;
|
||||||
|
return pEncoder->pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t tDecodeSTColumn(SCoder *pDecoder, STColumn *pCol) {
|
||||||
|
if (tDecodeI16(pDecoder, &pCol->colId) < 0) return -1;
|
||||||
|
if (tDecodeI8(pDecoder, &pCol->type) < 0) return -1;
|
||||||
|
if (tDecodeI8(pDecoder, &pCol->sma) < 0) return -1;
|
||||||
|
if (tDecodeI32(pDecoder, &pCol->bytes) < 0) return -1;
|
||||||
|
if (tDecodeI32(pDecoder, &pCol->offset) < 0) return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t tEncodeSchema(SCoder *pEncoder, const STSchema *pSchema) {
|
||||||
|
if (tEncodeI32(pEncoder, pSchema->numOfCols) < 0) return -1;
|
||||||
|
if (tEncodeI16(pEncoder, pSchema->version) < 0) return -1;
|
||||||
|
if (tEncodeU16(pEncoder, pSchema->flen) < 0) return -1;
|
||||||
|
if (tEncodeI32(pEncoder, pSchema->vlen) < 0) return -1;
|
||||||
|
if (tEncodeI32(pEncoder, pSchema->tlen) < 0) return -1;
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < schemaNCols(pSchema); i++) {
|
||||||
|
const STColumn *pCol = schemaColAt(pSchema, i);
|
||||||
|
if (tEncodeSTColumn(pEncoder, pCol) < 0) return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t tDecodeSchema(SCoder *pDecoder, STSchema *pSchema) {
|
||||||
|
if (tDecodeI32(pDecoder, &pSchema->numOfCols) < 0) return -1;
|
||||||
|
if (tDecodeI16(pDecoder, &pSchema->version) < 0) return -1;
|
||||||
|
if (tDecodeU16(pDecoder, &pSchema->flen) < 0) return -1;
|
||||||
|
if (tDecodeI32(pDecoder, &pSchema->vlen) < 0) return -1;
|
||||||
|
if (tDecodeI32(pDecoder, &pSchema->tlen) < 0) return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int tdInitTSchemaBuilder(STSchemaBuilder *pBuilder, schema_ver_t version) {
|
int tdInitTSchemaBuilder(STSchemaBuilder *pBuilder, schema_ver_t version) {
|
||||||
if (pBuilder == NULL) return -1;
|
if (pBuilder == NULL) return -1;
|
||||||
|
|
||||||
|
|
|
@ -103,6 +103,25 @@ STSRow *tGetSubmitBlkNext(SSubmitBlkIter *pIter) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t tPrintFixedSchemaSubmitReq(const SSubmitReq *pReq, STSchema *pTschema) {
|
||||||
|
SSubmitMsgIter msgIter = {0};
|
||||||
|
if (tInitSubmitMsgIter(pReq, &msgIter) < 0) return -1;
|
||||||
|
while (true) {
|
||||||
|
SSubmitBlk *pBlock = NULL;
|
||||||
|
if (tGetSubmitMsgNext(&msgIter, &pBlock) < 0) return -1;
|
||||||
|
if (pBlock == NULL) break;
|
||||||
|
SSubmitBlkIter blkIter = {0};
|
||||||
|
tInitSubmitBlkIter(&msgIter, pBlock, &blkIter);
|
||||||
|
STSRowIter rowIter = {0};
|
||||||
|
tdSTSRowIterInit(&rowIter, pTschema);
|
||||||
|
STSRow *row;
|
||||||
|
while ((row = tGetSubmitBlkNext(&blkIter)) != NULL) {
|
||||||
|
tdSRowPrint(row, pTschema, "stream");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t tEncodeSEpSet(SCoder *pEncoder, const SEpSet *pEp) {
|
int32_t tEncodeSEpSet(SCoder *pEncoder, const SEpSet *pEp) {
|
||||||
if (tEncodeI8(pEncoder, pEp->inUse) < 0) return -1;
|
if (tEncodeI8(pEncoder, pEp->inUse) < 0) return -1;
|
||||||
if (tEncodeI8(pEncoder, pEp->numOfEps) < 0) return -1;
|
if (tEncodeI8(pEncoder, pEp->numOfEps) < 0) return -1;
|
||||||
|
|
|
@ -419,6 +419,7 @@ typedef struct {
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char key[TSDB_PARTITION_KEY_LEN];
|
char key[TSDB_PARTITION_KEY_LEN];
|
||||||
|
int64_t dbUid;
|
||||||
int64_t offset;
|
int64_t offset;
|
||||||
} SMqOffsetObj;
|
} SMqOffsetObj;
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,8 @@ static FORCE_INLINE int32_t mndMakePartitionKey(char *key, const char *cgroup, c
|
||||||
return snprintf(key, TSDB_PARTITION_KEY_LEN, "%d:%s:%s", vgId, cgroup, topicName);
|
return snprintf(key, TSDB_PARTITION_KEY_LEN, "%d:%s:%s", vgId, cgroup, topicName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t mndDropOffsetByDB(SMnode *pMnode, STrans *pTrans, SDbObj *pDb);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -31,6 +31,8 @@ void mndReleaseSubscribe(SMnode *pMnode, SMqSubscribeObj *pSub);
|
||||||
|
|
||||||
int32_t mndMakeSubscribeKey(char *key, const char *cgroup, const char *topicName);
|
int32_t mndMakeSubscribeKey(char *key, const char *cgroup, const char *topicName);
|
||||||
|
|
||||||
|
int32_t mndDropSubByDB(SMnode *pMnode, STrans *pTrans, SDbObj *pDb);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -17,9 +17,12 @@
|
||||||
#include "mndDb.h"
|
#include "mndDb.h"
|
||||||
#include "mndAuth.h"
|
#include "mndAuth.h"
|
||||||
#include "mndDnode.h"
|
#include "mndDnode.h"
|
||||||
|
#include "mndOffset.h"
|
||||||
#include "mndShow.h"
|
#include "mndShow.h"
|
||||||
#include "mndSma.h"
|
#include "mndSma.h"
|
||||||
#include "mndStb.h"
|
#include "mndStb.h"
|
||||||
|
#include "mndSubscribe.h"
|
||||||
|
#include "mndTopic.h"
|
||||||
#include "mndTrans.h"
|
#include "mndTrans.h"
|
||||||
#include "mndUser.h"
|
#include "mndUser.h"
|
||||||
#include "mndVgroup.h"
|
#include "mndVgroup.h"
|
||||||
|
@ -1027,6 +1030,9 @@ static int32_t mndDropDb(SMnode *pMnode, SNodeMsg *pReq, SDbObj *pDb) {
|
||||||
|
|
||||||
if (mndSetDropDbRedoLogs(pMnode, pTrans, pDb) != 0) goto _OVER;
|
if (mndSetDropDbRedoLogs(pMnode, pTrans, pDb) != 0) goto _OVER;
|
||||||
if (mndSetDropDbCommitLogs(pMnode, pTrans, pDb) != 0) goto _OVER;
|
if (mndSetDropDbCommitLogs(pMnode, pTrans, pDb) != 0) goto _OVER;
|
||||||
|
/*if (mndDropOffsetByDB(pMnode, pTrans, pDb) != 0) goto _OVER;*/
|
||||||
|
/*if (mndDropSubByDB(pMnode, pTrans, pDb) != 0) goto _OVER;*/
|
||||||
|
/*if (mndDropTopicByDB(pMnode, pTrans, pDb) != 0) goto _OVER;*/
|
||||||
if (mndSetDropDbRedoActions(pMnode, pTrans, pDb) != 0) goto _OVER;
|
if (mndSetDropDbRedoActions(pMnode, pTrans, pDb) != 0) goto _OVER;
|
||||||
|
|
||||||
int32_t rspLen = 0;
|
int32_t rspLen = 0;
|
||||||
|
@ -1387,7 +1393,7 @@ static void dumpDbInfoData(SSDataBlock *pBlock, SDbObj *pDb, SShowObj *pShow, in
|
||||||
bool sysDb) {
|
bool sysDb) {
|
||||||
int32_t cols = 0;
|
int32_t cols = 0;
|
||||||
|
|
||||||
int32_t bytes = pShow->pMeta->pSchemas[cols].bytes;
|
int32_t bytes = pShow->pMeta->pSchemas[cols].bytes;
|
||||||
char *buf = taosMemoryMalloc(bytes);
|
char *buf = taosMemoryMalloc(bytes);
|
||||||
const char *name = mndGetDbStr(pDb->name);
|
const char *name = mndGetDbStr(pDb->name);
|
||||||
if (name != NULL) {
|
if (name != NULL) {
|
||||||
|
|
|
@ -231,3 +231,36 @@ static void mndCancelGetNextOffset(SMnode *pMnode, void *pIter) {
|
||||||
SSdb *pSdb = pMnode->pSdb;
|
SSdb *pSdb = pMnode->pSdb;
|
||||||
sdbCancelFetch(pSdb, pIter);
|
sdbCancelFetch(pSdb, pIter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t mndSetDropOffsetCommitLogs(SMnode *pMnode, STrans *pTrans, SMqOffsetObj *pOffset) {
|
||||||
|
SSdbRaw *pCommitRaw = mndOffsetActionEncode(pOffset);
|
||||||
|
if (pCommitRaw == NULL) return -1;
|
||||||
|
if (mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) return -1;
|
||||||
|
if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED) != 0) return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mndDropOffsetByDB(SMnode *pMnode, STrans *pTrans, SDbObj *pDb) {
|
||||||
|
int32_t code = -1;
|
||||||
|
SSdb *pSdb = pMnode->pSdb;
|
||||||
|
|
||||||
|
void *pIter = NULL;
|
||||||
|
SMqOffsetObj *pOffset = NULL;
|
||||||
|
while (1) {
|
||||||
|
pIter = sdbFetch(pSdb, SDB_SUBSCRIBE, pIter, (void **)&pOffset);
|
||||||
|
if (pIter == NULL) break;
|
||||||
|
|
||||||
|
if (pOffset->dbUid != pDb->uid) {
|
||||||
|
sdbRelease(pSdb, pOffset);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mndSetDropOffsetCommitLogs(pMnode, pTrans, pOffset) < 0) {
|
||||||
|
goto END;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
code = 0;
|
||||||
|
END:
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
|
@ -204,6 +204,8 @@ int32_t mndAddShuffledSinkToStream(SMnode* pMnode, STrans* pTrans, SStreamObj* p
|
||||||
pTask->smaSink.smaId = pStream->smaId;
|
pTask->smaSink.smaId = pStream->smaId;
|
||||||
} else {
|
} else {
|
||||||
pTask->sinkType = TASK_SINK__TABLE;
|
pTask->sinkType = TASK_SINK__TABLE;
|
||||||
|
pTask->tbSink.pSchemaWrapper = tCloneSSchemaWrapper(&pStream->outputSchema);
|
||||||
|
ASSERT(pTask->tbSink.pSchemaWrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
// dispatch
|
// dispatch
|
||||||
|
@ -242,6 +244,7 @@ int32_t mndAddFixedSinkToStream(SMnode* pMnode, STrans* pTrans, SStreamObj* pStr
|
||||||
pTask->smaSink.smaId = pStream->smaId;
|
pTask->smaSink.smaId = pStream->smaId;
|
||||||
} else {
|
} else {
|
||||||
pTask->sinkType = TASK_SINK__TABLE;
|
pTask->sinkType = TASK_SINK__TABLE;
|
||||||
|
pTask->tbSink.pSchemaWrapper = tCloneSSchemaWrapper(&pStream->outputSchema);
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
// dispatch
|
// dispatch
|
||||||
|
@ -316,6 +319,7 @@ int32_t mndScheduleStream(SMnode* pMnode, STrans* pTrans, SStreamObj* pStream) {
|
||||||
pTask->smaSink.smaId = pStream->smaId;
|
pTask->smaSink.smaId = pStream->smaId;
|
||||||
} else {
|
} else {
|
||||||
pTask->sinkType = TASK_SINK__TABLE;
|
pTask->sinkType = TASK_SINK__TABLE;
|
||||||
|
pTask->tbSink.pSchemaWrapper = tCloneSSchemaWrapper(&pStream->outputSchema);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -926,6 +926,12 @@ int32_t tqProcessTaskDeploy(STQ* pTq, char* msg, int32_t msgLen) {
|
||||||
pTask->ahandle = pTq->pVnode;
|
pTask->ahandle = pTq->pVnode;
|
||||||
if (pTask->sinkType == TASK_SINK__SMA) {
|
if (pTask->sinkType == TASK_SINK__SMA) {
|
||||||
pTask->smaSink.smaHandle = smaHandleRes;
|
pTask->smaSink.smaHandle = smaHandleRes;
|
||||||
|
} else if (pTask->sinkType == TASK_SINK__TABLE) {
|
||||||
|
ASSERT(pTask->tbSink.pSchemaWrapper);
|
||||||
|
ASSERT(pTask->tbSink.pSchemaWrapper->pSchema);
|
||||||
|
pTask->tbSink.pTSchema =
|
||||||
|
tdGetSTSChemaFromSSChema(&pTask->tbSink.pSchemaWrapper->pSchema, pTask->tbSink.pSchemaWrapper->nCols);
|
||||||
|
ASSERT(pTask->tbSink.pTSchema);
|
||||||
}
|
}
|
||||||
|
|
||||||
taosHashPut(pTq->pStreamTasks, &pTask->taskId, sizeof(int32_t), pTask, sizeof(SStreamTask));
|
taosHashPut(pTq->pStreamTasks, &pTask->taskId, sizeof(int32_t), pTask, sizeof(SStreamTask));
|
||||||
|
|
|
@ -3308,7 +3308,7 @@ void tsdbRetrieveDataBlockInfo(tsdbReaderT* pTsdbReadHandle, SDataBlockInfo* pDa
|
||||||
|
|
||||||
pDataBlockInfo->rows = cur->rows;
|
pDataBlockInfo->rows = cur->rows;
|
||||||
pDataBlockInfo->window = cur->win;
|
pDataBlockInfo->window = cur->win;
|
||||||
pDataBlockInfo->numOfCols = (int32_t)(QH_GET_NUM_OF_COLS(pHandle));
|
// ASSERT(pDataBlockInfo->numOfCols >= (int32_t)(QH_GET_NUM_OF_COLS(pHandle));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -277,7 +277,7 @@ typedef struct SOperatorInfo {
|
||||||
uint8_t operatorType;
|
uint8_t operatorType;
|
||||||
bool blocking; // block operator or not
|
bool blocking; // block operator or not
|
||||||
uint8_t status; // denote if current operator is completed
|
uint8_t status; // denote if current operator is completed
|
||||||
int32_t numOfOutput; // number of columns of the current operator results
|
int32_t numOfExprs; // number of columns of the current operator results
|
||||||
char* name; // name, used to show the query execution plan
|
char* name; // name, used to show the query execution plan
|
||||||
void* info; // extension attribution
|
void* info; // extension attribution
|
||||||
SExprInfo* pExpr;
|
SExprInfo* pExpr;
|
||||||
|
@ -415,8 +415,6 @@ typedef struct SOptrBasicInfo {
|
||||||
// TODO move the resultrowsiz together with SOptrBasicInfo:rowCellInfoOffset
|
// TODO move the resultrowsiz together with SOptrBasicInfo:rowCellInfoOffset
|
||||||
typedef struct SAggSupporter {
|
typedef struct SAggSupporter {
|
||||||
SHashObj* pResultRowHashTable; // quick locate the window object for each result
|
SHashObj* pResultRowHashTable; // quick locate the window object for each result
|
||||||
// SHashObj* pResultRowListSet; // used to check if current ResultRowInfo has ResultRow object or not
|
|
||||||
// SArray* pResultRowArrayList; // The array list that contains the Result rows
|
|
||||||
char* keyBuf; // window key buffer
|
char* keyBuf; // window key buffer
|
||||||
SDiskbasedBuf* pResultBuf; // query result buffer based on blocked-wised disk file
|
SDiskbasedBuf* pResultBuf; // query result buffer based on blocked-wised disk file
|
||||||
int32_t resultRowSize; // the result buffer size for each result row, with the meta data size for each row
|
int32_t resultRowSize; // the result buffer size for each result row, with the meta data size for each row
|
||||||
|
@ -577,13 +575,13 @@ typedef struct SSortedMergeOperatorInfo {
|
||||||
} SSortedMergeOperatorInfo;
|
} SSortedMergeOperatorInfo;
|
||||||
|
|
||||||
typedef struct SSortOperatorInfo {
|
typedef struct SSortOperatorInfo {
|
||||||
|
SOptrBasicInfo binfo;
|
||||||
uint32_t sortBufSize; // max buffer size for in-memory sort
|
uint32_t sortBufSize; // max buffer size for in-memory sort
|
||||||
SSDataBlock* pDataBlock;
|
|
||||||
SArray* pSortInfo;
|
SArray* pSortInfo;
|
||||||
SSortHandle* pSortHandle;
|
SSortHandle* pSortHandle;
|
||||||
SArray* inputSlotMap; // for index map from table scan output
|
SArray* inputSlotMap; // for index map from table scan output
|
||||||
int32_t bufPageSize;
|
int32_t bufPageSize;
|
||||||
int32_t numOfRowsInRes;
|
// int32_t numOfRowsInRes;
|
||||||
|
|
||||||
// TODO extact struct
|
// TODO extact struct
|
||||||
int64_t startTs; // sort start time
|
int64_t startTs; // sort start time
|
||||||
|
@ -645,10 +643,13 @@ SqlFunctionCtx* createSqlFunctionCtx(SExprInfo* pExprInfo, int32_t numOfOutput,
|
||||||
void relocateColumnData(SSDataBlock* pBlock, const SArray* pColMatchInfo, SArray* pCols);
|
void relocateColumnData(SSDataBlock* pBlock, const SArray* pColMatchInfo, SArray* pCols);
|
||||||
void initExecTimeWindowInfo(SColumnInfoData* pColData, STimeWindow* pQueryWindow);
|
void initExecTimeWindowInfo(SColumnInfoData* pColData, STimeWindow* pQueryWindow);
|
||||||
void cleanupAggSup(SAggSupporter* pAggSup);
|
void cleanupAggSup(SAggSupporter* pAggSup);
|
||||||
void destroyBasicOperatorInfo(void* param, int32_t numOfOutput);
|
void destroyBasicOperatorInfo(void* param, int32_t numOfOutput);
|
||||||
|
void appendOneRowToDataBlock(SSDataBlock* pBlock, STupleHandle* pTupleHandle);
|
||||||
|
|
||||||
void setResultRowInitCtx(SResultRow* pResult, SqlFunctionCtx* pCtx, int32_t numOfOutput,
|
SSDataBlock* getSortedBlockData(SSortHandle* pHandle, SSDataBlock* pDataBlock, int32_t capacity);
|
||||||
int32_t* rowCellInfoOffset);
|
SSDataBlock* loadNextDataBlock(void* param);
|
||||||
|
|
||||||
|
void setResultRowInitCtx(SResultRow* pResult, SqlFunctionCtx* pCtx, int32_t numOfOutput, int32_t* rowCellInfoOffset);
|
||||||
|
|
||||||
SResultRow* doSetResultOutBufByKey(SDiskbasedBuf* pResultBuf, SResultRowInfo* pResultRowInfo,
|
SResultRow* doSetResultOutBufByKey(SDiskbasedBuf* pResultBuf, SResultRowInfo* pResultRowInfo,
|
||||||
char* pData, int16_t bytes, bool masterscan, uint64_t groupId,
|
char* pData, int16_t bytes, bool masterscan, uint64_t groupId,
|
||||||
|
@ -663,7 +664,8 @@ SOperatorInfo* createAggregateOperatorInfo(SOperatorInfo* downstream, SExprInfo*
|
||||||
int32_t numOfScalarExpr, SExecTaskInfo* pTaskInfo, const STableGroupInfo* pTableGroupInfo);
|
int32_t numOfScalarExpr, SExecTaskInfo* pTaskInfo, const STableGroupInfo* pTableGroupInfo);
|
||||||
|
|
||||||
SOperatorInfo* createProjectOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t num, SSDataBlock* pResBlock, SLimit* pLimit, SLimit* pSlimit, SExecTaskInfo* pTaskInfo);
|
SOperatorInfo* createProjectOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t num, SSDataBlock* pResBlock, SLimit* pLimit, SLimit* pSlimit, SExecTaskInfo* pTaskInfo);
|
||||||
SOperatorInfo *createSortOperatorInfo(SOperatorInfo* downstream, SSDataBlock* pResBlock, SArray* pSortInfo, SArray* pIndexMap, SExecTaskInfo* pTaskInfo);
|
SOperatorInfo *createSortOperatorInfo(SOperatorInfo* downstream, SSDataBlock* pResBlock, SArray* pSortInfo, SExprInfo* pExprInfo, int32_t numOfCols,
|
||||||
|
SArray* pIndexMap, SExecTaskInfo* pTaskInfo);
|
||||||
|
|
||||||
SOperatorInfo* createSortedMergeOperatorInfo(SOperatorInfo** downstream, int32_t numOfDownstream, SExprInfo* pExprInfo, int32_t num, SArray* pSortInfo, SArray* pGroupInfo, SExecTaskInfo* pTaskInfo);
|
SOperatorInfo* createSortedMergeOperatorInfo(SOperatorInfo** downstream, int32_t numOfDownstream, SExprInfo* pExprInfo, int32_t num, SArray* pSortInfo, SArray* pGroupInfo, SExecTaskInfo* pTaskInfo);
|
||||||
|
|
||||||
|
|
|
@ -89,7 +89,7 @@ int32_t tsortClose(SSortHandle* pHandle);
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
int32_t tsortSetFetchRawDataFp(SSortHandle* pHandle, _sort_fetch_block_fn_t fp);
|
int32_t tsortSetFetchRawDataFp(SSortHandle* pHandle, _sort_fetch_block_fn_t fetchFp, void (*fp)(SSDataBlock*, void*), void* param);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
|
@ -202,9 +202,9 @@ SSDataBlock* createResDataBlock(SDataBlockDescNode* pNode) {
|
||||||
for (int32_t i = 0; i < numOfCols; ++i) {
|
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||||
SColumnInfoData idata = {{0}};
|
SColumnInfoData idata = {{0}};
|
||||||
SSlotDescNode* pDescNode = nodesListGetNode(pNode->pSlots, i);
|
SSlotDescNode* pDescNode = nodesListGetNode(pNode->pSlots, i);
|
||||||
if (!pDescNode->output) {
|
// if (!pDescNode->output) { // todo disable it temporarily
|
||||||
continue;
|
// continue;
|
||||||
}
|
// }
|
||||||
|
|
||||||
idata.info.type = pDescNode->dataType.type;
|
idata.info.type = pDescNode->dataType.type;
|
||||||
idata.info.bytes = pDescNode->dataType.bytes;
|
idata.info.bytes = pDescNode->dataType.bytes;
|
||||||
|
@ -651,7 +651,7 @@ static int32_t doSetInputDataBlock(SOperatorInfo* pOperator, SqlFunctionCtx* pCt
|
||||||
|
|
||||||
static void doSetInputDataBlockInfo(SOperatorInfo* pOperator, SqlFunctionCtx* pCtx, SSDataBlock* pBlock,
|
static void doSetInputDataBlockInfo(SOperatorInfo* pOperator, SqlFunctionCtx* pCtx, SSDataBlock* pBlock,
|
||||||
int32_t order) {
|
int32_t order) {
|
||||||
for (int32_t i = 0; i < pOperator->numOfOutput; ++i) {
|
for (int32_t i = 0; i < pOperator->numOfExprs; ++i) {
|
||||||
pCtx[i].order = order;
|
pCtx[i].order = order;
|
||||||
pCtx[i].size = pBlock->info.rows;
|
pCtx[i].size = pBlock->info.rows;
|
||||||
setBlockStatisInfo(&pCtx[i], &pOperator->pExpr[i], pBlock);
|
setBlockStatisInfo(&pCtx[i], &pOperator->pExpr[i], pBlock);
|
||||||
|
@ -713,7 +713,7 @@ static int32_t doSetInputDataBlock(SOperatorInfo* pOperator, SqlFunctionCtx* pCt
|
||||||
bool createDummyCol) {
|
bool createDummyCol) {
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
|
||||||
for (int32_t i = 0; i < pOperator->numOfOutput; ++i) {
|
for (int32_t i = 0; i < pOperator->numOfExprs; ++i) {
|
||||||
pCtx[i].order = order;
|
pCtx[i].order = order;
|
||||||
pCtx[i].size = pBlock->info.rows;
|
pCtx[i].size = pBlock->info.rows;
|
||||||
pCtx[i].pSrcBlock = pBlock;
|
pCtx[i].pSrcBlock = pBlock;
|
||||||
|
@ -798,7 +798,7 @@ static int32_t doSetInputDataBlock(SOperatorInfo* pOperator, SqlFunctionCtx* pCt
|
||||||
}
|
}
|
||||||
|
|
||||||
static void doAggregateImpl(SOperatorInfo* pOperator, TSKEY startTs, SqlFunctionCtx* pCtx) {
|
static void doAggregateImpl(SOperatorInfo* pOperator, TSKEY startTs, SqlFunctionCtx* pCtx) {
|
||||||
for (int32_t k = 0; k < pOperator->numOfOutput; ++k) {
|
for (int32_t k = 0; k < pOperator->numOfExprs; ++k) {
|
||||||
if (functionNeedToExecute(&pCtx[k])) {
|
if (functionNeedToExecute(&pCtx[k])) {
|
||||||
pCtx[k].startTs = startTs; // this can be set during create the struct
|
pCtx[k].startTs = startTs; // this can be set during create the struct
|
||||||
pCtx[k].fpSet.process(&pCtx[k]);
|
pCtx[k].fpSet.process(&pCtx[k]);
|
||||||
|
@ -2815,7 +2815,6 @@ static int32_t doSendFetchDataRequest(SExchangeInfo* pExchangeInfo, SExecTaskInf
|
||||||
// NOTE: sources columns are more than the destination SSDatablock columns.
|
// NOTE: sources columns are more than the destination SSDatablock columns.
|
||||||
void relocateColumnData(SSDataBlock* pBlock, const SArray* pColMatchInfo, SArray* pCols) {
|
void relocateColumnData(SSDataBlock* pBlock, const SArray* pColMatchInfo, SArray* pCols) {
|
||||||
size_t numOfSrcCols = taosArrayGetSize(pCols);
|
size_t numOfSrcCols = taosArrayGetSize(pCols);
|
||||||
ASSERT(numOfSrcCols >= pBlock->info.numOfCols);
|
|
||||||
|
|
||||||
int32_t i = 0, j = 0;
|
int32_t i = 0, j = 0;
|
||||||
while (i < numOfSrcCols && j < taosArrayGetSize(pColMatchInfo)) {
|
while (i < numOfSrcCols && j < taosArrayGetSize(pColMatchInfo)) {
|
||||||
|
@ -3287,7 +3286,7 @@ SOperatorInfo* createExchangeOperatorInfo(const SNodeList* pSources, SSDataBlock
|
||||||
pOperator->blocking = false;
|
pOperator->blocking = false;
|
||||||
pOperator->status = OP_NOT_OPENED;
|
pOperator->status = OP_NOT_OPENED;
|
||||||
pOperator->info = pInfo;
|
pOperator->info = pInfo;
|
||||||
pOperator->numOfOutput = pBlock->info.numOfCols;
|
pOperator->numOfExprs = pBlock->info.numOfCols;
|
||||||
pOperator->pTaskInfo = pTaskInfo;
|
pOperator->pTaskInfo = pTaskInfo;
|
||||||
|
|
||||||
pOperator->fpSet = createOperatorFpSet(prepareLoadRemoteData, doLoadRemoteData, NULL, NULL,
|
pOperator->fpSet = createOperatorFpSet(prepareLoadRemoteData, doLoadRemoteData, NULL, NULL,
|
||||||
|
@ -3345,49 +3344,6 @@ static void destroySortedMergeOperatorInfo(void* param, int32_t numOfOutput) {
|
||||||
cleanupAggSup(&pInfo->aggSup);
|
cleanupAggSup(&pInfo->aggSup);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO merge aggregate super table
|
|
||||||
static void appendOneRowToDataBlock(SSDataBlock* pBlock, STupleHandle* pTupleHandle) {
|
|
||||||
for (int32_t i = 0; i < pBlock->info.numOfCols; ++i) {
|
|
||||||
SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, i);
|
|
||||||
|
|
||||||
bool isNull = tsortIsNullVal(pTupleHandle, i);
|
|
||||||
if (isNull) {
|
|
||||||
colDataAppend(pColInfo, pBlock->info.rows, NULL, true);
|
|
||||||
} else {
|
|
||||||
char* pData = tsortGetValue(pTupleHandle, i);
|
|
||||||
colDataAppend(pColInfo, pBlock->info.rows, pData, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pBlock->info.rows += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
SSDataBlock* getSortedBlockData(SSortHandle* pHandle, SSDataBlock* pDataBlock, int32_t capacity) {
|
|
||||||
blockDataCleanup(pDataBlock);
|
|
||||||
blockDataEnsureCapacity(pDataBlock, capacity);
|
|
||||||
|
|
||||||
blockDataEnsureCapacity(pDataBlock, capacity);
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
STupleHandle* pTupleHandle = tsortNextTuple(pHandle);
|
|
||||||
if (pTupleHandle == NULL) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
appendOneRowToDataBlock(pDataBlock, pTupleHandle);
|
|
||||||
if (pDataBlock->info.rows >= capacity) {
|
|
||||||
return pDataBlock;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (pDataBlock->info.rows > 0) ? pDataBlock : NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
SSDataBlock* loadNextDataBlock(void* param) {
|
|
||||||
SOperatorInfo* pOperator = (SOperatorInfo*)param;
|
|
||||||
return pOperator->fpSet.getNextFn(pOperator);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool needToMerge(SSDataBlock* pBlock, SArray* groupInfo, char** buf, int32_t rowIndex) {
|
static bool needToMerge(SSDataBlock* pBlock, SArray* groupInfo, char** buf, int32_t rowIndex) {
|
||||||
size_t size = taosArrayGetSize(groupInfo);
|
size_t size = taosArrayGetSize(groupInfo);
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
|
@ -3490,8 +3446,8 @@ static void doMergeImpl(SOperatorInfo* pOperator, int32_t numOfExpr, SSDataBlock
|
||||||
doMergeResultImpl(pInfo, pCtx, numOfExpr, i);
|
doMergeResultImpl(pInfo, pCtx, numOfExpr, i);
|
||||||
} else {
|
} else {
|
||||||
doFinalizeResultImpl(pCtx, numOfExpr);
|
doFinalizeResultImpl(pCtx, numOfExpr);
|
||||||
int32_t numOfRows = getNumOfResult(pInfo->binfo.pCtx, pOperator->numOfOutput, NULL);
|
int32_t numOfRows = getNumOfResult(pInfo->binfo.pCtx, pOperator->numOfExprs, NULL);
|
||||||
// setTagValueForMultipleRows(pCtx, pOperator->numOfOutput, numOfRows);
|
// setTagValueForMultipleRows(pCtx, pOperator->numOfExprs, numOfRows);
|
||||||
|
|
||||||
// TODO check for available buffer;
|
// TODO check for available buffer;
|
||||||
|
|
||||||
|
@ -3541,13 +3497,13 @@ static SSDataBlock* doMerge(SOperatorInfo* pOperator) {
|
||||||
setInputDataBlock(pOperator, pInfo->binfo.pCtx, pDataBlock, TSDB_ORDER_ASC, true);
|
setInputDataBlock(pOperator, pInfo->binfo.pCtx, pDataBlock, TSDB_ORDER_ASC, true);
|
||||||
// updateOutputBuf(&pInfo->binfo, &pAggInfo->bufCapacity, pBlock->info.rows * pAggInfo->resultRowFactor,
|
// updateOutputBuf(&pInfo->binfo, &pAggInfo->bufCapacity, pBlock->info.rows * pAggInfo->resultRowFactor,
|
||||||
// pOperator->pRuntimeEnv, true);
|
// pOperator->pRuntimeEnv, true);
|
||||||
doMergeImpl(pOperator, pOperator->numOfOutput, pDataBlock);
|
doMergeImpl(pOperator, pOperator->numOfExprs, pDataBlock);
|
||||||
// flush to tuple store, and after all data have been handled, return to upstream node or sink node
|
// flush to tuple store, and after all data have been handled, return to upstream node or sink node
|
||||||
}
|
}
|
||||||
|
|
||||||
doFinalizeResultImpl(pInfo->binfo.pCtx, pOperator->numOfOutput);
|
doFinalizeResultImpl(pInfo->binfo.pCtx, pOperator->numOfExprs);
|
||||||
int32_t numOfRows = getNumOfResult(pInfo->binfo.pCtx, pOperator->numOfOutput, NULL);
|
int32_t numOfRows = getNumOfResult(pInfo->binfo.pCtx, pOperator->numOfExprs, NULL);
|
||||||
// setTagValueForMultipleRows(pCtx, pOperator->numOfOutput, numOfRows);
|
// setTagValueForMultipleRows(pCtx, pOperator->numOfExprs, numOfRows);
|
||||||
|
|
||||||
// TODO check for available buffer;
|
// TODO check for available buffer;
|
||||||
|
|
||||||
|
@ -3571,7 +3527,7 @@ static SSDataBlock* doSortedMerge(SOperatorInfo* pOperator) {
|
||||||
pInfo->pSortHandle = tsortCreateSortHandle(pInfo->pSortInfo, NULL, SORT_MULTISOURCE_MERGE, pInfo->bufPageSize,
|
pInfo->pSortHandle = tsortCreateSortHandle(pInfo->pSortInfo, NULL, SORT_MULTISOURCE_MERGE, pInfo->bufPageSize,
|
||||||
numOfBufPage, pInfo->binfo.pRes, "GET_TASKID(pTaskInfo)");
|
numOfBufPage, pInfo->binfo.pRes, "GET_TASKID(pTaskInfo)");
|
||||||
|
|
||||||
tsortSetFetchRawDataFp(pInfo->pSortHandle, loadNextDataBlock);
|
tsortSetFetchRawDataFp(pInfo->pSortHandle, loadNextDataBlock, NULL, NULL);
|
||||||
|
|
||||||
for (int32_t i = 0; i < pOperator->numOfDownstream; ++i) {
|
for (int32_t i = 0; i < pOperator->numOfDownstream; ++i) {
|
||||||
SSortSource* ps = taosMemoryCalloc(1, sizeof(SSortSource));
|
SSortSource* ps = taosMemoryCalloc(1, sizeof(SSortSource));
|
||||||
|
@ -3678,7 +3634,7 @@ SOperatorInfo* createSortedMergeOperatorInfo(SOperatorInfo** downstream, int32_t
|
||||||
pOperator->blocking = true;
|
pOperator->blocking = true;
|
||||||
pOperator->status = OP_NOT_OPENED;
|
pOperator->status = OP_NOT_OPENED;
|
||||||
pOperator->info = pInfo;
|
pOperator->info = pInfo;
|
||||||
pOperator->numOfOutput = num;
|
pOperator->numOfExprs = num;
|
||||||
pOperator->pExpr = pExprInfo;
|
pOperator->pExpr = pExprInfo;
|
||||||
|
|
||||||
pOperator->pTaskInfo = pTaskInfo;
|
pOperator->pTaskInfo = pTaskInfo;
|
||||||
|
@ -3703,79 +3659,6 @@ _error:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SSDataBlock* doSort(SOperatorInfo* pOperator) {
|
|
||||||
if (pOperator->status == OP_EXEC_DONE) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
|
||||||
SSortOperatorInfo* pInfo = pOperator->info;
|
|
||||||
|
|
||||||
if (pOperator->status == OP_RES_TO_RETURN) {
|
|
||||||
return getSortedBlockData(pInfo->pSortHandle, pInfo->pDataBlock, pInfo->numOfRowsInRes);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t numOfBufPage = pInfo->sortBufSize / pInfo->bufPageSize;
|
|
||||||
pInfo->pSortHandle = tsortCreateSortHandle(pInfo->pSortInfo, pInfo->inputSlotMap, SORT_SINGLESOURCE_SORT,
|
|
||||||
pInfo->bufPageSize, numOfBufPage, pInfo->pDataBlock, pTaskInfo->id.str);
|
|
||||||
|
|
||||||
tsortSetFetchRawDataFp(pInfo->pSortHandle, loadNextDataBlock);
|
|
||||||
|
|
||||||
SSortSource* ps = taosMemoryCalloc(1, sizeof(SSortSource));
|
|
||||||
ps->param = pOperator->pDownstream[0];
|
|
||||||
tsortAddSource(pInfo->pSortHandle, ps);
|
|
||||||
|
|
||||||
int32_t code = tsortOpen(pInfo->pSortHandle);
|
|
||||||
taosMemoryFreeClear(ps);
|
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
|
||||||
longjmp(pTaskInfo->env, terrno);
|
|
||||||
}
|
|
||||||
|
|
||||||
pOperator->status = OP_RES_TO_RETURN;
|
|
||||||
return getSortedBlockData(pInfo->pSortHandle, pInfo->pDataBlock, pInfo->numOfRowsInRes);
|
|
||||||
}
|
|
||||||
|
|
||||||
SOperatorInfo* createSortOperatorInfo(SOperatorInfo* downstream, SSDataBlock* pResBlock, SArray* pSortInfo,
|
|
||||||
SArray* pIndexMap, SExecTaskInfo* pTaskInfo) {
|
|
||||||
SSortOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SSortOperatorInfo));
|
|
||||||
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
|
|
||||||
int32_t rowSize = pResBlock->info.rowSize;
|
|
||||||
|
|
||||||
if (pInfo == NULL || pOperator == NULL || rowSize > 100 * 1024 * 1024) {
|
|
||||||
taosMemoryFreeClear(pInfo);
|
|
||||||
taosMemoryFreeClear(pOperator);
|
|
||||||
terrno = TSDB_CODE_QRY_OUT_OF_MEMORY;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
pInfo->bufPageSize = rowSize < 1024 ? 1024 * 2 : rowSize * 2; // there are headers, so pageSize = rowSize + header
|
|
||||||
|
|
||||||
pInfo->sortBufSize = pInfo->bufPageSize * 16; // TODO dynamic set the available sort buffer
|
|
||||||
pInfo->numOfRowsInRes = 1024;
|
|
||||||
pInfo->pDataBlock = pResBlock;
|
|
||||||
pInfo->pSortInfo = pSortInfo;
|
|
||||||
pInfo->inputSlotMap = pIndexMap;
|
|
||||||
|
|
||||||
pOperator->name = "SortOperator";
|
|
||||||
pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_SORT;
|
|
||||||
pOperator->blocking = true;
|
|
||||||
pOperator->status = OP_NOT_OPENED;
|
|
||||||
pOperator->info = pInfo;
|
|
||||||
|
|
||||||
pOperator->pTaskInfo = pTaskInfo;
|
|
||||||
pOperator->fpSet =
|
|
||||||
createOperatorFpSet(operatorDummyOpenFn, doSort, NULL, NULL, destroyOrderOperatorInfo, NULL, NULL, NULL);
|
|
||||||
|
|
||||||
int32_t code = appendDownstream(pOperator, &downstream, 1);
|
|
||||||
return pOperator;
|
|
||||||
|
|
||||||
_error:
|
|
||||||
pTaskInfo->code = TSDB_CODE_OUT_OF_MEMORY;
|
|
||||||
taosMemoryFree(pInfo);
|
|
||||||
taosMemoryFree(pOperator);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t getTableScanOrder(SOperatorInfo* pOperator) {
|
int32_t getTableScanOrder(SOperatorInfo* pOperator) {
|
||||||
if (pOperator->operatorType != QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN) {
|
if (pOperator->operatorType != QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN) {
|
||||||
if (pOperator->pDownstream == NULL || pOperator->pDownstream[0] == NULL) {
|
if (pOperator->pDownstream == NULL || pOperator->pDownstream[0] == NULL) {
|
||||||
|
@ -3813,7 +3696,7 @@ static int32_t doOpenAggregateOptr(SOperatorInfo* pOperator) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// if (pAggInfo->current != NULL) {
|
// if (pAggInfo->current != NULL) {
|
||||||
// setTagValue(pOperator, pAggInfo->current->pTable, pInfo->pCtx, pOperator->numOfOutput);
|
// setTagValue(pOperator, pAggInfo->current->pTable, pInfo->pCtx, pOperator->numOfExprs);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// there is an scalar expression that needs to be calculated before apply the group aggregation.
|
// there is an scalar expression that needs to be calculated before apply the group aggregation.
|
||||||
|
@ -3827,7 +3710,7 @@ static int32_t doOpenAggregateOptr(SOperatorInfo* pOperator) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// the pDataBlock are always the same one, no need to call this again
|
// the pDataBlock are always the same one, no need to call this again
|
||||||
setExecutionContext(pOperator->numOfOutput, pBlock->info.groupId, pTaskInfo, pAggInfo);
|
setExecutionContext(pOperator->numOfExprs, pBlock->info.groupId, pTaskInfo, pAggInfo);
|
||||||
setInputDataBlock(pOperator, pInfo->pCtx, pBlock, order, true);
|
setInputDataBlock(pOperator, pInfo->pCtx, pBlock, order, true);
|
||||||
doAggregateImpl(pOperator, 0, pInfo->pCtx);
|
doAggregateImpl(pOperator, 0, pInfo->pCtx);
|
||||||
|
|
||||||
|
@ -3848,7 +3731,7 @@ static int32_t doOpenAggregateOptr(SOperatorInfo* pOperator) {
|
||||||
}
|
}
|
||||||
|
|
||||||
closeAllResultRows(&pAggInfo->binfo.resultRowInfo);
|
closeAllResultRows(&pAggInfo->binfo.resultRowInfo);
|
||||||
finalizeMultiTupleQueryResult(pAggInfo->binfo.pCtx, pOperator->numOfOutput, pAggInfo->aggSup.pResultBuf,
|
finalizeMultiTupleQueryResult(pAggInfo->binfo.pCtx, pOperator->numOfExprs, pAggInfo->aggSup.pResultBuf,
|
||||||
&pAggInfo->binfo.resultRowInfo, pAggInfo->binfo.rowCellInfoOffset);
|
&pAggInfo->binfo.resultRowInfo, pAggInfo->binfo.rowCellInfoOffset);
|
||||||
|
|
||||||
initGroupedResultInfo(&pAggInfo->groupResInfo, pAggInfo->aggSup.pResultRowHashTable, false);
|
initGroupedResultInfo(&pAggInfo->groupResInfo, pAggInfo->aggSup.pResultRowHashTable, false);
|
||||||
|
@ -4092,17 +3975,17 @@ static SSDataBlock* doProjectOperation(SOperatorInfo* pOperator) {
|
||||||
|
|
||||||
// todo dynamic set tags
|
// todo dynamic set tags
|
||||||
// if (pTableQueryInfo != NULL) {
|
// if (pTableQueryInfo != NULL) {
|
||||||
// setTagValue(pOperator, pTableQueryInfo->pTable, pInfo->pCtx, pOperator->numOfOutput);
|
// setTagValue(pOperator, pTableQueryInfo->pTable, pInfo->pCtx, pOperator->numOfExprs);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// the pDataBlock are always the same one, no need to call this again
|
// the pDataBlock are always the same one, no need to call this again
|
||||||
setInputDataBlock(pOperator, pInfo->pCtx, pBlock, TSDB_ORDER_ASC);
|
setInputDataBlock(pOperator, pInfo->pCtx, pBlock, TSDB_ORDER_ASC);
|
||||||
|
|
||||||
blockDataEnsureCapacity(pInfo->pRes, pBlock->info.rows);
|
blockDataEnsureCapacity(pInfo->pRes, pBlock->info.rows);
|
||||||
projectApplyFunctions(pOperator->pExpr, pInfo->pRes, pBlock, pInfo->pCtx, pOperator->numOfOutput);
|
projectApplyFunctions(pOperator->pExpr, pInfo->pRes, pBlock, pInfo->pCtx, pOperator->numOfExprs);
|
||||||
if (pRes->info.rows >= pProjectInfo->binfo.capacity * 0.8) {
|
if (pRes->info.rows >= pProjectInfo->binfo.capacity * 0.8) {
|
||||||
copyTsColoum(pRes, pInfo->pCtx, pOperator->numOfOutput);
|
copyTsColoum(pRes, pInfo->pCtx, pOperator->numOfExprs);
|
||||||
resetResultRowEntryResult(pInfo->pCtx, pOperator->numOfOutput);
|
resetResultRowEntryResult(pInfo->pCtx, pOperator->numOfExprs);
|
||||||
return pRes;
|
return pRes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4127,14 +4010,14 @@ static SSDataBlock* doProjectOperation(SOperatorInfo* pOperator) {
|
||||||
pProjectInfo->existDataBlock = pBlock;
|
pProjectInfo->existDataBlock = pBlock;
|
||||||
break;
|
break;
|
||||||
} else { // init output buffer for a new group data
|
} else { // init output buffer for a new group data
|
||||||
initCtxOutputBuffer(pInfo->pCtx, pOperator->numOfOutput);
|
initCtxOutputBuffer(pInfo->pCtx, pOperator->numOfExprs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo dynamic set tags
|
// todo dynamic set tags
|
||||||
// STableQueryInfo* pTableQueryInfo = pRuntimeEnv->current;
|
// STableQueryInfo* pTableQueryInfo = pRuntimeEnv->current;
|
||||||
// if (pTableQueryInfo != NULL) {
|
// if (pTableQueryInfo != NULL) {
|
||||||
// setTagValue(pOperator, pTableQueryInfo->pTable, pInfo->pCtx, pOperator->numOfOutput);
|
// setTagValue(pOperator, pTableQueryInfo->pTable, pInfo->pCtx, pOperator->numOfExprs);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// the pDataBlock are always the same one, no need to call this again
|
// the pDataBlock are always the same one, no need to call this again
|
||||||
|
@ -4143,7 +4026,7 @@ static SSDataBlock* doProjectOperation(SOperatorInfo* pOperator) {
|
||||||
setInputDataBlock(pOperator, pInfo->pCtx, pBlock, order, false);
|
setInputDataBlock(pOperator, pInfo->pCtx, pBlock, order, false);
|
||||||
blockDataEnsureCapacity(pInfo->pRes, pInfo->pRes->info.rows + pBlock->info.rows);
|
blockDataEnsureCapacity(pInfo->pRes, pInfo->pRes->info.rows + pBlock->info.rows);
|
||||||
|
|
||||||
projectApplyFunctions(pOperator->pExpr, pInfo->pRes, pBlock, pInfo->pCtx, pOperator->numOfOutput,
|
projectApplyFunctions(pOperator->pExpr, pInfo->pRes, pBlock, pInfo->pCtx, pOperator->numOfExprs,
|
||||||
pProjectInfo->pPseudoColInfo);
|
pProjectInfo->pPseudoColInfo);
|
||||||
|
|
||||||
int32_t status = handleLimitOffset(pOperator, pBlock);
|
int32_t status = handleLimitOffset(pOperator, pBlock);
|
||||||
|
@ -4156,7 +4039,7 @@ static SSDataBlock* doProjectOperation(SOperatorInfo* pOperator) {
|
||||||
|
|
||||||
pProjectInfo->curOutput += pInfo->pRes->info.rows;
|
pProjectInfo->curOutput += pInfo->pRes->info.rows;
|
||||||
|
|
||||||
// copyTsColoum(pRes, pInfo->pCtx, pOperator->numOfOutput);
|
// copyTsColoum(pRes, pInfo->pCtx, pOperator->numOfExprs);
|
||||||
return (pInfo->pRes->info.rows > 0) ? pInfo->pRes : NULL;
|
return (pInfo->pRes->info.rows > 0) ? pInfo->pRes : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4289,7 +4172,7 @@ static void destroyOperatorInfo(SOperatorInfo* pOperator) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pOperator->fpSet.closeFn != NULL) {
|
if (pOperator->fpSet.closeFn != NULL) {
|
||||||
pOperator->fpSet.closeFn(pOperator->info, pOperator->numOfOutput);
|
pOperator->fpSet.closeFn(pOperator->info, pOperator->numOfExprs);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pOperator->pDownstream != NULL) {
|
if (pOperator->pDownstream != NULL) {
|
||||||
|
@ -4425,7 +4308,7 @@ SOperatorInfo* createAggregateOperatorInfo(SOperatorInfo* downstream, SExprInfo*
|
||||||
pOperator->status = OP_NOT_OPENED;
|
pOperator->status = OP_NOT_OPENED;
|
||||||
pOperator->info = pInfo;
|
pOperator->info = pInfo;
|
||||||
pOperator->pExpr = pExprInfo;
|
pOperator->pExpr = pExprInfo;
|
||||||
pOperator->numOfOutput = numOfCols;
|
pOperator->numOfExprs = numOfCols;
|
||||||
pOperator->pTaskInfo = pTaskInfo;
|
pOperator->pTaskInfo = pTaskInfo;
|
||||||
|
|
||||||
pOperator->fpSet = createOperatorFpSet(doOpenAggregateOptr, getAggregateResult, NULL, NULL, destroyAggOperatorInfo,
|
pOperator->fpSet = createOperatorFpSet(doOpenAggregateOptr, getAggregateResult, NULL, NULL, destroyAggOperatorInfo,
|
||||||
|
@ -4477,14 +4360,6 @@ static void destroyProjectOperatorInfo(void* param, int32_t numOfOutput) {
|
||||||
doDestroyBasicInfo(&pInfo->binfo, numOfOutput);
|
doDestroyBasicInfo(&pInfo->binfo, numOfOutput);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void destroyOrderOperatorInfo(void* param, int32_t numOfOutput) {
|
|
||||||
SSortOperatorInfo* pInfo = (SSortOperatorInfo*)param;
|
|
||||||
pInfo->pDataBlock = blockDataDestroy(pInfo->pDataBlock);
|
|
||||||
|
|
||||||
taosArrayDestroy(pInfo->pSortInfo);
|
|
||||||
taosArrayDestroy(pInfo->inputSlotMap);
|
|
||||||
}
|
|
||||||
|
|
||||||
void destroyExchangeOperatorInfo(void* param, int32_t numOfOutput) {
|
void destroyExchangeOperatorInfo(void* param, int32_t numOfOutput) {
|
||||||
SExchangeInfo* pExInfo = (SExchangeInfo*)param;
|
SExchangeInfo* pExInfo = (SExchangeInfo*)param;
|
||||||
taosArrayDestroy(pExInfo->pSources);
|
taosArrayDestroy(pExInfo->pSources);
|
||||||
|
@ -4538,7 +4413,7 @@ SOperatorInfo* createProjectOperatorInfo(SOperatorInfo* downstream, SExprInfo* p
|
||||||
pOperator->status = OP_NOT_OPENED;
|
pOperator->status = OP_NOT_OPENED;
|
||||||
pOperator->info = pInfo;
|
pOperator->info = pInfo;
|
||||||
pOperator->pExpr = pExprInfo;
|
pOperator->pExpr = pExprInfo;
|
||||||
pOperator->numOfOutput = num;
|
pOperator->numOfExprs = num;
|
||||||
|
|
||||||
pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doProjectOperation, NULL, NULL,
|
pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doProjectOperation, NULL, NULL,
|
||||||
destroyProjectOperatorInfo, NULL, NULL, NULL);
|
destroyProjectOperatorInfo, NULL, NULL, NULL);
|
||||||
|
@ -4621,7 +4496,7 @@ SOperatorInfo* createFillOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExp
|
||||||
pOperator->status = OP_NOT_OPENED;
|
pOperator->status = OP_NOT_OPENED;
|
||||||
pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_FILL;
|
pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_FILL;
|
||||||
pOperator->pExpr = pExpr;
|
pOperator->pExpr = pExpr;
|
||||||
pOperator->numOfOutput = numOfCols;
|
pOperator->numOfExprs = numOfCols;
|
||||||
pOperator->info = pInfo;
|
pOperator->info = pInfo;
|
||||||
|
|
||||||
pOperator->fpSet =
|
pOperator->fpSet =
|
||||||
|
@ -4979,7 +4854,14 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
|
||||||
SSDataBlock* pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
|
SSDataBlock* pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
|
||||||
SArray* info = createSortInfo(pSortPhyNode->pSortKeys, pSortPhyNode->pTargets);
|
SArray* info = createSortInfo(pSortPhyNode->pSortKeys, pSortPhyNode->pTargets);
|
||||||
SArray* slotMap = createIndexMap(pSortPhyNode->pTargets);
|
SArray* slotMap = createIndexMap(pSortPhyNode->pTargets);
|
||||||
pOptr = createSortOperatorInfo(ops[0], pResBlock, info, slotMap, pTaskInfo);
|
|
||||||
|
int32_t numOfCols = 0;
|
||||||
|
SExprInfo* pExprInfo = NULL;
|
||||||
|
if (pSortPhyNode->pExprs != NULL) {
|
||||||
|
pExprInfo = createExprInfo(pSortPhyNode->pExprs, NULL, &numOfCols);
|
||||||
|
}
|
||||||
|
|
||||||
|
pOptr = createSortOperatorInfo(ops[0], pResBlock, info, pExprInfo, numOfCols, slotMap, pTaskInfo);
|
||||||
} else if (QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW == type) {
|
} else if (QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW == type) {
|
||||||
SSessionWinodwPhysiNode* pSessionNode = (SSessionWinodwPhysiNode*)pPhyNode;
|
SSessionWinodwPhysiNode* pSessionNode = (SSessionWinodwPhysiNode*)pPhyNode;
|
||||||
|
|
||||||
|
@ -5566,7 +5448,7 @@ static SSDataBlock* doMergeJoin(struct SOperatorInfo* pOperator) {
|
||||||
// only the timestamp match support for ordinary table
|
// only the timestamp match support for ordinary table
|
||||||
ASSERT(pLeftCol->info.type == TSDB_DATA_TYPE_TIMESTAMP);
|
ASSERT(pLeftCol->info.type == TSDB_DATA_TYPE_TIMESTAMP);
|
||||||
if (*(int64_t*)pLeftVal == *(int64_t*)pRightVal) {
|
if (*(int64_t*)pLeftVal == *(int64_t*)pRightVal) {
|
||||||
for (int32_t i = 0; i < pOperator->numOfOutput; ++i) {
|
for (int32_t i = 0; i < pOperator->numOfExprs; ++i) {
|
||||||
SColumnInfoData* pDst = taosArrayGet(pRes->pDataBlock, i);
|
SColumnInfoData* pDst = taosArrayGet(pRes->pDataBlock, i);
|
||||||
|
|
||||||
SExprInfo* pExprInfo = &pOperator->pExpr[i];
|
SExprInfo* pExprInfo = &pOperator->pExpr[i];
|
||||||
|
@ -5633,7 +5515,7 @@ SOperatorInfo* createJoinOperatorInfo(SOperatorInfo** pDownstream, int32_t numOf
|
||||||
pOperator->blocking = false;
|
pOperator->blocking = false;
|
||||||
pOperator->status = OP_NOT_OPENED;
|
pOperator->status = OP_NOT_OPENED;
|
||||||
pOperator->pExpr = pExprInfo;
|
pOperator->pExpr = pExprInfo;
|
||||||
pOperator->numOfOutput = numOfCols;
|
pOperator->numOfExprs = numOfCols;
|
||||||
pOperator->info = pInfo;
|
pOperator->info = pInfo;
|
||||||
pOperator->pTaskInfo = pTaskInfo;
|
pOperator->pTaskInfo = pTaskInfo;
|
||||||
|
|
||||||
|
|
|
@ -227,16 +227,16 @@ static void doHashGroupbyAgg(SOperatorInfo* pOperator, SSDataBlock* pBlock) {
|
||||||
}
|
}
|
||||||
|
|
||||||
len = buildGroupKeys(pInfo->keyBuf, pInfo->pGroupColVals);
|
len = buildGroupKeys(pInfo->keyBuf, pInfo->pGroupColVals);
|
||||||
int32_t ret = setGroupResultOutputBuf(&(pInfo->binfo), pOperator->numOfOutput, pInfo->keyBuf, TSDB_DATA_TYPE_VARCHAR, len, 0, pInfo->aggSup.pResultBuf, pTaskInfo, &pInfo->aggSup);
|
int32_t ret = setGroupResultOutputBuf(&(pInfo->binfo), pOperator->numOfExprs, pInfo->keyBuf, TSDB_DATA_TYPE_VARCHAR, len, 0, pInfo->aggSup.pResultBuf, pTaskInfo, &pInfo->aggSup);
|
||||||
if (ret != TSDB_CODE_SUCCESS) { // null data, too many state code
|
if (ret != TSDB_CODE_SUCCESS) { // null data, too many state code
|
||||||
longjmp(pTaskInfo->env, TSDB_CODE_QRY_APP_ERROR);
|
longjmp(pTaskInfo->env, TSDB_CODE_QRY_APP_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t rowIndex = j - num;
|
int32_t rowIndex = j - num;
|
||||||
doApplyFunctions(pCtx, &w, NULL, rowIndex, num, NULL, pBlock->info.rows, pOperator->numOfOutput, TSDB_ORDER_ASC);
|
doApplyFunctions(pCtx, &w, NULL, rowIndex, num, NULL, pBlock->info.rows, pOperator->numOfExprs, TSDB_ORDER_ASC);
|
||||||
|
|
||||||
// assign the group keys or user input constant values if required
|
// assign the group keys or user input constant values if required
|
||||||
doAssignGroupKeys(pCtx, pOperator->numOfOutput, pBlock->info.rows, rowIndex);
|
doAssignGroupKeys(pCtx, pOperator->numOfExprs, pBlock->info.rows, rowIndex);
|
||||||
recordNewGroupKeys(pInfo->pGroupCols, pInfo->pGroupColVals, pBlock, j, numOfGroupCols);
|
recordNewGroupKeys(pInfo->pGroupCols, pInfo->pGroupColVals, pBlock, j, numOfGroupCols);
|
||||||
num = 1;
|
num = 1;
|
||||||
}
|
}
|
||||||
|
@ -244,15 +244,15 @@ static void doHashGroupbyAgg(SOperatorInfo* pOperator, SSDataBlock* pBlock) {
|
||||||
if (num > 0) {
|
if (num > 0) {
|
||||||
len = buildGroupKeys(pInfo->keyBuf, pInfo->pGroupColVals);
|
len = buildGroupKeys(pInfo->keyBuf, pInfo->pGroupColVals);
|
||||||
int32_t ret =
|
int32_t ret =
|
||||||
setGroupResultOutputBuf(&(pInfo->binfo), pOperator->numOfOutput, pInfo->keyBuf, TSDB_DATA_TYPE_VARCHAR, len,
|
setGroupResultOutputBuf(&(pInfo->binfo), pOperator->numOfExprs, pInfo->keyBuf, TSDB_DATA_TYPE_VARCHAR, len,
|
||||||
0, pInfo->aggSup.pResultBuf, pTaskInfo, &pInfo->aggSup);
|
0, pInfo->aggSup.pResultBuf, pTaskInfo, &pInfo->aggSup);
|
||||||
if (ret != TSDB_CODE_SUCCESS) {
|
if (ret != TSDB_CODE_SUCCESS) {
|
||||||
longjmp(pTaskInfo->env, TSDB_CODE_QRY_APP_ERROR);
|
longjmp(pTaskInfo->env, TSDB_CODE_QRY_APP_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t rowIndex = pBlock->info.rows - num;
|
int32_t rowIndex = pBlock->info.rows - num;
|
||||||
doApplyFunctions(pCtx, &w, NULL, rowIndex, num, NULL, pBlock->info.rows, pOperator->numOfOutput, TSDB_ORDER_ASC);
|
doApplyFunctions(pCtx, &w, NULL, rowIndex, num, NULL, pBlock->info.rows, pOperator->numOfExprs, TSDB_ORDER_ASC);
|
||||||
doAssignGroupKeys(pCtx, pOperator->numOfOutput, pBlock->info.rows, rowIndex);
|
doAssignGroupKeys(pCtx, pOperator->numOfExprs, pBlock->info.rows, rowIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,19 +291,19 @@ static SSDataBlock* hashGroupbyAggregate(SOperatorInfo* pOperator) {
|
||||||
projectApplyFunctions(pInfo->pScalarExprInfo, pBlock, pBlock, pInfo->pScalarFuncCtx, pInfo->numOfScalarExpr, NULL);
|
projectApplyFunctions(pInfo->pScalarExprInfo, pBlock, pBlock, pInfo->pScalarFuncCtx, pInfo->numOfScalarExpr, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// setTagValue(pOperator, pRuntimeEnv->current->pTable, pInfo->binfo.pCtx, pOperator->numOfOutput);
|
// setTagValue(pOperator, pRuntimeEnv->current->pTable, pInfo->binfo.pCtx, pOperator->numOfExprs);
|
||||||
doHashGroupbyAgg(pOperator, pBlock);
|
doHashGroupbyAgg(pOperator, pBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
pOperator->status = OP_RES_TO_RETURN;
|
pOperator->status = OP_RES_TO_RETURN;
|
||||||
closeAllResultRows(&pInfo->binfo.resultRowInfo);
|
closeAllResultRows(&pInfo->binfo.resultRowInfo);
|
||||||
|
|
||||||
finalizeMultiTupleQueryResult(pInfo->binfo.pCtx, pOperator->numOfOutput, pInfo->aggSup.pResultBuf,
|
finalizeMultiTupleQueryResult(pInfo->binfo.pCtx, pOperator->numOfExprs, pInfo->aggSup.pResultBuf,
|
||||||
&pInfo->binfo.resultRowInfo, pInfo->binfo.rowCellInfoOffset);
|
&pInfo->binfo.resultRowInfo, pInfo->binfo.rowCellInfoOffset);
|
||||||
// if (!stableQuery) { // finalize include the update of result rows
|
// if (!stableQuery) { // finalize include the update of result rows
|
||||||
// finalizeQueryResult(pInfo->binfo.pCtx, pOperator->numOfOutput);
|
// finalizeQueryResult(pInfo->binfo.pCtx, pOperator->numOfExprs);
|
||||||
// } else {
|
// } else {
|
||||||
// updateNumOfRowsInResultRows(pInfo->binfo.pCtx, pOperator->numOfOutput, &pInfo->binfo.resultRowInfo,
|
// updateNumOfRowsInResultRows(pInfo->binfo.pCtx, pOperator->numOfExprs, &pInfo->binfo.resultRowInfo,
|
||||||
// pInfo->binfo.rowCellInfoOffset);
|
// pInfo->binfo.rowCellInfoOffset);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
@ -357,7 +357,7 @@ SOperatorInfo* createGroupOperatorInfo(SOperatorInfo* downstream, SExprInfo* pEx
|
||||||
pOperator->status = OP_NOT_OPENED;
|
pOperator->status = OP_NOT_OPENED;
|
||||||
// pOperator->operatorType = OP_Groupby;
|
// pOperator->operatorType = OP_Groupby;
|
||||||
pOperator->pExpr = pExprInfo;
|
pOperator->pExpr = pExprInfo;
|
||||||
pOperator->numOfOutput = numOfCols;
|
pOperator->numOfExprs = numOfCols;
|
||||||
pOperator->info = pInfo;
|
pOperator->info = pInfo;
|
||||||
pOperator->pTaskInfo = pTaskInfo;
|
pOperator->pTaskInfo = pTaskInfo;
|
||||||
|
|
||||||
|
@ -392,7 +392,7 @@ static void doHashPartition(SOperatorInfo* pOperator, SSDataBlock* pBlock) {
|
||||||
|
|
||||||
int32_t* rows = (int32_t*) pPage;
|
int32_t* rows = (int32_t*) pPage;
|
||||||
|
|
||||||
size_t numOfCols = pOperator->numOfOutput;
|
size_t numOfCols = pOperator->numOfExprs;
|
||||||
for(int32_t i = 0; i < numOfCols; ++i) {
|
for(int32_t i = 0; i < numOfCols; ++i) {
|
||||||
SExprInfo* pExpr = &pOperator->pExpr[i];
|
SExprInfo* pExpr = &pOperator->pExpr[i];
|
||||||
int32_t slotId = pExpr->base.pParam[0].pCol->slotId;
|
int32_t slotId = pExpr->base.pParam[0].pCol->slotId;
|
||||||
|
@ -565,7 +565,7 @@ static SSDataBlock* hashPartition(SOperatorInfo* pOperator) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// setTagValue(pOperator, pRuntimeEnv->current->pTable, pInfo->binfo.pCtx, pOperator->numOfOutput);
|
// setTagValue(pOperator, pRuntimeEnv->current->pTable, pInfo->binfo.pCtx, pOperator->numOfExprs);
|
||||||
doHashPartition(pOperator, pBlock);
|
doHashPartition(pOperator, pBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -616,7 +616,7 @@ SOperatorInfo* createPartitionOperatorInfo(SOperatorInfo* downstream, SExprInfo*
|
||||||
pOperator->status = OP_NOT_OPENED;
|
pOperator->status = OP_NOT_OPENED;
|
||||||
pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_PARTITION;
|
pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_PARTITION;
|
||||||
pInfo->binfo.pRes = pResultBlock;
|
pInfo->binfo.pRes = pResultBlock;
|
||||||
pOperator->numOfOutput = numOfCols;
|
pOperator->numOfExprs = numOfCols;
|
||||||
pOperator->pExpr = pExprInfo;
|
pOperator->pExpr = pExprInfo;
|
||||||
pOperator->info = pInfo;
|
pOperator->info = pInfo;
|
||||||
|
|
||||||
|
|
|
@ -386,7 +386,7 @@ SOperatorInfo* createTableScanOperatorInfo(void* pDataReader, SQueryTableDataCon
|
||||||
pOperator->blocking = false;
|
pOperator->blocking = false;
|
||||||
pOperator->status = OP_NOT_OPENED;
|
pOperator->status = OP_NOT_OPENED;
|
||||||
pOperator->info = pInfo;
|
pOperator->info = pInfo;
|
||||||
pOperator->numOfOutput = numOfOutput;
|
pOperator->numOfExprs = numOfOutput;
|
||||||
pOperator->pTaskInfo = pTaskInfo;
|
pOperator->pTaskInfo = pTaskInfo;
|
||||||
|
|
||||||
pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doTableScan, NULL, NULL, NULL, NULL, NULL, NULL);
|
pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doTableScan, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||||
|
@ -646,7 +646,7 @@ SOperatorInfo* createStreamScanOperatorInfo(void* streamReadHandle, SSDataBlock*
|
||||||
pOperator->blocking = false;
|
pOperator->blocking = false;
|
||||||
pOperator->status = OP_NOT_OPENED;
|
pOperator->status = OP_NOT_OPENED;
|
||||||
pOperator->info = pInfo;
|
pOperator->info = pInfo;
|
||||||
pOperator->numOfOutput = pResBlock->info.numOfCols;
|
pOperator->numOfExprs = pResBlock->info.numOfCols;
|
||||||
pOperator->fpSet._openFn = operatorDummyOpenFn;
|
pOperator->fpSet._openFn = operatorDummyOpenFn;
|
||||||
pOperator->fpSet.getNextFn = doStreamBlockScan;
|
pOperator->fpSet.getNextFn = doStreamBlockScan;
|
||||||
pOperator->fpSet.closeFn = operatorDummyCloseFn;
|
pOperator->fpSet.closeFn = operatorDummyCloseFn;
|
||||||
|
@ -1020,7 +1020,7 @@ static SSDataBlock* doSysTableScan(SOperatorInfo* pOperator) {
|
||||||
|
|
||||||
SRetrieveMetaTableRsp* pTableRsp = pInfo->pRsp;
|
SRetrieveMetaTableRsp* pTableRsp = pInfo->pRsp;
|
||||||
setSDataBlockFromFetchRsp(pInfo->pRes, &pInfo->loadInfo, pTableRsp->numOfRows, pTableRsp->data,
|
setSDataBlockFromFetchRsp(pInfo->pRes, &pInfo->loadInfo, pTableRsp->numOfRows, pTableRsp->data,
|
||||||
pTableRsp->compLen, pOperator->numOfOutput, startTs, NULL, pInfo->scanCols);
|
pTableRsp->compLen, pOperator->numOfExprs, startTs, NULL, pInfo->scanCols);
|
||||||
|
|
||||||
// todo log the filter info
|
// todo log the filter info
|
||||||
doFilterResult(pInfo);
|
doFilterResult(pInfo);
|
||||||
|
@ -1150,7 +1150,7 @@ SOperatorInfo* createSysTableScanOperatorInfo(void* readHandle, SSDataBlock* pRe
|
||||||
pOperator->blocking = false;
|
pOperator->blocking = false;
|
||||||
pOperator->status = OP_NOT_OPENED;
|
pOperator->status = OP_NOT_OPENED;
|
||||||
pOperator->info = pInfo;
|
pOperator->info = pInfo;
|
||||||
pOperator->numOfOutput = pResBlock->info.numOfCols;
|
pOperator->numOfExprs = pResBlock->info.numOfCols;
|
||||||
pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doSysTableScan, NULL, NULL, destroySysScanOperator,
|
pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doSysTableScan, NULL, NULL, destroySysScanOperator,
|
||||||
NULL, NULL, NULL);
|
NULL, NULL, NULL);
|
||||||
pOperator->pTaskInfo = pTaskInfo;
|
pOperator->pTaskInfo = pTaskInfo;
|
||||||
|
@ -1247,7 +1247,7 @@ static SSDataBlock* doTagScan(SOperatorInfo* pOperator) {
|
||||||
|
|
||||||
char *data = NULL, *dst = NULL;
|
char *data = NULL, *dst = NULL;
|
||||||
int16_t type = 0, bytes = 0;
|
int16_t type = 0, bytes = 0;
|
||||||
for(int32_t j = 0; j < pOperator->numOfOutput; ++j) {
|
for(int32_t j = 0; j < pOperator->numOfExprs; ++j) {
|
||||||
// not assign value in case of user defined constant output column
|
// not assign value in case of user defined constant output column
|
||||||
if (TSDB_COL_IS_UD_COL(pExprInfo[j].base.pColumns->flag)) {
|
if (TSDB_COL_IS_UD_COL(pExprInfo[j].base.pColumns->flag)) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -1308,7 +1308,7 @@ SOperatorInfo* createTagScanOperatorInfo(void* readHandle, SExprInfo* pExpr, int
|
||||||
pOperator->status = OP_NOT_OPENED;
|
pOperator->status = OP_NOT_OPENED;
|
||||||
pOperator->info = pInfo;
|
pOperator->info = pInfo;
|
||||||
pOperator->pExpr = pExpr;
|
pOperator->pExpr = pExpr;
|
||||||
pOperator->numOfOutput = numOfOutput;
|
pOperator->numOfExprs = numOfOutput;
|
||||||
pOperator->pTaskInfo = pTaskInfo;
|
pOperator->pTaskInfo = pTaskInfo;
|
||||||
|
|
||||||
pOperator->fpSet =
|
pOperator->fpSet =
|
||||||
|
|
|
@ -0,0 +1,139 @@
|
||||||
|
#include "tdatablock.h"
|
||||||
|
#include "executorimpl.h"
|
||||||
|
|
||||||
|
static SSDataBlock* doSort(SOperatorInfo* pOperator);
|
||||||
|
static void destroyOrderOperatorInfo(void* param, int32_t numOfOutput);
|
||||||
|
|
||||||
|
SOperatorInfo* createSortOperatorInfo(SOperatorInfo* downstream, SSDataBlock* pResBlock, SArray* pSortInfo, SExprInfo* pExprInfo, int32_t numOfCols,
|
||||||
|
SArray* pIndexMap, SExecTaskInfo* pTaskInfo) {
|
||||||
|
SSortOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SSortOperatorInfo));
|
||||||
|
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
|
||||||
|
int32_t rowSize = pResBlock->info.rowSize;
|
||||||
|
|
||||||
|
if (pInfo == NULL || pOperator == NULL || rowSize > 100 * 1024 * 1024) {
|
||||||
|
goto _error;
|
||||||
|
}
|
||||||
|
|
||||||
|
pOperator->pExpr = pExprInfo;
|
||||||
|
pOperator->numOfExprs = numOfCols;
|
||||||
|
pInfo->binfo.pCtx = createSqlFunctionCtx(pExprInfo, numOfCols, &pInfo->binfo.rowCellInfoOffset);
|
||||||
|
pInfo->binfo.pRes = pResBlock;
|
||||||
|
|
||||||
|
initResultSizeInfo(pOperator, 1024);
|
||||||
|
pInfo->bufPageSize = rowSize < 1024 ? 1024 * 2 : rowSize * 2; // there are headers, so pageSize = rowSize + header
|
||||||
|
|
||||||
|
pInfo->sortBufSize = pInfo->bufPageSize * 16; // TODO dynamic set the available sort buffer
|
||||||
|
pInfo->pSortInfo = pSortInfo;
|
||||||
|
pInfo->inputSlotMap = pIndexMap;
|
||||||
|
pOperator->name = "SortOperator";
|
||||||
|
pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_SORT;
|
||||||
|
pOperator->blocking = true;
|
||||||
|
pOperator->status = OP_NOT_OPENED;
|
||||||
|
pOperator->info = pInfo;
|
||||||
|
|
||||||
|
pOperator->pTaskInfo = pTaskInfo;
|
||||||
|
pOperator->fpSet =
|
||||||
|
createOperatorFpSet(operatorDummyOpenFn, doSort, NULL, NULL, destroyOrderOperatorInfo, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
int32_t code = appendDownstream(pOperator, &downstream, 1);
|
||||||
|
return pOperator;
|
||||||
|
|
||||||
|
_error:
|
||||||
|
pTaskInfo->code = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
taosMemoryFree(pInfo);
|
||||||
|
taosMemoryFree(pOperator);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO merge aggregate super table
|
||||||
|
void appendOneRowToDataBlock(SSDataBlock* pBlock, STupleHandle* pTupleHandle) {
|
||||||
|
for (int32_t i = 0; i < pBlock->info.numOfCols; ++i) {
|
||||||
|
SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, i);
|
||||||
|
|
||||||
|
bool isNull = tsortIsNullVal(pTupleHandle, i);
|
||||||
|
if (isNull) {
|
||||||
|
colDataAppend(pColInfo, pBlock->info.rows, NULL, true);
|
||||||
|
} else {
|
||||||
|
char* pData = tsortGetValue(pTupleHandle, i);
|
||||||
|
colDataAppend(pColInfo, pBlock->info.rows, pData, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pBlock->info.rows += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
SSDataBlock* getSortedBlockData(SSortHandle* pHandle, SSDataBlock* pDataBlock, int32_t capacity) {
|
||||||
|
blockDataCleanup(pDataBlock);
|
||||||
|
blockDataEnsureCapacity(pDataBlock, capacity);
|
||||||
|
|
||||||
|
blockDataEnsureCapacity(pDataBlock, capacity);
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
STupleHandle* pTupleHandle = tsortNextTuple(pHandle);
|
||||||
|
if (pTupleHandle == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
appendOneRowToDataBlock(pDataBlock, pTupleHandle);
|
||||||
|
if (pDataBlock->info.rows >= capacity) {
|
||||||
|
return pDataBlock;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (pDataBlock->info.rows > 0) ? pDataBlock : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SSDataBlock* loadNextDataBlock(void* param) {
|
||||||
|
SOperatorInfo* pOperator = (SOperatorInfo*)param;
|
||||||
|
return pOperator->fpSet.getNextFn(pOperator);
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo refactor: merged with fetch fp
|
||||||
|
void applyScalarFunction(SSDataBlock* pBlock, void* param) {
|
||||||
|
SOperatorInfo* pOperator = param;
|
||||||
|
SSortOperatorInfo* pSort = pOperator->info;
|
||||||
|
if (pOperator->pExpr != NULL) {
|
||||||
|
projectApplyFunctions(pOperator->pExpr, pBlock, pBlock, pSort->binfo.pCtx, pOperator->numOfExprs, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SSDataBlock* doSort(SOperatorInfo* pOperator) {
|
||||||
|
if (pOperator->status == OP_EXEC_DONE) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||||
|
SSortOperatorInfo* pInfo = pOperator->info;
|
||||||
|
|
||||||
|
if (pOperator->status == OP_RES_TO_RETURN) {
|
||||||
|
return getSortedBlockData(pInfo->pSortHandle, pInfo->binfo.pRes, pOperator->resultInfo.capacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t numOfBufPage = pInfo->sortBufSize / pInfo->bufPageSize;
|
||||||
|
pInfo->pSortHandle = tsortCreateSortHandle(pInfo->pSortInfo, pInfo->inputSlotMap, SORT_SINGLESOURCE_SORT,
|
||||||
|
pInfo->bufPageSize, numOfBufPage, pInfo->binfo.pRes, pTaskInfo->id.str);
|
||||||
|
|
||||||
|
tsortSetFetchRawDataFp(pInfo->pSortHandle, loadNextDataBlock, applyScalarFunction, pOperator);
|
||||||
|
|
||||||
|
|
||||||
|
SSortSource* ps = taosMemoryCalloc(1, sizeof(SSortSource));
|
||||||
|
ps->param = pOperator->pDownstream[0];
|
||||||
|
tsortAddSource(pInfo->pSortHandle, ps);
|
||||||
|
|
||||||
|
int32_t code = tsortOpen(pInfo->pSortHandle);
|
||||||
|
taosMemoryFreeClear(ps);
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
longjmp(pTaskInfo->env, terrno);
|
||||||
|
}
|
||||||
|
|
||||||
|
pOperator->status = OP_RES_TO_RETURN;
|
||||||
|
return getSortedBlockData(pInfo->pSortHandle, pInfo->binfo.pRes, pOperator->resultInfo.capacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroyOrderOperatorInfo(void* param, int32_t numOfOutput) {
|
||||||
|
SSortOperatorInfo* pInfo = (SSortOperatorInfo*)param;
|
||||||
|
pInfo->binfo.pRes = blockDataDestroy(pInfo->binfo.pRes);
|
||||||
|
|
||||||
|
taosArrayDestroy(pInfo->pSortInfo);
|
||||||
|
taosArrayDestroy(pInfo->inputSlotMap);
|
||||||
|
}
|
|
@ -325,7 +325,7 @@ void doTimeWindowInterpolation(SOperatorInfo* pOperator, SOptrBasicInfo* pInfo,
|
||||||
|
|
||||||
SqlFunctionCtx* pCtx = pInfo->pCtx;
|
SqlFunctionCtx* pCtx = pInfo->pCtx;
|
||||||
|
|
||||||
for (int32_t k = 0; k < pOperator->numOfOutput; ++k) {
|
for (int32_t k = 0; k < pOperator->numOfExprs; ++k) {
|
||||||
int32_t functionId = pCtx[k].functionId;
|
int32_t functionId = pCtx[k].functionId;
|
||||||
if (functionId != FUNCTION_TWA && functionId != FUNCTION_INTERP) {
|
if (functionId != FUNCTION_TWA && functionId != FUNCTION_INTERP) {
|
||||||
pCtx[k].start.key = INT64_MIN;
|
pCtx[k].start.key = INT64_MIN;
|
||||||
|
@ -406,12 +406,12 @@ static bool setTimeWindowInterpolationStartTs(SOperatorInfo* pOperatorInfo, SqlF
|
||||||
// start exactly from this point, no need to do interpolation
|
// start exactly from this point, no need to do interpolation
|
||||||
TSKEY key = ascQuery ? win->skey : win->ekey;
|
TSKEY key = ascQuery ? win->skey : win->ekey;
|
||||||
if (key == curTs) {
|
if (key == curTs) {
|
||||||
setNotInterpoWindowKey(pCtx, pOperatorInfo->numOfOutput, RESULT_ROW_START_INTERP);
|
setNotInterpoWindowKey(pCtx, pOperatorInfo->numOfExprs, RESULT_ROW_START_INTERP);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lastTs == INT64_MIN && ((pos == 0 && ascQuery) || (pos == (numOfRows - 1) && !ascQuery))) {
|
if (lastTs == INT64_MIN && ((pos == 0 && ascQuery) || (pos == (numOfRows - 1) && !ascQuery))) {
|
||||||
setNotInterpoWindowKey(pCtx, pOperatorInfo->numOfOutput, RESULT_ROW_START_INTERP);
|
setNotInterpoWindowKey(pCtx, pOperatorInfo->numOfExprs, RESULT_ROW_START_INTERP);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -427,7 +427,7 @@ static bool setTimeWindowInterpolationEndTs(SOperatorInfo* pOperatorInfo, SqlFun
|
||||||
SArray* pDataBlock, const TSKEY* tsCols, TSKEY blockEkey,
|
SArray* pDataBlock, const TSKEY* tsCols, TSKEY blockEkey,
|
||||||
STimeWindow* win) {
|
STimeWindow* win) {
|
||||||
int32_t order = TSDB_ORDER_ASC;
|
int32_t order = TSDB_ORDER_ASC;
|
||||||
int32_t numOfOutput = pOperatorInfo->numOfOutput;
|
int32_t numOfOutput = pOperatorInfo->numOfExprs;
|
||||||
|
|
||||||
TSKEY actualEndKey = tsCols[endRowIndex];
|
TSKEY actualEndKey = tsCols[endRowIndex];
|
||||||
TSKEY key = order ? win->ekey : win->skey;
|
TSKEY key = order ? win->ekey : win->skey;
|
||||||
|
@ -572,7 +572,7 @@ static void doWindowBorderInterpolation(SOperatorInfo* pOperatorInfo, SSDataBloc
|
||||||
setResultRowInterpo(pResult, RESULT_ROW_START_INTERP);
|
setResultRowInterpo(pResult, RESULT_ROW_START_INTERP);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
setNotInterpoWindowKey(pCtx, pOperatorInfo->numOfOutput, RESULT_ROW_START_INTERP);
|
setNotInterpoWindowKey(pCtx, pOperatorInfo->numOfExprs, RESULT_ROW_START_INTERP);
|
||||||
}
|
}
|
||||||
|
|
||||||
// point interpolation does not require the end key time window interpolation.
|
// point interpolation does not require the end key time window interpolation.
|
||||||
|
@ -592,7 +592,7 @@ static void doWindowBorderInterpolation(SOperatorInfo* pOperatorInfo, SSDataBloc
|
||||||
setResultRowInterpo(pResult, RESULT_ROW_END_INTERP);
|
setResultRowInterpo(pResult, RESULT_ROW_END_INTERP);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
setNotInterpoWindowKey(pCtx, pOperatorInfo->numOfOutput, RESULT_ROW_END_INTERP);
|
setNotInterpoWindowKey(pCtx, pOperatorInfo->numOfExprs, RESULT_ROW_END_INTERP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -612,7 +612,7 @@ static SArray* hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pRe
|
||||||
SIntervalAggOperatorInfo* pInfo = (SIntervalAggOperatorInfo*)pOperatorInfo->info;
|
SIntervalAggOperatorInfo* pInfo = (SIntervalAggOperatorInfo*)pOperatorInfo->info;
|
||||||
|
|
||||||
SExecTaskInfo* pTaskInfo = pOperatorInfo->pTaskInfo;
|
SExecTaskInfo* pTaskInfo = pOperatorInfo->pTaskInfo;
|
||||||
int32_t numOfOutput = pOperatorInfo->numOfOutput;
|
int32_t numOfOutput = pOperatorInfo->numOfExprs;
|
||||||
|
|
||||||
SArray* pUpdated = NULL;
|
SArray* pUpdated = NULL;
|
||||||
if (pInfo->execModel == OPTR_EXEC_MODEL_STREAM) {
|
if (pInfo->execModel == OPTR_EXEC_MODEL_STREAM) {
|
||||||
|
@ -683,7 +683,7 @@ static SArray* hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pRe
|
||||||
tsCols[startPos], startPos, w.ekey, RESULT_ROW_END_INTERP);
|
tsCols[startPos], startPos, w.ekey, RESULT_ROW_END_INTERP);
|
||||||
|
|
||||||
setResultRowInterpo(pResult, RESULT_ROW_END_INTERP);
|
setResultRowInterpo(pResult, RESULT_ROW_END_INTERP);
|
||||||
setNotInterpoWindowKey(pInfo->binfo.pCtx, pOperatorInfo->numOfOutput, RESULT_ROW_START_INTERP);
|
setNotInterpoWindowKey(pInfo->binfo.pCtx, pOperatorInfo->numOfExprs, RESULT_ROW_START_INTERP);
|
||||||
|
|
||||||
doApplyFunctions(pInfo->binfo.pCtx, &w, &pInfo->timeWindowData, startPos, 0, tsCols, pSDataBlock->info.rows, numOfOutput, TSDB_ORDER_ASC);
|
doApplyFunctions(pInfo->binfo.pCtx, &w, &pInfo->timeWindowData, startPos, 0, tsCols, pSDataBlock->info.rows, numOfOutput, TSDB_ORDER_ASC);
|
||||||
}
|
}
|
||||||
|
@ -773,7 +773,7 @@ static int32_t doOpenIntervalAgg(SOperatorInfo* pOperator) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// setTagValue(pOperator, pRuntimeEnv->current->pTable, pInfo->pCtx, pOperator->numOfOutput);
|
// setTagValue(pOperator, pRuntimeEnv->current->pTable, pInfo->pCtx, pOperator->numOfExprs);
|
||||||
// the pDataBlock are always the same one, no need to call this again
|
// the pDataBlock are always the same one, no need to call this again
|
||||||
setInputDataBlock(pOperator, pInfo->binfo.pCtx, pBlock, order, true);
|
setInputDataBlock(pOperator, pInfo->binfo.pCtx, pBlock, order, true);
|
||||||
STableQueryInfo* pTableQueryInfo = pInfo->pCurrent;
|
STableQueryInfo* pTableQueryInfo = pInfo->pCurrent;
|
||||||
|
@ -798,7 +798,7 @@ static int32_t doOpenIntervalAgg(SOperatorInfo* pOperator) {
|
||||||
}
|
}
|
||||||
|
|
||||||
closeAllResultRows(&pInfo->binfo.resultRowInfo);
|
closeAllResultRows(&pInfo->binfo.resultRowInfo);
|
||||||
finalizeMultiTupleQueryResult(pInfo->binfo.pCtx, pOperator->numOfOutput, pInfo->aggSup.pResultBuf,
|
finalizeMultiTupleQueryResult(pInfo->binfo.pCtx, pOperator->numOfExprs, pInfo->aggSup.pResultBuf,
|
||||||
&pInfo->binfo.resultRowInfo, pInfo->binfo.rowCellInfoOffset);
|
&pInfo->binfo.resultRowInfo, pInfo->binfo.rowCellInfoOffset);
|
||||||
|
|
||||||
initGroupedResultInfo(&pInfo->groupResInfo, pInfo->aggSup.pResultRowHashTable, true);
|
initGroupedResultInfo(&pInfo->groupResInfo, pInfo->aggSup.pResultRowHashTable, true);
|
||||||
|
@ -813,7 +813,7 @@ static void doStateWindowAggImpl(SOperatorInfo* pOperator, SStateWindowOperatorI
|
||||||
int64_t gid = pBlock->info.groupId;
|
int64_t gid = pBlock->info.groupId;
|
||||||
|
|
||||||
bool masterScan = true;
|
bool masterScan = true;
|
||||||
int32_t numOfOutput = pOperator->numOfOutput;
|
int32_t numOfOutput = pOperator->numOfExprs;
|
||||||
int16_t bytes = pStateColInfoData->info.bytes;
|
int16_t bytes = pStateColInfoData->info.bytes;
|
||||||
|
|
||||||
SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, pInfo->tsSlotId);
|
SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, pInfo->tsSlotId);
|
||||||
|
@ -916,7 +916,7 @@ static SSDataBlock* doStateWindowAgg(SOperatorInfo* pOperator) {
|
||||||
|
|
||||||
pOperator->status = OP_RES_TO_RETURN;
|
pOperator->status = OP_RES_TO_RETURN;
|
||||||
closeAllResultRows(&pBInfo->resultRowInfo);
|
closeAllResultRows(&pBInfo->resultRowInfo);
|
||||||
finalizeMultiTupleQueryResult(pBInfo->pCtx, pOperator->numOfOutput, pInfo->aggSup.pResultBuf, &pBInfo->resultRowInfo,
|
finalizeMultiTupleQueryResult(pBInfo->pCtx, pOperator->numOfExprs, pInfo->aggSup.pResultBuf, &pBInfo->resultRowInfo,
|
||||||
pBInfo->rowCellInfoOffset);
|
pBInfo->rowCellInfoOffset);
|
||||||
|
|
||||||
initGroupedResultInfo(&pInfo->groupResInfo, pInfo->aggSup.pResultRowHashTable, true);
|
initGroupedResultInfo(&pInfo->groupResInfo, pInfo->aggSup.pResultRowHashTable, true);
|
||||||
|
@ -1013,13 +1013,13 @@ static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) {
|
||||||
// The timewindows that overlaps the timestamps of the input pBlock need to be recalculated and return to the
|
// The timewindows that overlaps the timestamps of the input pBlock need to be recalculated and return to the
|
||||||
// caller. Note that all the time window are not close till now.
|
// caller. Note that all the time window are not close till now.
|
||||||
|
|
||||||
// setTagValue(pOperator, pRuntimeEnv->current->pTable, pInfo->pCtx, pOperator->numOfOutput);
|
// setTagValue(pOperator, pRuntimeEnv->current->pTable, pInfo->pCtx, pOperator->numOfExprs);
|
||||||
// the pDataBlock are always the same one, no need to call this again
|
// the pDataBlock are always the same one, no need to call this again
|
||||||
setInputDataBlock(pOperator, pInfo->binfo.pCtx, pBlock, order, true);
|
setInputDataBlock(pOperator, pInfo->binfo.pCtx, pBlock, order, true);
|
||||||
pUpdated = hashIntervalAgg(pOperator, &pInfo->binfo.resultRowInfo, pBlock, 0);
|
pUpdated = hashIntervalAgg(pOperator, &pInfo->binfo.resultRowInfo, pBlock, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
finalizeUpdatedResult(pOperator->numOfOutput, pInfo->aggSup.pResultBuf, pUpdated, pInfo->binfo.rowCellInfoOffset);
|
finalizeUpdatedResult(pOperator->numOfExprs, pInfo->aggSup.pResultBuf, pUpdated, pInfo->binfo.rowCellInfoOffset);
|
||||||
|
|
||||||
initMultiResInfoFromArrayList(&pInfo->groupResInfo, pUpdated);
|
initMultiResInfoFromArrayList(&pInfo->groupResInfo, pUpdated);
|
||||||
blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity);
|
blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity);
|
||||||
|
@ -1082,7 +1082,7 @@ SOperatorInfo* createIntervalOperatorInfo(SOperatorInfo* downstream, SExprInfo*
|
||||||
pOperator->status = OP_NOT_OPENED;
|
pOperator->status = OP_NOT_OPENED;
|
||||||
pOperator->pExpr = pExprInfo;
|
pOperator->pExpr = pExprInfo;
|
||||||
pOperator->pTaskInfo = pTaskInfo;
|
pOperator->pTaskInfo = pTaskInfo;
|
||||||
pOperator->numOfOutput = numOfCols;
|
pOperator->numOfExprs = numOfCols;
|
||||||
pOperator->info = pInfo;
|
pOperator->info = pInfo;
|
||||||
|
|
||||||
pOperator->fpSet = createOperatorFpSet(doOpenIntervalAgg, doBuildIntervalResult, doStreamIntervalAgg, NULL,
|
pOperator->fpSet = createOperatorFpSet(doOpenIntervalAgg, doBuildIntervalResult, doStreamIntervalAgg, NULL,
|
||||||
|
@ -1141,7 +1141,7 @@ SOperatorInfo* createStreamIntervalOperatorInfo(SOperatorInfo* downstream, SExpr
|
||||||
pOperator->status = OP_NOT_OPENED;
|
pOperator->status = OP_NOT_OPENED;
|
||||||
pOperator->pExpr = pExprInfo;
|
pOperator->pExpr = pExprInfo;
|
||||||
pOperator->pTaskInfo = pTaskInfo;
|
pOperator->pTaskInfo = pTaskInfo;
|
||||||
pOperator->numOfOutput = numOfCols;
|
pOperator->numOfExprs = numOfCols;
|
||||||
pOperator->info = pInfo;
|
pOperator->info = pInfo;
|
||||||
|
|
||||||
pOperator->fpSet = createOperatorFpSet(doOpenIntervalAgg, doStreamIntervalAgg, doStreamIntervalAgg, NULL,
|
pOperator->fpSet = createOperatorFpSet(doOpenIntervalAgg, doStreamIntervalAgg, doStreamIntervalAgg, NULL,
|
||||||
|
@ -1169,7 +1169,7 @@ static void doSessionWindowAggImpl(SOperatorInfo* pOperator, SSessionAggOperator
|
||||||
SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, pInfo->tsSlotId);
|
SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, pInfo->tsSlotId);
|
||||||
|
|
||||||
bool masterScan = true;
|
bool masterScan = true;
|
||||||
int32_t numOfOutput = pOperator->numOfOutput;
|
int32_t numOfOutput = pOperator->numOfExprs;
|
||||||
int64_t gid = pBlock->info.groupId;
|
int64_t gid = pBlock->info.groupId;
|
||||||
|
|
||||||
int64_t gap = pInfo->gap;
|
int64_t gap = pInfo->gap;
|
||||||
|
@ -1270,7 +1270,7 @@ static SSDataBlock* doSessionWindowAgg(SOperatorInfo* pOperator) {
|
||||||
// restore the value
|
// restore the value
|
||||||
pOperator->status = OP_RES_TO_RETURN;
|
pOperator->status = OP_RES_TO_RETURN;
|
||||||
closeAllResultRows(&pBInfo->resultRowInfo);
|
closeAllResultRows(&pBInfo->resultRowInfo);
|
||||||
finalizeMultiTupleQueryResult(pBInfo->pCtx, pOperator->numOfOutput, pInfo->aggSup.pResultBuf, &pBInfo->resultRowInfo,
|
finalizeMultiTupleQueryResult(pBInfo->pCtx, pOperator->numOfExprs, pInfo->aggSup.pResultBuf, &pBInfo->resultRowInfo,
|
||||||
pBInfo->rowCellInfoOffset);
|
pBInfo->rowCellInfoOffset);
|
||||||
|
|
||||||
initGroupedResultInfo(&pInfo->groupResInfo, pInfo->aggSup.pResultRowHashTable, true);
|
initGroupedResultInfo(&pInfo->groupResInfo, pInfo->aggSup.pResultRowHashTable, true);
|
||||||
|
@ -1309,7 +1309,7 @@ static SSDataBlock* doAllIntervalAgg(SOperatorInfo* pOperator) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// setTagValue(pOperator, pRuntimeEnv->current->pTable, pIntervalInfo->pCtx, pOperator->numOfOutput);
|
// setTagValue(pOperator, pRuntimeEnv->current->pTable, pIntervalInfo->pCtx, pOperator->numOfExprs);
|
||||||
// the pDataBlock are always the same one, no need to call this again
|
// the pDataBlock are always the same one, no need to call this again
|
||||||
setInputDataBlock(pOperator, pSliceInfo->binfo.pCtx, pBlock, order, true);
|
setInputDataBlock(pOperator, pSliceInfo->binfo.pCtx, pBlock, order, true);
|
||||||
// hashAllIntervalAgg(pOperator, &pSliceInfo->binfo.resultRowInfo, pBlock, 0);
|
// hashAllIntervalAgg(pOperator, &pSliceInfo->binfo.resultRowInfo, pBlock, 0);
|
||||||
|
@ -1319,7 +1319,7 @@ static SSDataBlock* doAllIntervalAgg(SOperatorInfo* pOperator) {
|
||||||
pOperator->status = OP_RES_TO_RETURN;
|
pOperator->status = OP_RES_TO_RETURN;
|
||||||
closeAllResultRows(&pSliceInfo->binfo.resultRowInfo);
|
closeAllResultRows(&pSliceInfo->binfo.resultRowInfo);
|
||||||
setTaskStatus(pOperator->pTaskInfo, TASK_COMPLETED);
|
setTaskStatus(pOperator->pTaskInfo, TASK_COMPLETED);
|
||||||
// finalizeQueryResult(pSliceInfo->binfo.pCtx, pOperator->numOfOutput);
|
// finalizeQueryResult(pSliceInfo->binfo.pCtx, pOperator->numOfExprs);
|
||||||
|
|
||||||
// initGroupedResultInfo(&pSliceInfo->groupResInfo, &pSliceInfo->binfo.resultRowInfo);
|
// initGroupedResultInfo(&pSliceInfo->groupResInfo, &pSliceInfo->binfo.resultRowInfo);
|
||||||
// doBuildResultDatablock(&pRuntimeEnv->groupResInfo, pRuntimeEnv, pSliceInfo->pRes);
|
// doBuildResultDatablock(&pRuntimeEnv->groupResInfo, pRuntimeEnv, pSliceInfo->pRes);
|
||||||
|
@ -1346,7 +1346,7 @@ SOperatorInfo* createTimeSliceOperatorInfo(SOperatorInfo* downstream, SExprInfo*
|
||||||
pOperator->blocking = true;
|
pOperator->blocking = true;
|
||||||
pOperator->status = OP_NOT_OPENED;
|
pOperator->status = OP_NOT_OPENED;
|
||||||
pOperator->pExpr = pExprInfo;
|
pOperator->pExpr = pExprInfo;
|
||||||
pOperator->numOfOutput = numOfCols;
|
pOperator->numOfExprs = numOfCols;
|
||||||
pOperator->info = pInfo;
|
pOperator->info = pInfo;
|
||||||
pOperator->pTaskInfo = pTaskInfo;
|
pOperator->pTaskInfo = pTaskInfo;
|
||||||
|
|
||||||
|
@ -1388,7 +1388,7 @@ SOperatorInfo* createStatewindowOperatorInfo(SOperatorInfo* downstream, SExprInf
|
||||||
pOperator->blocking = true;
|
pOperator->blocking = true;
|
||||||
pOperator->status = OP_NOT_OPENED;
|
pOperator->status = OP_NOT_OPENED;
|
||||||
pOperator->pExpr = pExpr;
|
pOperator->pExpr = pExpr;
|
||||||
pOperator->numOfOutput = numOfCols;
|
pOperator->numOfExprs = numOfCols;
|
||||||
pOperator->pTaskInfo = pTaskInfo;
|
pOperator->pTaskInfo = pTaskInfo;
|
||||||
pOperator->info = pInfo;
|
pOperator->info = pInfo;
|
||||||
|
|
||||||
|
@ -1440,7 +1440,7 @@ SOperatorInfo* createSessionAggOperatorInfo(SOperatorInfo* downstream, SExprInfo
|
||||||
pOperator->blocking = true;
|
pOperator->blocking = true;
|
||||||
pOperator->status = OP_NOT_OPENED;
|
pOperator->status = OP_NOT_OPENED;
|
||||||
pOperator->pExpr = pExprInfo;
|
pOperator->pExpr = pExprInfo;
|
||||||
pOperator->numOfOutput = numOfCols;
|
pOperator->numOfExprs = numOfCols;
|
||||||
pOperator->info = pInfo;
|
pOperator->info = pInfo;
|
||||||
|
|
||||||
pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doSessionWindowAgg, NULL, NULL,
|
pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doSessionWindowAgg, NULL, NULL,
|
||||||
|
|
|
@ -42,11 +42,7 @@ struct SSortHandle {
|
||||||
|
|
||||||
_sort_fetch_block_fn_t fetchfp;
|
_sort_fetch_block_fn_t fetchfp;
|
||||||
_sort_merge_compar_fn_t comparFn;
|
_sort_merge_compar_fn_t comparFn;
|
||||||
|
|
||||||
void *pParam;
|
|
||||||
SMultiwayMergeTreeInfo *pMergeTree;
|
SMultiwayMergeTreeInfo *pMergeTree;
|
||||||
int32_t numOfCols;
|
|
||||||
|
|
||||||
int64_t startTs;
|
int64_t startTs;
|
||||||
uint64_t sortElapsed;
|
uint64_t sortElapsed;
|
||||||
uint64_t totalElapsed;
|
uint64_t totalElapsed;
|
||||||
|
@ -61,6 +57,9 @@ struct SSortHandle {
|
||||||
bool inMemSort;
|
bool inMemSort;
|
||||||
bool needAdjust;
|
bool needAdjust;
|
||||||
STupleHandle tupleHandle;
|
STupleHandle tupleHandle;
|
||||||
|
|
||||||
|
void *param;
|
||||||
|
void (*beforeFp)(SSDataBlock* pBlock, void* param);
|
||||||
};
|
};
|
||||||
|
|
||||||
static int32_t msortComparFn(const void *pLeft, const void *pRight, void *param);
|
static int32_t msortComparFn(const void *pLeft, const void *pRight, void *param);
|
||||||
|
@ -533,6 +532,13 @@ static int32_t createInitialSortedMultiSources(SSortHandle* pHandle) {
|
||||||
pHandle->pDataBlock = createOneDataBlock(pBlock, false);
|
pHandle->pDataBlock = createOneDataBlock(pBlock, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// perform the scalar function calculation before apply the sort
|
||||||
|
if (pHandle->beforeFp != NULL) {
|
||||||
|
pHandle->beforeFp(pBlock, pHandle->param);
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo relocate the columns
|
||||||
|
|
||||||
int32_t code = blockDataMerge(pHandle->pDataBlock, pBlock, pHandle->pIndexMap);
|
int32_t code = blockDataMerge(pHandle->pDataBlock, pBlock, pHandle->pIndexMap);
|
||||||
if (code != 0) {
|
if (code != 0) {
|
||||||
return code;
|
return code;
|
||||||
|
@ -623,8 +629,10 @@ int32_t tsortClose(SSortHandle* pHandle) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tsortSetFetchRawDataFp(SSortHandle* pHandle, _sort_fetch_block_fn_t fp) {
|
int32_t tsortSetFetchRawDataFp(SSortHandle* pHandle, _sort_fetch_block_fn_t fetchFp, void (*fp)(SSDataBlock*, void*), void* param) {
|
||||||
pHandle->fetchfp = fp;
|
pHandle->fetchfp = fetchFp;
|
||||||
|
pHandle->beforeFp = fp;
|
||||||
|
pHandle->param = param;
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -210,7 +210,7 @@ TEST(testCase, inMem_sort_Test) {
|
||||||
taosArrayPush(orderInfo, &oi);
|
taosArrayPush(orderInfo, &oi);
|
||||||
|
|
||||||
SSortHandle* phandle = tsortCreateSortHandle(orderInfo, NULL, SORT_SINGLESOURCE_SORT, 1024, 5, NULL, "test_abc");
|
SSortHandle* phandle = tsortCreateSortHandle(orderInfo, NULL, SORT_SINGLESOURCE_SORT, 1024, 5, NULL, "test_abc");
|
||||||
tsortSetFetchRawDataFp(phandle, getSingleColDummyBlock);
|
tsortSetFetchRawDataFp(phandle, getSingleColDummyBlock, NULL, NULL);
|
||||||
|
|
||||||
_info* pInfo = (_info*) taosMemoryCalloc(1, sizeof(_info));
|
_info* pInfo = (_info*) taosMemoryCalloc(1, sizeof(_info));
|
||||||
pInfo->startVal = 0;
|
pInfo->startVal = 0;
|
||||||
|
@ -299,7 +299,7 @@ TEST(testCase, external_mem_sort_Test) {
|
||||||
taosArrayPush(orderInfo, &oi);
|
taosArrayPush(orderInfo, &oi);
|
||||||
|
|
||||||
SSortHandle* phandle = tsortCreateSortHandle(orderInfo, NULL, SORT_SINGLESOURCE_SORT, 128, 3, NULL, "test_abc");
|
SSortHandle* phandle = tsortCreateSortHandle(orderInfo, NULL, SORT_SINGLESOURCE_SORT, 128, 3, NULL, "test_abc");
|
||||||
tsortSetFetchRawDataFp(phandle, getSingleColDummyBlock);
|
tsortSetFetchRawDataFp(phandle, getSingleColDummyBlock, NULL, NULL);
|
||||||
|
|
||||||
SSortSource* ps = static_cast<SSortSource*>(taosMemoryCalloc(1, sizeof(SSortSource)));
|
SSortSource* ps = static_cast<SSortSource*>(taosMemoryCalloc(1, sizeof(SSortSource)));
|
||||||
ps->param = &pInfo[i];
|
ps->param = &pInfo[i];
|
||||||
|
@ -366,7 +366,7 @@ TEST(testCase, ordered_merge_sort_Test) {
|
||||||
}
|
}
|
||||||
|
|
||||||
SSortHandle* phandle = tsortCreateSortHandle(orderInfo, NULL, SORT_MULTISOURCE_MERGE, 1024, 5, pBlock,"test_abc");
|
SSortHandle* phandle = tsortCreateSortHandle(orderInfo, NULL, SORT_MULTISOURCE_MERGE, 1024, 5, pBlock,"test_abc");
|
||||||
tsortSetFetchRawDataFp(phandle, getSingleColDummyBlock);
|
tsortSetFetchRawDataFp(phandle, getSingleColDummyBlock, NULL, NULL);
|
||||||
tsortSetComparFp(phandle, docomp);
|
tsortSetComparFp(phandle, docomp);
|
||||||
|
|
||||||
SSortSource* p[10] = {0};
|
SSortSource* p[10] = {0};
|
||||||
|
|
|
@ -48,8 +48,7 @@ target_include_directories(
|
||||||
PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/inc"
|
PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/inc"
|
||||||
)
|
)
|
||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
udf1 PUBLIC os
|
udf1 PUBLIC os)
|
||||||
)
|
|
||||||
|
|
||||||
add_library(udf2 MODULE test/udf2.c)
|
add_library(udf2 MODULE test/udf2.c)
|
||||||
target_include_directories(
|
target_include_directories(
|
||||||
|
|
|
@ -19,9 +19,6 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//TODO replaces them with fnDebug
|
|
||||||
//#define debugPrint(...) taosPrintLog("Function", DEBUG_INFO, 135, __VA_ARGS__)
|
|
||||||
#define debugPrint(...) {fprintf(stderr, __VA_ARGS__);fprintf(stderr, "\n");}
|
|
||||||
enum {
|
enum {
|
||||||
UDF_TASK_SETUP = 0,
|
UDF_TASK_SETUP = 0,
|
||||||
UDF_TASK_CALL = 1,
|
UDF_TASK_CALL = 1,
|
||||||
|
@ -107,7 +104,7 @@ void* decodeUdfRequest(const void *buf, SUdfRequest* request);
|
||||||
int32_t encodeUdfResponse(void **buf, const SUdfResponse *response);
|
int32_t encodeUdfResponse(void **buf, const SUdfResponse *response);
|
||||||
void* decodeUdfResponse(const void* buf, SUdfResponse *response);
|
void* decodeUdfResponse(const void* buf, SUdfResponse *response);
|
||||||
|
|
||||||
void freeUdfColumnData(SUdfColumnData *data);
|
void freeUdfColumnData(SUdfColumnData *data, SUdfColumnMeta *meta);
|
||||||
void freeUdfColumn(SUdfColumn* col);
|
void freeUdfColumn(SUdfColumn* col);
|
||||||
void freeUdfDataDataBlock(SUdfDataBlock *block);
|
void freeUdfDataDataBlock(SUdfDataBlock *block);
|
||||||
|
|
||||||
|
|
|
@ -481,8 +481,8 @@ void* decodeUdfResponse(const void* buf, SUdfResponse* rsp) {
|
||||||
return (void*)buf;
|
return (void*)buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void freeUdfColumnData(SUdfColumnData *data) {
|
void freeUdfColumnData(SUdfColumnData *data, SUdfColumnMeta *meta) {
|
||||||
if (data->varLengthColumn) {
|
if (IS_VAR_DATA_TYPE(meta->type)) {
|
||||||
taosMemoryFree(data->varLenCol.varOffsets);
|
taosMemoryFree(data->varLenCol.varOffsets);
|
||||||
data->varLenCol.varOffsets = NULL;
|
data->varLenCol.varOffsets = NULL;
|
||||||
taosMemoryFree(data->varLenCol.payload);
|
taosMemoryFree(data->varLenCol.payload);
|
||||||
|
@ -496,7 +496,7 @@ void freeUdfColumnData(SUdfColumnData *data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void freeUdfColumn(SUdfColumn* col) {
|
void freeUdfColumn(SUdfColumn* col) {
|
||||||
freeUdfColumnData(&col->colData);
|
freeUdfColumnData(&col->colData, &col->colMeta);
|
||||||
}
|
}
|
||||||
|
|
||||||
void freeUdfDataDataBlock(SUdfDataBlock *block) {
|
void freeUdfDataDataBlock(SUdfDataBlock *block) {
|
||||||
|
@ -528,8 +528,7 @@ int32_t convertDataBlockToUdfDataBlock(SSDataBlock *block, SUdfDataBlock *udfBlo
|
||||||
udfCol->colMeta.scale = col->info.scale;
|
udfCol->colMeta.scale = col->info.scale;
|
||||||
udfCol->colMeta.precision = col->info.precision;
|
udfCol->colMeta.precision = col->info.precision;
|
||||||
udfCol->colData.numOfRows = udfBlock->numOfRows;
|
udfCol->colData.numOfRows = udfBlock->numOfRows;
|
||||||
udfCol->colData.varLengthColumn = IS_VAR_DATA_TYPE(udfCol->colMeta.type);
|
if (IS_VAR_DATA_TYPE(udfCol->colMeta.type)) {
|
||||||
if (udfCol->colData.varLengthColumn) {
|
|
||||||
udfCol->colData.varLenCol.varOffsetsLen = sizeof(int32_t) * udfBlock->numOfRows;
|
udfCol->colData.varLenCol.varOffsetsLen = sizeof(int32_t) * udfBlock->numOfRows;
|
||||||
udfCol->colData.varLenCol.varOffsets = taosMemoryMalloc(udfCol->colData.varLenCol.varOffsetsLen);
|
udfCol->colData.varLenCol.varOffsets = taosMemoryMalloc(udfCol->colData.varLenCol.varOffsetsLen);
|
||||||
memcpy(udfCol->colData.varLenCol.varOffsets, col->varmeta.offset, udfCol->colData.varLenCol.varOffsetsLen);
|
memcpy(udfCol->colData.varLenCol.varOffsets, col->varmeta.offset, udfCol->colData.varLenCol.varOffsetsLen);
|
||||||
|
@ -555,7 +554,7 @@ int32_t convertDataBlockToUdfDataBlock(SSDataBlock *block, SUdfDataBlock *udfBlo
|
||||||
int32_t convertUdfColumnToDataBlock(SUdfColumn *udfCol, SSDataBlock *block) {
|
int32_t convertUdfColumnToDataBlock(SUdfColumn *udfCol, SSDataBlock *block) {
|
||||||
block->info.numOfCols = 1;
|
block->info.numOfCols = 1;
|
||||||
block->info.rows = udfCol->colData.numOfRows;
|
block->info.rows = udfCol->colData.numOfRows;
|
||||||
block->info.hasVarCol = udfCol->colData.varLengthColumn;
|
block->info.hasVarCol = IS_VAR_DATA_TYPE(udfCol->colMeta.type);
|
||||||
|
|
||||||
block->pDataBlock = taosArrayInit(1, sizeof(SColumnInfoData));
|
block->pDataBlock = taosArrayInit(1, sizeof(SColumnInfoData));
|
||||||
taosArraySetSize(block->pDataBlock, 1);
|
taosArraySetSize(block->pDataBlock, 1);
|
||||||
|
|
|
@ -75,8 +75,8 @@ typedef struct SUdf {
|
||||||
char path[PATH_MAX];
|
char path[PATH_MAX];
|
||||||
|
|
||||||
uv_lib_t lib;
|
uv_lib_t lib;
|
||||||
|
|
||||||
TUdfScalarProcFunc scalarProcFunc;
|
TUdfScalarProcFunc scalarProcFunc;
|
||||||
TUdfFreeUdfColumnFunc freeUdfColumn;
|
|
||||||
|
|
||||||
TUdfAggStartFunc aggStartFunc;
|
TUdfAggStartFunc aggStartFunc;
|
||||||
TUdfAggProcessFunc aggProcFunc;
|
TUdfAggProcessFunc aggProcFunc;
|
||||||
|
@ -106,11 +106,6 @@ int32_t udfdLoadUdf(char *udfName, SUdf *udf) {
|
||||||
char processFuncName[TSDB_FUNC_NAME_LEN] = {0};
|
char processFuncName[TSDB_FUNC_NAME_LEN] = {0};
|
||||||
strcpy(processFuncName, udfName);
|
strcpy(processFuncName, udfName);
|
||||||
uv_dlsym(&udf->lib, processFuncName, (void **)(&udf->scalarProcFunc));
|
uv_dlsym(&udf->lib, processFuncName, (void **)(&udf->scalarProcFunc));
|
||||||
char freeFuncName[TSDB_FUNC_NAME_LEN + 5] = {0};
|
|
||||||
char *freeSuffix = "_free";
|
|
||||||
strncpy(freeFuncName, processFuncName, strlen(processFuncName));
|
|
||||||
strncat(freeFuncName, freeSuffix, strlen(freeSuffix));
|
|
||||||
uv_dlsym(&udf->lib, freeFuncName, (void **)(&udf->freeUdfColumn));
|
|
||||||
} else if (udf->funcType == TSDB_FUNC_TYPE_AGGREGATE) {
|
} else if (udf->funcType == TSDB_FUNC_TYPE_AGGREGATE) {
|
||||||
char processFuncName[TSDB_FUNC_NAME_LEN] = {0};
|
char processFuncName[TSDB_FUNC_NAME_LEN] = {0};
|
||||||
strcpy(processFuncName, udfName);
|
strcpy(processFuncName, udfName);
|
||||||
|
@ -215,7 +210,7 @@ void udfdProcessRequest(uv_work_t *req) {
|
||||||
udf->scalarProcFunc(&input, &output);
|
udf->scalarProcFunc(&input, &output);
|
||||||
|
|
||||||
convertUdfColumnToDataBlock(&output, &response.callRsp.resultData);
|
convertUdfColumnToDataBlock(&output, &response.callRsp.resultData);
|
||||||
udf->freeUdfColumn(&output);
|
freeUdfColumn(&output);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TSDB_UDF_CALL_AGG_INIT: {
|
case TSDB_UDF_CALL_AGG_INIT: {
|
||||||
|
|
|
@ -18,52 +18,20 @@ int32_t udf1_destroy() {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t udf1(SUdfDataBlock* block, SUdfColumn *resultCol) {
|
int32_t udf1(SUdfDataBlock* block, SUdfColumn *resultCol) {
|
||||||
SUdfColumnData *resultData = &resultCol->colData;
|
|
||||||
resultData->numOfRows = block->numOfRows;
|
|
||||||
SUdfColumnData *srcData = &block->udfCols[0]->colData;
|
|
||||||
resultData->varLengthColumn = srcData->varLengthColumn;
|
|
||||||
|
|
||||||
if (resultData->varLengthColumn) {
|
|
||||||
resultData->varLenCol.varOffsetsLen = srcData->varLenCol.varOffsetsLen;
|
|
||||||
resultData->varLenCol.varOffsets = malloc(resultData->varLenCol.varOffsetsLen);
|
|
||||||
memcpy(resultData->varLenCol.varOffsets, srcData->varLenCol.varOffsets, srcData->varLenCol.varOffsetsLen);
|
|
||||||
|
|
||||||
resultData->varLenCol.payloadLen = srcData->varLenCol.payloadLen;
|
|
||||||
resultData->varLenCol.payload = malloc(resultData->varLenCol.payloadLen);
|
|
||||||
memcpy(resultData->varLenCol.payload, srcData->varLenCol.payload, srcData->varLenCol.payloadLen);
|
|
||||||
} else {
|
|
||||||
resultData->fixLenCol.nullBitmapLen = srcData->fixLenCol.nullBitmapLen;
|
|
||||||
resultData->fixLenCol.nullBitmap = malloc(resultData->fixLenCol.nullBitmapLen);
|
|
||||||
memcpy(resultData->fixLenCol.nullBitmap, srcData->fixLenCol.nullBitmap, srcData->fixLenCol.nullBitmapLen);
|
|
||||||
|
|
||||||
resultData->fixLenCol.dataLen = srcData->fixLenCol.dataLen;
|
|
||||||
resultData->fixLenCol.data = malloc(resultData->fixLenCol.dataLen);
|
|
||||||
memcpy(resultData->fixLenCol.data, srcData->fixLenCol.data, srcData->fixLenCol.dataLen);
|
|
||||||
for (int32_t i = 0; i < resultData->numOfRows; ++i) {
|
|
||||||
*(resultData->fixLenCol.data + i * sizeof(int32_t)) = 88;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SUdfColumnMeta *meta = &resultCol->colMeta;
|
SUdfColumnMeta *meta = &resultCol->colMeta;
|
||||||
meta->bytes = 4;
|
meta->bytes = 4;
|
||||||
meta->type = TSDB_DATA_TYPE_INT;
|
meta->type = TSDB_DATA_TYPE_INT;
|
||||||
meta->scale = 0;
|
meta->scale = 0;
|
||||||
meta->precision = 0;
|
meta->precision = 0;
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t udf1_free(SUdfColumn *col) {
|
SUdfColumnData *resultData = &resultCol->colData;
|
||||||
SUdfColumnData *data = &col->colData;
|
resultData->numOfRows = block->numOfRows;
|
||||||
if (data->varLengthColumn) {
|
SUdfColumnData *srcData = &block->udfCols[0]->colData;
|
||||||
free(data->varLenCol.varOffsets);
|
|
||||||
data->varLenCol.varOffsets = NULL;
|
for (int32_t i = 0; i < resultData->numOfRows; ++i) {
|
||||||
free(data->varLenCol.payload);
|
int32_t luckyNum = 88;
|
||||||
data->varLenCol.payload = NULL;
|
udfColSetRow(resultCol, i, (char*)&luckyNum, false);
|
||||||
} else {
|
|
||||||
free(data->fixLenCol.nullBitmap);
|
|
||||||
data->fixLenCol.nullBitmap = NULL;
|
|
||||||
free(data->fixLenCol.data);
|
|
||||||
data->fixLenCol.data = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
|
@ -1971,7 +1971,18 @@ static int32_t datumToJson(const void* pObj, SJson* pJson) {
|
||||||
case TSDB_DATA_TYPE_DOUBLE:
|
case TSDB_DATA_TYPE_DOUBLE:
|
||||||
code = tjsonAddDoubleToObject(pJson, jkValueDatum, pNode->datum.d);
|
code = tjsonAddDoubleToObject(pJson, jkValueDatum, pNode->datum.d);
|
||||||
break;
|
break;
|
||||||
case TSDB_DATA_TYPE_NCHAR:
|
case TSDB_DATA_TYPE_NCHAR: {
|
||||||
|
//cJSON only support utf-8 encoding. Convert memory content to hex string.
|
||||||
|
char *buf = taosMemoryCalloc(varDataLen(pNode->datum.p) * 2 + 1, sizeof(char));
|
||||||
|
code = taosHexEncode(varDataVal(pNode->datum.p), buf, varDataLen(pNode->datum.p));
|
||||||
|
if(code != TSDB_CODE_SUCCESS) {
|
||||||
|
taosMemoryFree(buf);
|
||||||
|
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||||
|
}
|
||||||
|
code = tjsonAddStringToObject(pJson, jkValueDatum, buf);
|
||||||
|
taosMemoryFree(buf);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case TSDB_DATA_TYPE_VARCHAR:
|
case TSDB_DATA_TYPE_VARCHAR:
|
||||||
case TSDB_DATA_TYPE_VARBINARY:
|
case TSDB_DATA_TYPE_VARBINARY:
|
||||||
code = tjsonAddStringToObject(pJson, jkValueDatum, varDataVal(pNode->datum.p));
|
code = tjsonAddStringToObject(pJson, jkValueDatum, varDataVal(pNode->datum.p));
|
||||||
|
@ -2074,7 +2085,26 @@ static int32_t jsonToDatum(const SJson* pJson, void* pObj) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
varDataSetLen(pNode->datum.p, pNode->node.resType.bytes);
|
varDataSetLen(pNode->datum.p, pNode->node.resType.bytes);
|
||||||
code = tjsonGetStringValue(pJson, jkValueDatum, varDataVal(pNode->datum.p));
|
if (TSDB_DATA_TYPE_NCHAR == pNode->node.resType.type) {
|
||||||
|
char *buf = taosMemoryCalloc(1, pNode->node.resType.bytes * 2 + VARSTR_HEADER_SIZE + 1);
|
||||||
|
if (NULL == buf) {
|
||||||
|
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
code = tjsonGetStringValue(pJson, jkValueDatum, buf);
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
taosMemoryFree(buf);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
code = taosHexDecode(buf, varDataVal(pNode->datum.p), pNode->node.resType.bytes - VARSTR_HEADER_SIZE);
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
taosMemoryFree(buf);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
taosMemoryFree(buf);
|
||||||
|
} else {
|
||||||
|
code = tjsonGetStringValue(pJson, jkValueDatum, varDataVal(pNode->datum.p));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TSDB_DATA_TYPE_JSON:
|
case TSDB_DATA_TYPE_JSON:
|
||||||
|
|
|
@ -363,10 +363,8 @@ SNode* createCastFunctionNode(SAstCreateContext* pCxt, SNode* pExpr, SDataType d
|
||||||
CHECK_OUT_OF_MEM(func);
|
CHECK_OUT_OF_MEM(func);
|
||||||
strcpy(func->functionName, "cast");
|
strcpy(func->functionName, "cast");
|
||||||
func->node.resType = dt;
|
func->node.resType = dt;
|
||||||
if (TSDB_DATA_TYPE_BINARY == dt.type) {
|
if (TSDB_DATA_TYPE_NCHAR == dt.type) {
|
||||||
func->node.resType.bytes += 2;
|
func->node.resType.bytes = func->node.resType.bytes * TSDB_NCHAR_SIZE;
|
||||||
} else if (TSDB_DATA_TYPE_NCHAR == dt.type) {
|
|
||||||
func->node.resType.bytes = func->node.resType.bytes * TSDB_NCHAR_SIZE + 2;
|
|
||||||
}
|
}
|
||||||
nodesListMakeAppend(&func->pParameterList, pExpr);
|
nodesListMakeAppend(&func->pParameterList, pExpr);
|
||||||
return (SNode*)func;
|
return (SNode*)func;
|
||||||
|
|
|
@ -1043,6 +1043,7 @@ static void destroyDataBlock(STableDataBlocks* pDataBlock) {
|
||||||
static void destroyInsertParseContext(SInsertParseContext* pCxt) {
|
static void destroyInsertParseContext(SInsertParseContext* pCxt) {
|
||||||
destroyInsertParseContextForTable(pCxt);
|
destroyInsertParseContextForTable(pCxt);
|
||||||
taosHashCleanup(pCxt->pVgroupsHashObj);
|
taosHashCleanup(pCxt->pVgroupsHashObj);
|
||||||
|
taosHashCleanup(pCxt->pSubTableHashObj);
|
||||||
|
|
||||||
destroyBlockHashmap(pCxt->pTableBlockHashObj);
|
destroyBlockHashmap(pCxt->pTableBlockHashObj);
|
||||||
destroyBlockArrayList(pCxt->pVgDataBlocks);
|
destroyBlockArrayList(pCxt->pVgDataBlocks);
|
||||||
|
|
|
@ -4062,7 +4062,8 @@ static int32_t setQuery(STranslateContext* pCxt, SQuery* pQuery) {
|
||||||
|
|
||||||
int32_t translate(SParseContext* pParseCxt, SQuery* pQuery) {
|
int32_t translate(SParseContext* pParseCxt, SQuery* pQuery) {
|
||||||
STranslateContext cxt = {0};
|
STranslateContext cxt = {0};
|
||||||
int32_t code = initTranslateContext(pParseCxt, &cxt);
|
|
||||||
|
int32_t code = initTranslateContext(pParseCxt, &cxt);
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = fmFuncMgtInit();
|
code = fmFuncMgtInit();
|
||||||
}
|
}
|
||||||
|
|
|
@ -709,6 +709,10 @@ int32_t castFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutp
|
||||||
int16_t outputType = GET_PARAM_TYPE(&pOutput[0]);
|
int16_t outputType = GET_PARAM_TYPE(&pOutput[0]);
|
||||||
int64_t outputLen = GET_PARAM_BYTES(&pOutput[0]);
|
int64_t outputLen = GET_PARAM_BYTES(&pOutput[0]);
|
||||||
|
|
||||||
|
if (IS_VAR_DATA_TYPE(outputType)) {
|
||||||
|
outputLen += VARSTR_HEADER_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
char *outputBuf = taosMemoryCalloc(outputLen * pInput[0].numOfRows, 1);
|
char *outputBuf = taosMemoryCalloc(outputLen * pInput[0].numOfRows, 1);
|
||||||
char *output = outputBuf;
|
char *output = outputBuf;
|
||||||
|
|
||||||
|
@ -790,29 +794,30 @@ int32_t castFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutp
|
||||||
}
|
}
|
||||||
case TSDB_DATA_TYPE_NCHAR: {
|
case TSDB_DATA_TYPE_NCHAR: {
|
||||||
int32_t outputCharLen = (outputLen - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE;
|
int32_t outputCharLen = (outputLen - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE;
|
||||||
|
int32_t len;
|
||||||
if (inputType == TSDB_DATA_TYPE_BOOL) {
|
if (inputType == TSDB_DATA_TYPE_BOOL) {
|
||||||
char tmp[8] = {0};
|
char tmp[8] = {0};
|
||||||
int32_t len = sprintf(tmp, "%.*s", outputCharLen, *(int8_t *)input ? "true" : "false" );
|
len = sprintf(tmp, "%.*s", outputCharLen, *(int8_t *)input ? "true" : "false" );
|
||||||
bool ret = taosMbsToUcs4(tmp, len, (TdUcs4 *)varDataVal(output), outputLen - VARSTR_HEADER_SIZE, &len);
|
bool ret = taosMbsToUcs4(tmp, len, (TdUcs4 *)varDataVal(output), outputLen - VARSTR_HEADER_SIZE, &len);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
return TSDB_CODE_FAILED;
|
return TSDB_CODE_FAILED;
|
||||||
}
|
}
|
||||||
varDataSetLen(output, len);
|
varDataSetLen(output, len);
|
||||||
} else if (inputType == TSDB_DATA_TYPE_BINARY) {
|
} else if (inputType == TSDB_DATA_TYPE_BINARY) {
|
||||||
int32_t len = outputCharLen > varDataLen(input) ? varDataLen(input) : outputCharLen;
|
len = outputCharLen > varDataLen(input) ? varDataLen(input) : outputCharLen;
|
||||||
bool ret = taosMbsToUcs4(input + VARSTR_HEADER_SIZE, len, (TdUcs4 *)varDataVal(output), outputLen - VARSTR_HEADER_SIZE, &len);
|
bool ret = taosMbsToUcs4(input + VARSTR_HEADER_SIZE, len, (TdUcs4 *)varDataVal(output), outputLen - VARSTR_HEADER_SIZE, &len);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
return TSDB_CODE_FAILED;
|
return TSDB_CODE_FAILED;
|
||||||
}
|
}
|
||||||
varDataSetLen(output, len);
|
varDataSetLen(output, len);
|
||||||
} else if (inputType == TSDB_DATA_TYPE_NCHAR) {
|
} else if (inputType == TSDB_DATA_TYPE_NCHAR) {
|
||||||
int32_t len = TMIN(outputLen, varDataLen(input) + VARSTR_HEADER_SIZE);
|
len = TMIN(outputLen - VARSTR_HEADER_SIZE, varDataLen(input));
|
||||||
memcpy(output, input, len);
|
memcpy(output, input, len + VARSTR_HEADER_SIZE);
|
||||||
varDataSetLen(output, len - VARSTR_HEADER_SIZE);
|
varDataSetLen(output, len);
|
||||||
} else {
|
} else {
|
||||||
char tmp[400] = {0};
|
char tmp[400] = {0};
|
||||||
NUM_TO_STRING(inputType, input, sizeof(tmp), tmp);
|
NUM_TO_STRING(inputType, input, sizeof(tmp), tmp);
|
||||||
int32_t len = (int32_t)strlen(tmp);
|
len = (int32_t)strlen(tmp);
|
||||||
len = outputCharLen > len ? len : outputCharLen;
|
len = outputCharLen > len ? len : outputCharLen;
|
||||||
bool ret = taosMbsToUcs4(tmp, len, (TdUcs4 *)varDataVal(output), outputLen - VARSTR_HEADER_SIZE, &len);
|
bool ret = taosMbsToUcs4(tmp, len, (TdUcs4 *)varDataVal(output), outputLen - VARSTR_HEADER_SIZE, &len);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
|
@ -820,6 +825,10 @@ int32_t castFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutp
|
||||||
}
|
}
|
||||||
varDataSetLen(output, len);
|
varDataSetLen(output, len);
|
||||||
}
|
}
|
||||||
|
//for constant conversion, need to set proper length of pOutput description
|
||||||
|
if (len < outputLen - VARSTR_HEADER_SIZE) {
|
||||||
|
pOutput->columnData->info.bytes = len;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
|
|
|
@ -152,8 +152,10 @@ int32_t streamExecTask(SStreamTask* pTask, SMsgCb* pMsgCb, const void* input, in
|
||||||
|
|
||||||
// sink
|
// sink
|
||||||
if (pTask->sinkType == TASK_SINK__TABLE) {
|
if (pTask->sinkType == TASK_SINK__TABLE) {
|
||||||
//
|
/*blockDebugShowData(pRes);*/
|
||||||
blockDebugShowData(pRes);
|
ASSERT(pTask->tbSink.pTSchema);
|
||||||
|
SSubmitReq* pReq = tdBlockToSubmit(pRes, pTask->tbSink.pTSchema);
|
||||||
|
tPrintFixedSchemaSubmitReq(pReq, pTask->tbSink.pTSchema);
|
||||||
} else if (pTask->sinkType == TASK_SINK__SMA) {
|
} else if (pTask->sinkType == TASK_SINK__SMA) {
|
||||||
pTask->smaSink.smaHandle(pTask->ahandle, pTask->smaSink.smaId, pRes);
|
pTask->smaSink.smaHandle(pTask->ahandle, pTask->smaSink.smaId, pRes);
|
||||||
//
|
//
|
||||||
|
@ -274,7 +276,8 @@ int32_t tEncodeSStreamTask(SCoder* pEncoder, const SStreamTask* pTask) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pTask->sinkType == TASK_SINK__TABLE) {
|
if (pTask->sinkType == TASK_SINK__TABLE) {
|
||||||
if (tEncodeI8(pEncoder, pTask->tbSink.reserved) < 0) return -1;
|
/*if (tEncodeI8(pEncoder, pTask->tbSink.reserved) < 0) return -1;*/
|
||||||
|
if (tEncodeSSchemaWrapper(pEncoder, pTask->tbSink.pSchemaWrapper) < 0) return -1;
|
||||||
} else if (pTask->sinkType == TASK_SINK__SMA) {
|
} else if (pTask->sinkType == TASK_SINK__SMA) {
|
||||||
if (tEncodeI64(pEncoder, pTask->smaSink.smaId) < 0) return -1;
|
if (tEncodeI64(pEncoder, pTask->smaSink.smaId) < 0) return -1;
|
||||||
} else if (pTask->sinkType == TASK_SINK__FETCH) {
|
} else if (pTask->sinkType == TASK_SINK__FETCH) {
|
||||||
|
@ -318,7 +321,10 @@ int32_t tDecodeSStreamTask(SCoder* pDecoder, SStreamTask* pTask) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pTask->sinkType == TASK_SINK__TABLE) {
|
if (pTask->sinkType == TASK_SINK__TABLE) {
|
||||||
if (tDecodeI8(pDecoder, &pTask->tbSink.reserved) < 0) return -1;
|
/*if (tDecodeI8(pDecoder, &pTask->tbSink.reserved) < 0) return -1;*/
|
||||||
|
pTask->tbSink.pSchemaWrapper = taosMemoryCalloc(1, sizeof(SSchemaWrapper));
|
||||||
|
if (pTask->tbSink.pSchemaWrapper == NULL) return -1;
|
||||||
|
if (tDecodeSSchemaWrapper(pDecoder, pTask->tbSink.pSchemaWrapper) < 0) return -1;
|
||||||
} else if (pTask->sinkType == TASK_SINK__SMA) {
|
} else if (pTask->sinkType == TASK_SINK__SMA) {
|
||||||
if (tDecodeI64(pDecoder, &pTask->smaSink.smaId) < 0) return -1;
|
if (tDecodeI64(pDecoder, &pTask->smaSink.smaId) < 0) return -1;
|
||||||
} else if (pTask->sinkType == TASK_SINK__FETCH) {
|
} else if (pTask->sinkType == TASK_SINK__FETCH) {
|
||||||
|
|
|
@ -435,7 +435,7 @@ int transDQSched(SDelayQueue* queue, void (*func)(void* arg), void* arg, uint64_
|
||||||
if (minNode) {
|
if (minNode) {
|
||||||
SDelayTask* minTask = container_of(minNode, SDelayTask, node);
|
SDelayTask* minTask = container_of(minNode, SDelayTask, node);
|
||||||
if (minTask->execTime < task->execTime) {
|
if (minTask->execTime < task->execTime) {
|
||||||
timeoutMs = minTask->execTime <= now ? 0 : now - minTask->execTime;
|
timeoutMs = minTask->execTime <= now ? 0 : minTask->execTime - now;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -195,6 +195,36 @@ int32_t taosUcs4len(TdUcs4 *ucs4) {
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//dst buffer size should be at least 2*len + 1
|
||||||
|
int32_t taosHexEncode(const char *src, char *dst, int32_t len) {
|
||||||
|
if (!dst) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < len; ++i) {
|
||||||
|
sprintf(dst + i * 2, "%02x", src[i] & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t taosHexDecode(const char *src, char *dst, int32_t len) {
|
||||||
|
if (!dst) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t hn, ln, out;
|
||||||
|
for (int i = 0, j = 0; i < len * 2; i += 2, ++j ) {
|
||||||
|
hn = src[i] > '9' ? src[i] - 'A' + 10 : src[i] - '0';
|
||||||
|
ln = src[i + 1] > '9' ? src[i + 1] - 'A' + 10 : src[i + 1] - '0';
|
||||||
|
|
||||||
|
out = (hn << 4) | ln;
|
||||||
|
memcpy(dst + j, &out, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t taosWcharWidth(TdWchar wchar) { return wcwidth(wchar); }
|
int32_t taosWcharWidth(TdWchar wchar) { return wcwidth(wchar); }
|
||||||
|
|
||||||
int32_t taosWcharsWidth(TdWchar *pWchar, int32_t size) { return wcswidth(pWchar, size); }
|
int32_t taosWcharsWidth(TdWchar *pWchar, int32_t size) { return wcswidth(pWchar, size); }
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
./test.sh -f tsim/query/explain.sim
|
./test.sh -f tsim/query/explain.sim
|
||||||
./test.sh -f tsim/query/session.sim
|
./test.sh -f tsim/query/session.sim
|
||||||
./test.sh -f tsim/query/scalarNull.sim
|
./test.sh -f tsim/query/scalarNull.sim
|
||||||
|
./test.sh -f tsim/query/udf.sim
|
||||||
|
|
||||||
# ---- qnode
|
# ---- qnode
|
||||||
./test.sh -f tsim/qnode/basic1.sim
|
./test.sh -f tsim/qnode/basic1.sim
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set +e
|
||||||
|
#set -x
|
||||||
|
|
||||||
|
echo "Executing copy_udf.sh"
|
||||||
|
|
||||||
|
SCRIPT_DIR=`dirname $0`
|
||||||
|
cd $SCRIPT_DIR/../
|
||||||
|
|
||||||
|
IN_TDINTERNAL="community"
|
||||||
|
if [[ "$SCRIPT_DIR" == *"$IN_TDINTERNAL"* ]]; then
|
||||||
|
cd ../../..
|
||||||
|
else
|
||||||
|
cd ../../
|
||||||
|
fi
|
||||||
|
|
||||||
|
TAOS_DIR=`pwd`
|
||||||
|
UDF1_DIR=`find $TAOS_DIR -name "libudf1.so"|grep lib|head -n1`
|
||||||
|
UDF2_DIR=`find $TAOS_DIR -name "libudf2.so"|grep lib|head -n1`
|
||||||
|
|
||||||
|
echo $UDF1_DIR
|
||||||
|
echo $UDF2_DIR
|
||||||
|
|
||||||
|
UDF_TMP=/tmp/udf
|
||||||
|
mkdir $UDF_TMP
|
||||||
|
rm $UDF_TMP/libudf1.so
|
||||||
|
rm $UDF_TMP/libudf2.so
|
||||||
|
|
||||||
|
echo "Copy udf shared library files to $UDF_TMP"
|
||||||
|
|
||||||
|
cp $UDF1_DIR $UDF_TMP
|
||||||
|
cp $UDF2_DIR $UDF_TMP
|
|
@ -66,7 +66,7 @@ print ============= create database
|
||||||
# | REPLICA value [1 | 3]
|
# | REPLICA value [1 | 3]
|
||||||
# | WAL value [1 | 2]
|
# | WAL value [1 | 2]
|
||||||
|
|
||||||
sql create database db CACHELAST 3 COMP 0 DAYS 345600 FSYNC 1000 MAXROWS 8000 MINROWS 10 KEEP 1440000 PRECISION 'ns' REPLICA 1 WAL 2 VGROUPS 6 SINGLE_STABLE 1
|
sql create database db CACHELAST 3 COMP 0 DAYS 345600 FSYNC 1000 MAXROWS 8000 MINROWS 10 KEEP 1440000 PRECISION 'ns' REPLICA 3 WAL 2 VGROUPS 6 SINGLE_STABLE 1
|
||||||
sql show databases
|
sql show databases
|
||||||
print rows: $rows
|
print rows: $rows
|
||||||
print $data00 $data01 $data02 $data03 $data04 $data05 $data06 $data07 $data08 $data09
|
print $data00 $data01 $data02 $data03 $data04 $data05 $data06 $data07 $data08 $data09
|
||||||
|
@ -86,7 +86,7 @@ endi
|
||||||
if $data3_db != 0 then # ntables
|
if $data3_db != 0 then # ntables
|
||||||
return -1
|
return -1
|
||||||
endi
|
endi
|
||||||
if $data4_db != 1 then # replica
|
if $data4_db != 3 then # replica
|
||||||
return -1
|
return -1
|
||||||
endi
|
endi
|
||||||
if $data5_db != nostrict then # strict
|
if $data5_db != nostrict then # strict
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
system sh/stop_dnodes.sh
|
||||||
|
|
||||||
|
system sh/deploy.sh -n dnode1 -i 1
|
||||||
|
system sh/cfg.sh -n dnode1 -c wallevel -v 2
|
||||||
|
system sh/cfg.sh -n dnode1 -c numOfMnodes -v 1
|
||||||
|
|
||||||
|
print ========= start dnode1 as LEADER
|
||||||
|
system sh/exec.sh -n dnode1 -s start
|
||||||
|
sleep 2000
|
||||||
|
sql connect
|
||||||
|
|
||||||
|
print ======== step1 udf
|
||||||
|
system sh/copy_udf.sh
|
||||||
|
sql create database udf vgroups 3;
|
||||||
|
sql use udf;
|
||||||
|
sql show databases;
|
||||||
|
|
||||||
|
sql create table t (ts timestamp, f int);
|
||||||
|
sql insert into t values(now, 1)(now+1s, 2);
|
||||||
|
|
||||||
|
sql create function udf1 as '/tmp/udf/libudf1.so' outputtype int bufSize 8;
|
||||||
|
sql create aggregate function udf2 as '/tmp/udf/libudf2.so' outputtype double bufSize 8;
|
||||||
|
sql show functions;
|
||||||
|
if $rows != 2 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
sql select udf1(f) from t;
|
||||||
|
if $rows != 2 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
if $data00 != 88 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
if $data10 != 88 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
sql select udf2(f) from t;
|
||||||
|
if $rows != 1 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
if $data00 != 2.236067977 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
#sql drop function udf1;
|
||||||
|
#sql drop function udf2;
|
||||||
|
system sh/exec.sh -n dnode1 -s stop -x SIGKILL
|
Loading…
Reference in New Issue