Merge branch '3.0' into feature/queryredirect
This commit is contained in:
commit
07b46f9e3c
|
@ -13,6 +13,7 @@ ELSEIF (TD_WINDOWS)
|
||||||
INSTALL(FILES ${TD_SOURCE_DIR}/packaging/cfg/taos.cfg DESTINATION cfg)
|
INSTALL(FILES ${TD_SOURCE_DIR}/packaging/cfg/taos.cfg DESTINATION cfg)
|
||||||
INSTALL(FILES ${TD_SOURCE_DIR}/include/client/taos.h DESTINATION include)
|
INSTALL(FILES ${TD_SOURCE_DIR}/include/client/taos.h DESTINATION include)
|
||||||
INSTALL(FILES ${TD_SOURCE_DIR}/include/util/taoserror.h DESTINATION include)
|
INSTALL(FILES ${TD_SOURCE_DIR}/include/util/taoserror.h DESTINATION include)
|
||||||
|
INSTALL(FILES ${TD_SOURCE_DIR}/include/libs/function/taosudf.h DESTINATION include)
|
||||||
INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos.lib DESTINATION driver)
|
INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos.lib DESTINATION driver)
|
||||||
INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos_static.lib DESTINATION driver)
|
INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos_static.lib DESTINATION driver)
|
||||||
INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos.dll DESTINATION driver)
|
INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos.dll DESTINATION driver)
|
||||||
|
|
|
@ -26,7 +26,7 @@ public class LineProtocolExample {
|
||||||
|
|
||||||
private static void createDatabase(Connection conn) throws SQLException {
|
private static void createDatabase(Connection conn) throws SQLException {
|
||||||
try (Statement stmt = conn.createStatement()) {
|
try (Statement stmt = conn.createStatement()) {
|
||||||
// the default precision is ms (microsecond), but we use us(microsecond) here.
|
// the default precision is ms (millisecond), but we use us(microsecond) here.
|
||||||
stmt.execute("CREATE DATABASE IF NOT EXISTS test PRECISION 'us'");
|
stmt.execute("CREATE DATABASE IF NOT EXISTS test PRECISION 'us'");
|
||||||
stmt.execute("USE test");
|
stmt.execute("USE test");
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,266 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can use, redistribute, and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3
|
||||||
|
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TDENGINE_TAOSUDF_H
|
||||||
|
#define TDENGINE_TAOSUDF_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <taos.h>
|
||||||
|
#include <taoserror.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
#define FORCE_INLINE inline __attribute__((always_inline))
|
||||||
|
#else
|
||||||
|
#define FORCE_INLINE
|
||||||
|
#endif
|
||||||
|
typedef struct SUdfColumnMeta {
|
||||||
|
int16_t type;
|
||||||
|
int32_t bytes;
|
||||||
|
uint8_t precision;
|
||||||
|
uint8_t scale;
|
||||||
|
} SUdfColumnMeta;
|
||||||
|
|
||||||
|
typedef struct SUdfColumnData {
|
||||||
|
int32_t numOfRows;
|
||||||
|
int32_t rowsAlloc;
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
int32_t nullBitmapLen;
|
||||||
|
char *nullBitmap;
|
||||||
|
int32_t dataLen;
|
||||||
|
char *data;
|
||||||
|
} fixLenCol;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
int32_t varOffsetsLen;
|
||||||
|
int32_t *varOffsets;
|
||||||
|
int32_t payloadLen;
|
||||||
|
char *payload;
|
||||||
|
int32_t payloadAllocLen;
|
||||||
|
} varLenCol;
|
||||||
|
};
|
||||||
|
} SUdfColumnData;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct SUdfColumn {
|
||||||
|
SUdfColumnMeta colMeta;
|
||||||
|
bool hasNull;
|
||||||
|
SUdfColumnData colData;
|
||||||
|
} SUdfColumn;
|
||||||
|
|
||||||
|
typedef struct SUdfDataBlock {
|
||||||
|
int32_t numOfRows;
|
||||||
|
int32_t numOfCols;
|
||||||
|
SUdfColumn **udfCols;
|
||||||
|
} SUdfDataBlock;
|
||||||
|
|
||||||
|
typedef struct SUdfInterBuf {
|
||||||
|
int32_t bufLen;
|
||||||
|
char* buf;
|
||||||
|
int8_t numOfResult; //zero or one
|
||||||
|
} SUdfInterBuf;
|
||||||
|
typedef void *UdfcFuncHandle;
|
||||||
|
|
||||||
|
// dynamic lib init and destroy
|
||||||
|
typedef int32_t (*TUdfInitFunc)();
|
||||||
|
typedef int32_t (*TUdfDestroyFunc)();
|
||||||
|
|
||||||
|
#define UDF_MEMORY_EXP_GROWTH 1.5
|
||||||
|
#define NBIT (3u)
|
||||||
|
#define BitPos(_n) ((_n) & ((1 << NBIT) - 1))
|
||||||
|
#define BMCharPos(bm_, r_) ((bm_)[(r_) >> NBIT])
|
||||||
|
#define BitmapLen(_n) (((_n) + ((1 << NBIT) - 1)) >> NBIT)
|
||||||
|
|
||||||
|
#define udfColDataIsNull_var(pColumn, row) ((pColumn->colData.varLenCol.varOffsets)[row] == -1)
|
||||||
|
#define udfColDataIsNull_f(pColumn, row) ((BMCharPos(pColumn->colData.fixLenCol.nullBitmap, row) & (1u << (7u - BitPos(row)))) == (1u << (7u - BitPos(row))))
|
||||||
|
#define udfColDataSetNull_f(pColumn, row) \
|
||||||
|
do { \
|
||||||
|
BMCharPos(pColumn->colData.fixLenCol.nullBitmap, row) |= (1u << (7u - BitPos(row))); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define udfColDataSetNotNull_f(pColumn, r_) \
|
||||||
|
do { \
|
||||||
|
BMCharPos(pColumn->colData.fixLenCol.nullBitmap, r_) &= ~(1u << (7u - BitPos(r_))); \
|
||||||
|
} while (0)
|
||||||
|
#define udfColDataSetNull_var(pColumn, row) ((pColumn->colData.varLenCol.varOffsets)[row] = -1)
|
||||||
|
|
||||||
|
typedef uint16_t VarDataLenT; // maxVarDataLen: 32767
|
||||||
|
#define VARSTR_HEADER_SIZE sizeof(VarDataLenT)
|
||||||
|
#define varDataLen(v) ((VarDataLenT *)(v))[0]
|
||||||
|
#define varDataVal(v) ((char *)(v) + VARSTR_HEADER_SIZE)
|
||||||
|
#define varDataTLen(v) (sizeof(VarDataLenT) + varDataLen(v))
|
||||||
|
#define varDataCopy(dst, v) memcpy((dst), (void *)(v), varDataTLen(v))
|
||||||
|
#define varDataLenByData(v) (*(VarDataLenT *)(((char *)(v)) - VARSTR_HEADER_SIZE))
|
||||||
|
#define varDataSetLen(v, _len) (((VarDataLenT *)(v))[0] = (VarDataLenT)(_len))
|
||||||
|
#define IS_VAR_DATA_TYPE(t) \
|
||||||
|
(((t) == TSDB_DATA_TYPE_VARCHAR) || ((t) == TSDB_DATA_TYPE_NCHAR) || ((t) == TSDB_DATA_TYPE_JSON))
|
||||||
|
#define IS_STR_DATA_TYPE(t) (((t) == TSDB_DATA_TYPE_VARCHAR) || ((t) == TSDB_DATA_TYPE_NCHAR))
|
||||||
|
|
||||||
|
|
||||||
|
static FORCE_INLINE char* udfColDataGetData(const SUdfColumn* pColumn, int32_t row) {
|
||||||
|
if (IS_VAR_DATA_TYPE(pColumn->colMeta.type)) {
|
||||||
|
return pColumn->colData.varLenCol.payload + pColumn->colData.varLenCol.varOffsets[row];
|
||||||
|
} else {
|
||||||
|
return pColumn->colData.fixLenCol.data + pColumn->colMeta.bytes * row;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static FORCE_INLINE bool udfColDataIsNull(const SUdfColumn* pColumn, int32_t row) {
|
||||||
|
if (IS_VAR_DATA_TYPE(pColumn->colMeta.type)) {
|
||||||
|
if (pColumn->colMeta.type == TSDB_DATA_TYPE_JSON) {
|
||||||
|
if (udfColDataIsNull_var(pColumn, row)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
char* data = udfColDataGetData(pColumn, row);
|
||||||
|
return (*data == TSDB_DATA_TYPE_NULL);
|
||||||
|
} else {
|
||||||
|
return udfColDataIsNull_var(pColumn, row);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return udfColDataIsNull_f(pColumn, row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = (data->rowsAlloc< 8) ? 8 : data->rowsAlloc;
|
||||||
|
while (allocCapacity < newCapacity) {
|
||||||
|
allocCapacity *= UDF_MEMORY_EXP_GROWTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IS_VAR_DATA_TYPE(meta->type)) {
|
||||||
|
char* tmp = (char*)realloc(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 = (char*)realloc(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 = (char*)realloc(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 void udfColDataSetNull(SUdfColumn* pColumn, int32_t row) {
|
||||||
|
udfColEnsureCapacity(pColumn, row+1);
|
||||||
|
if (IS_VAR_DATA_TYPE(pColumn->colMeta.type)) {
|
||||||
|
udfColDataSetNull_var(pColumn, row);
|
||||||
|
} else {
|
||||||
|
udfColDataSetNull_f(pColumn, row);
|
||||||
|
}
|
||||||
|
pColumn->hasNull = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static FORCE_INLINE int32_t udfColDataSet(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) {
|
||||||
|
udfColDataSetNull(pColumn, currentRow);
|
||||||
|
} else {
|
||||||
|
if (!isVarCol) {
|
||||||
|
udfColDataSetNotNull_f(pColumn, 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 + sizeof(char));
|
||||||
|
} else if (*pData == TSDB_DATA_TYPE_BIGINT || *pData == TSDB_DATA_TYPE_DOUBLE) {
|
||||||
|
dataLen = sizeof(int64_t);
|
||||||
|
} else if (*pData == TSDB_DATA_TYPE_BOOL) {
|
||||||
|
dataLen = sizeof(char);
|
||||||
|
}
|
||||||
|
dataLen += sizeof(char);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = (char*)realloc(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 = (currentRow + 1 > data->numOfRows) ? (currentRow+1) : data->numOfRows;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef int32_t (*TUdfScalarProcFunc)(SUdfDataBlock* block, SUdfColumn *resultCol);
|
||||||
|
|
||||||
|
typedef int32_t (*TUdfAggStartFunc)(SUdfInterBuf *buf);
|
||||||
|
typedef int32_t (*TUdfAggProcessFunc)(SUdfDataBlock* block, SUdfInterBuf *interBuf, SUdfInterBuf *newInterBuf);
|
||||||
|
typedef int32_t (*TUdfAggFinishFunc)(SUdfInterBuf* buf, SUdfInterBuf *resultData);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // TDENGINE_TAOSUDF_H
|
|
@ -16,6 +16,13 @@
|
||||||
#ifndef TDENGINE_TUDF_H
|
#ifndef TDENGINE_TUDF_H
|
||||||
#define TDENGINE_TUDF_H
|
#define TDENGINE_TUDF_H
|
||||||
|
|
||||||
|
#undef malloc
|
||||||
|
#define malloc malloc
|
||||||
|
#undef free
|
||||||
|
#define free free
|
||||||
|
#undef realloc
|
||||||
|
#define alloc alloc
|
||||||
|
#include <taosudf.h>
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
@ -36,56 +43,6 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
#define UDF_DNODE_ID_ENV_NAME "DNODE_ID"
|
#define UDF_DNODE_ID_ENV_NAME "DNODE_ID"
|
||||||
|
|
||||||
//======================================================================================
|
|
||||||
//begin API to taosd and qworker
|
|
||||||
|
|
||||||
typedef struct SUdfColumnMeta {
|
|
||||||
int16_t type;
|
|
||||||
int32_t bytes;
|
|
||||||
uint8_t precision;
|
|
||||||
uint8_t scale;
|
|
||||||
} SUdfColumnMeta;
|
|
||||||
|
|
||||||
typedef struct SUdfColumnData {
|
|
||||||
int32_t numOfRows;
|
|
||||||
int32_t rowsAlloc;
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
int32_t nullBitmapLen;
|
|
||||||
char *nullBitmap;
|
|
||||||
int32_t dataLen;
|
|
||||||
char *data;
|
|
||||||
} fixLenCol;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
int32_t varOffsetsLen;
|
|
||||||
int32_t *varOffsets;
|
|
||||||
int32_t payloadLen;
|
|
||||||
char *payload;
|
|
||||||
int32_t payloadAllocLen;
|
|
||||||
} varLenCol;
|
|
||||||
};
|
|
||||||
} SUdfColumnData;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct SUdfColumn {
|
|
||||||
SUdfColumnMeta colMeta;
|
|
||||||
bool hasNull;
|
|
||||||
SUdfColumnData colData;
|
|
||||||
} SUdfColumn;
|
|
||||||
|
|
||||||
typedef struct SUdfDataBlock {
|
|
||||||
int32_t numOfRows;
|
|
||||||
int32_t numOfCols;
|
|
||||||
SUdfColumn **udfCols;
|
|
||||||
} SUdfDataBlock;
|
|
||||||
|
|
||||||
typedef struct SUdfInterBuf {
|
|
||||||
int32_t bufLen;
|
|
||||||
char* buf;
|
|
||||||
int8_t numOfResult; //zero or one
|
|
||||||
} SUdfInterBuf;
|
|
||||||
typedef void *UdfcFuncHandle;
|
|
||||||
|
|
||||||
//low level APIs
|
//low level APIs
|
||||||
/**
|
/**
|
||||||
|
@ -127,177 +84,6 @@ int32_t udfAggFinalize(struct SqlFunctionCtx *pCtx, SSDataBlock* pBlock);
|
||||||
int32_t callUdfScalarFunc(char *udfName, SScalarParam *input, int32_t numOfCols, SScalarParam *output);
|
int32_t callUdfScalarFunc(char *udfName, SScalarParam *input, int32_t numOfCols, SScalarParam *output);
|
||||||
|
|
||||||
int32_t cleanUpUdfs();
|
int32_t cleanUpUdfs();
|
||||||
// end API to taosd and qworker
|
|
||||||
//=============================================================================================================================
|
|
||||||
// begin API to UDF writer.
|
|
||||||
|
|
||||||
// dynamic lib init and destroy
|
|
||||||
typedef int32_t (*TUdfInitFunc)();
|
|
||||||
typedef int32_t (*TUdfDestroyFunc)();
|
|
||||||
|
|
||||||
//TODO: add API to check function arguments type, number etc.
|
|
||||||
|
|
||||||
#define UDF_MEMORY_EXP_GROWTH 1.5
|
|
||||||
|
|
||||||
#define udfColDataIsNull_var(pColumn, row) ((pColumn->colData.varLenCol.varOffsets)[row] == -1)
|
|
||||||
#define udfColDataIsNull_f(pColumn, row) ((BMCharPos(pColumn->colData.fixLenCol.nullBitmap, row) & (1u << (7u - BitPos(row)))) == (1u << (7u - BitPos(row))))
|
|
||||||
#define udfColDataSetNull_f(pColumn, row) \
|
|
||||||
do { \
|
|
||||||
BMCharPos(pColumn->colData.fixLenCol.nullBitmap, row) |= (1u << (7u - BitPos(row))); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define udfColDataSetNotNull_f(pColumn, r_) \
|
|
||||||
do { \
|
|
||||||
BMCharPos(pColumn->colData.fixLenCol.nullBitmap, r_) &= ~(1u << (7u - BitPos(r_))); \
|
|
||||||
} while (0)
|
|
||||||
#define udfColDataSetNull_var(pColumn, row) ((pColumn->colData.varLenCol.varOffsets)[row] = -1)
|
|
||||||
|
|
||||||
|
|
||||||
static FORCE_INLINE char* udfColDataGetData(const SUdfColumn* pColumn, int32_t row) {
|
|
||||||
if (IS_VAR_DATA_TYPE(pColumn->colMeta.type)) {
|
|
||||||
return pColumn->colData.varLenCol.payload + pColumn->colData.varLenCol.varOffsets[row];
|
|
||||||
} else {
|
|
||||||
return pColumn->colData.fixLenCol.data + pColumn->colMeta.bytes * row;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static FORCE_INLINE bool udfColDataIsNull(const SUdfColumn* pColumn, int32_t row) {
|
|
||||||
if (IS_VAR_DATA_TYPE(pColumn->colMeta.type)) {
|
|
||||||
if (pColumn->colMeta.type == TSDB_DATA_TYPE_JSON) {
|
|
||||||
if (udfColDataIsNull_var(pColumn, row)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
char* data = udfColDataGetData(pColumn, row);
|
|
||||||
return (*data == TSDB_DATA_TYPE_NULL);
|
|
||||||
} else {
|
|
||||||
return udfColDataIsNull_var(pColumn, row);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return udfColDataIsNull_f(pColumn, row);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 = TMAX(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 void udfColDataSetNull(SUdfColumn* pColumn, int32_t row) {
|
|
||||||
udfColEnsureCapacity(pColumn, row+1);
|
|
||||||
if (IS_VAR_DATA_TYPE(pColumn->colMeta.type)) {
|
|
||||||
udfColDataSetNull_var(pColumn, row);
|
|
||||||
} else {
|
|
||||||
udfColDataSetNull_f(pColumn, row);
|
|
||||||
}
|
|
||||||
pColumn->hasNull = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static FORCE_INLINE int32_t udfColDataSet(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) {
|
|
||||||
udfColDataSetNull(pColumn, 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 = TMAX(currentRow + 1, data->numOfRows);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef int32_t (*TUdfScalarProcFunc)(SUdfDataBlock* block, SUdfColumn *resultCol);
|
|
||||||
|
|
||||||
typedef int32_t (*TUdfAggStartFunc)(SUdfInterBuf *buf);
|
|
||||||
typedef int32_t (*TUdfAggProcessFunc)(SUdfDataBlock* block, SUdfInterBuf *interBuf, SUdfInterBuf *newInterBuf);
|
|
||||||
typedef int32_t (*TUdfAggFinishFunc)(SUdfInterBuf* buf, SUdfInterBuf *resultData);
|
|
||||||
|
|
||||||
|
|
||||||
// end API to UDF writer
|
|
||||||
//=======================================================================================================================
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,6 +103,7 @@ typedef struct SIndefRowsFuncLogicNode {
|
||||||
SLogicNode node;
|
SLogicNode node;
|
||||||
SNodeList* pFuncs;
|
SNodeList* pFuncs;
|
||||||
bool isTailFunc;
|
bool isTailFunc;
|
||||||
|
bool isUniqueFunc;
|
||||||
} SIndefRowsFuncLogicNode;
|
} SIndefRowsFuncLogicNode;
|
||||||
|
|
||||||
typedef struct SInterpFuncLogicNode {
|
typedef struct SInterpFuncLogicNode {
|
||||||
|
|
|
@ -50,6 +50,7 @@ typedef struct SExprNode {
|
||||||
char aliasName[TSDB_COL_NAME_LEN];
|
char aliasName[TSDB_COL_NAME_LEN];
|
||||||
char userAlias[TSDB_COL_NAME_LEN];
|
char userAlias[TSDB_COL_NAME_LEN];
|
||||||
SArray* pAssociation;
|
SArray* pAssociation;
|
||||||
|
bool orderAlias;
|
||||||
} SExprNode;
|
} SExprNode;
|
||||||
|
|
||||||
typedef enum EColumnType { COLUMN_TYPE_COLUMN = 1, COLUMN_TYPE_TAG, COLUMN_TYPE_TBNAME } EColumnType;
|
typedef enum EColumnType { COLUMN_TYPE_COLUMN = 1, COLUMN_TYPE_TAG, COLUMN_TYPE_TBNAME } EColumnType;
|
||||||
|
|
|
@ -48,6 +48,8 @@ int32_t qCreateQueryPlan(SPlanContext* pCxt, SQueryPlan** pPlan, SArray* pExecNo
|
||||||
// @pSource one execution location of this group of datasource subplans
|
// @pSource one execution location of this group of datasource subplans
|
||||||
int32_t qSetSubplanExecutionNode(SSubplan* pSubplan, int32_t groupId, SDownstreamSourceNode* pSource);
|
int32_t qSetSubplanExecutionNode(SSubplan* pSubplan, int32_t groupId, SDownstreamSourceNode* pSource);
|
||||||
|
|
||||||
|
int32_t qClearSubplanExecutionNode(SSubplan* pSubplan, int32_t groupId);
|
||||||
|
|
||||||
// Convert to subplan to string for the scheduler to send to the executor
|
// Convert to subplan to string for the scheduler to send to the executor
|
||||||
int32_t qSubPlanToString(const SSubplan* pSubplan, char** pStr, int32_t* pLen);
|
int32_t qSubPlanToString(const SSubplan* pSubplan, char** pStr, int32_t* pLen);
|
||||||
int32_t qStringToSubplan(const char* pStr, SSubplan** pSubplan);
|
int32_t qStringToSubplan(const char* pStr, SSubplan** pSubplan);
|
||||||
|
|
|
@ -283,19 +283,19 @@ extern int32_t (*queryProcessMsgRsp[TDMT_MAX])(void* output, char* msg, int32_t
|
||||||
#define qDebug(...) \
|
#define qDebug(...) \
|
||||||
do { \
|
do { \
|
||||||
if (qDebugFlag & DEBUG_DEBUG) { \
|
if (qDebugFlag & DEBUG_DEBUG) { \
|
||||||
taosPrintLog("QRY ", DEBUG_DEBUG, qDebugFlag, __VA_ARGS__); \
|
taosPrintLog("QRY ", DEBUG_DEBUG, tsLogEmbedded ? 255 : qDebugFlag, __VA_ARGS__); \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
#define qTrace(...) \
|
#define qTrace(...) \
|
||||||
do { \
|
do { \
|
||||||
if (qDebugFlag & DEBUG_TRACE) { \
|
if (qDebugFlag & DEBUG_TRACE) { \
|
||||||
taosPrintLog("QRY ", DEBUG_TRACE, qDebugFlag, __VA_ARGS__); \
|
taosPrintLog("QRY ", DEBUG_TRACE, tsLogEmbedded ? 255 : qDebugFlag, __VA_ARGS__); \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
#define qDebugL(...) \
|
#define qDebugL(...) \
|
||||||
do { \
|
do { \
|
||||||
if (qDebugFlag & DEBUG_DEBUG) { \
|
if (qDebugFlag & DEBUG_DEBUG) { \
|
||||||
taosPrintLongString("QRY ", DEBUG_DEBUG, qDebugFlag, __VA_ARGS__); \
|
taosPrintLongString("QRY ", DEBUG_DEBUG, tsLogEmbedded ? 255 : qDebugFlag, __VA_ARGS__); \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
|
|
@ -615,6 +615,7 @@ int32_t* taosGetErrno();
|
||||||
//rsma
|
//rsma
|
||||||
#define TSDB_CODE_RSMA_INVALID_ENV TAOS_DEF_ERROR_CODE(0, 0x3150)
|
#define TSDB_CODE_RSMA_INVALID_ENV TAOS_DEF_ERROR_CODE(0, 0x3150)
|
||||||
#define TSDB_CODE_RSMA_INVALID_STAT TAOS_DEF_ERROR_CODE(0, 0x3151)
|
#define TSDB_CODE_RSMA_INVALID_STAT TAOS_DEF_ERROR_CODE(0, 0x3151)
|
||||||
|
#define TSDB_CODE_RSMA_QTASKINFO_CREATE TAOS_DEF_ERROR_CODE(0, 0x3152)
|
||||||
|
|
||||||
//index
|
//index
|
||||||
#define TSDB_CODE_INDEX_REBUILDING TAOS_DEF_ERROR_CODE(0, 0x3200)
|
#define TSDB_CODE_INDEX_REBUILDING TAOS_DEF_ERROR_CODE(0, 0x3200)
|
||||||
|
|
|
@ -170,7 +170,7 @@ function check_lib_path() {
|
||||||
|
|
||||||
function check_header_path() {
|
function check_header_path() {
|
||||||
# check all header
|
# check all header
|
||||||
header_dir=("taos.h" "taosdef.h" "taoserror.h")
|
header_dir=("taos.h" "taosdef.h" "taoserror.h" "taosudf.h")
|
||||||
for i in "${header_dir[@]}";do
|
for i in "${header_dir[@]}";do
|
||||||
check_link ${inc_link_dir}/$i
|
check_link ${inc_link_dir}/$i
|
||||||
done
|
done
|
||||||
|
|
|
@ -29,6 +29,7 @@ else
|
||||||
${csudo}rm -f ${bin_link_dir}/taosdemo || :
|
${csudo}rm -f ${bin_link_dir}/taosdemo || :
|
||||||
${csudo}rm -f ${cfg_link_dir}/* || :
|
${csudo}rm -f ${cfg_link_dir}/* || :
|
||||||
${csudo}rm -f ${inc_link_dir}/taos.h || :
|
${csudo}rm -f ${inc_link_dir}/taos.h || :
|
||||||
|
${csudo}rm -f ${inc_link_dir}/taosudf.h || :
|
||||||
${csudo}rm -f ${lib_link_dir}/libtaos.* || :
|
${csudo}rm -f ${lib_link_dir}/libtaos.* || :
|
||||||
|
|
||||||
${csudo}rm -f ${log_link_dir} || :
|
${csudo}rm -f ${log_link_dir} || :
|
||||||
|
|
|
@ -70,6 +70,7 @@ cp ${compile_dir}/build/lib/${libfile} ${pkg_dir}${install_home_pat
|
||||||
cp ${compile_dir}/../include/client/taos.h ${pkg_dir}${install_home_path}/include
|
cp ${compile_dir}/../include/client/taos.h ${pkg_dir}${install_home_path}/include
|
||||||
cp ${compile_dir}/../include/common/taosdef.h ${pkg_dir}${install_home_path}/include
|
cp ${compile_dir}/../include/common/taosdef.h ${pkg_dir}${install_home_path}/include
|
||||||
cp ${compile_dir}/../include/util/taoserror.h ${pkg_dir}${install_home_path}/include
|
cp ${compile_dir}/../include/util/taoserror.h ${pkg_dir}${install_home_path}/include
|
||||||
|
cp ${compile_dir}/../include/libs/function/taosudf.h ${pkg_dir}${install_home_path}/include
|
||||||
cp -r ${top_dir}/examples/* ${pkg_dir}${install_home_path}/examples
|
cp -r ${top_dir}/examples/* ${pkg_dir}${install_home_path}/examples
|
||||||
#cp -r ${top_dir}/src/connector/python ${pkg_dir}${install_home_path}/connector
|
#cp -r ${top_dir}/src/connector/python ${pkg_dir}${install_home_path}/connector
|
||||||
#cp -r ${top_dir}/src/connector/go ${pkg_dir}${install_home_path}/connector
|
#cp -r ${top_dir}/src/connector/go ${pkg_dir}${install_home_path}/connector
|
||||||
|
|
|
@ -77,6 +77,7 @@ cp %{_compiledir}/build/lib/${libfile} %{buildroot}%{homepath}/driv
|
||||||
cp %{_compiledir}/../include/client/taos.h %{buildroot}%{homepath}/include
|
cp %{_compiledir}/../include/client/taos.h %{buildroot}%{homepath}/include
|
||||||
cp %{_compiledir}/../include/common/taosdef.h %{buildroot}%{homepath}/include
|
cp %{_compiledir}/../include/common/taosdef.h %{buildroot}%{homepath}/include
|
||||||
cp %{_compiledir}/../include/util/taoserror.h %{buildroot}%{homepath}/include
|
cp %{_compiledir}/../include/util/taoserror.h %{buildroot}%{homepath}/include
|
||||||
|
cp %{_compiledir}/../include/libs/function/taosudf.h %{buildroot}%{homepath}/include
|
||||||
#cp -r %{_compiledir}/../src/connector/python %{buildroot}%{homepath}/connector
|
#cp -r %{_compiledir}/../src/connector/python %{buildroot}%{homepath}/connector
|
||||||
#cp -r %{_compiledir}/../src/connector/go %{buildroot}%{homepath}/connector
|
#cp -r %{_compiledir}/../src/connector/go %{buildroot}%{homepath}/connector
|
||||||
#cp -r %{_compiledir}/../src/connector/nodejs %{buildroot}%{homepath}/connector
|
#cp -r %{_compiledir}/../src/connector/nodejs %{buildroot}%{homepath}/connector
|
||||||
|
@ -201,6 +202,7 @@ if [ $1 -eq 0 ];then
|
||||||
${csudo}rm -f ${inc_link_dir}/taos.h || :
|
${csudo}rm -f ${inc_link_dir}/taos.h || :
|
||||||
${csudo}rm -f ${inc_link_dir}/taosdef.h || :
|
${csudo}rm -f ${inc_link_dir}/taosdef.h || :
|
||||||
${csudo}rm -f ${inc_link_dir}/taoserror.h || :
|
${csudo}rm -f ${inc_link_dir}/taoserror.h || :
|
||||||
|
${csudo}rm -f ${inc_link_dir}/taosudf.h || :
|
||||||
${csudo}rm -f ${lib_link_dir}/libtaos.* || :
|
${csudo}rm -f ${lib_link_dir}/libtaos.* || :
|
||||||
|
|
||||||
${csudo}rm -f ${log_link_dir} || :
|
${csudo}rm -f ${log_link_dir} || :
|
||||||
|
|
|
@ -314,11 +314,12 @@ function install_jemalloc() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function install_header() {
|
function install_header() {
|
||||||
${csudo}rm -f ${inc_link_dir}/taos.h ${inc_link_dir}/taosdef.h ${inc_link_dir}/taoserror.h || :
|
${csudo}rm -f ${inc_link_dir}/taos.h ${inc_link_dir}/taosdef.h ${inc_link_dir}/taoserror.h ${inc_link_dir}/taosudf.h || :
|
||||||
${csudo}cp -f ${script_dir}/inc/* ${install_main_dir}/include && ${csudo}chmod 644 ${install_main_dir}/include/*
|
${csudo}cp -f ${script_dir}/inc/* ${install_main_dir}/include && ${csudo}chmod 644 ${install_main_dir}/include/*
|
||||||
${csudo}ln -s ${install_main_dir}/include/taos.h ${inc_link_dir}/taos.h
|
${csudo}ln -s ${install_main_dir}/include/taos.h ${inc_link_dir}/taos.h
|
||||||
${csudo}ln -s ${install_main_dir}/include/taosdef.h ${inc_link_dir}/taosdef.h
|
${csudo}ln -s ${install_main_dir}/include/taosdef.h ${inc_link_dir}/taosdef.h
|
||||||
${csudo}ln -s ${install_main_dir}/include/taoserror.h ${inc_link_dir}/taoserror.h
|
${csudo}ln -s ${install_main_dir}/include/taoserror.h ${inc_link_dir}/taoserror.h
|
||||||
|
${csudo}ln -s ${install_main_dir}/include/taosudf.h ${inc_link_dir}/taosudf.h
|
||||||
}
|
}
|
||||||
|
|
||||||
function add_newHostname_to_hosts() {
|
function add_newHostname_to_hosts() {
|
||||||
|
|
|
@ -115,11 +115,12 @@ function install_bin() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function install_header() {
|
function install_header() {
|
||||||
${csudo}rm -f ${inc_link_dir}/taos.h ${inc_link_dir}/taosdef.h ${inc_link_dir}/taoserror.h || :
|
${csudo}rm -f ${inc_link_dir}/taos.h ${inc_link_dir}/taosdef.h ${inc_link_dir}/taoserror.h ${inc_link_dir}/taosudf.h || :
|
||||||
${csudo}cp -f ${script_dir}/inc/* ${install_main_dir}/include && ${csudo}chmod 644 ${install_main_dir}/include/*
|
${csudo}cp -f ${script_dir}/inc/* ${install_main_dir}/include && ${csudo}chmod 644 ${install_main_dir}/include/*
|
||||||
${csudo}ln -s ${install_main_dir}/include/taos.h ${inc_link_dir}/taos.h
|
${csudo}ln -s ${install_main_dir}/include/taos.h ${inc_link_dir}/taos.h
|
||||||
${csudo}ln -s ${install_main_dir}/include/taosdef.h ${inc_link_dir}/taosdef.h
|
${csudo}ln -s ${install_main_dir}/include/taosdef.h ${inc_link_dir}/taosdef.h
|
||||||
${csudo}ln -s ${install_main_dir}/include/taoserror.h ${inc_link_dir}/taoserror.h
|
${csudo}ln -s ${install_main_dir}/include/taoserror.h ${inc_link_dir}/taoserror.h
|
||||||
|
${csudo}ln -s ${install_main_dir}/include/taosudf.h ${inc_link_dir}/taosudf.h
|
||||||
}
|
}
|
||||||
|
|
||||||
function install_jemalloc() {
|
function install_jemalloc() {
|
||||||
|
|
|
@ -148,11 +148,12 @@ function install_lib() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function install_header() {
|
function install_header() {
|
||||||
${csudo}rm -f ${inc_link_dir}/taos.h ${inc_link_dir}/taosdef.h ${inc_link_dir}/taoserror.h || :
|
${csudo}rm -f ${inc_link_dir}/taos.h ${inc_link_dir}/taosdef.h ${inc_link_dir}/taoserror.h ${inc_link_dir}/taosudf.h || :
|
||||||
${csudo}cp -f ${script_dir}/inc/* ${install_main_dir}/include && ${csudo}chmod 644 ${install_main_dir}/include/*
|
${csudo}cp -f ${script_dir}/inc/* ${install_main_dir}/include && ${csudo}chmod 644 ${install_main_dir}/include/*
|
||||||
${csudo}ln -s ${install_main_dir}/include/taos.h ${inc_link_dir}/taos.h
|
${csudo}ln -s ${install_main_dir}/include/taos.h ${inc_link_dir}/taos.h
|
||||||
${csudo}ln -s ${install_main_dir}/include/taosdef.h ${inc_link_dir}/taosdef.h
|
${csudo}ln -s ${install_main_dir}/include/taosdef.h ${inc_link_dir}/taosdef.h
|
||||||
${csudo}ln -s ${install_main_dir}/include/taoserror.h ${inc_link_dir}/taoserror.h
|
${csudo}ln -s ${install_main_dir}/include/taoserror.h ${inc_link_dir}/taoserror.h
|
||||||
|
${csudo}ln -s ${install_main_dir}/include/taosudf.h ${inc_link_dir}/taosudf.h
|
||||||
}
|
}
|
||||||
|
|
||||||
function install_jemalloc() {
|
function install_jemalloc() {
|
||||||
|
|
|
@ -349,16 +349,17 @@ function install_lib() {
|
||||||
function install_header() {
|
function install_header() {
|
||||||
|
|
||||||
if [ "$osType" != "Darwin" ]; then
|
if [ "$osType" != "Darwin" ]; then
|
||||||
${csudo}rm -f ${inc_link_dir}/taos.h ${inc_link_dir}/taosdef.h ${inc_link_dir}/taoserror.h || :
|
${csudo}rm -f ${inc_link_dir}/taos.h ${inc_link_dir}/taosdef.h ${inc_link_dir}/taoserror.h ${inc_link_dir}/taosudf.h || :
|
||||||
${csudo}cp -f ${source_dir}/include/client/taos.h ${source_dir}/include/common/taosdef.h ${source_dir}/include/util/taoserror.h \
|
${csudo}cp -f ${source_dir}/include/client/taos.h ${source_dir}/include/common/taosdef.h ${source_dir}/include/util/taoserror.h ${source_dir}/include/libs/function/taosudf.h \
|
||||||
${install_main_dir}/include && ${csudo}chmod 644 ${install_main_dir}/include/*
|
${install_main_dir}/include && ${csudo}chmod 644 ${install_main_dir}/include/*
|
||||||
${csudo}ln -s ${install_main_dir}/include/taos.h ${inc_link_dir}/taos.h
|
${csudo}ln -s ${install_main_dir}/include/taos.h ${inc_link_dir}/taos.h
|
||||||
${csudo}ln -s ${install_main_dir}/include/taosdef.h ${inc_link_dir}/taosdef.h
|
${csudo}ln -s ${install_main_dir}/include/taosdef.h ${inc_link_dir}/taosdef.h
|
||||||
${csudo}ln -s ${install_main_dir}/include/taoserror.h ${inc_link_dir}/taoserror.h
|
${csudo}ln -s ${install_main_dir}/include/taoserror.h ${inc_link_dir}/taoserror.h
|
||||||
|
${csudo}ln -s ${install_main_dir}/include/taosudf.h ${inc_link_dir}/taosudf.h
|
||||||
else
|
else
|
||||||
${csudo}cp -f ${source_dir}/include/client/taos.h ${source_dir}/include/common/taosdef.h ${source_dir}/include/util/taoserror.h \
|
${csudo}cp -f ${source_dir}/include/client/taos.h ${source_dir}/include/common/taosdef.h ${source_dir}/include/util/taoserror.h ${source_dir}/include/libs/function/taosudf.h \
|
||||||
${install_main_dir}/include ||
|
${install_main_dir}/include ||
|
||||||
${csudo}cp -f ${source_dir}/include/client/taos.h ${source_dir}/include/common/taosdef.h ${source_dir}/include/util/taoserror.h \
|
${csudo}cp -f ${source_dir}/include/client/taos.h ${source_dir}/include/common/taosdef.h ${source_dir}/include/util/taoserror.h ${source_dir}/include/libs/function/taosudf.h \
|
||||||
${install_main_2_dir}/include &&
|
${install_main_2_dir}/include &&
|
||||||
${csudo}chmod 644 ${install_main_dir}/include/* ||
|
${csudo}chmod 644 ${install_main_dir}/include/* ||
|
||||||
${csudo}chmod 644 ${install_main_2_dir}/include/*
|
${csudo}chmod 644 ${install_main_2_dir}/include/*
|
||||||
|
|
|
@ -36,7 +36,7 @@ fi
|
||||||
bin_files="${build_dir}/bin/tarbitrator ${script_dir}/remove_arbi.sh"
|
bin_files="${build_dir}/bin/tarbitrator ${script_dir}/remove_arbi.sh"
|
||||||
install_files="${script_dir}/install_arbi.sh"
|
install_files="${script_dir}/install_arbi.sh"
|
||||||
|
|
||||||
#header_files="${code_dir}/include/client/taos.h ${code_dir}/include/common/taosdef.h ${code_dir}/include/util/taoserror.h"
|
#header_files="${code_dir}/include/client/taos.h ${code_dir}/include/common/taosdef.h ${code_dir}/include/util/taoserror.h ${code_dir}/include/libs/function/taosudf.h"
|
||||||
init_file_tarbitrator_deb=${script_dir}/../deb/tarbitratord
|
init_file_tarbitrator_deb=${script_dir}/../deb/tarbitratord
|
||||||
init_file_tarbitrator_rpm=${script_dir}/../rpm/tarbitratord
|
init_file_tarbitrator_rpm=${script_dir}/../rpm/tarbitratord
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,7 @@ else
|
||||||
lib_files="${build_dir}/lib/libtaos.${version}.dylib"
|
lib_files="${build_dir}/lib/libtaos.${version}.dylib"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
header_files="${code_dir}/include/client/taos.h ${code_dir}/include/common/taosdef.h ${code_dir}/include/util/taoserror.h"
|
header_files="${code_dir}/include/client/taos.h ${code_dir}/include/common/taosdef.h ${code_dir}/include/util/taoserror.h ${code_dir}/include/libs/function/taosudf.h"
|
||||||
if [ "$dbName" != "taos" ]; then
|
if [ "$dbName" != "taos" ]; then
|
||||||
cfg_dir="${top_dir}/../enterprise/packaging/cfg"
|
cfg_dir="${top_dir}/../enterprise/packaging/cfg"
|
||||||
else
|
else
|
||||||
|
|
|
@ -93,7 +93,7 @@ else
|
||||||
fi
|
fi
|
||||||
|
|
||||||
lib_files="${build_dir}/lib/libtaos.so.${version}"
|
lib_files="${build_dir}/lib/libtaos.so.${version}"
|
||||||
header_files="${code_dir}/include/client/taos.h ${code_dir}/include/common/taosdef.h ${code_dir}/include/util/taoserror.h"
|
header_files="${code_dir}/include/client/taos.h ${code_dir}/include/common/taosdef.h ${code_dir}/include/util/taoserror.h ${code_dir}/include/libs/function/taosudf.h"
|
||||||
|
|
||||||
if [ "$dbName" != "taos" ]; then
|
if [ "$dbName" != "taos" ]; then
|
||||||
cfg_dir="${top_dir}/../enterprise/packaging/cfg"
|
cfg_dir="${top_dir}/../enterprise/packaging/cfg"
|
||||||
|
|
|
@ -81,10 +81,11 @@ function kill_taosd() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function install_include() {
|
function install_include() {
|
||||||
${csudo}rm -f ${inc_link_dir}/taos.h ${inc_link_dir}/taosdef.h ${inc_link_dir}/taoserror.h|| :
|
${csudo}rm -f ${inc_link_dir}/taos.h ${inc_link_dir}/taosdef.h ${inc_link_dir}/taoserror.h ${inc_link_dir}/taosudf.h || :
|
||||||
${csudo}ln -s ${inc_dir}/taos.h ${inc_link_dir}/taos.h
|
${csudo}ln -s ${inc_dir}/taos.h ${inc_link_dir}/taos.h
|
||||||
${csudo}ln -s ${inc_dir}/taosdef.h ${inc_link_dir}/taosdef.h
|
${csudo}ln -s ${inc_dir}/taosdef.h ${inc_link_dir}/taosdef.h
|
||||||
${csudo}ln -s ${inc_dir}/taoserror.h ${inc_link_dir}/taoserror.h
|
${csudo}ln -s ${inc_dir}/taoserror.h ${inc_link_dir}/taoserror.h
|
||||||
|
${csudo}ln -s ${inc_dir}/taosudf.h ${inc_link_dir}/taosudf.h
|
||||||
}
|
}
|
||||||
|
|
||||||
function install_lib() {
|
function install_lib() {
|
||||||
|
|
|
@ -128,6 +128,7 @@ ${csudo}rm -f ${cfg_link_dir}/*.new || :
|
||||||
${csudo}rm -f ${inc_link_dir}/taos.h || :
|
${csudo}rm -f ${inc_link_dir}/taos.h || :
|
||||||
${csudo}rm -f ${inc_link_dir}/taosdef.h || :
|
${csudo}rm -f ${inc_link_dir}/taosdef.h || :
|
||||||
${csudo}rm -f ${inc_link_dir}/taoserror.h || :
|
${csudo}rm -f ${inc_link_dir}/taoserror.h || :
|
||||||
|
${csudo}rm -f ${inc_link_dir}/taosudf.h || :
|
||||||
${csudo}rm -f ${lib_link_dir}/libtaos.* || :
|
${csudo}rm -f ${lib_link_dir}/libtaos.* || :
|
||||||
${csudo}rm -f ${lib64_link_dir}/libtaos.* || :
|
${csudo}rm -f ${lib64_link_dir}/libtaos.* || :
|
||||||
|
|
||||||
|
|
|
@ -84,6 +84,7 @@ function clean_header() {
|
||||||
${csudo} rm -f ${inc_link_dir}/taos.h || :
|
${csudo} rm -f ${inc_link_dir}/taos.h || :
|
||||||
${csudo} rm -f ${inc_link_dir}/taosdef.h || :
|
${csudo} rm -f ${inc_link_dir}/taosdef.h || :
|
||||||
${csudo} rm -f ${inc_link_dir}/taoserror.h || :
|
${csudo} rm -f ${inc_link_dir}/taoserror.h || :
|
||||||
|
${csudo} rm -f ${inc_link_dir}/taosudf.h || :
|
||||||
}
|
}
|
||||||
|
|
||||||
function clean_config() {
|
function clean_config() {
|
||||||
|
|
|
@ -59,6 +59,8 @@ function clean_header() {
|
||||||
${csudo}rm -f ${inc_link_dir}/taos.h || :
|
${csudo}rm -f ${inc_link_dir}/taos.h || :
|
||||||
${csudo}rm -f ${inc_link_dir}/taosdef.h || :
|
${csudo}rm -f ${inc_link_dir}/taosdef.h || :
|
||||||
${csudo}rm -f ${inc_link_dir}/taoserror.h || :
|
${csudo}rm -f ${inc_link_dir}/taoserror.h || :
|
||||||
|
${csudo}rm -f ${inc_link_dir}/taosudf.h || :
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function clean_log() {
|
function clean_log() {
|
||||||
|
|
|
@ -54,6 +54,7 @@ function clean_header() {
|
||||||
${csudo}rm -f ${inc_link_dir}/taos.h || :
|
${csudo}rm -f ${inc_link_dir}/taos.h || :
|
||||||
${csudo}rm -f ${inc_link_dir}/taosdef.h || :
|
${csudo}rm -f ${inc_link_dir}/taosdef.h || :
|
||||||
${csudo}rm -f ${inc_link_dir}/taoserror.h || :
|
${csudo}rm -f ${inc_link_dir}/taoserror.h || :
|
||||||
|
${csudo}rm -f ${inc_link_dir}/taosudf.h || :
|
||||||
}
|
}
|
||||||
|
|
||||||
function clean_config() {
|
function clean_config() {
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
|
|
||||||
#define _DEFAULT_SOURCE
|
#define _DEFAULT_SOURCE
|
||||||
#include "mndAcct.h"
|
#include "mndAcct.h"
|
||||||
#include "mndPrivilege.h"
|
|
||||||
#include "mndBnode.h"
|
#include "mndBnode.h"
|
||||||
#include "mndCluster.h"
|
#include "mndCluster.h"
|
||||||
#include "mndConsumer.h"
|
#include "mndConsumer.h"
|
||||||
|
@ -27,6 +26,7 @@
|
||||||
#include "mndMnode.h"
|
#include "mndMnode.h"
|
||||||
#include "mndOffset.h"
|
#include "mndOffset.h"
|
||||||
#include "mndPerfSchema.h"
|
#include "mndPerfSchema.h"
|
||||||
|
#include "mndPrivilege.h"
|
||||||
#include "mndProfile.h"
|
#include "mndProfile.h"
|
||||||
#include "mndQnode.h"
|
#include "mndQnode.h"
|
||||||
#include "mndQuery.h"
|
#include "mndQuery.h"
|
||||||
|
@ -416,7 +416,7 @@ int32_t mndProcessSyncMsg(SRpcMsg *pMsg) {
|
||||||
char *syncNodeStr = sync2SimpleStr(pMgmt->sync);
|
char *syncNodeStr = sync2SimpleStr(pMgmt->sync);
|
||||||
static int64_t mndTick = 0;
|
static int64_t mndTick = 0;
|
||||||
if (++mndTick % 10 == 1) {
|
if (++mndTick % 10 == 1) {
|
||||||
mTrace("vgId:%d, sync heartbeat msg:%s, %s", syncGetVgId(pMgmt->sync), TMSG_INFO(pMsg->msgType), syncNodeStr);
|
mTrace("vgId:%d, sync trace msg:%s, %s", syncGetVgId(pMgmt->sync), TMSG_INFO(pMsg->msgType), syncNodeStr);
|
||||||
}
|
}
|
||||||
if (gRaftDetailLog) {
|
if (gRaftDetailLog) {
|
||||||
char logBuf[512] = {0};
|
char logBuf[512] = {0};
|
||||||
|
|
|
@ -205,16 +205,16 @@ struct STFile {
|
||||||
uint8_t state;
|
uint8_t state;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define TD_FILE_F(tf) (&((tf)->f))
|
#define TD_TFILE_F(tf) (&((tf)->f))
|
||||||
#define TD_FILE_PFILE(tf) ((tf)->pFile)
|
#define TD_TFILE_PFILE(tf) ((tf)->pFile)
|
||||||
#define TD_FILE_OPENED(tf) (TD_FILE_PFILE(tf) != NULL)
|
#define TD_TFILE_OPENED(tf) (TD_TFILE_PFILE(tf) != NULL)
|
||||||
#define TD_FILE_FULL_NAME(tf) (TD_FILE_F(tf)->aname)
|
#define TD_TFILE_FULL_NAME(tf) (TD_TFILE_F(tf)->aname)
|
||||||
#define TD_FILE_REL_NAME(tf) (TD_FILE_F(tf)->rname)
|
#define TD_TFILE_REL_NAME(tf) (TD_TFILE_F(tf)->rname)
|
||||||
#define TD_FILE_OPENED(tf) (TD_FILE_PFILE(tf) != NULL)
|
#define TD_TFILE_OPENED(tf) (TD_TFILE_PFILE(tf) != NULL)
|
||||||
#define TD_FILE_CLOSED(tf) (!TD_FILE_OPENED(tf))
|
#define TD_TFILE_CLOSED(tf) (!TD_TFILE_OPENED(tf))
|
||||||
#define TD_FILE_SET_CLOSED(f) (TD_FILE_PFILE(f) = NULL)
|
#define TD_TFILE_SET_CLOSED(f) (TD_TFILE_PFILE(f) = NULL)
|
||||||
#define TD_FILE_SET_STATE(tf, s) ((tf)->state = (s))
|
#define TD_TFILE_SET_STATE(tf, s) ((tf)->state = (s))
|
||||||
#define TD_FILE_DID(tf) (TD_FILE_F(tf)->did)
|
#define TD_TFILE_DID(tf) (TD_TFILE_F(tf)->did)
|
||||||
|
|
||||||
int32_t tdInitTFile(STFile *pTFile, STfs *pTfs, const char *fname);
|
int32_t tdInitTFile(STFile *pTFile, STfs *pTfs, const char *fname);
|
||||||
int32_t tdCreateTFile(STFile *pTFile, STfs *pTfs, bool updateHeader, int8_t fType);
|
int32_t tdCreateTFile(STFile *pTFile, STfs *pTfs, bool updateHeader, int8_t fType);
|
||||||
|
|
|
@ -64,6 +64,7 @@ typedef struct STsdbSnapshotReader STsdbSnapshotReader;
|
||||||
#define VNODE_TQ_DIR "tq"
|
#define VNODE_TQ_DIR "tq"
|
||||||
#define VNODE_WAL_DIR "wal"
|
#define VNODE_WAL_DIR "wal"
|
||||||
#define VNODE_TSMA_DIR "tsma"
|
#define VNODE_TSMA_DIR "tsma"
|
||||||
|
#define VNODE_RSMA_DIR "rsma"
|
||||||
#define VNODE_RSMA0_DIR "tsdb"
|
#define VNODE_RSMA0_DIR "tsdb"
|
||||||
#define VNODE_RSMA1_DIR "rsma1"
|
#define VNODE_RSMA1_DIR "rsma1"
|
||||||
#define VNODE_RSMA2_DIR "rsma2"
|
#define VNODE_RSMA2_DIR "rsma2"
|
||||||
|
@ -161,7 +162,6 @@ SSubmitReq* tdBlockToSubmit(const SArray* pBlocks, const STSchema* pSchema, bool
|
||||||
|
|
||||||
// sma
|
// sma
|
||||||
int32_t smaOpen(SVnode* pVnode);
|
int32_t smaOpen(SVnode* pVnode);
|
||||||
int32_t smaClose(SSma* pSma);
|
|
||||||
int32_t smaCloseEnv(SSma* pSma);
|
int32_t smaCloseEnv(SSma* pSma);
|
||||||
int32_t smaCloseEx(SSma* pSma);
|
int32_t smaCloseEx(SSma* pSma);
|
||||||
|
|
||||||
|
|
|
@ -123,7 +123,7 @@ int32_t smaOpen(SVnode *pVnode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// restore the rsma
|
// restore the rsma
|
||||||
#if 0
|
#if 1
|
||||||
if (rsmaRestore(pSma) < 0) {
|
if (rsmaRestore(pSma) < 0) {
|
||||||
goto _err;
|
goto _err;
|
||||||
}
|
}
|
||||||
|
@ -154,12 +154,6 @@ int32_t smaCloseEx(SSma *pSma) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t smaClose(SSma *pSma) {
|
|
||||||
smaCloseEnv(pSma);
|
|
||||||
smaCloseEx(pSma);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief rsma env restore
|
* @brief rsma env restore
|
||||||
*
|
*
|
||||||
|
|
|
@ -17,11 +17,12 @@
|
||||||
|
|
||||||
#define RSMA_QTASKINFO_PERSIST_MS 7200000
|
#define RSMA_QTASKINFO_PERSIST_MS 7200000
|
||||||
#define RSMA_QTASKINFO_BUFSIZE 32768
|
#define RSMA_QTASKINFO_BUFSIZE 32768
|
||||||
|
#define RSMA_QTASKINFO_HEAD_LEN (sizeof(int32_t) + sizeof(int8_t) + sizeof(int64_t)) // len + type + suid
|
||||||
typedef enum { TD_QTASK_TMP_FILE = 0, TD_QTASK_CUR_FILE } TD_QTASK_FILE_T;
|
typedef enum { TD_QTASK_TMP_FILE = 0, TD_QTASK_CUR_FILE } TD_QTASK_FILE_T;
|
||||||
static const char *tdQTaskInfoFname[] = {"qtaskinfo.t", "qtaskinfo"};
|
static const char *tdQTaskInfoFname[] = {"qtaskinfo.t", "qtaskinfo"};
|
||||||
|
|
||||||
typedef struct SRSmaQTaskInfoItem SRSmaQTaskInfoItem;
|
typedef struct SRSmaQTaskInfoItem SRSmaQTaskInfoItem;
|
||||||
typedef struct SRSmaQTaskFIter SRSmaQTaskFIter;
|
typedef struct SRSmaQTaskInfoIter SRSmaQTaskInfoIter;
|
||||||
|
|
||||||
static int32_t tdUidStorePut(STbUidStore *pStore, tb_uid_t suid, tb_uid_t *uid);
|
static int32_t tdUidStorePut(STbUidStore *pStore, tb_uid_t suid, tb_uid_t *uid);
|
||||||
static int32_t tdUpdateTbUidListImpl(SSma *pSma, tb_uid_t *suid, SArray *tbUids);
|
static int32_t tdUpdateTbUidListImpl(SSma *pSma, tb_uid_t *suid, SArray *tbUids);
|
||||||
|
@ -32,13 +33,17 @@ static int32_t tdExecuteRSmaImpl(SSma *pSma, const void *pMsg, int32_t inputType
|
||||||
static void tdRSmaFetchTrigger(void *param, void *tmrId);
|
static void tdRSmaFetchTrigger(void *param, void *tmrId);
|
||||||
static void tdRSmaPersistTrigger(void *param, void *tmrId);
|
static void tdRSmaPersistTrigger(void *param, void *tmrId);
|
||||||
static void *tdRSmaPersistExec(void *param);
|
static void *tdRSmaPersistExec(void *param);
|
||||||
static void tdRSmaQTaskGetFName(int32_t vid, int8_t ftype, char *outputName);
|
static void tdRSmaQTaskInfoGetFName(int32_t vid, int8_t ftype, char *outputName);
|
||||||
|
|
||||||
static int32_t tdRSmaQTaskInfoIterInit(SRSmaQTaskFIter *pIter, STFile *pTFile);
|
static int32_t tdRSmaQTaskInfoIterInit(SRSmaQTaskInfoIter *pIter, STFile *pTFile);
|
||||||
static int32_t tdRSmaQTaskInfoIterNextBlock(SRSmaQTaskFIter *pIter, bool *isFinish);
|
static int32_t tdRSmaQTaskInfoIterNextBlock(SRSmaQTaskInfoIter *pIter, bool *isFinish);
|
||||||
static int32_t tdRSmaQTaskInfoIterNext(SRSmaQTaskFIter *pIter, SRSmaQTaskInfoItem *pItem, bool *isEnd);
|
static int32_t tdRSmaQTaskInfoRestore(SSma *pSma, SRSmaQTaskInfoIter *pIter);
|
||||||
static int32_t tdRSmaQTaskInfoItemRestore(SSma *pSma, const SRSmaQTaskInfoItem *infoItem);
|
static int32_t tdRSmaQTaskInfoItemRestore(SSma *pSma, const SRSmaQTaskInfoItem *infoItem);
|
||||||
|
|
||||||
|
static int32_t tdRSmaRestoreQTaskInfoInit(SSma *pSma);
|
||||||
|
static int32_t tdRSmaRestoreQTaskInfoReload(SSma *pSma);
|
||||||
|
static int32_t tdRSmaRestoreTSDataReload(SSma *pSma);
|
||||||
|
|
||||||
struct SRSmaInfoItem {
|
struct SRSmaInfoItem {
|
||||||
SRSmaInfo *pRsmaInfo;
|
SRSmaInfo *pRsmaInfo;
|
||||||
void *taskInfo; // qTaskInfo_t
|
void *taskInfo; // qTaskInfo_t
|
||||||
|
@ -63,22 +68,23 @@ struct SRSmaQTaskInfoItem {
|
||||||
void *qTaskInfo;
|
void *qTaskInfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SRSmaQTaskFIter {
|
struct SRSmaQTaskInfoIter {
|
||||||
STFile *pTFile;
|
STFile *pTFile;
|
||||||
int64_t offset;
|
int64_t offset;
|
||||||
int64_t fsize;
|
int64_t fsize;
|
||||||
int32_t nBytes;
|
int32_t nBytes;
|
||||||
int32_t nAlloc;
|
int32_t nAlloc;
|
||||||
char *buf;
|
char *pBuf;
|
||||||
// ------------
|
// ------------
|
||||||
|
char *qBuf; // for iterator
|
||||||
int32_t nBufPos;
|
int32_t nBufPos;
|
||||||
};
|
};
|
||||||
|
|
||||||
static FORCE_INLINE int32_t tdRSmaQTaskInfoContLen(int32_t lenWithHead) {
|
static FORCE_INLINE int32_t tdRSmaQTaskInfoContLen(int32_t lenWithHead) {
|
||||||
return lenWithHead - sizeof(int32_t) - sizeof(int8_t) - sizeof(int64_t);
|
return lenWithHead - RSMA_QTASKINFO_HEAD_LEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FORCE_INLINE void tdRSmaQTaskInfoIterDestroy(SRSmaQTaskFIter *pIter) { taosMemoryFreeClear(pIter->buf); }
|
static FORCE_INLINE void tdRSmaQTaskInfoIterDestroy(SRSmaQTaskInfoIter *pIter) { taosMemoryFreeClear(pIter->pBuf); }
|
||||||
|
|
||||||
static FORCE_INLINE void tdFreeTaskHandle(qTaskInfo_t *taskHandle, int32_t vgId, int32_t level) {
|
static FORCE_INLINE void tdFreeTaskHandle(qTaskInfo_t *taskHandle, int32_t vgId, int32_t level) {
|
||||||
// Note: free/kill may in RC
|
// Note: free/kill may in RC
|
||||||
|
@ -244,6 +250,7 @@ static int32_t tdSetRSmaInfoItemParams(SSma *pSma, SRSmaParam *param, SRSmaInfo
|
||||||
pItem->pRsmaInfo = pRSmaInfo;
|
pItem->pRsmaInfo = pRSmaInfo;
|
||||||
pItem->taskInfo = qCreateStreamExecTaskInfo(param->qmsg[idx], pReadHandle);
|
pItem->taskInfo = qCreateStreamExecTaskInfo(param->qmsg[idx], pReadHandle);
|
||||||
if (!pItem->taskInfo) {
|
if (!pItem->taskInfo) {
|
||||||
|
terrno = TSDB_CODE_RSMA_QTASKINFO_CREATE;
|
||||||
goto _err;
|
goto _err;
|
||||||
}
|
}
|
||||||
pItem->triggerStat = TASK_TRIGGER_STAT_INACTIVE;
|
pItem->triggerStat = TASK_TRIGGER_STAT_INACTIVE;
|
||||||
|
@ -294,7 +301,7 @@ int32_t tdProcessRSmaCreateImpl(SSma *pSma, SRSmaParam *param, int64_t suid, con
|
||||||
|
|
||||||
pRSmaInfo = taosHashGet(RSMA_INFO_HASH(pStat), &suid, sizeof(tb_uid_t));
|
pRSmaInfo = taosHashGet(RSMA_INFO_HASH(pStat), &suid, sizeof(tb_uid_t));
|
||||||
if (pRSmaInfo) {
|
if (pRSmaInfo) {
|
||||||
ASSERT(0); // TODO: free original pRSmaInfo is exists abnormally
|
ASSERT(0); // TODO: free original pRSmaInfo if exists abnormally
|
||||||
smaDebug("vgId:%d, rsma info already exists for table %s, %" PRIi64, SMA_VID(pSma), tbName, suid);
|
smaDebug("vgId:%d, rsma info already exists for table %s, %" PRIi64, SMA_VID(pSma), tbName, suid);
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -338,10 +345,10 @@ int32_t tdProcessRSmaCreateImpl(SSma *pSma, SRSmaParam *param, int64_t suid, con
|
||||||
|
|
||||||
if (taosHashPut(RSMA_INFO_HASH(pStat), &suid, sizeof(tb_uid_t), &pRSmaInfo, sizeof(pRSmaInfo)) < 0) {
|
if (taosHashPut(RSMA_INFO_HASH(pStat), &suid, sizeof(tb_uid_t), &pRSmaInfo, sizeof(pRSmaInfo)) < 0) {
|
||||||
goto _err;
|
goto _err;
|
||||||
} else {
|
|
||||||
smaDebug("vgId:%d, register rsma info succeed for suid:%" PRIi64, SMA_VID(pSma), suid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
smaDebug("vgId:%d, register rsma info succeed for suid:%" PRIi64, SMA_VID(pSma), suid);
|
||||||
|
|
||||||
// start the persist timer
|
// start the persist timer
|
||||||
if (TASK_TRIGGER_STAT_INIT ==
|
if (TASK_TRIGGER_STAT_INIT ==
|
||||||
atomic_val_compare_exchange_8(RSMA_TRIGGER_STAT(pStat), TASK_TRIGGER_STAT_INIT, TASK_TRIGGER_STAT_ACTIVE)) {
|
atomic_val_compare_exchange_8(RSMA_TRIGGER_STAT(pStat), TASK_TRIGGER_STAT_INIT, TASK_TRIGGER_STAT_ACTIVE)) {
|
||||||
|
@ -356,10 +363,9 @@ _err:
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Check and init qTaskInfo_t, only applicable to stable with SRSmaParam.
|
* @brief Check and init qTaskInfo_t, only applicable to stable with SRSmaParam currently
|
||||||
*
|
*
|
||||||
* @param pTsdb
|
* @param pVnode
|
||||||
* @param pMeta
|
|
||||||
* @param pReq
|
* @param pReq
|
||||||
* @return int32_t
|
* @return int32_t
|
||||||
*/
|
*/
|
||||||
|
@ -695,8 +701,310 @@ int32_t tdProcessRSmaSubmit(SSma *pSma, void *pMsg, int32_t inputType) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tdRSmaQTaskGetFName(int32_t vid, int8_t ftype, char *outputName) {
|
static int32_t tdRSmaRestoreQTaskInfoInit(SSma *pSma) {
|
||||||
tdGetVndFileName(vid, "rsma", tdQTaskInfoFname[ftype], outputName);
|
SVnode *pVnode = pSma->pVnode;
|
||||||
|
|
||||||
|
SArray *suidList = taosArrayInit(1, sizeof(tb_uid_t));
|
||||||
|
if (tsdbGetStbIdList(SMA_META(pSma), 0, suidList) < 0) {
|
||||||
|
taosArrayDestroy(suidList);
|
||||||
|
smaError("vgId:%d, failed to restore rsma env since get stb id list error: %s", TD_VID(pVnode), terrstr());
|
||||||
|
return TSDB_CODE_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t arrSize = taosArrayGetSize(suidList);
|
||||||
|
if (arrSize == 0) {
|
||||||
|
taosArrayDestroy(suidList);
|
||||||
|
smaDebug("vgId:%d, no need to restore rsma env since empty stb id list", TD_VID(pVnode));
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
SMetaReader mr = {0};
|
||||||
|
metaReaderInit(&mr, SMA_META(pSma), 0);
|
||||||
|
for (int32_t i = 0; i < arrSize; ++i) {
|
||||||
|
tb_uid_t suid = *(tb_uid_t *)taosArrayGet(suidList, i);
|
||||||
|
smaDebug("vgId:%d, rsma restore, suid[%d] is %" PRIi64, TD_VID(pVnode), i, suid);
|
||||||
|
if (metaGetTableEntryByUid(&mr, suid) < 0) {
|
||||||
|
smaError("vgId:%d, rsma restore, failed to get table meta for %" PRIi64 " since %s", TD_VID(pVnode), suid,
|
||||||
|
terrstr());
|
||||||
|
goto _err;
|
||||||
|
}
|
||||||
|
ASSERT(mr.me.type == TSDB_SUPER_TABLE);
|
||||||
|
ASSERT(mr.me.uid == suid);
|
||||||
|
if (TABLE_IS_ROLLUP(mr.me.flags)) {
|
||||||
|
SRSmaParam *param = &mr.me.stbEntry.rsmaParam;
|
||||||
|
for (int i = 0; i < TSDB_RETENTION_L2; ++i) {
|
||||||
|
smaDebug("vgId:%d, rsma restore, table:%" PRIi64 " level:%d, maxdelay:%" PRIi64 " watermark:%" PRIi64
|
||||||
|
" qmsgLen:%" PRIi32,
|
||||||
|
TD_VID(pVnode), suid, i, param->maxdelay[i], param->watermark[i], param->qmsgLen[i]);
|
||||||
|
}
|
||||||
|
if (tdProcessRSmaCreateImpl(pSma, &mr.me.stbEntry.rsmaParam, suid, mr.me.name) < 0) {
|
||||||
|
smaError("vgId:%d, rsma restore env failed for %" PRIi64 " since %s", TD_VID(pVnode), suid, terrstr());
|
||||||
|
goto _err;
|
||||||
|
}
|
||||||
|
smaDebug("vgId:%d, rsma restore env success for %" PRIi64, TD_VID(pVnode), suid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
metaReaderClear(&mr);
|
||||||
|
taosArrayDestroy(suidList);
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
_err:
|
||||||
|
metaReaderClear(&mr);
|
||||||
|
taosArrayDestroy(suidList);
|
||||||
|
|
||||||
|
return TSDB_CODE_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t tdRSmaRestoreQTaskInfoReload(SSma *pSma) {
|
||||||
|
SVnode *pVnode = pSma->pVnode;
|
||||||
|
STFile tFile = {0};
|
||||||
|
char qTaskInfoFName[TSDB_FILENAME_LEN];
|
||||||
|
|
||||||
|
tdRSmaQTaskInfoGetFName(TD_VID(pVnode), TD_QTASK_CUR_FILE, qTaskInfoFName);
|
||||||
|
if (tdInitTFile(&tFile, pVnode->pTfs, qTaskInfoFName) < 0) {
|
||||||
|
goto _err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!taosCheckExistFile(TD_TFILE_FULL_NAME(&tFile))) {
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tdOpenTFile(&tFile, TD_FILE_READ) < 0) {
|
||||||
|
goto _err;
|
||||||
|
}
|
||||||
|
|
||||||
|
SRSmaQTaskInfoIter fIter = {0};
|
||||||
|
if (tdRSmaQTaskInfoIterInit(&fIter, &tFile) < 0) {
|
||||||
|
tdRSmaQTaskInfoIterDestroy(&fIter);
|
||||||
|
tdCloseTFile(&tFile);
|
||||||
|
goto _err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tdRSmaQTaskInfoRestore(pSma, &fIter) < 0) {
|
||||||
|
tdRSmaQTaskInfoIterDestroy(&fIter);
|
||||||
|
tdCloseTFile(&tFile);
|
||||||
|
goto _err;
|
||||||
|
}
|
||||||
|
|
||||||
|
tdRSmaQTaskInfoIterDestroy(&fIter);
|
||||||
|
tdCloseTFile(&tFile);
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
_err:
|
||||||
|
smaError("rsma restore, qtaskinfo reload failed since %s", terrstr());
|
||||||
|
return TSDB_CODE_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief reload ts data from checkpoint
|
||||||
|
*
|
||||||
|
* @param pSma
|
||||||
|
* @return int32_t
|
||||||
|
*/
|
||||||
|
static int32_t tdRSmaRestoreTSDataReload(SSma *pSma) {
|
||||||
|
// TODO
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
_err:
|
||||||
|
smaError("rsma restore, ts data reload failed since %s", terrstr());
|
||||||
|
return TSDB_CODE_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t tdProcessRSmaRestoreImpl(SSma *pSma) {
|
||||||
|
// step 1: iterate all stables to restore the rsma env
|
||||||
|
if (tdRSmaRestoreQTaskInfoInit(pSma) < 0) {
|
||||||
|
goto _err;
|
||||||
|
}
|
||||||
|
|
||||||
|
// step 2: retrieve qtaskinfo items from the persistence file(rsma/qtaskinfo) and restore
|
||||||
|
if (tdRSmaRestoreQTaskInfoReload(pSma) < 0) {
|
||||||
|
goto _err;
|
||||||
|
}
|
||||||
|
|
||||||
|
// step 3: reload ts data from checkpoint
|
||||||
|
if (tdRSmaRestoreTSDataReload(pSma) < 0) {
|
||||||
|
goto _err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
_err:
|
||||||
|
smaError("failed to restore rsma task since %s", terrstr());
|
||||||
|
return TSDB_CODE_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t tdRSmaQTaskInfoItemRestore(SSma *pSma, const SRSmaQTaskInfoItem *pItem) {
|
||||||
|
SRSmaStat *pStat = (SRSmaStat *)SMA_ENV_STAT((SSmaEnv *)pSma->pRSmaEnv);
|
||||||
|
SRSmaInfo *pRSmaInfo = NULL;
|
||||||
|
void *qTaskInfo = NULL;
|
||||||
|
|
||||||
|
pRSmaInfo = taosHashGet(RSMA_INFO_HASH(pStat), &pItem->suid, sizeof(pItem->suid));
|
||||||
|
|
||||||
|
if (!pRSmaInfo || !(pRSmaInfo = *(SRSmaInfo **)pRSmaInfo)) {
|
||||||
|
smaDebug("vgId:%d, no restore as no rsma info for table:%" PRIu64, SMA_VID(pSma), pItem->suid);
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pItem->type == 1) {
|
||||||
|
qTaskInfo = pRSmaInfo->items[0].taskInfo;
|
||||||
|
} else if (pItem->type == 2) {
|
||||||
|
qTaskInfo = pRSmaInfo->items[1].taskInfo;
|
||||||
|
} else {
|
||||||
|
ASSERT(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!qTaskInfo) {
|
||||||
|
smaDebug("vgId:%d, no restore as NULL rsma qTaskInfo for table:%" PRIu64, SMA_VID(pSma), pItem->suid);
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qDeserializeTaskStatus(qTaskInfo, pItem->qTaskInfo, pItem->len) < 0) {
|
||||||
|
smaError("vgId:%d, restore rsma task failed for table:%" PRIi64 " level %d since %s", SMA_VID(pSma), pItem->suid,
|
||||||
|
pItem->type, terrstr(terrno));
|
||||||
|
return TSDB_CODE_FAILED;
|
||||||
|
}
|
||||||
|
smaDebug("vgId:%d, restore rsma task success for table:%" PRIi64 " level %d", SMA_VID(pSma), pItem->suid, pItem->type);
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t tdRSmaQTaskInfoIterInit(SRSmaQTaskInfoIter *pIter, STFile *pTFile) {
|
||||||
|
memset(pIter, 0, sizeof(*pIter));
|
||||||
|
pIter->pTFile = pTFile;
|
||||||
|
pIter->offset = TD_FILE_HEAD_SIZE;
|
||||||
|
|
||||||
|
if (tdGetTFileSize(pTFile, &pIter->fsize) < 0) {
|
||||||
|
return TSDB_CODE_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((pIter->fsize - TD_FILE_HEAD_SIZE) < RSMA_QTASKINFO_BUFSIZE) {
|
||||||
|
pIter->nAlloc = pIter->fsize - TD_FILE_HEAD_SIZE;
|
||||||
|
} else {
|
||||||
|
pIter->nAlloc = RSMA_QTASKINFO_BUFSIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pIter->nAlloc < TD_FILE_HEAD_SIZE) {
|
||||||
|
pIter->nAlloc = TD_FILE_HEAD_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
pIter->pBuf = taosMemoryMalloc(pIter->nAlloc);
|
||||||
|
if (!pIter->pBuf) {
|
||||||
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
return TSDB_CODE_FAILED;
|
||||||
|
}
|
||||||
|
pIter->qBuf = pIter->pBuf;
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t tdRSmaQTaskInfoIterNextBlock(SRSmaQTaskInfoIter *pIter, bool *isFinish) {
|
||||||
|
STFile *pTFile = pIter->pTFile;
|
||||||
|
int64_t nBytes = RSMA_QTASKINFO_BUFSIZE;
|
||||||
|
|
||||||
|
if (pIter->offset >= pIter->fsize) {
|
||||||
|
*isFinish = true;
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((pIter->fsize - pIter->offset) < RSMA_QTASKINFO_BUFSIZE) {
|
||||||
|
nBytes = pIter->fsize - pIter->offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tdSeekTFile(pTFile, pIter->offset, SEEK_SET) < 0) {
|
||||||
|
ASSERT(0);
|
||||||
|
return TSDB_CODE_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tdReadTFile(pTFile, pIter->qBuf, nBytes) != nBytes) {
|
||||||
|
ASSERT(0);
|
||||||
|
return TSDB_CODE_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t infoLen = 0;
|
||||||
|
taosDecodeFixedI32(pIter->qBuf, &infoLen);
|
||||||
|
if (infoLen > nBytes) {
|
||||||
|
ASSERT(infoLen > RSMA_QTASKINFO_BUFSIZE);
|
||||||
|
pIter->nAlloc = infoLen;
|
||||||
|
void *pBuf = taosMemoryRealloc(pIter->pBuf, infoLen);
|
||||||
|
if (!pBuf) {
|
||||||
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
return TSDB_CODE_FAILED;
|
||||||
|
}
|
||||||
|
pIter->pBuf = pBuf;
|
||||||
|
pIter->qBuf = pIter->pBuf;
|
||||||
|
nBytes = infoLen;
|
||||||
|
|
||||||
|
if (tdSeekTFile(pTFile, pIter->offset, SEEK_SET)) {
|
||||||
|
ASSERT(0);
|
||||||
|
return TSDB_CODE_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tdReadTFile(pTFile, pIter->pBuf, nBytes) != nBytes) {
|
||||||
|
ASSERT(0);
|
||||||
|
return TSDB_CODE_FAILED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pIter->offset += nBytes;
|
||||||
|
pIter->nBytes = nBytes;
|
||||||
|
pIter->nBufPos = 0;
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t tdRSmaQTaskInfoRestore(SSma *pSma, SRSmaQTaskInfoIter *pIter) {
|
||||||
|
while (1) {
|
||||||
|
// block iter
|
||||||
|
bool isFinish = false;
|
||||||
|
if (tdRSmaQTaskInfoIterNextBlock(pIter, &isFinish) < 0) {
|
||||||
|
ASSERT(0);
|
||||||
|
return TSDB_CODE_FAILED;
|
||||||
|
}
|
||||||
|
if (isFinish) {
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// consume the block
|
||||||
|
int32_t qTaskInfoLenWithHead = 0;
|
||||||
|
pIter->qBuf = taosDecodeFixedI32(pIter->qBuf, &qTaskInfoLenWithHead);
|
||||||
|
if (qTaskInfoLenWithHead < RSMA_QTASKINFO_HEAD_LEN) {
|
||||||
|
terrno = TSDB_CODE_TDB_FILE_CORRUPTED;
|
||||||
|
return TSDB_CODE_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
if ((pIter->nBufPos + qTaskInfoLenWithHead) <= pIter->nBytes) {
|
||||||
|
SRSmaQTaskInfoItem infoItem = {0};
|
||||||
|
pIter->qBuf = taosDecodeFixedI8(pIter->qBuf, &infoItem.type);
|
||||||
|
pIter->qBuf = taosDecodeFixedI64(pIter->qBuf, &infoItem.suid);
|
||||||
|
infoItem.qTaskInfo = pIter->qBuf;
|
||||||
|
infoItem.len = tdRSmaQTaskInfoContLen(qTaskInfoLenWithHead);
|
||||||
|
// do the restore job
|
||||||
|
smaDebug("vgId:%d, restore the qtask info %s offset:%" PRIi64 "\n", SMA_VID(pSma),
|
||||||
|
TD_TFILE_FULL_NAME(pIter->pTFile), pIter->offset - pIter->nBytes + pIter->nBufPos);
|
||||||
|
tdRSmaQTaskInfoItemRestore(pSma, &infoItem);
|
||||||
|
|
||||||
|
pIter->qBuf = POINTER_SHIFT(pIter->qBuf, infoItem.len);
|
||||||
|
pIter->nBufPos += qTaskInfoLenWithHead;
|
||||||
|
|
||||||
|
if ((pIter->nBufPos + RSMA_QTASKINFO_HEAD_LEN) >= pIter->nBytes) {
|
||||||
|
// prepare and load next block in the file
|
||||||
|
pIter->offset -= (pIter->nBytes - pIter->nBufPos);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
pIter->qBuf = taosDecodeFixedI32(pIter->qBuf, &qTaskInfoLenWithHead);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// prepare and load next block in the file
|
||||||
|
pIter->offset -= (pIter->nBytes - pIter->nBufPos);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tdRSmaQTaskInfoGetFName(int32_t vid, int8_t ftype, char *outputName) {
|
||||||
|
tdGetVndFileName(vid, VNODE_RSMA_DIR, tdQTaskInfoFname[ftype], outputName);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *tdRSmaPersistExec(void *param) {
|
static void *tdRSmaPersistExec(void *param) {
|
||||||
|
@ -704,6 +1012,7 @@ static void *tdRSmaPersistExec(void *param) {
|
||||||
SRSmaStat *pRSmaStat = param;
|
SRSmaStat *pRSmaStat = param;
|
||||||
SSma *pSma = pRSmaStat->pSma;
|
SSma *pSma = pRSmaStat->pSma;
|
||||||
STfs *pTfs = pSma->pVnode->pTfs;
|
STfs *pTfs = pSma->pVnode->pTfs;
|
||||||
|
int32_t vid = SMA_VID(pSma);
|
||||||
int64_t toffset = 0;
|
int64_t toffset = 0;
|
||||||
bool isFileCreated = false;
|
bool isFileCreated = false;
|
||||||
|
|
||||||
|
@ -717,25 +1026,15 @@ static void *tdRSmaPersistExec(void *param) {
|
||||||
}
|
}
|
||||||
|
|
||||||
STFile tFile = {0};
|
STFile tFile = {0};
|
||||||
int32_t vid = SMA_VID(pSma);
|
|
||||||
|
|
||||||
while (infoHash) {
|
while (infoHash) {
|
||||||
SRSmaInfo *pRSmaInfo = *(SRSmaInfo **)infoHash;
|
SRSmaInfo *pRSmaInfo = *(SRSmaInfo **)infoHash;
|
||||||
|
|
||||||
#if 0
|
|
||||||
smaDebug("table %" PRIi64 " sleep 15s start ...", pRSmaInfo->items[0].pRsmaInfo->suid);
|
|
||||||
for (int32_t i = 15; i > 0; --i) {
|
|
||||||
taosSsleep(1);
|
|
||||||
smaDebug("table %" PRIi64 " countdown %d", pRSmaInfo->items[0].pRsmaInfo->suid, i);
|
|
||||||
}
|
|
||||||
smaDebug("table %" PRIi64 " sleep 15s end ...", pRSmaInfo->items[0].pRsmaInfo->suid);
|
|
||||||
#endif
|
|
||||||
for (int32_t i = 0; i < TSDB_RETENTION_L2; ++i) {
|
for (int32_t i = 0; i < TSDB_RETENTION_L2; ++i) {
|
||||||
qTaskInfo_t taskInfo = pRSmaInfo->items[i].taskInfo;
|
qTaskInfo_t taskInfo = pRSmaInfo->items[i].taskInfo;
|
||||||
if (!taskInfo) {
|
if (!taskInfo) {
|
||||||
smaDebug("vgId:%d, table %" PRIi64 " level %d qTaskInfo is NULL", vid, pRSmaInfo->suid, i + 1);
|
smaDebug("vgId:%d, table %" PRIi64 " level %d qTaskInfo is NULL", vid, pRSmaInfo->suid, i + 1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *pOutput = NULL;
|
char *pOutput = NULL;
|
||||||
int32_t len = 0;
|
int32_t len = 0;
|
||||||
int8_t type = (int8_t)(i + 1);
|
int8_t type = (int8_t)(i + 1);
|
||||||
|
@ -743,20 +1042,17 @@ static void *tdRSmaPersistExec(void *param) {
|
||||||
smaError("vgId:%d, table %" PRIi64 " level %d serialize rsma task failed since %s", vid, pRSmaInfo->suid, i + 1,
|
smaError("vgId:%d, table %" PRIi64 " level %d serialize rsma task failed since %s", vid, pRSmaInfo->suid, i + 1,
|
||||||
terrstr(terrno));
|
terrstr(terrno));
|
||||||
goto _err;
|
goto _err;
|
||||||
} else {
|
|
||||||
if (!pOutput) {
|
|
||||||
smaDebug("vgId:%d, table %" PRIi64
|
|
||||||
" level %d serialize rsma task success but no output(len %d) and no need to persist",
|
|
||||||
vid, pRSmaInfo->suid, i + 1, len);
|
|
||||||
continue;
|
|
||||||
} else if (len <= 0) {
|
|
||||||
smaDebug("vgId:%d, table %" PRIi64 " level %d serialize rsma task success with len %d and no need to persist",
|
|
||||||
vid, pRSmaInfo->suid, i + 1, len);
|
|
||||||
taosMemoryFree(pOutput);
|
|
||||||
}
|
}
|
||||||
smaDebug("vgId:%d, table %" PRIi64 " level %d serialize rsma task success with len %d and need persist", vid,
|
if (!pOutput || len <= 0) {
|
||||||
|
smaDebug("vgId:%d, table %" PRIi64 " level %d serialize rsma task success but no output(len %d), not persist",
|
||||||
|
vid, pRSmaInfo->suid, i + 1, len);
|
||||||
|
taosMemoryFreeClear(pOutput);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
smaDebug("vgId:%d, table %" PRIi64 " level %d serialize rsma task success with len %d, need persist", vid,
|
||||||
pRSmaInfo->suid, i + 1, len);
|
pRSmaInfo->suid, i + 1, len);
|
||||||
#if 1
|
#if 0
|
||||||
if (qDeserializeTaskStatus(taskInfo, pOutput, len) < 0) {
|
if (qDeserializeTaskStatus(taskInfo, pOutput, len) < 0) {
|
||||||
smaError("vgId:%d, table %" PRIi64 "level %d deserialize rsma task failed since %s", vid, pRSmaInfo->suid,
|
smaError("vgId:%d, table %" PRIi64 "level %d deserialize rsma task failed since %s", vid, pRSmaInfo->suid,
|
||||||
i + 1, terrstr(terrno));
|
i + 1, terrstr(terrno));
|
||||||
|
@ -764,48 +1060,59 @@ static void *tdRSmaPersistExec(void *param) {
|
||||||
smaDebug("vgId:%d, table %" PRIi64 " level %d deserialize rsma task success", vid, pRSmaInfo->suid, i + 1);
|
smaDebug("vgId:%d, table %" PRIi64 " level %d deserialize rsma task success", vid, pRSmaInfo->suid, i + 1);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
if (!isFileCreated) {
|
if (!isFileCreated) {
|
||||||
char qTaskInfoFName[TSDB_FILENAME_LEN];
|
char qTaskInfoFName[TSDB_FILENAME_LEN];
|
||||||
tdRSmaQTaskGetFName(vid, TD_QTASK_TMP_FILE, qTaskInfoFName);
|
tdRSmaQTaskInfoGetFName(vid, TD_QTASK_TMP_FILE, qTaskInfoFName);
|
||||||
tdInitTFile(&tFile, pTfs, qTaskInfoFName);
|
tdInitTFile(&tFile, pTfs, qTaskInfoFName);
|
||||||
tdCreateTFile(&tFile, pTfs, true, -1);
|
tdCreateTFile(&tFile, pTfs, true, -1);
|
||||||
|
|
||||||
isFileCreated = true;
|
isFileCreated = true;
|
||||||
}
|
}
|
||||||
len += (sizeof(len) + sizeof(type) + sizeof(pRSmaInfo->suid));
|
|
||||||
tdAppendTFile(&tFile, &len, sizeof(len), &toffset);
|
char tmpBuf[RSMA_QTASKINFO_HEAD_LEN] = {0};
|
||||||
tdAppendTFile(&tFile, &type, sizeof(type), &toffset);
|
void *pTmpBuf = &tmpBuf;
|
||||||
tdAppendTFile(&tFile, &pRSmaInfo->suid, sizeof(pRSmaInfo->suid), &toffset);
|
int32_t headLen = 0;
|
||||||
|
headLen += taosEncodeFixedI32(&pTmpBuf, len + RSMA_QTASKINFO_HEAD_LEN);
|
||||||
|
headLen += taosEncodeFixedI8(&pTmpBuf, type);
|
||||||
|
headLen += taosEncodeFixedI64(&pTmpBuf, pRSmaInfo->suid);
|
||||||
|
|
||||||
|
ASSERT(headLen <= RSMA_QTASKINFO_HEAD_LEN);
|
||||||
|
tdAppendTFile(&tFile, (void *)&tmpBuf, headLen, &toffset);
|
||||||
|
smaDebug("vgId:%d, table %" PRIi64 " level %d head part len:%d appended to offset:%" PRIi64, vid, pRSmaInfo->suid,
|
||||||
|
i + 1, headLen, toffset);
|
||||||
tdAppendTFile(&tFile, pOutput, len, &toffset);
|
tdAppendTFile(&tFile, pOutput, len, &toffset);
|
||||||
|
smaDebug("vgId:%d, table %" PRIi64 " level %d body part len:%d appended to offset:%" PRIi64, vid, pRSmaInfo->suid,
|
||||||
|
i + 1, len, toffset);
|
||||||
|
|
||||||
taosMemoryFree(pOutput);
|
taosMemoryFree(pOutput);
|
||||||
}
|
}
|
||||||
|
|
||||||
infoHash = taosHashIterate(RSMA_INFO_HASH(pRSmaStat), infoHash);
|
infoHash = taosHashIterate(RSMA_INFO_HASH(pRSmaStat), infoHash);
|
||||||
}
|
}
|
||||||
_normal:
|
_normal:
|
||||||
if (isFileCreated) {
|
if (isFileCreated) {
|
||||||
if (tdUpdateTFileHeader(&tFile) < 0) {
|
if (tdUpdateTFileHeader(&tFile) < 0) {
|
||||||
smaError("vgId:%d, failed to update tfile %s header since %s", vid, TD_FILE_FULL_NAME(&tFile), tstrerror(terrno));
|
smaError("vgId:%d, failed to update tfile %s header since %s", vid, TD_TFILE_FULL_NAME(&tFile),
|
||||||
|
tstrerror(terrno));
|
||||||
tdCloseTFile(&tFile);
|
tdCloseTFile(&tFile);
|
||||||
tdRemoveTFile(&tFile);
|
tdRemoveTFile(&tFile);
|
||||||
goto _err;
|
goto _err;
|
||||||
} else {
|
} else {
|
||||||
smaDebug("vgId:%d, succeed to update tfile %s header", vid, TD_FILE_FULL_NAME(&tFile));
|
smaDebug("vgId:%d, succeed to update tfile %s header", vid, TD_TFILE_FULL_NAME(&tFile));
|
||||||
}
|
}
|
||||||
|
|
||||||
tdCloseTFile(&tFile);
|
tdCloseTFile(&tFile);
|
||||||
|
|
||||||
char newFName[TSDB_FILENAME_LEN];
|
char newFName[TSDB_FILENAME_LEN];
|
||||||
strncpy(newFName, TD_FILE_FULL_NAME(&tFile), TSDB_FILENAME_LEN);
|
strncpy(newFName, TD_TFILE_FULL_NAME(&tFile), TSDB_FILENAME_LEN);
|
||||||
char *pos = strstr(newFName, tdQTaskInfoFname[TD_QTASK_TMP_FILE]);
|
char *pos = strstr(newFName, tdQTaskInfoFname[TD_QTASK_TMP_FILE]);
|
||||||
strncpy(pos, tdQTaskInfoFname[TD_QTASK_CUR_FILE], TSDB_FILENAME_LEN - POINTER_DISTANCE(pos, newFName));
|
strncpy(pos, tdQTaskInfoFname[TD_QTASK_CUR_FILE], TSDB_FILENAME_LEN - POINTER_DISTANCE(pos, newFName));
|
||||||
if (taosRenameFile(TD_FILE_FULL_NAME(&tFile), newFName) != 0) {
|
if (taosRenameFile(TD_TFILE_FULL_NAME(&tFile), newFName) != 0) {
|
||||||
smaError("vgId:%d, failed to rename %s to %s", vid, TD_FILE_FULL_NAME(&tFile), newFName);
|
smaError("vgId:%d, failed to rename %s to %s", vid, TD_TFILE_FULL_NAME(&tFile), newFName);
|
||||||
goto _err;
|
goto _err;
|
||||||
} else {
|
} else {
|
||||||
smaDebug("vgId:%d, succeed to rename %s to %s", vid, TD_FILE_FULL_NAME(&tFile), newFName);
|
smaDebug("vgId:%d, succeed to rename %s to %s", vid, TD_TFILE_FULL_NAME(&tFile), newFName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
goto _end;
|
goto _end;
|
||||||
|
@ -841,13 +1148,14 @@ static void tdRSmaPersistTask(SRSmaStat *pRSmaStat) {
|
||||||
if (TASK_TRIGGER_STAT_INACTIVE == atomic_val_compare_exchange_8(RSMA_TRIGGER_STAT(pRSmaStat),
|
if (TASK_TRIGGER_STAT_INACTIVE == atomic_val_compare_exchange_8(RSMA_TRIGGER_STAT(pRSmaStat),
|
||||||
TASK_TRIGGER_STAT_INACTIVE,
|
TASK_TRIGGER_STAT_INACTIVE,
|
||||||
TASK_TRIGGER_STAT_ACTIVE)) {
|
TASK_TRIGGER_STAT_ACTIVE)) {
|
||||||
smaDebug("persist task is active again");
|
smaDebug("vgId:%d, persist task is active again", SMA_VID(pRSmaStat->pSma));
|
||||||
} else if (TASK_TRIGGER_STAT_CANCELLED == atomic_val_compare_exchange_8(RSMA_TRIGGER_STAT(pRSmaStat),
|
} else if (TASK_TRIGGER_STAT_CANCELLED == atomic_val_compare_exchange_8(RSMA_TRIGGER_STAT(pRSmaStat),
|
||||||
TASK_TRIGGER_STAT_CANCELLED,
|
TASK_TRIGGER_STAT_CANCELLED,
|
||||||
TASK_TRIGGER_STAT_FINISHED)) {
|
TASK_TRIGGER_STAT_FINISHED)) {
|
||||||
smaDebug(" persist task is cancelled and set finished");
|
smaDebug("vgId:%d, persist task is cancelled and set finished", SMA_VID(pRSmaStat->pSma));
|
||||||
} else {
|
} else {
|
||||||
smaWarn("persist task in abnormal stat %" PRIi8, atomic_load_8(RSMA_TRIGGER_STAT(pRSmaStat)));
|
smaWarn("vgId:%d, persist task in abnormal stat %" PRIi8, atomic_load_8(RSMA_TRIGGER_STAT(pRSmaStat)),
|
||||||
|
SMA_VID(pRSmaStat->pSma));
|
||||||
ASSERT(0);
|
ASSERT(0);
|
||||||
}
|
}
|
||||||
atomic_store_8(RSMA_RUNNING_STAT(pRSmaStat), 0);
|
atomic_store_8(RSMA_RUNNING_STAT(pRSmaStat), 0);
|
||||||
|
@ -864,6 +1172,7 @@ static void tdRSmaPersistTask(SRSmaStat *pRSmaStat) {
|
||||||
*/
|
*/
|
||||||
static void tdRSmaPersistTrigger(void *param, void *tmrId) {
|
static void tdRSmaPersistTrigger(void *param, void *tmrId) {
|
||||||
SRSmaStat *pRSmaStat = param;
|
SRSmaStat *pRSmaStat = param;
|
||||||
|
|
||||||
int8_t tmrStat =
|
int8_t tmrStat =
|
||||||
atomic_val_compare_exchange_8(RSMA_TRIGGER_STAT(pRSmaStat), TASK_TRIGGER_STAT_ACTIVE, TASK_TRIGGER_STAT_INACTIVE);
|
atomic_val_compare_exchange_8(RSMA_TRIGGER_STAT(pRSmaStat), TASK_TRIGGER_STAT_ACTIVE, TASK_TRIGGER_STAT_INACTIVE);
|
||||||
switch (tmrStat) {
|
switch (tmrStat) {
|
||||||
|
@ -872,7 +1181,7 @@ static void tdRSmaPersistTrigger(void *param, void *tmrId) {
|
||||||
if (TASK_TRIGGER_STAT_CANCELLED != atomic_val_compare_exchange_8(RSMA_TRIGGER_STAT(pRSmaStat),
|
if (TASK_TRIGGER_STAT_CANCELLED != atomic_val_compare_exchange_8(RSMA_TRIGGER_STAT(pRSmaStat),
|
||||||
TASK_TRIGGER_STAT_CANCELLED,
|
TASK_TRIGGER_STAT_CANCELLED,
|
||||||
TASK_TRIGGER_STAT_FINISHED)) {
|
TASK_TRIGGER_STAT_FINISHED)) {
|
||||||
smaDebug("rsma persistence start since active");
|
smaDebug("vgId:%d, rsma persistence start since active", SMA_VID(pRSmaStat->pSma));
|
||||||
|
|
||||||
// start persist task
|
// start persist task
|
||||||
tdRSmaPersistTask(pRSmaStat);
|
tdRSmaPersistTask(pRSmaStat);
|
||||||
|
@ -895,252 +1204,6 @@ static void tdRSmaPersistTrigger(void *param, void *tmrId) {
|
||||||
} break;
|
} break;
|
||||||
default: {
|
default: {
|
||||||
smaWarn("rsma persistence not start since unknown stat %" PRIi8, tmrStat);
|
smaWarn("rsma persistence not start since unknown stat %" PRIi8, tmrStat);
|
||||||
ASSERT(0);
|
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tdProcessRSmaRestoreImpl(SSma *pSma) {
|
|
||||||
SVnode *pVnode = pSma->pVnode;
|
|
||||||
|
|
||||||
// step 1: iterate all stables to restore the rsma env
|
|
||||||
|
|
||||||
SArray *suidList = taosArrayInit(1, sizeof(tb_uid_t));
|
|
||||||
if (tsdbGetStbIdList(SMA_META(pSma), 0, suidList) < 0) {
|
|
||||||
smaError("vgId:%d, failed to restore rsma since get stb id list error: %s", TD_VID(pVnode), terrstr());
|
|
||||||
return TSDB_CODE_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (taosArrayGetSize(suidList) == 0) {
|
|
||||||
smaDebug("vgId:%d no need to restore rsma since empty stb id list", TD_VID(pVnode));
|
|
||||||
return TSDB_CODE_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
SMetaReader mr = {0};
|
|
||||||
metaReaderInit(&mr, SMA_META(pSma), 0);
|
|
||||||
for (int32_t i = 0; i < taosArrayGetSize(suidList); ++i) {
|
|
||||||
tb_uid_t suid = *(tb_uid_t *)taosArrayGet(suidList, i);
|
|
||||||
smaDebug("suid [%d] is %" PRIi64, i, suid);
|
|
||||||
if (metaGetTableEntryByUid(&mr, suid) < 0) {
|
|
||||||
smaError("vgId:%d failed to get table meta for %" PRIi64 " since %s", TD_VID(pVnode), suid, terrstr());
|
|
||||||
goto _err;
|
|
||||||
}
|
|
||||||
ASSERT(mr.me.type == TSDB_SUPER_TABLE);
|
|
||||||
ASSERT(mr.me.uid == suid);
|
|
||||||
if (TABLE_IS_ROLLUP(mr.me.flags)) {
|
|
||||||
SRSmaParam *param = &mr.me.stbEntry.rsmaParam;
|
|
||||||
for (int i = 0; i < 2; ++i) {
|
|
||||||
smaDebug("vgId: %d table:%" PRIi64 " maxdelay[%d]:%" PRIi64 " watermark[%d]:%" PRIi64, TD_VID(pSma->pVnode),
|
|
||||||
suid, i, param->maxdelay[i], i, param->watermark[i]);
|
|
||||||
}
|
|
||||||
if (tdProcessRSmaCreateImpl(pSma, &mr.me.stbEntry.rsmaParam, suid, mr.me.name) < 0) {
|
|
||||||
smaError("vgId:%d failed to retore rsma env for %" PRIi64 " since %s", TD_VID(pVnode), suid, terrstr());
|
|
||||||
goto _err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// step 2: retrieve qtaskinfo object from the rsma/qtaskinfo file and restore
|
|
||||||
STFile tFile = {0};
|
|
||||||
char qTaskInfoFName[TSDB_FILENAME_LEN];
|
|
||||||
|
|
||||||
tdRSmaQTaskGetFName(TD_VID(pVnode), TD_QTASK_CUR_FILE, qTaskInfoFName);
|
|
||||||
if (tdInitTFile(&tFile, pVnode->pTfs, qTaskInfoFName) < 0) {
|
|
||||||
goto _err;
|
|
||||||
}
|
|
||||||
if (tdOpenTFile(&tFile, TD_FILE_READ) < 0) {
|
|
||||||
goto _err;
|
|
||||||
}
|
|
||||||
SRSmaQTaskFIter fIter = {0};
|
|
||||||
if (tdRSmaQTaskInfoIterInit(&fIter, &tFile) < 0) {
|
|
||||||
goto _err;
|
|
||||||
}
|
|
||||||
SRSmaQTaskInfoItem infoItem = {0};
|
|
||||||
bool isEnd = false;
|
|
||||||
int32_t code = 0;
|
|
||||||
while ((code = tdRSmaQTaskInfoIterNext(&fIter, &infoItem, &isEnd)) == 0) {
|
|
||||||
if (isEnd) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if ((code = tdRSmaQTaskInfoItemRestore(pSma, &infoItem)) < 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tdRSmaQTaskInfoIterDestroy(&fIter);
|
|
||||||
|
|
||||||
if (code < 0) {
|
|
||||||
goto _err;
|
|
||||||
}
|
|
||||||
|
|
||||||
metaReaderClear(&mr);
|
|
||||||
taosArrayDestroy(suidList);
|
|
||||||
return TSDB_CODE_SUCCESS;
|
|
||||||
_err:
|
|
||||||
ASSERT(0);
|
|
||||||
metaReaderClear(&mr);
|
|
||||||
taosArrayDestroy(suidList);
|
|
||||||
smaError("failed to restore rsma info since %s", terrstr());
|
|
||||||
return TSDB_CODE_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t tdRSmaQTaskInfoItemRestore(SSma *pSma, const SRSmaQTaskInfoItem *infoItem) {
|
|
||||||
SRSmaStat *pStat = (SRSmaStat *)SMA_ENV_STAT((SSmaEnv *)pSma->pRSmaEnv);
|
|
||||||
SRSmaInfo *pRSmaInfo = NULL;
|
|
||||||
void *qTaskInfo = NULL;
|
|
||||||
|
|
||||||
pRSmaInfo = taosHashGet(RSMA_INFO_HASH(pStat), &infoItem->suid, sizeof(infoItem->suid));
|
|
||||||
|
|
||||||
if (!pRSmaInfo || !(pRSmaInfo = *(SRSmaInfo **)pRSmaInfo)) {
|
|
||||||
smaDebug("vgId:%d, no restore as no rsma info for suid:%" PRIu64, SMA_VID(pSma), infoItem->suid);
|
|
||||||
return TSDB_CODE_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (infoItem->type == 1) {
|
|
||||||
qTaskInfo = pRSmaInfo->items[0].taskInfo;
|
|
||||||
} else if (infoItem->type == 2) {
|
|
||||||
qTaskInfo = pRSmaInfo->items[1].taskInfo;
|
|
||||||
} else {
|
|
||||||
ASSERT(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!qTaskInfo) {
|
|
||||||
smaDebug("vgId:%d, no restore as NULL rsma qTaskInfo for suid:%" PRIu64, SMA_VID(pSma), infoItem->suid);
|
|
||||||
return TSDB_CODE_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (qDeserializeTaskStatus(qTaskInfo, infoItem->qTaskInfo, infoItem->len) < 0) {
|
|
||||||
smaError("vgId:%d, restore rsma failed for suid:%" PRIi64 " level %d since %s", SMA_VID(pSma), infoItem->suid,
|
|
||||||
infoItem->type, terrstr(terrno));
|
|
||||||
return TSDB_CODE_FAILED;
|
|
||||||
}
|
|
||||||
smaDebug("vgId:%d, restore rsma success for suid:%" PRIi64 " level %d", SMA_VID(pSma), infoItem->suid,
|
|
||||||
infoItem->type);
|
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t tdRSmaQTaskInfoIterInit(SRSmaQTaskFIter *pIter, STFile *pTFile) {
|
|
||||||
memset(pIter, 0, sizeof(*pIter));
|
|
||||||
pIter->pTFile = pTFile;
|
|
||||||
pIter->offset = TD_FILE_HEAD_SIZE;
|
|
||||||
|
|
||||||
if (tdGetTFileSize(pTFile, &pIter->fsize) < 0) {
|
|
||||||
return TSDB_CODE_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((pIter->fsize - TD_FILE_HEAD_SIZE) < RSMA_QTASKINFO_BUFSIZE) {
|
|
||||||
pIter->nAlloc = pIter->fsize - TD_FILE_HEAD_SIZE;
|
|
||||||
} else {
|
|
||||||
pIter->nAlloc = RSMA_QTASKINFO_BUFSIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pIter->nAlloc < TD_FILE_HEAD_SIZE) {
|
|
||||||
pIter->nAlloc = TD_FILE_HEAD_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
pIter->buf = taosMemoryMalloc(pIter->nAlloc);
|
|
||||||
if (!pIter->buf) {
|
|
||||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
|
||||||
return TSDB_CODE_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t tdRSmaQTaskInfoIterNextBlock(SRSmaQTaskFIter *pIter, bool *isFinish) {
|
|
||||||
STFile *pTFile = pIter->pTFile;
|
|
||||||
int64_t nBytes = RSMA_QTASKINFO_BUFSIZE;
|
|
||||||
|
|
||||||
if (pIter->offset >= pIter->fsize) {
|
|
||||||
*isFinish = true;
|
|
||||||
return TSDB_CODE_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((pIter->fsize - pIter->offset) < RSMA_QTASKINFO_BUFSIZE) {
|
|
||||||
nBytes = pIter->fsize - pIter->offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tdSeekTFile(pTFile, pIter->offset, SEEK_SET) < 0) {
|
|
||||||
ASSERT(0);
|
|
||||||
return TSDB_CODE_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tdReadTFile(pTFile, pIter->buf, nBytes) != nBytes) {
|
|
||||||
ASSERT(0);
|
|
||||||
return TSDB_CODE_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t infoLen = 0;
|
|
||||||
taosDecodeFixedI32(pIter->buf, &infoLen);
|
|
||||||
if (infoLen > nBytes) {
|
|
||||||
ASSERT(infoLen > RSMA_QTASKINFO_BUFSIZE);
|
|
||||||
pIter->nAlloc = infoLen;
|
|
||||||
void *pBuf = taosMemoryRealloc(pIter->buf, infoLen);
|
|
||||||
if (!pBuf) {
|
|
||||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
|
||||||
return TSDB_CODE_FAILED;
|
|
||||||
}
|
|
||||||
pIter->buf = pBuf;
|
|
||||||
nBytes = infoLen;
|
|
||||||
|
|
||||||
if (tdSeekTFile(pTFile, pIter->offset, SEEK_SET)) {
|
|
||||||
ASSERT(0);
|
|
||||||
return TSDB_CODE_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tdReadTFile(pTFile, pIter->buf, nBytes) != nBytes) {
|
|
||||||
ASSERT(0);
|
|
||||||
return TSDB_CODE_FAILED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pIter->offset += nBytes;
|
|
||||||
pIter->nBytes = nBytes;
|
|
||||||
pIter->nBufPos = 0;
|
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t tdRSmaQTaskInfoIterNext(SRSmaQTaskFIter *pIter, SRSmaQTaskInfoItem *pItem, bool *isEnd) {
|
|
||||||
while (1) {
|
|
||||||
// block iter
|
|
||||||
bool isFinish = false;
|
|
||||||
if (tdRSmaQTaskInfoIterNextBlock(pIter, &isFinish) < 0) {
|
|
||||||
ASSERT(0);
|
|
||||||
return TSDB_CODE_FAILED;
|
|
||||||
}
|
|
||||||
if (isFinish) {
|
|
||||||
*isEnd = true;
|
|
||||||
return TSDB_CODE_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
// consume the block
|
|
||||||
int32_t qTaskInfoLenWithHead = 0;
|
|
||||||
pIter->buf = taosDecodeFixedI32(pIter->buf, &qTaskInfoLenWithHead);
|
|
||||||
if (qTaskInfoLenWithHead < 0) {
|
|
||||||
terrno = TSDB_CODE_TDB_FILE_CORRUPTED;
|
|
||||||
return TSDB_CODE_FAILED;
|
|
||||||
}
|
|
||||||
while (1) {
|
|
||||||
if ((pIter->nBufPos + qTaskInfoLenWithHead) <= pIter->nBytes) {
|
|
||||||
pIter->buf = taosDecodeFixedI8(pIter->buf, &pItem->type);
|
|
||||||
pIter->buf = taosDecodeFixedI64(pIter->buf, &pItem->suid);
|
|
||||||
pItem->qTaskInfo = pIter->buf;
|
|
||||||
pItem->len = tdRSmaQTaskInfoContLen(qTaskInfoLenWithHead);
|
|
||||||
// do the restore job
|
|
||||||
printf("%s:%d ###### restore the qtask info offset:%" PRIi64 "\n", __func__, __LINE__, pIter->offset);
|
|
||||||
|
|
||||||
pIter->buf = POINTER_SHIFT(pIter->buf, pItem->len);
|
|
||||||
pIter->nBufPos += qTaskInfoLenWithHead;
|
|
||||||
|
|
||||||
pIter->buf = taosDecodeFixedI32(pIter->buf, &qTaskInfoLenWithHead);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// prepare and load next block in the file
|
|
||||||
pIter->offset -= (pIter->nBytes - pIter->nBufPos);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
|
@ -22,7 +22,6 @@
|
||||||
|
|
||||||
#define TD_FILE_INIT_MAGIC 0xFFFFFFFF
|
#define TD_FILE_INIT_MAGIC 0xFFFFFFFF
|
||||||
|
|
||||||
|
|
||||||
static int32_t tdEncodeTFInfo(void **buf, STFInfo *pInfo);
|
static int32_t tdEncodeTFInfo(void **buf, STFInfo *pInfo);
|
||||||
static void *tdDecodeTFInfo(void *buf, STFInfo *pInfo);
|
static void *tdDecodeTFInfo(void *buf, STFInfo *pInfo);
|
||||||
|
|
||||||
|
@ -46,7 +45,7 @@ static void *tdDecodeTFInfo(void *buf, STFInfo *pInfo) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t tdWriteTFile(STFile *pTFile, void *buf, int64_t nbyte) {
|
int64_t tdWriteTFile(STFile *pTFile, void *buf, int64_t nbyte) {
|
||||||
ASSERT(TD_FILE_OPENED(pTFile));
|
ASSERT(TD_TFILE_OPENED(pTFile));
|
||||||
|
|
||||||
int64_t nwrite = taosWriteFile(pTFile->pFile, buf, nbyte);
|
int64_t nwrite = taosWriteFile(pTFile->pFile, buf, nbyte);
|
||||||
if (nwrite < nbyte) {
|
if (nwrite < nbyte) {
|
||||||
|
@ -58,9 +57,9 @@ int64_t tdWriteTFile(STFile *pTFile, void *buf, int64_t nbyte) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t tdSeekTFile(STFile *pTFile, int64_t offset, int whence) {
|
int64_t tdSeekTFile(STFile *pTFile, int64_t offset, int whence) {
|
||||||
ASSERT(TD_FILE_OPENED(pTFile));
|
ASSERT(TD_TFILE_OPENED(pTFile));
|
||||||
|
|
||||||
int64_t loffset = taosLSeekFile(TD_FILE_PFILE(pTFile), offset, whence);
|
int64_t loffset = taosLSeekFile(TD_TFILE_PFILE(pTFile), offset, whence);
|
||||||
if (loffset < 0) {
|
if (loffset < 0) {
|
||||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -70,12 +69,12 @@ int64_t tdSeekTFile(STFile *pTFile, int64_t offset, int whence) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t tdGetTFileSize(STFile *pTFile, int64_t *size) {
|
int64_t tdGetTFileSize(STFile *pTFile, int64_t *size) {
|
||||||
ASSERT(TD_FILE_OPENED(pTFile));
|
ASSERT(TD_TFILE_OPENED(pTFile));
|
||||||
return taosFStatFile(pTFile->pFile, size, NULL);
|
return taosFStatFile(pTFile->pFile, size, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t tdReadTFile(STFile *pTFile, void *buf, int64_t nbyte) {
|
int64_t tdReadTFile(STFile *pTFile, void *buf, int64_t nbyte) {
|
||||||
ASSERT(TD_FILE_OPENED(pTFile));
|
ASSERT(TD_TFILE_OPENED(pTFile));
|
||||||
|
|
||||||
int64_t nread = taosReadFile(pTFile->pFile, buf, nbyte);
|
int64_t nread = taosReadFile(pTFile->pFile, buf, nbyte);
|
||||||
if (nread < 0) {
|
if (nread < 0) {
|
||||||
|
@ -108,7 +107,7 @@ int32_t tdLoadTFileHeader(STFile *pTFile, STFInfo *pInfo) {
|
||||||
char buf[TD_FILE_HEAD_SIZE] = "\0";
|
char buf[TD_FILE_HEAD_SIZE] = "\0";
|
||||||
uint32_t _version;
|
uint32_t _version;
|
||||||
|
|
||||||
ASSERT(TD_FILE_OPENED(pTFile));
|
ASSERT(TD_TFILE_OPENED(pTFile));
|
||||||
|
|
||||||
if (tdSeekTFile(pTFile, 0, SEEK_SET) < 0) {
|
if (tdSeekTFile(pTFile, 0, SEEK_SET) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -133,7 +132,7 @@ void tdUpdateTFileMagic(STFile *pTFile, void *pCksm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t tdAppendTFile(STFile *pTFile, void *buf, int64_t nbyte, int64_t *offset) {
|
int64_t tdAppendTFile(STFile *pTFile, void *buf, int64_t nbyte, int64_t *offset) {
|
||||||
ASSERT(TD_FILE_OPENED(pTFile));
|
ASSERT(TD_TFILE_OPENED(pTFile));
|
||||||
|
|
||||||
int64_t toffset;
|
int64_t toffset;
|
||||||
|
|
||||||
|
@ -141,6 +140,11 @@ int64_t tdAppendTFile(STFile *pTFile, void *buf, int64_t nbyte, int64_t *offset)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
smaDebug("append to file %s, offset:%" PRIi64 " + nbyte:%" PRIi64 " =%" PRIi64, TD_TFILE_FULL_NAME(pTFile), toffset,
|
||||||
|
nbyte, toffset + nbyte);
|
||||||
|
#endif
|
||||||
|
|
||||||
ASSERT(pTFile->info.fsize == toffset);
|
ASSERT(pTFile->info.fsize == toffset);
|
||||||
|
|
||||||
if (offset) {
|
if (offset) {
|
||||||
|
@ -157,9 +161,9 @@ int64_t tdAppendTFile(STFile *pTFile, void *buf, int64_t nbyte, int64_t *offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tdOpenTFile(STFile *pTFile, int flags) {
|
int32_t tdOpenTFile(STFile *pTFile, int flags) {
|
||||||
ASSERT(!TD_FILE_OPENED(pTFile));
|
ASSERT(!TD_TFILE_OPENED(pTFile));
|
||||||
|
|
||||||
pTFile->pFile = taosOpenFile(TD_FILE_FULL_NAME(pTFile), flags);
|
pTFile->pFile = taosOpenFile(TD_TFILE_FULL_NAME(pTFile), flags);
|
||||||
if (pTFile->pFile == NULL) {
|
if (pTFile->pFile == NULL) {
|
||||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -169,9 +173,9 @@ int32_t tdOpenTFile(STFile *pTFile, int flags) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void tdCloseTFile(STFile *pTFile) {
|
void tdCloseTFile(STFile *pTFile) {
|
||||||
if (TD_FILE_OPENED(pTFile)) {
|
if (TD_TFILE_OPENED(pTFile)) {
|
||||||
taosCloseFile(&pTFile->pFile);
|
taosCloseFile(&pTFile->pFile);
|
||||||
TD_FILE_SET_CLOSED(pTFile);
|
TD_TFILE_SET_CLOSED(pTFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,8 +187,8 @@ int32_t tdInitTFile(STFile *pTFile, STfs *pTfs, const char *fname) {
|
||||||
char fullname[TSDB_FILENAME_LEN];
|
char fullname[TSDB_FILENAME_LEN];
|
||||||
SDiskID did = {0};
|
SDiskID did = {0};
|
||||||
|
|
||||||
TD_FILE_SET_STATE(pTFile, TD_FILE_STATE_OK);
|
TD_TFILE_SET_STATE(pTFile, TD_FILE_STATE_OK);
|
||||||
TD_FILE_SET_CLOSED(pTFile);
|
TD_TFILE_SET_CLOSED(pTFile);
|
||||||
|
|
||||||
memset(&(pTFile->info), 0, sizeof(pTFile->info));
|
memset(&(pTFile->info), 0, sizeof(pTFile->info));
|
||||||
pTFile->info.magic = TD_FILE_INIT_MAGIC;
|
pTFile->info.magic = TD_FILE_INIT_MAGIC;
|
||||||
|
@ -202,18 +206,18 @@ int32_t tdInitTFile(STFile *pTFile, STfs *pTfs, const char *fname) {
|
||||||
int32_t tdCreateTFile(STFile *pTFile, STfs *pTfs, bool updateHeader, int8_t fType) {
|
int32_t tdCreateTFile(STFile *pTFile, STfs *pTfs, bool updateHeader, int8_t fType) {
|
||||||
ASSERT(pTFile->info.fsize == 0 && pTFile->info.magic == TD_FILE_INIT_MAGIC);
|
ASSERT(pTFile->info.fsize == 0 && pTFile->info.magic == TD_FILE_INIT_MAGIC);
|
||||||
|
|
||||||
pTFile->pFile = taosOpenFile(TD_FILE_FULL_NAME(pTFile), TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC);
|
pTFile->pFile = taosOpenFile(TD_TFILE_FULL_NAME(pTFile), TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC);
|
||||||
if (pTFile->pFile == NULL) {
|
if (pTFile->pFile == NULL) {
|
||||||
if (errno == ENOENT) {
|
if (errno == ENOENT) {
|
||||||
// Try to create directory recursively
|
// Try to create directory recursively
|
||||||
char *s = strdup(TD_FILE_REL_NAME(pTFile));
|
char *s = strdup(TD_TFILE_REL_NAME(pTFile));
|
||||||
if (tfsMkdirRecurAt(pTfs, taosDirName(s), TD_FILE_DID(pTFile)) < 0) {
|
if (tfsMkdirRecurAt(pTfs, taosDirName(s), TD_TFILE_DID(pTFile)) < 0) {
|
||||||
taosMemoryFreeClear(s);
|
taosMemoryFreeClear(s);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
taosMemoryFreeClear(s);
|
taosMemoryFreeClear(s);
|
||||||
|
|
||||||
pTFile->pFile = taosOpenFile(TD_FILE_FULL_NAME(pTFile), TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC);
|
pTFile->pFile = taosOpenFile(TD_TFILE_FULL_NAME(pTFile), TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC);
|
||||||
if (pTFile->pFile == NULL) {
|
if (pTFile->pFile == NULL) {
|
||||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -240,7 +244,7 @@ int32_t tdCreateTFile(STFile *pTFile, STfs *pTfs, bool updateHeader, int8_t fTyp
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tdRemoveTFile(STFile *pTFile) { return tfsRemoveFile(TD_FILE_F(pTFile)); }
|
int32_t tdRemoveTFile(STFile *pTFile) { return tfsRemoveFile(TD_TFILE_F(pTFile)); }
|
||||||
|
|
||||||
// smaXXXUtil ================
|
// smaXXXUtil ================
|
||||||
// ...
|
// ...
|
|
@ -152,14 +152,14 @@ SVnode *vnodeOpen(const char *path, STfs *pTfs, SMsgCb msgCb) {
|
||||||
return pVnode;
|
return pVnode;
|
||||||
|
|
||||||
_err:
|
_err:
|
||||||
if (pVnode->pSma) smaClose(pVnode->pSma);
|
if (pVnode->pSma) smaCloseEnv(pVnode->pSma);
|
||||||
if (pVnode->pQuery) vnodeQueryClose(pVnode);
|
if (pVnode->pQuery) vnodeQueryClose(pVnode);
|
||||||
if (pVnode->pTq) tqClose(pVnode->pTq);
|
if (pVnode->pTq) tqClose(pVnode->pTq);
|
||||||
if (pVnode->pWal) walClose(pVnode->pWal);
|
if (pVnode->pWal) walClose(pVnode->pWal);
|
||||||
if (pVnode->pTsdb) tsdbClose(&pVnode->pTsdb);
|
if (pVnode->pTsdb) tsdbClose(&pVnode->pTsdb);
|
||||||
|
if (pVnode->pSma) smaCloseEx(pVnode->pSma);
|
||||||
if (pVnode->pMeta) metaClose(pVnode->pMeta);
|
if (pVnode->pMeta) metaClose(pVnode->pMeta);
|
||||||
|
|
||||||
|
|
||||||
tsem_destroy(&(pVnode->canCommit));
|
tsem_destroy(&(pVnode->canCommit));
|
||||||
taosMemoryFree(pVnode);
|
taosMemoryFree(pVnode);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -243,7 +243,7 @@ int32_t vnodeProcessSyncReq(SVnode *pVnode, SRpcMsg *pMsg, SRpcMsg **pRsp) {
|
||||||
char *syncNodeStr = sync2SimpleStr(pVnode->sync);
|
char *syncNodeStr = sync2SimpleStr(pVnode->sync);
|
||||||
static int64_t vndTick = 0;
|
static int64_t vndTick = 0;
|
||||||
if (++vndTick % 10 == 1) {
|
if (++vndTick % 10 == 1) {
|
||||||
vGTrace("vgId:%d, sync heartbeat msg:%s, %s", syncGetVgId(pVnode->sync), TMSG_INFO(pMsg->msgType), syncNodeStr);
|
vGTrace("vgId:%d, sync trace msg:%s, %s", syncGetVgId(pVnode->sync), TMSG_INFO(pMsg->msgType), syncNodeStr);
|
||||||
}
|
}
|
||||||
if (gRaftDetailLog) {
|
if (gRaftDetailLog) {
|
||||||
char logBuf[512] = {0};
|
char logBuf[512] = {0};
|
||||||
|
|
|
@ -1291,7 +1291,9 @@ void catalogDestroy(void) {
|
||||||
|
|
||||||
atomic_store_8((int8_t*)&gCtgMgmt.exit, true);
|
atomic_store_8((int8_t*)&gCtgMgmt.exit, true);
|
||||||
|
|
||||||
|
if (!taosCheckCurrentInDll()) {
|
||||||
ctgClearCacheEnqueue(NULL, true, true, true);
|
ctgClearCacheEnqueue(NULL, true, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
taosHashCleanup(gCtgMgmt.pCluster);
|
taosHashCleanup(gCtgMgmt.pCluster);
|
||||||
gCtgMgmt.pCluster = NULL;
|
gCtgMgmt.pCluster = NULL;
|
||||||
|
|
|
@ -273,8 +273,7 @@ SResultRow* doSetResultOutBufByKey(SDiskbasedBuf* pResultBuf, SResultRowInfo* pR
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1. close current opened time window
|
// 1. close current opened time window
|
||||||
if (pResultRowInfo->cur.pageId != -1 && ((pResult == NULL) || (pResult->pageId != pResultRowInfo->cur.pageId &&
|
if (pResultRowInfo->cur.pageId != -1 && ((pResult == NULL) || (pResult->pageId != pResultRowInfo->cur.pageId))) {
|
||||||
pResult->offset != pResultRowInfo->cur.offset))) {
|
|
||||||
SResultRowPosition pos = pResultRowInfo->cur;
|
SResultRowPosition pos = pResultRowInfo->cur;
|
||||||
SFilePage* pPage = getBufPage(pResultBuf, pos.pageId);
|
SFilePage* pPage = getBufPage(pResultBuf, pos.pageId);
|
||||||
releaseBufPage(pResultBuf, pPage);
|
releaseBufPage(pResultBuf, pPage);
|
||||||
|
|
|
@ -1600,13 +1600,11 @@ static SSDataBlock* doSysTableScan(SOperatorInfo* pOperator) {
|
||||||
strncpy(pInfo->req.tb, tNameGetTableName(&pInfo->name), tListLen(pInfo->req.tb));
|
strncpy(pInfo->req.tb, tNameGetTableName(&pInfo->name), tListLen(pInfo->req.tb));
|
||||||
strcpy(pInfo->req.user, pInfo->pUser);
|
strcpy(pInfo->req.user, pInfo->pUser);
|
||||||
|
|
||||||
/*
|
|
||||||
if (pInfo->showRewrite) {
|
if (pInfo->showRewrite) {
|
||||||
char dbName[TSDB_DB_NAME_LEN] = {0};
|
char dbName[TSDB_DB_NAME_LEN] = {0};
|
||||||
getDBNameFromCondition(pInfo->pCondition, dbName);
|
getDBNameFromCondition(pInfo->pCondition, dbName);
|
||||||
sprintf(pInfo->req.db, "%d.%s", pInfo->accountId, dbName);
|
sprintf(pInfo->req.db, "%d.%s", pInfo->accountId, dbName);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
int32_t contLen = tSerializeSRetrieveTableReq(NULL, 0, &pInfo->req);
|
int32_t contLen = tSerializeSRetrieveTableReq(NULL, 0, &pInfo->req);
|
||||||
char* buf1 = taosMemoryCalloc(1, contLen);
|
char* buf1 = taosMemoryCalloc(1, contLen);
|
||||||
|
|
|
@ -191,6 +191,11 @@ bool getUniqueFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
|
||||||
bool uniqueFunctionSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo);
|
bool uniqueFunctionSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo);
|
||||||
int32_t uniqueFunction(SqlFunctionCtx *pCtx);
|
int32_t uniqueFunction(SqlFunctionCtx *pCtx);
|
||||||
|
|
||||||
|
bool getModeFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
|
||||||
|
bool modeFunctionSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo);
|
||||||
|
int32_t modeFunction(SqlFunctionCtx *pCtx);
|
||||||
|
int32_t modeFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock);
|
||||||
|
|
||||||
bool getTwaFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
|
bool getTwaFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
|
||||||
bool twaFunctionSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo);
|
bool twaFunctionSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo);
|
||||||
int32_t twaFunction(SqlFunctionCtx *pCtx);
|
int32_t twaFunction(SqlFunctionCtx *pCtx);
|
||||||
|
|
|
@ -1045,20 +1045,29 @@ static int32_t translateFirstLastMerge(SFunctionNode* pFunc, char* pErrBuf, int3
|
||||||
return translateFirstLastImpl(pFunc, pErrBuf, len, false);
|
return translateFirstLastImpl(pFunc, pErrBuf, len, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t translateUnique(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
static int32_t translateUniqueMode(SFunctionNode* pFunc, char* pErrBuf, int32_t len, bool isUnique) {
|
||||||
if (1 != LIST_LENGTH(pFunc->pParameterList)) {
|
if (1 != LIST_LENGTH(pFunc->pParameterList)) {
|
||||||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
SNode* pPara = nodesListGetNode(pFunc->pParameterList, 0);
|
SNode* pPara = nodesListGetNode(pFunc->pParameterList, 0);
|
||||||
if (!nodesExprHasColumn(pPara)) {
|
if (!nodesExprHasColumn(pPara)) {
|
||||||
return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR, "The parameters of UNIQUE must contain columns");
|
return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR, "The parameters of %s must contain columns",
|
||||||
|
isUnique ? "UNIQUE" : "MODE");
|
||||||
}
|
}
|
||||||
|
|
||||||
pFunc->node.resType = ((SExprNode*)pPara)->resType;
|
pFunc->node.resType = ((SExprNode*)pPara)->resType;
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t translateUnique(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||||
|
return translateUniqueMode(pFunc, pErrBuf, len, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t translateMode(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||||
|
return translateUniqueMode(pFunc, pErrBuf, len, false);
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t translateDiff(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
static int32_t translateDiff(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||||
int32_t numOfParams = LIST_LENGTH(pFunc->pParameterList);
|
int32_t numOfParams = LIST_LENGTH(pFunc->pParameterList);
|
||||||
if (numOfParams == 0 || numOfParams > 2) {
|
if (numOfParams == 0 || numOfParams > 2) {
|
||||||
|
@ -1882,7 +1891,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||||
{
|
{
|
||||||
.name = "first",
|
.name = "first",
|
||||||
.type = FUNCTION_TYPE_FIRST,
|
.type = FUNCTION_TYPE_FIRST,
|
||||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_MULTI_RES_FUNC | FUNC_MGT_TIMELINE_FUNC,
|
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_MULTI_RES_FUNC | FUNC_MGT_TIMELINE_FUNC,
|
||||||
.translateFunc = translateFirstLast,
|
.translateFunc = translateFirstLast,
|
||||||
.getEnvFunc = getFirstLastFuncEnv,
|
.getEnvFunc = getFirstLastFuncEnv,
|
||||||
.initFunc = functionSetup,
|
.initFunc = functionSetup,
|
||||||
|
@ -1917,7 +1926,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||||
{
|
{
|
||||||
.name = "last",
|
.name = "last",
|
||||||
.type = FUNCTION_TYPE_LAST,
|
.type = FUNCTION_TYPE_LAST,
|
||||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_MULTI_RES_FUNC | FUNC_MGT_TIMELINE_FUNC,
|
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_MULTI_RES_FUNC | FUNC_MGT_TIMELINE_FUNC,
|
||||||
.translateFunc = translateFirstLast,
|
.translateFunc = translateFirstLast,
|
||||||
.getEnvFunc = getFirstLastFuncEnv,
|
.getEnvFunc = getFirstLastFuncEnv,
|
||||||
.initFunc = functionSetup,
|
.initFunc = functionSetup,
|
||||||
|
@ -2109,7 +2118,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||||
{
|
{
|
||||||
.name = "unique",
|
.name = "unique",
|
||||||
.type = FUNCTION_TYPE_UNIQUE,
|
.type = FUNCTION_TYPE_UNIQUE,
|
||||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_INDEFINITE_ROWS_FUNC | FUNC_MGT_TIMELINE_FUNC |
|
.classification = FUNC_MGT_SELECT_FUNC | FUNC_MGT_INDEFINITE_ROWS_FUNC | FUNC_MGT_TIMELINE_FUNC |
|
||||||
FUNC_MGT_FORBID_STREAM_FUNC | FUNC_MGT_FORBID_WINDOW_FUNC | FUNC_MGT_FORBID_GROUP_BY_FUNC,
|
FUNC_MGT_FORBID_STREAM_FUNC | FUNC_MGT_FORBID_WINDOW_FUNC | FUNC_MGT_FORBID_GROUP_BY_FUNC,
|
||||||
.translateFunc = translateUnique,
|
.translateFunc = translateUnique,
|
||||||
.getEnvFunc = getUniqueFuncEnv,
|
.getEnvFunc = getUniqueFuncEnv,
|
||||||
|
@ -2117,6 +2126,16 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||||
.processFunc = uniqueFunction,
|
.processFunc = uniqueFunction,
|
||||||
.finalizeFunc = NULL
|
.finalizeFunc = NULL
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.name = "mode",
|
||||||
|
.type = FUNCTION_TYPE_MODE,
|
||||||
|
.classification = FUNC_MGT_AGG_FUNC,
|
||||||
|
.translateFunc = translateMode,
|
||||||
|
.getEnvFunc = getModeFuncEnv,
|
||||||
|
.initFunc = modeFunctionSetup,
|
||||||
|
.processFunc = modeFunction,
|
||||||
|
.finalizeFunc = modeFinalize,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
.name = "abs",
|
.name = "abs",
|
||||||
.type = FUNCTION_TYPE_ABS,
|
.type = FUNCTION_TYPE_ABS,
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#define TAIL_MAX_OFFSET 100
|
#define TAIL_MAX_OFFSET 100
|
||||||
|
|
||||||
#define UNIQUE_MAX_RESULT_SIZE (1024 * 1024 * 10)
|
#define UNIQUE_MAX_RESULT_SIZE (1024 * 1024 * 10)
|
||||||
|
#define MODE_MAX_RESULT_SIZE UNIQUE_MAX_RESULT_SIZE
|
||||||
|
|
||||||
#define HLL_BUCKET_BITS 14 // The bits of the bucket
|
#define HLL_BUCKET_BITS 14 // The bits of the bucket
|
||||||
#define HLL_DATA_BITS (64 - HLL_BUCKET_BITS)
|
#define HLL_DATA_BITS (64 - HLL_BUCKET_BITS)
|
||||||
|
@ -246,6 +247,19 @@ typedef struct SUniqueInfo {
|
||||||
char pItems[];
|
char pItems[];
|
||||||
} SUniqueInfo;
|
} SUniqueInfo;
|
||||||
|
|
||||||
|
typedef struct SModeItem {
|
||||||
|
int64_t count;
|
||||||
|
char data[];
|
||||||
|
} SModeItem;
|
||||||
|
|
||||||
|
typedef struct SModeInfo {
|
||||||
|
int32_t numOfPoints;
|
||||||
|
uint8_t colType;
|
||||||
|
int16_t colBytes;
|
||||||
|
SHashObj* pHash;
|
||||||
|
char pItems[];
|
||||||
|
} SModeInfo;
|
||||||
|
|
||||||
typedef struct SDerivInfo {
|
typedef struct SDerivInfo {
|
||||||
double prevValue; // previous value
|
double prevValue; // previous value
|
||||||
TSKEY prevTs; // previous timestamp
|
TSKEY prevTs; // previous timestamp
|
||||||
|
@ -4694,21 +4708,100 @@ int32_t uniqueFunction(SqlFunctionCtx* pCtx) {
|
||||||
return pInfo->numOfPoints;
|
return pInfo->numOfPoints;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t uniqueFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
bool getModeFuncEnv(SFunctionNode* pFunc, SFuncExecEnv* pEnv) {
|
||||||
|
pEnv->calcMemSize = sizeof(SModeInfo) + MODE_MAX_RESULT_SIZE;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool modeFunctionSetup(SqlFunctionCtx* pCtx, SResultRowEntryInfo* pResInfo) {
|
||||||
|
if (!functionSetup(pCtx, pResInfo)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SModeInfo* pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||||
|
pInfo->numOfPoints = 0;
|
||||||
|
pInfo->colType = pCtx->resDataInfo.type;
|
||||||
|
pInfo->colBytes = pCtx->resDataInfo.bytes;
|
||||||
|
if (pInfo->pHash != NULL) {
|
||||||
|
taosHashClear(pInfo->pHash);
|
||||||
|
} else {
|
||||||
|
pInfo->pHash = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void doModeAdd(SModeInfo* pInfo, char* data, bool isNull) {
|
||||||
|
// ignore null elements
|
||||||
|
if (isNull) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t hashKeyBytes = IS_VAR_DATA_TYPE(pInfo->colType) ? varDataTLen(data) : pInfo->colBytes;
|
||||||
|
SModeItem** pHashItem = taosHashGet(pInfo->pHash, data, hashKeyBytes);
|
||||||
|
if (pHashItem == NULL) {
|
||||||
|
int32_t size = sizeof(SModeItem) + pInfo->colBytes;
|
||||||
|
SModeItem* pItem = (SModeItem*)(pInfo->pItems + pInfo->numOfPoints * size);
|
||||||
|
memcpy(pItem->data, data, pInfo->colBytes);
|
||||||
|
pItem->count += 1;
|
||||||
|
|
||||||
|
taosHashPut(pInfo->pHash, data, hashKeyBytes, &pItem, sizeof(SModeItem*));
|
||||||
|
pInfo->numOfPoints++;
|
||||||
|
} else {
|
||||||
|
(*pHashItem)->count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t modeFunction(SqlFunctionCtx* pCtx) {
|
||||||
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
|
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
|
||||||
SUniqueInfo* pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
SModeInfo* pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||||
|
|
||||||
|
SInputColumnInfoData* pInput = &pCtx->input;
|
||||||
|
|
||||||
|
SColumnInfoData* pInputCol = pInput->pData[0];
|
||||||
|
SColumnInfoData* pOutput = (SColumnInfoData*)pCtx->pOutput;
|
||||||
|
|
||||||
|
int32_t startOffset = pCtx->offset;
|
||||||
|
for (int32_t i = pInput->startRowIndex; i < pInput->numOfRows + pInput->startRowIndex; ++i) {
|
||||||
|
char* data = colDataGetData(pInputCol, i);
|
||||||
|
doModeAdd(pInfo, data, colDataIsNull_s(pInputCol, i));
|
||||||
|
|
||||||
|
if (sizeof(SModeInfo) + pInfo->numOfPoints * (sizeof(SModeItem) + pInfo->colBytes) >= MODE_MAX_RESULT_SIZE) {
|
||||||
|
taosHashCleanup(pInfo->pHash);
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SET_VAL(pResInfo, 1, 1);
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t modeFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||||
|
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
|
||||||
|
SModeInfo* pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||||
int32_t slotId = pCtx->pExpr->base.resSchema.slotId;
|
int32_t slotId = pCtx->pExpr->base.resSchema.slotId;
|
||||||
SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, slotId);
|
SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, slotId);
|
||||||
|
int32_t currentRow = pBlock->info.rows;
|
||||||
|
|
||||||
for (int32_t i = 0; i < pResInfo->numOfRes; ++i) {
|
int32_t resIndex;
|
||||||
SUniqueItem* pItem = (SUniqueItem*)(pInfo->pItems + i * (sizeof(SUniqueItem) + pInfo->colBytes));
|
int32_t maxCount = 0;
|
||||||
colDataAppend(pCol, i, pItem->data, false);
|
for (int32_t i = 0; i < pInfo->numOfPoints; ++i) {
|
||||||
// TODO: handle ts output
|
SModeItem* pItem = (SModeItem*)(pInfo->pItems + i * (sizeof(SModeItem) + pInfo->colBytes));
|
||||||
|
if (pItem->count > maxCount) {
|
||||||
|
maxCount = pItem->count;
|
||||||
|
resIndex = i;
|
||||||
|
} else if (pItem->count == maxCount) {
|
||||||
|
resIndex = -1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SModeItem* pResItem = (SModeItem*)(pInfo->pItems + resIndex * (sizeof(SModeItem) + pInfo->colBytes));
|
||||||
|
colDataAppend(pCol, currentRow, pResItem->data, (resIndex == -1) ? true : false);
|
||||||
|
|
||||||
return pResInfo->numOfRes;
|
return pResInfo->numOfRes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool getTwaFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv) {
|
bool getTwaFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv) {
|
||||||
pEnv->calcMemSize = sizeof(STwaInfo);
|
pEnv->calcMemSize = sizeof(STwaInfo);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -2,12 +2,8 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "tudf.h"
|
#include "taosudf.h"
|
||||||
|
|
||||||
#undef malloc
|
|
||||||
#define malloc malloc
|
|
||||||
#undef free
|
|
||||||
#define free free
|
|
||||||
|
|
||||||
DLL_EXPORT int32_t udf1_init() {
|
DLL_EXPORT int32_t udf1_init() {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -1,13 +1,9 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
#include "tudf.h"
|
#include "taosudf.h"
|
||||||
|
|
||||||
#undef malloc
|
|
||||||
#define malloc malloc
|
|
||||||
#undef free
|
|
||||||
#define free free
|
|
||||||
|
|
||||||
DLL_EXPORT int32_t udf2_init() {
|
DLL_EXPORT int32_t udf2_init() {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -100,6 +100,7 @@ static int32_t exprNodeCopy(const SExprNode* pSrc, SExprNode* pDst) {
|
||||||
COPY_OBJECT_FIELD(resType, sizeof(SDataType));
|
COPY_OBJECT_FIELD(resType, sizeof(SDataType));
|
||||||
COPY_CHAR_ARRAY_FIELD(aliasName);
|
COPY_CHAR_ARRAY_FIELD(aliasName);
|
||||||
COPY_CHAR_ARRAY_FIELD(userAlias);
|
COPY_CHAR_ARRAY_FIELD(userAlias);
|
||||||
|
COPY_SCALAR_FIELD(orderAlias);
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1500,7 +1500,8 @@ typedef struct SCollectFuncsCxt {
|
||||||
|
|
||||||
static EDealRes collectFuncs(SNode* pNode, void* pContext) {
|
static EDealRes collectFuncs(SNode* pNode, void* pContext) {
|
||||||
SCollectFuncsCxt* pCxt = (SCollectFuncsCxt*)pContext;
|
SCollectFuncsCxt* pCxt = (SCollectFuncsCxt*)pContext;
|
||||||
if (QUERY_NODE_FUNCTION == nodeType(pNode) && pCxt->classifier(((SFunctionNode*)pNode)->funcId)) {
|
if (QUERY_NODE_FUNCTION == nodeType(pNode) && pCxt->classifier(((SFunctionNode*)pNode)->funcId) &&
|
||||||
|
!(((SExprNode*)pNode)->orderAlias)) {
|
||||||
pCxt->errCode = nodesListStrictAppend(pCxt->pFuncs, nodesCloneNode(pNode));
|
pCxt->errCode = nodesListStrictAppend(pCxt->pFuncs, nodesCloneNode(pNode));
|
||||||
return (TSDB_CODE_SUCCESS == pCxt->errCode ? DEAL_RES_IGNORE_CHILD : DEAL_RES_ERROR);
|
return (TSDB_CODE_SUCCESS == pCxt->errCode ? DEAL_RES_IGNORE_CHILD : DEAL_RES_ERROR);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1355,25 +1355,6 @@ static EDealRes rewriteColToSelectValFunc(STranslateContext* pCxt, SNode** pNode
|
||||||
return TSDB_CODE_SUCCESS == pCxt->errCode ? DEAL_RES_IGNORE_CHILD : DEAL_RES_ERROR;
|
return TSDB_CODE_SUCCESS == pCxt->errCode ? DEAL_RES_IGNORE_CHILD : DEAL_RES_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static EDealRes rewriteExprToGroupKeyFunc(STranslateContext* pCxt, SNode** pNode) {
|
|
||||||
SFunctionNode* pFunc = (SFunctionNode*)nodesMakeNode(QUERY_NODE_FUNCTION);
|
|
||||||
if (NULL == pFunc) {
|
|
||||||
pCxt->errCode = TSDB_CODE_OUT_OF_MEMORY;
|
|
||||||
return DEAL_RES_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
strcpy(pFunc->functionName, "_group_key");
|
|
||||||
strcpy(pFunc->node.aliasName, ((SExprNode*)*pNode)->aliasName);
|
|
||||||
pCxt->errCode = nodesListMakeAppend(&pFunc->pParameterList, *pNode);
|
|
||||||
if (TSDB_CODE_SUCCESS == pCxt->errCode) {
|
|
||||||
*pNode = (SNode*)pFunc;
|
|
||||||
pCxt->errCode = fmGetFuncInfo(pFunc, pCxt->msgBuf.buf, pCxt->msgBuf.len);
|
|
||||||
}
|
|
||||||
pCxt->pCurrSelectStmt->hasAggFuncs = true;
|
|
||||||
|
|
||||||
return (TSDB_CODE_SUCCESS == pCxt->errCode ? DEAL_RES_IGNORE_CHILD : DEAL_RES_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
static EDealRes doCheckExprForGroupBy(SNode** pNode, void* pContext) {
|
static EDealRes doCheckExprForGroupBy(SNode** pNode, void* pContext) {
|
||||||
SCheckExprForGroupByCxt* pCxt = (SCheckExprForGroupByCxt*)pContext;
|
SCheckExprForGroupByCxt* pCxt = (SCheckExprForGroupByCxt*)pContext;
|
||||||
if (!nodesIsExprNode(*pNode) || isAliasColumn(*pNode)) {
|
if (!nodesIsExprNode(*pNode) || isAliasColumn(*pNode)) {
|
||||||
|
@ -1393,7 +1374,13 @@ static EDealRes doCheckExprForGroupBy(SNode** pNode, void* pContext) {
|
||||||
SNode* pGroupNode = NULL;
|
SNode* pGroupNode = NULL;
|
||||||
FOREACH(pGroupNode, getGroupByList(pCxt->pTranslateCxt)) {
|
FOREACH(pGroupNode, getGroupByList(pCxt->pTranslateCxt)) {
|
||||||
if (nodesEqualNode(getGroupByNode(pGroupNode), *pNode)) {
|
if (nodesEqualNode(getGroupByNode(pGroupNode), *pNode)) {
|
||||||
return rewriteExprToGroupKeyFunc(pCxt->pTranslateCxt, pNode);
|
return DEAL_RES_IGNORE_CHILD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SNode* pPartKey = NULL;
|
||||||
|
FOREACH(pPartKey, pCxt->pTranslateCxt->pCurrSelectStmt->pPartitionByList) {
|
||||||
|
if (nodesEqualNode(pPartKey, *pNode)) {
|
||||||
|
return DEAL_RES_IGNORE_CHILD;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isScanPseudoColumnFunc(*pNode) || QUERY_NODE_COLUMN == nodeType(*pNode)) {
|
if (isScanPseudoColumnFunc(*pNode) || QUERY_NODE_COLUMN == nodeType(*pNode)) {
|
||||||
|
@ -1451,25 +1438,6 @@ static int32_t rewriteColsToSelectValFunc(STranslateContext* pCxt, SSelectStmt*
|
||||||
return pCxt->errCode;
|
return pCxt->errCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
static EDealRes rewriteExprsToGroupKeyFuncImpl(SNode** pNode, void* pContext) {
|
|
||||||
STranslateContext* pCxt = pContext;
|
|
||||||
SNode* pPartKey = NULL;
|
|
||||||
FOREACH(pPartKey, pCxt->pCurrSelectStmt->pPartitionByList) {
|
|
||||||
if (nodesEqualNode(pPartKey, *pNode)) {
|
|
||||||
return rewriteExprToGroupKeyFunc(pCxt, pNode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return DEAL_RES_CONTINUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t rewriteExprsToGroupKeyFunc(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
|
||||||
nodesRewriteExprs(pSelect->pProjectionList, rewriteExprsToGroupKeyFuncImpl, pCxt);
|
|
||||||
if (TSDB_CODE_SUCCESS == pCxt->errCode && !pSelect->isDistinct) {
|
|
||||||
nodesRewriteExprs(pSelect->pOrderByList, rewriteExprsToGroupKeyFuncImpl, pCxt);
|
|
||||||
}
|
|
||||||
return pCxt->errCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct CheckAggColCoexistCxt {
|
typedef struct CheckAggColCoexistCxt {
|
||||||
STranslateContext* pTranslateCxt;
|
STranslateContext* pTranslateCxt;
|
||||||
bool existAggFunc;
|
bool existAggFunc;
|
||||||
|
@ -1529,9 +1497,6 @@ static int32_t checkAggColCoexist(STranslateContext* pCxt, SSelectStmt* pSelect)
|
||||||
if (cxt.existIndefiniteRowsFunc && cxt.existCol) {
|
if (cxt.existIndefiniteRowsFunc && cxt.existCol) {
|
||||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC);
|
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC);
|
||||||
}
|
}
|
||||||
if (cxt.existAggFunc && NULL != pSelect->pPartitionByList) {
|
|
||||||
return rewriteExprsToGroupKeyFunc(pCxt, pSelect);
|
|
||||||
}
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2408,54 +2373,6 @@ static EDealRes rewriteSeletcValueFunc(STranslateContext* pCxt, SNode** pNode) {
|
||||||
return TSDB_CODE_SUCCESS == pCxt->errCode ? DEAL_RES_IGNORE_CHILD : DEAL_RES_ERROR;
|
return TSDB_CODE_SUCCESS == pCxt->errCode ? DEAL_RES_IGNORE_CHILD : DEAL_RES_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static EDealRes rewriteUniqueFunc(SNode** pNode, void* pContext) {
|
|
||||||
SRwriteUniqueCxt* pCxt = pContext;
|
|
||||||
if (QUERY_NODE_FUNCTION == nodeType(*pNode)) {
|
|
||||||
SFunctionNode* pFunc = (SFunctionNode*)*pNode;
|
|
||||||
if (FUNCTION_TYPE_UNIQUE == pFunc->funcType) {
|
|
||||||
SNode* pExpr = nodesListGetNode(pFunc->pParameterList, 0);
|
|
||||||
NODES_CLEAR_LIST(pFunc->pParameterList);
|
|
||||||
strcpy(((SExprNode*)pExpr)->aliasName, ((SExprNode*)*pNode)->aliasName);
|
|
||||||
nodesDestroyNode(*pNode);
|
|
||||||
*pNode = pExpr;
|
|
||||||
pCxt->pExpr = pExpr;
|
|
||||||
return DEAL_RES_IGNORE_CHILD;
|
|
||||||
} else if (FUNCTION_TYPE_SELECT_VALUE == pFunc->funcType) {
|
|
||||||
return rewriteSeletcValueFunc(pCxt->pTranslateCxt, pNode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return DEAL_RES_CONTINUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static SNode* createGroupingSet(SNode* pExpr) {
|
|
||||||
SGroupingSetNode* pGroupingSet = (SGroupingSetNode*)nodesMakeNode(QUERY_NODE_GROUPING_SET);
|
|
||||||
if (NULL == pGroupingSet) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
pGroupingSet->groupingSetType = GP_TYPE_NORMAL;
|
|
||||||
if (TSDB_CODE_SUCCESS != nodesListMakeStrictAppend(&pGroupingSet->pParameterList, nodesCloneNode(pExpr))) {
|
|
||||||
nodesDestroyNode((SNode*)pGroupingSet);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return (SNode*)pGroupingSet;
|
|
||||||
}
|
|
||||||
|
|
||||||
// from: select unique(expr), col1 + col2 from t where_clause partition_by_clause order_by_clause ...
|
|
||||||
// to: select expr, first(col1) + first(col2) from t where_clause partition_by_clause group by expr order_by_clause ...
|
|
||||||
static int32_t rewriteUniqueStmt(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
|
||||||
if (!pSelect->hasUniqueFunc) {
|
|
||||||
return TSDB_CODE_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
SRwriteUniqueCxt cxt = {.pTranslateCxt = pCxt, .pExpr = NULL};
|
|
||||||
nodesRewriteExprs(pSelect->pProjectionList, rewriteUniqueFunc, &cxt);
|
|
||||||
if (TSDB_CODE_SUCCESS == cxt.pTranslateCxt->errCode) {
|
|
||||||
cxt.pTranslateCxt->errCode = nodesListMakeStrictAppend(&pSelect->pGroupByList, createGroupingSet(cxt.pExpr));
|
|
||||||
}
|
|
||||||
pSelect->hasIndefiniteRowsFunc = false;
|
|
||||||
return cxt.pTranslateCxt->errCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct SReplaceOrderByAliasCxt {
|
typedef struct SReplaceOrderByAliasCxt {
|
||||||
STranslateContext* pTranslateCxt;
|
STranslateContext* pTranslateCxt;
|
||||||
SNodeList* pProjectionList;
|
SNodeList* pProjectionList;
|
||||||
|
@ -2474,6 +2391,7 @@ static EDealRes replaceOrderByAliasImpl(SNode** pNode, void* pContext) {
|
||||||
pCxt->pTranslateCxt->errCode = TSDB_CODE_OUT_OF_MEMORY;
|
pCxt->pTranslateCxt->errCode = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
return DEAL_RES_ERROR;
|
return DEAL_RES_ERROR;
|
||||||
}
|
}
|
||||||
|
((SExprNode*)pNew)->orderAlias = true;
|
||||||
nodesDestroyNode(*pNode);
|
nodesDestroyNode(*pNode);
|
||||||
*pNode = pNew;
|
*pNode = pNew;
|
||||||
return DEAL_RES_CONTINUE;
|
return DEAL_RES_CONTINUE;
|
||||||
|
@ -2529,9 +2447,6 @@ static int32_t translateSelectFrom(STranslateContext* pCxt, SSelectStmt* pSelect
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = translateInterp(pCxt, pSelect);
|
code = translateInterp(pCxt, pSelect);
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
|
||||||
code = rewriteUniqueStmt(pCxt, pSelect);
|
|
||||||
}
|
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = rewriteTimelineFunc(pCxt, pSelect);
|
code = rewriteTimelineFunc(pCxt, pSelect);
|
||||||
}
|
}
|
||||||
|
|
|
@ -232,8 +232,6 @@ TEST_F(ParserSelectTest, groupBySemanticCheck) {
|
||||||
|
|
||||||
run("SELECT COUNT(*) cnt, c1 FROM t1 WHERE c1 > 0", TSDB_CODE_PAR_NOT_SINGLE_GROUP);
|
run("SELECT COUNT(*) cnt, c1 FROM t1 WHERE c1 > 0", TSDB_CODE_PAR_NOT_SINGLE_GROUP);
|
||||||
run("SELECT COUNT(*) cnt, c2 FROM t1 WHERE c1 > 0 GROUP BY c1", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION);
|
run("SELECT COUNT(*) cnt, c2 FROM t1 WHERE c1 > 0 GROUP BY c1", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION);
|
||||||
run("SELECT COUNT(*) cnt, c2 FROM t1 WHERE c1 > 0 PARTITION BY c2 GROUP BY c1",
|
|
||||||
TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserSelectTest, orderBy) {
|
TEST_F(ParserSelectTest, orderBy) {
|
||||||
|
|
|
@ -437,6 +437,33 @@ static SColumnNode* createColumnByExpr(const char* pStmtName, SExprNode* pExpr)
|
||||||
return pCol;
|
return pCol;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SNode* createGroupingSetNode(SNode* pExpr) {
|
||||||
|
SGroupingSetNode* pGroupingSet = (SGroupingSetNode*)nodesMakeNode(QUERY_NODE_GROUPING_SET);
|
||||||
|
if (NULL == pGroupingSet) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
pGroupingSet->groupingSetType = GP_TYPE_NORMAL;
|
||||||
|
if (TSDB_CODE_SUCCESS != nodesListMakeStrictAppend(&pGroupingSet->pParameterList, nodesCloneNode(pExpr))) {
|
||||||
|
nodesDestroyNode((SNode*)pGroupingSet);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return (SNode*)pGroupingSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t createGroupKeysFromPartKeys(SNodeList* pPartKeys, SNodeList** pOutput) {
|
||||||
|
SNodeList* pGroupKeys = NULL;
|
||||||
|
SNode* pPartKey = NULL;
|
||||||
|
FOREACH(pPartKey, pPartKeys) {
|
||||||
|
int32_t code = nodesListMakeStrictAppend(&pGroupKeys, createGroupingSetNode(pPartKey));
|
||||||
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
|
nodesDestroyList(pGroupKeys);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*pOutput = pGroupKeys;
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t createAggLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) {
|
static int32_t createAggLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) {
|
||||||
if (!pSelect->hasAggFuncs && NULL == pSelect->pGroupByList) {
|
if (!pSelect->hasAggFuncs && NULL == pSelect->pGroupByList) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
@ -459,12 +486,20 @@ static int32_t createAggLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect,
|
||||||
code = rewriteExprsForSelect(pAgg->pAggFuncs, pSelect, SQL_CLAUSE_GROUP_BY);
|
code = rewriteExprsForSelect(pAgg->pAggFuncs, pSelect, SQL_CLAUSE_GROUP_BY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (NULL != pSelect->pPartitionByList) {
|
||||||
|
code = createGroupKeysFromPartKeys(pSelect->pPartitionByList, &pAgg->pGroupKeys);
|
||||||
|
}
|
||||||
|
|
||||||
if (NULL != pSelect->pGroupByList) {
|
if (NULL != pSelect->pGroupByList) {
|
||||||
|
if (NULL != pAgg->pGroupKeys) {
|
||||||
|
code = nodesListStrictAppendList(pAgg->pGroupKeys, nodesCloneList(pSelect->pGroupByList));
|
||||||
|
} else {
|
||||||
pAgg->pGroupKeys = nodesCloneList(pSelect->pGroupByList);
|
pAgg->pGroupKeys = nodesCloneList(pSelect->pGroupByList);
|
||||||
if (NULL == pAgg->pGroupKeys) {
|
if (NULL == pAgg->pGroupKeys) {
|
||||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// rewrite the expression in subsequent clauses
|
// rewrite the expression in subsequent clauses
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
@ -508,6 +543,7 @@ static int32_t createIndefRowsFuncLogicNode(SLogicPlanContext* pCxt, SSelectStmt
|
||||||
}
|
}
|
||||||
|
|
||||||
pIdfRowsFunc->isTailFunc = pSelect->hasTailFunc;
|
pIdfRowsFunc->isTailFunc = pSelect->hasTailFunc;
|
||||||
|
pIdfRowsFunc->isUniqueFunc = pSelect->hasUniqueFunc;
|
||||||
|
|
||||||
// indefinite rows functions and _select_values functions
|
// indefinite rows functions and _select_values functions
|
||||||
int32_t code = nodesCollectFuncs(pSelect, SQL_CLAUSE_SELECT, fmIsVectorFunc, &pIdfRowsFunc->pFuncs);
|
int32_t code = nodesCollectFuncs(pSelect, SQL_CLAUSE_SELECT, fmIsVectorFunc, &pIdfRowsFunc->pFuncs);
|
||||||
|
@ -809,7 +845,8 @@ static int32_t createProjectLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSel
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t createPartitionLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) {
|
static int32_t createPartitionLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) {
|
||||||
if (NULL == pSelect->pPartitionByList) {
|
if (NULL == pSelect->pPartitionByList || (pSelect->hasAggFuncs && NULL == pSelect->pWindow) ||
|
||||||
|
NULL != pSelect->pGroupByList) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -987,6 +987,7 @@ static int32_t smaIndexOptimizeImpl(SOptimizeContext* pCxt, SLogicSubplan* pLogi
|
||||||
code = smaIndexOptApplyIndex(pLogicSubplan, pScan, pIndex, pSmaCols, wstrartIndex);
|
code = smaIndexOptApplyIndex(pLogicSubplan, pScan, pIndex, pSmaCols, wstrartIndex);
|
||||||
taosArrayDestroyEx(pScan->pSmaIndexes, smaIndexOptDestroySmaIndex);
|
taosArrayDestroyEx(pScan->pSmaIndexes, smaIndexOptDestroySmaIndex);
|
||||||
pScan->pSmaIndexes = NULL;
|
pScan->pSmaIndexes = NULL;
|
||||||
|
pCxt->optimized = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1033,12 +1034,30 @@ static SNodeList* partTagsGetPartKeys(SLogicNode* pNode) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SNodeList* partTagsGetFuncs(SLogicNode* pNode) {
|
||||||
|
if (QUERY_NODE_LOGIC_PLAN_PARTITION == nodeType(pNode)) {
|
||||||
|
return NULL;
|
||||||
|
} else {
|
||||||
|
return ((SAggLogicNode*)pNode)->pAggFuncs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool partTagsOptAreSupportedFuncs(SNodeList* pFuncs) {
|
||||||
|
SNode* pFunc = NULL;
|
||||||
|
FOREACH(pFunc, pFuncs) {
|
||||||
|
if (fmIsIndefiniteRowsFunc(((SFunctionNode*)pFunc)->funcId) && !fmIsSelectFunc(((SFunctionNode*)pFunc)->funcId)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool partTagsOptMayBeOptimized(SLogicNode* pNode) {
|
static bool partTagsOptMayBeOptimized(SLogicNode* pNode) {
|
||||||
if (!partTagsIsOptimizableNode(pNode)) {
|
if (!partTagsIsOptimizableNode(pNode)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return !partTagsOptHasCol(partTagsGetPartKeys(pNode));
|
return !partTagsOptHasCol(partTagsGetPartKeys(pNode)) && partTagsOptAreSupportedFuncs(partTagsGetFuncs(pNode));
|
||||||
}
|
}
|
||||||
|
|
||||||
static EDealRes partTagsOptRebuildTbanmeImpl(SNode** pNode, void* pContext) {
|
static EDealRes partTagsOptRebuildTbanmeImpl(SNode** pNode, void* pContext) {
|
||||||
|
@ -1064,6 +1083,59 @@ static int32_t partTagsOptRebuildTbanme(SNodeList* pPartKeys) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SNode* partTagsCreateWrapperFunc(const char* pFuncName, SNode* pNode) {
|
||||||
|
SFunctionNode* pFunc = (SFunctionNode*)nodesMakeNode(QUERY_NODE_FUNCTION);
|
||||||
|
if (NULL == pFunc) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(pFunc->functionName, pFuncName);
|
||||||
|
if (QUERY_NODE_COLUMN == nodeType(pNode)) {
|
||||||
|
SColumnNode* pCol = (SColumnNode*)pNode;
|
||||||
|
sprintf(pFunc->node.aliasName, "%s.%s", pCol->tableAlias, pCol->colName);
|
||||||
|
} else {
|
||||||
|
strcpy(pFunc->node.aliasName, ((SExprNode*)pNode)->aliasName);
|
||||||
|
}
|
||||||
|
int32_t code = nodesListMakeStrictAppend(&pFunc->pParameterList, nodesCloneNode(pNode));
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = fmGetFuncInfo(pFunc, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
|
nodesDestroyNode((SNode*)pFunc);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (SNode*)pFunc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool partTagsHasIndefRowsSelectFunc(SNodeList* pFuncs) {
|
||||||
|
SNode* pFunc = NULL;
|
||||||
|
FOREACH(pFunc, pFuncs) {
|
||||||
|
if (fmIsIndefiniteRowsFunc(((SFunctionNode*)pFunc)->funcId)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t partTagsRewriteGroupTagsToFuncs(SNodeList* pGroupTags, SNodeList* pAggFuncs) {
|
||||||
|
bool hasIndefRowsSelectFunc = partTagsHasIndefRowsSelectFunc(pAggFuncs);
|
||||||
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
SNode* pNode = NULL;
|
||||||
|
FOREACH(pNode, pGroupTags) {
|
||||||
|
if (hasIndefRowsSelectFunc) {
|
||||||
|
code = nodesListStrictAppend(pAggFuncs, partTagsCreateWrapperFunc("_select_value", pNode));
|
||||||
|
} else {
|
||||||
|
code = nodesListStrictAppend(pAggFuncs, partTagsCreateWrapperFunc("_group_key", pNode));
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t partTagsOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan) {
|
static int32_t partTagsOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan) {
|
||||||
SLogicNode* pNode = optFindPossibleNode(pLogicSubplan->pNode, partTagsOptMayBeOptimized);
|
SLogicNode* pNode = optFindPossibleNode(pLogicSubplan->pNode, partTagsOptMayBeOptimized);
|
||||||
if (NULL == pNode) {
|
if (NULL == pNode) {
|
||||||
|
@ -1080,15 +1152,17 @@ static int32_t partTagsOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSub
|
||||||
nodesDestroyNode((SNode*)pNode);
|
nodesDestroyNode((SNode*)pNode);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
SAggLogicNode* pAgg = (SAggLogicNode*)pNode;
|
||||||
SNode* pGroupKey = NULL;
|
SNode* pGroupKey = NULL;
|
||||||
FOREACH(pGroupKey, ((SAggLogicNode*)pNode)->pGroupKeys) {
|
FOREACH(pGroupKey, pAgg->pGroupKeys) {
|
||||||
code = nodesListMakeStrictAppend(
|
code = nodesListMakeStrictAppend(
|
||||||
&pScan->pGroupTags, nodesCloneNode(nodesListGetNode(((SGroupingSetNode*)pGroupKey)->pParameterList, 0)));
|
&pScan->pGroupTags, nodesCloneNode(nodesListGetNode(((SGroupingSetNode*)pGroupKey)->pParameterList, 0)));
|
||||||
if (TSDB_CODE_SUCCESS != code) {
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NODES_DESTORY_LIST(((SAggLogicNode*)pNode)->pGroupKeys);
|
NODES_DESTORY_LIST(pAgg->pGroupKeys);
|
||||||
|
code = partTagsRewriteGroupTagsToFuncs(pScan->pGroupTags, pAgg->pAggFuncs);
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = partTagsOptRebuildTbanme(pScan->pGroupTags);
|
code = partTagsOptRebuildTbanme(pScan->pGroupTags);
|
||||||
|
@ -1125,7 +1199,8 @@ static bool eliminateProjOptMayBeOptimized(SLogicNode* pNode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
SProjectLogicNode* pProjectNode = (SProjectLogicNode*)pNode;
|
SProjectLogicNode* pProjectNode = (SProjectLogicNode*)pNode;
|
||||||
if (NULL != pProjectNode->node.pLimit || NULL != pProjectNode->node.pSlimit) {
|
if (NULL != pProjectNode->node.pLimit || NULL != pProjectNode->node.pSlimit ||
|
||||||
|
NULL != pProjectNode->node.pConditions) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1163,6 +1238,7 @@ static int32_t eliminateProjOptimizeImpl(SOptimizeContext* pCxt, SLogicSubplan*
|
||||||
NODES_CLEAR_LIST(pProjectNode->node.pChildren);
|
NODES_CLEAR_LIST(pProjectNode->node.pChildren);
|
||||||
nodesDestroyNode((SNode*)pProjectNode);
|
nodesDestroyNode((SNode*)pProjectNode);
|
||||||
}
|
}
|
||||||
|
pCxt->optimized = true;
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1306,6 +1382,7 @@ static int32_t rewriteTailOptimizeImpl(SOptimizeContext* pCxt, SLogicSubplan* pL
|
||||||
nodesDestroyNode((SNode*)pSort);
|
nodesDestroyNode((SNode*)pSort);
|
||||||
nodesDestroyNode((SNode*)pProject);
|
nodesDestroyNode((SNode*)pProject);
|
||||||
}
|
}
|
||||||
|
pCxt->optimized = true;
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1344,6 +1421,7 @@ static int32_t eliminateSetOpOptimizeImpl(SOptimizeContext* pCxt, SLogicSubplan*
|
||||||
|
|
||||||
pSetOpNode->pChildren = NULL;
|
pSetOpNode->pChildren = NULL;
|
||||||
ERASE_NODE(pSetOpNode->pParent->pChildren);
|
ERASE_NODE(pSetOpNode->pParent->pChildren);
|
||||||
|
pCxt->optimized = true;
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1360,6 +1438,261 @@ static int32_t eliminateSetOpOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLo
|
||||||
return eliminateSetOpOptimizeImpl(pCxt, pLogicSubplan, pSetOpNode);
|
return eliminateSetOpOptimizeImpl(pCxt, pLogicSubplan, pSetOpNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool rewriteUniqueOptMayBeOptimized(SLogicNode* pNode) {
|
||||||
|
return QUERY_NODE_LOGIC_PLAN_INDEF_ROWS_FUNC == nodeType(pNode) && ((SIndefRowsFuncLogicNode*)pNode)->isUniqueFunc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SNode* rewriteUniqueOptCreateGroupingSet(SNode* pExpr) {
|
||||||
|
SGroupingSetNode* pGroupingSet = (SGroupingSetNode*)nodesMakeNode(QUERY_NODE_GROUPING_SET);
|
||||||
|
if (NULL == pGroupingSet) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
pGroupingSet->groupingSetType = GP_TYPE_NORMAL;
|
||||||
|
SExprNode* pGroupExpr = (SExprNode*)nodesCloneNode(pExpr);
|
||||||
|
if (TSDB_CODE_SUCCESS != nodesListMakeStrictAppend(&pGroupingSet->pParameterList, (SNode*)pGroupExpr)) {
|
||||||
|
nodesDestroyNode((SNode*)pGroupingSet);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return (SNode*)pGroupingSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SNode* rewriteUniqueOptCreateFirstFunc(SFunctionNode* pSelectValue, SNode* pCol) {
|
||||||
|
SFunctionNode* pFunc = (SFunctionNode*)nodesMakeNode(QUERY_NODE_FUNCTION);
|
||||||
|
if (NULL == pFunc) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(pFunc->functionName, "first");
|
||||||
|
if (NULL != pSelectValue) {
|
||||||
|
sprintf(pFunc->node.aliasName, "%s", pSelectValue->node.aliasName);
|
||||||
|
} else {
|
||||||
|
sprintf(pFunc->node.aliasName, "%s.%p", pFunc->functionName, pFunc);
|
||||||
|
}
|
||||||
|
int32_t code = nodesListMakeStrictAppend(&pFunc->pParameterList, nodesCloneNode(pCol));
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = fmGetFuncInfo(pFunc, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
|
nodesDestroyNode((SNode*)pFunc);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (SNode*)pFunc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t rewriteUniqueOptCreateAgg(SIndefRowsFuncLogicNode* pIndef, SLogicNode** pOutput) {
|
||||||
|
SAggLogicNode* pAgg = (SAggLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_AGG);
|
||||||
|
if (NULL == pAgg) {
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
TSWAP(pAgg->node.pChildren, pIndef->node.pChildren);
|
||||||
|
pAgg->node.precision = pIndef->node.precision;
|
||||||
|
|
||||||
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
bool hasSelectPrimaryKey = false;
|
||||||
|
SNode* pPrimaryKey = NULL;
|
||||||
|
SNode* pNode = NULL;
|
||||||
|
FOREACH(pNode, pIndef->pFuncs) {
|
||||||
|
SFunctionNode* pFunc = (SFunctionNode*)pNode;
|
||||||
|
SNode* pExpr = nodesListGetNode(pFunc->pParameterList, 0);
|
||||||
|
if (FUNCTION_TYPE_UNIQUE == pFunc->funcType) {
|
||||||
|
pPrimaryKey = nodesListGetNode(pFunc->pParameterList, 1);
|
||||||
|
code = nodesListMakeStrictAppend(&pAgg->pGroupKeys, rewriteUniqueOptCreateGroupingSet(pExpr));
|
||||||
|
} else if (PRIMARYKEY_TIMESTAMP_COL_ID == ((SColumnNode*)pExpr)->colId) { // _select_value(ts) => first(ts)
|
||||||
|
hasSelectPrimaryKey = true;
|
||||||
|
code = nodesListMakeStrictAppend(&pAgg->pAggFuncs, rewriteUniqueOptCreateFirstFunc(pFunc, pExpr));
|
||||||
|
} else { // _select_value(other_col)
|
||||||
|
code = nodesListMakeStrictAppend(&pAgg->pAggFuncs, nodesCloneNode(pNode));
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = createColumnByRewriteExprs(pAgg->pGroupKeys, &pAgg->node.pTargets);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code && NULL != pAgg->pAggFuncs) {
|
||||||
|
code = createColumnByRewriteExprs(pAgg->pAggFuncs, &pAgg->node.pTargets);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TSDB_CODE_SUCCESS == code && !hasSelectPrimaryKey && NULL != pAgg->pAggFuncs) {
|
||||||
|
code = nodesListMakeStrictAppend(&pAgg->pAggFuncs, rewriteUniqueOptCreateFirstFunc(NULL, pPrimaryKey));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
*pOutput = (SLogicNode*)pAgg;
|
||||||
|
} else {
|
||||||
|
nodesDestroyNode((SNode*)pAgg);
|
||||||
|
}
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SNode* rewriteUniqueOptCreateProjectCol(SFunctionNode* pFunc) {
|
||||||
|
SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN);
|
||||||
|
if (NULL == pCol) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pCol->node.resType = pFunc->node.resType;
|
||||||
|
if (FUNCTION_TYPE_UNIQUE == pFunc->funcType) {
|
||||||
|
SExprNode* pExpr = (SExprNode*)nodesListGetNode(pFunc->pParameterList, 0);
|
||||||
|
if (QUERY_NODE_COLUMN == nodeType(pExpr)) {
|
||||||
|
strcpy(pCol->tableAlias, ((SColumnNode*)pExpr)->tableAlias);
|
||||||
|
strcpy(pCol->colName, ((SColumnNode*)pExpr)->colName);
|
||||||
|
} else {
|
||||||
|
strcpy(pCol->colName, pExpr->aliasName);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
strcpy(pCol->colName, pFunc->node.aliasName);
|
||||||
|
}
|
||||||
|
strcpy(pCol->node.aliasName, pFunc->node.aliasName);
|
||||||
|
|
||||||
|
return (SNode*)pCol;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t rewriteUniqueOptCreateProject(SIndefRowsFuncLogicNode* pIndef, SLogicNode** pOutput) {
|
||||||
|
SProjectLogicNode* pProject = (SProjectLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_PROJECT);
|
||||||
|
if (NULL == pProject) {
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
TSWAP(pProject->node.pTargets, pIndef->node.pTargets);
|
||||||
|
pProject->node.precision = pIndef->node.precision;
|
||||||
|
|
||||||
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
SNode* pNode = NULL;
|
||||||
|
FOREACH(pNode, pIndef->pFuncs) {
|
||||||
|
code = nodesListMakeStrictAppend(&pProject->pProjections, rewriteUniqueOptCreateProjectCol((SFunctionNode*)pNode));
|
||||||
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
*pOutput = (SLogicNode*)pProject;
|
||||||
|
} else {
|
||||||
|
nodesDestroyNode((SNode*)pProject);
|
||||||
|
}
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t rewriteUniqueOptimizeImpl(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan,
|
||||||
|
SIndefRowsFuncLogicNode* pIndef) {
|
||||||
|
SLogicNode* pAgg = NULL;
|
||||||
|
SLogicNode* pProject = NULL;
|
||||||
|
int32_t code = rewriteUniqueOptCreateAgg(pIndef, &pAgg);
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = rewriteUniqueOptCreateProject(pIndef, &pProject);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = nodesListMakeAppend(&pProject->pChildren, (SNode*)pAgg);
|
||||||
|
pAgg->pParent = pProject;
|
||||||
|
pAgg = NULL;
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = replaceLogicNode(pLogicSubplan, (SLogicNode*)pIndef, pProject);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
nodesDestroyNode((SNode*)pIndef);
|
||||||
|
} else {
|
||||||
|
nodesDestroyNode((SNode*)pAgg);
|
||||||
|
nodesDestroyNode((SNode*)pProject);
|
||||||
|
}
|
||||||
|
pCxt->optimized = true;
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t rewriteUniqueOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan) {
|
||||||
|
SIndefRowsFuncLogicNode* pIndef =
|
||||||
|
(SIndefRowsFuncLogicNode*)optFindPossibleNode(pLogicSubplan->pNode, rewriteUniqueOptMayBeOptimized);
|
||||||
|
|
||||||
|
if (NULL == pIndef) {
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rewriteUniqueOptimizeImpl(pCxt, pLogicSubplan, pIndef);
|
||||||
|
}
|
||||||
|
|
||||||
|
// merge projects
|
||||||
|
static bool mergeProjectsMayBeOptimized(SLogicNode* pNode) {
|
||||||
|
if (QUERY_NODE_LOGIC_PLAN_PROJECT != nodeType(pNode) || 1 != LIST_LENGTH(pNode->pChildren)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
SLogicNode* pChild = (SLogicNode*)nodesListGetNode(pNode->pChildren, 0);
|
||||||
|
if (QUERY_NODE_LOGIC_PLAN_PROJECT != nodeType(pChild) || 1 < LIST_LENGTH(pChild->pChildren) ||
|
||||||
|
NULL != pChild->pConditions || NULL != pChild->pLimit || NULL != pChild->pSlimit) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct SMergeProjectionsContext {
|
||||||
|
SProjectLogicNode* pChildProj;
|
||||||
|
int32_t errCode;
|
||||||
|
} SMergeProjectionsContext;
|
||||||
|
|
||||||
|
static EDealRes mergeProjectionsExpr(SNode** pNode, void* pContext) {
|
||||||
|
SMergeProjectionsContext* pCxt = pContext;
|
||||||
|
SProjectLogicNode* pChildProj = pCxt->pChildProj;
|
||||||
|
if (QUERY_NODE_COLUMN == nodeType(*pNode)) {
|
||||||
|
SNode* pTarget;
|
||||||
|
FOREACH(pTarget, ((SLogicNode*)pChildProj)->pTargets) {
|
||||||
|
if (nodesEqualNode(pTarget, *pNode)) {
|
||||||
|
SNode* pProjection;
|
||||||
|
FOREACH(pProjection, pChildProj->pProjections) {
|
||||||
|
if (0 == strcmp(((SColumnNode*)pTarget)->colName, ((SExprNode*)pProjection)->aliasName)) {
|
||||||
|
SNode* pExpr = nodesCloneNode(pProjection);
|
||||||
|
if (pExpr == NULL) {
|
||||||
|
pCxt->errCode = terrno;
|
||||||
|
return DEAL_RES_ERROR;
|
||||||
|
}
|
||||||
|
nodesDestroyNode(*pNode);
|
||||||
|
*pNode = pExpr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return DEAL_RES_IGNORE_CHILD;
|
||||||
|
}
|
||||||
|
return DEAL_RES_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mergeProjectsOptimizeImpl(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan, SLogicNode* pSelfNode) {
|
||||||
|
SLogicNode* pChild = (SLogicNode*)nodesListGetNode(pSelfNode->pChildren, 0);
|
||||||
|
SMergeProjectionsContext cxt = {.pChildProj = (SProjectLogicNode*)pChild, .errCode = TSDB_CODE_SUCCESS};
|
||||||
|
|
||||||
|
nodesRewriteExprs(((SProjectLogicNode*)pSelfNode)->pProjections, mergeProjectionsExpr, &cxt);
|
||||||
|
int32_t code = cxt.errCode;
|
||||||
|
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
if (1 == LIST_LENGTH(pChild->pChildren)) {
|
||||||
|
SLogicNode* pGrandChild = (SLogicNode*)nodesListGetNode(pChild->pChildren, 0);
|
||||||
|
code = replaceLogicNode(pLogicSubplan, pChild, pGrandChild);
|
||||||
|
} else { // no grand child
|
||||||
|
NODES_CLEAR_LIST(pSelfNode->pChildren);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
NODES_CLEAR_LIST(pChild->pChildren);
|
||||||
|
}
|
||||||
|
nodesDestroyNode((SNode*)pChild);
|
||||||
|
pCxt->optimized = true;
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mergeProjectsOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan) {
|
||||||
|
SLogicNode* pProjectNode = optFindPossibleNode(pLogicSubplan->pNode, mergeProjectsMayBeOptimized);
|
||||||
|
if (NULL == pProjectNode) {
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mergeProjectsOptimizeImpl(pCxt, pLogicSubplan, pProjectNode);
|
||||||
|
}
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const SOptimizeRule optimizeRuleSet[] = {
|
static const SOptimizeRule optimizeRuleSet[] = {
|
||||||
{.pName = "ScanPath", .optimizeFunc = scanPathOptimize},
|
{.pName = "ScanPath", .optimizeFunc = scanPathOptimize},
|
||||||
|
@ -1367,25 +1700,40 @@ static const SOptimizeRule optimizeRuleSet[] = {
|
||||||
{.pName = "SortPrimaryKey", .optimizeFunc = sortPrimaryKeyOptimize},
|
{.pName = "SortPrimaryKey", .optimizeFunc = sortPrimaryKeyOptimize},
|
||||||
{.pName = "SmaIndex", .optimizeFunc = smaIndexOptimize},
|
{.pName = "SmaIndex", .optimizeFunc = smaIndexOptimize},
|
||||||
{.pName = "PartitionTags", .optimizeFunc = partTagsOptimize},
|
{.pName = "PartitionTags", .optimizeFunc = partTagsOptimize},
|
||||||
|
{.pName = "MergeProjects", .optimizeFunc = mergeProjectsOptimize},
|
||||||
{.pName = "EliminateProject", .optimizeFunc = eliminateProjOptimize},
|
{.pName = "EliminateProject", .optimizeFunc = eliminateProjOptimize},
|
||||||
{.pName = "EliminateSetOperator", .optimizeFunc = eliminateSetOpOptimize},
|
{.pName = "EliminateSetOperator", .optimizeFunc = eliminateSetOpOptimize},
|
||||||
{.pName = "RewriteTail", .optimizeFunc = rewriteTailOptimize}
|
{.pName = "RewriteTail", .optimizeFunc = rewriteTailOptimize},
|
||||||
|
{.pName = "RewriteUnique", .optimizeFunc = rewriteUniqueOptimize}
|
||||||
};
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
static const int32_t optimizeRuleNum = (sizeof(optimizeRuleSet) / sizeof(SOptimizeRule));
|
static const int32_t optimizeRuleNum = (sizeof(optimizeRuleSet) / sizeof(SOptimizeRule));
|
||||||
|
|
||||||
|
static void dumpLogicSubplan(const char* pRuleName, SLogicSubplan* pSubplan) {
|
||||||
|
char* pStr = NULL;
|
||||||
|
nodesNodeToString((SNode*)pSubplan, false, &pStr, NULL);
|
||||||
|
qDebugL("apply optimize %s rule: %s", pRuleName, pStr);
|
||||||
|
taosMemoryFree(pStr);
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t applyOptimizeRule(SPlanContext* pCxt, SLogicSubplan* pLogicSubplan) {
|
static int32_t applyOptimizeRule(SPlanContext* pCxt, SLogicSubplan* pLogicSubplan) {
|
||||||
SOptimizeContext cxt = {.pPlanCxt = pCxt, .optimized = false};
|
SOptimizeContext cxt = {.pPlanCxt = pCxt, .optimized = false};
|
||||||
|
bool optimized = false;
|
||||||
do {
|
do {
|
||||||
cxt.optimized = false;
|
optimized = false;
|
||||||
for (int32_t i = 0; i < optimizeRuleNum; ++i) {
|
for (int32_t i = 0; i < optimizeRuleNum; ++i) {
|
||||||
|
cxt.optimized = false;
|
||||||
int32_t code = optimizeRuleSet[i].optimizeFunc(&cxt, pLogicSubplan);
|
int32_t code = optimizeRuleSet[i].optimizeFunc(&cxt, pLogicSubplan);
|
||||||
if (TSDB_CODE_SUCCESS != code) {
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
if (cxt.optimized) {
|
||||||
|
optimized = true;
|
||||||
|
dumpLogicSubplan(optimizeRuleSet[i].pName, pLogicSubplan);
|
||||||
}
|
}
|
||||||
} while (cxt.optimized);
|
}
|
||||||
|
} while (optimized);
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1237,7 +1237,7 @@ static const int32_t splitRuleNum = (sizeof(splitRuleSet) / sizeof(SSplitRule));
|
||||||
static void dumpLogicSubplan(const char* pRuleName, SLogicSubplan* pSubplan) {
|
static void dumpLogicSubplan(const char* pRuleName, SLogicSubplan* pSubplan) {
|
||||||
char* pStr = NULL;
|
char* pStr = NULL;
|
||||||
nodesNodeToString((SNode*)pSubplan, false, &pStr, NULL);
|
nodesNodeToString((SNode*)pSubplan, false, &pStr, NULL);
|
||||||
qDebugL("apply %s rule: %s", pRuleName, pStr);
|
qDebugL("apply split %s rule: %s", pRuleName, pStr);
|
||||||
taosMemoryFree(pStr);
|
taosMemoryFree(pStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,6 +85,11 @@ int32_t qSetSubplanExecutionNode(SSubplan* subplan, int32_t groupId, SDownstream
|
||||||
return setSubplanExecutionNode(subplan->pNode, groupId, pSource);
|
return setSubplanExecutionNode(subplan->pNode, groupId, pSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t qClearSubplanExecutionNode(SSubplan* pSubplan, int32_t groupId) {
|
||||||
|
// todo
|
||||||
|
return TSDB_CODE_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t qSubPlanToString(const SSubplan* pSubplan, char** pStr, int32_t* pLen) {
|
int32_t qSubPlanToString(const SSubplan* pSubplan, char** pStr, int32_t* pLen) {
|
||||||
if (SUBPLAN_TYPE_MODIFY == pSubplan->subplanType && NULL == pSubplan->pNode) {
|
if (SUBPLAN_TYPE_MODIFY == pSubplan->subplanType && NULL == pSubplan->pNode) {
|
||||||
SDataInserterNode* insert = (SDataInserterNode*)pSubplan->pDataSink;
|
SDataInserterNode* insert = (SDataInserterNode*)pSubplan->pDataSink;
|
||||||
|
|
|
@ -56,6 +56,8 @@ TEST_F(PlanBasicTest, uniqueFunc) {
|
||||||
|
|
||||||
run("SELECT UNIQUE(c2 + 10) FROM t1 WHERE c1 > 10");
|
run("SELECT UNIQUE(c2 + 10) FROM t1 WHERE c1 > 10");
|
||||||
|
|
||||||
|
run("SELECT UNIQUE(c2 + 10), c2 FROM t1 WHERE c1 > 10");
|
||||||
|
|
||||||
run("SELECT UNIQUE(c2 + 10), ts, c2 FROM t1 WHERE c1 > 10");
|
run("SELECT UNIQUE(c2 + 10), ts, c2 FROM t1 WHERE c1 > 10");
|
||||||
|
|
||||||
run("SELECT UNIQUE(c1) a FROM t1 ORDER BY a");
|
run("SELECT UNIQUE(c1) a FROM t1 ORDER BY a");
|
||||||
|
@ -75,6 +77,8 @@ TEST_F(PlanBasicTest, tailFunc) {
|
||||||
run("SELECT TAIL(c2 + 10, 10, 80) FROM t1 WHERE c1 > 10 LIMIT 5");
|
run("SELECT TAIL(c2 + 10, 10, 80) FROM t1 WHERE c1 > 10 LIMIT 5");
|
||||||
|
|
||||||
run("SELECT TAIL(c2 + 10, 10, 80) FROM t1 WHERE c1 > 10 PARTITION BY c1 LIMIT 5");
|
run("SELECT TAIL(c2 + 10, 10, 80) FROM t1 WHERE c1 > 10 PARTITION BY c1 LIMIT 5");
|
||||||
|
|
||||||
|
run("SELECT TAIL(c1, 2, 1) FROM st1s1 UNION ALL SELECT c1 FROM st1s2");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(PlanBasicTest, interpFunc) {
|
TEST_F(PlanBasicTest, interpFunc) {
|
||||||
|
@ -97,6 +101,16 @@ TEST_F(PlanBasicTest, lastRowFunc) {
|
||||||
run("SELECT LAST_ROW(c1) FROM st1");
|
run("SELECT LAST_ROW(c1) FROM st1");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(PlanBasicTest, sampleFunc) {
|
||||||
|
useDb("root", "test");
|
||||||
|
|
||||||
|
run("SELECT SAMPLE(c1, 10) FROM t1");
|
||||||
|
|
||||||
|
run("SELECT SAMPLE(c1, 10) FROM st1");
|
||||||
|
|
||||||
|
run("SELECT SAMPLE(c1, 10) FROM st1 PARTITION BY TBNAME");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(PlanBasicTest, withoutFrom) {
|
TEST_F(PlanBasicTest, withoutFrom) {
|
||||||
useDb("root", "test");
|
useDb("root", "test");
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ using namespace std;
|
||||||
|
|
||||||
class PlanOptimizeTest : public PlannerTestBase {};
|
class PlanOptimizeTest : public PlannerTestBase {};
|
||||||
|
|
||||||
TEST_F(PlanOptimizeTest, optimizeScanData) {
|
TEST_F(PlanOptimizeTest, scanPath) {
|
||||||
useDb("root", "test");
|
useDb("root", "test");
|
||||||
|
|
||||||
run("SELECT COUNT(*) FROM t1");
|
run("SELECT COUNT(*) FROM t1");
|
||||||
|
@ -32,7 +32,7 @@ TEST_F(PlanOptimizeTest, optimizeScanData) {
|
||||||
run("SELECT PERCENTILE(c1, 40), COUNT(*) FROM t1");
|
run("SELECT PERCENTILE(c1, 40), COUNT(*) FROM t1");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(PlanOptimizeTest, ConditionPushDown) {
|
TEST_F(PlanOptimizeTest, pushDownCondition) {
|
||||||
useDb("root", "test");
|
useDb("root", "test");
|
||||||
|
|
||||||
run("SELECT ts, c1 FROM st1 WHERE tag1 > 4");
|
run("SELECT ts, c1 FROM st1 WHERE tag1 > 4");
|
||||||
|
@ -42,9 +42,11 @@ TEST_F(PlanOptimizeTest, ConditionPushDown) {
|
||||||
run("SELECT ts, c1 FROM st1 WHERE tag1 > 4 AND tag2 = 'hello'");
|
run("SELECT ts, c1 FROM st1 WHERE tag1 > 4 AND tag2 = 'hello'");
|
||||||
|
|
||||||
run("SELECT ts, c1 FROM st1 WHERE tag1 > 4 AND tag2 = 'hello' AND c1 > 10");
|
run("SELECT ts, c1 FROM st1 WHERE tag1 > 4 AND tag2 = 'hello' AND c1 > 10");
|
||||||
|
|
||||||
|
run("SELECT ts, c1 FROM (SELECT * FROM st1) WHERE tag1 > 4");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(PlanOptimizeTest, orderByPrimaryKey) {
|
TEST_F(PlanOptimizeTest, sortPrimaryKey) {
|
||||||
useDb("root", "test");
|
useDb("root", "test");
|
||||||
|
|
||||||
run("SELECT c1 FROM t1 ORDER BY ts");
|
run("SELECT c1 FROM t1 ORDER BY ts");
|
||||||
|
|
|
@ -57,7 +57,7 @@ SSyncSnapshotSender *snapshotSenderCreate(SSyncNode *pSyncNode, int32_t replicaI
|
||||||
void snapshotSenderDestroy(SSyncSnapshotSender *pSender);
|
void snapshotSenderDestroy(SSyncSnapshotSender *pSender);
|
||||||
bool snapshotSenderIsStart(SSyncSnapshotSender *pSender);
|
bool snapshotSenderIsStart(SSyncSnapshotSender *pSender);
|
||||||
void snapshotSenderStart(SSyncSnapshotSender *pSender, SSnapshot snapshot, void *pReader);
|
void snapshotSenderStart(SSyncSnapshotSender *pSender, SSnapshot snapshot, void *pReader);
|
||||||
void snapshotSenderStop(SSyncSnapshotSender *pSender);
|
void snapshotSenderStop(SSyncSnapshotSender *pSender, bool finish);
|
||||||
int32_t snapshotSend(SSyncSnapshotSender *pSender);
|
int32_t snapshotSend(SSyncSnapshotSender *pSender);
|
||||||
int32_t snapshotReSend(SSyncSnapshotSender *pSender);
|
int32_t snapshotReSend(SSyncSnapshotSender *pSender);
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ SSyncSnapshotReceiver *snapshotReceiverCreate(SSyncNode *pSyncNode, SRaftId from
|
||||||
void snapshotReceiverDestroy(SSyncSnapshotReceiver *pReceiver);
|
void snapshotReceiverDestroy(SSyncSnapshotReceiver *pReceiver);
|
||||||
void snapshotReceiverStart(SSyncSnapshotReceiver *pReceiver, SyncTerm privateTerm, SyncSnapshotSend *pBeginMsg);
|
void snapshotReceiverStart(SSyncSnapshotReceiver *pReceiver, SyncTerm privateTerm, SyncSnapshotSend *pBeginMsg);
|
||||||
bool snapshotReceiverIsStart(SSyncSnapshotReceiver *pReceiver);
|
bool snapshotReceiverIsStart(SSyncSnapshotReceiver *pReceiver);
|
||||||
void snapshotReceiverStop(SSyncSnapshotReceiver *pReceiver, bool apply);
|
void snapshotReceiverStop(SSyncSnapshotReceiver *pReceiver);
|
||||||
|
|
||||||
cJSON *snapshotReceiver2Json(SSyncSnapshotReceiver *pReceiver);
|
cJSON *snapshotReceiver2Json(SSyncSnapshotReceiver *pReceiver);
|
||||||
char *snapshotReceiver2Str(SSyncSnapshotReceiver *pReceiver);
|
char *snapshotReceiver2Str(SSyncSnapshotReceiver *pReceiver);
|
||||||
|
|
|
@ -240,7 +240,10 @@ int32_t syncNodeOnAppendEntriesReplySnapshotCb(SSyncNode* ths, SyncAppendEntries
|
||||||
SSyncSnapshotSender* pSender = syncNodeGetSnapshotSender(ths, &(pMsg->srcId));
|
SSyncSnapshotSender* pSender = syncNodeGetSnapshotSender(ths, &(pMsg->srcId));
|
||||||
ASSERT(pSender != NULL);
|
ASSERT(pSender != NULL);
|
||||||
|
|
||||||
SSnapshot snapshot;
|
SSnapshot snapshot = {.data = NULL,
|
||||||
|
.lastApplyIndex = SYNC_INDEX_INVALID,
|
||||||
|
.lastApplyTerm = 0,
|
||||||
|
.lastConfigIndex = SYNC_INDEX_INVALID};
|
||||||
void* pReader = NULL;
|
void* pReader = NULL;
|
||||||
ths->pFsm->FpGetSnapshot(ths->pFsm, &snapshot, NULL, &pReader);
|
ths->pFsm->FpGetSnapshot(ths->pFsm, &snapshot, NULL, &pReader);
|
||||||
if (snapshot.lastApplyIndex >= SYNC_INDEX_BEGIN && nextIndex <= snapshot.lastApplyIndex + 1 &&
|
if (snapshot.lastApplyIndex >= SYNC_INDEX_BEGIN && nextIndex <= snapshot.lastApplyIndex + 1 &&
|
||||||
|
@ -249,10 +252,6 @@ int32_t syncNodeOnAppendEntriesReplySnapshotCb(SSyncNode* ths, SyncAppendEntries
|
||||||
ASSERT(pReader != NULL);
|
ASSERT(pReader != NULL);
|
||||||
snapshotSenderStart(pSender, snapshot, pReader);
|
snapshotSenderStart(pSender, snapshot, pReader);
|
||||||
|
|
||||||
char* eventLog = snapshotSender2SimpleStr(pSender, "snapshot sender start");
|
|
||||||
syncNodeEventLog(ths, eventLog);
|
|
||||||
taosMemoryFree(eventLog);
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// no snapshot
|
// no snapshot
|
||||||
if (pReader != NULL) {
|
if (pReader != NULL) {
|
||||||
|
@ -260,23 +259,6 @@ int32_t syncNodeOnAppendEntriesReplySnapshotCb(SSyncNode* ths, SyncAppendEntries
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
bool hasSnapshot = syncNodeHasSnapshot(ths);
|
|
||||||
SSnapshot snapshot;
|
|
||||||
ths->pFsm->FpGetSnapshotInfo(ths->pFsm, &snapshot);
|
|
||||||
|
|
||||||
// start sending snapshot first time
|
|
||||||
// start here, stop by receiver
|
|
||||||
if (hasSnapshot && nextIndex <= snapshot.lastApplyIndex + 1 && !snapshotSenderIsStart(pSender) &&
|
|
||||||
pMsg->privateTerm < pSender->privateTerm) {
|
|
||||||
snapshotSenderStart(pSender);
|
|
||||||
|
|
||||||
char* eventLog = snapshotSender2SimpleStr(pSender, "snapshot sender start");
|
|
||||||
syncNodeEventLog(ths, eventLog);
|
|
||||||
taosMemoryFree(eventLog);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
SyncIndex sentryIndex = pSender->snapshot.lastApplyIndex + 1;
|
SyncIndex sentryIndex = pSender->snapshot.lastApplyIndex + 1;
|
||||||
|
|
||||||
// update nextIndex to sentryIndex
|
// update nextIndex to sentryIndex
|
||||||
|
@ -300,5 +282,5 @@ int32_t syncNodeOnAppendEntriesReplySnapshotCb(SSyncNode* ths, SyncAppendEntries
|
||||||
syncIndexMgrLog2("recv sync-append-entries-reply, after pNextIndex:", ths->pNextIndex);
|
syncIndexMgrLog2("recv sync-append-entries-reply, after pNextIndex:", ths->pNextIndex);
|
||||||
syncIndexMgrLog2("recv sync-append-entries-reply, after pMatchIndex:", ths->pMatchIndex);
|
syncIndexMgrLog2("recv sync-append-entries-reply, after pMatchIndex:", ths->pMatchIndex);
|
||||||
|
|
||||||
return ret;
|
return 0;
|
||||||
}
|
}
|
|
@ -698,7 +698,7 @@ int32_t syncNodePropose(SSyncNode* pSyncNode, SRpcMsg* pMsg, bool isWeak) {
|
||||||
} else {
|
} else {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
terrno = TSDB_CODE_SYN_NOT_LEADER;
|
terrno = TSDB_CODE_SYN_NOT_LEADER;
|
||||||
sError("syncPropose not leader, %s", syncUtilState2String(pSyncNode->state));
|
sError("sync propose not leader, %s", syncUtilState2String(pSyncNode->state));
|
||||||
goto _END;
|
goto _END;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1414,46 +1414,59 @@ void syncNodeErrorLog(const SSyncNode* pSyncNode, char* str) {
|
||||||
int32_t userStrLen = strlen(str);
|
int32_t userStrLen = strlen(str);
|
||||||
|
|
||||||
SSnapshot snapshot = {.data = NULL, .lastApplyIndex = -1, .lastApplyTerm = 0};
|
SSnapshot snapshot = {.data = NULL, .lastApplyIndex = -1, .lastApplyTerm = 0};
|
||||||
if (pSyncNode->pFsm->FpGetSnapshotInfo != NULL) {
|
if (pSyncNode->pFsm != NULL && pSyncNode->pFsm->FpGetSnapshotInfo != NULL) {
|
||||||
pSyncNode->pFsm->FpGetSnapshotInfo(pSyncNode->pFsm, &snapshot);
|
pSyncNode->pFsm->FpGetSnapshotInfo(pSyncNode->pFsm, &snapshot);
|
||||||
}
|
}
|
||||||
SyncIndex logLastIndex = pSyncNode->pLogStore->syncLogLastIndex(pSyncNode->pLogStore);
|
|
||||||
SyncIndex logBeginIndex = pSyncNode->pLogStore->syncLogBeginIndex(pSyncNode->pLogStore);
|
SyncIndex logLastIndex = SYNC_INDEX_INVALID;
|
||||||
|
SyncIndex logBeginIndex = SYNC_INDEX_INVALID;
|
||||||
|
if (pSyncNode->pLogStore != NULL) {
|
||||||
|
logLastIndex = pSyncNode->pLogStore->syncLogLastIndex(pSyncNode->pLogStore);
|
||||||
|
logBeginIndex = pSyncNode->pLogStore->syncLogBeginIndex(pSyncNode->pLogStore);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* pCfgStr = syncCfg2SimpleStr(&(pSyncNode->pRaftCfg->cfg));
|
||||||
|
char* printStr = "";
|
||||||
|
if (pCfgStr != NULL) {
|
||||||
|
printStr = pCfgStr;
|
||||||
|
}
|
||||||
|
|
||||||
if (userStrLen < 256) {
|
if (userStrLen < 256) {
|
||||||
char logBuf[128 + 256];
|
char logBuf[256 + 256];
|
||||||
if (pSyncNode != NULL && pSyncNode->pRaftCfg != NULL && pSyncNode->pRaftStore != NULL) {
|
if (pSyncNode != NULL && pSyncNode->pRaftCfg != NULL && pSyncNode->pRaftStore != NULL) {
|
||||||
snprintf(logBuf, sizeof(logBuf),
|
snprintf(logBuf, sizeof(logBuf),
|
||||||
"vgId:%d, sync %s %s, term:%lu, commit:%ld, beginlog:%ld, lastlog:%ld, lastsnapshot:%ld, standby:%d, "
|
"vgId:%d, sync %s %s, term:%lu, commit:%ld, beginlog:%ld, lastlog:%ld, lastsnapshot:%ld, standby:%d, "
|
||||||
"replica-num:%d, "
|
"replica-num:%d, "
|
||||||
"lconfig:%ld, changing:%d",
|
"lconfig:%ld, changing:%d, restore:%d, %s",
|
||||||
pSyncNode->vgId, syncUtilState2String(pSyncNode->state), str, pSyncNode->pRaftStore->currentTerm,
|
pSyncNode->vgId, syncUtilState2String(pSyncNode->state), str, pSyncNode->pRaftStore->currentTerm,
|
||||||
pSyncNode->commitIndex, logBeginIndex, logLastIndex, snapshot.lastApplyIndex,
|
pSyncNode->commitIndex, logBeginIndex, logLastIndex, snapshot.lastApplyIndex,
|
||||||
pSyncNode->pRaftCfg->isStandBy, pSyncNode->replicaNum, pSyncNode->pRaftCfg->lastConfigIndex,
|
pSyncNode->pRaftCfg->isStandBy, pSyncNode->replicaNum, pSyncNode->pRaftCfg->lastConfigIndex,
|
||||||
pSyncNode->changing);
|
pSyncNode->changing, pSyncNode->restoreFinish, printStr);
|
||||||
} else {
|
} else {
|
||||||
snprintf(logBuf, sizeof(logBuf), "%s", str);
|
snprintf(logBuf, sizeof(logBuf), "%s", str);
|
||||||
}
|
}
|
||||||
sError("%s", logBuf);
|
sError("%s", logBuf);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
int len = 128 + userStrLen;
|
int len = 256 + userStrLen;
|
||||||
char* s = (char*)taosMemoryMalloc(len);
|
char* s = (char*)taosMemoryMalloc(len);
|
||||||
if (pSyncNode != NULL && pSyncNode->pRaftCfg != NULL && pSyncNode->pRaftStore != NULL) {
|
if (pSyncNode != NULL && pSyncNode->pRaftCfg != NULL && pSyncNode->pRaftStore != NULL) {
|
||||||
snprintf(s, len,
|
snprintf(s, len,
|
||||||
"vgId:%d, sync %s %s, term:%lu, commit:%ld, beginlog:%ld, lastlog:%ld, lastsnapshot:%ld, standby:%d, "
|
"vgId:%d, sync %s %s, term:%lu, commit:%ld, beginlog:%ld, lastlog:%ld, lastsnapshot:%ld, standby:%d, "
|
||||||
"replica-num:%d, "
|
"replica-num:%d, "
|
||||||
"lconfig:%ld, changing:%d",
|
"lconfig:%ld, changing:%d, restore:%d, %s",
|
||||||
pSyncNode->vgId, syncUtilState2String(pSyncNode->state), str, pSyncNode->pRaftStore->currentTerm,
|
pSyncNode->vgId, syncUtilState2String(pSyncNode->state), str, pSyncNode->pRaftStore->currentTerm,
|
||||||
pSyncNode->commitIndex, logBeginIndex, logLastIndex, snapshot.lastApplyIndex,
|
pSyncNode->commitIndex, logBeginIndex, logLastIndex, snapshot.lastApplyIndex,
|
||||||
pSyncNode->pRaftCfg->isStandBy, pSyncNode->replicaNum, pSyncNode->pRaftCfg->lastConfigIndex,
|
pSyncNode->pRaftCfg->isStandBy, pSyncNode->replicaNum, pSyncNode->pRaftCfg->lastConfigIndex,
|
||||||
pSyncNode->changing);
|
pSyncNode->changing, pSyncNode->restoreFinish, printStr);
|
||||||
} else {
|
} else {
|
||||||
snprintf(s, len, "%s", str);
|
snprintf(s, len, "%s", str);
|
||||||
}
|
}
|
||||||
sError("%s", s);
|
sError("%s", s);
|
||||||
taosMemoryFree(s);
|
taosMemoryFree(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
taosMemoryFree(pCfgStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
char* syncNode2SimpleStr(const SSyncNode* pSyncNode) {
|
char* syncNode2SimpleStr(const SSyncNode* pSyncNode) {
|
||||||
|
@ -1475,18 +1488,6 @@ char* syncNode2SimpleStr(const SSyncNode* pSyncNode) {
|
||||||
pSyncNode->commitIndex, logBeginIndex, logLastIndex, snapshot.lastApplyIndex, pSyncNode->pRaftCfg->isStandBy,
|
pSyncNode->commitIndex, logBeginIndex, logLastIndex, snapshot.lastApplyIndex, pSyncNode->pRaftCfg->isStandBy,
|
||||||
pSyncNode->replicaNum, pSyncNode->pRaftCfg->lastConfigIndex, pSyncNode->changing, pSyncNode->restoreFinish);
|
pSyncNode->replicaNum, pSyncNode->pRaftCfg->lastConfigIndex, pSyncNode->changing, pSyncNode->restoreFinish);
|
||||||
|
|
||||||
/*
|
|
||||||
snprintf(s, len,
|
|
||||||
"syncNode: vgId:%d, term:%lu, commit:%ld, state:%d %s, standby:%d, "
|
|
||||||
"lc:%lu, "
|
|
||||||
"lc-user:%lu, "
|
|
||||||
"ems:%d, replica-num:%d, restore:%d, changing:%d",
|
|
||||||
pSyncNode->vgId, pSyncNode->pRaftStore->currentTerm, pSyncNode->commitIndex, pSyncNode->state,
|
|
||||||
syncUtilState2String(pSyncNode->state), pSyncNode->pRaftCfg->isStandBy, pSyncNode->electTimerLogicClock,
|
|
||||||
pSyncNode->electTimerLogicClockUser, pSyncNode->electTimerMS, pSyncNode->replicaNum,
|
|
||||||
pSyncNode->restoreFinish, pSyncNode->changing);
|
|
||||||
*/
|
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
//----------------------------------
|
//----------------------------------
|
||||||
static void snapshotReceiverDoStart(SSyncSnapshotReceiver *pReceiver, SyncTerm privateTerm,
|
static void snapshotReceiverDoStart(SSyncSnapshotReceiver *pReceiver, SyncTerm privateTerm,
|
||||||
SyncSnapshotSend *pBeginMsg);
|
SyncSnapshotSend *pBeginMsg);
|
||||||
|
static void snapshotReceiverGotData(SSyncSnapshotReceiver *pReceiver, SyncSnapshotSend *pMsg);
|
||||||
|
|
||||||
//----------------------------------
|
//----------------------------------
|
||||||
SSyncSnapshotSender *snapshotSenderCreate(SSyncNode *pSyncNode, int32_t replicaIndex) {
|
SSyncSnapshotSender *snapshotSenderCreate(SSyncNode *pSyncNode, int32_t replicaIndex) {
|
||||||
|
@ -50,7 +51,7 @@ SSyncSnapshotSender *snapshotSenderCreate(SSyncNode *pSyncNode, int32_t replicaI
|
||||||
pSender->pSyncNode->pFsm->FpGetSnapshotInfo(pSender->pSyncNode->pFsm, &(pSender->snapshot));
|
pSender->pSyncNode->pFsm->FpGetSnapshotInfo(pSender->pSyncNode->pFsm, &(pSender->snapshot));
|
||||||
pSender->finish = false;
|
pSender->finish = false;
|
||||||
} else {
|
} else {
|
||||||
sError("vgId:%d cannot create snapshot sender", pSyncNode->vgId);
|
sError("vgId:%d, cannot create snapshot sender", pSyncNode->vgId);
|
||||||
}
|
}
|
||||||
|
|
||||||
return pSender;
|
return pSender;
|
||||||
|
@ -127,7 +128,7 @@ void snapshotSenderStart(SSyncSnapshotSender *pSender, SSnapshot snapshot, void
|
||||||
syncEntryDestory(pEntry);
|
syncEntryDestory(pEntry);
|
||||||
} else {
|
} else {
|
||||||
if (pSender->snapshot.lastConfigIndex == pSender->pSyncNode->pRaftCfg->lastConfigIndex) {
|
if (pSender->snapshot.lastConfigIndex == pSender->pSyncNode->pRaftCfg->lastConfigIndex) {
|
||||||
sTrace("vgId:%d sync sender get cfg from local", pSender->pSyncNode->vgId);
|
sTrace("vgId:%d, sync sender get cfg from local", pSender->pSyncNode->vgId);
|
||||||
pSender->lastConfig = pSender->pSyncNode->pRaftCfg->cfg;
|
pSender->lastConfig = pSender->pSyncNode->pRaftCfg->cfg;
|
||||||
getLastConfig = true;
|
getLastConfig = true;
|
||||||
}
|
}
|
||||||
|
@ -176,13 +177,13 @@ void snapshotSenderStart(SSyncSnapshotSender *pSender, SSnapshot snapshot, void
|
||||||
|
|
||||||
// event log
|
// event log
|
||||||
do {
|
do {
|
||||||
char *eventLog = snapshotSender2SimpleStr(pSender, "snapshot sender send");
|
char *eventLog = snapshotSender2SimpleStr(pSender, "snapshot sender start");
|
||||||
syncNodeEventLog(pSender->pSyncNode, eventLog);
|
syncNodeEventLog(pSender->pSyncNode, eventLog);
|
||||||
taosMemoryFree(eventLog);
|
taosMemoryFree(eventLog);
|
||||||
} while (0);
|
} while (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void snapshotSenderStop(SSyncSnapshotSender *pSender) {
|
void snapshotSenderStop(SSyncSnapshotSender *pSender, bool finish) {
|
||||||
// close reader
|
// close reader
|
||||||
if (pSender->pReader != NULL) {
|
if (pSender->pReader != NULL) {
|
||||||
int32_t ret = pSender->pSyncNode->pFsm->FpSnapshotStopRead(pSender->pSyncNode->pFsm, pSender->pReader);
|
int32_t ret = pSender->pSyncNode->pFsm->FpSnapshotStopRead(pSender->pSyncNode->pFsm, pSender->pReader);
|
||||||
|
@ -199,6 +200,14 @@ void snapshotSenderStop(SSyncSnapshotSender *pSender) {
|
||||||
|
|
||||||
// update flag
|
// update flag
|
||||||
pSender->start = false;
|
pSender->start = false;
|
||||||
|
pSender->finish = finish;
|
||||||
|
|
||||||
|
// event log
|
||||||
|
do {
|
||||||
|
char *eventLog = snapshotSender2SimpleStr(pSender, "snapshot sender stop");
|
||||||
|
syncNodeEventLog(pSender->pSyncNode, eventLog);
|
||||||
|
taosMemoryFree(eventLog);
|
||||||
|
} while (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// when sender receive ack, call this function to send msg from seq
|
// when sender receive ack, call this function to send msg from seq
|
||||||
|
@ -354,8 +363,9 @@ char *snapshotSender2SimpleStr(SSyncSnapshotSender *pSender, char *event) {
|
||||||
uint16_t port;
|
uint16_t port;
|
||||||
syncUtilU642Addr(destId.addr, host, sizeof(host), &port);
|
syncUtilU642Addr(destId.addr, host, sizeof(host), &port);
|
||||||
|
|
||||||
snprintf(s, len, "%s %p laindex:%ld laterm:%lu lcindex:%ld seq:%d ack:%d finish:%d pterm:%lu replica-index:%d %s:%d",
|
snprintf(s, len,
|
||||||
event, pSender, pSender->snapshot.lastApplyIndex, pSender->snapshot.lastApplyTerm,
|
"%s {%p laindex:%ld laterm:%lu lcindex:%ld seq:%d ack:%d finish:%d pterm:%lu replica-index:%d %s:%d}", event,
|
||||||
|
pSender, pSender->snapshot.lastApplyIndex, pSender->snapshot.lastApplyTerm,
|
||||||
pSender->snapshot.lastConfigIndex, pSender->seq, pSender->ack, pSender->finish, pSender->privateTerm,
|
pSender->snapshot.lastConfigIndex, pSender->seq, pSender->ack, pSender->finish, pSender->privateTerm,
|
||||||
pSender->replicaIndex, host, port);
|
pSender->replicaIndex, host, port);
|
||||||
|
|
||||||
|
@ -386,7 +396,7 @@ SSyncSnapshotReceiver *snapshotReceiverCreate(SSyncNode *pSyncNode, SRaftId from
|
||||||
pReceiver->snapshot.lastConfigIndex = SYNC_INDEX_INVALID;
|
pReceiver->snapshot.lastConfigIndex = SYNC_INDEX_INVALID;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
sError("vgId:%d cannot create snapshot receiver", pSyncNode->vgId);
|
sError("vgId:%d, cannot create snapshot receiver", pSyncNode->vgId);
|
||||||
}
|
}
|
||||||
|
|
||||||
return pReceiver;
|
return pReceiver;
|
||||||
|
@ -409,9 +419,9 @@ void snapshotReceiverDestroy(SSyncSnapshotReceiver *pReceiver) {
|
||||||
|
|
||||||
bool snapshotReceiverIsStart(SSyncSnapshotReceiver *pReceiver) { return pReceiver->start; }
|
bool snapshotReceiverIsStart(SSyncSnapshotReceiver *pReceiver) { return pReceiver->start; }
|
||||||
|
|
||||||
// static do start
|
// static do start by privateTerm, pBeginMsg
|
||||||
// receive first snapshot data
|
// receive first snapshot data
|
||||||
// privateTerm, pBeginMsg
|
// write first block data
|
||||||
static void snapshotReceiverDoStart(SSyncSnapshotReceiver *pReceiver, SyncTerm privateTerm,
|
static void snapshotReceiverDoStart(SSyncSnapshotReceiver *pReceiver, SyncTerm privateTerm,
|
||||||
SyncSnapshotSend *pBeginMsg) {
|
SyncSnapshotSend *pBeginMsg) {
|
||||||
// update state
|
// update state
|
||||||
|
@ -419,6 +429,7 @@ static void snapshotReceiverDoStart(SSyncSnapshotReceiver *pReceiver, SyncTerm p
|
||||||
pReceiver->privateTerm = privateTerm;
|
pReceiver->privateTerm = privateTerm;
|
||||||
pReceiver->ack = SYNC_SNAPSHOT_SEQ_BEGIN;
|
pReceiver->ack = SYNC_SNAPSHOT_SEQ_BEGIN;
|
||||||
pReceiver->fromId = pBeginMsg->srcId;
|
pReceiver->fromId = pBeginMsg->srcId;
|
||||||
|
pReceiver->start = true;
|
||||||
|
|
||||||
// update snapshot
|
// update snapshot
|
||||||
pReceiver->snapshot.lastApplyIndex = pBeginMsg->lastIndex;
|
pReceiver->snapshot.lastApplyIndex = pBeginMsg->lastIndex;
|
||||||
|
@ -429,8 +440,16 @@ static void snapshotReceiverDoStart(SSyncSnapshotReceiver *pReceiver, SyncTerm p
|
||||||
ASSERT(pReceiver->pWriter == NULL);
|
ASSERT(pReceiver->pWriter == NULL);
|
||||||
int32_t ret = pReceiver->pSyncNode->pFsm->FpSnapshotStartWrite(pReceiver->pSyncNode->pFsm, &(pReceiver->pWriter));
|
int32_t ret = pReceiver->pSyncNode->pFsm->FpSnapshotStartWrite(pReceiver->pSyncNode->pFsm, &(pReceiver->pWriter));
|
||||||
ASSERT(ret == 0);
|
ASSERT(ret == 0);
|
||||||
|
|
||||||
|
// event log
|
||||||
|
do {
|
||||||
|
char *eventLog = snapshotReceiver2SimpleStr(pReceiver, "snapshot receiver start");
|
||||||
|
syncNodeEventLog(pReceiver->pSyncNode, eventLog);
|
||||||
|
taosMemoryFree(eventLog);
|
||||||
|
} while (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// force stop
|
||||||
static void snapshotReceiverForceStop(SSyncSnapshotReceiver *pReceiver) {
|
static void snapshotReceiverForceStop(SSyncSnapshotReceiver *pReceiver) {
|
||||||
// force close, abandon incomplete data
|
// force close, abandon incomplete data
|
||||||
if (pReceiver->pWriter != NULL) {
|
if (pReceiver->pWriter != NULL) {
|
||||||
|
@ -441,33 +460,35 @@ static void snapshotReceiverForceStop(SSyncSnapshotReceiver *pReceiver) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pReceiver->start = false;
|
pReceiver->start = false;
|
||||||
|
|
||||||
|
// event log
|
||||||
|
do {
|
||||||
|
char *eventLog = snapshotReceiver2SimpleStr(pReceiver, "snapshot receiver force stop");
|
||||||
|
syncNodeEventLog(pReceiver->pSyncNode, eventLog);
|
||||||
|
taosMemoryFree(eventLog);
|
||||||
|
} while (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if receiver receive msg from seq = SYNC_SNAPSHOT_SEQ_BEGIN, start receiver
|
// if receiver receive msg from seq = SYNC_SNAPSHOT_SEQ_BEGIN, start receiver
|
||||||
// if already start, force close, start again
|
// if already start, force close, start again
|
||||||
void snapshotReceiverStart(SSyncSnapshotReceiver *pReceiver, SyncTerm privateTerm, SyncSnapshotSend *pBeginMsg) {
|
void snapshotReceiverStart(SSyncSnapshotReceiver *pReceiver, SyncTerm privateTerm, SyncSnapshotSend *pBeginMsg) {
|
||||||
if (!snapshotReceiverIsStart(pReceiver)) {
|
if (!snapshotReceiverIsStart(pReceiver)) {
|
||||||
// start
|
// first start
|
||||||
snapshotReceiverDoStart(pReceiver, privateTerm, pBeginMsg);
|
snapshotReceiverDoStart(pReceiver, privateTerm, pBeginMsg);
|
||||||
pReceiver->start = true;
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// already start
|
// already start
|
||||||
sInfo("snapshot recv, receiver already start");
|
sInfo("vgId:%d, snapshot recv, receiver already start", pReceiver->pSyncNode->vgId);
|
||||||
|
|
||||||
// force close, abandon incomplete data
|
// force close, abandon incomplete data
|
||||||
int32_t ret =
|
snapshotReceiverForceStop(pReceiver);
|
||||||
pReceiver->pSyncNode->pFsm->FpSnapshotStopWrite(pReceiver->pSyncNode->pFsm, pReceiver->pWriter, false);
|
|
||||||
ASSERT(ret == 0);
|
|
||||||
pReceiver->pWriter = NULL;
|
|
||||||
|
|
||||||
// start again
|
// start again
|
||||||
snapshotReceiverDoStart(pReceiver, privateTerm, pBeginMsg);
|
snapshotReceiverDoStart(pReceiver, privateTerm, pBeginMsg);
|
||||||
pReceiver->start = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void snapshotReceiverStop(SSyncSnapshotReceiver *pReceiver, bool apply) {
|
void snapshotReceiverStop(SSyncSnapshotReceiver *pReceiver) {
|
||||||
if (pReceiver->pWriter != NULL) {
|
if (pReceiver->pWriter != NULL) {
|
||||||
int32_t ret =
|
int32_t ret =
|
||||||
pReceiver->pSyncNode->pFsm->FpSnapshotStopWrite(pReceiver->pSyncNode->pFsm, pReceiver->pWriter, false);
|
pReceiver->pSyncNode->pFsm->FpSnapshotStopWrite(pReceiver->pSyncNode->pFsm, pReceiver->pWriter, false);
|
||||||
|
@ -477,8 +498,69 @@ void snapshotReceiverStop(SSyncSnapshotReceiver *pReceiver, bool apply) {
|
||||||
|
|
||||||
pReceiver->start = false;
|
pReceiver->start = false;
|
||||||
|
|
||||||
if (apply) {
|
// event log
|
||||||
// ++(pReceiver->privateTerm);
|
do {
|
||||||
|
SSnapshot snapshot;
|
||||||
|
pReceiver->pSyncNode->pFsm->FpGetSnapshotInfo(pReceiver->pSyncNode->pFsm, &snapshot);
|
||||||
|
char *eventLog = snapshotReceiver2SimpleStr(pReceiver, "snapshot receiver stop");
|
||||||
|
syncNodeEventLog(pReceiver->pSyncNode, eventLog);
|
||||||
|
taosMemoryFree(eventLog);
|
||||||
|
} while (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void snapshotReceiverFinish(SSyncSnapshotReceiver *pReceiver, SyncSnapshotSend *pMsg) {
|
||||||
|
ASSERT(pMsg->seq == SYNC_SNAPSHOT_SEQ_END);
|
||||||
|
|
||||||
|
if (pReceiver->pWriter != NULL) {
|
||||||
|
int32_t code = 0;
|
||||||
|
if (pMsg->dataLen > 0) {
|
||||||
|
code = pReceiver->pSyncNode->pFsm->FpSnapshotDoWrite(pReceiver->pSyncNode->pFsm, pReceiver->pWriter, pMsg->data,
|
||||||
|
pMsg->dataLen);
|
||||||
|
ASSERT(code == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
code = pReceiver->pSyncNode->pFsm->FpSnapshotStopWrite(pReceiver->pSyncNode->pFsm, pReceiver->pWriter, true);
|
||||||
|
ASSERT(code == 0);
|
||||||
|
pReceiver->pWriter = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pReceiver->ack = SYNC_SNAPSHOT_SEQ_END;
|
||||||
|
|
||||||
|
// update commit index
|
||||||
|
if (pReceiver->snapshot.lastApplyIndex > pReceiver->pSyncNode->commitIndex) {
|
||||||
|
pReceiver->pSyncNode->commitIndex = pReceiver->snapshot.lastApplyIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
// reset wal
|
||||||
|
pReceiver->pSyncNode->pLogStore->syncLogRestoreFromSnapshot(pReceiver->pSyncNode->pLogStore, pMsg->lastIndex);
|
||||||
|
|
||||||
|
// event log
|
||||||
|
do {
|
||||||
|
SSnapshot snapshot;
|
||||||
|
pReceiver->pSyncNode->pFsm->FpGetSnapshotInfo(pReceiver->pSyncNode->pFsm, &snapshot);
|
||||||
|
char *eventLog = snapshotReceiver2SimpleStr(pReceiver, "snapshot receiver got last data, finish, apply snapshot");
|
||||||
|
syncNodeEventLog(pReceiver->pSyncNode, eventLog);
|
||||||
|
taosMemoryFree(eventLog);
|
||||||
|
} while (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void snapshotReceiverGotData(SSyncSnapshotReceiver *pReceiver, SyncSnapshotSend *pMsg) {
|
||||||
|
ASSERT(pMsg->seq == pReceiver->ack + 1);
|
||||||
|
|
||||||
|
if (pReceiver->pWriter != NULL) {
|
||||||
|
if (pMsg->dataLen > 0) {
|
||||||
|
int32_t code = pReceiver->pSyncNode->pFsm->FpSnapshotDoWrite(pReceiver->pSyncNode->pFsm, pReceiver->pWriter,
|
||||||
|
pMsg->data, pMsg->dataLen);
|
||||||
|
ASSERT(code == 0);
|
||||||
|
}
|
||||||
|
pReceiver->ack = pMsg->seq;
|
||||||
|
|
||||||
|
// event log
|
||||||
|
do {
|
||||||
|
char *eventLog = snapshotReceiver2SimpleStr(pReceiver, "snapshot receiver receiving");
|
||||||
|
syncNodeEventLog(pReceiver->pSyncNode, eventLog);
|
||||||
|
taosMemoryFree(eventLog);
|
||||||
|
} while (0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -548,7 +630,7 @@ char *snapshotReceiver2SimpleStr(SSyncSnapshotReceiver *pReceiver, char *event)
|
||||||
uint16_t port;
|
uint16_t port;
|
||||||
syncUtilU642Addr(fromId.addr, host, sizeof(host), &port);
|
syncUtilU642Addr(fromId.addr, host, sizeof(host), &port);
|
||||||
|
|
||||||
snprintf(s, len, "%s %p start:%d ack:%d term:%lu pterm:%lu from:%s:%d laindex:%ld laterm:%lu lcindex:%ld", event,
|
snprintf(s, len, "%s {%p start:%d ack:%d term:%lu pterm:%lu from:%s:%d laindex:%ld laterm:%lu lcindex:%ld}", event,
|
||||||
pReceiver, pReceiver->start, pReceiver->ack, pReceiver->term, pReceiver->privateTerm, host, port,
|
pReceiver, pReceiver->start, pReceiver->ack, pReceiver->term, pReceiver->privateTerm, host, port,
|
||||||
pReceiver->snapshot.lastApplyIndex, pReceiver->snapshot.lastApplyTerm, pReceiver->snapshot.lastConfigIndex);
|
pReceiver->snapshot.lastApplyIndex, pReceiver->snapshot.lastApplyTerm, pReceiver->snapshot.lastConfigIndex);
|
||||||
|
|
||||||
|
@ -560,33 +642,20 @@ int32_t syncNodeOnSnapshotSendCb(SSyncNode *pSyncNode, SyncSnapshotSend *pMsg) {
|
||||||
// get receiver
|
// get receiver
|
||||||
SSyncSnapshotReceiver *pReceiver = pSyncNode->pNewNodeReceiver;
|
SSyncSnapshotReceiver *pReceiver = pSyncNode->pNewNodeReceiver;
|
||||||
bool needRsp = false;
|
bool needRsp = false;
|
||||||
int32_t writeCode = 0;
|
|
||||||
|
|
||||||
// state, term, seq/ack
|
// state, term, seq/ack
|
||||||
if (pSyncNode->state == TAOS_SYNC_STATE_FOLLOWER) {
|
if (pSyncNode->state == TAOS_SYNC_STATE_FOLLOWER) {
|
||||||
if (pMsg->term == pSyncNode->pRaftStore->currentTerm) {
|
if (pMsg->term == pSyncNode->pRaftStore->currentTerm) {
|
||||||
if (pMsg->seq == SYNC_SNAPSHOT_SEQ_BEGIN) {
|
if (pMsg->seq == SYNC_SNAPSHOT_SEQ_BEGIN) {
|
||||||
// begin
|
// begin, no data
|
||||||
snapshotReceiverStart(pReceiver, pMsg->privateTerm, pMsg);
|
snapshotReceiverStart(pReceiver, pMsg->privateTerm, pMsg);
|
||||||
pReceiver->ack = pMsg->seq;
|
|
||||||
needRsp = true;
|
needRsp = true;
|
||||||
|
|
||||||
char *eventLog = snapshotReceiver2SimpleStr(pReceiver, "snapshot receiver begin");
|
|
||||||
syncNodeEventLog(pSyncNode, eventLog);
|
|
||||||
taosMemoryFree(eventLog);
|
|
||||||
|
|
||||||
} else if (pMsg->seq == SYNC_SNAPSHOT_SEQ_END) {
|
} else if (pMsg->seq == SYNC_SNAPSHOT_SEQ_END) {
|
||||||
// end, finish FSM
|
// end, finish FSM
|
||||||
writeCode = pSyncNode->pFsm->FpSnapshotDoWrite(pSyncNode->pFsm, pReceiver->pWriter, pMsg->data, pMsg->dataLen);
|
snapshotReceiverFinish(pReceiver, pMsg);
|
||||||
ASSERT(writeCode == 0);
|
snapshotReceiverStop(pReceiver);
|
||||||
|
needRsp = true;
|
||||||
pSyncNode->pFsm->FpSnapshotStopWrite(pSyncNode->pFsm, pReceiver->pWriter, true);
|
|
||||||
if (pReceiver->snapshot.lastApplyIndex > pReceiver->pSyncNode->commitIndex) {
|
|
||||||
pReceiver->pSyncNode->commitIndex = pReceiver->snapshot.lastApplyIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
// pSyncNode->pLogStore->syncLogSetBeginIndex(pSyncNode->pLogStore, pMsg->lastIndex + 1);
|
|
||||||
pSyncNode->pLogStore->syncLogRestoreFromSnapshot(pSyncNode->pLogStore, pMsg->lastIndex);
|
|
||||||
|
|
||||||
// maybe update lastconfig
|
// maybe update lastconfig
|
||||||
if (pMsg->lastConfigIndex >= SYNC_INDEX_BEGIN) {
|
if (pMsg->lastConfigIndex >= SYNC_INDEX_BEGIN) {
|
||||||
|
@ -601,89 +670,83 @@ int32_t syncNodeOnSnapshotSendCb(SSyncNode *pSyncNode, SyncSnapshotSend *pMsg) {
|
||||||
syncNodeDoConfigChange(pSyncNode, &newSyncCfg, pMsg->lastConfigIndex);
|
syncNodeDoConfigChange(pSyncNode, &newSyncCfg, pMsg->lastConfigIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
SSnapshot snapshot;
|
|
||||||
pSyncNode->pFsm->FpGetSnapshotInfo(pSyncNode->pFsm, &snapshot);
|
|
||||||
|
|
||||||
do {
|
|
||||||
char *eventLog = snapshotReceiver2SimpleStr(pReceiver, "snapshot receiver finish, apply snapshot");
|
|
||||||
syncNodeEventLog(pSyncNode, eventLog);
|
|
||||||
taosMemoryFree(eventLog);
|
|
||||||
} while (0);
|
|
||||||
|
|
||||||
pReceiver->pWriter = NULL;
|
|
||||||
snapshotReceiverStop(pReceiver, true);
|
|
||||||
pReceiver->ack = pMsg->seq;
|
|
||||||
needRsp = true;
|
|
||||||
|
|
||||||
do {
|
|
||||||
char *eventLog = snapshotReceiver2SimpleStr(pReceiver, "snapshot receiver stop");
|
|
||||||
syncNodeEventLog(pSyncNode, eventLog);
|
|
||||||
taosMemoryFree(eventLog);
|
|
||||||
} while (0);
|
|
||||||
|
|
||||||
} else if (pMsg->seq == SYNC_SNAPSHOT_SEQ_FORCE_CLOSE) {
|
} else if (pMsg->seq == SYNC_SNAPSHOT_SEQ_FORCE_CLOSE) {
|
||||||
pSyncNode->pFsm->FpSnapshotStopWrite(pSyncNode->pFsm, pReceiver->pWriter, false);
|
// force close
|
||||||
snapshotReceiverStop(pReceiver, false);
|
snapshotReceiverForceStop(pReceiver);
|
||||||
needRsp = false;
|
needRsp = false;
|
||||||
|
|
||||||
do {
|
|
||||||
char *eventLog = snapshotReceiver2SimpleStr(pReceiver, "snapshot receiver force close");
|
|
||||||
syncNodeEventLog(pSyncNode, eventLog);
|
|
||||||
taosMemoryFree(eventLog);
|
|
||||||
} while (0);
|
|
||||||
|
|
||||||
} else if (pMsg->seq > SYNC_SNAPSHOT_SEQ_BEGIN && pMsg->seq < SYNC_SNAPSHOT_SEQ_END) {
|
} else if (pMsg->seq > SYNC_SNAPSHOT_SEQ_BEGIN && pMsg->seq < SYNC_SNAPSHOT_SEQ_END) {
|
||||||
// transfering
|
// transfering
|
||||||
if (pMsg->seq == pReceiver->ack + 1) {
|
if (pMsg->seq == pReceiver->ack + 1) {
|
||||||
writeCode =
|
snapshotReceiverGotData(pReceiver, pMsg);
|
||||||
pSyncNode->pFsm->FpSnapshotDoWrite(pSyncNode->pFsm, pReceiver->pWriter, pMsg->data, pMsg->dataLen);
|
|
||||||
ASSERT(writeCode == 0);
|
|
||||||
pReceiver->ack = pMsg->seq;
|
|
||||||
}
|
}
|
||||||
needRsp = true;
|
needRsp = true;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// error log
|
||||||
do {
|
do {
|
||||||
char *eventLog = snapshotReceiver2SimpleStr(pReceiver, "snapshot receiver receiving");
|
char logBuf[96];
|
||||||
syncNodeEventLog(pSyncNode, eventLog);
|
snprintf(logBuf, sizeof(logBuf), "snapshot receiver recv error seq:%d, my ack:%d", pMsg->seq, pReceiver->ack);
|
||||||
|
char *eventLog = snapshotReceiver2SimpleStr(pReceiver, logBuf);
|
||||||
|
syncNodeErrorLog(pSyncNode, eventLog);
|
||||||
taosMemoryFree(eventLog);
|
taosMemoryFree(eventLog);
|
||||||
} while (0);
|
} while (0);
|
||||||
|
|
||||||
} else {
|
return -1;
|
||||||
ASSERT(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// send ack
|
||||||
if (needRsp) {
|
if (needRsp) {
|
||||||
|
// build msg
|
||||||
SyncSnapshotRsp *pRspMsg = syncSnapshotRspBuild(pSyncNode->vgId);
|
SyncSnapshotRsp *pRspMsg = syncSnapshotRspBuild(pSyncNode->vgId);
|
||||||
pRspMsg->srcId = pSyncNode->myRaftId;
|
pRspMsg->srcId = pSyncNode->myRaftId;
|
||||||
pRspMsg->destId = pMsg->srcId;
|
pRspMsg->destId = pMsg->srcId;
|
||||||
pRspMsg->term = pSyncNode->pRaftStore->currentTerm;
|
pRspMsg->term = pSyncNode->pRaftStore->currentTerm;
|
||||||
pRspMsg->lastIndex = pMsg->lastIndex;
|
pRspMsg->lastIndex = pMsg->lastIndex;
|
||||||
pRspMsg->lastTerm = pMsg->lastTerm;
|
pRspMsg->lastTerm = pMsg->lastTerm;
|
||||||
pRspMsg->ack = pReceiver->ack;
|
pRspMsg->ack = pReceiver->ack; // receiver maybe already closed
|
||||||
pRspMsg->code = writeCode;
|
pRspMsg->code = 0;
|
||||||
pRspMsg->privateTerm = pReceiver->privateTerm;
|
pRspMsg->privateTerm = pReceiver->privateTerm; // receiver maybe already closed
|
||||||
|
|
||||||
|
// send msg
|
||||||
SRpcMsg rpcMsg;
|
SRpcMsg rpcMsg;
|
||||||
syncSnapshotRsp2RpcMsg(pRspMsg, &rpcMsg);
|
syncSnapshotRsp2RpcMsg(pRspMsg, &rpcMsg);
|
||||||
syncNodeSendMsgById(&(pRspMsg->destId), pSyncNode, &rpcMsg);
|
syncNodeSendMsgById(&(pRspMsg->destId), pSyncNode, &rpcMsg);
|
||||||
|
|
||||||
syncSnapshotRspDestroy(pRspMsg);
|
syncSnapshotRspDestroy(pRspMsg);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// error log
|
||||||
|
do {
|
||||||
|
char *eventLog = snapshotReceiver2SimpleStr(pReceiver, "snapshot receiver term not equal");
|
||||||
|
syncNodeErrorLog(pSyncNode, eventLog);
|
||||||
|
taosMemoryFree(eventLog);
|
||||||
|
} while (0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
syncNodeLog2("syncNodeOnSnapshotSendCb not follower", pSyncNode);
|
// error log
|
||||||
|
do {
|
||||||
|
char *eventLog = snapshotReceiver2SimpleStr(pReceiver, "snapshot receiver not follower");
|
||||||
|
syncNodeErrorLog(pSyncNode, eventLog);
|
||||||
|
taosMemoryFree(eventLog);
|
||||||
|
} while (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void snapshotSenderUpdateProgress(SSyncSnapshotSender *pSender, SyncSnapshotRsp *pMsg) {
|
||||||
|
ASSERT(pMsg->ack == pSender->seq);
|
||||||
|
pSender->ack = pMsg->ack;
|
||||||
|
++(pSender->seq);
|
||||||
|
}
|
||||||
|
|
||||||
// sender receives ack, set seq = ack + 1, send msg from seq
|
// sender receives ack, set seq = ack + 1, send msg from seq
|
||||||
// if ack == SYNC_SNAPSHOT_SEQ_END, stop sender
|
// if ack == SYNC_SNAPSHOT_SEQ_END, stop sender
|
||||||
int32_t syncNodeOnSnapshotRspCb(SSyncNode *pSyncNode, SyncSnapshotRsp *pMsg) {
|
int32_t syncNodeOnSnapshotRspCb(SSyncNode *pSyncNode, SyncSnapshotRsp *pMsg) {
|
||||||
// if already drop replica, do not process
|
// if already drop replica, do not process
|
||||||
if (!syncNodeInRaftGroup(pSyncNode, &(pMsg->srcId)) && pSyncNode->state == TAOS_SYNC_STATE_LEADER) {
|
if (!syncNodeInRaftGroup(pSyncNode, &(pMsg->srcId)) && pSyncNode->state == TAOS_SYNC_STATE_LEADER) {
|
||||||
sInfo("recv SyncSnapshotRsp maybe replica already dropped");
|
sError("vgId:%d, recv sync-snapshot-rsp, maybe replica already dropped", pSyncNode->vgId);
|
||||||
return 0;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get sender
|
// get sender
|
||||||
|
@ -695,27 +758,49 @@ int32_t syncNodeOnSnapshotRspCb(SSyncNode *pSyncNode, SyncSnapshotRsp *pMsg) {
|
||||||
if (pMsg->term == pSyncNode->pRaftStore->currentTerm) {
|
if (pMsg->term == pSyncNode->pRaftStore->currentTerm) {
|
||||||
// receiver ack is finish, close sender
|
// receiver ack is finish, close sender
|
||||||
if (pMsg->ack == SYNC_SNAPSHOT_SEQ_END) {
|
if (pMsg->ack == SYNC_SNAPSHOT_SEQ_END) {
|
||||||
pSender->finish = true;
|
snapshotSenderStop(pSender, true);
|
||||||
snapshotSenderStop(pSender);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// send next msg
|
// send next msg
|
||||||
if (pMsg->ack == pSender->seq) {
|
if (pMsg->ack == pSender->seq) {
|
||||||
// update sender ack
|
// update sender ack
|
||||||
pSender->ack = pMsg->ack;
|
snapshotSenderUpdateProgress(pSender, pMsg);
|
||||||
(pSender->seq)++;
|
|
||||||
snapshotSend(pSender);
|
snapshotSend(pSender);
|
||||||
|
|
||||||
} else if (pMsg->ack == pSender->seq - 1) {
|
} else if (pMsg->ack == pSender->seq - 1) {
|
||||||
snapshotReSend(pSender);
|
snapshotReSend(pSender);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
ASSERT(0);
|
do {
|
||||||
}
|
char logBuf[96];
|
||||||
|
snprintf(logBuf, sizeof(logBuf), "snapshot sender recv error ack:%d, my seq:%d", pMsg->ack, pSender->seq);
|
||||||
|
char *eventLog = snapshotSender2SimpleStr(pSender, logBuf);
|
||||||
|
syncNodeErrorLog(pSyncNode, eventLog);
|
||||||
|
taosMemoryFree(eventLog);
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
syncNodeLog2("syncNodeOnSnapshotRspCb not leader", pSyncNode);
|
// error log
|
||||||
|
do {
|
||||||
|
char *eventLog = snapshotSender2SimpleStr(pSender, "snapshot sender term not equal");
|
||||||
|
syncNodeErrorLog(pSyncNode, eventLog);
|
||||||
|
taosMemoryFree(eventLog);
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// error log
|
||||||
|
do {
|
||||||
|
char *eventLog = snapshotSender2SimpleStr(pSender, "snapshot sender not leader");
|
||||||
|
syncNodeErrorLog(pSyncNode, eventLog);
|
||||||
|
taosMemoryFree(eventLog);
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -229,7 +229,7 @@ typedef struct {
|
||||||
|
|
||||||
SAsyncPool* transCreateAsyncPool(uv_loop_t* loop, int sz, void* arg, AsyncCB cb);
|
SAsyncPool* transCreateAsyncPool(uv_loop_t* loop, int sz, void* arg, AsyncCB cb);
|
||||||
void transDestroyAsyncPool(SAsyncPool* pool);
|
void transDestroyAsyncPool(SAsyncPool* pool);
|
||||||
int transSendAsync(SAsyncPool* pool, queue* mq);
|
int transAsyncSend(SAsyncPool* pool, queue* mq);
|
||||||
|
|
||||||
#define TRANS_DESTROY_ASYNC_POOL_MSG(pool, msgType, freeFunc) \
|
#define TRANS_DESTROY_ASYNC_POOL_MSG(pool, msgType, freeFunc) \
|
||||||
do { \
|
do { \
|
||||||
|
|
|
@ -964,7 +964,7 @@ void cliSendQuit(SCliThrd* thrd) {
|
||||||
// cli can stop gracefully
|
// cli can stop gracefully
|
||||||
SCliMsg* msg = taosMemoryCalloc(1, sizeof(SCliMsg));
|
SCliMsg* msg = taosMemoryCalloc(1, sizeof(SCliMsg));
|
||||||
msg->type = Quit;
|
msg->type = Quit;
|
||||||
transSendAsync(thrd->asyncPool, &msg->q);
|
transAsyncSend(thrd->asyncPool, &msg->q);
|
||||||
}
|
}
|
||||||
void cliWalkCb(uv_handle_t* handle, void* arg) {
|
void cliWalkCb(uv_handle_t* handle, void* arg) {
|
||||||
if (!uv_is_closing(handle)) {
|
if (!uv_is_closing(handle)) {
|
||||||
|
@ -1131,7 +1131,7 @@ void transReleaseCliHandle(void* handle) {
|
||||||
cmsg->msg = tmsg;
|
cmsg->msg = tmsg;
|
||||||
cmsg->type = Release;
|
cmsg->type = Release;
|
||||||
|
|
||||||
transSendAsync(pThrd->asyncPool, &cmsg->q);
|
transAsyncSend(pThrd->asyncPool, &cmsg->q);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1164,7 +1164,7 @@ void transSendRequest(void* shandle, const SEpSet* pEpSet, STransMsg* pReq, STra
|
||||||
STraceId* trace = &pReq->info.traceId;
|
STraceId* trace = &pReq->info.traceId;
|
||||||
tGTrace("%s send request at thread:%08" PRId64 ", dst: %s:%d, app:%p", transLabel(pTransInst), pThrd->pid,
|
tGTrace("%s send request at thread:%08" PRId64 ", dst: %s:%d, app:%p", transLabel(pTransInst), pThrd->pid,
|
||||||
EPSET_GET_INUSE_IP(&pCtx->epSet), EPSET_GET_INUSE_PORT(&pCtx->epSet), pReq->info.ahandle);
|
EPSET_GET_INUSE_IP(&pCtx->epSet), EPSET_GET_INUSE_PORT(&pCtx->epSet), pReq->info.ahandle);
|
||||||
ASSERT(transSendAsync(pThrd->asyncPool, &(cliMsg->q)) == 0);
|
ASSERT(transAsyncSend(pThrd->asyncPool, &(cliMsg->q)) == 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1198,7 +1198,7 @@ void transSendRecv(void* shandle, const SEpSet* pEpSet, STransMsg* pReq, STransM
|
||||||
tGTrace("%s send request at thread:%08" PRId64 ", dst: %s:%d, app:%p", transLabel(pTransInst), pThrd->pid,
|
tGTrace("%s send request at thread:%08" PRId64 ", dst: %s:%d, app:%p", transLabel(pTransInst), pThrd->pid,
|
||||||
EPSET_GET_INUSE_IP(&pCtx->epSet), EPSET_GET_INUSE_PORT(&pCtx->epSet), pReq->info.ahandle);
|
EPSET_GET_INUSE_IP(&pCtx->epSet), EPSET_GET_INUSE_PORT(&pCtx->epSet), pReq->info.ahandle);
|
||||||
|
|
||||||
transSendAsync(pThrd->asyncPool, &(cliMsg->q));
|
transAsyncSend(pThrd->asyncPool, &(cliMsg->q));
|
||||||
tsem_wait(sem);
|
tsem_wait(sem);
|
||||||
tsem_destroy(sem);
|
tsem_destroy(sem);
|
||||||
taosMemoryFree(sem);
|
taosMemoryFree(sem);
|
||||||
|
@ -1227,7 +1227,7 @@ void transSetDefaultAddr(void* shandle, const char* ip, const char* fqdn) {
|
||||||
SCliThrd* thrd = ((SCliObj*)pTransInst->tcphandle)->pThreadObj[i];
|
SCliThrd* thrd = ((SCliObj*)pTransInst->tcphandle)->pThreadObj[i];
|
||||||
tDebug("%s update epset at thread:%08" PRId64 "", pTransInst->label, thrd->pid);
|
tDebug("%s update epset at thread:%08" PRId64 "", pTransInst->label, thrd->pid);
|
||||||
|
|
||||||
transSendAsync(thrd->asyncPool, &(cliMsg->q));
|
transAsyncSend(thrd->asyncPool, &(cliMsg->q));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -204,7 +204,7 @@ void transDestroyAsyncPool(SAsyncPool* pool) {
|
||||||
taosMemoryFree(pool->asyncs);
|
taosMemoryFree(pool->asyncs);
|
||||||
taosMemoryFree(pool);
|
taosMemoryFree(pool);
|
||||||
}
|
}
|
||||||
int transSendAsync(SAsyncPool* pool, queue* q) {
|
int transAsyncSend(SAsyncPool* pool, queue* q) {
|
||||||
int idx = pool->index;
|
int idx = pool->index;
|
||||||
idx = idx % pool->nAsync;
|
idx = idx % pool->nAsync;
|
||||||
// no need mutex here
|
// no need mutex here
|
||||||
|
|
|
@ -983,7 +983,7 @@ void sendQuitToWorkThrd(SWorkThrd* pThrd) {
|
||||||
SSvrMsg* msg = taosMemoryCalloc(1, sizeof(SSvrMsg));
|
SSvrMsg* msg = taosMemoryCalloc(1, sizeof(SSvrMsg));
|
||||||
msg->type = Quit;
|
msg->type = Quit;
|
||||||
tDebug("server send quit msg to work thread");
|
tDebug("server send quit msg to work thread");
|
||||||
transSendAsync(pThrd->asyncPool, &msg->q);
|
transAsyncSend(pThrd->asyncPool, &msg->q);
|
||||||
}
|
}
|
||||||
|
|
||||||
void transCloseServer(void* arg) {
|
void transCloseServer(void* arg) {
|
||||||
|
|
|
@ -582,10 +582,10 @@ TAOS_DEFINE_ERROR(TSDB_CODE_TSMA_INVALID_PTR, "Invalid tsma pointe
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_TSMA_INVALID_PARA, "Invalid tsma parameters")
|
TAOS_DEFINE_ERROR(TSDB_CODE_TSMA_INVALID_PARA, "Invalid tsma parameters")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_TSMA_NO_INDEX_IN_CACHE, "No tsma index in cache")
|
TAOS_DEFINE_ERROR(TSDB_CODE_TSMA_NO_INDEX_IN_CACHE, "No tsma index in cache")
|
||||||
|
|
||||||
|
|
||||||
//rsma
|
//rsma
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_RSMA_INVALID_ENV, "Invalid rsma env")
|
TAOS_DEFINE_ERROR(TSDB_CODE_RSMA_INVALID_ENV, "Invalid rsma env")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_RSMA_INVALID_STAT, "Invalid rsma state")
|
TAOS_DEFINE_ERROR(TSDB_CODE_RSMA_INVALID_STAT, "Invalid rsma state")
|
||||||
|
TAOS_DEFINE_ERROR(TSDB_CODE_RSMA_QTASKINFO_CREATE, "Rsma qtaskinfo creation error")
|
||||||
|
|
||||||
//tq
|
//tq
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_TQ_NO_COMMITTED_OFFSET, "No committed offset")
|
TAOS_DEFINE_ERROR(TSDB_CODE_TQ_NO_COMMITTED_OFFSET, "No committed offset")
|
||||||
|
|
|
@ -87,6 +87,12 @@ class ConfigureyCluster:
|
||||||
else:
|
else:
|
||||||
tdLog.exit("create cluster with %d dnode but check dnode not ready within 5s ! "%self.dnodeNums)
|
tdLog.exit("create cluster with %d dnode but check dnode not ready within 5s ! "%self.dnodeNums)
|
||||||
|
|
||||||
|
def checkConnectStatus(self,dnodeNo,hostname=hostname):
|
||||||
|
dnodeNo = int(dnodeNo)
|
||||||
|
tdLog.info("check dnode-%d connection"%(dnodeNo+1))
|
||||||
|
hostname = socket.gethostname()
|
||||||
|
port = 6030 + dnodeNo*100
|
||||||
|
connectToDnode = tdCom.newcon(host=hostname,port=port)
|
||||||
|
return connectToDnode
|
||||||
|
|
||||||
cluster = ConfigureyCluster()
|
cluster = ConfigureyCluster()
|
|
@ -379,6 +379,11 @@ class TDCom:
|
||||||
tdLog.info("cfgPath: %s" % cfgPath)
|
tdLog.info("cfgPath: %s" % cfgPath)
|
||||||
return cfgPath
|
return cfgPath
|
||||||
|
|
||||||
|
def newcon(self,host='localhost',port=6030,user='root',password='taosdata'):
|
||||||
|
con=taos.connect(host=host, user=user, password=password, port=port)
|
||||||
|
print(con)
|
||||||
|
return con
|
||||||
|
|
||||||
def newcur(self,host='localhost',port=6030,user='root',password='taosdata'):
|
def newcur(self,host='localhost',port=6030,user='root',password='taosdata'):
|
||||||
cfgPath = self.getClientCfgPath()
|
cfgPath = self.getClientCfgPath()
|
||||||
con=taos.connect(host=host, user=user, password=password, config=cfgPath, port=port)
|
con=taos.connect(host=host, user=user, password=password, config=cfgPath, port=port)
|
||||||
|
@ -637,5 +642,13 @@ class TDCom:
|
||||||
column_value_str = ", ".join(str(v) for v in column_value_list)
|
column_value_str = ", ".join(str(v) for v in column_value_list)
|
||||||
insert_sql = f'insert into {dbname}.{tbname} values ({column_value_str});'
|
insert_sql = f'insert into {dbname}.{tbname} values ({column_value_str});'
|
||||||
tsql.execute(insert_sql)
|
tsql.execute(insert_sql)
|
||||||
|
def getOneRow(self, location, containElm):
|
||||||
|
res_list = list()
|
||||||
|
if 0 <= location < tdSql.queryRows:
|
||||||
|
for row in tdSql.queryResult:
|
||||||
|
if row[location] == containElm:
|
||||||
|
res_list.append(row)
|
||||||
|
return res_list
|
||||||
|
else:
|
||||||
|
tdLog.exit(f"getOneRow out of range: row_index={location} row_count={self.query_row}")
|
||||||
tdCom = TDCom()
|
tdCom = TDCom()
|
||||||
|
|
|
@ -8,21 +8,35 @@
|
||||||
./test.sh -f tsim/user/privilege_sysinfo.sim
|
./test.sh -f tsim/user/privilege_sysinfo.sim
|
||||||
|
|
||||||
## ---- db
|
## ---- db
|
||||||
./test.sh -f tsim/db/create_all_options.sim
|
|
||||||
./test.sh -f tsim/db/alter_option.sim
|
./test.sh -f tsim/db/alter_option.sim
|
||||||
./test.sh -f tsim/db/alter_replica_13.sim
|
./test.sh -f tsim/db/alter_replica_13.sim
|
||||||
#./test.sh -f tsim/db/alter_replica_31.sim
|
./test.sh -f tsim/db/alter_replica_31.sim
|
||||||
./test.sh -f tsim/db/basic1.sim
|
./test.sh -f tsim/db/basic1.sim
|
||||||
./test.sh -f tsim/db/basic2.sim
|
./test.sh -f tsim/db/basic2.sim
|
||||||
./test.sh -f tsim/db/basic3.sim
|
./test.sh -f tsim/db/basic3.sim
|
||||||
./test.sh -f tsim/db/basic6.sim
|
./test.sh -f tsim/db/basic6.sim
|
||||||
./test.sh -f tsim/db/basic7.sim
|
./test.sh -f tsim/db/basic7.sim
|
||||||
|
#./test.sh -f tsim/db/commit.sim
|
||||||
|
./test.sh -f tsim/db/create_all_options.sim
|
||||||
|
#./test.sh -f tsim/db/delete_part.sim
|
||||||
|
#./test.sh -f tsim/db/delete.sim
|
||||||
./test.sh -f tsim/db/error1.sim
|
./test.sh -f tsim/db/error1.sim
|
||||||
./test.sh -f tsim/db/taosdlog.sim
|
./test.sh -f tsim/db/taosdlog.sim
|
||||||
|
|
||||||
# ---- dnode
|
# ---- dnode
|
||||||
./test.sh -f tsim/dnode/balance_replica1.sim
|
./test.sh -f tsim/dnode/balance_replica1.sim
|
||||||
#./test.sh -f tsim/dnode/balance_replica3.sim
|
./test.sh -f tsim/dnode/balance_replica3.sim
|
||||||
|
./test.sh -f tsim/dnode/balance1.sim
|
||||||
|
./test.sh -f tsim/dnode/balance2.sim
|
||||||
|
./test.sh -f tsim/dnode/balance3.sim
|
||||||
|
./test.sh -f tsim/dnode/balancex.sim
|
||||||
|
#./test.sh -f tsim/dnode/cluster_alter.sim
|
||||||
|
#./test.sh -f tsim/dnode/cluster_balance1.sim
|
||||||
|
#./test.sh -f tsim/dnode/cluster_balance2.sim
|
||||||
|
#./test.sh -f tsim/dnode/cluster_balance3.sim
|
||||||
|
#./test.sh -f tsim/dnode/cluster_cache.sim
|
||||||
|
#./test.sh -f tsim/dnode/cluster_flowctrl.sim
|
||||||
|
#./test.sh -f tsim/dnode/cluster_vgroup100.sim
|
||||||
./test.sh -f tsim/dnode/create_dnode.sim
|
./test.sh -f tsim/dnode/create_dnode.sim
|
||||||
./test.sh -f tsim/dnode/drop_dnode_has_mnode.sim
|
./test.sh -f tsim/dnode/drop_dnode_has_mnode.sim
|
||||||
./test.sh -f tsim/dnode/drop_dnode_has_qnode_snode.sim
|
./test.sh -f tsim/dnode/drop_dnode_has_qnode_snode.sim
|
||||||
|
@ -30,11 +44,13 @@
|
||||||
./test.sh -f tsim/dnode/drop_dnode_has_vnode_replica3.sim
|
./test.sh -f tsim/dnode/drop_dnode_has_vnode_replica3.sim
|
||||||
./test.sh -f tsim/dnode/drop_dnode_has_multi_vnode_replica1.sim
|
./test.sh -f tsim/dnode/drop_dnode_has_multi_vnode_replica1.sim
|
||||||
./test.sh -f tsim/dnode/drop_dnode_has_multi_vnode_replica3.sim
|
./test.sh -f tsim/dnode/drop_dnode_has_multi_vnode_replica3.sim
|
||||||
|
./test.sh -f tsim/dnode/offline_reason.sim
|
||||||
./test.sh -f tsim/dnode/redistribute_vgroup_replica1.sim
|
./test.sh -f tsim/dnode/redistribute_vgroup_replica1.sim
|
||||||
./test.sh -f tsim/dnode/redistribute_vgroup_replica3_v1_leader.sim
|
./test.sh -f tsim/dnode/redistribute_vgroup_replica3_v1_leader.sim
|
||||||
./test.sh -f tsim/dnode/redistribute_vgroup_replica3_v1_follower.sim
|
./test.sh -f tsim/dnode/redistribute_vgroup_replica3_v1_follower.sim
|
||||||
./test.sh -f tsim/dnode/redistribute_vgroup_replica3_v2.sim
|
./test.sh -f tsim/dnode/redistribute_vgroup_replica3_v2.sim
|
||||||
./test.sh -f tsim/dnode/redistribute_vgroup_replica3_v3.sim
|
./test.sh -f tsim/dnode/redistribute_vgroup_replica3_v3.sim
|
||||||
|
./test.sh -f tsim/dnode/vnode_clean.sim
|
||||||
|
|
||||||
# ---- insert
|
# ---- insert
|
||||||
./test.sh -f tsim/insert/basic0.sim
|
./test.sh -f tsim/insert/basic0.sim
|
||||||
|
@ -72,7 +88,7 @@
|
||||||
./test.sh -f tsim/mnode/basic2.sim
|
./test.sh -f tsim/mnode/basic2.sim
|
||||||
./test.sh -f tsim/mnode/basic3.sim
|
./test.sh -f tsim/mnode/basic3.sim
|
||||||
./test.sh -f tsim/mnode/basic4.sim
|
./test.sh -f tsim/mnode/basic4.sim
|
||||||
#./test.sh -f tsim/mnode/basic5.sim
|
./test.sh -f tsim/mnode/basic5.sim
|
||||||
|
|
||||||
# ---- show
|
# ---- show
|
||||||
./test.sh -f tsim/show/basic.sim
|
./test.sh -f tsim/show/basic.sim
|
||||||
|
@ -85,6 +101,7 @@
|
||||||
./test.sh -f tsim/stream/basic1.sim
|
./test.sh -f tsim/stream/basic1.sim
|
||||||
./test.sh -f tsim/stream/basic2.sim
|
./test.sh -f tsim/stream/basic2.sim
|
||||||
./test.sh -f tsim/stream/distributeInterval0.sim
|
./test.sh -f tsim/stream/distributeInterval0.sim
|
||||||
|
# ./test.sh -f tsim/stream/distributeIntervalRetrive0.sim
|
||||||
# ./test.sh -f tsim/stream/distributesession0.sim
|
# ./test.sh -f tsim/stream/distributesession0.sim
|
||||||
# ./test.sh -f tsim/stream/session0.sim
|
# ./test.sh -f tsim/stream/session0.sim
|
||||||
./test.sh -f tsim/stream/session1.sim
|
./test.sh -f tsim/stream/session1.sim
|
||||||
|
@ -96,7 +113,6 @@
|
||||||
./test.sh -f tsim/stream/schedSnode.sim
|
./test.sh -f tsim/stream/schedSnode.sim
|
||||||
./test.sh -f tsim/stream/windowClose.sim
|
./test.sh -f tsim/stream/windowClose.sim
|
||||||
|
|
||||||
|
|
||||||
# ---- transaction
|
# ---- transaction
|
||||||
./test.sh -f tsim/trans/lossdata1.sim
|
./test.sh -f tsim/trans/lossdata1.sim
|
||||||
./test.sh -f tsim/trans/create_db.sim
|
./test.sh -f tsim/trans/create_db.sim
|
||||||
|
@ -155,6 +171,19 @@
|
||||||
# --- valgrind
|
# --- valgrind
|
||||||
./test.sh -f tsim/valgrind/checkError.sim -v
|
./test.sh -f tsim/valgrind/checkError.sim -v
|
||||||
|
|
||||||
|
# --- vnode
|
||||||
|
#./test.sh -f tsim/vnode/replica3_basic.sim
|
||||||
|
#./test.sh -f tsim/vnode/replica3_repeat.sim
|
||||||
|
./test.sh -f tsim/vnode/replica3_vgroup.sim
|
||||||
|
#./test.sh -f tsim/vnode/replica3_many.sim
|
||||||
|
#./test.sh -f tsim/vnode/replica3_import.sim
|
||||||
|
./test.sh -f tsim/vnode/stable_balance_replica1.sim
|
||||||
|
./test.sh -f tsim/vnode/stable_dnode2_stop.sim
|
||||||
|
./test.sh -f tsim/vnode/stable_dnode2.sim
|
||||||
|
./test.sh -f tsim/vnode/stable_dnode3.sim
|
||||||
|
./test.sh -f tsim/vnode/stable_replica3_dnode6.sim
|
||||||
|
./test.sh -f tsim/vnode/stable_replica3_vnode3.sim
|
||||||
|
|
||||||
# --- sync
|
# --- sync
|
||||||
./test.sh -f tsim/sync/3Replica1VgElect.sim
|
./test.sh -f tsim/sync/3Replica1VgElect.sim
|
||||||
./test.sh -f tsim/sync/3Replica5VgElect.sim
|
./test.sh -f tsim/sync/3Replica5VgElect.sim
|
||||||
|
|
|
@ -1,56 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
echo "Executing move_dnode.sh"
|
|
||||||
|
|
||||||
UNAME_BIN=`which uname`
|
|
||||||
OS_TYPE=`$UNAME_BIN`
|
|
||||||
|
|
||||||
SCRIPT_DIR=`dirname $0`
|
|
||||||
cd $SCRIPT_DIR/../
|
|
||||||
SCRIPT_DIR=`pwd`
|
|
||||||
echo "SCRIPT_DIR: $SCRIPT_DIR"
|
|
||||||
|
|
||||||
IN_TDINTERNAL="community"
|
|
||||||
if [[ "$SCRIPT_DIR" == *"$IN_TDINTERNAL"* ]]; then
|
|
||||||
cd ../../..
|
|
||||||
else
|
|
||||||
cd ../../
|
|
||||||
fi
|
|
||||||
|
|
||||||
TAOS_DIR=`pwd`
|
|
||||||
TAOSD_DIR=`find . -name "taosd"|grep bin|head -n1`
|
|
||||||
|
|
||||||
if [[ "$OS_TYPE" != "Darwin" ]]; then
|
|
||||||
cut_opt="--field="
|
|
||||||
else
|
|
||||||
cut_opt="-f "
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$TAOSD_DIR" == *"$IN_TDINTERNAL"* ]]; then
|
|
||||||
BIN_DIR=`find . -name "taosd"|grep bin|head -n1|cut -d '/' ${cut_opt}2,3`
|
|
||||||
else
|
|
||||||
BIN_DIR=`find . -name "taosd"|grep bin|head -n1|cut -d '/' ${cut_opt}2`
|
|
||||||
fi
|
|
||||||
|
|
||||||
BUILD_DIR=$TAOS_DIR/$BIN_DIR/build
|
|
||||||
|
|
||||||
SIM_DIR=$TAOS_DIR/sim
|
|
||||||
|
|
||||||
NODE_DIR=$SIM_DIR/$NODE_NAME
|
|
||||||
|
|
||||||
if [ -d "$SIM_DIR/$2" ];then
|
|
||||||
rm -rf $SIM_DIR/$2
|
|
||||||
fi
|
|
||||||
mv $SIM_DIR/$1 $SIM_DIR/$2
|
|
||||||
|
|
||||||
if [[ $2 =~ "dnode2" ]];then
|
|
||||||
sed -i 's/serverPort 7100/serverPort 7200/g' $SIM_DIR/$2/cfg/taos.cfg
|
|
||||||
sed -i 's/dnode1/dnode2/g' $SIM_DIR/$2/cfg/taos.cfg
|
|
||||||
sed -i 's/7100/7200/g' $SIM_DIR/$2/data/dnode/dnodeEps.json
|
|
||||||
elif [[ $2 =~ "dnode4" ]];then
|
|
||||||
sed -i 's/serverPort 7100/serverPort 7400/g' $SIM_DIR/$2/cfg/taos.cfg
|
|
||||||
sed -i 's/dnode1/dnode4/g' $SIM_DIR/$2/cfg/taos.cfg
|
|
||||||
sed -i 's/7100/7400/g' $SIM_DIR/dnode2/data/dnode/dnodeEps.json
|
|
||||||
sed -i 's/7100/7400/g' $SIM_DIR/dnode3/data/dnode/dnodeEps.json
|
|
||||||
sed -i 's/7100/7400/g' $SIM_DIR/$2/data/dnode/dnodeEps.json
|
|
||||||
fi
|
|
|
@ -19,7 +19,7 @@ for /F "usebackq tokens=*" %%i in (!caseFile!) do (
|
||||||
call :GetTimeSeconds !time!
|
call :GetTimeSeconds !time!
|
||||||
set time1=!_timeTemp!
|
set time1=!_timeTemp!
|
||||||
echo Start at !time!
|
echo Start at !time!
|
||||||
call !line:./test.sh=wtest.bat! > result_!a!.txt 2>error_!a!.txt
|
call !line:./test.sh=wtest.bat! > result_!a!.txt 2>error_!a!.txt || set /a errorlevel=8
|
||||||
if errorlevel 1 ( call :colorEcho 0c "failed" &echo. && set /a exitNum=8 && echo %%i >>failed.txt ) else ( call :colorEcho 0a "Success" &echo. )
|
if errorlevel 1 ( call :colorEcho 0c "failed" &echo. && set /a exitNum=8 && echo %%i >>failed.txt ) else ( call :colorEcho 0a "Success" &echo. )
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue