Merge branch 'develop' into feature/TD-5331
This commit is contained in:
commit
152483045b
|
|
@ -83,6 +83,8 @@ IF (TD_ARM_64)
|
||||||
ADD_DEFINITIONS(-DUSE_LIBICONV)
|
ADD_DEFINITIONS(-DUSE_LIBICONV)
|
||||||
MESSAGE(STATUS "arm64 is defined")
|
MESSAGE(STATUS "arm64 is defined")
|
||||||
SET(COMMON_FLAGS "-Wall -Werror -fPIC -fsigned-char -fpack-struct=8 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE")
|
SET(COMMON_FLAGS "-Wall -Werror -fPIC -fsigned-char -fpack-struct=8 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE")
|
||||||
|
|
||||||
|
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/lua/src)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
IF (TD_ARM_32)
|
IF (TD_ARM_32)
|
||||||
|
|
@ -91,6 +93,8 @@ IF (TD_ARM_32)
|
||||||
ADD_DEFINITIONS(-DUSE_LIBICONV)
|
ADD_DEFINITIONS(-DUSE_LIBICONV)
|
||||||
MESSAGE(STATUS "arm32 is defined")
|
MESSAGE(STATUS "arm32 is defined")
|
||||||
SET(COMMON_FLAGS "-Wall -Werror -fPIC -fsigned-char -fpack-struct=8 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE -Wno-pointer-to-int-cast -Wno-int-to-pointer-cast -Wno-incompatible-pointer-types ")
|
SET(COMMON_FLAGS "-Wall -Werror -fPIC -fsigned-char -fpack-struct=8 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE -Wno-pointer-to-int-cast -Wno-int-to-pointer-cast -Wno-incompatible-pointer-types ")
|
||||||
|
|
||||||
|
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/lua/src)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
IF (TD_MIPS_64)
|
IF (TD_MIPS_64)
|
||||||
|
|
@ -143,6 +147,7 @@ IF (TD_LINUX)
|
||||||
|
|
||||||
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/cJson/inc)
|
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/cJson/inc)
|
||||||
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/lz4/inc)
|
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/lz4/inc)
|
||||||
|
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/lua/src)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
IF (TD_DARWIN_64)
|
IF (TD_DARWIN_64)
|
||||||
|
|
@ -164,6 +169,7 @@ IF (TD_DARWIN_64)
|
||||||
SET(RELEASE_FLAGS "-Og")
|
SET(RELEASE_FLAGS "-Og")
|
||||||
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/cJson/inc)
|
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/cJson/inc)
|
||||||
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/lz4/inc)
|
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/lz4/inc)
|
||||||
|
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/lua/src)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
IF (TD_WINDOWS)
|
IF (TD_WINDOWS)
|
||||||
|
|
@ -194,6 +200,7 @@ IF (TD_WINDOWS)
|
||||||
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/regex)
|
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/regex)
|
||||||
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/wepoll/inc)
|
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/wepoll/inc)
|
||||||
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/MsvcLibX/include)
|
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/MsvcLibX/include)
|
||||||
|
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/lua/src)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
IF (TD_WINDOWS_64)
|
IF (TD_WINDOWS_64)
|
||||||
|
|
|
||||||
|
|
@ -182,7 +182,13 @@ function install_jemalloc() {
|
||||||
${csudo} /usr/bin/install -c -d /usr/local/share/man/man3
|
${csudo} /usr/bin/install -c -d /usr/local/share/man/man3
|
||||||
${csudo} /usr/bin/install -c -m 644 ${jemalloc_dir}/share/man/man3/jemalloc.3 /usr/local/share/man/man3
|
${csudo} /usr/bin/install -c -m 644 ${jemalloc_dir}/share/man/man3/jemalloc.3 /usr/local/share/man/man3
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ -d /etc/ld.so.conf.d ]; then
|
||||||
|
${csudo} echo "/usr/local/lib" > /etc/ld.so.conf.d/jemalloc.conf
|
||||||
${csudo} ldconfig
|
${csudo} ldconfig
|
||||||
|
else
|
||||||
|
echo "/etc/ld.so.conf.d not found!"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -195,6 +195,15 @@ if [ "$pagMode" == "lite" ]; then
|
||||||
pkg_name=${pkg_name}-Lite
|
pkg_name=${pkg_name}-Lite
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "$verType" == "beta" ]; then
|
||||||
|
pkg_name=${pkg_name}-${verType}
|
||||||
|
elif [ "$verType" == "stable" ]; then
|
||||||
|
pkg_name=${pkg_name}
|
||||||
|
else
|
||||||
|
echo "unknow verType, nor stable or beta"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "$osType" != "Darwin" ]; then
|
if [ "$osType" != "Darwin" ]; then
|
||||||
tar -zcv -f "$(basename ${pkg_name}).tar.gz" $(basename ${install_dir}) --remove-files || :
|
tar -zcv -f "$(basename ${pkg_name}).tar.gz" $(basename ${install_dir}) --remove-files || :
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,39 @@ mkdir -p ${install_dir}
|
||||||
mkdir -p ${install_dir}/inc && cp ${header_files} ${install_dir}/inc
|
mkdir -p ${install_dir}/inc && cp ${header_files} ${install_dir}/inc
|
||||||
mkdir -p ${install_dir}/cfg && cp ${cfg_dir}/taos.cfg ${install_dir}/cfg/taos.cfg
|
mkdir -p ${install_dir}/cfg && cp ${cfg_dir}/taos.cfg ${install_dir}/cfg/taos.cfg
|
||||||
|
|
||||||
|
if [ -f ${build_dir}/bin/jemalloc-config ]; then
|
||||||
|
mkdir -p ${install_dir}/jemalloc/{bin,lib,lib/pkgconfig,include/jemalloc,share/doc/jemalloc,share/man/man3}
|
||||||
|
cp ${build_dir}/bin/jemalloc-config ${install_dir}/jemalloc/bin
|
||||||
|
if [ -f ${build_dir}/bin/jemalloc.sh ]; then
|
||||||
|
cp ${build_dir}/bin/jemalloc.sh ${install_dir}/jemalloc/bin
|
||||||
|
fi
|
||||||
|
if [ -f ${build_dir}/bin/jeprof ]; then
|
||||||
|
cp ${build_dir}/bin/jeprof ${install_dir}/jemalloc/bin
|
||||||
|
fi
|
||||||
|
if [ -f ${build_dir}/include/jemalloc/jemalloc.h ]; then
|
||||||
|
cp ${build_dir}/include/jemalloc/jemalloc.h ${install_dir}/jemalloc/include/jemalloc
|
||||||
|
fi
|
||||||
|
if [ -f ${build_dir}/lib/libjemalloc.so.2 ]; then
|
||||||
|
cp ${build_dir}/lib/libjemalloc.so.2 ${install_dir}/jemalloc/lib
|
||||||
|
ln -sf libjemalloc.so.2 ${install_dir}/jemalloc/lib/libjemalloc.so
|
||||||
|
fi
|
||||||
|
if [ -f ${build_dir}/lib/libjemalloc.a ]; then
|
||||||
|
cp ${build_dir}/lib/libjemalloc.a ${install_dir}/jemalloc/lib
|
||||||
|
fi
|
||||||
|
if [ -f ${build_dir}/lib/libjemalloc_pic.a ]; then
|
||||||
|
cp ${build_dir}/lib/libjemalloc_pic.a ${install_dir}/jemalloc/lib
|
||||||
|
fi
|
||||||
|
if [ -f ${build_dir}/lib/pkgconfig/jemalloc.pc ]; then
|
||||||
|
cp ${build_dir}/lib/pkgconfig/jemalloc.pc ${install_dir}/jemalloc/lib/pkgconfig
|
||||||
|
fi
|
||||||
|
if [ -f ${build_dir}/share/doc/jemalloc/jemalloc.html ]; then
|
||||||
|
cp ${build_dir}/share/doc/jemalloc/jemalloc.html ${install_dir}/jemalloc/share/doc/jemalloc
|
||||||
|
fi
|
||||||
|
if [ -f ${build_dir}/share/man/man3/jemalloc.3 ]; then
|
||||||
|
cp ${build_dir}/share/man/man3/jemalloc.3 ${install_dir}/jemalloc/share/man/man3
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
sed -i '/dataDir/ {s/taos/power/g}' ${install_dir}/cfg/taos.cfg
|
sed -i '/dataDir/ {s/taos/power/g}' ${install_dir}/cfg/taos.cfg
|
||||||
sed -i '/logDir/ {s/taos/power/g}' ${install_dir}/cfg/taos.cfg
|
sed -i '/logDir/ {s/taos/power/g}' ${install_dir}/cfg/taos.cfg
|
||||||
sed -i "s/TDengine/PowerDB/g" ${install_dir}/cfg/taos.cfg
|
sed -i "s/TDengine/PowerDB/g" ${install_dir}/cfg/taos.cfg
|
||||||
|
|
|
||||||
|
|
@ -37,13 +37,13 @@ ELSEIF (TD_DARWIN)
|
||||||
|
|
||||||
# set the static lib name
|
# set the static lib name
|
||||||
ADD_LIBRARY(taos_static STATIC ${SRC})
|
ADD_LIBRARY(taos_static STATIC ${SRC})
|
||||||
TARGET_LINK_LIBRARIES(taos_static common query trpc tutil pthread m)
|
TARGET_LINK_LIBRARIES(taos_static common query trpc tutil pthread m lua)
|
||||||
SET_TARGET_PROPERTIES(taos_static PROPERTIES OUTPUT_NAME "taos_static")
|
SET_TARGET_PROPERTIES(taos_static PROPERTIES OUTPUT_NAME "taos_static")
|
||||||
SET_TARGET_PROPERTIES(taos_static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
|
SET_TARGET_PROPERTIES(taos_static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
|
||||||
|
|
||||||
# generate dynamic library (*.dylib)
|
# generate dynamic library (*.dylib)
|
||||||
ADD_LIBRARY(taos SHARED ${SRC})
|
ADD_LIBRARY(taos SHARED ${SRC})
|
||||||
TARGET_LINK_LIBRARIES(taos common query trpc tutil pthread m)
|
TARGET_LINK_LIBRARIES(taos common query trpc tutil pthread m lua)
|
||||||
SET_TARGET_PROPERTIES(taos PROPERTIES CLEAN_DIRECT_OUTPUT 1)
|
SET_TARGET_PROPERTIES(taos PROPERTIES CLEAN_DIRECT_OUTPUT 1)
|
||||||
|
|
||||||
#set version of .dylib
|
#set version of .dylib
|
||||||
|
|
@ -68,19 +68,19 @@ ELSEIF (TD_WINDOWS)
|
||||||
IF (NOT TD_GODLL)
|
IF (NOT TD_GODLL)
|
||||||
SET_TARGET_PROPERTIES(taos PROPERTIES LINK_FLAGS /DEF:${TD_COMMUNITY_DIR}/src/client/src/taos.def)
|
SET_TARGET_PROPERTIES(taos PROPERTIES LINK_FLAGS /DEF:${TD_COMMUNITY_DIR}/src/client/src/taos.def)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
TARGET_LINK_LIBRARIES(taos trpc tutil query)
|
TARGET_LINK_LIBRARIES(taos trpc tutil query lua)
|
||||||
|
|
||||||
ELSEIF (TD_DARWIN)
|
ELSEIF (TD_DARWIN)
|
||||||
SET(CMAKE_MACOSX_RPATH 1)
|
SET(CMAKE_MACOSX_RPATH 1)
|
||||||
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/jni/linux)
|
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/jni/linux)
|
||||||
|
|
||||||
ADD_LIBRARY(taos_static STATIC ${SRC})
|
ADD_LIBRARY(taos_static STATIC ${SRC})
|
||||||
TARGET_LINK_LIBRARIES(taos_static query trpc tutil pthread m)
|
TARGET_LINK_LIBRARIES(taos_static query trpc tutil pthread m lua)
|
||||||
SET_TARGET_PROPERTIES(taos_static PROPERTIES OUTPUT_NAME "taos_static")
|
SET_TARGET_PROPERTIES(taos_static PROPERTIES OUTPUT_NAME "taos_static")
|
||||||
|
|
||||||
# generate dynamic library (*.dylib)
|
# generate dynamic library (*.dylib)
|
||||||
ADD_LIBRARY(taos SHARED ${SRC})
|
ADD_LIBRARY(taos SHARED ${SRC})
|
||||||
TARGET_LINK_LIBRARIES(taos query trpc tutil pthread m)
|
TARGET_LINK_LIBRARIES(taos query trpc tutil pthread m lua)
|
||||||
|
|
||||||
SET_TARGET_PROPERTIES(taos PROPERTIES CLEAN_DIRECT_OUTPUT 1)
|
SET_TARGET_PROPERTIES(taos PROPERTIES CLEAN_DIRECT_OUTPUT 1)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -94,11 +94,21 @@ typedef struct SVgroupTableInfo {
|
||||||
SArray *itemList; // SArray<STableIdInfo>
|
SArray *itemList; // SArray<STableIdInfo>
|
||||||
} SVgroupTableInfo;
|
} SVgroupTableInfo;
|
||||||
|
|
||||||
|
typedef struct SBlockKeyTuple {
|
||||||
|
TSKEY skey;
|
||||||
|
void* payloadAddr;
|
||||||
|
} SBlockKeyTuple;
|
||||||
|
|
||||||
|
typedef struct SBlockKeyInfo {
|
||||||
|
int32_t maxBytesAlloc;
|
||||||
|
SBlockKeyTuple* pKeyTuple;
|
||||||
|
} SBlockKeyInfo;
|
||||||
|
|
||||||
int32_t converToStr(char *str, int type, void *buf, int32_t bufSize, int32_t *len);
|
int32_t converToStr(char *str, int type, void *buf, int32_t bufSize, int32_t *len);
|
||||||
|
|
||||||
int32_t tscCreateDataBlock(size_t initialSize, int32_t rowSize, int32_t startOffset, SName* name, STableMeta* pTableMeta, STableDataBlocks** dataBlocks);
|
int32_t tscCreateDataBlock(size_t initialSize, int32_t rowSize, int32_t startOffset, SName* name, STableMeta* pTableMeta, STableDataBlocks** dataBlocks);
|
||||||
void tscDestroyDataBlock(STableDataBlocks* pDataBlock, bool removeMeta);
|
void tscDestroyDataBlock(STableDataBlocks* pDataBlock, bool removeMeta);
|
||||||
void tscSortRemoveDataBlockDupRows(STableDataBlocks* dataBuf);
|
int tscSortRemoveDataBlockDupRows(STableDataBlocks* dataBuf, SBlockKeyInfo* pBlkKeyInfo);
|
||||||
int32_t tsSetBlockInfo(SSubmitBlk *pBlocks, const STableMeta *pTableMeta, int32_t numOfRows);
|
int32_t tsSetBlockInfo(SSubmitBlk *pBlocks, const STableMeta *pTableMeta, int32_t numOfRows);
|
||||||
|
|
||||||
void tscDestroyBoundColumnInfo(SParsedDataColInfo* pColInfo);
|
void tscDestroyBoundColumnInfo(SParsedDataColInfo* pColInfo);
|
||||||
|
|
@ -108,6 +118,7 @@ SParamInfo* tscAddParamToDataBlock(STableDataBlocks* pDataBlock, char type, uint
|
||||||
uint32_t offset);
|
uint32_t offset);
|
||||||
|
|
||||||
void* tscDestroyBlockArrayList(SArray* pDataBlockList);
|
void* tscDestroyBlockArrayList(SArray* pDataBlockList);
|
||||||
|
void* tscDestroyUdfArrayList(SArray* pUdfList);
|
||||||
void* tscDestroyBlockHashTable(SHashObj* pBlockHashTable, bool removeMeta);
|
void* tscDestroyBlockHashTable(SHashObj* pBlockHashTable, bool removeMeta);
|
||||||
|
|
||||||
int32_t tscCopyDataBlockToPayload(SSqlObj* pSql, STableDataBlocks* pDataBlock);
|
int32_t tscCopyDataBlockToPayload(SSqlObj* pSql, STableDataBlocks* pDataBlock);
|
||||||
|
|
@ -262,6 +273,7 @@ void tscVgroupTableCopy(SVgroupTableInfo* info, SVgroupTableInfo* pInfo);
|
||||||
int tscGetSTableVgroupInfo(SSqlObj* pSql, SQueryInfo* pQueryInfo);
|
int tscGetSTableVgroupInfo(SSqlObj* pSql, SQueryInfo* pQueryInfo);
|
||||||
int tscGetTableMeta(SSqlObj* pSql, STableMetaInfo* pTableMetaInfo);
|
int tscGetTableMeta(SSqlObj* pSql, STableMetaInfo* pTableMetaInfo);
|
||||||
int tscGetTableMetaEx(SSqlObj* pSql, STableMetaInfo* pTableMetaInfo, bool createIfNotExists);
|
int tscGetTableMetaEx(SSqlObj* pSql, STableMetaInfo* pTableMetaInfo, bool createIfNotExists);
|
||||||
|
int32_t tscGetUdfFromNode(SSqlObj *pSql, SQueryInfo* pQueryInfo);
|
||||||
|
|
||||||
void tscResetForNextRetrieve(SSqlRes* pRes);
|
void tscResetForNextRetrieve(SSqlRes* pRes);
|
||||||
void executeQuery(SSqlObj* pSql, SQueryInfo* pQueryInfo);
|
void executeQuery(SSqlObj* pSql, SQueryInfo* pQueryInfo);
|
||||||
|
|
@ -308,10 +320,9 @@ bool hasMoreClauseToTry(SSqlObj* pSql);
|
||||||
void tscFreeQueryInfo(SSqlCmd* pCmd, bool removeMeta);
|
void tscFreeQueryInfo(SSqlCmd* pCmd, bool removeMeta);
|
||||||
|
|
||||||
void tscTryQueryNextVnode(SSqlObj *pSql, __async_cb_func_t fp);
|
void tscTryQueryNextVnode(SSqlObj *pSql, __async_cb_func_t fp);
|
||||||
void tscAsyncQuerySingleRowForNextVnode(void *param, TAOS_RES *tres, int numOfRows);
|
|
||||||
void tscTryQueryNextClause(SSqlObj* pSql, __async_cb_func_t fp);
|
void tscTryQueryNextClause(SSqlObj* pSql, __async_cb_func_t fp);
|
||||||
int tscSetMgmtEpSetFromCfg(const char *first, const char *second, SRpcCorEpSet *corEpSet);
|
int tscSetMgmtEpSetFromCfg(const char *first, const char *second, SRpcCorEpSet *corEpSet);
|
||||||
int32_t getMultiTableMetaFromMnode(SSqlObj *pSql, SArray* pNameList, SArray* pVgroupNameList, __async_cb_func_t fp);
|
int32_t getMultiTableMetaFromMnode(SSqlObj *pSql, SArray* pNameList, SArray* pVgroupNameList, SArray* pUdfList, __async_cb_func_t fp, bool metaClone);
|
||||||
|
|
||||||
int tscTransferTableNameList(SSqlObj *pSql, const char *pNameList, int32_t length, SArray* pNameArray);
|
int tscTransferTableNameList(SSqlObj *pSql, const char *pNameList, int32_t length, SArray* pNameArray);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -88,13 +88,43 @@ typedef struct SBoundColumn {
|
||||||
int32_t offset; // all column offset value
|
int32_t offset; // all column offset value
|
||||||
} SBoundColumn;
|
} SBoundColumn;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint16_t schemaColIdx;
|
||||||
|
uint16_t boundIdx;
|
||||||
|
uint16_t finalIdx;
|
||||||
|
} SBoundIdxInfo;
|
||||||
|
|
||||||
|
typedef enum _COL_ORDER_STATUS {
|
||||||
|
ORDER_STATUS_UNKNOWN = 0,
|
||||||
|
ORDER_STATUS_ORDERED = 1,
|
||||||
|
ORDER_STATUS_DISORDERED = 2,
|
||||||
|
} EOrderStatus;
|
||||||
|
|
||||||
typedef struct SParsedDataColInfo {
|
typedef struct SParsedDataColInfo {
|
||||||
int16_t numOfCols;
|
int16_t numOfCols;
|
||||||
int16_t numOfBound;
|
int16_t numOfBound;
|
||||||
int32_t *boundedColumns;
|
int32_t * boundedColumns; // bounded column idx according to schema
|
||||||
SBoundColumn * cols;
|
SBoundColumn * cols;
|
||||||
|
SBoundIdxInfo *colIdxInfo;
|
||||||
|
int8_t orderStatus; // bounded columns:
|
||||||
} SParsedDataColInfo;
|
} SParsedDataColInfo;
|
||||||
|
|
||||||
|
#define IS_DATA_COL_ORDERED(s) ((s) == (int8_t)ORDER_STATUS_ORDERED)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
SSchema * pSchema;
|
||||||
|
int16_t sversion;
|
||||||
|
int32_t flen;
|
||||||
|
uint16_t nCols;
|
||||||
|
void * buf;
|
||||||
|
void * pDataBlock;
|
||||||
|
SSubmitBlk *pSubmitBlk;
|
||||||
|
} SMemRowBuilder;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
TDRowLenT allNullLen;
|
||||||
|
} SMemRowHelper;
|
||||||
|
|
||||||
typedef struct STableDataBlocks {
|
typedef struct STableDataBlocks {
|
||||||
SName tableName;
|
SName tableName;
|
||||||
int8_t tsSource; // where does the UNIX timestamp come from, server or client
|
int8_t tsSource; // where does the UNIX timestamp come from, server or client
|
||||||
|
|
@ -116,6 +146,7 @@ typedef struct STableDataBlocks {
|
||||||
uint32_t numOfAllocedParams;
|
uint32_t numOfAllocedParams;
|
||||||
uint32_t numOfParams;
|
uint32_t numOfParams;
|
||||||
SParamInfo * params;
|
SParamInfo * params;
|
||||||
|
SMemRowHelper rowHelper;
|
||||||
} STableDataBlocks;
|
} STableDataBlocks;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
@ -147,6 +178,7 @@ typedef struct {
|
||||||
SInsertStatementParam insertParam;
|
SInsertStatementParam insertParam;
|
||||||
char reserve1[3]; // fix bus error on arm32
|
char reserve1[3]; // fix bus error on arm32
|
||||||
int32_t count; // todo remove it
|
int32_t count; // todo remove it
|
||||||
|
bool subCmd;
|
||||||
|
|
||||||
char reserve2[3]; // fix bus error on arm32
|
char reserve2[3]; // fix bus error on arm32
|
||||||
int16_t numOfCols;
|
int16_t numOfCols;
|
||||||
|
|
@ -243,6 +275,7 @@ typedef struct SSqlObj {
|
||||||
void * pStream;
|
void * pStream;
|
||||||
void * pSubscription;
|
void * pSubscription;
|
||||||
char * sqlstr;
|
char * sqlstr;
|
||||||
|
void * pBuf; // table meta buffer
|
||||||
char parseRetry;
|
char parseRetry;
|
||||||
char retry;
|
char retry;
|
||||||
char maxRetry;
|
char maxRetry;
|
||||||
|
|
@ -386,6 +419,11 @@ extern int (*tscBuildMsg[TSDB_SQL_MAX])(SSqlObj *pSql, SSqlInfo *pInfo);
|
||||||
void tscBuildVgroupTableInfo(SSqlObj* pSql, STableMetaInfo* pTableMetaInfo, SArray* tables);
|
void tscBuildVgroupTableInfo(SSqlObj* pSql, STableMetaInfo* pTableMetaInfo, SArray* tables);
|
||||||
int16_t getNewResColId(SSqlCmd* pCmd);
|
int16_t getNewResColId(SSqlCmd* pCmd);
|
||||||
|
|
||||||
|
int32_t schemaIdxCompar(const void *lhs, const void *rhs);
|
||||||
|
int32_t boundIdxCompar(const void *lhs, const void *rhs);
|
||||||
|
int initSMemRowHelper(SMemRowHelper *pHelper, SSchema *pSSchema, uint16_t nCols, uint16_t allNullColsLen);
|
||||||
|
int32_t getExtendedRowSize(STableComInfo *tinfo);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -602,6 +602,15 @@ static void doExecuteFinalMerge(SOperatorInfo* pOperator, int32_t numOfExpr, SSD
|
||||||
if (functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_TS_DUMMY) {
|
if (functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_TS_DUMMY) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (functionId < 0) {
|
||||||
|
SUdfInfo* pUdfInfo = taosArrayGet(pInfo->udfInfo, -1 * functionId - 1);
|
||||||
|
|
||||||
|
doInvokeUdf(pUdfInfo, &pCtx[j], 0, TSDB_UDF_FUNC_MERGE);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
aAggs[functionId].mergeFunc(&pCtx[j]);
|
aAggs[functionId].mergeFunc(&pCtx[j]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -610,6 +619,15 @@ static void doExecuteFinalMerge(SOperatorInfo* pOperator, int32_t numOfExpr, SSD
|
||||||
if (functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_TS_DUMMY) {
|
if (functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_TS_DUMMY) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (functionId < 0) {
|
||||||
|
SUdfInfo* pUdfInfo = taosArrayGet(pInfo->udfInfo, -1 * functionId - 1);
|
||||||
|
|
||||||
|
doInvokeUdf(pUdfInfo, &pCtx[j], 0, TSDB_UDF_FUNC_FINALIZE);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
aAggs[functionId].xFinalize(&pCtx[j]);
|
aAggs[functionId].xFinalize(&pCtx[j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -626,7 +644,11 @@ static void doExecuteFinalMerge(SOperatorInfo* pOperator, int32_t numOfExpr, SSD
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int32_t j = 0; j < numOfExpr; ++j) {
|
for(int32_t j = 0; j < numOfExpr; ++j) {
|
||||||
aAggs[pCtx[j].functionId].init(&pCtx[j]);
|
if (pCtx[j].functionId < 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
aAggs[pCtx[j].functionId].init(&pCtx[j], pCtx[j].resultInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int32_t j = 0; j < numOfExpr; ++j) {
|
for (int32_t j = 0; j < numOfExpr; ++j) {
|
||||||
|
|
@ -638,6 +660,15 @@ static void doExecuteFinalMerge(SOperatorInfo* pOperator, int32_t numOfExpr, SSD
|
||||||
if (functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_TS_DUMMY) {
|
if (functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_TS_DUMMY) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (functionId < 0) {
|
||||||
|
SUdfInfo* pUdfInfo = taosArrayGet(pInfo->udfInfo, -1 * functionId - 1);
|
||||||
|
|
||||||
|
doInvokeUdf(pUdfInfo, &pCtx[j], 0, TSDB_UDF_FUNC_MERGE);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
aAggs[functionId].mergeFunc(&pCtx[j]);
|
aAggs[functionId].mergeFunc(&pCtx[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -651,6 +682,15 @@ static void doExecuteFinalMerge(SOperatorInfo* pOperator, int32_t numOfExpr, SSD
|
||||||
if (functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_TS_DUMMY) {
|
if (functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_TS_DUMMY) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (functionId < 0) {
|
||||||
|
SUdfInfo* pUdfInfo = taosArrayGet(pInfo->udfInfo, -1 * functionId - 1);
|
||||||
|
|
||||||
|
doInvokeUdf(pUdfInfo, &pCtx[j], 0, TSDB_UDF_FUNC_MERGE);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
aAggs[functionId].mergeFunc(&pCtx[j]);
|
aAggs[functionId].mergeFunc(&pCtx[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -871,7 +911,6 @@ SSDataBlock* doGlobalAggregate(void* param, bool* newgroup) {
|
||||||
|
|
||||||
{
|
{
|
||||||
if (pAggInfo->hasDataBlockForNewGroup) {
|
if (pAggInfo->hasDataBlockForNewGroup) {
|
||||||
pAggInfo->binfo.pRes->info.rows = 0;
|
|
||||||
pAggInfo->hasPrev = false; // now we start from a new group data set.
|
pAggInfo->hasPrev = false; // now we start from a new group data set.
|
||||||
|
|
||||||
// not belongs to the same group, return the result of current group;
|
// not belongs to the same group, return the result of current group;
|
||||||
|
|
@ -880,7 +919,13 @@ SSDataBlock* doGlobalAggregate(void* param, bool* newgroup) {
|
||||||
|
|
||||||
{ // reset output buffer
|
{ // reset output buffer
|
||||||
for(int32_t j = 0; j < pOperator->numOfOutput; ++j) {
|
for(int32_t j = 0; j < pOperator->numOfOutput; ++j) {
|
||||||
aAggs[pAggInfo->binfo.pCtx[j].functionId].init(&pAggInfo->binfo.pCtx[j]);
|
SQLFunctionCtx* pCtx = &pAggInfo->binfo.pCtx[j];
|
||||||
|
if (pCtx->functionId < 0) {
|
||||||
|
clearOutputBuf(&pAggInfo->binfo, &pAggInfo->bufCapacity);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
aAggs[pCtx->functionId].init(pCtx, pCtx->resultInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -933,6 +978,14 @@ SSDataBlock* doGlobalAggregate(void* param, bool* newgroup) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (functionId < 0) {
|
||||||
|
SUdfInfo* pUdfInfo = taosArrayGet(pAggInfo->udfInfo, -1 * functionId - 1);
|
||||||
|
|
||||||
|
doInvokeUdf(pUdfInfo, &pAggInfo->binfo.pCtx[j], 0, TSDB_UDF_FUNC_FINALIZE);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
aAggs[functionId].xFinalize(&pAggInfo->binfo.pCtx[j]);
|
aAggs[functionId].xFinalize(&pAggInfo->binfo.pCtx[j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,10 +38,33 @@ enum {
|
||||||
TSDB_USE_CLI_TS = 1,
|
TSDB_USE_CLI_TS = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static uint8_t TRUE_VALUE = (uint8_t)TSDB_TRUE;
|
||||||
|
static uint8_t FALSE_VALUE = (uint8_t)TSDB_FALSE;
|
||||||
|
|
||||||
static int32_t tscAllocateMemIfNeed(STableDataBlocks *pDataBlock, int32_t rowSize, int32_t *numOfRows);
|
static int32_t tscAllocateMemIfNeed(STableDataBlocks *pDataBlock, int32_t rowSize, int32_t *numOfRows);
|
||||||
static int32_t parseBoundColumns(SInsertStatementParam *pInsertParam, SParsedDataColInfo *pColInfo, SSchema *pSchema,
|
static int32_t parseBoundColumns(SInsertStatementParam *pInsertParam, SParsedDataColInfo *pColInfo, SSchema *pSchema,
|
||||||
char *str, char **end);
|
char *str, char **end);
|
||||||
|
|
||||||
|
int32_t getExtendedRowSize(STableComInfo *tinfo) {
|
||||||
|
return tinfo->rowSize + PAYLOAD_HEADER_LEN + PAYLOAD_COL_HEAD_LEN * tinfo->numOfColumns;
|
||||||
|
}
|
||||||
|
int initSMemRowHelper(SMemRowHelper *pHelper, SSchema *pSSchema, uint16_t nCols, uint16_t allNullColsLen) {
|
||||||
|
pHelper->allNullLen = allNullColsLen; // TODO: get allNullColsLen when creating or altering table meta
|
||||||
|
if (pHelper->allNullLen == 0) {
|
||||||
|
for (uint16_t i = 0; i < nCols; ++i) {
|
||||||
|
uint8_t type = pSSchema[i].type;
|
||||||
|
int32_t typeLen = TYPE_BYTES[type];
|
||||||
|
pHelper->allNullLen += typeLen;
|
||||||
|
if (TSDB_DATA_TYPE_BINARY == type) {
|
||||||
|
pHelper->allNullLen += (VARSTR_HEADER_SIZE + CHAR_BYTES);
|
||||||
|
} else if (TSDB_DATA_TYPE_NCHAR == type) {
|
||||||
|
int len = VARSTR_HEADER_SIZE + TSDB_NCHAR_SIZE;
|
||||||
|
pHelper->allNullLen += len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
static int32_t tscToDouble(SStrToken *pToken, double *value, char **endPtr) {
|
static int32_t tscToDouble(SStrToken *pToken, double *value, char **endPtr) {
|
||||||
errno = 0;
|
errno = 0;
|
||||||
*value = strtold(pToken->z, endPtr);
|
*value = strtold(pToken->z, endPtr);
|
||||||
|
|
@ -378,6 +401,342 @@ int32_t tsParseOneColumn(SSchema *pSchema, SStrToken *pToken, char *payload, cha
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static FORCE_INLINE TDRowLenT tsSetPayloadColValue(char *payloadStart, char *payload, int16_t columnId,
|
||||||
|
uint8_t columnType, const void *value, uint16_t valueLen, TDRowTLenT tOffset) {
|
||||||
|
payloadColSetId(payload, columnId);
|
||||||
|
payloadColSetType(payload, columnType);
|
||||||
|
memcpy(POINTER_SHIFT(payloadStart,tOffset), value, valueLen);
|
||||||
|
return valueLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t tsParseOneColumnKV(SSchema *pSchema, SStrToken *pToken, char *payloadStart, char *primaryKeyStart,
|
||||||
|
char *payload, char *msg, char **str, bool primaryKey, int16_t timePrec,
|
||||||
|
TDRowTLenT tOffset, TDRowLenT *sizeAppend, TDRowLenT *dataRowColDeltaLen,
|
||||||
|
TDRowLenT *kvRowColLen) {
|
||||||
|
int64_t iv;
|
||||||
|
int32_t ret;
|
||||||
|
char * endptr = NULL;
|
||||||
|
|
||||||
|
if (IS_NUMERIC_TYPE(pSchema->type) && pToken->n == 0) {
|
||||||
|
return tscInvalidOperationMsg(msg, "invalid numeric data", pToken->z);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (pSchema->type) {
|
||||||
|
case TSDB_DATA_TYPE_BOOL: { // bool
|
||||||
|
if (isNullStr(pToken)) {
|
||||||
|
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type,
|
||||||
|
tdGetNullVal(TSDB_DATA_TYPE_BOOL), TYPE_BYTES[TSDB_DATA_TYPE_BOOL], tOffset);
|
||||||
|
} else {
|
||||||
|
if ((pToken->type == TK_BOOL || pToken->type == TK_STRING) && (pToken->n != 0)) {
|
||||||
|
if (strncmp(pToken->z, "true", pToken->n) == 0) {
|
||||||
|
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type, &TRUE_VALUE,
|
||||||
|
TYPE_BYTES[TSDB_DATA_TYPE_BOOL], tOffset);
|
||||||
|
*kvRowColLen += (TDRowLenT)(sizeof(SColIdx) + TYPE_BYTES[TSDB_DATA_TYPE_BOOL]);
|
||||||
|
} else if (strncmp(pToken->z, "false", pToken->n) == 0) {
|
||||||
|
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type, &FALSE_VALUE,
|
||||||
|
TYPE_BYTES[TSDB_DATA_TYPE_BOOL], tOffset);
|
||||||
|
*kvRowColLen += (TDRowLenT)(sizeof(SColIdx) + TYPE_BYTES[TSDB_DATA_TYPE_BOOL]);
|
||||||
|
} else {
|
||||||
|
return tscSQLSyntaxErrMsg(msg, "invalid bool data", pToken->z);
|
||||||
|
}
|
||||||
|
} else if (pToken->type == TK_INTEGER) {
|
||||||
|
iv = strtoll(pToken->z, NULL, 10);
|
||||||
|
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type,
|
||||||
|
((iv == 0) ? &FALSE_VALUE : &TRUE_VALUE), TYPE_BYTES[TSDB_DATA_TYPE_BOOL], tOffset);
|
||||||
|
*kvRowColLen += (TDRowLenT)(sizeof(SColIdx) + TYPE_BYTES[TSDB_DATA_TYPE_BOOL]);
|
||||||
|
} else if (pToken->type == TK_FLOAT) {
|
||||||
|
double dv = strtod(pToken->z, NULL);
|
||||||
|
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type,
|
||||||
|
((dv == 0) ? &FALSE_VALUE : &TRUE_VALUE), TYPE_BYTES[TSDB_DATA_TYPE_BOOL], tOffset);
|
||||||
|
*kvRowColLen += (TDRowLenT)(sizeof(SColIdx) + TYPE_BYTES[TSDB_DATA_TYPE_BOOL]);
|
||||||
|
} else {
|
||||||
|
return tscInvalidOperationMsg(msg, "invalid bool data", pToken->z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TSDB_DATA_TYPE_TINYINT:
|
||||||
|
if (isNullStr(pToken)) {
|
||||||
|
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type,
|
||||||
|
tdGetNullVal(TSDB_DATA_TYPE_TINYINT), TYPE_BYTES[TSDB_DATA_TYPE_TINYINT], tOffset);
|
||||||
|
} else {
|
||||||
|
ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, true);
|
||||||
|
if (ret != TSDB_CODE_SUCCESS) {
|
||||||
|
return tscInvalidOperationMsg(msg, "invalid tinyint data", pToken->z);
|
||||||
|
} else if (!IS_VALID_TINYINT(iv)) {
|
||||||
|
return tscInvalidOperationMsg(msg, "data overflow", pToken->z);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t tmpVal = (uint8_t)iv;
|
||||||
|
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type, &tmpVal,
|
||||||
|
TYPE_BYTES[TSDB_DATA_TYPE_TINYINT], tOffset);
|
||||||
|
*kvRowColLen += (TDRowLenT)(sizeof(SColIdx) + TYPE_BYTES[TSDB_DATA_TYPE_TINYINT]);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TSDB_DATA_TYPE_UTINYINT:
|
||||||
|
if (isNullStr(pToken)) {
|
||||||
|
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type,
|
||||||
|
tdGetNullVal(TSDB_DATA_TYPE_UTINYINT), TYPE_BYTES[TSDB_DATA_TYPE_UTINYINT], tOffset);
|
||||||
|
} else {
|
||||||
|
ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, false);
|
||||||
|
if (ret != TSDB_CODE_SUCCESS) {
|
||||||
|
return tscInvalidOperationMsg(msg, "invalid unsigned tinyint data", pToken->z);
|
||||||
|
} else if (!IS_VALID_UTINYINT(iv)) {
|
||||||
|
return tscInvalidOperationMsg(msg, "unsigned tinyint data overflow", pToken->z);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t tmpVal = (uint8_t)iv;
|
||||||
|
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type, &tmpVal,
|
||||||
|
TYPE_BYTES[TSDB_DATA_TYPE_UTINYINT], tOffset);
|
||||||
|
*kvRowColLen += (TDRowLenT)(sizeof(SColIdx) + TYPE_BYTES[TSDB_DATA_TYPE_UTINYINT]);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TSDB_DATA_TYPE_SMALLINT:
|
||||||
|
if (isNullStr(pToken)) {
|
||||||
|
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type,
|
||||||
|
tdGetNullVal(TSDB_DATA_TYPE_SMALLINT), TYPE_BYTES[TSDB_DATA_TYPE_SMALLINT], tOffset);
|
||||||
|
} else {
|
||||||
|
ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, true);
|
||||||
|
if (ret != TSDB_CODE_SUCCESS) {
|
||||||
|
return tscInvalidOperationMsg(msg, "invalid smallint data", pToken->z);
|
||||||
|
} else if (!IS_VALID_SMALLINT(iv)) {
|
||||||
|
return tscInvalidOperationMsg(msg, "smallint data overflow", pToken->z);
|
||||||
|
}
|
||||||
|
|
||||||
|
int16_t tmpVal = (int16_t)iv;
|
||||||
|
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type, &tmpVal,
|
||||||
|
TYPE_BYTES[TSDB_DATA_TYPE_SMALLINT], tOffset);
|
||||||
|
*kvRowColLen += (TDRowLenT)(sizeof(SColIdx) + TYPE_BYTES[TSDB_DATA_TYPE_SMALLINT]);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TSDB_DATA_TYPE_USMALLINT:
|
||||||
|
if (isNullStr(pToken)) {
|
||||||
|
*sizeAppend =
|
||||||
|
tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type,
|
||||||
|
tdGetNullVal(TSDB_DATA_TYPE_USMALLINT), TYPE_BYTES[TSDB_DATA_TYPE_USMALLINT], tOffset);
|
||||||
|
} else {
|
||||||
|
ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, false);
|
||||||
|
if (ret != TSDB_CODE_SUCCESS) {
|
||||||
|
return tscInvalidOperationMsg(msg, "invalid unsigned smallint data", pToken->z);
|
||||||
|
} else if (!IS_VALID_USMALLINT(iv)) {
|
||||||
|
return tscInvalidOperationMsg(msg, "unsigned smallint data overflow", pToken->z);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t tmpVal = (uint16_t)iv;
|
||||||
|
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type, &tmpVal,
|
||||||
|
TYPE_BYTES[TSDB_DATA_TYPE_USMALLINT], tOffset);
|
||||||
|
*kvRowColLen += (TDRowLenT)(sizeof(SColIdx) + TYPE_BYTES[TSDB_DATA_TYPE_USMALLINT]);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TSDB_DATA_TYPE_INT:
|
||||||
|
if (isNullStr(pToken)) {
|
||||||
|
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type,
|
||||||
|
tdGetNullVal(TSDB_DATA_TYPE_INT), TYPE_BYTES[TSDB_DATA_TYPE_INT], tOffset);
|
||||||
|
} else {
|
||||||
|
ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, true);
|
||||||
|
if (ret != TSDB_CODE_SUCCESS) {
|
||||||
|
return tscInvalidOperationMsg(msg, "invalid int data", pToken->z);
|
||||||
|
} else if (!IS_VALID_INT(iv)) {
|
||||||
|
return tscInvalidOperationMsg(msg, "int data overflow", pToken->z);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t tmpVal = (int32_t)iv;
|
||||||
|
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type, &tmpVal,
|
||||||
|
TYPE_BYTES[TSDB_DATA_TYPE_INT], tOffset);
|
||||||
|
*kvRowColLen += (TDRowLenT)(sizeof(SColIdx) + TYPE_BYTES[TSDB_DATA_TYPE_INT]);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TSDB_DATA_TYPE_UINT:
|
||||||
|
if (isNullStr(pToken)) {
|
||||||
|
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type,
|
||||||
|
tdGetNullVal(TSDB_DATA_TYPE_UINT), TYPE_BYTES[TSDB_DATA_TYPE_UINT], tOffset);
|
||||||
|
} else {
|
||||||
|
ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, false);
|
||||||
|
if (ret != TSDB_CODE_SUCCESS) {
|
||||||
|
return tscInvalidOperationMsg(msg, "invalid unsigned int data", pToken->z);
|
||||||
|
} else if (!IS_VALID_UINT(iv)) {
|
||||||
|
return tscInvalidOperationMsg(msg, "unsigned int data overflow", pToken->z);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t tmpVal = (uint32_t)iv;
|
||||||
|
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type, &tmpVal,
|
||||||
|
TYPE_BYTES[TSDB_DATA_TYPE_UINT], tOffset);
|
||||||
|
*kvRowColLen += (TDRowLenT)(sizeof(SColIdx) + TYPE_BYTES[TSDB_DATA_TYPE_UINT]);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TSDB_DATA_TYPE_BIGINT:
|
||||||
|
if (isNullStr(pToken)) {
|
||||||
|
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type,
|
||||||
|
tdGetNullVal(TSDB_DATA_TYPE_BIGINT), TYPE_BYTES[TSDB_DATA_TYPE_BIGINT], tOffset);
|
||||||
|
} else {
|
||||||
|
ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, true);
|
||||||
|
if (ret != TSDB_CODE_SUCCESS) {
|
||||||
|
return tscInvalidOperationMsg(msg, "invalid bigint data", pToken->z);
|
||||||
|
} else if (!IS_VALID_BIGINT(iv)) {
|
||||||
|
return tscInvalidOperationMsg(msg, "bigint data overflow", pToken->z);
|
||||||
|
}
|
||||||
|
|
||||||
|
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type, &iv,
|
||||||
|
TYPE_BYTES[TSDB_DATA_TYPE_BIGINT], tOffset);
|
||||||
|
*kvRowColLen += (TDRowLenT)(sizeof(SColIdx) + TYPE_BYTES[TSDB_DATA_TYPE_BIGINT]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TSDB_DATA_TYPE_UBIGINT:
|
||||||
|
if (isNullStr(pToken)) {
|
||||||
|
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type,
|
||||||
|
tdGetNullVal(TSDB_DATA_TYPE_UBIGINT), TYPE_BYTES[TSDB_DATA_TYPE_UBIGINT], tOffset);
|
||||||
|
} else {
|
||||||
|
ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, false);
|
||||||
|
if (ret != TSDB_CODE_SUCCESS) {
|
||||||
|
return tscInvalidOperationMsg(msg, "invalid unsigned bigint data", pToken->z);
|
||||||
|
} else if (!IS_VALID_UBIGINT((uint64_t)iv)) {
|
||||||
|
return tscInvalidOperationMsg(msg, "unsigned bigint data overflow", pToken->z);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t tmpVal = (uint64_t)iv;
|
||||||
|
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type, &tmpVal,
|
||||||
|
TYPE_BYTES[TSDB_DATA_TYPE_UBIGINT], tOffset);
|
||||||
|
*kvRowColLen += (TDRowLenT)(sizeof(SColIdx) + TYPE_BYTES[TSDB_DATA_TYPE_UBIGINT]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TSDB_DATA_TYPE_FLOAT:
|
||||||
|
if (isNullStr(pToken)) {
|
||||||
|
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type,
|
||||||
|
getNullValue(TSDB_DATA_TYPE_FLOAT), TYPE_BYTES[TSDB_DATA_TYPE_FLOAT], tOffset);
|
||||||
|
} else {
|
||||||
|
double dv;
|
||||||
|
if (TK_ILLEGAL == tscToDouble(pToken, &dv, &endptr)) {
|
||||||
|
return tscInvalidOperationMsg(msg, "illegal float data", pToken->z);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (((dv == HUGE_VAL || dv == -HUGE_VAL) && errno == ERANGE) || dv > FLT_MAX || dv < -FLT_MAX || isinf(dv) ||
|
||||||
|
isnan(dv)) {
|
||||||
|
return tscInvalidOperationMsg(msg, "illegal float data", pToken->z);
|
||||||
|
}
|
||||||
|
|
||||||
|
float tmpVal = (float)dv;
|
||||||
|
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type, &tmpVal,
|
||||||
|
TYPE_BYTES[TSDB_DATA_TYPE_FLOAT], tOffset);
|
||||||
|
*kvRowColLen += (TDRowLenT)(sizeof(SColIdx) + TYPE_BYTES[TSDB_DATA_TYPE_FLOAT]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TSDB_DATA_TYPE_DOUBLE:
|
||||||
|
if (isNullStr(pToken)) {
|
||||||
|
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type,
|
||||||
|
tdGetNullVal(TSDB_DATA_TYPE_DOUBLE), TYPE_BYTES[TSDB_DATA_TYPE_DOUBLE], tOffset);
|
||||||
|
} else {
|
||||||
|
double dv;
|
||||||
|
if (TK_ILLEGAL == tscToDouble(pToken, &dv, &endptr)) {
|
||||||
|
return tscInvalidOperationMsg(msg, "illegal double data", pToken->z);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (((dv == HUGE_VAL || dv == -HUGE_VAL) && errno == ERANGE) || isinf(dv) || isnan(dv)) {
|
||||||
|
return tscInvalidOperationMsg(msg, "illegal double data", pToken->z);
|
||||||
|
}
|
||||||
|
|
||||||
|
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type, &dv,
|
||||||
|
TYPE_BYTES[TSDB_DATA_TYPE_DOUBLE], tOffset);
|
||||||
|
*kvRowColLen += (TDRowLenT)(sizeof(SColIdx) + TYPE_BYTES[TSDB_DATA_TYPE_DOUBLE]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TSDB_DATA_TYPE_BINARY:
|
||||||
|
// binary data cannot be null-terminated char string, otherwise the last char of the string is lost
|
||||||
|
if (pToken->type == TK_NULL) {
|
||||||
|
payloadColSetId(payload, pSchema->colId);
|
||||||
|
payloadColSetType(payload, pSchema->type);
|
||||||
|
memcpy(POINTER_SHIFT(payloadStart, tOffset), tdGetNullVal(TSDB_DATA_TYPE_BINARY), VARSTR_HEADER_SIZE + CHAR_BYTES);
|
||||||
|
*sizeAppend = (TDRowLenT)(VARSTR_HEADER_SIZE + CHAR_BYTES);
|
||||||
|
} else { // too long values will return invalid sql, not be truncated automatically
|
||||||
|
if (pToken->n + VARSTR_HEADER_SIZE > pSchema->bytes) { // todo refactor
|
||||||
|
return tscInvalidOperationMsg(msg, "string data overflow", pToken->z);
|
||||||
|
}
|
||||||
|
// STR_WITH_SIZE_TO_VARSTR(payload, pToken->z, pToken->n);
|
||||||
|
|
||||||
|
payloadColSetId(payload, pSchema->colId);
|
||||||
|
payloadColSetType(payload, pSchema->type);
|
||||||
|
varDataSetLen(POINTER_SHIFT(payloadStart,tOffset), pToken->n);
|
||||||
|
memcpy(varDataVal(POINTER_SHIFT(payloadStart,tOffset)), pToken->z, pToken->n);
|
||||||
|
*sizeAppend = (TDRowLenT)(VARSTR_HEADER_SIZE + pToken->n);
|
||||||
|
*dataRowColDeltaLen += (TDRowLenT)(pToken->n - CHAR_BYTES);
|
||||||
|
*kvRowColLen += (TDRowLenT)(sizeof(SColIdx) + VARSTR_HEADER_SIZE + pToken->n);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TSDB_DATA_TYPE_NCHAR:
|
||||||
|
if (pToken->type == TK_NULL) {
|
||||||
|
payloadColSetId(payload, pSchema->colId);
|
||||||
|
payloadColSetType(payload, pSchema->type);
|
||||||
|
memcpy(POINTER_SHIFT(payloadStart,tOffset), tdGetNullVal(TSDB_DATA_TYPE_NCHAR), VARSTR_HEADER_SIZE + TSDB_NCHAR_SIZE);
|
||||||
|
*sizeAppend = (TDRowLenT)(VARSTR_HEADER_SIZE + TSDB_NCHAR_SIZE);
|
||||||
|
} else {
|
||||||
|
// if the converted output len is over than pColumnModel->bytes, return error: 'Argument list too long'
|
||||||
|
int32_t output = 0;
|
||||||
|
payloadColSetId(payload, pSchema->colId);
|
||||||
|
payloadColSetType(payload, pSchema->type);
|
||||||
|
if (!taosMbsToUcs4(pToken->z, pToken->n, varDataVal(POINTER_SHIFT(payloadStart,tOffset)),
|
||||||
|
pSchema->bytes - VARSTR_HEADER_SIZE, &output)) {
|
||||||
|
char buf[512] = {0};
|
||||||
|
snprintf(buf, tListLen(buf), "%s", strerror(errno));
|
||||||
|
return tscInvalidOperationMsg(msg, buf, pToken->z);
|
||||||
|
}
|
||||||
|
|
||||||
|
varDataSetLen(POINTER_SHIFT(payloadStart,tOffset), output);
|
||||||
|
|
||||||
|
*sizeAppend = (TDRowLenT)(VARSTR_HEADER_SIZE + output);
|
||||||
|
*dataRowColDeltaLen += (TDRowLenT)(output - sizeof(uint32_t));
|
||||||
|
*kvRowColLen += (TDRowLenT)(sizeof(SColIdx) + VARSTR_HEADER_SIZE + output);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TSDB_DATA_TYPE_TIMESTAMP: {
|
||||||
|
if (pToken->type == TK_NULL) {
|
||||||
|
if (primaryKey) {
|
||||||
|
// When building SKVRow primaryKey, we should not skip even with NULL value.
|
||||||
|
int64_t tmpVal = 0;
|
||||||
|
*sizeAppend = tsSetPayloadColValue(payloadStart, primaryKeyStart, pSchema->colId, pSchema->type, &tmpVal,
|
||||||
|
TYPE_BYTES[TSDB_DATA_TYPE_TIMESTAMP], tOffset);
|
||||||
|
*kvRowColLen += (TDRowLenT)(sizeof(SColIdx) + TYPE_BYTES[TSDB_DATA_TYPE_TIMESTAMP]);
|
||||||
|
} else {
|
||||||
|
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type,
|
||||||
|
tdGetNullVal(TSDB_DATA_TYPE_TIMESTAMP),
|
||||||
|
TYPE_BYTES[TSDB_DATA_TYPE_TIMESTAMP], tOffset);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int64_t tmpVal;
|
||||||
|
if (tsParseTime(pToken, &tmpVal, str, msg, timePrec) != TSDB_CODE_SUCCESS) {
|
||||||
|
return tscInvalidOperationMsg(msg, "invalid timestamp", pToken->z);
|
||||||
|
}
|
||||||
|
|
||||||
|
*sizeAppend = tsSetPayloadColValue(payloadStart, primaryKey ? primaryKeyStart : payload, pSchema->colId,
|
||||||
|
pSchema->type, &tmpVal, TYPE_BYTES[TSDB_DATA_TYPE_TIMESTAMP], tOffset);
|
||||||
|
*kvRowColLen += (TDRowLenT)(sizeof(SColIdx) + TYPE_BYTES[TSDB_DATA_TYPE_TIMESTAMP]);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The server time/client time should not be mixed up in one sql string
|
* The server time/client time should not be mixed up in one sql string
|
||||||
* Do not employ sort operation is not involved if server time is used.
|
* Do not employ sort operation is not involved if server time is used.
|
||||||
|
|
@ -414,24 +773,38 @@ int32_t tsCheckTimestamp(STableDataBlocks *pDataBlocks, const char *start) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tsParseOneRow(char **str, STableDataBlocks *pDataBlocks, int16_t timePrec, int32_t *len,
|
int tsParseOneRow(char **str, STableDataBlocks *pDataBlocks, int16_t timePrec, int32_t *len, char *tmpTokenBuf,
|
||||||
char *tmpTokenBuf, SInsertStatementParam* pInsertParam) {
|
SInsertStatementParam *pInsertParam) {
|
||||||
int32_t index = 0;
|
int32_t index = 0;
|
||||||
SStrToken sToken = {0};
|
SStrToken sToken = {0};
|
||||||
|
|
||||||
|
SMemRowHelper *pHelper = &pDataBlocks->rowHelper;
|
||||||
char * payload = pDataBlocks->pData + pDataBlocks->size;
|
char * payload = pDataBlocks->pData + pDataBlocks->size;
|
||||||
|
|
||||||
SParsedDataColInfo *spd = &pDataBlocks->boundColumnInfo;
|
SParsedDataColInfo *spd = &pDataBlocks->boundColumnInfo;
|
||||||
SSchema * schema = tscGetTableSchema(pDataBlocks->pTableMeta);
|
SSchema * schema = tscGetTableSchema(pDataBlocks->pTableMeta);
|
||||||
|
|
||||||
|
TDRowTLenT dataRowLen = pHelper->allNullLen;
|
||||||
|
TDRowTLenT kvRowLen = TD_MEM_ROW_KV_VER_SIZE;
|
||||||
|
TDRowTLenT payloadValOffset = 0;
|
||||||
|
TDRowLenT colValOffset = 0;
|
||||||
|
ASSERT(dataRowLen > 0);
|
||||||
|
|
||||||
|
payloadSetNCols(payload, spd->numOfBound);
|
||||||
|
payloadValOffset = payloadValuesOffset(payload); // rely on payloadNCols
|
||||||
|
// payloadSetTLen(payload, payloadValOffset);
|
||||||
|
|
||||||
|
char *kvPrimaryKeyStart = payload + PAYLOAD_HEADER_LEN; // primaryKey in 1st column tuple
|
||||||
|
char *kvStart = kvPrimaryKeyStart + PAYLOAD_COL_HEAD_LEN; // the column tuple behind the primaryKey
|
||||||
|
|
||||||
// 1. set the parsed value from sql string
|
// 1. set the parsed value from sql string
|
||||||
int32_t rowSize = 0;
|
|
||||||
for (int i = 0; i < spd->numOfBound; ++i) {
|
for (int i = 0; i < spd->numOfBound; ++i) {
|
||||||
// the start position in data block buffer of current value in sql
|
// the start position in data block buffer of current value in sql
|
||||||
int32_t colIndex = spd->boundedColumns[i];
|
int32_t colIndex = spd->boundedColumns[i];
|
||||||
|
|
||||||
char *start = payload + spd->cols[colIndex].offset;
|
char *start = payload + spd->cols[colIndex].offset;
|
||||||
SSchema *pSchema = &schema[colIndex];
|
|
||||||
rowSize += pSchema->bytes;
|
SSchema *pSchema = &schema[colIndex]; // get colId here
|
||||||
|
|
||||||
index = 0;
|
index = 0;
|
||||||
sToken = tStrGetToken(*str, &index, true);
|
sToken = tStrGetToken(*str, &index, true);
|
||||||
|
|
@ -453,7 +826,8 @@ int tsParseOneRow(char **str, STableDataBlocks *pDataBlocks, int16_t timePrec, i
|
||||||
|
|
||||||
int16_t type = sToken.type;
|
int16_t type = sToken.type;
|
||||||
if ((type != TK_NOW && type != TK_INTEGER && type != TK_STRING && type != TK_FLOAT && type != TK_BOOL &&
|
if ((type != TK_NOW && type != TK_INTEGER && type != TK_STRING && type != TK_FLOAT && type != TK_BOOL &&
|
||||||
type != TK_NULL && type != TK_HEX && type != TK_OCT && type != TK_BIN) || (sToken.n == 0) || (type == TK_RP)) {
|
type != TK_NULL && type != TK_HEX && type != TK_OCT && type != TK_BIN) ||
|
||||||
|
(sToken.n == 0) || (type == TK_RP)) {
|
||||||
return tscSQLSyntaxErrMsg(pInsertParam->msg, "invalid data or symbol", sToken.z);
|
return tscSQLSyntaxErrMsg(pInsertParam->msg, "invalid data or symbol", sToken.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -488,41 +862,53 @@ int tsParseOneRow(char **str, STableDataBlocks *pDataBlocks, int16_t timePrec, i
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isPrimaryKey = (colIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX);
|
bool isPrimaryKey = (colIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX);
|
||||||
int32_t ret = tsParseOneColumn(pSchema, &sToken, start, pInsertParam->msg, str, isPrimaryKey, timePrec);
|
TDRowLenT dataRowDeltaColLen = 0; // When combine the data as SDataRow, the delta len between all NULL columns.
|
||||||
|
TDRowLenT kvRowColLen = 0;
|
||||||
|
TDRowLenT colValAppended = 0;
|
||||||
|
|
||||||
|
if (!IS_DATA_COL_ORDERED(spd->orderStatus)) {
|
||||||
|
ASSERT(spd->colIdxInfo != NULL);
|
||||||
|
if(!isPrimaryKey) {
|
||||||
|
kvStart = POINTER_SHIFT(kvPrimaryKeyStart, spd->colIdxInfo[i].finalIdx * PAYLOAD_COL_HEAD_LEN);
|
||||||
|
} else {
|
||||||
|
ASSERT(spd->colIdxInfo[i].finalIdx == 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// the primary key locates in 1st column
|
||||||
|
int32_t ret = tsParseOneColumnKV(pSchema, &sToken, payload, kvPrimaryKeyStart, kvStart, pInsertParam->msg, str,
|
||||||
|
isPrimaryKey, timePrec, payloadValOffset + colValOffset, &colValAppended,
|
||||||
|
&dataRowDeltaColLen, &kvRowColLen);
|
||||||
if (ret != TSDB_CODE_SUCCESS) {
|
if (ret != TSDB_CODE_SUCCESS) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isPrimaryKey && tsCheckTimestamp(pDataBlocks, start) != TSDB_CODE_SUCCESS) {
|
if (isPrimaryKey) {
|
||||||
|
if (tsCheckTimestamp(pDataBlocks, payloadValues(payload)) != TSDB_CODE_SUCCESS) {
|
||||||
tscInvalidOperationMsg(pInsertParam->msg, "client time/server time can not be mixed up", sToken.z);
|
tscInvalidOperationMsg(pInsertParam->msg, "client time/server time can not be mixed up", sToken.z);
|
||||||
return TSDB_CODE_TSC_INVALID_TIME_STAMP;
|
return TSDB_CODE_TSC_INVALID_TIME_STAMP;
|
||||||
}
|
}
|
||||||
}
|
payloadColSetOffset(kvPrimaryKeyStart, colValOffset);
|
||||||
|
|
||||||
// 2. set the null value for the columns that do not assign values
|
|
||||||
if (spd->numOfBound < spd->numOfCols) {
|
|
||||||
char *ptr = payload;
|
|
||||||
|
|
||||||
for (int32_t i = 0; i < spd->numOfCols; ++i) {
|
|
||||||
if (!spd->cols[i].hasVal) { // current column do not have any value to insert, set it to null
|
|
||||||
if (schema[i].type == TSDB_DATA_TYPE_BINARY) {
|
|
||||||
varDataSetLen(ptr, sizeof(int8_t));
|
|
||||||
*(uint8_t*) varDataVal(ptr) = TSDB_DATA_BINARY_NULL;
|
|
||||||
} else if (schema[i].type == TSDB_DATA_TYPE_NCHAR) {
|
|
||||||
varDataSetLen(ptr, sizeof(int32_t));
|
|
||||||
*(uint32_t*) varDataVal(ptr) = TSDB_DATA_NCHAR_NULL;
|
|
||||||
} else {
|
} else {
|
||||||
setNull(ptr, schema[i].type, schema[i].bytes);
|
payloadColSetOffset(kvStart, colValOffset);
|
||||||
|
if (IS_DATA_COL_ORDERED(spd->orderStatus)) {
|
||||||
|
kvStart += PAYLOAD_COL_HEAD_LEN; // move to next column
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr += schema[i].bytes;
|
colValOffset += colValAppended;
|
||||||
|
kvRowLen += kvRowColLen;
|
||||||
|
dataRowLen += dataRowDeltaColLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
rowSize = (int32_t)(ptr - payload);
|
if (kvRowLen < dataRowLen) {
|
||||||
|
payloadSetType(payload, SMEM_ROW_KV);
|
||||||
|
} else {
|
||||||
|
payloadSetType(payload, SMEM_ROW_DATA);
|
||||||
}
|
}
|
||||||
|
|
||||||
*len = rowSize;
|
*len = (int32_t)(payloadValOffset + colValOffset);
|
||||||
|
payloadSetTLen(payload, *len);
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -536,6 +922,27 @@ static int32_t rowDataCompar(const void *lhs, const void *rhs) {
|
||||||
return left > right ? 1 : -1;
|
return left > right ? 1 : -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
int32_t schemaIdxCompar(const void *lhs, const void *rhs) {
|
||||||
|
uint16_t left = *(uint16_t *)lhs;
|
||||||
|
uint16_t right = *(uint16_t *)rhs;
|
||||||
|
|
||||||
|
if (left == right) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return left > right ? 1 : -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t boundIdxCompar(const void *lhs, const void *rhs) {
|
||||||
|
uint16_t left = *(uint16_t *)POINTER_SHIFT(lhs, sizeof(uint16_t));
|
||||||
|
uint16_t right = *(uint16_t *)POINTER_SHIFT(rhs, sizeof(uint16_t));
|
||||||
|
|
||||||
|
if (left == right) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return left > right ? 1 : -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int32_t tsParseValues(char **str, STableDataBlocks *pDataBlock, int maxRows, SInsertStatementParam *pInsertParam,
|
int32_t tsParseValues(char **str, STableDataBlocks *pDataBlock, int maxRows, SInsertStatementParam *pInsertParam,
|
||||||
int32_t* numOfRows, char *tmpTokenBuf) {
|
int32_t* numOfRows, char *tmpTokenBuf) {
|
||||||
|
|
@ -551,21 +958,26 @@ int32_t tsParseValues(char **str, STableDataBlocks *pDataBlock, int maxRows, SIn
|
||||||
|
|
||||||
int32_t precision = tinfo.precision;
|
int32_t precision = tinfo.precision;
|
||||||
|
|
||||||
|
int32_t extendedRowSize = getExtendedRowSize(&tinfo);
|
||||||
|
|
||||||
|
initSMemRowHelper(&pDataBlock->rowHelper, tscGetTableSchema(pDataBlock->pTableMeta),
|
||||||
|
tscGetNumOfColumns(pDataBlock->pTableMeta), 0);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
index = 0;
|
index = 0;
|
||||||
sToken = tStrGetToken(*str, &index, false);
|
sToken = tStrGetToken(*str, &index, false);
|
||||||
if (sToken.n == 0 || sToken.type != TK_LP) break;
|
if (sToken.n == 0 || sToken.type != TK_LP) break;
|
||||||
|
|
||||||
*str += index;
|
*str += index;
|
||||||
if ((*numOfRows) >= maxRows || pDataBlock->size + tinfo.rowSize >= pDataBlock->nAllocSize) {
|
if ((*numOfRows) >= maxRows || pDataBlock->size + extendedRowSize >= pDataBlock->nAllocSize) {
|
||||||
int32_t tSize;
|
int32_t tSize;
|
||||||
code = tscAllocateMemIfNeed(pDataBlock, tinfo.rowSize, &tSize);
|
code = tscAllocateMemIfNeed(pDataBlock, extendedRowSize, &tSize);
|
||||||
if (code != TSDB_CODE_SUCCESS) { //TODO pass the correct error code to client
|
if (code != TSDB_CODE_SUCCESS) { //TODO pass the correct error code to client
|
||||||
strcpy(pInsertParam->msg, "client out of memory");
|
strcpy(pInsertParam->msg, "client out of memory");
|
||||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(tSize > maxRows);
|
ASSERT(tSize >= maxRows);
|
||||||
maxRows = tSize;
|
maxRows = tSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -601,9 +1013,10 @@ int32_t tsParseValues(char **str, STableDataBlocks *pDataBlock, int maxRows, SIn
|
||||||
void tscSetBoundColumnInfo(SParsedDataColInfo *pColInfo, SSchema *pSchema, int32_t numOfCols) {
|
void tscSetBoundColumnInfo(SParsedDataColInfo *pColInfo, SSchema *pSchema, int32_t numOfCols) {
|
||||||
pColInfo->numOfCols = numOfCols;
|
pColInfo->numOfCols = numOfCols;
|
||||||
pColInfo->numOfBound = numOfCols;
|
pColInfo->numOfBound = numOfCols;
|
||||||
|
pColInfo->orderStatus = ORDER_STATUS_ORDERED;
|
||||||
pColInfo->boundedColumns = calloc(pColInfo->numOfCols, sizeof(int32_t));
|
pColInfo->boundedColumns = calloc(pColInfo->numOfCols, sizeof(int32_t));
|
||||||
pColInfo->cols = calloc(pColInfo->numOfCols, sizeof(SBoundColumn));
|
pColInfo->cols = calloc(pColInfo->numOfCols, sizeof(SBoundColumn));
|
||||||
|
pColInfo->colIdxInfo = NULL;
|
||||||
|
|
||||||
for (int32_t i = 0; i < pColInfo->numOfCols; ++i) {
|
for (int32_t i = 0; i < pColInfo->numOfCols; ++i) {
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
|
|
@ -656,8 +1069,9 @@ int32_t FORCE_INLINE tsSetBlockInfo(SSubmitBlk *pBlocks, const STableMeta *pTabl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
// data block is disordered, sort it in ascending order
|
// data block is disordered, sort it in ascending order
|
||||||
void tscSortRemoveDataBlockDupRows(STableDataBlocks *dataBuf) {
|
static void tscSortRemoveDataBlockDupRowsOld(STableDataBlocks *dataBuf) {
|
||||||
SSubmitBlk *pBlocks = (SSubmitBlk *)dataBuf->pData;
|
SSubmitBlk *pBlocks = (SSubmitBlk *)dataBuf->pData;
|
||||||
|
|
||||||
// size is less than the total size, since duplicated rows may be removed yet.
|
// size is less than the total size, since duplicated rows may be removed yet.
|
||||||
|
|
@ -700,12 +1114,91 @@ void tscSortRemoveDataBlockDupRows(STableDataBlocks *dataBuf) {
|
||||||
|
|
||||||
dataBuf->prevTS = INT64_MIN;
|
dataBuf->prevTS = INT64_MIN;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// data block is disordered, sort it in ascending order
|
||||||
|
int tscSortRemoveDataBlockDupRows(STableDataBlocks *dataBuf, SBlockKeyInfo *pBlkKeyInfo) {
|
||||||
|
SSubmitBlk *pBlocks = (SSubmitBlk *)dataBuf->pData;
|
||||||
|
int16_t nRows = pBlocks->numOfRows;
|
||||||
|
|
||||||
|
// size is less than the total size, since duplicated rows may be removed yet.
|
||||||
|
|
||||||
|
// if use server time, this block must be ordered
|
||||||
|
if (dataBuf->tsSource == TSDB_USE_SERVER_TS) {
|
||||||
|
assert(dataBuf->ordered);
|
||||||
|
}
|
||||||
|
// allocate memory
|
||||||
|
size_t nAlloc = nRows * sizeof(SBlockKeyTuple);
|
||||||
|
if (pBlkKeyInfo->pKeyTuple == NULL || pBlkKeyInfo->maxBytesAlloc < nAlloc) {
|
||||||
|
size_t nRealAlloc = nAlloc + 10 * sizeof(SBlockKeyTuple);
|
||||||
|
char * tmp = trealloc(pBlkKeyInfo->pKeyTuple, nRealAlloc);
|
||||||
|
if (tmp == NULL) {
|
||||||
|
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
pBlkKeyInfo->pKeyTuple = (SBlockKeyTuple *)tmp;
|
||||||
|
pBlkKeyInfo->maxBytesAlloc = (int32_t)nRealAlloc;
|
||||||
|
}
|
||||||
|
memset(pBlkKeyInfo->pKeyTuple, 0, nAlloc);
|
||||||
|
|
||||||
|
SBlockKeyTuple *pBlkKeyTuple = pBlkKeyInfo->pKeyTuple;
|
||||||
|
char * pBlockData = pBlocks->data;
|
||||||
|
TDRowTLenT totolPayloadTLen = 0;
|
||||||
|
TDRowTLenT payloadTLen = 0;
|
||||||
|
int n = 0;
|
||||||
|
while (n < nRows) {
|
||||||
|
pBlkKeyTuple->skey = payloadTSKey(pBlockData);
|
||||||
|
pBlkKeyTuple->payloadAddr = pBlockData;
|
||||||
|
payloadTLen = payloadTLen(pBlockData);
|
||||||
|
#if 0
|
||||||
|
ASSERT(payloadNCols(pBlockData) <= 4096);
|
||||||
|
ASSERT(payloadTLen(pBlockData) < 65536);
|
||||||
|
#endif
|
||||||
|
totolPayloadTLen += payloadTLen;
|
||||||
|
// next loop
|
||||||
|
pBlockData += payloadTLen;
|
||||||
|
++pBlkKeyTuple;
|
||||||
|
++n;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dataBuf->ordered) {
|
||||||
|
pBlkKeyTuple = pBlkKeyInfo->pKeyTuple;
|
||||||
|
qsort(pBlkKeyTuple, nRows, sizeof(SBlockKeyTuple), rowDataCompar);
|
||||||
|
|
||||||
|
pBlkKeyTuple = pBlkKeyInfo->pKeyTuple;
|
||||||
|
int32_t i = 0;
|
||||||
|
int32_t j = 1;
|
||||||
|
while (j < nRows) {
|
||||||
|
TSKEY ti = (pBlkKeyTuple + i)->skey;
|
||||||
|
TSKEY tj = (pBlkKeyTuple + j)->skey;
|
||||||
|
|
||||||
|
if (ti == tj) {
|
||||||
|
totolPayloadTLen -= payloadTLen(pBlkKeyTuple + j);
|
||||||
|
++j;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t nextPos = (++i);
|
||||||
|
if (nextPos != j) {
|
||||||
|
memmove(pBlkKeyTuple + nextPos, pBlkKeyTuple + j, sizeof(SBlockKeyTuple));
|
||||||
|
}
|
||||||
|
++j;
|
||||||
|
}
|
||||||
|
|
||||||
|
dataBuf->ordered = true;
|
||||||
|
pBlocks->numOfRows = i + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
dataBuf->size = sizeof(SSubmitBlk) + totolPayloadTLen;
|
||||||
|
dataBuf->prevTS = INT64_MIN;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t doParseInsertStatement(SInsertStatementParam *pInsertParam, char **str, STableDataBlocks* dataBuf, int32_t *totalNum) {
|
static int32_t doParseInsertStatement(SInsertStatementParam *pInsertParam, char **str, STableDataBlocks* dataBuf, int32_t *totalNum) {
|
||||||
STableComInfo tinfo = tscGetTableInfo(dataBuf->pTableMeta);
|
STableComInfo tinfo = tscGetTableInfo(dataBuf->pTableMeta);
|
||||||
|
|
||||||
int32_t maxNumOfRows;
|
int32_t maxNumOfRows;
|
||||||
int32_t code = tscAllocateMemIfNeed(dataBuf, tinfo.rowSize, &maxNumOfRows);
|
int32_t code = tscAllocateMemIfNeed(dataBuf, getExtendedRowSize(&tinfo), &maxNumOfRows);
|
||||||
if (TSDB_CODE_SUCCESS != code) {
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
@ -1038,10 +1531,11 @@ static int32_t validateDataSource(SInsertStatementParam *pInsertParam, int32_t t
|
||||||
|
|
||||||
static int32_t parseBoundColumns(SInsertStatementParam *pInsertParam, SParsedDataColInfo* pColInfo, SSchema* pSchema,
|
static int32_t parseBoundColumns(SInsertStatementParam *pInsertParam, SParsedDataColInfo* pColInfo, SSchema* pSchema,
|
||||||
char* str, char **end) {
|
char* str, char **end) {
|
||||||
pColInfo->numOfBound = 0;
|
int32_t nCols = pColInfo->numOfCols;
|
||||||
|
|
||||||
memset(pColInfo->boundedColumns, 0, sizeof(int32_t) * pColInfo->numOfCols);
|
pColInfo->numOfBound = 0;
|
||||||
for(int32_t i = 0; i < pColInfo->numOfCols; ++i) {
|
memset(pColInfo->boundedColumns, 0, sizeof(int32_t) * nCols);
|
||||||
|
for (int32_t i = 0; i < nCols; ++i) {
|
||||||
pColInfo->cols[i].hasVal = false;
|
pColInfo->cols[i].hasVal = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1056,6 +1550,8 @@ static int32_t parseBoundColumns(SInsertStatementParam *pInsertParam, SParsedDat
|
||||||
goto _clean;
|
goto _clean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isOrdered = true;
|
||||||
|
int32_t lastColIdx = -1; // last column found
|
||||||
while (1) {
|
while (1) {
|
||||||
index = 0;
|
index = 0;
|
||||||
sToken = tStrGetToken(str, &index, false);
|
sToken = tStrGetToken(str, &index, false);
|
||||||
|
|
@ -1076,7 +1572,8 @@ static int32_t parseBoundColumns(SInsertStatementParam *pInsertParam, SParsedDat
|
||||||
bool findColumnIndex = false;
|
bool findColumnIndex = false;
|
||||||
|
|
||||||
// todo speedup by using hash list
|
// todo speedup by using hash list
|
||||||
for (int32_t t = 0; t < pColInfo->numOfCols; ++t) {
|
int32_t nScanned = 0, t = lastColIdx + 1;
|
||||||
|
while (t < nCols) {
|
||||||
if (strncmp(sToken.z, pSchema[t].name, sToken.n) == 0 && strlen(pSchema[t].name) == sToken.n) {
|
if (strncmp(sToken.z, pSchema[t].name, sToken.n) == 0 && strlen(pSchema[t].name) == sToken.n) {
|
||||||
if (pColInfo->cols[t].hasVal == true) {
|
if (pColInfo->cols[t].hasVal == true) {
|
||||||
code = tscInvalidOperationMsg(pInsertParam->msg, "duplicated column name", sToken.z);
|
code = tscInvalidOperationMsg(pInsertParam->msg, "duplicated column name", sToken.z);
|
||||||
|
|
@ -1085,10 +1582,39 @@ static int32_t parseBoundColumns(SInsertStatementParam *pInsertParam, SParsedDat
|
||||||
|
|
||||||
pColInfo->cols[t].hasVal = true;
|
pColInfo->cols[t].hasVal = true;
|
||||||
pColInfo->boundedColumns[pColInfo->numOfBound] = t;
|
pColInfo->boundedColumns[pColInfo->numOfBound] = t;
|
||||||
pColInfo->numOfBound += 1;
|
++pColInfo->numOfBound;
|
||||||
findColumnIndex = true;
|
findColumnIndex = true;
|
||||||
|
if (isOrdered && (lastColIdx > t)) {
|
||||||
|
isOrdered = false;
|
||||||
|
}
|
||||||
|
lastColIdx = t;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
++t;
|
||||||
|
++nScanned;
|
||||||
|
}
|
||||||
|
if (!findColumnIndex) {
|
||||||
|
t = 0;
|
||||||
|
int32_t nRemain = nCols - nScanned;
|
||||||
|
while (t < nRemain) {
|
||||||
|
if (strncmp(sToken.z, pSchema[t].name, sToken.n) == 0 && strlen(pSchema[t].name) == sToken.n) {
|
||||||
|
if (pColInfo->cols[t].hasVal == true) {
|
||||||
|
code = tscInvalidOperationMsg(pInsertParam->msg, "duplicated column name", sToken.z);
|
||||||
|
goto _clean;
|
||||||
|
}
|
||||||
|
|
||||||
|
pColInfo->cols[t].hasVal = true;
|
||||||
|
pColInfo->boundedColumns[pColInfo->numOfBound] = t;
|
||||||
|
++pColInfo->numOfBound;
|
||||||
|
findColumnIndex = true;
|
||||||
|
if (isOrdered && (lastColIdx > t)) {
|
||||||
|
isOrdered = false;
|
||||||
|
}
|
||||||
|
lastColIdx = t;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++t;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!findColumnIndex) {
|
if (!findColumnIndex) {
|
||||||
|
|
@ -1097,7 +1623,29 @@ static int32_t parseBoundColumns(SInsertStatementParam *pInsertParam, SParsedDat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&pColInfo->boundedColumns[pColInfo->numOfBound], 0 , sizeof(int32_t) * (pColInfo->numOfCols - pColInfo->numOfBound));
|
pColInfo->orderStatus = isOrdered ? ORDER_STATUS_ORDERED : ORDER_STATUS_DISORDERED;
|
||||||
|
|
||||||
|
if (!isOrdered) {
|
||||||
|
pColInfo->colIdxInfo = tcalloc(pColInfo->numOfBound, sizeof(SBoundIdxInfo));
|
||||||
|
if (pColInfo->colIdxInfo == NULL) {
|
||||||
|
code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
|
goto _clean;
|
||||||
|
}
|
||||||
|
SBoundIdxInfo *pColIdx = pColInfo->colIdxInfo;
|
||||||
|
for (uint16_t i = 0; i < pColInfo->numOfBound; ++i) {
|
||||||
|
pColIdx[i].schemaColIdx = (uint16_t)pColInfo->boundedColumns[i];
|
||||||
|
pColIdx[i].boundIdx = i;
|
||||||
|
}
|
||||||
|
qsort(pColIdx, pColInfo->numOfBound, sizeof(SBoundIdxInfo), schemaIdxCompar);
|
||||||
|
for (uint16_t i = 0; i < pColInfo->numOfBound; ++i) {
|
||||||
|
pColIdx[i].finalIdx = i;
|
||||||
|
}
|
||||||
|
qsort(pColIdx, pColInfo->numOfBound, sizeof(SBoundIdxInfo), boundIdxCompar);
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&pColInfo->boundedColumns[pColInfo->numOfBound], 0,
|
||||||
|
sizeof(int32_t) * (pColInfo->numOfCols - pColInfo->numOfBound));
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
|
||||||
_clean:
|
_clean:
|
||||||
|
|
@ -1494,21 +2042,24 @@ static void parseFileSendDataBlock(void *param, TAOS_RES *tres, int32_t numOfRow
|
||||||
}
|
}
|
||||||
|
|
||||||
STableDataBlocks *pTableDataBlock = NULL;
|
STableDataBlocks *pTableDataBlock = NULL;
|
||||||
int32_t ret =
|
int32_t ret = tscGetDataBlockFromList(pInsertParam->pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE,
|
||||||
tscGetDataBlockFromList(pInsertParam->pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk),
|
sizeof(SSubmitBlk), tinfo.rowSize, &pTableMetaInfo->name, pTableMeta,
|
||||||
tinfo.rowSize, &pTableMetaInfo->name, pTableMeta, &pTableDataBlock, NULL);
|
&pTableDataBlock, NULL);
|
||||||
if (ret != TSDB_CODE_SUCCESS) {
|
if (ret != TSDB_CODE_SUCCESS) {
|
||||||
pParentSql->res.code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
pParentSql->res.code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
goto _error;
|
goto _error;
|
||||||
}
|
}
|
||||||
|
|
||||||
tscAllocateMemIfNeed(pTableDataBlock, tinfo.rowSize, &maxRows);
|
tscAllocateMemIfNeed(pTableDataBlock, getExtendedRowSize(&tinfo), &maxRows);
|
||||||
tokenBuf = calloc(1, TSDB_MAX_BYTES_PER_ROW);
|
tokenBuf = calloc(1, TSDB_MAX_BYTES_PER_ROW);
|
||||||
if (tokenBuf == NULL) {
|
if (tokenBuf == NULL) {
|
||||||
code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
goto _error;
|
goto _error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initSMemRowHelper(&pTableDataBlock->rowHelper, tscGetTableSchema(pTableDataBlock->pTableMeta),
|
||||||
|
tscGetNumOfColumns(pTableDataBlock->pTableMeta), 0);
|
||||||
|
|
||||||
while ((readLen = tgetline(&line, &n, fp)) != -1) {
|
while ((readLen = tgetline(&line, &n, fp)) != -1) {
|
||||||
if (('\r' == line[readLen - 1]) || ('\n' == line[readLen - 1])) {
|
if (('\r' == line[readLen - 1]) || ('\n' == line[readLen - 1])) {
|
||||||
line[--readLen] = 0;
|
line[--readLen] = 0;
|
||||||
|
|
|
||||||
|
|
@ -293,6 +293,7 @@ static char* normalStmtBuildSql(STscStmt* stmt) {
|
||||||
return taosStringBuilderGetResult(&sb, NULL);
|
return taosStringBuilderGetResult(&sb, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
static int fillColumnsNull(STableDataBlocks* pBlock, int32_t rowNum) {
|
static int fillColumnsNull(STableDataBlocks* pBlock, int32_t rowNum) {
|
||||||
SParsedDataColInfo* spd = &pBlock->boundColumnInfo;
|
SParsedDataColInfo* spd = &pBlock->boundColumnInfo;
|
||||||
int32_t offset = 0;
|
int32_t offset = 0;
|
||||||
|
|
@ -320,8 +321,129 @@ static int fillColumnsNull(STableDataBlocks* pBlock, int32_t rowNum) {
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* input:
|
||||||
|
* - schema:
|
||||||
|
* - payload:
|
||||||
|
* - spd:
|
||||||
|
* output:
|
||||||
|
* - pBlock with data block replaced by K-V format
|
||||||
|
*/
|
||||||
|
static int refactorPayload(STableDataBlocks* pBlock, int32_t rowNum) {
|
||||||
|
SParsedDataColInfo* spd = &pBlock->boundColumnInfo;
|
||||||
|
SSchema* schema = (SSchema*)pBlock->pTableMeta->schema;
|
||||||
|
SMemRowHelper* pHelper = &pBlock->rowHelper;
|
||||||
|
STableMeta* pTableMeta = pBlock->pTableMeta;
|
||||||
|
STableComInfo tinfo = tscGetTableInfo(pTableMeta);
|
||||||
|
int code = TSDB_CODE_SUCCESS;
|
||||||
|
int32_t extendedRowSize = getExtendedRowSize(&tinfo);
|
||||||
|
TDRowTLenT destPayloadSize = sizeof(SSubmitBlk);
|
||||||
|
|
||||||
|
ASSERT(pHelper->allNullLen >= 8);
|
||||||
|
|
||||||
|
TDRowTLenT destAllocSize = sizeof(SSubmitBlk) + rowNum * extendedRowSize;
|
||||||
|
SSubmitBlk* pDestBlock = tcalloc(destAllocSize, 1);
|
||||||
|
if (pDestBlock == NULL) {
|
||||||
|
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
memcpy(pDestBlock, pBlock->pData, sizeof(SSubmitBlk));
|
||||||
|
char* destPayload = (char*)pDestBlock + sizeof(SSubmitBlk);
|
||||||
|
|
||||||
|
char* srcPayload = (char*)pBlock->pData + sizeof(SSubmitBlk);
|
||||||
|
|
||||||
|
for (int n = 0; n < rowNum; ++n) {
|
||||||
|
payloadSetNCols(destPayload, spd->numOfBound);
|
||||||
|
|
||||||
|
TDRowTLenT dataRowLen = pHelper->allNullLen;
|
||||||
|
TDRowTLenT kvRowLen = TD_MEM_ROW_KV_VER_SIZE + sizeof(SColIdx) * spd->numOfBound;
|
||||||
|
TDRowTLenT payloadValOffset = payloadValuesOffset(destPayload); // rely on payloadNCols
|
||||||
|
TDRowLenT colValOffset = 0;
|
||||||
|
|
||||||
|
char* kvPrimaryKeyStart = destPayload + PAYLOAD_HEADER_LEN; // primaryKey in 1st column tuple
|
||||||
|
char* kvStart = kvPrimaryKeyStart + PAYLOAD_COL_HEAD_LEN; // the column tuple behind the primaryKey
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < spd->numOfBound; ++i) {
|
||||||
|
int32_t colIndex = spd->boundedColumns[i];
|
||||||
|
ASSERT(spd->cols[colIndex].hasVal);
|
||||||
|
char* start = srcPayload + spd->cols[colIndex].offset;
|
||||||
|
SSchema* pSchema = &schema[colIndex]; // get colId here
|
||||||
|
bool isPrimaryKey = (colIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX);
|
||||||
|
|
||||||
|
// the primary key locates in 1st column
|
||||||
|
if (!IS_DATA_COL_ORDERED(spd->orderStatus)) {
|
||||||
|
ASSERT(spd->colIdxInfo != NULL);
|
||||||
|
if (!isPrimaryKey) {
|
||||||
|
kvStart = POINTER_SHIFT(kvPrimaryKeyStart, spd->colIdxInfo[i].finalIdx * PAYLOAD_COL_HEAD_LEN);
|
||||||
|
} else {
|
||||||
|
ASSERT(spd->colIdxInfo[i].finalIdx == 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isPrimaryKey) {
|
||||||
|
payloadColSetId(kvPrimaryKeyStart, pSchema->colId);
|
||||||
|
payloadColSetType(kvPrimaryKeyStart, pSchema->type);
|
||||||
|
payloadColSetOffset(kvPrimaryKeyStart, colValOffset);
|
||||||
|
memcpy(POINTER_SHIFT(destPayload, payloadValOffset + colValOffset), start, TYPE_BYTES[pSchema->type]);
|
||||||
|
colValOffset += TYPE_BYTES[pSchema->type];
|
||||||
|
kvRowLen += TYPE_BYTES[pSchema->type];
|
||||||
|
} else {
|
||||||
|
payloadColSetId(kvStart, pSchema->colId);
|
||||||
|
payloadColSetType(kvStart, pSchema->type);
|
||||||
|
payloadColSetOffset(kvStart, colValOffset);
|
||||||
|
if (IS_VAR_DATA_TYPE(pSchema->type)) {
|
||||||
|
varDataCopy(POINTER_SHIFT(destPayload, payloadValOffset + colValOffset), start);
|
||||||
|
colValOffset += varDataTLen(start);
|
||||||
|
kvRowLen += varDataTLen(start);
|
||||||
|
if (pSchema->type == TSDB_DATA_TYPE_BINARY) {
|
||||||
|
dataRowLen += (varDataLen(start) - CHAR_BYTES);
|
||||||
|
} else if (pSchema->type == TSDB_DATA_TYPE_NCHAR) {
|
||||||
|
dataRowLen += (varDataLen(start) - TSDB_NCHAR_SIZE);
|
||||||
|
} else {
|
||||||
|
ASSERT(0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
memcpy(POINTER_SHIFT(destPayload, payloadValOffset + colValOffset), start, TYPE_BYTES[pSchema->type]);
|
||||||
|
colValOffset += TYPE_BYTES[pSchema->type];
|
||||||
|
kvRowLen += TYPE_BYTES[pSchema->type];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IS_DATA_COL_ORDERED(spd->orderStatus)) {
|
||||||
|
kvStart += PAYLOAD_COL_HEAD_LEN; // move to next column
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // end of column
|
||||||
|
|
||||||
|
if (kvRowLen < dataRowLen) {
|
||||||
|
payloadSetType(destPayload, SMEM_ROW_KV);
|
||||||
|
} else {
|
||||||
|
payloadSetType(destPayload, SMEM_ROW_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT(colValOffset <= TSDB_MAX_BYTES_PER_ROW);
|
||||||
|
|
||||||
|
TDRowTLenT len = payloadValOffset + colValOffset;
|
||||||
|
payloadSetTLen(destPayload, len);
|
||||||
|
|
||||||
|
// next loop
|
||||||
|
srcPayload += pBlock->rowSize;
|
||||||
|
destPayload += len;
|
||||||
|
|
||||||
|
destPayloadSize += len;
|
||||||
|
} // end of row
|
||||||
|
|
||||||
|
ASSERT(destPayloadSize <= destAllocSize);
|
||||||
|
|
||||||
|
tfree(pBlock->pData);
|
||||||
|
pBlock->pData = (char*)pDestBlock;
|
||||||
|
pBlock->nAllocSize = destAllocSize;
|
||||||
|
pBlock->size = destPayloadSize;
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
int32_t fillTablesColumnsNull(SSqlObj* pSql) {
|
int32_t fillTablesColumnsNull(SSqlObj* pSql) {
|
||||||
SSqlCmd* pCmd = &pSql->cmd;
|
SSqlCmd* pCmd = &pSql->cmd;
|
||||||
|
|
||||||
|
|
@ -344,9 +466,90 @@ int32_t fillTablesColumnsNull(SSqlObj* pSql) {
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check and sort
|
||||||
|
*/
|
||||||
|
static int initPayloadEnv(STableDataBlocks* pBlock, int32_t rowNum) {
|
||||||
|
SParsedDataColInfo* spd = &pBlock->boundColumnInfo;
|
||||||
|
if (spd->orderStatus != ORDER_STATUS_UNKNOWN) {
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isOrdered = true;
|
||||||
|
int32_t lastColIdx = -1;
|
||||||
|
for (int32_t i = 0; i < spd->numOfBound; ++i) {
|
||||||
|
ASSERT(spd->cols[i].hasVal);
|
||||||
|
int32_t colIdx = spd->boundedColumns[i];
|
||||||
|
if (isOrdered) {
|
||||||
|
if (lastColIdx > colIdx) {
|
||||||
|
isOrdered = false;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
lastColIdx = colIdx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
spd->orderStatus = isOrdered ? ORDER_STATUS_ORDERED : ORDER_STATUS_DISORDERED;
|
||||||
|
|
||||||
|
if (isOrdered) {
|
||||||
|
spd->colIdxInfo = NULL;
|
||||||
|
} else {
|
||||||
|
spd->colIdxInfo = calloc(spd->numOfBound, sizeof(SBoundIdxInfo));
|
||||||
|
if (spd->colIdxInfo == NULL) {
|
||||||
|
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
SBoundIdxInfo* pColIdx = spd->colIdxInfo;
|
||||||
|
for (uint16_t i = 0; i < spd->numOfBound; ++i) {
|
||||||
|
pColIdx[i].schemaColIdx = (uint16_t)spd->boundedColumns[i];
|
||||||
|
pColIdx[i].boundIdx = i;
|
||||||
|
}
|
||||||
|
qsort(pColIdx, spd->numOfBound, sizeof(SBoundIdxInfo), schemaIdxCompar);
|
||||||
|
for (uint16_t i = 0; i < spd->numOfBound; ++i) {
|
||||||
|
pColIdx[i].finalIdx = i;
|
||||||
|
}
|
||||||
|
qsort(pColIdx, spd->numOfBound, sizeof(SBoundIdxInfo), boundIdxCompar);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refactor the raw payload structure to K-V format as the in tsParseOneRow()
|
||||||
|
*/
|
||||||
|
int32_t fillTablesPayload(SSqlObj* pSql) {
|
||||||
|
SSqlCmd* pCmd = &pSql->cmd;
|
||||||
|
int code = TSDB_CODE_SUCCESS;
|
||||||
|
|
||||||
|
STableDataBlocks** p = taosHashIterate(pCmd->insertParam.pTableBlockHashList, NULL);
|
||||||
|
|
||||||
|
STableDataBlocks* pOneTableBlock = *p;
|
||||||
|
while (pOneTableBlock) {
|
||||||
|
SSubmitBlk* pBlocks = (SSubmitBlk*)pOneTableBlock->pData;
|
||||||
|
|
||||||
|
if (pBlocks->numOfRows > 0) {
|
||||||
|
initSMemRowHelper(&pOneTableBlock->rowHelper, tscGetTableSchema(pOneTableBlock->pTableMeta),
|
||||||
|
tscGetNumOfColumns(pOneTableBlock->pTableMeta), 0);
|
||||||
|
if ((code = initPayloadEnv(pOneTableBlock, pBlocks->numOfRows)) != TSDB_CODE_SUCCESS) {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
if ((code = refactorPayload(pOneTableBlock, pBlocks->numOfRows)) != TSDB_CODE_SUCCESS) {
|
||||||
|
return code;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
p = taosHashIterate(pCmd->insertParam.pTableBlockHashList, p);
|
||||||
|
if (p == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
pOneTableBlock = *p;
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// functions for insertion statement preparation
|
// functions for insertion statement preparation
|
||||||
static FORCE_INLINE int doBindParam(STableDataBlocks* pBlock, char* data, SParamInfo* param, TAOS_BIND* bind, int32_t colNum) {
|
static FORCE_INLINE int doBindParam(STableDataBlocks* pBlock, char* data, SParamInfo* param, TAOS_BIND* bind, int32_t colNum) {
|
||||||
|
|
@ -1202,9 +1405,12 @@ static int insertStmtExecute(STscStmt* stmt) {
|
||||||
pBlk->uid = pTableMeta->id.uid;
|
pBlk->uid = pTableMeta->id.uid;
|
||||||
pBlk->tid = pTableMeta->id.tid;
|
pBlk->tid = pTableMeta->id.tid;
|
||||||
|
|
||||||
fillTablesColumnsNull(stmt->pSql);
|
int code = fillTablesPayload(stmt->pSql);
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
int code = tscMergeTableDataBlocks(&stmt->pSql->cmd.insertParam, false);
|
code = tscMergeTableDataBlocks(&stmt->pSql->cmd.insertParam, false);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
@ -1269,8 +1475,6 @@ static void insertBatchClean(STscStmt* pStmt) {
|
||||||
static int insertBatchStmtExecute(STscStmt* pStmt) {
|
static int insertBatchStmtExecute(STscStmt* pStmt) {
|
||||||
int32_t code = 0;
|
int32_t code = 0;
|
||||||
|
|
||||||
int64_t st1 = taosGetTimestampUs();
|
|
||||||
|
|
||||||
if(pStmt->mtb.nameSet == false) {
|
if(pStmt->mtb.nameSet == false) {
|
||||||
tscError("0x%"PRIx64" no table name set", pStmt->pSql->self);
|
tscError("0x%"PRIx64" no table name set", pStmt->pSql->self);
|
||||||
return invalidOperationMsg(tscGetErrorMsgPayload(&pStmt->pSql->cmd), "no table name set");
|
return invalidOperationMsg(tscGetErrorMsgPayload(&pStmt->pSql->cmd), "no table name set");
|
||||||
|
|
@ -1283,37 +1487,25 @@ static int insertBatchStmtExecute(STscStmt* pStmt) {
|
||||||
return TSDB_CODE_TSC_APP_ERROR;
|
return TSDB_CODE_TSC_APP_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
fillTablesColumnsNull(pStmt->pSql);
|
fillTablesPayload(pStmt->pSql);
|
||||||
|
|
||||||
int64_t st2 = taosGetTimestampUs();
|
|
||||||
|
|
||||||
if ((code = tscMergeTableDataBlocks(&pStmt->pSql->cmd.insertParam, false)) != TSDB_CODE_SUCCESS) {
|
if ((code = tscMergeTableDataBlocks(&pStmt->pSql->cmd.insertParam, false)) != TSDB_CODE_SUCCESS) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t st3 = taosGetTimestampUs();
|
|
||||||
|
|
||||||
code = tscHandleMultivnodeInsert(pStmt->pSql);
|
code = tscHandleMultivnodeInsert(pStmt->pSql);
|
||||||
|
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t st4 = taosGetTimestampUs();
|
|
||||||
|
|
||||||
// wait for the callback function to post the semaphore
|
// wait for the callback function to post the semaphore
|
||||||
tsem_wait(&pStmt->pSql->rspSem);
|
tsem_wait(&pStmt->pSql->rspSem);
|
||||||
|
|
||||||
int64_t st5 = taosGetTimestampUs();
|
|
||||||
|
|
||||||
code = pStmt->pSql->res.code;
|
code = pStmt->pSql->res.code;
|
||||||
|
|
||||||
insertBatchClean(pStmt);
|
insertBatchClean(pStmt);
|
||||||
|
|
||||||
int64_t st6 = taosGetTimestampUs();
|
|
||||||
|
|
||||||
tscDebug("use time:%"PRId64 ",%"PRId64 ",%"PRId64 ",%"PRId64 ",%"PRId64, st2-st1, st3-st2, st4-st3, st5-st4, st6-st5);
|
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@
|
||||||
#include "tstrbuild.h"
|
#include "tstrbuild.h"
|
||||||
#include "ttoken.h"
|
#include "ttoken.h"
|
||||||
#include "ttokendef.h"
|
#include "ttokendef.h"
|
||||||
|
#include "qScript.h"
|
||||||
#include "ttype.h"
|
#include "ttype.h"
|
||||||
|
|
||||||
#define DEFAULT_PRIMARY_TIMESTAMP_COL_NAME "_c0"
|
#define DEFAULT_PRIMARY_TIMESTAMP_COL_NAME "_c0"
|
||||||
|
|
@ -77,7 +78,8 @@ static bool validateTagParams(SArray* pTagsList, SArray* pFieldList, SSqlCmd* pC
|
||||||
static int32_t setObjFullName(char* fullName, const char* account, SStrToken* pDB, SStrToken* tableName, int32_t* len);
|
static int32_t setObjFullName(char* fullName, const char* account, SStrToken* pDB, SStrToken* tableName, int32_t* len);
|
||||||
static void getColumnName(tSqlExprItem* pItem, char* resultFieldName, char* rawName, int32_t nameLength);
|
static void getColumnName(tSqlExprItem* pItem, char* resultFieldName, char* rawName, int32_t nameLength);
|
||||||
|
|
||||||
static int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t colIndex, tSqlExprItem* pItem, bool finalResult);
|
static int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t colIndex, tSqlExprItem* pItem,
|
||||||
|
bool finalResult, SUdfInfo* pUdfInfo);
|
||||||
static int32_t insertResultField(SQueryInfo* pQueryInfo, int32_t outputIndex, SColumnList* pIdList, int16_t bytes,
|
static int32_t insertResultField(SQueryInfo* pQueryInfo, int32_t outputIndex, SColumnList* pIdList, int16_t bytes,
|
||||||
int8_t type, char* fieldName, SExprInfo* pSqlExpr);
|
int8_t type, char* fieldName, SExprInfo* pSqlExpr);
|
||||||
|
|
||||||
|
|
@ -386,6 +388,137 @@ static int32_t normalizeVarDataTypeLength(SSqlCmd* pCmd) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t readFromFile(char *name, uint32_t *len, void **buf) {
|
||||||
|
struct stat fileStat;
|
||||||
|
if (stat(name, &fileStat) < 0) {
|
||||||
|
tscError("stat file %s failed, error:%s", name, strerror(errno));
|
||||||
|
return TAOS_SYSTEM_ERROR(errno);
|
||||||
|
}
|
||||||
|
|
||||||
|
*len = fileStat.st_size;
|
||||||
|
|
||||||
|
if (*len <= 0) {
|
||||||
|
tscError("file %s is empty", name);
|
||||||
|
return TSDB_CODE_TSC_FILE_EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
*buf = calloc(1, *len);
|
||||||
|
if (*buf == NULL) {
|
||||||
|
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fd = open(name, O_RDONLY);
|
||||||
|
if (fd < 0) {
|
||||||
|
tscError("open file %s failed, error:%s", name, strerror(errno));
|
||||||
|
tfree(*buf);
|
||||||
|
return TAOS_SYSTEM_ERROR(errno);
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t s = taosRead(fd, *buf, *len);
|
||||||
|
if (s != *len) {
|
||||||
|
tscError("read file %s failed, error:%s", name, strerror(errno));
|
||||||
|
close(fd);
|
||||||
|
tfree(*buf);
|
||||||
|
return TSDB_CODE_TSC_APP_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32_t handleUserDefinedFunc(SSqlObj* pSql, struct SSqlInfo* pInfo) {
|
||||||
|
const char *msg1 = "function name is too long";
|
||||||
|
const char *msg2 = "path is too long";
|
||||||
|
const char *msg3 = "invalid outputtype";
|
||||||
|
const char *msg4 = "invalid script";
|
||||||
|
SSqlCmd *pCmd = &pSql->cmd;
|
||||||
|
|
||||||
|
switch (pInfo->type) {
|
||||||
|
case TSDB_SQL_CREATE_FUNCTION: {
|
||||||
|
SCreateFuncInfo *createInfo = &pInfo->pMiscInfo->funcOpt;
|
||||||
|
uint32_t len = 0;
|
||||||
|
void *buf = NULL;
|
||||||
|
|
||||||
|
if (createInfo->output.type == (uint8_t)-1 || createInfo->output.bytes < 0) {
|
||||||
|
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3);
|
||||||
|
}
|
||||||
|
|
||||||
|
createInfo->name.z[createInfo->name.n] = 0;
|
||||||
|
|
||||||
|
strdequote(createInfo->name.z);
|
||||||
|
|
||||||
|
if (strlen(createInfo->name.z) >= TSDB_FUNC_NAME_LEN) {
|
||||||
|
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
||||||
|
}
|
||||||
|
|
||||||
|
createInfo->path.z[createInfo->path.n] = 0;
|
||||||
|
|
||||||
|
strdequote(createInfo->path.z);
|
||||||
|
|
||||||
|
if (strlen(createInfo->path.z) >= PATH_MAX) {
|
||||||
|
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t ret = readFromFile(createInfo->path.z, &len, &buf);
|
||||||
|
if (ret) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
//distinguish *.lua and *.so
|
||||||
|
int32_t pathLen = (int32_t)strlen(createInfo->path.z);
|
||||||
|
if ((pathLen > 3) && (0 == strncmp(createInfo->path.z + pathLen - 3, "lua", 3)) && !isValidScript(buf, len)) {
|
||||||
|
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4);
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO CHECK CODE
|
||||||
|
if (len + sizeof(SCreateFuncMsg) > pSql->cmd.allocSize) {
|
||||||
|
ret = tscAllocPayload(&pSql->cmd, len + sizeof(SCreateFuncMsg));
|
||||||
|
if (ret) {
|
||||||
|
tfree(buf);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SCreateFuncMsg *pMsg = (SCreateFuncMsg *)pSql->cmd.payload;
|
||||||
|
|
||||||
|
strcpy(pMsg->name, createInfo->name.z);
|
||||||
|
strcpy(pMsg->path, createInfo->path.z);
|
||||||
|
|
||||||
|
pMsg->funcType = htonl(createInfo->type);
|
||||||
|
pMsg->bufSize = htonl(createInfo->bufSize);
|
||||||
|
|
||||||
|
pMsg->outputType = createInfo->output.type;
|
||||||
|
pMsg->outputLen = htons(createInfo->output.bytes);
|
||||||
|
|
||||||
|
pMsg->codeLen = htonl(len);
|
||||||
|
memcpy(pMsg->code, buf, len);
|
||||||
|
tfree(buf);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TSDB_SQL_DROP_FUNCTION: {
|
||||||
|
SStrToken* t0 = taosArrayGet(pInfo->pMiscInfo->a, 0);
|
||||||
|
|
||||||
|
SDropFuncMsg *pMsg = (SDropFuncMsg *)pSql->cmd.payload;
|
||||||
|
|
||||||
|
t0->z[t0->n] = 0;
|
||||||
|
|
||||||
|
strdequote(t0->z);
|
||||||
|
|
||||||
|
if (strlen(t0->z) >= TSDB_FUNC_NAME_LEN) {
|
||||||
|
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(pMsg->name, t0->z);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return TSDB_CODE_TSC_APP_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
|
int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
|
||||||
if (pInfo == NULL || pSql == NULL) {
|
if (pInfo == NULL || pSql == NULL) {
|
||||||
return TSDB_CODE_TSC_APP_ERROR;
|
return TSDB_CODE_TSC_APP_ERROR;
|
||||||
|
|
@ -486,6 +619,16 @@ int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case TSDB_SQL_CREATE_FUNCTION:
|
||||||
|
case TSDB_SQL_DROP_FUNCTION: {
|
||||||
|
code = handleUserDefinedFunc(pSql, pInfo);
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case TSDB_SQL_ALTER_DB:
|
case TSDB_SQL_ALTER_DB:
|
||||||
case TSDB_SQL_CREATE_DB: {
|
case TSDB_SQL_CREATE_DB: {
|
||||||
const char* msg1 = "invalid db name";
|
const char* msg1 = "invalid db name";
|
||||||
|
|
@ -769,7 +912,15 @@ int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SArray *pUdfInfo = NULL;
|
||||||
|
if (pQueryInfo->pUdfInfo) {
|
||||||
|
pUdfInfo = taosArrayDup(pQueryInfo->pUdfInfo);
|
||||||
|
}
|
||||||
|
|
||||||
pQueryInfo = pCmd->active;
|
pQueryInfo = pCmd->active;
|
||||||
|
pQueryInfo->pUdfInfo = pUdfInfo;
|
||||||
|
pQueryInfo->udfCopy = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1245,12 +1396,16 @@ static bool validateTableColumnInfo(SArray* pFieldList, SSqlCmd* pCmd) {
|
||||||
const char* msg4 = "invalid data type";
|
const char* msg4 = "invalid data type";
|
||||||
const char* msg5 = "invalid binary/nchar column length";
|
const char* msg5 = "invalid binary/nchar column length";
|
||||||
const char* msg6 = "invalid column name";
|
const char* msg6 = "invalid column name";
|
||||||
|
const char* msg7 = "too many columns";
|
||||||
|
|
||||||
// number of fields no less than 2
|
// number of fields no less than 2
|
||||||
size_t numOfCols = taosArrayGetSize(pFieldList);
|
size_t numOfCols = taosArrayGetSize(pFieldList);
|
||||||
if (numOfCols <= 1 || numOfCols > TSDB_MAX_COLUMNS) {
|
if (numOfCols <= 1 ) {
|
||||||
invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg);
|
invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg);
|
||||||
return false;
|
return false;
|
||||||
|
} else if (numOfCols > TSDB_MAX_COLUMNS) {
|
||||||
|
invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg7);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// first column must be timestamp
|
// first column must be timestamp
|
||||||
|
|
@ -1385,6 +1540,7 @@ bool validateOneTags(SSqlCmd* pCmd, TAOS_FIELD* pTagField) {
|
||||||
const char* msg4 = "invalid tag name";
|
const char* msg4 = "invalid tag name";
|
||||||
const char* msg5 = "invalid binary/nchar tag length";
|
const char* msg5 = "invalid binary/nchar tag length";
|
||||||
const char* msg6 = "invalid data type in tags";
|
const char* msg6 = "invalid data type in tags";
|
||||||
|
const char* msg7 = "too many columns";
|
||||||
|
|
||||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0);
|
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0);
|
||||||
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
|
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
|
||||||
|
|
@ -1392,6 +1548,12 @@ bool validateOneTags(SSqlCmd* pCmd, TAOS_FIELD* pTagField) {
|
||||||
int32_t numOfTags = tscGetNumOfTags(pTableMeta);
|
int32_t numOfTags = tscGetNumOfTags(pTableMeta);
|
||||||
int32_t numOfCols = tscGetNumOfColumns(pTableMeta);
|
int32_t numOfCols = tscGetNumOfColumns(pTableMeta);
|
||||||
|
|
||||||
|
// no more max columns
|
||||||
|
if (numOfTags + numOfCols >= TSDB_MAX_COLUMNS) {
|
||||||
|
invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg7);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// no more than 6 tags
|
// no more than 6 tags
|
||||||
if (numOfTags == TSDB_MAX_TAGS) {
|
if (numOfTags == TSDB_MAX_TAGS) {
|
||||||
char msg[128] = {0};
|
char msg[128] = {0};
|
||||||
|
|
@ -1809,6 +1971,69 @@ static bool hasNoneUserDefineExpr(SQueryInfo* pQueryInfo) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void genUdfList(SArray* pUdfInfo, tSqlExpr *pNode) {
|
||||||
|
if (pNode == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pNode->type == SQL_NODE_EXPR) {
|
||||||
|
genUdfList(pUdfInfo, pNode->pLeft);
|
||||||
|
genUdfList(pUdfInfo, pNode->pRight);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pNode->type == SQL_NODE_SQLFUNCTION) {
|
||||||
|
pNode->functionId = isValidFunction(pNode->Expr.operand.z, pNode->Expr.operand.n);
|
||||||
|
if (pNode->functionId < 0) { // extract all possible user defined function
|
||||||
|
struct SUdfInfo info = {0};
|
||||||
|
info.name = strndup(pNode->Expr.operand.z, pNode->Expr.operand.n);
|
||||||
|
int32_t functionId = (int32_t)taosArrayGetSize(pUdfInfo) * (-1) - 1;
|
||||||
|
info.functionId = functionId;
|
||||||
|
|
||||||
|
taosArrayPush(pUdfInfo, &info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
static int32_t checkForUdf(SSqlObj* pSql, SQueryInfo* pQueryInfo, SArray* pSelection) {
|
||||||
|
if (pQueryInfo->pUdfInfo != NULL) {
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
pQueryInfo->pUdfInfo = taosArrayInit(4, sizeof(struct SUdfInfo));
|
||||||
|
|
||||||
|
size_t nExpr = taosArrayGetSize(pSelection);
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < nExpr; ++i) {
|
||||||
|
tSqlExprItem* pItem = taosArrayGet(pSelection, i);
|
||||||
|
|
||||||
|
int32_t type = pItem->pNode->type;
|
||||||
|
if (type == SQL_NODE_EXPR || type == SQL_NODE_SQLFUNCTION) {
|
||||||
|
genUdfList(pQueryInfo->pUdfInfo, pItem->pNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (taosArrayGetSize(pQueryInfo->pUdfInfo) > 0) {
|
||||||
|
return tscGetUdfFromNode(pSql, pQueryInfo);
|
||||||
|
} else {
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
static SUdfInfo* isValidUdf(SArray* pUdfInfo, const char* name, int32_t len) {
|
||||||
|
size_t t = taosArrayGetSize(pUdfInfo);
|
||||||
|
for(int32_t i = 0; i < t; ++i) {
|
||||||
|
SUdfInfo* pUdf = taosArrayGet(pUdfInfo, i);
|
||||||
|
if (strlen(pUdf->name) == len && strncasecmp(pUdf->name, name, len) == 0) {
|
||||||
|
return pUdf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t validateSelectNodeList(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pSelNodeList, bool joinQuery,
|
int32_t validateSelectNodeList(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pSelNodeList, bool joinQuery,
|
||||||
bool timeWindowQuery, bool outerQuery) {
|
bool timeWindowQuery, bool outerQuery) {
|
||||||
assert(pSelNodeList != NULL && pCmd != NULL);
|
assert(pSelNodeList != NULL && pCmd != NULL);
|
||||||
|
|
@ -1841,12 +2066,18 @@ int32_t validateSelectNodeList(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pS
|
||||||
int32_t type = pItem->pNode->type;
|
int32_t type = pItem->pNode->type;
|
||||||
if (type == SQL_NODE_SQLFUNCTION) {
|
if (type == SQL_NODE_SQLFUNCTION) {
|
||||||
pItem->pNode->functionId = isValidFunction(pItem->pNode->Expr.operand.z, pItem->pNode->Expr.operand.n);
|
pItem->pNode->functionId = isValidFunction(pItem->pNode->Expr.operand.z, pItem->pNode->Expr.operand.n);
|
||||||
|
SUdfInfo* pUdfInfo = NULL;
|
||||||
if (pItem->pNode->functionId < 0) {
|
if (pItem->pNode->functionId < 0) {
|
||||||
|
pUdfInfo = isValidUdf(pQueryInfo->pUdfInfo, pItem->pNode->Expr.operand.z, pItem->pNode->Expr.operand.n);
|
||||||
|
if (pUdfInfo == NULL) {
|
||||||
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5);
|
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pItem->pNode->functionId = pUdfInfo->functionId;
|
||||||
|
}
|
||||||
|
|
||||||
// sql function in selection clause, append sql function info in pSqlCmd structure sequentially
|
// sql function in selection clause, append sql function info in pSqlCmd structure sequentially
|
||||||
if (addExprAndResultField(pCmd, pQueryInfo, outputIndex, pItem, true) != TSDB_CODE_SUCCESS) {
|
if (addExprAndResultField(pCmd, pQueryInfo, outputIndex, pItem, true, pUdfInfo) != TSDB_CODE_SUCCESS) {
|
||||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
}
|
}
|
||||||
} else if (type == SQL_NODE_TABLE_COLUMN || type == SQL_NODE_VALUE) {
|
} else if (type == SQL_NODE_TABLE_COLUMN || type == SQL_NODE_VALUE) {
|
||||||
|
|
@ -2101,7 +2332,8 @@ int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t setExprInfoForFunctions(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSchema* pSchema, SConvertFunc cvtFunc,
|
static int32_t setExprInfoForFunctions(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSchema* pSchema, SConvertFunc cvtFunc,
|
||||||
const char* name, int32_t resColIdx, SColumnIndex* pColIndex, bool finalResult) {
|
const char* name, int32_t resColIdx, SColumnIndex* pColIndex, bool finalResult,
|
||||||
|
SUdfInfo* pUdfInfo) {
|
||||||
const char* msg1 = "not support column types";
|
const char* msg1 = "not support column types";
|
||||||
|
|
||||||
int32_t f = cvtFunc.execFuncId;
|
int32_t f = cvtFunc.execFuncId;
|
||||||
|
|
@ -2117,7 +2349,7 @@ static int32_t setExprInfoForFunctions(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SS
|
||||||
int16_t resBytes = 0;
|
int16_t resBytes = 0;
|
||||||
int32_t interBufSize = 0;
|
int32_t interBufSize = 0;
|
||||||
|
|
||||||
getResultDataInfo(pSchema->type, pSchema->bytes, f, 0, &resType, &resBytes, &interBufSize, 0, false);
|
getResultDataInfo(pSchema->type, pSchema->bytes, f, 0, &resType, &resBytes, &interBufSize, 0, false, pUdfInfo);
|
||||||
SExprInfo* pExpr = tscExprAppend(pQueryInfo, f, pColIndex, resType, resBytes, getNewResColId(pCmd), interBufSize, false);
|
SExprInfo* pExpr = tscExprAppend(pQueryInfo, f, pColIndex, resType, resBytes, getNewResColId(pCmd), interBufSize, false);
|
||||||
tstrncpy(pExpr->base.aliasName, name, tListLen(pExpr->base.aliasName));
|
tstrncpy(pExpr->base.aliasName, name, tListLen(pExpr->base.aliasName));
|
||||||
|
|
||||||
|
|
@ -2189,18 +2421,19 @@ static void updateLastScanOrderIfNeeded(SQueryInfo* pQueryInfo) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static UNUSED_FUNC void updateFunctionInterBuf(SQueryInfo* pQueryInfo, bool superTable) {
|
static UNUSED_FUNC void updateFunctionInterBuf(SQueryInfo* pQueryInfo, bool superTable, SUdfInfo* pUdfInfo) {
|
||||||
size_t numOfExpr = tscNumOfExprs(pQueryInfo);
|
size_t numOfExpr = tscNumOfExprs(pQueryInfo);
|
||||||
for (int32_t i = 0; i < numOfExpr; ++i) {
|
for (int32_t i = 0; i < numOfExpr; ++i) {
|
||||||
SExprInfo* pExpr = tscExprGet(pQueryInfo, i);
|
SExprInfo* pExpr = tscExprGet(pQueryInfo, i);
|
||||||
|
|
||||||
int32_t param = (int32_t)pExpr->base.param[0].i64;
|
int32_t param = (int32_t)pExpr->base.param[0].i64;
|
||||||
getResultDataInfo(pExpr->base.colType, pExpr->base.colBytes, pExpr->base.functionId, param, &pExpr->base.resType, &pExpr->base.resBytes,
|
getResultDataInfo(pExpr->base.colType, pExpr->base.colBytes, pExpr->base.functionId, param, &pExpr->base.resType, &pExpr->base.resBytes,
|
||||||
&pExpr->base.interBytes, 0, superTable);
|
&pExpr->base.interBytes, 0, superTable, pUdfInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t colIndex, tSqlExprItem* pItem, bool finalResult) {
|
int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t colIndex, tSqlExprItem* pItem, bool finalResult,
|
||||||
|
SUdfInfo* pUdfInfo) {
|
||||||
STableMetaInfo* pTableMetaInfo = NULL;
|
STableMetaInfo* pTableMetaInfo = NULL;
|
||||||
int32_t functionId = pItem->pNode->functionId;
|
int32_t functionId = pItem->pNode->functionId;
|
||||||
|
|
||||||
|
|
@ -2349,7 +2582,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
|
||||||
int32_t intermediateResSize = 0;
|
int32_t intermediateResSize = 0;
|
||||||
|
|
||||||
if (getResultDataInfo(pSchema->type, pSchema->bytes, functionId, 0, &resultType, &resultSize,
|
if (getResultDataInfo(pSchema->type, pSchema->bytes, functionId, 0, &resultType, &resultSize,
|
||||||
&intermediateResSize, 0, false) != TSDB_CODE_SUCCESS) {
|
&intermediateResSize, 0, false, NULL) != TSDB_CODE_SUCCESS) {
|
||||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2483,7 +2716,8 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
|
||||||
SStrToken t = {.z = pSchema[j].name, .n = (uint32_t)strnlen(pSchema[j].name, TSDB_COL_NAME_LEN)};
|
SStrToken t = {.z = pSchema[j].name, .n = (uint32_t)strnlen(pSchema[j].name, TSDB_COL_NAME_LEN)};
|
||||||
setResultColName(name, pItem, cvtFunc.originFuncId, &t, true);
|
setResultColName(name, pItem, cvtFunc.originFuncId, &t, true);
|
||||||
|
|
||||||
if (setExprInfoForFunctions(pCmd, pQueryInfo, &pSchema[j], cvtFunc, name, colIndex++, &index, finalResult) != 0) {
|
if (setExprInfoForFunctions(pCmd, pQueryInfo, &pSchema[j], cvtFunc, name, colIndex++, &index,
|
||||||
|
finalResult, pUdfInfo) != 0) {
|
||||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2506,7 +2740,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
|
||||||
bool multiColOutput = taosArrayGetSize(pItem->pNode->Expr.paramList) > 1;
|
bool multiColOutput = taosArrayGetSize(pItem->pNode->Expr.paramList) > 1;
|
||||||
setResultColName(name, pItem, cvtFunc.originFuncId, &pParamElem->pNode->columnName, multiColOutput);
|
setResultColName(name, pItem, cvtFunc.originFuncId, &pParamElem->pNode->columnName, multiColOutput);
|
||||||
|
|
||||||
if (setExprInfoForFunctions(pCmd, pQueryInfo, pSchema, cvtFunc, name, colIndex++, &index, finalResult) != 0) {
|
if (setExprInfoForFunctions(pCmd, pQueryInfo, pSchema, cvtFunc, name, colIndex++, &index, finalResult, pUdfInfo) != 0) {
|
||||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2531,7 +2765,8 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
|
||||||
SStrToken t = {.z = pSchema[i].name, .n = (uint32_t)strnlen(pSchema[i].name, TSDB_COL_NAME_LEN)};
|
SStrToken t = {.z = pSchema[i].name, .n = (uint32_t)strnlen(pSchema[i].name, TSDB_COL_NAME_LEN)};
|
||||||
setResultColName(name, pItem, cvtFunc.originFuncId, &t, true);
|
setResultColName(name, pItem, cvtFunc.originFuncId, &t, true);
|
||||||
|
|
||||||
if (setExprInfoForFunctions(pCmd, pQueryInfo, &pSchema[index.columnIndex], cvtFunc, name, colIndex, &index, finalResult) != 0) {
|
if (setExprInfoForFunctions(pCmd, pQueryInfo, &pSchema[index.columnIndex], cvtFunc, name, colIndex, &index,
|
||||||
|
finalResult, pUdfInfo) != 0) {
|
||||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
}
|
}
|
||||||
colIndex++;
|
colIndex++;
|
||||||
|
|
@ -2602,7 +2837,8 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
|
||||||
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5);
|
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5);
|
||||||
}
|
}
|
||||||
|
|
||||||
getResultDataInfo(pSchema->type, pSchema->bytes, functionId, 0, &resultType, &resultSize, &interResult, 0, false);
|
getResultDataInfo(pSchema->type, pSchema->bytes, functionId, 0, &resultType, &resultSize, &interResult, 0, false,
|
||||||
|
pUdfInfo);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* sql function transformation
|
* sql function transformation
|
||||||
|
|
@ -2715,7 +2951,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
|
||||||
int16_t type = 0;
|
int16_t type = 0;
|
||||||
int32_t inter = 0;
|
int32_t inter = 0;
|
||||||
|
|
||||||
int32_t ret = getResultDataInfo(s.type, s.bytes, TSDB_FUNC_TID_TAG, 0, &type, &bytes, &inter, 0, 0);
|
int32_t ret = getResultDataInfo(s.type, s.bytes, TSDB_FUNC_TID_TAG, 0, &type, &bytes, &inter, 0, 0, NULL);
|
||||||
assert(ret == TSDB_CODE_SUCCESS);
|
assert(ret == TSDB_CODE_SUCCESS);
|
||||||
|
|
||||||
s.type = (uint8_t)type;
|
s.type = (uint8_t)type;
|
||||||
|
|
@ -2739,7 +2975,8 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
|
||||||
int32_t inter = 0;
|
int32_t inter = 0;
|
||||||
int16_t resType = 0;
|
int16_t resType = 0;
|
||||||
int16_t bytes = 0;
|
int16_t bytes = 0;
|
||||||
getResultDataInfo(TSDB_DATA_TYPE_INT, 4, TSDB_FUNC_BLKINFO, 0, &resType, &bytes, &inter, 0, 0);
|
|
||||||
|
getResultDataInfo(TSDB_DATA_TYPE_INT, 4, TSDB_FUNC_BLKINFO, 0, &resType, &bytes, &inter, 0, 0, NULL);
|
||||||
|
|
||||||
SSchema s = {.name = "block_dist", .type = TSDB_DATA_TYPE_BINARY, .bytes = bytes};
|
SSchema s = {.name = "block_dist", .type = TSDB_DATA_TYPE_BINARY, .bytes = bytes};
|
||||||
|
|
||||||
|
|
@ -2757,10 +2994,64 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default: {
|
||||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
pUdfInfo = isValidUdf(pQueryInfo->pUdfInfo, pItem->pNode->Expr.operand.z, pItem->pNode->Expr.operand.n);
|
||||||
|
if (pUdfInfo == NULL) {
|
||||||
|
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg9);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tSqlExprItem* pParamElem = taosArrayGet(pItem->pNode->Expr.paramList, 0);;
|
||||||
|
if (pParamElem->pNode->tokenId != TK_ID) {
|
||||||
|
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2);
|
||||||
|
}
|
||||||
|
|
||||||
|
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
|
||||||
|
if (getColumnIndexByName(&pParamElem->pNode->columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) {
|
||||||
|
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
|
||||||
|
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6);
|
||||||
|
}
|
||||||
|
|
||||||
|
pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
|
||||||
|
|
||||||
|
// functions can not be applied to tags
|
||||||
|
if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) {
|
||||||
|
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t inter = 0;
|
||||||
|
int16_t resType = 0;
|
||||||
|
int16_t bytes = 0;
|
||||||
|
getResultDataInfo(TSDB_DATA_TYPE_INT, 4, functionId, 0, &resType, &bytes, &inter, 0, false, pUdfInfo);
|
||||||
|
|
||||||
|
SExprInfo* pExpr = tscExprAppend(pQueryInfo, functionId, &index, resType, bytes, getNewResColId(pCmd), inter, false);
|
||||||
|
|
||||||
|
memset(pExpr->base.aliasName, 0, tListLen(pExpr->base.aliasName));
|
||||||
|
getColumnName(pItem, pExpr->base.aliasName, pExpr->base.token, sizeof(pExpr->base.aliasName) - 1);
|
||||||
|
|
||||||
|
SSchema s = {0};
|
||||||
|
s.type = (uint8_t)resType;
|
||||||
|
s.bytes = bytes;
|
||||||
|
s.colId = pExpr->base.colInfo.colId;
|
||||||
|
|
||||||
|
uint64_t uid = pTableMetaInfo->pTableMeta->id.uid;
|
||||||
|
SColumnList ids = createColumnList(1, index.tableIndex, index.columnIndex);
|
||||||
|
if (finalResult) {
|
||||||
|
insertResultField(pQueryInfo, colIndex, &ids, pUdfInfo->resBytes, pUdfInfo->resType, pExpr->base.aliasName, pExpr);
|
||||||
|
} else {
|
||||||
|
for (int32_t i = 0; i < ids.num; ++i) {
|
||||||
|
tscColumnListInsert(pQueryInfo->colList, index.columnIndex, uid, &s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tscInsertPrimaryTsSourceColumn(pQueryInfo, pTableMetaInfo->pTableMeta->id.uid);
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo refactor
|
// todo refactor
|
||||||
|
|
@ -3074,7 +3365,7 @@ int32_t tscTansformFuncForSTableQuery(SQueryInfo* pQueryInfo) {
|
||||||
(functionId >= TSDB_FUNC_FIRST_DST && functionId <= TSDB_FUNC_STDDEV_DST) ||
|
(functionId >= TSDB_FUNC_FIRST_DST && functionId <= TSDB_FUNC_STDDEV_DST) ||
|
||||||
(functionId >= TSDB_FUNC_RATE && functionId <= TSDB_FUNC_IRATE)) {
|
(functionId >= TSDB_FUNC_RATE && functionId <= TSDB_FUNC_IRATE)) {
|
||||||
if (getResultDataInfo(pSrcSchema->type, pSrcSchema->bytes, functionId, (int32_t)pExpr->base.param[0].i64, &type, &bytes,
|
if (getResultDataInfo(pSrcSchema->type, pSrcSchema->bytes, functionId, (int32_t)pExpr->base.param[0].i64, &type, &bytes,
|
||||||
&interBytes, 0, true) != TSDB_CODE_SUCCESS) {
|
&interBytes, 0, true, NULL) != TSDB_CODE_SUCCESS) {
|
||||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3105,6 +3396,10 @@ void tscRestoreFuncForSTableQuery(SQueryInfo* pQueryInfo) {
|
||||||
int32_t inter = 0;
|
int32_t inter = 0;
|
||||||
|
|
||||||
int32_t functionId = pExpr->base.functionId;
|
int32_t functionId = pExpr->base.functionId;
|
||||||
|
if (functionId < 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (functionId >= TSDB_FUNC_TS && functionId <= TSDB_FUNC_DIFF) {
|
if (functionId >= TSDB_FUNC_TS && functionId <= TSDB_FUNC_DIFF) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -3117,8 +3412,8 @@ void tscRestoreFuncForSTableQuery(SQueryInfo* pQueryInfo) {
|
||||||
functionId = TSDB_FUNC_STDDEV;
|
functionId = TSDB_FUNC_STDDEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
getResultDataInfo(pSchema->type, pSchema->bytes, functionId, 0, &pExpr->base.resType, &pExpr->base.resBytes,
|
getResultDataInfo(pSchema->type, pSchema->bytes, functionId, 0, &pExpr->base.resType, &pExpr->base.resBytes, &inter,
|
||||||
&inter, 0, false);
|
0, false, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3131,6 +3426,10 @@ bool hasUnsupportFunctionsForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo)
|
||||||
size_t size = tscNumOfExprs(pQueryInfo);
|
size_t size = tscNumOfExprs(pQueryInfo);
|
||||||
for (int32_t i = 0; i < size; ++i) {
|
for (int32_t i = 0; i < size; ++i) {
|
||||||
int32_t functionId = tscExprGet(pQueryInfo, i)->base.functionId;
|
int32_t functionId = tscExprGet(pQueryInfo, i)->base.functionId;
|
||||||
|
if (functionId < 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if ((aAggs[functionId].status & TSDB_FUNCSTATE_STABLE) == 0) {
|
if ((aAggs[functionId].status & TSDB_FUNCSTATE_STABLE) == 0) {
|
||||||
invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3);
|
invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3);
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -3175,40 +3474,48 @@ static bool groupbyTagsOrNull(SQueryInfo* pQueryInfo) {
|
||||||
|
|
||||||
static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery, bool twQuery) {
|
static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery, bool twQuery) {
|
||||||
int32_t startIdx = 0;
|
int32_t startIdx = 0;
|
||||||
|
int32_t aggUdf = 0;
|
||||||
|
int32_t scalarUdf = 0;
|
||||||
|
int32_t prjNum = 0;
|
||||||
|
int32_t aggNum = 0;
|
||||||
|
|
||||||
size_t numOfExpr = tscNumOfExprs(pQueryInfo);
|
size_t numOfExpr = tscNumOfExprs(pQueryInfo);
|
||||||
assert(numOfExpr > 0);
|
assert(numOfExpr > 0);
|
||||||
|
|
||||||
SExprInfo* pExpr = tscExprGet(pQueryInfo, startIdx);
|
int32_t factor = INT32_MAX;
|
||||||
|
|
||||||
// ts function can be simultaneously used with any other functions.
|
|
||||||
int32_t functionID = pExpr->base.functionId;
|
|
||||||
if (functionID == TSDB_FUNC_TS || functionID == TSDB_FUNC_TS_DUMMY) {
|
|
||||||
startIdx++;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t factor = functionCompatList[tscExprGet(pQueryInfo, startIdx)->base.functionId];
|
|
||||||
|
|
||||||
if (tscExprGet(pQueryInfo, 0)->base.functionId == TSDB_FUNC_LAST_ROW && (joinQuery || twQuery || !groupbyTagsOrNull(pQueryInfo))) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// diff function cannot be executed with other function
|
// diff function cannot be executed with other function
|
||||||
// arithmetic function can be executed with other arithmetic functions
|
// arithmetic function can be executed with other arithmetic functions
|
||||||
size_t size = tscNumOfExprs(pQueryInfo);
|
size_t size = tscNumOfExprs(pQueryInfo);
|
||||||
|
|
||||||
for (int32_t i = startIdx + 1; i < size; ++i) {
|
for (int32_t i = startIdx; i < size; ++i) {
|
||||||
SExprInfo* pExpr1 = tscExprGet(pQueryInfo, i);
|
SExprInfo* pExpr1 = tscExprGet(pQueryInfo, i);
|
||||||
|
|
||||||
int16_t functionId = pExpr1->base.functionId;
|
int16_t functionId = pExpr1->base.functionId;
|
||||||
if (functionId == TSDB_FUNC_TAGPRJ || functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_TS) {
|
if (functionId < 0) {
|
||||||
|
SUdfInfo* pUdfInfo = taosArrayGet(pQueryInfo->pUdfInfo, -1 * functionId - 1);
|
||||||
|
pUdfInfo->funcType == TSDB_UDF_TYPE_AGGREGATE ? ++aggUdf : ++scalarUdf;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (functionId == TSDB_FUNC_TAGPRJ || functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_TS || functionId == TSDB_FUNC_TS_DUMMY) {
|
||||||
|
++prjNum;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (functionId == TSDB_FUNC_PRJ) {
|
||||||
|
++prjNum;
|
||||||
|
}
|
||||||
|
|
||||||
if (functionId == TSDB_FUNC_PRJ && (pExpr1->base.colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX || TSDB_COL_IS_UD_COL(pExpr1->base.colInfo.flag))) {
|
if (functionId == TSDB_FUNC_PRJ && (pExpr1->base.colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX || TSDB_COL_IS_UD_COL(pExpr1->base.colInfo.flag))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (factor == INT32_MAX) {
|
||||||
|
factor = functionCompatList[functionId];
|
||||||
|
} else {
|
||||||
if (functionCompatList[functionId] != factor) {
|
if (functionCompatList[functionId] != factor) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -3216,12 +3523,25 @@ static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery, bool
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (functionId == TSDB_FUNC_LAST_ROW && (joinQuery || twQuery || !groupbyTagsOrNull(pQueryInfo))) {
|
if (functionId == TSDB_FUNC_LAST_ROW && (joinQuery || twQuery || !groupbyTagsOrNull(pQueryInfo))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
aggNum = (int32_t)size - prjNum - aggUdf - scalarUdf;
|
||||||
|
|
||||||
|
assert(aggNum >= 0);
|
||||||
|
|
||||||
|
if (aggUdf > 0 && (prjNum > 0 || aggNum > 0 || scalarUdf > 0)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scalarUdf > 0 && aggNum > 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3830,7 +4150,7 @@ static int32_t validateSQLExpr(SSqlCmd* pCmd, tSqlExpr* pExpr, SQueryInfo* pQuer
|
||||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addExprAndResultField(pCmd, pQueryInfo, outputIndex, &item, false) != TSDB_CODE_SUCCESS) {
|
if (addExprAndResultField(pCmd, pQueryInfo, outputIndex, &item, false, NULL) != TSDB_CODE_SUCCESS) {
|
||||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -5771,6 +6091,16 @@ int32_t validateFunctionsInIntervalOrGroupbyQuery(SSqlCmd* pCmd, SQueryInfo* pQu
|
||||||
for (int32_t k = 0; k < size; ++k) {
|
for (int32_t k = 0; k < size; ++k) {
|
||||||
SExprInfo* pExpr = tscExprGet(pQueryInfo, k);
|
SExprInfo* pExpr = tscExprGet(pQueryInfo, k);
|
||||||
|
|
||||||
|
if (pExpr->base.functionId < 0) {
|
||||||
|
SUdfInfo* pUdfInfo = taosArrayGet(pQueryInfo->pUdfInfo, -1 * pExpr->base.functionId - 1);
|
||||||
|
if (pUdfInfo->funcType == TSDB_UDF_TYPE_SCALAR) {
|
||||||
|
isProjectionFunction = true;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// projection query on primary timestamp, the selectivity function needs to be present.
|
// projection query on primary timestamp, the selectivity function needs to be present.
|
||||||
if (pExpr->base.functionId == TSDB_FUNC_PRJ && pExpr->base.colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) {
|
if (pExpr->base.functionId == TSDB_FUNC_PRJ && pExpr->base.colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) {
|
||||||
bool hasSelectivity = false;
|
bool hasSelectivity = false;
|
||||||
|
|
@ -5790,6 +6120,7 @@ int32_t validateFunctionsInIntervalOrGroupbyQuery(SSqlCmd* pCmd, SQueryInfo* pQu
|
||||||
int32_t f = pExpr->base.functionId;
|
int32_t f = pExpr->base.functionId;
|
||||||
if ((f == TSDB_FUNC_PRJ && pExpr->base.numOfParams == 0) || f == TSDB_FUNC_DIFF || f == TSDB_FUNC_ARITHM || f == TSDB_FUNC_DERIVATIVE) {
|
if ((f == TSDB_FUNC_PRJ && pExpr->base.numOfParams == 0) || f == TSDB_FUNC_DIFF || f == TSDB_FUNC_ARITHM || f == TSDB_FUNC_DERIVATIVE) {
|
||||||
isProjectionFunction = true;
|
isProjectionFunction = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -6275,11 +6606,15 @@ static void doUpdateSqlFunctionForTagPrj(SQueryInfo* pQueryInfo) {
|
||||||
|
|
||||||
for (int32_t i = 0; i < size; ++i) {
|
for (int32_t i = 0; i < size; ++i) {
|
||||||
SExprInfo* pExpr = tscExprGet(pQueryInfo, i);
|
SExprInfo* pExpr = tscExprGet(pQueryInfo, i);
|
||||||
|
if (pExpr->base.functionId < 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if ((pExpr->base.functionId != TSDB_FUNC_TAG_DUMMY && pExpr->base.functionId != TSDB_FUNC_TS_DUMMY) &&
|
if ((pExpr->base.functionId != TSDB_FUNC_TAG_DUMMY && pExpr->base.functionId != TSDB_FUNC_TS_DUMMY) &&
|
||||||
!(pExpr->base.functionId == TSDB_FUNC_PRJ && TSDB_COL_IS_UD_COL(pExpr->base.colInfo.flag))) {
|
!(pExpr->base.functionId == TSDB_FUNC_PRJ && TSDB_COL_IS_UD_COL(pExpr->base.colInfo.flag))) {
|
||||||
SSchema* pColSchema = &pSchema[pExpr->base.colInfo.colIndex];
|
SSchema* pColSchema = &pSchema[pExpr->base.colInfo.colIndex];
|
||||||
getResultDataInfo(pColSchema->type, pColSchema->bytes, pExpr->base.functionId, (int32_t)pExpr->base.param[0].i64, &pExpr->base.resType,
|
getResultDataInfo(pColSchema->type, pColSchema->bytes, pExpr->base.functionId, (int32_t)pExpr->base.param[0].i64, &pExpr->base.resType,
|
||||||
&pExpr->base.resBytes, &pExpr->base.interBytes, tagLength, isSTable);
|
&pExpr->base.resBytes, &pExpr->base.interBytes, tagLength, isSTable, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -6407,6 +6742,14 @@ static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo, char* msg) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (functionId < 0) {
|
||||||
|
SUdfInfo* pUdfInfo = taosArrayGet(pQueryInfo->pUdfInfo, -1 * functionId - 1);
|
||||||
|
if (pUdfInfo->funcType == TSDB_UDF_TYPE_AGGREGATE) {
|
||||||
|
++numOfAggregation;
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if ((aAggs[functionId].status & TSDB_FUNCSTATE_SELECTIVITY) != 0) {
|
if ((aAggs[functionId].status & TSDB_FUNCSTATE_SELECTIVITY) != 0) {
|
||||||
numOfSelectivity++;
|
numOfSelectivity++;
|
||||||
|
|
@ -6634,6 +6977,10 @@ int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, char*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (f < 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if ((!pQueryInfo->stateWindow) && (f == TSDB_FUNC_DIFF || f == TSDB_FUNC_DERIVATIVE || f == TSDB_FUNC_TWA || f == TSDB_FUNC_IRATE)) {
|
if ((!pQueryInfo->stateWindow) && (f == TSDB_FUNC_DIFF || f == TSDB_FUNC_DERIVATIVE || f == TSDB_FUNC_TWA || f == TSDB_FUNC_IRATE)) {
|
||||||
for (int32_t j = 0; j < pQueryInfo->groupbyExpr.numOfGroupCols; ++j) {
|
for (int32_t j = 0; j < pQueryInfo->groupbyExpr.numOfGroupCols; ++j) {
|
||||||
SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, j);
|
SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, j);
|
||||||
|
|
@ -6647,8 +6994,8 @@ int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, char*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_MULTIOUTPUT(aAggs[f].status) && f != TSDB_FUNC_TOP && f != TSDB_FUNC_BOTTOM &&
|
if (IS_MULTIOUTPUT(aAggs[f].status) && f != TSDB_FUNC_TOP && f != TSDB_FUNC_BOTTOM && f != TSDB_FUNC_DIFF &&
|
||||||
f != TSDB_FUNC_DIFF && f != TSDB_FUNC_DERIVATIVE && f != TSDB_FUNC_TAGPRJ && f != TSDB_FUNC_PRJ) {
|
f != TSDB_FUNC_DERIVATIVE && f != TSDB_FUNC_TAGPRJ && f != TSDB_FUNC_PRJ) {
|
||||||
return invalidOperationMsg(msg, msg1);
|
return invalidOperationMsg(msg, msg1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -6675,6 +7022,7 @@ int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, char*
|
||||||
return checkUpdateTagPrjFunctions(pQueryInfo, msg);
|
return checkUpdateTagPrjFunctions(pQueryInfo, msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t doLocalQueryProcess(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode) {
|
int32_t doLocalQueryProcess(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode) {
|
||||||
const char* msg1 = "only one expression allowed";
|
const char* msg1 = "only one expression allowed";
|
||||||
const char* msg2 = "invalid expression in select clause";
|
const char* msg2 = "invalid expression in select clause";
|
||||||
|
|
@ -6853,9 +7201,17 @@ void tscPrintSelNodeList(SSqlObj* pSql, int32_t subClauseIndex) {
|
||||||
|
|
||||||
char tmpBuf[1024] = {0};
|
char tmpBuf[1024] = {0};
|
||||||
int32_t tmpLen = 0;
|
int32_t tmpLen = 0;
|
||||||
|
char *name = NULL;
|
||||||
|
|
||||||
|
if (pExpr->base.functionId < 0) {
|
||||||
|
SUdfInfo* pUdfInfo = taosArrayGet(pQueryInfo->pUdfInfo, -1 * pExpr->base.functionId - 1);
|
||||||
|
name = pUdfInfo->name;
|
||||||
|
} else {
|
||||||
|
name = aAggs[pExpr->base.functionId].name;
|
||||||
|
}
|
||||||
|
|
||||||
tmpLen =
|
tmpLen =
|
||||||
sprintf(tmpBuf, "%s(uid:%" PRIu64 ", %d)", aAggs[pExpr->base.functionId].name, pExpr->base.uid,
|
sprintf(tmpBuf, "%s(uid:%" PRId64 ", %d)", name, pExpr->base.uid, pExpr->base.colInfo.colId);
|
||||||
pExpr->base.colInfo.colId);
|
|
||||||
|
|
||||||
if (tmpLen + offset >= totalBufSize - 1) break;
|
if (tmpLen + offset >= totalBufSize - 1) break;
|
||||||
|
|
||||||
|
|
@ -7384,7 +7740,7 @@ int32_t tscGetExprFilters(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pSelect
|
||||||
int32_t outputIndex = (int32_t)tscNumOfExprs(pQueryInfo);
|
int32_t outputIndex = (int32_t)tscNumOfExprs(pQueryInfo);
|
||||||
|
|
||||||
// ADD TRUE FOR TEST
|
// ADD TRUE FOR TEST
|
||||||
if (addExprAndResultField(pCmd, pQueryInfo, outputIndex, &item, true) != TSDB_CODE_SUCCESS) {
|
if (addExprAndResultField(pCmd, pQueryInfo, outputIndex, &item, true, NULL) != TSDB_CODE_SUCCESS) {
|
||||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -7674,6 +8030,7 @@ int32_t loadAllTableMeta(SSqlObj* pSql, struct SSqlInfo* pInfo) {
|
||||||
SArray* pVgroupList = NULL;
|
SArray* pVgroupList = NULL;
|
||||||
SArray* plist = NULL;
|
SArray* plist = NULL;
|
||||||
STableMeta* pTableMeta = NULL;
|
STableMeta* pTableMeta = NULL;
|
||||||
|
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd);
|
||||||
|
|
||||||
pCmd->pTableMetaMap = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK);
|
pCmd->pTableMetaMap = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK);
|
||||||
|
|
||||||
|
|
@ -7702,8 +8059,12 @@ int32_t loadAllTableMeta(SSqlObj* pSql, struct SSqlInfo* pInfo) {
|
||||||
uint32_t maxSize = tscGetTableMetaMaxSize();
|
uint32_t maxSize = tscGetTableMetaMaxSize();
|
||||||
char name[TSDB_TABLE_FNAME_LEN] = {0};
|
char name[TSDB_TABLE_FNAME_LEN] = {0};
|
||||||
|
|
||||||
char buf[80 * 1024] = {0};
|
assert(maxSize < 80 * TSDB_MAX_COLUMNS);
|
||||||
assert(maxSize < 80 * 1024);
|
if (!pSql->pBuf) {
|
||||||
|
if (NULL == (pSql->pBuf = tcalloc(1, 80 * TSDB_MAX_COLUMNS))) {
|
||||||
|
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
pTableMeta = calloc(1, maxSize);
|
pTableMeta = calloc(1, maxSize);
|
||||||
|
|
||||||
plist = taosArrayInit(4, POINTER_BYTES);
|
plist = taosArrayInit(4, POINTER_BYTES);
|
||||||
|
|
@ -7720,7 +8081,7 @@ int32_t loadAllTableMeta(SSqlObj* pSql, struct SSqlInfo* pInfo) {
|
||||||
|
|
||||||
if (pTableMeta->id.uid > 0) {
|
if (pTableMeta->id.uid > 0) {
|
||||||
if (pTableMeta->tableType == TSDB_CHILD_TABLE) {
|
if (pTableMeta->tableType == TSDB_CHILD_TABLE) {
|
||||||
code = tscCreateTableMetaFromSTableMeta(pTableMeta, name, buf);
|
code = tscCreateTableMetaFromSTableMeta(pTableMeta, name, pSql->pBuf);
|
||||||
|
|
||||||
// create the child table meta from super table failed, try load it from mnode
|
// create the child table meta from super table failed, try load it from mnode
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
|
@ -7753,9 +8114,41 @@ int32_t loadAllTableMeta(SSqlObj* pSql, struct SSqlInfo* pInfo) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t funcSize = 0;
|
||||||
|
if (pInfo->funcs) {
|
||||||
|
funcSize = taosArrayGetSize(pInfo->funcs);
|
||||||
|
}
|
||||||
|
if (funcSize > 0) {
|
||||||
|
for (size_t i = 0; i < funcSize; ++i) {
|
||||||
|
SStrToken* t = taosArrayGet(pInfo->funcs, i);
|
||||||
|
if (NULL == t) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t->n >= TSDB_FUNC_NAME_LEN) {
|
||||||
|
code = tscSQLSyntaxErrMsg(tscGetErrorMsgPayload(pCmd), "too long function name", t->z);
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
goto _end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t functionId = isValidFunction(t->z, t->n);
|
||||||
|
if (functionId < 0) {
|
||||||
|
struct SUdfInfo info = {0};
|
||||||
|
info.name = strndup(t->z, t->n);
|
||||||
|
if (pQueryInfo->pUdfInfo == NULL) {
|
||||||
|
pQueryInfo->pUdfInfo = taosArrayInit(4, sizeof(struct SUdfInfo));
|
||||||
|
}
|
||||||
|
|
||||||
|
info.functionId = (int32_t)taosArrayGetSize(pQueryInfo->pUdfInfo) * (-1) - 1;;
|
||||||
|
taosArrayPush(pQueryInfo->pUdfInfo, &info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// load the table meta for a given table name list
|
// load the table meta for a given table name list
|
||||||
if (taosArrayGetSize(plist) > 0 || taosArrayGetSize(pVgroupList) > 0) {
|
if (taosArrayGetSize(plist) > 0 || taosArrayGetSize(pVgroupList) > 0 || (pQueryInfo->pUdfInfo && taosArrayGetSize(pQueryInfo->pUdfInfo) > 0)) {
|
||||||
code = getMultiTableMetaFromMnode(pSql, plist, pVgroupList, tscTableMetaCallBack);
|
code = getMultiTableMetaFromMnode(pSql, plist, pVgroupList, pQueryInfo->pUdfInfo, tscTableMetaCallBack, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
_end:
|
_end:
|
||||||
|
|
@ -7884,12 +8277,21 @@ static int32_t doValidateSubquery(SSqlNode* pSqlNode, int32_t index, SSqlObj* pS
|
||||||
|
|
||||||
// union all is not support currently
|
// union all is not support currently
|
||||||
SSqlNode* p = taosArrayGetP(subInfo->pSubquery, 0);
|
SSqlNode* p = taosArrayGetP(subInfo->pSubquery, 0);
|
||||||
|
if (taosArrayGetSize(subInfo->pSubquery) >= 2) {
|
||||||
|
return invalidOperationMsg(msgBuf, "not support union in subquery");
|
||||||
|
}
|
||||||
SQueryInfo* pSub = calloc(1, sizeof(SQueryInfo));
|
SQueryInfo* pSub = calloc(1, sizeof(SQueryInfo));
|
||||||
tscInitQueryInfo(pSub);
|
tscInitQueryInfo(pSub);
|
||||||
|
|
||||||
|
SArray *pUdfInfo = NULL;
|
||||||
|
if (pQueryInfo->pUdfInfo) {
|
||||||
|
pUdfInfo = taosArrayDup(pQueryInfo->pUdfInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
pSub->pUdfInfo = pUdfInfo;
|
||||||
|
pSub->udfCopy = true;
|
||||||
|
|
||||||
int32_t code = validateSqlNode(pSql, p, pSub);
|
int32_t code = validateSqlNode(pSql, p, pSub);
|
||||||
assert(code != TSDB_CODE_TSC_ACTION_IN_PROGRESS);
|
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
@ -8231,6 +8633,7 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf
|
||||||
pQueryInfo->simpleAgg = isSimpleAggregateRv(pQueryInfo);
|
pQueryInfo->simpleAgg = isSimpleAggregateRv(pQueryInfo);
|
||||||
pQueryInfo->onlyTagQuery = onlyTagPrjFunction(pQueryInfo);
|
pQueryInfo->onlyTagQuery = onlyTagPrjFunction(pQueryInfo);
|
||||||
pQueryInfo->groupbyColumn = tscGroupbyColumn(pQueryInfo);
|
pQueryInfo->groupbyColumn = tscGroupbyColumn(pQueryInfo);
|
||||||
|
//pQueryInfo->globalMerge = tscIsTwoStageSTableQuery(pQueryInfo, 0);
|
||||||
|
|
||||||
pQueryInfo->arithmeticOnAgg = tsIsArithmeticQueryOnAggResult(pQueryInfo);
|
pQueryInfo->arithmeticOnAgg = tsIsArithmeticQueryOnAggResult(pQueryInfo);
|
||||||
pQueryInfo->orderProjectQuery = tscOrderedProjectionQueryOnSTable(pQueryInfo, 0);
|
pQueryInfo->orderProjectQuery = tscOrderedProjectionQueryOnSTable(pQueryInfo, 0);
|
||||||
|
|
@ -8460,9 +8863,7 @@ void normalizeSqlNode(SSqlNode* pSqlNode, const char* dbName) {
|
||||||
// 2. pSqlNode->pWhere
|
// 2. pSqlNode->pWhere
|
||||||
// 3. pSqlNode->pHaving
|
// 3. pSqlNode->pHaving
|
||||||
// 4. pSqlNode->pSortOrder
|
// 4. pSqlNode->pSortOrder
|
||||||
|
|
||||||
// pSqlNode->from
|
// pSqlNode->from
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -503,6 +503,7 @@ int doBuildAndSendMsg(SSqlObj *pSql) {
|
||||||
pCmd->command == TSDB_SQL_INSERT ||
|
pCmd->command == TSDB_SQL_INSERT ||
|
||||||
pCmd->command == TSDB_SQL_CONNECT ||
|
pCmd->command == TSDB_SQL_CONNECT ||
|
||||||
pCmd->command == TSDB_SQL_HB ||
|
pCmd->command == TSDB_SQL_HB ||
|
||||||
|
pCmd->command == TSDB_SQL_RETRIEVE_FUNC ||
|
||||||
pCmd->command == TSDB_SQL_STABLEVGROUP) {
|
pCmd->command == TSDB_SQL_STABLEVGROUP) {
|
||||||
pRes->code = tscBuildMsg[pCmd->command](pSql, NULL);
|
pRes->code = tscBuildMsg[pCmd->command](pSql, NULL);
|
||||||
}
|
}
|
||||||
|
|
@ -545,7 +546,7 @@ int tscBuildAndSendRequest(SSqlObj *pSql, SQueryInfo* pQueryInfo) {
|
||||||
type = pQueryInfo->type;
|
type = pQueryInfo->type;
|
||||||
|
|
||||||
// while numOfTables equals to 0, it must be Heartbeat
|
// while numOfTables equals to 0, it must be Heartbeat
|
||||||
assert((pQueryInfo->numOfTables == 0 && pQueryInfo->command == TSDB_SQL_HB) || pQueryInfo->numOfTables > 0);
|
assert((pQueryInfo->numOfTables == 0 && (pQueryInfo->command == TSDB_SQL_HB || pSql->cmd.command == TSDB_SQL_RETRIEVE_FUNC)) || pQueryInfo->numOfTables > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
tscDebug("0x%"PRIx64" SQL cmd:%s will be processed, name:%s, type:%d", pSql->self, sqlCmd[pCmd->command], name, type);
|
tscDebug("0x%"PRIx64" SQL cmd:%s will be processed, name:%s, type:%d", pSql->self, sqlCmd[pCmd->command], name, type);
|
||||||
|
|
@ -1032,6 +1033,34 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
pMsg += sizeof(int32_t);
|
pMsg += sizeof(int32_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// support only one udf
|
||||||
|
if (pQueryInfo->pUdfInfo != NULL && taosArrayGetSize(pQueryInfo->pUdfInfo) > 0) {
|
||||||
|
pQueryMsg->udfContentOffset = htonl((int32_t) (pMsg - pCmd->payload));
|
||||||
|
for(int32_t i = 0; i < taosArrayGetSize(pQueryInfo->pUdfInfo); ++i) {
|
||||||
|
SUdfInfo* pUdfInfo = taosArrayGet(pQueryInfo->pUdfInfo, i);
|
||||||
|
*(int8_t*) pMsg = pUdfInfo->resType;
|
||||||
|
pMsg += sizeof(pUdfInfo->resType);
|
||||||
|
|
||||||
|
*(int16_t*) pMsg = htons(pUdfInfo->resBytes);
|
||||||
|
pMsg += sizeof(pUdfInfo->resBytes);
|
||||||
|
|
||||||
|
STR_TO_VARSTR(pMsg, pUdfInfo->name);
|
||||||
|
|
||||||
|
pMsg += varDataTLen(pMsg);
|
||||||
|
|
||||||
|
*(int32_t*) pMsg = htonl(pUdfInfo->funcType);
|
||||||
|
pMsg += sizeof(pUdfInfo->funcType);
|
||||||
|
|
||||||
|
*(int32_t*) pMsg = htonl(pUdfInfo->bufSize);
|
||||||
|
pMsg += sizeof(pUdfInfo->bufSize);
|
||||||
|
|
||||||
|
pQueryMsg->udfContentLen = htonl(pUdfInfo->contLen);
|
||||||
|
memcpy(pMsg, pUdfInfo->content, pUdfInfo->contLen);
|
||||||
|
|
||||||
|
pMsg += pUdfInfo->contLen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(pMsg, pSql->sqlstr, sqlLen);
|
memcpy(pMsg, pSql->sqlstr, sqlLen);
|
||||||
pMsg += sqlLen;
|
pMsg += sqlLen;
|
||||||
|
|
||||||
|
|
@ -1067,6 +1096,18 @@ int32_t tscBuildCreateDbMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t tscBuildCreateFuncMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
|
SSqlCmd *pCmd = &pSql->cmd;
|
||||||
|
SCreateFuncMsg *pCreateFuncMsg = (SCreateFuncMsg *)pCmd->payload;
|
||||||
|
|
||||||
|
pCmd->msgType = TSDB_MSG_TYPE_CM_CREATE_FUNCTION;
|
||||||
|
|
||||||
|
pCmd->payloadLen = sizeof(SCreateFuncMsg) + htonl(pCreateFuncMsg->codeLen);
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int32_t tscBuildCreateDnodeMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
int32_t tscBuildCreateDnodeMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
SSqlCmd *pCmd = &pSql->cmd;
|
SSqlCmd *pCmd = &pSql->cmd;
|
||||||
pCmd->payloadLen = sizeof(SCreateDnodeMsg);
|
pCmd->payloadLen = sizeof(SCreateDnodeMsg);
|
||||||
|
|
@ -1191,6 +1232,17 @@ int32_t tscBuildDropDbMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t tscBuildDropFuncMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
|
SSqlCmd *pCmd = &pSql->cmd;
|
||||||
|
|
||||||
|
pCmd->msgType = TSDB_MSG_TYPE_CM_DROP_FUNCTION;
|
||||||
|
|
||||||
|
pCmd->payloadLen = sizeof(SDropFuncMsg);
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int32_t tscBuildDropTableMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
int32_t tscBuildDropTableMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
SSqlCmd *pCmd = &pSql->cmd;
|
SSqlCmd *pCmd = &pSql->cmd;
|
||||||
pCmd->payloadLen = sizeof(SCMDropTableMsg);
|
pCmd->payloadLen = sizeof(SCMDropTableMsg);
|
||||||
|
|
@ -1294,9 +1346,17 @@ int32_t tscBuildShowMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SShowInfo *pShowInfo = &pInfo->pMiscInfo->showOpt;
|
||||||
SShowMsg *pShowMsg = (SShowMsg *)pCmd->payload;
|
SShowMsg *pShowMsg = (SShowMsg *)pCmd->payload;
|
||||||
|
|
||||||
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0);
|
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0);
|
||||||
|
if (pShowInfo->showType == TSDB_MGMT_TABLE_FUNCTION) {
|
||||||
|
pShowMsg->type = pShowInfo->showType;
|
||||||
|
pShowMsg->payloadLen = 0;
|
||||||
|
pCmd->payloadLen = sizeof(SShowMsg);
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
if (tNameIsEmpty(&pTableMetaInfo->name)) {
|
if (tNameIsEmpty(&pTableMetaInfo->name)) {
|
||||||
pthread_mutex_lock(&pObj->mutex);
|
pthread_mutex_lock(&pObj->mutex);
|
||||||
|
|
@ -1306,7 +1366,6 @@ int32_t tscBuildShowMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
tNameGetFullDbName(&pTableMetaInfo->name, pShowMsg->db);
|
tNameGetFullDbName(&pTableMetaInfo->name, pShowMsg->db);
|
||||||
}
|
}
|
||||||
|
|
||||||
SShowInfo *pShowInfo = &pInfo->pMiscInfo->showOpt;
|
|
||||||
pShowMsg->type = pShowInfo->showType;
|
pShowMsg->type = pShowInfo->showType;
|
||||||
|
|
||||||
if (pShowInfo->showType != TSDB_MGMT_TABLE_VNODES) {
|
if (pShowInfo->showType != TSDB_MGMT_TABLE_VNODES) {
|
||||||
|
|
@ -1819,6 +1878,29 @@ int tscBuildSTableVgroupMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int tscBuildRetrieveFuncMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
|
SSqlCmd *pCmd = &pSql->cmd;
|
||||||
|
|
||||||
|
char *pMsg = pCmd->payload;
|
||||||
|
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd);
|
||||||
|
int32_t numOfFuncs = (int32_t)taosArrayGetSize(pQueryInfo->pUdfInfo);
|
||||||
|
|
||||||
|
SRetrieveFuncMsg *pRetrieveFuncMsg = (SRetrieveFuncMsg *)pMsg;
|
||||||
|
pRetrieveFuncMsg->num = htonl(numOfFuncs);
|
||||||
|
|
||||||
|
pMsg += sizeof(SRetrieveFuncMsg);
|
||||||
|
for(int32_t i = 0; i < numOfFuncs; ++i) {
|
||||||
|
SUdfInfo* pUdf = taosArrayGet(pQueryInfo->pUdfInfo, i);
|
||||||
|
STR_TO_NET_VARSTR(pMsg, pUdf->name);
|
||||||
|
pMsg += varDataNetTLen(pMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
pCmd->msgType = TSDB_MSG_TYPE_CM_RETRIEVE_FUNC;
|
||||||
|
pCmd->payloadLen = (int32_t)(pMsg - pCmd->payload);
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
int tscBuildHeartBeatMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
int tscBuildHeartBeatMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
SSqlCmd *pCmd = &pSql->cmd;
|
SSqlCmd *pCmd = &pSql->cmd;
|
||||||
STscObj *pObj = pSql->pTscObj;
|
STscObj *pObj = pSql->pTscObj;
|
||||||
|
|
@ -1873,7 +1955,6 @@ static int32_t tableMetaMsgConvert(STableMetaMsg* pMetaMsg) {
|
||||||
pMetaMsg->vgroup.vgId = htonl(pMetaMsg->vgroup.vgId);
|
pMetaMsg->vgroup.vgId = htonl(pMetaMsg->vgroup.vgId);
|
||||||
|
|
||||||
pMetaMsg->uid = htobe64(pMetaMsg->uid);
|
pMetaMsg->uid = htobe64(pMetaMsg->uid);
|
||||||
// pMetaMsg->contLen = htonl(pMetaMsg->contLen);
|
|
||||||
pMetaMsg->numOfColumns = htons(pMetaMsg->numOfColumns);
|
pMetaMsg->numOfColumns = htons(pMetaMsg->numOfColumns);
|
||||||
|
|
||||||
if ((pMetaMsg->tableType != TSDB_SUPER_TABLE) &&
|
if ((pMetaMsg->tableType != TSDB_SUPER_TABLE) &&
|
||||||
|
|
@ -1938,13 +2019,14 @@ static void doAddTableMetaToLocalBuf(STableMeta* pTableMeta, STableMetaMsg* pMet
|
||||||
int32_t len = (int32_t) strnlen(pTableMeta->sTableName, TSDB_TABLE_FNAME_LEN);
|
int32_t len = (int32_t) strnlen(pTableMeta->sTableName, TSDB_TABLE_FNAME_LEN);
|
||||||
|
|
||||||
// The super tableMeta already exists, create it according to tableMeta and add it to hash map
|
// The super tableMeta already exists, create it according to tableMeta and add it to hash map
|
||||||
|
if (updateSTable) {
|
||||||
STableMeta* pSupTableMeta = createSuperTableMeta(pMetaMsg);
|
STableMeta* pSupTableMeta = createSuperTableMeta(pMetaMsg);
|
||||||
|
|
||||||
uint32_t size = tscGetTableMetaSize(pSupTableMeta);
|
uint32_t size = tscGetTableMetaSize(pSupTableMeta);
|
||||||
int32_t code = taosHashPut(tscTableMetaInfo, pTableMeta->sTableName, len, pSupTableMeta, size);
|
int32_t code = taosHashPut(tscTableMetaInfo, pTableMeta->sTableName, len, pSupTableMeta, size);
|
||||||
assert(code == TSDB_CODE_SUCCESS);
|
assert(code == TSDB_CODE_SUCCESS);
|
||||||
|
|
||||||
tfree(pSupTableMeta);
|
tfree(pSupTableMeta);
|
||||||
|
}
|
||||||
|
|
||||||
CChildTableMeta* cMeta = tscCreateChildMeta(pTableMeta);
|
CChildTableMeta* cMeta = tscCreateChildMeta(pTableMeta);
|
||||||
taosHashPut(tscTableMetaInfo, pMetaMsg->tableFname, strlen(pMetaMsg->tableFname), cMeta, sizeof(CChildTableMeta));
|
taosHashPut(tscTableMetaInfo, pMetaMsg->tableFname, strlen(pMetaMsg->tableFname), cMeta, sizeof(CChildTableMeta));
|
||||||
|
|
@ -2034,12 +2116,64 @@ static SVgroupsInfo* createVgroupInfoFromMsg(char* pMsg, int32_t* size, uint64_t
|
||||||
return pVgroupInfo;
|
return pVgroupInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int tscProcessRetrieveFuncRsp(SSqlObj* pSql) {
|
||||||
|
SSqlCmd* pCmd = &pSql->cmd;
|
||||||
|
SUdfFuncMsg* pFuncMsg = (SUdfFuncMsg *)pSql->res.pRsp;
|
||||||
|
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd);
|
||||||
|
|
||||||
|
pFuncMsg->num = htonl(pFuncMsg->num);
|
||||||
|
assert(pFuncMsg->num == taosArrayGetSize(pQueryInfo->pUdfInfo));
|
||||||
|
|
||||||
|
char* pMsg = pFuncMsg->content;
|
||||||
|
for(int32_t i = 0; i < pFuncMsg->num; ++i) {
|
||||||
|
SFunctionInfoMsg* pFunc = (SFunctionInfoMsg*) pMsg;
|
||||||
|
|
||||||
|
for(int32_t j = 0; j < pFuncMsg->num; ++j) {
|
||||||
|
SUdfInfo* pUdfInfo = taosArrayGet(pQueryInfo->pUdfInfo, j);
|
||||||
|
if (strcmp(pUdfInfo->name, pFunc->name) != 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pUdfInfo->content) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
pUdfInfo->resBytes = htons(pFunc->resBytes);
|
||||||
|
pUdfInfo->resType = pFunc->resType;
|
||||||
|
pUdfInfo->funcType = htonl(pFunc->funcType);
|
||||||
|
pUdfInfo->contLen = htonl(pFunc->len);
|
||||||
|
pUdfInfo->bufSize = htonl(pFunc->bufSize);
|
||||||
|
|
||||||
|
pUdfInfo->content = malloc(pUdfInfo->contLen);
|
||||||
|
memcpy(pUdfInfo->content, pFunc->content, pUdfInfo->contLen);
|
||||||
|
|
||||||
|
pMsg += sizeof(SFunctionInfoMsg) + pUdfInfo->contLen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// master sqlObj locates in param
|
||||||
|
SSqlObj* parent = (SSqlObj*)taosAcquireRef(tscObjRef, (int64_t)pSql->param);
|
||||||
|
if(parent == NULL) {
|
||||||
|
return pSql->res.code;
|
||||||
|
}
|
||||||
|
|
||||||
|
SQueryInfo* parQueryInfo = tscGetQueryInfo(&parent->cmd);
|
||||||
|
|
||||||
|
assert(parent->signature == parent && (int64_t)pSql->param == parent->self);
|
||||||
|
taosArrayDestroy(parQueryInfo->pUdfInfo);
|
||||||
|
|
||||||
|
parQueryInfo->pUdfInfo = pQueryInfo->pUdfInfo; // assigned to parent sql obj.
|
||||||
|
pQueryInfo->pUdfInfo = NULL;
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
int tscProcessMultiTableMetaRsp(SSqlObj *pSql) {
|
int tscProcessMultiTableMetaRsp(SSqlObj *pSql) {
|
||||||
char *rsp = pSql->res.pRsp;
|
char *rsp = pSql->res.pRsp;
|
||||||
|
|
||||||
SMultiTableMeta *pMultiMeta = (SMultiTableMeta *)rsp;
|
SMultiTableMeta *pMultiMeta = (SMultiTableMeta *)rsp;
|
||||||
pMultiMeta->numOfTables = htonl(pMultiMeta->numOfTables);
|
pMultiMeta->numOfTables = htonl(pMultiMeta->numOfTables);
|
||||||
pMultiMeta->numOfVgroup = htonl(pMultiMeta->numOfVgroup);
|
pMultiMeta->numOfVgroup = htonl(pMultiMeta->numOfVgroup);
|
||||||
|
pMultiMeta->numOfUdf = htonl(pMultiMeta->numOfUdf);
|
||||||
|
|
||||||
rsp += sizeof(SMultiTableMeta);
|
rsp += sizeof(SMultiTableMeta);
|
||||||
|
|
||||||
|
|
@ -2049,10 +2183,10 @@ int tscProcessMultiTableMetaRsp(SSqlObj *pSql) {
|
||||||
}
|
}
|
||||||
|
|
||||||
SSqlCmd *pParentCmd = &pParentSql->cmd;
|
SSqlCmd *pParentCmd = &pParentSql->cmd;
|
||||||
SHashObj *pSet = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK);
|
SHashObj *pSet = taosHashInit(pMultiMeta->numOfVgroup, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK);
|
||||||
|
|
||||||
char* pMsg = pMultiMeta->meta;
|
|
||||||
char* buf = NULL;
|
char* buf = NULL;
|
||||||
|
char* pMsg = pMultiMeta->meta;
|
||||||
if (pMultiMeta->compressed) {
|
if (pMultiMeta->compressed) {
|
||||||
buf = malloc(pMultiMeta->rawLen - sizeof(SMultiTableMeta));
|
buf = malloc(pMultiMeta->rawLen - sizeof(SMultiTableMeta));
|
||||||
int32_t len = tsDecompressString(pMultiMeta->meta, pMultiMeta->contLen - sizeof(SMultiTableMeta), 1,
|
int32_t len = tsDecompressString(pMultiMeta->meta, pMultiMeta->contLen - sizeof(SMultiTableMeta), 1,
|
||||||
|
|
@ -2073,6 +2207,7 @@ int tscProcessMultiTableMetaRsp(SSqlObj *pSql) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool freeMeta = false;
|
||||||
STableMeta* pTableMeta = tscCreateTableMetaFromMsg(pMetaMsg);
|
STableMeta* pTableMeta = tscCreateTableMetaFromMsg(pMetaMsg);
|
||||||
if (!tIsValidSchema(pTableMeta->schema, pTableMeta->tableInfo.numOfColumns, pTableMeta->tableInfo.numOfTags)) {
|
if (!tIsValidSchema(pTableMeta->schema, pTableMeta->tableInfo.numOfColumns, pTableMeta->tableInfo.numOfTags)) {
|
||||||
tscError("0x%"PRIx64" invalid table meta from mnode, name:%s", pSql->self, pMetaMsg->tableFname);
|
tscError("0x%"PRIx64" invalid table meta from mnode, name:%s", pSql->self, pMetaMsg->tableFname);
|
||||||
|
|
@ -2087,22 +2222,27 @@ int tscProcessMultiTableMetaRsp(SSqlObj *pSql) {
|
||||||
SName sn = {0};
|
SName sn = {0};
|
||||||
tNameFromString(&sn, pMetaMsg->tableFname, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE);
|
tNameFromString(&sn, pMetaMsg->tableFname, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE);
|
||||||
|
|
||||||
|
if (pMultiMeta->metaClone == 1 || pTableMeta->tableType == TSDB_SUPER_TABLE) {
|
||||||
|
STableMetaVgroupInfo p = {.pTableMeta = pTableMeta,};
|
||||||
|
|
||||||
const char* tableName = tNameGetTableName(&sn);
|
const char* tableName = tNameGetTableName(&sn);
|
||||||
size_t keyLen = strlen(tableName);
|
size_t keyLen = strlen(tableName);
|
||||||
|
|
||||||
STableMetaVgroupInfo p = {.pTableMeta = pTableMeta,};
|
|
||||||
taosHashPut(pParentCmd->pTableMetaMap, tableName, keyLen, &p, sizeof(STableMetaVgroupInfo));
|
taosHashPut(pParentCmd->pTableMetaMap, tableName, keyLen, &p, sizeof(STableMetaVgroupInfo));
|
||||||
|
} else {
|
||||||
|
freeMeta = true;
|
||||||
|
}
|
||||||
|
|
||||||
bool addToBuf = false;
|
// for each super table, only update meta information once
|
||||||
if (taosHashGet(pSet, &pMetaMsg->uid, sizeof(pMetaMsg->uid)) == NULL) {
|
bool updateStableMeta = false;
|
||||||
addToBuf = true;
|
if (pTableMeta->tableType == TSDB_CHILD_TABLE && taosHashGet(pSet, &pMetaMsg->suid, sizeof(pMetaMsg->suid)) == NULL) {
|
||||||
taosHashPut(pSet, &pMetaMsg->uid, sizeof(pMetaMsg->uid), "", 0);
|
updateStableMeta = true;
|
||||||
|
taosHashPut(pSet, &pTableMeta->suid, sizeof(pMetaMsg->suid), "", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// create the tableMeta and add it into the TableMeta map
|
// create the tableMeta and add it into the TableMeta map
|
||||||
doAddTableMetaToLocalBuf(pTableMeta, pMetaMsg, addToBuf);
|
doAddTableMetaToLocalBuf(pTableMeta, pMetaMsg, updateStableMeta);
|
||||||
|
|
||||||
// if the vgroup is not updated in current process, update it.
|
// for each vgroup, only update the information once.
|
||||||
int64_t vgId = pMetaMsg->vgroup.vgId;
|
int64_t vgId = pMetaMsg->vgroup.vgId;
|
||||||
if (pTableMeta->tableType != TSDB_SUPER_TABLE && taosHashGet(pSet, &vgId, sizeof(vgId)) == NULL) {
|
if (pTableMeta->tableType != TSDB_SUPER_TABLE && taosHashGet(pSet, &vgId, sizeof(vgId)) == NULL) {
|
||||||
doUpdateVgroupInfo(pTableMeta, &pMetaMsg->vgroup);
|
doUpdateVgroupInfo(pTableMeta, &pMetaMsg->vgroup);
|
||||||
|
|
@ -2110,6 +2250,9 @@ int tscProcessMultiTableMetaRsp(SSqlObj *pSql) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pMsg += pMetaMsg->contLen;
|
pMsg += pMetaMsg->contLen;
|
||||||
|
if (freeMeta) {
|
||||||
|
tfree(pTableMeta);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int32_t i = 0; i < pMultiMeta->numOfVgroup; ++i) {
|
for(int32_t i = 0; i < pMultiMeta->numOfVgroup; ++i) {
|
||||||
|
|
@ -2128,6 +2271,37 @@ int tscProcessMultiTableMetaRsp(SSqlObj *pSql) {
|
||||||
pMsg += size;
|
pMsg += size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SQueryInfo* pQueryInfo = tscGetQueryInfo(pParentCmd);
|
||||||
|
if (pMultiMeta->numOfUdf > 0) {
|
||||||
|
assert(pQueryInfo->pUdfInfo != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int32_t i = 0; i < pMultiMeta->numOfUdf; ++i) {
|
||||||
|
SFunctionInfoMsg* pFunc = (SFunctionInfoMsg*) pMsg;
|
||||||
|
|
||||||
|
for(int32_t j = 0; j < pMultiMeta->numOfUdf; ++j) {
|
||||||
|
SUdfInfo* pUdfInfo = taosArrayGet(pQueryInfo->pUdfInfo, j);
|
||||||
|
if (strcmp(pUdfInfo->name, pFunc->name) != 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pUdfInfo->content) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
pUdfInfo->resBytes = htons(pFunc->resBytes);
|
||||||
|
pUdfInfo->resType = pFunc->resType;
|
||||||
|
pUdfInfo->funcType = htonl(pFunc->funcType);
|
||||||
|
pUdfInfo->contLen = htonl(pFunc->len);
|
||||||
|
pUdfInfo->bufSize = htonl(pFunc->bufSize);
|
||||||
|
|
||||||
|
pUdfInfo->content = malloc(pUdfInfo->contLen);
|
||||||
|
memcpy(pUdfInfo->content, pFunc->content, pUdfInfo->contLen);
|
||||||
|
|
||||||
|
pMsg += sizeof(SFunctionInfoMsg) + pUdfInfo->contLen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pSql->res.code = TSDB_CODE_SUCCESS;
|
pSql->res.code = TSDB_CODE_SUCCESS;
|
||||||
pSql->res.numOfTotal = pMultiMeta->numOfTables;
|
pSql->res.numOfTotal = pMultiMeta->numOfTables;
|
||||||
tscDebug("0x%"PRIx64" load multi-tableMeta from mnode, numOfTables:%d", pSql->self, pMultiMeta->numOfTables);
|
tscDebug("0x%"PRIx64" load multi-tableMeta from mnode, numOfTables:%d", pSql->self, pMultiMeta->numOfTables);
|
||||||
|
|
@ -2518,7 +2692,7 @@ static int32_t getTableMetaFromMnode(SSqlObj *pSql, STableMetaInfo *pTableMetaIn
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t getMultiTableMetaFromMnode(SSqlObj *pSql, SArray* pNameList, SArray* pVgroupNameList, __async_cb_func_t fp) {
|
int32_t getMultiTableMetaFromMnode(SSqlObj *pSql, SArray* pNameList, SArray* pVgroupNameList, SArray* pUdfList, __async_cb_func_t fp, bool metaClone) {
|
||||||
SSqlObj *pNew = calloc(1, sizeof(SSqlObj));
|
SSqlObj *pNew = calloc(1, sizeof(SSqlObj));
|
||||||
if (NULL == pNew) {
|
if (NULL == pNew) {
|
||||||
tscError("0x%"PRIx64" failed to allocate sqlobj to get multiple table meta", pSql->self);
|
tscError("0x%"PRIx64" failed to allocate sqlobj to get multiple table meta", pSql->self);
|
||||||
|
|
@ -2531,8 +2705,9 @@ int32_t getMultiTableMetaFromMnode(SSqlObj *pSql, SArray* pNameList, SArray* pVg
|
||||||
|
|
||||||
int32_t numOfTable = (int32_t) taosArrayGetSize(pNameList);
|
int32_t numOfTable = (int32_t) taosArrayGetSize(pNameList);
|
||||||
int32_t numOfVgroupList = (int32_t) taosArrayGetSize(pVgroupNameList);
|
int32_t numOfVgroupList = (int32_t) taosArrayGetSize(pVgroupNameList);
|
||||||
|
int32_t numOfUdf = pUdfList ? (int32_t)taosArrayGetSize(pUdfList) : 0;
|
||||||
|
|
||||||
int32_t size = (numOfTable + numOfVgroupList) * TSDB_TABLE_FNAME_LEN + sizeof(SMultiTableInfoMsg);
|
int32_t size = (numOfTable + numOfVgroupList) * TSDB_TABLE_FNAME_LEN + TSDB_FUNC_NAME_LEN * numOfUdf + sizeof(SMultiTableInfoMsg);
|
||||||
if (TSDB_CODE_SUCCESS != tscAllocPayload(&pNew->cmd, size)) {
|
if (TSDB_CODE_SUCCESS != tscAllocPayload(&pNew->cmd, size)) {
|
||||||
tscError("0x%"PRIx64" malloc failed for payload to get table meta", pSql->self);
|
tscError("0x%"PRIx64" malloc failed for payload to get table meta", pSql->self);
|
||||||
tscFreeSqlObj(pNew);
|
tscFreeSqlObj(pNew);
|
||||||
|
|
@ -2540,14 +2715,16 @@ int32_t getMultiTableMetaFromMnode(SSqlObj *pSql, SArray* pNameList, SArray* pVg
|
||||||
}
|
}
|
||||||
|
|
||||||
SMultiTableInfoMsg* pInfo = (SMultiTableInfoMsg*) pNew->cmd.payload;
|
SMultiTableInfoMsg* pInfo = (SMultiTableInfoMsg*) pNew->cmd.payload;
|
||||||
|
pInfo->metaClone = metaClone? 1:0;
|
||||||
pInfo->numOfTables = htonl((uint32_t) taosArrayGetSize(pNameList));
|
pInfo->numOfTables = htonl((uint32_t) taosArrayGetSize(pNameList));
|
||||||
pInfo->numOfVgroups = htonl((uint32_t) taosArrayGetSize(pVgroupNameList));
|
pInfo->numOfVgroups = htonl((uint32_t) taosArrayGetSize(pVgroupNameList));
|
||||||
|
pInfo->numOfUdfs = htonl(numOfUdf);
|
||||||
|
|
||||||
char* start = pInfo->tableNames;
|
char* start = pInfo->tableNames;
|
||||||
int32_t len = 0;
|
int32_t len = 0;
|
||||||
for(int32_t i = 0; i < numOfTable; ++i) {
|
for(int32_t i = 0; i < numOfTable; ++i) {
|
||||||
char* name = taosArrayGetP(pNameList, i);
|
char* name = taosArrayGetP(pNameList, i);
|
||||||
if (i < numOfTable - 1 || numOfVgroupList > 0) {
|
if (i < numOfTable - 1 || numOfVgroupList > 0 || numOfUdf > 0) {
|
||||||
len = sprintf(start, "%s,", name);
|
len = sprintf(start, "%s,", name);
|
||||||
} else {
|
} else {
|
||||||
len = sprintf(start, "%s", name);
|
len = sprintf(start, "%s", name);
|
||||||
|
|
@ -2558,7 +2735,7 @@ int32_t getMultiTableMetaFromMnode(SSqlObj *pSql, SArray* pNameList, SArray* pVg
|
||||||
|
|
||||||
for(int32_t i = 0; i < numOfVgroupList; ++i) {
|
for(int32_t i = 0; i < numOfVgroupList; ++i) {
|
||||||
char* name = taosArrayGetP(pVgroupNameList, i);
|
char* name = taosArrayGetP(pVgroupNameList, i);
|
||||||
if (i < numOfVgroupList - 1) {
|
if (i < numOfVgroupList - 1 || numOfUdf > 0) {
|
||||||
len = sprintf(start, "%s,", name);
|
len = sprintf(start, "%s,", name);
|
||||||
} else {
|
} else {
|
||||||
len = sprintf(start, "%s", name);
|
len = sprintf(start, "%s", name);
|
||||||
|
|
@ -2567,12 +2744,23 @@ int32_t getMultiTableMetaFromMnode(SSqlObj *pSql, SArray* pNameList, SArray* pVg
|
||||||
start += len;
|
start += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(int32_t i = 0; i < numOfUdf; ++i) {
|
||||||
|
SUdfInfo * u = taosArrayGet(pUdfList, i);
|
||||||
|
if (i < numOfUdf - 1) {
|
||||||
|
len = sprintf(start, "%s,", u->name);
|
||||||
|
} else {
|
||||||
|
len = sprintf(start, "%s", u->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
start += len;
|
||||||
|
}
|
||||||
|
|
||||||
pNew->cmd.payloadLen = (int32_t) ((start - pInfo->tableNames) + sizeof(SMultiTableInfoMsg));
|
pNew->cmd.payloadLen = (int32_t) ((start - pInfo->tableNames) + sizeof(SMultiTableInfoMsg));
|
||||||
pNew->cmd.msgType = TSDB_MSG_TYPE_CM_TABLES_META;
|
pNew->cmd.msgType = TSDB_MSG_TYPE_CM_TABLES_META;
|
||||||
|
|
||||||
registerSqlObj(pNew);
|
registerSqlObj(pNew);
|
||||||
tscDebug("0x%"PRIx64" new pSqlObj:0x%"PRIx64" to get %d tableMeta, vgroupInfo:%d, msg size:%d", pSql->self,
|
tscDebug("0x%"PRIx64" new pSqlObj:0x%"PRIx64" to get %d tableMeta, vgroupInfo:%d, udf:%d, msg size:%d", pSql->self,
|
||||||
pNew->self, numOfTable, numOfVgroupList, pNew->cmd.payloadLen);
|
pNew->self, numOfTable, numOfVgroupList, numOfUdf, pNew->cmd.payloadLen);
|
||||||
|
|
||||||
pNew->fp = fp;
|
pNew->fp = fp;
|
||||||
pNew->param = (void *)pSql->self;
|
pNew->param = (void *)pSql->self;
|
||||||
|
|
@ -2616,22 +2804,24 @@ int32_t tscGetTableMetaImpl(SSqlObj* pSql, STableMetaInfo *pTableMetaInfo, bool
|
||||||
taosHashGetClone(tscTableMetaInfo, name, len, NULL, pTableMetaInfo->pTableMeta, -1);
|
taosHashGetClone(tscTableMetaInfo, name, len, NULL, pTableMetaInfo->pTableMeta, -1);
|
||||||
|
|
||||||
// TODO resize the tableMeta
|
// TODO resize the tableMeta
|
||||||
char buf[80*1024] = {0};
|
assert(size < 80 * TSDB_MAX_COLUMNS);
|
||||||
assert(size < 80*1024);
|
if (!pSql->pBuf) {
|
||||||
|
if (NULL == (pSql->pBuf = tcalloc(1, 80 * TSDB_MAX_COLUMNS))) {
|
||||||
|
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
STableMeta* pMeta = pTableMetaInfo->pTableMeta;
|
STableMeta* pMeta = pTableMetaInfo->pTableMeta;
|
||||||
if (pMeta->id.uid > 0) {
|
if (pMeta->id.uid > 0) {
|
||||||
// in case of child table, here only get the
|
// in case of child table, here only get the
|
||||||
if (pMeta->tableType == TSDB_CHILD_TABLE) {
|
if (pMeta->tableType == TSDB_CHILD_TABLE) {
|
||||||
int32_t code = tscCreateTableMetaFromSTableMeta(pTableMetaInfo->pTableMeta, name, buf);
|
int32_t code = tscCreateTableMetaFromSTableMeta(pTableMetaInfo->pTableMeta, name, pSql->pBuf);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
return getTableMetaFromMnode(pSql, pTableMetaInfo, autocreate);
|
return getTableMetaFromMnode(pSql, pTableMetaInfo, autocreate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
return getTableMetaFromMnode(pSql, pTableMetaInfo, autocreate);
|
return getTableMetaFromMnode(pSql, pTableMetaInfo, autocreate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2643,6 +2833,60 @@ int tscGetTableMetaEx(SSqlObj *pSql, STableMetaInfo *pTableMetaInfo, bool create
|
||||||
return tscGetTableMetaImpl(pSql, pTableMetaInfo, createIfNotExists);
|
return tscGetTableMetaImpl(pSql, pTableMetaInfo, createIfNotExists);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t tscGetUdfFromNode(SSqlObj *pSql, SQueryInfo* pQueryInfo) {
|
||||||
|
SSqlObj *pNew = calloc(1, sizeof(SSqlObj));
|
||||||
|
if (NULL == pNew) {
|
||||||
|
tscError("%p malloc failed for new sqlobj to get user-defined functions", pSql);
|
||||||
|
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
pNew->pTscObj = pSql->pTscObj;
|
||||||
|
pNew->signature = pNew;
|
||||||
|
pNew->cmd.command = TSDB_SQL_RETRIEVE_FUNC;
|
||||||
|
|
||||||
|
if (tscAddQueryInfo(&pNew->cmd) != TSDB_CODE_SUCCESS) {
|
||||||
|
tscError("%p malloc failed for new queryinfo", pSql);
|
||||||
|
tscFreeSqlObj(pNew);
|
||||||
|
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
SQueryInfo *pNewQueryInfo = tscGetQueryInfo(&pNew->cmd);
|
||||||
|
|
||||||
|
pNewQueryInfo->pUdfInfo = taosArrayInit(4, sizeof(SUdfInfo));
|
||||||
|
for(int32_t i = 0; i < taosArrayGetSize(pQueryInfo->pUdfInfo); ++i) {
|
||||||
|
SUdfInfo info = {0};
|
||||||
|
SUdfInfo* p1 = taosArrayGet(pQueryInfo->pUdfInfo, i);
|
||||||
|
info = *p1;
|
||||||
|
info.name = strdup(p1->name);
|
||||||
|
taosArrayPush(pNewQueryInfo->pUdfInfo, &info);
|
||||||
|
}
|
||||||
|
|
||||||
|
pNew->cmd.active = pNewQueryInfo;
|
||||||
|
|
||||||
|
if (TSDB_CODE_SUCCESS != tscAllocPayload(&pNew->cmd, TSDB_DEFAULT_PAYLOAD_SIZE + pSql->cmd.payloadLen)) {
|
||||||
|
tscError("%p malloc failed for payload to get table meta", pSql);
|
||||||
|
tscFreeSqlObj(pNew);
|
||||||
|
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
tscDebug("%p new pSqlObj:%p to retrieve udf", pSql, pNew);
|
||||||
|
registerSqlObj(pNew);
|
||||||
|
|
||||||
|
pNew->fp = tscTableMetaCallBack;
|
||||||
|
pNew->param = (void *)pSql->self;
|
||||||
|
|
||||||
|
tscDebug("%p metaRid from %" PRId64 " to %" PRId64 , pSql, pSql->metaRid, pNew->self);
|
||||||
|
|
||||||
|
pSql->metaRid = pNew->self;
|
||||||
|
|
||||||
|
int32_t code = tscBuildAndSendRequest(pNew, NULL);
|
||||||
|
if (code == TSDB_CODE_SUCCESS) {
|
||||||
|
code = TSDB_CODE_TSC_ACTION_IN_PROGRESS; // notify application that current process needs to be terminated
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* retrieve table meta from mnode, and then update the local table meta hashmap.
|
* retrieve table meta from mnode, and then update the local table meta hashmap.
|
||||||
* @param pSql sql object
|
* @param pSql sql object
|
||||||
|
|
@ -2692,7 +2936,6 @@ int tscGetSTableVgroupInfo(SSqlObj *pSql, SQueryInfo* pQueryInfo) {
|
||||||
if (allVgroupInfoRetrieved(pQueryInfo)) {
|
if (allVgroupInfoRetrieved(pQueryInfo)) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
SSqlObj *pNew = calloc(1, sizeof(SSqlObj));
|
SSqlObj *pNew = calloc(1, sizeof(SSqlObj));
|
||||||
pNew->pTscObj = pSql->pTscObj;
|
pNew->pTscObj = pSql->pTscObj;
|
||||||
pNew->signature = pNew;
|
pNew->signature = pNew;
|
||||||
|
|
@ -2744,6 +2987,7 @@ void tscInitMsgsFp() {
|
||||||
|
|
||||||
tscBuildMsg[TSDB_SQL_CREATE_DB] = tscBuildCreateDbMsg;
|
tscBuildMsg[TSDB_SQL_CREATE_DB] = tscBuildCreateDbMsg;
|
||||||
tscBuildMsg[TSDB_SQL_CREATE_USER] = tscBuildUserMsg;
|
tscBuildMsg[TSDB_SQL_CREATE_USER] = tscBuildUserMsg;
|
||||||
|
tscBuildMsg[TSDB_SQL_CREATE_FUNCTION] = tscBuildCreateFuncMsg;
|
||||||
|
|
||||||
tscBuildMsg[TSDB_SQL_CREATE_ACCT] = tscBuildAcctMsg;
|
tscBuildMsg[TSDB_SQL_CREATE_ACCT] = tscBuildAcctMsg;
|
||||||
tscBuildMsg[TSDB_SQL_ALTER_ACCT] = tscBuildAcctMsg;
|
tscBuildMsg[TSDB_SQL_ALTER_ACCT] = tscBuildAcctMsg;
|
||||||
|
|
@ -2752,6 +2996,7 @@ void tscInitMsgsFp() {
|
||||||
tscBuildMsg[TSDB_SQL_DROP_USER] = tscBuildDropUserAcctMsg;
|
tscBuildMsg[TSDB_SQL_DROP_USER] = tscBuildDropUserAcctMsg;
|
||||||
tscBuildMsg[TSDB_SQL_DROP_ACCT] = tscBuildDropUserAcctMsg;
|
tscBuildMsg[TSDB_SQL_DROP_ACCT] = tscBuildDropUserAcctMsg;
|
||||||
tscBuildMsg[TSDB_SQL_DROP_DB] = tscBuildDropDbMsg;
|
tscBuildMsg[TSDB_SQL_DROP_DB] = tscBuildDropDbMsg;
|
||||||
|
tscBuildMsg[TSDB_SQL_DROP_FUNCTION] = tscBuildDropFuncMsg;
|
||||||
tscBuildMsg[TSDB_SQL_SYNC_DB_REPLICA] = tscBuildSyncDbReplicaMsg;
|
tscBuildMsg[TSDB_SQL_SYNC_DB_REPLICA] = tscBuildSyncDbReplicaMsg;
|
||||||
tscBuildMsg[TSDB_SQL_DROP_TABLE] = tscBuildDropTableMsg;
|
tscBuildMsg[TSDB_SQL_DROP_TABLE] = tscBuildDropTableMsg;
|
||||||
tscBuildMsg[TSDB_SQL_ALTER_USER] = tscBuildUserMsg;
|
tscBuildMsg[TSDB_SQL_ALTER_USER] = tscBuildUserMsg;
|
||||||
|
|
@ -2767,6 +3012,7 @@ void tscInitMsgsFp() {
|
||||||
tscBuildMsg[TSDB_SQL_USE_DB] = tscBuildUseDbMsg;
|
tscBuildMsg[TSDB_SQL_USE_DB] = tscBuildUseDbMsg;
|
||||||
// tscBuildMsg[TSDB_SQL_META] = tscBuildTableMetaMsg;
|
// tscBuildMsg[TSDB_SQL_META] = tscBuildTableMetaMsg;
|
||||||
tscBuildMsg[TSDB_SQL_STABLEVGROUP] = tscBuildSTableVgroupMsg;
|
tscBuildMsg[TSDB_SQL_STABLEVGROUP] = tscBuildSTableVgroupMsg;
|
||||||
|
tscBuildMsg[TSDB_SQL_RETRIEVE_FUNC] = tscBuildRetrieveFuncMsg;
|
||||||
|
|
||||||
tscBuildMsg[TSDB_SQL_HB] = tscBuildHeartBeatMsg;
|
tscBuildMsg[TSDB_SQL_HB] = tscBuildHeartBeatMsg;
|
||||||
tscBuildMsg[TSDB_SQL_SHOW] = tscBuildShowMsg;
|
tscBuildMsg[TSDB_SQL_SHOW] = tscBuildShowMsg;
|
||||||
|
|
@ -2785,6 +3031,7 @@ void tscInitMsgsFp() {
|
||||||
tscProcessMsgRsp[TSDB_SQL_META] = tscProcessTableMetaRsp;
|
tscProcessMsgRsp[TSDB_SQL_META] = tscProcessTableMetaRsp;
|
||||||
tscProcessMsgRsp[TSDB_SQL_STABLEVGROUP] = tscProcessSTableVgroupRsp;
|
tscProcessMsgRsp[TSDB_SQL_STABLEVGROUP] = tscProcessSTableVgroupRsp;
|
||||||
tscProcessMsgRsp[TSDB_SQL_MULTI_META] = tscProcessMultiTableMetaRsp;
|
tscProcessMsgRsp[TSDB_SQL_MULTI_META] = tscProcessMultiTableMetaRsp;
|
||||||
|
tscProcessMsgRsp[TSDB_SQL_RETRIEVE_FUNC] = tscProcessRetrieveFuncRsp;
|
||||||
|
|
||||||
tscProcessMsgRsp[TSDB_SQL_SHOW] = tscProcessShowRsp;
|
tscProcessMsgRsp[TSDB_SQL_SHOW] = tscProcessShowRsp;
|
||||||
tscProcessMsgRsp[TSDB_SQL_RETRIEVE] = tscProcessRetrieveRspFromNode; // rsp handled by same function.
|
tscProcessMsgRsp[TSDB_SQL_RETRIEVE] = tscProcessRetrieveRspFromNode; // rsp handled by same function.
|
||||||
|
|
@ -2814,3 +3061,4 @@ void tscInitMsgsFp() {
|
||||||
tscKeepConn[TSDB_SQL_FETCH] = 1;
|
tscKeepConn[TSDB_SQL_FETCH] = 1;
|
||||||
tscKeepConn[TSDB_SQL_HB] = 1;
|
tscKeepConn[TSDB_SQL_HB] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -566,7 +566,7 @@ static bool tscKillQueryInDnode(SSqlObj* pSql) {
|
||||||
|
|
||||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd);
|
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd);
|
||||||
|
|
||||||
if ((pQueryInfo == NULL) || tscIsTwoStageSTableQuery(pQueryInfo, 0)) {
|
if ((pQueryInfo == NULL) || pQueryInfo->globalMerge) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -679,7 +679,7 @@ static void tscKillSTableQuery(SSqlObj *pSql) {
|
||||||
|
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd);
|
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd);
|
||||||
|
|
||||||
if (!tscIsTwoStageSTableQuery(pQueryInfo, 0)) {
|
if (!pQueryInfo->globalMerge) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -730,7 +730,7 @@ void taos_stop_query(TAOS_RES *res) {
|
||||||
|
|
||||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd);
|
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd);
|
||||||
|
|
||||||
if (tscIsTwoStageSTableQuery(pQueryInfo, 0)) {
|
if (pQueryInfo->globalMerge) {
|
||||||
assert(pSql->rpcRid <= 0);
|
assert(pSql->rpcRid <= 0);
|
||||||
tscKillSTableQuery(pSql);
|
tscKillSTableQuery(pSql);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -945,28 +945,35 @@ int taos_load_table_info(TAOS *taos, const char *tableNameList) {
|
||||||
return TSDB_CODE_TSC_DISCONNECTED;
|
return TSDB_CODE_TSC_DISCONNECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
SSqlObj* pSql = calloc(1, sizeof(SSqlObj));
|
|
||||||
pSql->pTscObj = taos;
|
|
||||||
pSql->signature = pSql;
|
|
||||||
pSql->cmd.pTableMetaMap = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK);
|
|
||||||
|
|
||||||
int32_t length = (int32_t)strlen(tableNameList);
|
int32_t length = (int32_t)strlen(tableNameList);
|
||||||
|
if (length == 0) {
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
if (length > MAX_TABLE_NAME_LENGTH) {
|
if (length > MAX_TABLE_NAME_LENGTH) {
|
||||||
tscError("0x%"PRIx64" tableNameList too long, length:%d, maximum allowed:%d", pSql->self, length, MAX_TABLE_NAME_LENGTH);
|
tscError("tableNameList too long, length:%d, maximum allowed:%d", length, MAX_TABLE_NAME_LENGTH);
|
||||||
tscFreeSqlObj(pSql);
|
|
||||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *str = calloc(1, length + 1);
|
char *str = calloc(1, length + 1);
|
||||||
if (str == NULL) {
|
if (str == NULL) {
|
||||||
tscError("0x%"PRIx64" failed to allocate sql string buffer", pSql->self);
|
tscError("failed to allocate sql string buffer, size:%d", length);
|
||||||
tscFreeSqlObj(pSql);
|
|
||||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
strtolower(str, tableNameList);
|
strtolower(str, tableNameList);
|
||||||
SArray* plist = taosArrayInit(4, POINTER_BYTES);
|
SArray* plist = taosArrayInit(4, POINTER_BYTES);
|
||||||
SArray* vgroupList = taosArrayInit(4, POINTER_BYTES);
|
SArray* vgroupList = taosArrayInit(4, POINTER_BYTES);
|
||||||
|
if (plist == NULL || vgroupList == NULL) {
|
||||||
|
tfree(str);
|
||||||
|
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
SSqlObj* pSql = calloc(1, sizeof(SSqlObj));
|
||||||
|
tscAllocPayload(&pSql->cmd, 1024);
|
||||||
|
|
||||||
|
pSql->pTscObj = taos;
|
||||||
|
pSql->signature = pSql;
|
||||||
|
|
||||||
int32_t code = (uint8_t) tscTransferTableNameList(pSql, str, length, plist);
|
int32_t code = (uint8_t) tscTransferTableNameList(pSql, str, length, plist);
|
||||||
free(str);
|
free(str);
|
||||||
|
|
@ -976,10 +983,11 @@ int taos_load_table_info(TAOS *taos, const char *tableNameList) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pSql->cmd.pTableMetaMap = taosHashInit(taosArrayGetSize(plist), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK);
|
||||||
registerSqlObj(pSql);
|
registerSqlObj(pSql);
|
||||||
tscDebug("0x%"PRIx64" load multiple table meta, tableNameList: %s pObj:%p", pSql->self, tableNameList, pObj);
|
tscDebug("0x%"PRIx64" load multiple table meta, tableNameList: %s pObj:%p", pSql->self, tableNameList, pObj);
|
||||||
|
|
||||||
code = getMultiTableMetaFromMnode(pSql, plist, vgroupList, loadMultiTableMetaCallback);
|
code = getMultiTableMetaFromMnode(pSql, plist, vgroupList, NULL, loadMultiTableMetaCallback, false);
|
||||||
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||||
code = TSDB_CODE_SUCCESS;
|
code = TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
#include "tscSubquery.h"
|
#include "tscSubquery.h"
|
||||||
#include "qTableMeta.h"
|
#include "qTableMeta.h"
|
||||||
#include "tsclient.h"
|
#include "tsclient.h"
|
||||||
|
#include "qUdf.h"
|
||||||
#include "qUtil.h"
|
#include "qUtil.h"
|
||||||
#include "qPlan.h"
|
#include "qPlan.h"
|
||||||
|
|
||||||
|
|
@ -32,7 +33,7 @@ typedef struct SInsertSupporter {
|
||||||
} SInsertSupporter;
|
} SInsertSupporter;
|
||||||
|
|
||||||
static void freeJoinSubqueryObj(SSqlObj* pSql);
|
static void freeJoinSubqueryObj(SSqlObj* pSql);
|
||||||
static bool tscHasRemainDataInSubqueryResultSet(SSqlObj *pSql);
|
//static bool tscHasRemainDataInSubqueryResultSet(SSqlObj *pSql);
|
||||||
|
|
||||||
static int32_t tsCompare(int32_t order, int64_t left, int64_t right) {
|
static int32_t tsCompare(int32_t order, int64_t left, int64_t right) {
|
||||||
if (left == right) {
|
if (left == right) {
|
||||||
|
|
@ -711,6 +712,15 @@ static void updateQueryTimeRange(SQueryInfo* pQueryInfo, STimeWindow* win) {
|
||||||
pQueryInfo->window = *win;
|
pQueryInfo->window = *win;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t tagValCompar(const void* p1, const void* p2) {
|
||||||
|
const STidTags* t1 = (const STidTags*) varDataVal(p1);
|
||||||
|
const STidTags* t2 = (const STidTags*) varDataVal(p2);
|
||||||
|
|
||||||
|
__compar_fn_t func = getComparFunc(t1->padding, 0);
|
||||||
|
|
||||||
|
return func(t1->tag, t2->tag);
|
||||||
|
}
|
||||||
|
|
||||||
int32_t tidTagsCompar(const void* p1, const void* p2) {
|
int32_t tidTagsCompar(const void* p1, const void* p2) {
|
||||||
const STidTags* t1 = (const STidTags*) (p1);
|
const STidTags* t1 = (const STidTags*) (p1);
|
||||||
const STidTags* t2 = (const STidTags*) (p2);
|
const STidTags* t2 = (const STidTags*) (p2);
|
||||||
|
|
@ -719,28 +729,7 @@ int32_t tidTagsCompar(const void* p1, const void* p2) {
|
||||||
return (t1->vgId > t2->vgId) ? 1 : -1;
|
return (t1->vgId > t2->vgId) ? 1 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
tstr* tag1 = (tstr*) t1->tag;
|
return tagValCompar(p1, p2);
|
||||||
tstr* tag2 = (tstr*) t2->tag;
|
|
||||||
|
|
||||||
if (tag1->len != tag2->len) {
|
|
||||||
return (tag1->len > tag2->len)? 1: -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return strncmp(tag1->data, tag2->data, tag1->len);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t tagValCompar(const void* p1, const void* p2) {
|
|
||||||
const STidTags* t1 = (const STidTags*) varDataVal(p1);
|
|
||||||
const STidTags* t2 = (const STidTags*) varDataVal(p2);
|
|
||||||
|
|
||||||
tstr* tag1 = (tstr*) t1->tag;
|
|
||||||
tstr* tag2 = (tstr*) t2->tag;
|
|
||||||
|
|
||||||
if (tag1->len != tag2->len) {
|
|
||||||
return (tag1->len > tag2->len)? 1: -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return memcmp(tag1->data, tag2->data, tag1->len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void tscBuildVgroupTableInfo(SSqlObj* pSql, STableMetaInfo* pTableMetaInfo, SArray* tables) {
|
void tscBuildVgroupTableInfo(SSqlObj* pSql, STableMetaInfo* pTableMetaInfo, SArray* tables) {
|
||||||
|
|
@ -870,6 +859,12 @@ static bool checkForDuplicateTagVal(SSchema* pColSchema, SJoinSupporter* p1, SSq
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void setTidTagType(SJoinSupporter* p, uint8_t type) {
|
||||||
|
for (int32_t i = 0; i < p->num; ++i) {
|
||||||
|
STidTags * tag = (STidTags*) varDataVal(p->pIdTagList + i * p->tagSize);
|
||||||
|
tag->padding = type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t getIntersectionOfTableTuple(SQueryInfo* pQueryInfo, SSqlObj* pParentSql, SArray* resList) {
|
static int32_t getIntersectionOfTableTuple(SQueryInfo* pQueryInfo, SSqlObj* pParentSql, SArray* resList) {
|
||||||
int16_t joinNum = pParentSql->subState.numOfSub;
|
int16_t joinNum = pParentSql->subState.numOfSub;
|
||||||
|
|
@ -889,6 +884,8 @@ static int32_t getIntersectionOfTableTuple(SQueryInfo* pQueryInfo, SSqlObj* pPar
|
||||||
for (int32_t i = 0; i < joinNum; i++) {
|
for (int32_t i = 0; i < joinNum; i++) {
|
||||||
SJoinSupporter* p = pParentSql->pSubs[i]->param;
|
SJoinSupporter* p = pParentSql->pSubs[i]->param;
|
||||||
|
|
||||||
|
setTidTagType(p, pColSchema->type);
|
||||||
|
|
||||||
ctxlist[i].p = p;
|
ctxlist[i].p = p;
|
||||||
ctxlist[i].res = taosArrayInit(p->num, size);
|
ctxlist[i].res = taosArrayInit(p->num, size);
|
||||||
|
|
||||||
|
|
@ -1896,7 +1893,7 @@ int32_t tscCreateJoinSubquery(SSqlObj *pSql, int16_t tableIndex, SJoinSupporter
|
||||||
int16_t type = 0;
|
int16_t type = 0;
|
||||||
int32_t inter = 0;
|
int32_t inter = 0;
|
||||||
|
|
||||||
getResultDataInfo(s->type, s->bytes, TSDB_FUNC_TID_TAG, 0, &type, &bytes, &inter, 0, 0);
|
getResultDataInfo(s->type, s->bytes, TSDB_FUNC_TID_TAG, 0, &type, &bytes, &inter, 0, 0, NULL);
|
||||||
|
|
||||||
SSchema s1 = {.colId = s->colId, .type = (uint8_t)type, .bytes = bytes};
|
SSchema s1 = {.colId = s->colId, .type = (uint8_t)type, .bytes = bytes};
|
||||||
pSupporter->tagSize = s1.bytes;
|
pSupporter->tagSize = s1.bytes;
|
||||||
|
|
@ -2295,6 +2292,7 @@ int32_t tscHandleFirstRoundStableQuery(SSqlObj *pSql) {
|
||||||
|
|
||||||
SArray* pColList = pNewQueryInfo->colList;
|
SArray* pColList = pNewQueryInfo->colList;
|
||||||
pNewQueryInfo->colList = NULL;
|
pNewQueryInfo->colList = NULL;
|
||||||
|
pNewQueryInfo->fillType = TSDB_FILL_NONE;
|
||||||
|
|
||||||
tscClearSubqueryInfo(pCmd);
|
tscClearSubqueryInfo(pCmd);
|
||||||
tscFreeSqlResult(pSql);
|
tscFreeSqlResult(pSql);
|
||||||
|
|
@ -2439,7 +2437,7 @@ int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) {
|
||||||
|
|
||||||
pRes->qId = 0x1; // hack the qhandle check
|
pRes->qId = 0x1; // hack the qhandle check
|
||||||
|
|
||||||
const uint32_t nBufferSize = (1u << 16u); // 64KB
|
const uint32_t nBufferSize = (1u << 18u); // 256KB
|
||||||
|
|
||||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd);
|
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd);
|
||||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||||
|
|
@ -2801,6 +2799,28 @@ static void tscAllDataRetrievedFromDnode(SRetrieveSupport *trsupport, SSqlObj* p
|
||||||
|
|
||||||
tscFreeRetrieveSup(pSql);
|
tscFreeRetrieveSup(pSql);
|
||||||
|
|
||||||
|
// set the command flag must be after the semaphore been correctly set.
|
||||||
|
if (pParentSql->cmd.command != TSDB_SQL_RETRIEVE_EMPTY_RESULT) {
|
||||||
|
pParentSql->cmd.command = TSDB_SQL_RETRIEVE_GLOBALMERGE;
|
||||||
|
|
||||||
|
SQueryInfo *pQueryInfo2 = tscGetQueryInfo(&pParentSql->cmd);
|
||||||
|
|
||||||
|
size_t size = tscNumOfExprs(pQueryInfo);
|
||||||
|
for (int32_t j = 0; j < size; ++j) {
|
||||||
|
SExprInfo* pExprInfo = tscExprGet(pQueryInfo2, j);
|
||||||
|
|
||||||
|
int32_t functionId = pExprInfo->base.functionId;
|
||||||
|
if (functionId < 0) {
|
||||||
|
SUdfInfo* pUdfInfo = taosArrayGet(pQueryInfo2->pUdfInfo, -1 * functionId - 1);
|
||||||
|
code = initUdfInfo(pUdfInfo);
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
pParentSql->res.code = code;
|
||||||
|
tscAsyncResultOnError(pParentSql);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (pParentSql->res.code == TSDB_CODE_SUCCESS) {
|
if (pParentSql->res.code == TSDB_CODE_SUCCESS) {
|
||||||
(*pParentSql->fp)(pParentSql->param, pParentSql, 0);
|
(*pParentSql->fp)(pParentSql->param, pParentSql, 0);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@
|
||||||
#include "tconfig.h"
|
#include "tconfig.h"
|
||||||
#include "ttimezone.h"
|
#include "ttimezone.h"
|
||||||
#include "tlocale.h"
|
#include "tlocale.h"
|
||||||
|
#include "qScript.h"
|
||||||
|
|
||||||
// global, not configurable
|
// global, not configurable
|
||||||
#define TSC_VAR_NOT_RELEASE 1
|
#define TSC_VAR_NOT_RELEASE 1
|
||||||
|
|
@ -148,6 +149,8 @@ void taos_init_imp(void) {
|
||||||
taosInitNotes();
|
taosInitNotes();
|
||||||
|
|
||||||
rpcInit();
|
rpcInit();
|
||||||
|
|
||||||
|
scriptEnvPoolInit();
|
||||||
tscDebug("starting to initialize TAOS client ...");
|
tscDebug("starting to initialize TAOS client ...");
|
||||||
tscDebug("Local End Point is:%s", tsLocalEp);
|
tscDebug("Local End Point is:%s", tsLocalEp);
|
||||||
}
|
}
|
||||||
|
|
@ -202,7 +205,9 @@ void taos_cleanup(void) {
|
||||||
if (atomic_val_compare_exchange_32(&sentinel, TSC_VAR_NOT_RELEASE, TSC_VAR_RELEASED) != TSC_VAR_NOT_RELEASE) {
|
if (atomic_val_compare_exchange_32(&sentinel, TSC_VAR_NOT_RELEASE, TSC_VAR_RELEASED) != TSC_VAR_NOT_RELEASE) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (tscEmbedded == 0) {
|
||||||
|
scriptEnvPoolCleanup();
|
||||||
|
}
|
||||||
taosHashCleanup(tscTableMetaInfo);
|
taosHashCleanup(tscTableMetaInfo);
|
||||||
tscTableMetaInfo = NULL;
|
tscTableMetaInfo = NULL;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -216,6 +216,15 @@ bool tscIsProjectionQueryOnSTable(SQueryInfo* pQueryInfo, int32_t tableIndex) {
|
||||||
for (int32_t i = 0; i < numOfExprs; ++i) {
|
for (int32_t i = 0; i < numOfExprs; ++i) {
|
||||||
int32_t functionId = tscExprGet(pQueryInfo, i)->base.functionId;
|
int32_t functionId = tscExprGet(pQueryInfo, i)->base.functionId;
|
||||||
|
|
||||||
|
if (functionId < 0) {
|
||||||
|
SUdfInfo* pUdfInfo = taosArrayGet(pQueryInfo->pUdfInfo, -1 * functionId - 1);
|
||||||
|
if (pUdfInfo->funcType == TSDB_UDF_TYPE_AGGREGATE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (functionId != TSDB_FUNC_PRJ &&
|
if (functionId != TSDB_FUNC_PRJ &&
|
||||||
functionId != TSDB_FUNC_TAGPRJ &&
|
functionId != TSDB_FUNC_TAGPRJ &&
|
||||||
functionId != TSDB_FUNC_TAG &&
|
functionId != TSDB_FUNC_TAG &&
|
||||||
|
|
@ -266,6 +275,16 @@ bool tscIsProjectionQuery(SQueryInfo* pQueryInfo) {
|
||||||
f != TSDB_FUNC_DERIVATIVE) {
|
f != TSDB_FUNC_DERIVATIVE) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (f < 0) {
|
||||||
|
SUdfInfo* pUdfInfo = taosArrayGet(pQueryInfo->pUdfInfo, -1 * f - 1);
|
||||||
|
if (pUdfInfo->funcType == TSDB_UDF_TYPE_AGGREGATE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -338,6 +357,10 @@ bool tsIsArithmeticQueryOnAggResult(SQueryInfo* pQueryInfo) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tscIsProjectionQuery(pQueryInfo)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -526,6 +549,15 @@ bool isSimpleAggregateRv(SQueryInfo* pQueryInfo) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t functionId = pExpr->base.functionId;
|
int32_t functionId = pExpr->base.functionId;
|
||||||
|
if (functionId < 0) {
|
||||||
|
SUdfInfo* pUdfInfo = taosArrayGet(pQueryInfo->pUdfInfo, -1 * functionId - 1);
|
||||||
|
if (pUdfInfo->funcType == TSDB_UDF_TYPE_AGGREGATE) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (functionId == TSDB_FUNC_TS || functionId == TSDB_FUNC_TS_DUMMY) {
|
if (functionId == TSDB_FUNC_TS || functionId == TSDB_FUNC_TS_DUMMY) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -1302,6 +1334,12 @@ void tscFreeQueryInfo(SSqlCmd* pCmd, bool removeMeta) {
|
||||||
tfree(pUpQueryInfo);
|
tfree(pUpQueryInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pQueryInfo->udfCopy) {
|
||||||
|
pQueryInfo->pUdfInfo = taosArrayDestroy(pQueryInfo->pUdfInfo);
|
||||||
|
} else {
|
||||||
|
pQueryInfo->pUdfInfo = tscDestroyUdfArrayList(pQueryInfo->pUdfInfo);
|
||||||
|
}
|
||||||
|
|
||||||
freeQueryInfoImpl(pQueryInfo);
|
freeQueryInfoImpl(pQueryInfo);
|
||||||
clearAllTableMetaInfo(pQueryInfo, removeMeta);
|
clearAllTableMetaInfo(pQueryInfo, removeMeta);
|
||||||
|
|
||||||
|
|
@ -1450,6 +1488,7 @@ void tscFreeSqlObj(SSqlObj* pSql) {
|
||||||
pSql->signature = NULL;
|
pSql->signature = NULL;
|
||||||
pSql->fp = NULL;
|
pSql->fp = NULL;
|
||||||
tfree(pSql->sqlstr);
|
tfree(pSql->sqlstr);
|
||||||
|
tfree(pSql->pBuf);
|
||||||
|
|
||||||
tfree(pSql->pSubs);
|
tfree(pSql->pSubs);
|
||||||
pSql->subState.numOfSub = 0;
|
pSql->subState.numOfSub = 0;
|
||||||
|
|
@ -1470,6 +1509,7 @@ void tscFreeSqlObj(SSqlObj* pSql) {
|
||||||
void tscDestroyBoundColumnInfo(SParsedDataColInfo* pColInfo) {
|
void tscDestroyBoundColumnInfo(SParsedDataColInfo* pColInfo) {
|
||||||
tfree(pColInfo->boundedColumns);
|
tfree(pColInfo->boundedColumns);
|
||||||
tfree(pColInfo->cols);
|
tfree(pColInfo->cols);
|
||||||
|
tfree(pColInfo->colIdxInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tscDestroyDataBlock(STableDataBlocks* pDataBlock, bool removeMeta) {
|
void tscDestroyDataBlock(STableDataBlocks* pDataBlock, bool removeMeta) {
|
||||||
|
|
@ -1539,6 +1579,47 @@ void* tscDestroyBlockArrayList(SArray* pDataBlockList) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void freeUdfInfo(SUdfInfo* pUdfInfo) {
|
||||||
|
if (pUdfInfo == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pUdfInfo->funcs[TSDB_UDF_FUNC_DESTROY]) {
|
||||||
|
(*(udfDestroyFunc)pUdfInfo->funcs[TSDB_UDF_FUNC_DESTROY])(&pUdfInfo->init);
|
||||||
|
}
|
||||||
|
|
||||||
|
tfree(pUdfInfo->name);
|
||||||
|
|
||||||
|
if (pUdfInfo->path) {
|
||||||
|
unlink(pUdfInfo->path);
|
||||||
|
}
|
||||||
|
|
||||||
|
tfree(pUdfInfo->path);
|
||||||
|
|
||||||
|
tfree(pUdfInfo->content);
|
||||||
|
|
||||||
|
taosCloseDll(pUdfInfo->handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void* tscDestroyUdfArrayList(SArray* pUdfList) {
|
||||||
|
if (pUdfList == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t size = taosArrayGetSize(pUdfList);
|
||||||
|
for (int32_t i = 0; i < size; i++) {
|
||||||
|
SUdfInfo* udf = taosArrayGet(pUdfList, i);
|
||||||
|
freeUdfInfo(udf);
|
||||||
|
}
|
||||||
|
|
||||||
|
taosArrayDestroy(pUdfList);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void* tscDestroyBlockHashTable(SHashObj* pBlockHashTable, bool removeMeta) {
|
void* tscDestroyBlockHashTable(SHashObj* pBlockHashTable, bool removeMeta) {
|
||||||
if (pBlockHashTable == NULL) {
|
if (pBlockHashTable == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -1689,7 +1770,103 @@ int32_t tscGetDataBlockFromList(SHashObj* pHashList, int64_t id, int32_t size, i
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int trimDataBlock(void* pDataBlock, STableDataBlocks* pTableDataBlock, bool includeSchema) {
|
static SMemRow tdGenMemRowFromBuilder(SMemRowBuilder* pBuilder) {
|
||||||
|
SSchema* pSchema = pBuilder->pSchema;
|
||||||
|
char* p = (char*)pBuilder->buf;
|
||||||
|
int toffset = 0;
|
||||||
|
uint16_t nCols = pBuilder->nCols;
|
||||||
|
|
||||||
|
uint8_t memRowType = payloadType(p);
|
||||||
|
uint16_t nColsBound = payloadNCols(p);
|
||||||
|
if (pBuilder->nCols <= 0 || nColsBound <= 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
char* pVals = POINTER_SHIFT(p, payloadValuesOffset(p));
|
||||||
|
SMemRow* memRow = (SMemRow)pBuilder->pDataBlock;
|
||||||
|
memRowSetType(memRow, memRowType);
|
||||||
|
|
||||||
|
// ----------------- Raw payload structure for row:
|
||||||
|
/* |<------------ Head ------------->|<----------- body of column data tuple ------------------->|
|
||||||
|
* | |<----------------- flen ------------->|<--- value part --->|
|
||||||
|
* |SMemRowType| dataTLen | nCols | colId | colType | offset | ... | value |...|...|... |
|
||||||
|
* +-----------+----------+----------+--------------------------------------|--------------------|
|
||||||
|
* | uint8_t | uint32_t | uint16_t | int16_t | uint8_t | uint16_t | ... |.......|...|...|... |
|
||||||
|
* +-----------+----------+----------+--------------------------------------+--------------------|
|
||||||
|
* 1. offset in column data tuple starts from the value part in case of uint16_t overflow.
|
||||||
|
* 2. dataTLen: total length including the header and body.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (memRowType == SMEM_ROW_DATA) {
|
||||||
|
SDataRow trow = (SDataRow)memRowDataBody(memRow);
|
||||||
|
dataRowSetLen(trow, (TDRowLenT)(TD_DATA_ROW_HEAD_SIZE + pBuilder->flen));
|
||||||
|
dataRowSetVersion(trow, pBuilder->sversion);
|
||||||
|
|
||||||
|
p = (char*)payloadBody(pBuilder->buf);
|
||||||
|
uint16_t i = 0, j = 0;
|
||||||
|
while (j < nCols) {
|
||||||
|
if (i >= nColsBound) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
int16_t colId = payloadColId(p);
|
||||||
|
if (colId == pSchema[j].colId) {
|
||||||
|
// ASSERT(payloadColType(p) == pSchema[j].type);
|
||||||
|
tdAppendColVal(trow, POINTER_SHIFT(pVals, payloadColOffset(p)), pSchema[j].type, toffset);
|
||||||
|
toffset += TYPE_BYTES[pSchema[j].type];
|
||||||
|
p = payloadNextCol(p);
|
||||||
|
++i;
|
||||||
|
++j;
|
||||||
|
} else if (colId < pSchema[j].colId) {
|
||||||
|
p = payloadNextCol(p);
|
||||||
|
++i;
|
||||||
|
} else {
|
||||||
|
tdAppendColVal(trow, tdGetNullVal(pSchema[j].type), pSchema[j].type, toffset);
|
||||||
|
toffset += TYPE_BYTES[pSchema[j].type];
|
||||||
|
++j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (j < nCols) {
|
||||||
|
tdAppendColVal(trow, tdGetNullVal(pSchema[j].type), pSchema[j].type, toffset);
|
||||||
|
toffset += TYPE_BYTES[pSchema[j].type];
|
||||||
|
++j;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0 // no need anymore
|
||||||
|
while (i < nColsBound) {
|
||||||
|
p = payloadNextCol(p);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} else if (memRowType == SMEM_ROW_KV) {
|
||||||
|
SKVRow kvRow = (SKVRow)memRowKvBody(memRow);
|
||||||
|
kvRowSetLen(kvRow, (TDRowLenT)(TD_KV_ROW_HEAD_SIZE + sizeof(SColIdx) * nColsBound));
|
||||||
|
kvRowSetNCols(kvRow, nColsBound);
|
||||||
|
memRowSetKvVersion(memRow, pBuilder->sversion);
|
||||||
|
|
||||||
|
p = (char*)payloadBody(pBuilder->buf);
|
||||||
|
int i = 0;
|
||||||
|
while (i < nColsBound) {
|
||||||
|
int16_t colId = payloadColId(p);
|
||||||
|
uint8_t colType = payloadColType(p);
|
||||||
|
tdAppendKvColVal(kvRow, POINTER_SHIFT(pVals,payloadColOffset(p)), colId, colType, toffset);
|
||||||
|
toffset += sizeof(SColIdx);
|
||||||
|
p = payloadNextCol(p);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
ASSERT(0);
|
||||||
|
}
|
||||||
|
int32_t rowTLen = memRowTLen(memRow);
|
||||||
|
pBuilder->pDataBlock = (char*)pBuilder->pDataBlock + rowTLen; // next row
|
||||||
|
pBuilder->pSubmitBlk->dataLen += rowTLen;
|
||||||
|
|
||||||
|
return memRow;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Erase the empty space reserved for binary data
|
||||||
|
static int trimDataBlock(void* pDataBlock, STableDataBlocks* pTableDataBlock, bool includeSchema, SBlockKeyTuple *blkKeyTuple) {
|
||||||
// TODO: optimize this function, handle the case while binary is not presented
|
// TODO: optimize this function, handle the case while binary is not presented
|
||||||
STableMeta* pTableMeta = pTableDataBlock->pTableMeta;
|
STableMeta* pTableMeta = pTableDataBlock->pTableMeta;
|
||||||
STableComInfo tinfo = tscGetTableInfo(pTableMeta);
|
STableComInfo tinfo = tscGetTableInfo(pTableMeta);
|
||||||
|
|
@ -1729,20 +1906,18 @@ static int trimDataBlock(void* pDataBlock, STableDataBlocks* pTableDataBlock, bo
|
||||||
pBlock->dataLen = 0;
|
pBlock->dataLen = 0;
|
||||||
int32_t numOfRows = htons(pBlock->numOfRows);
|
int32_t numOfRows = htons(pBlock->numOfRows);
|
||||||
|
|
||||||
|
SMemRowBuilder rowBuilder;
|
||||||
|
rowBuilder.pSchema = pSchema;
|
||||||
|
rowBuilder.sversion = pTableMeta->sversion;
|
||||||
|
rowBuilder.flen = flen;
|
||||||
|
rowBuilder.nCols = tinfo.numOfColumns;
|
||||||
|
rowBuilder.pDataBlock = pDataBlock;
|
||||||
|
rowBuilder.pSubmitBlk = pBlock;
|
||||||
|
rowBuilder.buf = p;
|
||||||
|
|
||||||
for (int32_t i = 0; i < numOfRows; ++i) {
|
for (int32_t i = 0; i < numOfRows; ++i) {
|
||||||
SDataRow trow = (SDataRow) pDataBlock;
|
rowBuilder.buf = (blkKeyTuple + i)->payloadAddr;
|
||||||
dataRowSetLen(trow, (uint16_t)(TD_DATA_ROW_HEAD_SIZE + flen));
|
tdGenMemRowFromBuilder(&rowBuilder);
|
||||||
dataRowSetVersion(trow, pTableMeta->sversion);
|
|
||||||
|
|
||||||
int toffset = 0;
|
|
||||||
for (int32_t j = 0; j < tinfo.numOfColumns; j++) {
|
|
||||||
tdAppendColVal(trow, p, pSchema[j].type, pSchema[j].bytes, toffset);
|
|
||||||
toffset += TYPE_BYTES[pSchema[j].type];
|
|
||||||
p += pSchema[j].bytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
pDataBlock = (char*)pDataBlock + dataRowLen(trow);
|
|
||||||
pBlock->dataLen += dataRowLen(trow);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t len = pBlock->dataLen + pBlock->schemaLen;
|
int32_t len = pBlock->dataLen + pBlock->schemaLen;
|
||||||
|
|
@ -1753,7 +1928,7 @@ static int trimDataBlock(void* pDataBlock, STableDataBlocks* pTableDataBlock, bo
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t getRowExpandSize(STableMeta* pTableMeta) {
|
static int32_t getRowExpandSize(STableMeta* pTableMeta) {
|
||||||
int32_t result = TD_DATA_ROW_HEAD_SIZE;
|
int32_t result = TD_MEM_ROW_DATA_HEAD_SIZE;
|
||||||
int32_t columns = tscGetNumOfColumns(pTableMeta);
|
int32_t columns = tscGetNumOfColumns(pTableMeta);
|
||||||
SSchema* pSchema = tscGetTableSchema(pTableMeta);
|
SSchema* pSchema = tscGetTableSchema(pTableMeta);
|
||||||
for(int32_t i = 0; i < columns; i++) {
|
for(int32_t i = 0; i < columns; i++) {
|
||||||
|
|
@ -1787,13 +1962,16 @@ static void extractTableNameList(SInsertStatementParam *pInsertParam, bool freeB
|
||||||
|
|
||||||
int32_t tscMergeTableDataBlocks(SInsertStatementParam *pInsertParam, bool freeBlockMap) {
|
int32_t tscMergeTableDataBlocks(SInsertStatementParam *pInsertParam, bool freeBlockMap) {
|
||||||
const int INSERT_HEAD_SIZE = sizeof(SMsgDesc) + sizeof(SSubmitMsg);
|
const int INSERT_HEAD_SIZE = sizeof(SMsgDesc) + sizeof(SSubmitMsg);
|
||||||
|
int code = 0;
|
||||||
void* pVnodeDataBlockHashList = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
void* pVnodeDataBlockHashList = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
||||||
SArray* pVnodeDataBlockList = taosArrayInit(8, POINTER_BYTES);
|
SArray* pVnodeDataBlockList = taosArrayInit(8, POINTER_BYTES);
|
||||||
|
|
||||||
STableDataBlocks** p = taosHashIterate(pInsertParam->pTableBlockHashList, NULL);
|
STableDataBlocks** p = taosHashIterate(pInsertParam->pTableBlockHashList, NULL);
|
||||||
|
|
||||||
STableDataBlocks* pOneTableBlock = *p;
|
STableDataBlocks* pOneTableBlock = *p;
|
||||||
|
|
||||||
|
SBlockKeyInfo blkKeyInfo = {0}; // share by pOneTableBlock
|
||||||
|
|
||||||
while(pOneTableBlock) {
|
while(pOneTableBlock) {
|
||||||
SSubmitBlk* pBlocks = (SSubmitBlk*) pOneTableBlock->pData;
|
SSubmitBlk* pBlocks = (SSubmitBlk*) pOneTableBlock->pData;
|
||||||
if (pBlocks->numOfRows > 0) {
|
if (pBlocks->numOfRows > 0) {
|
||||||
|
|
@ -1807,6 +1985,7 @@ int32_t tscMergeTableDataBlocks(SInsertStatementParam *pInsertParam, bool freeBl
|
||||||
tscError("0x%"PRIx64" failed to prepare the data block buffer for merging table data, code:%d", pInsertParam->objectId, ret);
|
tscError("0x%"PRIx64" failed to prepare the data block buffer for merging table data, code:%d", pInsertParam->objectId, ret);
|
||||||
taosHashCleanup(pVnodeDataBlockHashList);
|
taosHashCleanup(pVnodeDataBlockHashList);
|
||||||
tscDestroyBlockArrayList(pVnodeDataBlockList);
|
tscDestroyBlockArrayList(pVnodeDataBlockList);
|
||||||
|
tfree(blkKeyInfo.pKeyTuple);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1825,16 +2004,26 @@ int32_t tscMergeTableDataBlocks(SInsertStatementParam *pInsertParam, bool freeBl
|
||||||
taosHashCleanup(pVnodeDataBlockHashList);
|
taosHashCleanup(pVnodeDataBlockHashList);
|
||||||
tscDestroyBlockArrayList(pVnodeDataBlockList);
|
tscDestroyBlockArrayList(pVnodeDataBlockList);
|
||||||
tfree(dataBuf->pData);
|
tfree(dataBuf->pData);
|
||||||
|
tfree(blkKeyInfo.pKeyTuple);
|
||||||
|
|
||||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tscSortRemoveDataBlockDupRows(pOneTableBlock);
|
if ((code = tscSortRemoveDataBlockDupRows(pOneTableBlock, &blkKeyInfo)) != 0) {
|
||||||
char* ekey = (char*)pBlocks->data + pOneTableBlock->rowSize*(pBlocks->numOfRows-1);
|
taosHashCleanup(pVnodeDataBlockHashList);
|
||||||
|
tscDestroyBlockArrayList(pVnodeDataBlockList);
|
||||||
|
tfree(dataBuf->pData);
|
||||||
|
tfree(blkKeyInfo.pKeyTuple);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
tscDebug("0x%"PRIx64" name:%s, tid:%d rows:%d sversion:%d skey:%" PRId64 ", ekey:%" PRId64, pInsertParam->objectId, tNameGetTableName(&pOneTableBlock->tableName),
|
ASSERT(blkKeyInfo.pKeyTuple != NULL && pBlocks->numOfRows > 0);
|
||||||
pBlocks->tid, pBlocks->numOfRows, pBlocks->sversion, GET_INT64_VAL(pBlocks->data), GET_INT64_VAL(ekey));
|
|
||||||
|
SBlockKeyTuple* pLastKeyTuple = blkKeyInfo.pKeyTuple + pBlocks->numOfRows - 1;
|
||||||
|
tscDebug("0x%" PRIx64 " name:%s, tid:%d rows:%d sversion:%d skey:%" PRId64 ", ekey:%" PRId64,
|
||||||
|
pInsertParam->objectId, tNameGetTableName(&pOneTableBlock->tableName), pBlocks->tid, pBlocks->numOfRows,
|
||||||
|
pBlocks->sversion, blkKeyInfo.pKeyTuple->skey, pLastKeyTuple->skey);
|
||||||
|
|
||||||
int32_t len = pBlocks->numOfRows * (pOneTableBlock->rowSize + expandSize) + sizeof(STColumn) * tscGetNumOfColumns(pOneTableBlock->pTableMeta);
|
int32_t len = pBlocks->numOfRows * (pOneTableBlock->rowSize + expandSize) + sizeof(STColumn) * tscGetNumOfColumns(pOneTableBlock->pTableMeta);
|
||||||
|
|
||||||
|
|
@ -1845,7 +2034,7 @@ int32_t tscMergeTableDataBlocks(SInsertStatementParam *pInsertParam, bool freeBl
|
||||||
pBlocks->schemaLen = 0;
|
pBlocks->schemaLen = 0;
|
||||||
|
|
||||||
// erase the empty space reserved for binary data
|
// erase the empty space reserved for binary data
|
||||||
int32_t finalLen = trimDataBlock(dataBuf->pData + dataBuf->size, pOneTableBlock, pInsertParam->schemaAttached);
|
int32_t finalLen = trimDataBlock(dataBuf->pData + dataBuf->size, pOneTableBlock, pInsertParam->schemaAttached, blkKeyInfo.pKeyTuple);
|
||||||
assert(finalLen <= len);
|
assert(finalLen <= len);
|
||||||
|
|
||||||
dataBuf->size += (finalLen + sizeof(SSubmitBlk));
|
dataBuf->size += (finalLen + sizeof(SSubmitBlk));
|
||||||
|
|
@ -1873,6 +2062,7 @@ int32_t tscMergeTableDataBlocks(SInsertStatementParam *pInsertParam, bool freeBl
|
||||||
// free the table data blocks;
|
// free the table data blocks;
|
||||||
pInsertParam->pDataBlocks = pVnodeDataBlockList;
|
pInsertParam->pDataBlocks = pVnodeDataBlockList;
|
||||||
taosHashCleanup(pVnodeDataBlockHashList);
|
taosHashCleanup(pVnodeDataBlockHashList);
|
||||||
|
tfree(blkKeyInfo.pKeyTuple);
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
@ -3060,6 +3250,14 @@ int32_t tscQueryInfoCopy(SQueryInfo* pQueryInfo, const SQueryInfo* pSrc) {
|
||||||
tscAddTableMetaInfo(pQueryInfo, &p1->name, pMeta, p1->vgroupList, p1->tagColList, p1->pVgroupTables);
|
tscAddTableMetaInfo(pQueryInfo, &p1->name, pMeta, p1->vgroupList, p1->tagColList, p1->pVgroupTables);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SArray *pUdfInfo = NULL;
|
||||||
|
if (pSrc->pUdfInfo) {
|
||||||
|
pUdfInfo = taosArrayDup(pSrc->pUdfInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
pQueryInfo->pUdfInfo = pUdfInfo;
|
||||||
|
pQueryInfo->udfCopy = true;
|
||||||
|
|
||||||
_error:
|
_error:
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
@ -3106,8 +3304,10 @@ void tscVgroupTableCopy(SVgroupTableInfo* info, SVgroupTableInfo* pInfo) {
|
||||||
info->vgInfo.epAddr[j].fqdn = strdup(pInfo->vgInfo.epAddr[j].fqdn);
|
info->vgInfo.epAddr[j].fqdn = strdup(pInfo->vgInfo.epAddr[j].fqdn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pInfo->itemList) {
|
||||||
info->itemList = taosArrayDup(pInfo->itemList);
|
info->itemList = taosArrayDup(pInfo->itemList);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SArray* tscVgroupTableInfoDup(SArray* pVgroupTables) {
|
SArray* tscVgroupTableInfoDup(SArray* pVgroupTables) {
|
||||||
if (pVgroupTables == NULL) {
|
if (pVgroupTables == NULL) {
|
||||||
|
|
@ -3357,6 +3557,11 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, __async_cb_func_t
|
||||||
|
|
||||||
SQueryInfo* pNewQueryInfo = tscGetQueryInfo(pnCmd);
|
SQueryInfo* pNewQueryInfo = tscGetQueryInfo(pnCmd);
|
||||||
|
|
||||||
|
if (pQueryInfo->pUdfInfo) {
|
||||||
|
pNewQueryInfo->pUdfInfo = taosArrayDup(pQueryInfo->pUdfInfo);
|
||||||
|
pNewQueryInfo->udfCopy = true;
|
||||||
|
}
|
||||||
|
|
||||||
pNewQueryInfo->command = pQueryInfo->command;
|
pNewQueryInfo->command = pQueryInfo->command;
|
||||||
pnCmd->active = pNewQueryInfo;
|
pnCmd->active = pNewQueryInfo;
|
||||||
|
|
||||||
|
|
@ -3376,6 +3581,7 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, __async_cb_func_t
|
||||||
pNewQueryInfo->numOfTables = 0;
|
pNewQueryInfo->numOfTables = 0;
|
||||||
pNewQueryInfo->pTableMetaInfo = NULL;
|
pNewQueryInfo->pTableMetaInfo = NULL;
|
||||||
pNewQueryInfo->bufLen = pQueryInfo->bufLen;
|
pNewQueryInfo->bufLen = pQueryInfo->bufLen;
|
||||||
|
|
||||||
pNewQueryInfo->buf = malloc(pQueryInfo->bufLen);
|
pNewQueryInfo->buf = malloc(pQueryInfo->bufLen);
|
||||||
if (pNewQueryInfo->buf == NULL) {
|
if (pNewQueryInfo->buf == NULL) {
|
||||||
terrno = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
terrno = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
|
|
@ -4218,7 +4424,7 @@ int32_t createProjectionExpr(SQueryInfo* pQueryInfo, STableMetaInfo* pTableMetaI
|
||||||
|
|
||||||
int32_t inter = 0;
|
int32_t inter = 0;
|
||||||
getResultDataInfo(pSource->base.colType, pSource->base.colBytes, functionId, 0, &pse->resType,
|
getResultDataInfo(pSource->base.colType, pSource->base.colBytes, functionId, 0, &pse->resType,
|
||||||
&pse->resBytes, &inter, 0, false);
|
&pse->resBytes, &inter, 0, false, NULL);
|
||||||
pse->colType = pse->resType;
|
pse->colType = pse->resType;
|
||||||
pse->colBytes = pse->resBytes;
|
pse->colBytes = pse->resBytes;
|
||||||
|
|
||||||
|
|
@ -4285,8 +4491,14 @@ static int32_t createGlobalAggregateExpr(SQueryAttr* pQueryAttr, SQueryInfo* pQu
|
||||||
functionId = TSDB_FUNC_STDDEV;
|
functionId = TSDB_FUNC_STDDEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SUdfInfo* pUdfInfo = NULL;
|
||||||
|
|
||||||
|
if (functionId < 0) {
|
||||||
|
pUdfInfo = taosArrayGet(pQueryInfo->pUdfInfo, -1 * functionId - 1);
|
||||||
|
}
|
||||||
|
|
||||||
getResultDataInfo(pExpr->base.colType, pExpr->base.colBytes, functionId, 0, &pse->resType, &pse->resBytes, &inter,
|
getResultDataInfo(pExpr->base.colType, pExpr->base.colBytes, functionId, 0, &pse->resType, &pse->resBytes, &inter,
|
||||||
0, false);
|
0, false, pUdfInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4362,6 +4574,7 @@ int32_t tscCreateQueryFromQueryInfo(SQueryInfo* pQueryInfo, SQueryAttr* pQueryAt
|
||||||
pQueryAttr->order = pQueryInfo->order;
|
pQueryAttr->order = pQueryInfo->order;
|
||||||
pQueryAttr->fillType = pQueryInfo->fillType;
|
pQueryAttr->fillType = pQueryInfo->fillType;
|
||||||
pQueryAttr->havingNum = pQueryInfo->havingFieldNum;
|
pQueryAttr->havingNum = pQueryInfo->havingFieldNum;
|
||||||
|
pQueryAttr->pUdfInfo = pQueryInfo->pUdfInfo;
|
||||||
|
|
||||||
if (pQueryInfo->order.order == TSDB_ORDER_ASC) { // TODO refactor
|
if (pQueryInfo->order.order == TSDB_ORDER_ASC) { // TODO refactor
|
||||||
pQueryAttr->window = pQueryInfo->window;
|
pQueryAttr->window = pQueryInfo->window;
|
||||||
|
|
@ -4474,8 +4687,13 @@ static int32_t doAddTableName(char* nextStr, char** str, SArray* pNameArray, SSq
|
||||||
strncpy(tablename, *str, TSDB_TABLE_FNAME_LEN);
|
strncpy(tablename, *str, TSDB_TABLE_FNAME_LEN);
|
||||||
len = (int32_t) strlen(tablename);
|
len = (int32_t) strlen(tablename);
|
||||||
} else {
|
} else {
|
||||||
memcpy(tablename, *str, nextStr - (*str));
|
|
||||||
len = (int32_t)(nextStr - (*str));
|
len = (int32_t)(nextStr - (*str));
|
||||||
|
if (len >= TSDB_TABLE_NAME_LEN) {
|
||||||
|
sprintf(pCmd->payload, "table name too long");
|
||||||
|
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(tablename, *str, nextStr - (*str));
|
||||||
tablename[len] = '\0';
|
tablename[len] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4487,9 +4705,8 @@ static int32_t doAddTableName(char* nextStr, char** str, SArray* pNameArray, SSq
|
||||||
|
|
||||||
// Check if the table name available or not
|
// Check if the table name available or not
|
||||||
if (tscValidateName(&sToken) != TSDB_CODE_SUCCESS) {
|
if (tscValidateName(&sToken) != TSDB_CODE_SUCCESS) {
|
||||||
code = TSDB_CODE_TSC_INVALID_TABLE_ID_LENGTH;
|
|
||||||
sprintf(pCmd->payload, "table name is invalid");
|
sprintf(pCmd->payload, "table name is invalid");
|
||||||
return code;
|
return TSDB_CODE_TSC_INVALID_TABLE_ID_LENGTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
SName name = {0};
|
SName name = {0};
|
||||||
|
|
@ -4505,6 +4722,15 @@ static int32_t doAddTableName(char* nextStr, char** str, SArray* pNameArray, SSq
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t nameComparFn(const void* n1, const void* n2) {
|
||||||
|
int32_t ret = strcmp(*(char**)n1, *(char**)n2);
|
||||||
|
if (ret == 0) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return ret > 0? 1:-1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int tscTransferTableNameList(SSqlObj *pSql, const char *pNameList, int32_t length, SArray* pNameArray) {
|
int tscTransferTableNameList(SSqlObj *pSql, const char *pNameList, int32_t length, SArray* pNameArray) {
|
||||||
SSqlCmd *pCmd = &pSql->cmd;
|
SSqlCmd *pCmd = &pSql->cmd;
|
||||||
|
|
||||||
|
|
@ -4540,12 +4766,44 @@ int tscTransferTableNameList(SSqlObj *pSql, const char *pNameList, int32_t lengt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (taosArrayGetSize(pNameArray) > TSDB_MULTI_TABLEMETA_MAX_NUM) {
|
size_t len = taosArrayGetSize(pNameArray);
|
||||||
|
if (len == 1) {
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len > TSDB_MULTI_TABLEMETA_MAX_NUM) {
|
||||||
code = TSDB_CODE_TSC_INVALID_TABLE_ID_LENGTH;
|
code = TSDB_CODE_TSC_INVALID_TABLE_ID_LENGTH;
|
||||||
sprintf(pCmd->payload, "tables over the max number");
|
sprintf(pCmd->payload, "tables over the max number");
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
taosArraySort(pNameArray, nameComparFn);
|
||||||
|
|
||||||
|
int32_t pos = 0;
|
||||||
|
for(int32_t i = 1; i < len; ++i) {
|
||||||
|
char** p1 = taosArrayGet(pNameArray, pos);
|
||||||
|
char** p2 = taosArrayGet(pNameArray, i);
|
||||||
|
|
||||||
|
if (strcmp(*p1, *p2) == 0) {
|
||||||
|
// do nothing
|
||||||
|
} else {
|
||||||
|
if (pos + 1 != i) {
|
||||||
|
char* p = taosArrayGetP(pNameArray, pos + 1);
|
||||||
|
tfree(p);
|
||||||
|
taosArraySet(pNameArray, pos + 1, p2);
|
||||||
|
pos += 1;
|
||||||
|
} else {
|
||||||
|
pos += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int32_t i = pos + 1; i < pNameArray->size; ++i) {
|
||||||
|
char* p = taosArrayGetP(pNameArray, i);
|
||||||
|
tfree(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
pNameArray->size = pos + 1;
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,8 +41,10 @@ enum {
|
||||||
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_MGMT, "mgmt" )
|
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_MGMT, "mgmt" )
|
||||||
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_CREATE_DB, "create-db" )
|
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_CREATE_DB, "create-db" )
|
||||||
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_CREATE_TABLE, "create-table" )
|
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_CREATE_TABLE, "create-table" )
|
||||||
|
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_CREATE_FUNCTION, "create-function" )
|
||||||
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_DROP_DB, "drop-db" )
|
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_DROP_DB, "drop-db" )
|
||||||
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_DROP_TABLE, "drop-table" )
|
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_DROP_TABLE, "drop-table" )
|
||||||
|
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_DROP_FUNCTION, "drop-function" )
|
||||||
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_CREATE_ACCT, "create-acct" )
|
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_CREATE_ACCT, "create-acct" )
|
||||||
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_CREATE_USER, "create-user" )
|
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_CREATE_USER, "create-user" )
|
||||||
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_DROP_ACCT, "drop-acct" )
|
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_DROP_ACCT, "drop-acct" )
|
||||||
|
|
@ -74,6 +76,7 @@ enum {
|
||||||
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_STABLEVGROUP, "stable-vgroup" )
|
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_STABLEVGROUP, "stable-vgroup" )
|
||||||
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_MULTI_META, "multi-meta" )
|
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_MULTI_META, "multi-meta" )
|
||||||
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_HB, "heart-beat" )
|
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_HB, "heart-beat" )
|
||||||
|
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_RETRIEVE_FUNC, "retrieve-function" )
|
||||||
|
|
||||||
// SQL below for client local
|
// SQL below for client local
|
||||||
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_LOCAL, "local" )
|
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_LOCAL, "local" )
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,35 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
typedef struct {
|
||||||
|
VarDataLenT len;
|
||||||
|
uint8_t data;
|
||||||
|
} SBinaryNullT;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
VarDataLenT len;
|
||||||
|
uint32_t data;
|
||||||
|
} SNCharNullT;
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
extern const uint8_t BoolNull;
|
||||||
|
extern const uint8_t TinyintNull;
|
||||||
|
extern const uint16_t SmallintNull;
|
||||||
|
extern const uint32_t IntNull;
|
||||||
|
extern const uint64_t BigintNull;
|
||||||
|
extern const uint64_t TimestampNull;
|
||||||
|
extern const uint8_t UTinyintNull;
|
||||||
|
extern const uint16_t USmallintNull;
|
||||||
|
extern const uint32_t UIntNull;
|
||||||
|
extern const uint64_t UBigintNull;
|
||||||
|
extern const uint32_t FloatNull;
|
||||||
|
extern const uint64_t DoubleNull;
|
||||||
|
extern const SBinaryNullT BinaryNull;
|
||||||
|
extern const SNCharNullT NcharNull;
|
||||||
|
|
||||||
|
const void *tdGetNullVal(int8_t type);
|
||||||
|
|
||||||
#define STR_TO_VARSTR(x, str) \
|
#define STR_TO_VARSTR(x, str) \
|
||||||
do { \
|
do { \
|
||||||
VarDataLenT __len = (VarDataLenT)strlen(str); \
|
VarDataLenT __len = (VarDataLenT)strlen(str); \
|
||||||
|
|
@ -31,6 +60,14 @@ extern "C" {
|
||||||
memcpy(varDataVal(x), (str), __len); \
|
memcpy(varDataVal(x), (str), __len); \
|
||||||
} while (0);
|
} while (0);
|
||||||
|
|
||||||
|
#define STR_TO_NET_VARSTR(x, str) \
|
||||||
|
do { \
|
||||||
|
VarDataLenT __len = (VarDataLenT)strlen(str); \
|
||||||
|
*(VarDataLenT *)(x) = htons(__len); \
|
||||||
|
memcpy(varDataVal(x), (str), __len); \
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
|
||||||
#define STR_WITH_MAXSIZE_TO_VARSTR(x, str, _maxs) \
|
#define STR_WITH_MAXSIZE_TO_VARSTR(x, str, _maxs) \
|
||||||
do { \
|
do { \
|
||||||
char *_e = stpncpy(varDataVal(x), (str), (_maxs)-VARSTR_HEADER_SIZE); \
|
char *_e = stpncpy(varDataVal(x), (str), (_maxs)-VARSTR_HEADER_SIZE); \
|
||||||
|
|
@ -47,8 +84,8 @@ extern "C" {
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int8_t type; // Column type
|
int8_t type; // Column type
|
||||||
int16_t colId; // column ID
|
int16_t colId; // column ID
|
||||||
int16_t bytes; // column bytes
|
uint16_t bytes; // column bytes
|
||||||
int16_t offset; // point offset in SDataRow after the header part
|
uint16_t offset; // point offset in SDataRow after the header part.
|
||||||
} STColumn;
|
} STColumn;
|
||||||
|
|
||||||
#define colType(col) ((col)->type)
|
#define colType(col) ((col)->type)
|
||||||
|
|
@ -159,10 +196,11 @@ static FORCE_INLINE int tkeyComparFn(const void *tkey1, const void *tkey2) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------- Data row structure
|
// ----------------- Data row structure
|
||||||
|
|
||||||
/* A data row, the format is like below:
|
/* A data row, the format is like below:
|
||||||
* |<--------------------+--------------------------- len ---------------------------------->|
|
* |<------------------------------------------------ len ---------------------------------->|
|
||||||
* |<-- Head -->|<--------- flen -------------->| |
|
* |<-- Head -->|<--------- flen -------------->| |
|
||||||
* +---------------------+---------------------------------+---------------------------------+
|
* +---------------------+---------------------------------+---------------------------------+
|
||||||
* | uint16_t | int16_t | | |
|
* | uint16_t | int16_t | | |
|
||||||
|
|
@ -176,8 +214,8 @@ typedef void *SDataRow;
|
||||||
|
|
||||||
#define TD_DATA_ROW_HEAD_SIZE (sizeof(uint16_t) + sizeof(int16_t))
|
#define TD_DATA_ROW_HEAD_SIZE (sizeof(uint16_t) + sizeof(int16_t))
|
||||||
|
|
||||||
#define dataRowLen(r) (*(uint16_t *)(r))
|
#define dataRowLen(r) (*(TDRowLenT *)(r)) // 0~65535
|
||||||
#define dataRowVersion(r) *(int16_t *)POINTER_SHIFT(r, sizeof(int16_t))
|
#define dataRowVersion(r) (*(int16_t *)POINTER_SHIFT(r, sizeof(int16_t)))
|
||||||
#define dataRowTuple(r) POINTER_SHIFT(r, TD_DATA_ROW_HEAD_SIZE)
|
#define dataRowTuple(r) POINTER_SHIFT(r, TD_DATA_ROW_HEAD_SIZE)
|
||||||
#define dataRowTKey(r) (*(TKEY *)(dataRowTuple(r)))
|
#define dataRowTKey(r) (*(TKEY *)(dataRowTuple(r)))
|
||||||
#define dataRowKey(r) tdGetKey(dataRowTKey(r))
|
#define dataRowKey(r) tdGetKey(dataRowTKey(r))
|
||||||
|
|
@ -193,20 +231,19 @@ void tdInitDataRow(SDataRow row, STSchema *pSchema);
|
||||||
SDataRow tdDataRowDup(SDataRow row);
|
SDataRow tdDataRowDup(SDataRow row);
|
||||||
|
|
||||||
// offset here not include dataRow header length
|
// offset here not include dataRow header length
|
||||||
static FORCE_INLINE int tdAppendColVal(SDataRow row, void *value, int8_t type, int32_t bytes, int32_t offset) {
|
static FORCE_INLINE int tdAppendColVal(SDataRow row, const void *value, int8_t type, int32_t offset) {
|
||||||
ASSERT(value != NULL);
|
ASSERT(value != NULL);
|
||||||
int32_t toffset = offset + TD_DATA_ROW_HEAD_SIZE;
|
int32_t toffset = offset + TD_DATA_ROW_HEAD_SIZE;
|
||||||
char * ptr = (char *)POINTER_SHIFT(row, dataRowLen(row));
|
|
||||||
|
|
||||||
if (IS_VAR_DATA_TYPE(type)) {
|
if (IS_VAR_DATA_TYPE(type)) {
|
||||||
*(VarDataOffsetT *)POINTER_SHIFT(row, toffset) = dataRowLen(row);
|
*(VarDataOffsetT *)POINTER_SHIFT(row, toffset) = dataRowLen(row);
|
||||||
memcpy(ptr, value, varDataTLen(value));
|
memcpy(POINTER_SHIFT(row, dataRowLen(row)), value, varDataTLen(value));
|
||||||
dataRowLen(row) += varDataTLen(value);
|
dataRowLen(row) += varDataTLen(value);
|
||||||
} else {
|
} else {
|
||||||
if (offset == 0) {
|
if (offset == 0) {
|
||||||
ASSERT(type == TSDB_DATA_TYPE_TIMESTAMP);
|
ASSERT(type == TSDB_DATA_TYPE_TIMESTAMP);
|
||||||
TKEY tvalue = tdGetTKEY(*(TSKEY *)value);
|
TKEY tvalue = tdGetTKEY(*(TSKEY *)value);
|
||||||
memcpy(POINTER_SHIFT(row, toffset), (void *)(&tvalue), TYPE_BYTES[type]);
|
memcpy(POINTER_SHIFT(row, toffset), (const void *)(&tvalue), TYPE_BYTES[type]);
|
||||||
} else {
|
} else {
|
||||||
memcpy(POINTER_SHIFT(row, toffset), value, TYPE_BYTES[type]);
|
memcpy(POINTER_SHIFT(row, toffset), value, TYPE_BYTES[type]);
|
||||||
}
|
}
|
||||||
|
|
@ -237,17 +274,21 @@ typedef struct SDataCol {
|
||||||
TSKEY ts; // only used in last NULL column
|
TSKEY ts; // only used in last NULL column
|
||||||
} SDataCol;
|
} SDataCol;
|
||||||
|
|
||||||
|
#define isAllRowsNull(pCol) ((pCol)->len == 0)
|
||||||
static FORCE_INLINE void dataColReset(SDataCol *pDataCol) { pDataCol->len = 0; }
|
static FORCE_INLINE void dataColReset(SDataCol *pDataCol) { pDataCol->len = 0; }
|
||||||
|
|
||||||
void dataColInit(SDataCol *pDataCol, STColumn *pCol, void **pBuf, int maxPoints);
|
void dataColInit(SDataCol *pDataCol, STColumn *pCol, void **pBuf, int maxPoints);
|
||||||
void dataColAppendVal(SDataCol *pCol, void *value, int numOfRows, int maxPoints);
|
void dataColAppendVal(SDataCol *pCol, const void *value, int numOfRows, int maxPoints);
|
||||||
void dataColSetOffset(SDataCol *pCol, int nEle);
|
void dataColSetOffset(SDataCol *pCol, int nEle);
|
||||||
|
|
||||||
bool isNEleNull(SDataCol *pCol, int nEle);
|
bool isNEleNull(SDataCol *pCol, int nEle);
|
||||||
void dataColSetNEleNull(SDataCol *pCol, int nEle, int maxPoints);
|
void dataColSetNEleNull(SDataCol *pCol, int nEle, int maxPoints);
|
||||||
|
|
||||||
// Get the data pointer from a column-wised data
|
// Get the data pointer from a column-wised data
|
||||||
static FORCE_INLINE void *tdGetColDataOfRow(SDataCol *pCol, int row) {
|
static FORCE_INLINE const void *tdGetColDataOfRow(SDataCol *pCol, int row) {
|
||||||
|
if (isAllRowsNull(pCol)) {
|
||||||
|
return tdGetNullVal(pCol->type);
|
||||||
|
}
|
||||||
if (IS_VAR_DATA_TYPE(pCol->type)) {
|
if (IS_VAR_DATA_TYPE(pCol->type)) {
|
||||||
return POINTER_SHIFT(pCol->pData, pCol->dataOff[row]);
|
return POINTER_SHIFT(pCol->pData, pCol->dataOff[row]);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -279,7 +320,7 @@ typedef struct {
|
||||||
} SDataCols;
|
} SDataCols;
|
||||||
|
|
||||||
#define keyCol(pCols) (&((pCols)->cols[0])) // Key column
|
#define keyCol(pCols) (&((pCols)->cols[0])) // Key column
|
||||||
#define dataColsTKeyAt(pCols, idx) ((TKEY *)(keyCol(pCols)->pData))[(idx)]
|
#define dataColsTKeyAt(pCols, idx) ((TKEY *)(keyCol(pCols)->pData))[(idx)] // the idx row of column-wised data
|
||||||
#define dataColsKeyAt(pCols, idx) tdGetKey(dataColsTKeyAt(pCols, idx))
|
#define dataColsKeyAt(pCols, idx) tdGetKey(dataColsTKeyAt(pCols, idx))
|
||||||
static FORCE_INLINE TKEY dataColsTKeyFirst(SDataCols *pCols) {
|
static FORCE_INLINE TKEY dataColsTKeyFirst(SDataCols *pCols) {
|
||||||
if (pCols->numOfRows) {
|
if (pCols->numOfRows) {
|
||||||
|
|
@ -323,13 +364,13 @@ void tdResetDataCols(SDataCols *pCols);
|
||||||
int tdInitDataCols(SDataCols *pCols, STSchema *pSchema);
|
int tdInitDataCols(SDataCols *pCols, STSchema *pSchema);
|
||||||
SDataCols *tdDupDataCols(SDataCols *pCols, bool keepData);
|
SDataCols *tdDupDataCols(SDataCols *pCols, bool keepData);
|
||||||
SDataCols *tdFreeDataCols(SDataCols *pCols);
|
SDataCols *tdFreeDataCols(SDataCols *pCols);
|
||||||
void tdAppendDataRowToDataCol(SDataRow row, STSchema *pSchema, SDataCols *pCols);
|
|
||||||
int tdMergeDataCols(SDataCols *target, SDataCols *source, int rowsToMerge, int *pOffset);
|
int tdMergeDataCols(SDataCols *target, SDataCols *source, int rowsToMerge, int *pOffset);
|
||||||
|
|
||||||
// ----------------- K-V data row structure
|
// ----------------- K-V data row structure
|
||||||
/*
|
/* |<-------------------------------------- len -------------------------------------------->|
|
||||||
|
* |<----- header ----->|<--------------------------- body -------------------------------->|
|
||||||
* +----------+----------+---------------------------------+---------------------------------+
|
* +----------+----------+---------------------------------+---------------------------------+
|
||||||
* | int16_t | int16_t | | |
|
* | uint16_t | int16_t | | |
|
||||||
* +----------+----------+---------------------------------+---------------------------------+
|
* +----------+----------+---------------------------------+---------------------------------+
|
||||||
* | len | ncols | cols index | data part |
|
* | len | ncols | cols index | data part |
|
||||||
* +----------+----------+---------------------------------+---------------------------------+
|
* +----------+----------+---------------------------------+---------------------------------+
|
||||||
|
|
@ -338,13 +379,13 @@ typedef void *SKVRow;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int16_t colId;
|
int16_t colId;
|
||||||
int16_t offset;
|
uint16_t offset;
|
||||||
} SColIdx;
|
} SColIdx;
|
||||||
|
|
||||||
#define TD_KV_ROW_HEAD_SIZE (2 * sizeof(int16_t))
|
#define TD_KV_ROW_HEAD_SIZE (sizeof(uint16_t) + sizeof(int16_t))
|
||||||
|
|
||||||
#define kvRowLen(r) (*(int16_t *)(r))
|
#define kvRowLen(r) (*(TDRowLenT *)(r))
|
||||||
#define kvRowNCols(r) (*(int16_t *)POINTER_SHIFT(r, sizeof(int16_t)))
|
#define kvRowNCols(r) (*(int16_t *)POINTER_SHIFT(r, sizeof(uint16_t)))
|
||||||
#define kvRowSetLen(r, len) kvRowLen(r) = (len)
|
#define kvRowSetLen(r, len) kvRowLen(r) = (len)
|
||||||
#define kvRowSetNCols(r, n) kvRowNCols(r) = (n)
|
#define kvRowSetNCols(r, n) kvRowNCols(r) = (n)
|
||||||
#define kvRowColIdx(r) (SColIdx *)POINTER_SHIFT(r, TD_KV_ROW_HEAD_SIZE)
|
#define kvRowColIdx(r) (SColIdx *)POINTER_SHIFT(r, TD_KV_ROW_HEAD_SIZE)
|
||||||
|
|
@ -354,6 +395,9 @@ typedef struct {
|
||||||
#define kvRowColIdxAt(r, i) (kvRowColIdx(r) + (i))
|
#define kvRowColIdxAt(r, i) (kvRowColIdx(r) + (i))
|
||||||
#define kvRowFree(r) tfree(r)
|
#define kvRowFree(r) tfree(r)
|
||||||
#define kvRowEnd(r) POINTER_SHIFT(r, kvRowLen(r))
|
#define kvRowEnd(r) POINTER_SHIFT(r, kvRowLen(r))
|
||||||
|
#define kvRowTKey(r) (*(TKEY *)(kvRowValues(r)))
|
||||||
|
#define kvRowKey(r) tdGetKey(kvRowTKey(r))
|
||||||
|
#define kvRowDeleted(r) TKEY_IS_DELETED(kvRowTKey(r))
|
||||||
|
|
||||||
SKVRow tdKVRowDup(SKVRow row);
|
SKVRow tdKVRowDup(SKVRow row);
|
||||||
int tdSetKVRowDataOfCol(SKVRow *orow, int16_t colId, int8_t type, void *value);
|
int tdSetKVRowDataOfCol(SKVRow *orow, int16_t colId, int8_t type, void *value);
|
||||||
|
|
@ -377,13 +421,44 @@ static FORCE_INLINE void *tdGetKVRowValOfCol(SKVRow row, int16_t colId) {
|
||||||
return kvRowColVal(row, (SColIdx *)ret);
|
return kvRowColVal(row, (SColIdx *)ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static FORCE_INLINE void *tdGetKVRowIdxOfCol(SKVRow row, int16_t colId) {
|
||||||
|
return taosbsearch(&colId, kvRowColIdx(row), kvRowNCols(row), sizeof(SColIdx), comparTagId, TD_EQ);
|
||||||
|
}
|
||||||
|
|
||||||
|
// offset here not include kvRow header length
|
||||||
|
static FORCE_INLINE int tdAppendKvColVal(SKVRow row, const void *value, int16_t colId, int8_t type, int32_t offset) {
|
||||||
|
ASSERT(value != NULL);
|
||||||
|
int32_t toffset = offset + TD_KV_ROW_HEAD_SIZE;
|
||||||
|
SColIdx *pColIdx = (SColIdx *)POINTER_SHIFT(row, toffset);
|
||||||
|
char * ptr = (char *)POINTER_SHIFT(row, kvRowLen(row));
|
||||||
|
|
||||||
|
pColIdx->colId = colId;
|
||||||
|
pColIdx->offset = kvRowLen(row); // offset of pColIdx including the TD_KV_ROW_HEAD_SIZE
|
||||||
|
|
||||||
|
if (IS_VAR_DATA_TYPE(type)) {
|
||||||
|
memcpy(ptr, value, varDataTLen(value));
|
||||||
|
kvRowLen(row) += varDataTLen(value);
|
||||||
|
} else {
|
||||||
|
if (offset == 0) {
|
||||||
|
ASSERT(type == TSDB_DATA_TYPE_TIMESTAMP);
|
||||||
|
TKEY tvalue = tdGetTKEY(*(TSKEY *)value);
|
||||||
|
memcpy(ptr, (void *)(&tvalue), TYPE_BYTES[type]);
|
||||||
|
} else {
|
||||||
|
memcpy(ptr, value, TYPE_BYTES[type]);
|
||||||
|
}
|
||||||
|
kvRowLen(row) += TYPE_BYTES[type];
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------- K-V data row builder
|
// ----------------- K-V data row builder
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int16_t tCols;
|
int16_t tCols;
|
||||||
int16_t nCols;
|
int16_t nCols;
|
||||||
SColIdx *pColIdx;
|
SColIdx *pColIdx;
|
||||||
int16_t alloc;
|
uint16_t alloc;
|
||||||
int16_t size;
|
uint16_t size;
|
||||||
void * buf;
|
void * buf;
|
||||||
} SKVRowBuilder;
|
} SKVRowBuilder;
|
||||||
|
|
||||||
|
|
@ -419,6 +494,144 @@ static FORCE_INLINE int tdAddColToKVRow(SKVRowBuilder *pBuilder, int16_t colId,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------- SMemRow appended with sequential data row structure
|
||||||
|
/*
|
||||||
|
* |---------|------------------------------------------------- len ---------------------------------->|
|
||||||
|
* |<-------- Head ------>|<--------- flen -------------->| |
|
||||||
|
* |---------+---------------------+---------------------------------+---------------------------------+
|
||||||
|
* | uint8_t | uint16_t | int16_t | | |
|
||||||
|
* |---------+----------+----------+---------------------------------+---------------------------------+
|
||||||
|
* | flag | len | sversion | First part | Second part |
|
||||||
|
* +---------+----------+----------+---------------------------------+---------------------------------+
|
||||||
|
*
|
||||||
|
* NOTE: timestamp in this row structure is TKEY instead of TSKEY
|
||||||
|
*/
|
||||||
|
|
||||||
|
// ----------------- SMemRow appended with extended K-V data row structure
|
||||||
|
/* |--------------------|------------------------------------------------ len ---------------------------------->|
|
||||||
|
* |<------------- Head ------------>|<--------- flen -------------->| |
|
||||||
|
* |--------------------+----------+--------------------------------------------+---------------------------------+
|
||||||
|
* | uint8_t | int16_t | uint16_t | int16_t | | |
|
||||||
|
* |---------+----------+----------+----------+---------------------------------+---------------------------------+
|
||||||
|
* | flag | sversion | len | ncols | cols index | data part |
|
||||||
|
* |---------+----------+----------+----------+---------------------------------+---------------------------------+
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef void *SMemRow;
|
||||||
|
|
||||||
|
#define TD_MEM_ROW_TYPE_SIZE sizeof(uint8_t)
|
||||||
|
#define TD_MEM_ROW_KV_VER_SIZE sizeof(int16_t)
|
||||||
|
#define TD_MEM_ROW_KV_TYPE_VER_SIZE (TD_MEM_ROW_TYPE_SIZE + TD_MEM_ROW_KV_VER_SIZE)
|
||||||
|
#define TD_MEM_ROW_DATA_HEAD_SIZE (TD_MEM_ROW_TYPE_SIZE + TD_DATA_ROW_HEAD_SIZE)
|
||||||
|
// #define TD_MEM_ROW_KV_HEAD_SIZE (TD_MEM_ROW_TYPE_SIZE + TD_MEM_ROW_KV_VER_SIZE + TD_KV_ROW_HEAD_SIZE)
|
||||||
|
|
||||||
|
#define SMEM_ROW_DATA 0U // SDataRow
|
||||||
|
#define SMEM_ROW_KV 1U // SKVRow
|
||||||
|
|
||||||
|
#define memRowType(r) (*(uint8_t *)(r))
|
||||||
|
#define isDataRow(r) (SMEM_ROW_DATA == memRowType(r))
|
||||||
|
#define isKvRow(r) (SMEM_ROW_KV == memRowType(r))
|
||||||
|
|
||||||
|
#define memRowDataBody(r) POINTER_SHIFT(r, TD_MEM_ROW_TYPE_SIZE) // section after flag
|
||||||
|
#define memRowKvBody(r) \
|
||||||
|
POINTER_SHIFT(r, TD_MEM_ROW_KV_TYPE_VER_SIZE) // section after flag + sversion as to reuse SKVRow
|
||||||
|
|
||||||
|
#define memRowDataLen(r) (*(TDRowLenT *)memRowDataBody(r)) // 0~65535
|
||||||
|
#define memRowKvLen(r) (*(TDRowLenT *)memRowKvBody(r)) // 0~65535
|
||||||
|
|
||||||
|
#define memRowDataTLen(r) \
|
||||||
|
((TDRowTLenT)(memRowDataLen(r) + TD_MEM_ROW_TYPE_SIZE)) // using uint32_t/int32_t to store the TLen
|
||||||
|
|
||||||
|
#define memRowKvTLen(r) ((TDRowTLenT)(memRowKvLen(r) + TD_MEM_ROW_KV_TYPE_VER_SIZE))
|
||||||
|
|
||||||
|
#define memRowLen(r) (isDataRow(r) ? memRowDataLen(r) : memRowKvLen(r))
|
||||||
|
#define memRowTLen(r) (isDataRow(r) ? memRowDataTLen(r) : memRowKvTLen(r)) // using uint32_t/int32_t to store the TLen
|
||||||
|
|
||||||
|
#define memRowDataVersion(r) dataRowVersion(memRowDataBody(r))
|
||||||
|
#define memRowKvVersion(r) (*(int16_t *)POINTER_SHIFT(r, TD_MEM_ROW_TYPE_SIZE))
|
||||||
|
#define memRowVersion(r) (isDataRow(r) ? memRowDataVersion(r) : memRowKvVersion(r)) // schema version
|
||||||
|
#define memRowSetKvVersion(r, v) (memRowKvVersion(r) = (v))
|
||||||
|
#define memRowTuple(r) (isDataRow(r) ? dataRowTuple(memRowDataBody(r)) : kvRowValues(memRowKvBody(r)))
|
||||||
|
|
||||||
|
#define memRowTKey(r) (isDataRow(r) ? dataRowTKey(memRowDataBody(r)) : kvRowTKey(memRowKvBody(r)))
|
||||||
|
#define memRowKey(r) (isDataRow(r) ? dataRowKey(memRowDataBody(r)) : kvRowKey(memRowKvBody(r)))
|
||||||
|
#define memRowSetTKey(r, k) \
|
||||||
|
do { \
|
||||||
|
if (isDataRow(r)) { \
|
||||||
|
dataRowTKey(memRowDataBody(r)) = (k); \
|
||||||
|
} else { \
|
||||||
|
kvRowTKey(memRowKvBody(r)) = (k); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define memRowSetType(r, t) (memRowType(r) = (t))
|
||||||
|
#define memRowSetLen(r, l) (isDataRow(r) ? memRowDataLen(r) = (l) : memRowKvLen(r) = (l))
|
||||||
|
#define memRowSetVersion(r, v) (isDataRow(r) ? dataRowSetVersion(memRowDataBody(r), v) : memRowKvSetVersion(r, v))
|
||||||
|
#define memRowCpy(dst, r) memcpy((dst), (r), memRowTLen(r))
|
||||||
|
#define memRowMaxBytesFromSchema(s) (schemaTLen(s) + TD_MEM_ROW_DATA_HEAD_SIZE)
|
||||||
|
#define memRowDeleted(r) TKEY_IS_DELETED(memRowTKey(r))
|
||||||
|
|
||||||
|
SMemRow tdMemRowDup(SMemRow row);
|
||||||
|
void tdAppendMemRowToDataCol(SMemRow row, STSchema *pSchema, SDataCols *pCols);
|
||||||
|
// NOTE: offset here including the header size
|
||||||
|
static FORCE_INLINE void *tdGetKvRowDataOfCol(void *row, int32_t offset) { return POINTER_SHIFT(row, offset); }
|
||||||
|
// NOTE: offset here including the header size
|
||||||
|
static FORCE_INLINE void *tdGetMemRowDataOfCol(void *row, int8_t type, int32_t offset) {
|
||||||
|
if (isDataRow(row)) {
|
||||||
|
return tdGetRowDataOfCol(row, type, offset);
|
||||||
|
} else if (isKvRow(row)) {
|
||||||
|
return tdGetKvRowDataOfCol(row, offset);
|
||||||
|
} else {
|
||||||
|
ASSERT(0);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------- Raw payload structure for row:
|
||||||
|
/* |<------------ Head ------------->|<----------- body of column data tuple ------------------->|
|
||||||
|
* | |<----------------- flen ------------->|<--- value part --->|
|
||||||
|
* |SMemRowType| dataTLen | nCols | colId | colType | offset | ... | value |...|...|... |
|
||||||
|
* +-----------+----------+----------+--------------------------------------|--------------------|
|
||||||
|
* | uint8_t | uint32_t | uint16_t | int16_t | uint8_t | uint16_t | ... |.......|...|...|... |
|
||||||
|
* +-----------+----------+----------+--------------------------------------+--------------------|
|
||||||
|
* 1. offset in column data tuple starts from the value part in case of uint16_t overflow.
|
||||||
|
* 2. dataTLen: total length including the header and body.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define PAYLOAD_NCOLS_LEN sizeof(uint16_t)
|
||||||
|
#define PAYLOAD_NCOLS_OFFSET (sizeof(uint8_t) + sizeof(TDRowTLenT))
|
||||||
|
#define PAYLOAD_HEADER_LEN (PAYLOAD_NCOLS_OFFSET + PAYLOAD_NCOLS_LEN)
|
||||||
|
#define PAYLOAD_ID_LEN sizeof(int16_t)
|
||||||
|
#define PAYLOAD_ID_TYPE_LEN (sizeof(int16_t) + sizeof(uint8_t))
|
||||||
|
#define PAYLOAD_COL_HEAD_LEN (PAYLOAD_ID_TYPE_LEN + sizeof(uint16_t))
|
||||||
|
#define PAYLOAD_PRIMARY_COL_LEN (PAYLOAD_ID_TYPE_LEN + sizeof(TSKEY))
|
||||||
|
|
||||||
|
#define payloadBody(r) POINTER_SHIFT(r, PAYLOAD_HEADER_LEN)
|
||||||
|
#define payloadType(r) (*(uint8_t *)(r))
|
||||||
|
#define payloadSetType(r, t) (payloadType(r) = (t))
|
||||||
|
#define payloadTLen(r) (*(TDRowTLenT *)POINTER_SHIFT(r, TD_MEM_ROW_TYPE_SIZE)) // including total header
|
||||||
|
#define payloadSetTLen(r, l) (payloadTLen(r) = (l))
|
||||||
|
#define payloadNCols(r) (*(TDRowLenT *)POINTER_SHIFT(r, PAYLOAD_NCOLS_OFFSET))
|
||||||
|
#define payloadSetNCols(r, n) (payloadNCols(r) = (n))
|
||||||
|
#define payloadValuesOffset(r) \
|
||||||
|
(PAYLOAD_HEADER_LEN + payloadNCols(r) * PAYLOAD_COL_HEAD_LEN) // avoid using the macro in loop
|
||||||
|
#define payloadValues(r) POINTER_SHIFT(r, payloadValuesOffset(r)) // avoid using the macro in loop
|
||||||
|
#define payloadColId(c) (*(int16_t *)(c))
|
||||||
|
#define payloadColType(c) (*(uint8_t *)POINTER_SHIFT(c, PAYLOAD_ID_LEN))
|
||||||
|
#define payloadColOffset(c) (*(uint16_t *)POINTER_SHIFT(c, PAYLOAD_ID_TYPE_LEN))
|
||||||
|
#define payloadColValue(c) POINTER_SHIFT(c, payloadColOffset(c))
|
||||||
|
|
||||||
|
#define payloadColSetId(c, i) (payloadColId(c) = (i))
|
||||||
|
#define payloadColSetType(c, t) (payloadColType(c) = (t))
|
||||||
|
#define payloadColSetOffset(c, o) (payloadColOffset(c) = (o))
|
||||||
|
|
||||||
|
#define payloadTSKey(r) (*(TSKEY *)POINTER_SHIFT(r, payloadValuesOffset(r)))
|
||||||
|
#define payloadTKey(r) (*(TKEY *)POINTER_SHIFT(r, payloadValuesOffset(r)))
|
||||||
|
#define payloadKey(r) tdGetKey(payloadTKey(r))
|
||||||
|
|
||||||
|
|
||||||
|
static FORCE_INLINE char *payloadNextCol(char *pCol) { return (char *)POINTER_SHIFT(pCol, PAYLOAD_COL_HEAD_LEN); }
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,21 @@
|
||||||
#include "tcoding.h"
|
#include "tcoding.h"
|
||||||
#include "wchar.h"
|
#include "wchar.h"
|
||||||
|
|
||||||
|
const uint8_t BoolNull = TSDB_DATA_BOOL_NULL;
|
||||||
|
const uint8_t TinyintNull = TSDB_DATA_TINYINT_NULL;
|
||||||
|
const uint16_t SmallintNull = TSDB_DATA_SMALLINT_NULL;
|
||||||
|
const uint32_t IntNull = TSDB_DATA_INT_NULL;
|
||||||
|
const uint64_t BigintNull = TSDB_DATA_BIGINT_NULL;
|
||||||
|
const uint64_t TimestampNull = TSDB_DATA_BIGINT_NULL;
|
||||||
|
const uint8_t UTinyintNull = TSDB_DATA_UTINYINT_NULL;
|
||||||
|
const uint16_t USmallintNull = TSDB_DATA_USMALLINT_NULL;
|
||||||
|
const uint32_t UIntNull = TSDB_DATA_UINT_NULL;
|
||||||
|
const uint64_t UBigintNull = TSDB_DATA_UBIGINT_NULL;
|
||||||
|
const uint32_t FloatNull = TSDB_DATA_FLOAT_NULL;
|
||||||
|
const uint64_t DoubleNull = TSDB_DATA_DOUBLE_NULL;
|
||||||
|
const SBinaryNullT BinaryNull = {1, TSDB_DATA_BINARY_NULL};
|
||||||
|
const SNCharNullT NcharNull = {4, TSDB_DATA_NCHAR_NULL};
|
||||||
|
|
||||||
static void tdMergeTwoDataCols(SDataCols *target, SDataCols *src1, int *iter1, int limit1, SDataCols *src2, int *iter2,
|
static void tdMergeTwoDataCols(SDataCols *target, SDataCols *src1, int *iter1, int limit1, SDataCols *src2, int *iter2,
|
||||||
int limit2, int tRows);
|
int limit2, int tRows);
|
||||||
|
|
||||||
|
|
@ -198,6 +213,14 @@ SDataRow tdDataRowDup(SDataRow row) {
|
||||||
return trow;
|
return trow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SMemRow tdMemRowDup(SMemRow row) {
|
||||||
|
SMemRow trow = malloc(memRowTLen(row));
|
||||||
|
if (trow == NULL) return NULL;
|
||||||
|
|
||||||
|
memRowCpy(trow, row);
|
||||||
|
return trow;
|
||||||
|
}
|
||||||
|
|
||||||
void dataColInit(SDataCol *pDataCol, STColumn *pCol, void **pBuf, int maxPoints) {
|
void dataColInit(SDataCol *pDataCol, STColumn *pCol, void **pBuf, int maxPoints) {
|
||||||
pDataCol->type = colType(pCol);
|
pDataCol->type = colType(pCol);
|
||||||
pDataCol->colId = colColId(pCol);
|
pDataCol->colId = colColId(pCol);
|
||||||
|
|
@ -217,11 +240,22 @@ void dataColInit(SDataCol *pDataCol, STColumn *pCol, void **pBuf, int maxPoints)
|
||||||
*pBuf = POINTER_SHIFT(*pBuf, pDataCol->spaceSize);
|
*pBuf = POINTER_SHIFT(*pBuf, pDataCol->spaceSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// value from timestamp should be TKEY here instead of TSKEY
|
// value from timestamp should be TKEY here instead of TSKEY
|
||||||
void dataColAppendVal(SDataCol *pCol, void *value, int numOfRows, int maxPoints) {
|
void dataColAppendVal(SDataCol *pCol, const void *value, int numOfRows, int maxPoints) {
|
||||||
ASSERT(pCol != NULL && value != NULL);
|
ASSERT(pCol != NULL && value != NULL);
|
||||||
|
|
||||||
|
if (isAllRowsNull(pCol)) {
|
||||||
|
if (isNull(value, pCol->type)) {
|
||||||
|
// all null value yet, just return
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numOfRows > 0) {
|
||||||
|
// Find the first not null value, fill all previouse values as NULL
|
||||||
|
dataColSetNEleNull(pCol, numOfRows, maxPoints);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (IS_VAR_DATA_TYPE(pCol->type)) {
|
if (IS_VAR_DATA_TYPE(pCol->type)) {
|
||||||
// set offset
|
// set offset
|
||||||
pCol->dataOff[numOfRows] = pCol->len;
|
pCol->dataOff[numOfRows] = pCol->len;
|
||||||
|
|
@ -243,7 +277,7 @@ bool isNEleNull(SDataCol *pCol, int nEle) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dataColSetNullAt(SDataCol *pCol, int index) {
|
FORCE_INLINE void dataColSetNullAt(SDataCol *pCol, int index) {
|
||||||
if (IS_VAR_DATA_TYPE(pCol->type)) {
|
if (IS_VAR_DATA_TYPE(pCol->type)) {
|
||||||
pCol->dataOff[index] = pCol->len;
|
pCol->dataOff[index] = pCol->len;
|
||||||
char *ptr = POINTER_SHIFT(pCol->pData, pCol->len);
|
char *ptr = POINTER_SHIFT(pCol->pData, pCol->len);
|
||||||
|
|
@ -399,8 +433,7 @@ void tdResetDataCols(SDataCols *pCols) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
static void tdAppendDataRowToDataCol(SDataRow row, STSchema *pSchema, SDataCols *pCols) {
|
||||||
void tdAppendDataRowToDataCol(SDataRow row, STSchema *pSchema, SDataCols *pCols) {
|
|
||||||
ASSERT(pCols->numOfRows == 0 || dataColsKeyLast(pCols) < dataRowKey(row));
|
ASSERT(pCols->numOfRows == 0 || dataColsKeyLast(pCols) < dataRowKey(row));
|
||||||
|
|
||||||
int rcol = 0;
|
int rcol = 0;
|
||||||
|
|
@ -419,7 +452,8 @@ void tdAppendDataRowToDataCol(SDataRow row, STSchema *pSchema, SDataCols *pCols)
|
||||||
while (dcol < pCols->numOfCols) {
|
while (dcol < pCols->numOfCols) {
|
||||||
SDataCol *pDataCol = &(pCols->cols[dcol]);
|
SDataCol *pDataCol = &(pCols->cols[dcol]);
|
||||||
if (rcol >= schemaNCols(pSchema)) {
|
if (rcol >= schemaNCols(pSchema)) {
|
||||||
dataColSetNullAt(pDataCol, pCols->numOfRows);
|
// dataColSetNullAt(pDataCol, pCols->numOfRows);
|
||||||
|
dataColAppendVal(pDataCol, tdGetNullVal(pDataCol->type), pCols->numOfRows, pCols->maxPoints);
|
||||||
dcol++;
|
dcol++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -433,7 +467,8 @@ void tdAppendDataRowToDataCol(SDataRow row, STSchema *pSchema, SDataCols *pCols)
|
||||||
} else if (pRowCol->colId < pDataCol->colId) {
|
} else if (pRowCol->colId < pDataCol->colId) {
|
||||||
rcol++;
|
rcol++;
|
||||||
} else {
|
} else {
|
||||||
dataColSetNullAt(pDataCol, pCols->numOfRows);
|
// dataColSetNullAt(pDataCol, pCols->numOfRows);
|
||||||
|
dataColAppendVal(pDataCol, tdGetNullVal(pDataCol->type), pCols->numOfRows, pCols->maxPoints);
|
||||||
dcol++;
|
dcol++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -441,6 +476,62 @@ void tdAppendDataRowToDataCol(SDataRow row, STSchema *pSchema, SDataCols *pCols)
|
||||||
pCols->numOfRows++;
|
pCols->numOfRows++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void tdAppendKvRowToDataCol(SKVRow row, STSchema *pSchema, SDataCols *pCols) {
|
||||||
|
ASSERT(pCols->numOfRows == 0 || dataColsKeyLast(pCols) < kvRowKey(row));
|
||||||
|
|
||||||
|
int rcol = 0;
|
||||||
|
int dcol = 0;
|
||||||
|
|
||||||
|
if (kvRowDeleted(row)) {
|
||||||
|
for (; dcol < pCols->numOfCols; dcol++) {
|
||||||
|
SDataCol *pDataCol = &(pCols->cols[dcol]);
|
||||||
|
if (dcol == 0) {
|
||||||
|
dataColAppendVal(pDataCol, kvRowValues(row), pCols->numOfRows, pCols->maxPoints);
|
||||||
|
} else {
|
||||||
|
dataColSetNullAt(pDataCol, pCols->numOfRows);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int nRowCols = kvRowNCols(row);
|
||||||
|
|
||||||
|
while (dcol < pCols->numOfCols) {
|
||||||
|
SDataCol *pDataCol = &(pCols->cols[dcol]);
|
||||||
|
if (rcol >= nRowCols || rcol >= schemaNCols(pSchema)) {
|
||||||
|
// dataColSetNullAt(pDataCol, pCols->numOfRows);
|
||||||
|
dataColAppendVal(pDataCol, tdGetNullVal(pDataCol->type), pCols->numOfRows, pCols->maxPoints);
|
||||||
|
++dcol;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
SColIdx *colIdx = kvRowColIdxAt(row, rcol);
|
||||||
|
|
||||||
|
if (colIdx->colId == pDataCol->colId) {
|
||||||
|
void *value = tdGetKvRowDataOfCol(row, colIdx->offset);
|
||||||
|
dataColAppendVal(pDataCol, value, pCols->numOfRows, pCols->maxPoints);
|
||||||
|
++dcol;
|
||||||
|
++rcol;
|
||||||
|
} else if (colIdx->colId < pDataCol->colId) {
|
||||||
|
++rcol;
|
||||||
|
} else {
|
||||||
|
// dataColSetNullAt(pDataCol, pCols->numOfRows);
|
||||||
|
dataColAppendVal(pDataCol, tdGetNullVal(pDataCol->type), pCols->numOfRows, pCols->maxPoints);
|
||||||
|
++dcol;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pCols->numOfRows++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tdAppendMemRowToDataCol(SMemRow row, STSchema *pSchema, SDataCols *pCols) {
|
||||||
|
if (isDataRow(row)) {
|
||||||
|
tdAppendDataRowToDataCol(memRowDataBody(row), pSchema, pCols);
|
||||||
|
} else if (isKvRow(row)) {
|
||||||
|
tdAppendKvRowToDataCol(memRowKvBody(row), pSchema, pCols);
|
||||||
|
} else {
|
||||||
|
ASSERT(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int tdMergeDataCols(SDataCols *target, SDataCols *source, int rowsToMerge, int *pOffset) {
|
int tdMergeDataCols(SDataCols *target, SDataCols *source, int rowsToMerge, int *pOffset) {
|
||||||
ASSERT(rowsToMerge > 0 && rowsToMerge <= source->numOfRows);
|
ASSERT(rowsToMerge > 0 && rowsToMerge <= source->numOfRows);
|
||||||
ASSERT(target->numOfCols == source->numOfCols);
|
ASSERT(target->numOfCols == source->numOfCols);
|
||||||
|
|
@ -563,7 +654,7 @@ int tdSetKVRowDataOfCol(SKVRow *orow, int16_t colId, int8_t type, void *value) {
|
||||||
nrow = malloc(kvRowLen(row) + sizeof(SColIdx) + diff);
|
nrow = malloc(kvRowLen(row) + sizeof(SColIdx) + diff);
|
||||||
if (nrow == NULL) return -1;
|
if (nrow == NULL) return -1;
|
||||||
|
|
||||||
kvRowSetLen(nrow, kvRowLen(row) + (int16_t)sizeof(SColIdx) + diff);
|
kvRowSetLen(nrow, kvRowLen(row) + (uint16_t)sizeof(SColIdx) + diff);
|
||||||
kvRowSetNCols(nrow, kvRowNCols(row) + 1);
|
kvRowSetNCols(nrow, kvRowNCols(row) + 1);
|
||||||
|
|
||||||
if (ptr == NULL) {
|
if (ptr == NULL) {
|
||||||
|
|
@ -605,8 +696,8 @@ int tdSetKVRowDataOfCol(SKVRow *orow, int16_t colId, int8_t type, void *value) {
|
||||||
if (varDataTLen(value) == varDataTLen(pOldVal)) { // just update the column value in place
|
if (varDataTLen(value) == varDataTLen(pOldVal)) { // just update the column value in place
|
||||||
memcpy(pOldVal, value, varDataTLen(value));
|
memcpy(pOldVal, value, varDataTLen(value));
|
||||||
} else { // need to reallocate the memory
|
} else { // need to reallocate the memory
|
||||||
int16_t diff = varDataTLen(value) - varDataTLen(pOldVal);
|
uint16_t diff = varDataTLen(value) - varDataTLen(pOldVal);
|
||||||
int16_t nlen = kvRowLen(row) + diff;
|
uint16_t nlen = kvRowLen(row) + diff;
|
||||||
ASSERT(nlen > 0);
|
ASSERT(nlen > 0);
|
||||||
nrow = malloc(nlen);
|
nrow = malloc(nlen);
|
||||||
if (nrow == NULL) return -1;
|
if (nrow == NULL) return -1;
|
||||||
|
|
@ -709,3 +800,39 @@ SKVRow tdGetKVRowFromBuilder(SKVRowBuilder *pBuilder) {
|
||||||
|
|
||||||
return row;
|
return row;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const void *tdGetNullVal(int8_t type) {
|
||||||
|
switch (type) {
|
||||||
|
case TSDB_DATA_TYPE_BOOL:
|
||||||
|
return &BoolNull;
|
||||||
|
case TSDB_DATA_TYPE_TINYINT:
|
||||||
|
return &TinyintNull;
|
||||||
|
case TSDB_DATA_TYPE_SMALLINT:
|
||||||
|
return &SmallintNull;
|
||||||
|
case TSDB_DATA_TYPE_INT:
|
||||||
|
return &IntNull;
|
||||||
|
case TSDB_DATA_TYPE_BIGINT:
|
||||||
|
return &BigintNull;
|
||||||
|
case TSDB_DATA_TYPE_FLOAT:
|
||||||
|
return &FloatNull;
|
||||||
|
case TSDB_DATA_TYPE_DOUBLE:
|
||||||
|
return &DoubleNull;
|
||||||
|
case TSDB_DATA_TYPE_BINARY:
|
||||||
|
return &BinaryNull;
|
||||||
|
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||||
|
return &TimestampNull;
|
||||||
|
case TSDB_DATA_TYPE_NCHAR:
|
||||||
|
return &NcharNull;
|
||||||
|
case TSDB_DATA_TYPE_UTINYINT:
|
||||||
|
return &UTinyintNull;
|
||||||
|
case TSDB_DATA_TYPE_USMALLINT:
|
||||||
|
return &USmallintNull;
|
||||||
|
case TSDB_DATA_TYPE_UINT:
|
||||||
|
return &UIntNull;
|
||||||
|
case TSDB_DATA_TYPE_UBIGINT:
|
||||||
|
return &UBigintNull;
|
||||||
|
default:
|
||||||
|
ASSERT(0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -19,6 +19,7 @@ import com.taosdata.jdbc.utils.NullType;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
|
import java.time.Instant;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
|
|
@ -463,6 +464,25 @@ public class TSDBResultSetRowData {
|
||||||
data.set(col, tsObj);
|
data.set(col, tsObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this implementation is used for TDengine old version
|
||||||
|
*/
|
||||||
|
public void setTimestamp(int col, long ts) {
|
||||||
|
//TODO: this implementation contains logical error
|
||||||
|
// when precision is us the (long ts) is 16 digital number
|
||||||
|
// when precision is ms, the (long ts) is 13 digital number
|
||||||
|
// we need a JNI function like this:
|
||||||
|
// public void setTimestamp(int col, long epochSecond, long nanoAdjustment)
|
||||||
|
if (ts < 1_0000_0000_0000_0L) {
|
||||||
|
data.set(col, new Timestamp(ts));
|
||||||
|
} else {
|
||||||
|
long epochSec = ts / 1000_000L;
|
||||||
|
long nanoAdjustment = ts % 1000_000L * 1000L;
|
||||||
|
Timestamp timestamp = Timestamp.from(Instant.ofEpochSecond(epochSec, nanoAdjustment));
|
||||||
|
data.set(col, timestamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Timestamp getTimestamp(int col, int nativeType) {
|
public Timestamp getTimestamp(int col, int nativeType) {
|
||||||
Object obj = data.get(col - 1);
|
Object obj = data.get(col - 1);
|
||||||
if (obj == null)
|
if (obj == null)
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import com.google.common.collect.RangeSet;
|
||||||
import com.google.common.collect.TreeRangeSet;
|
import com.google.common.collect.TreeRangeSet;
|
||||||
import com.taosdata.jdbc.enums.TimestampPrecision;
|
import com.taosdata.jdbc.enums.TimestampPrecision;
|
||||||
|
|
||||||
import java.nio.charset.Charset;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.sql.Date;
|
import java.sql.Date;
|
||||||
import java.sql.Time;
|
import java.sql.Time;
|
||||||
|
|
@ -110,15 +109,27 @@ public class Utils {
|
||||||
return rawSql;
|
return rawSql;
|
||||||
// toLowerCase
|
// toLowerCase
|
||||||
String preparedSql = rawSql.trim().toLowerCase();
|
String preparedSql = rawSql.trim().toLowerCase();
|
||||||
String[] clause = new String[]{"values\\s*\\([\\s\\S]*?\\)", "tags\\s*\\([\\s\\S]*?\\)", "where[\\s\\S]*"};
|
String[] clause = new String[]{"tags\\s*\\([\\s\\S]*?\\)", "where[\\s\\S]*"};
|
||||||
Map<Integer, Integer> placeholderPositions = new HashMap<>();
|
Map<Integer, Integer> placeholderPositions = new HashMap<>();
|
||||||
RangeSet<Integer> clauseRangeSet = TreeRangeSet.create();
|
RangeSet<Integer> clauseRangeSet = TreeRangeSet.create();
|
||||||
findPlaceholderPosition(preparedSql, placeholderPositions);
|
findPlaceholderPosition(preparedSql, placeholderPositions);
|
||||||
|
// find tags and where clause's position
|
||||||
findClauseRangeSet(preparedSql, clause, clauseRangeSet);
|
findClauseRangeSet(preparedSql, clause, clauseRangeSet);
|
||||||
|
// find values clause's position
|
||||||
|
findValuesClauseRangeSet(preparedSql, clauseRangeSet);
|
||||||
|
|
||||||
return transformSql(rawSql, parameters, placeholderPositions, clauseRangeSet);
|
return transformSql(rawSql, parameters, placeholderPositions, clauseRangeSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void findValuesClauseRangeSet(String preparedSql, RangeSet<Integer> clauseRangeSet) {
|
||||||
|
Matcher matcher = Pattern.compile("(values|,)\\s*(\\([^)]*\\))").matcher(preparedSql);
|
||||||
|
while (matcher.find()) {
|
||||||
|
int start = matcher.start(2);
|
||||||
|
int end = matcher.end(2);
|
||||||
|
clauseRangeSet.add(Range.closedOpen(start, end));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void findClauseRangeSet(String preparedSql, String[] regexArr, RangeSet<Integer> clauseRangeSet) {
|
private static void findClauseRangeSet(String preparedSql, String[] regexArr, RangeSet<Integer> clauseRangeSet) {
|
||||||
clauseRangeSet.clear();
|
clauseRangeSet.clear();
|
||||||
for (String regex : regexArr) {
|
for (String regex : regexArr) {
|
||||||
|
|
@ -126,7 +137,7 @@ public class Utils {
|
||||||
while (matcher.find()) {
|
while (matcher.find()) {
|
||||||
int start = matcher.start();
|
int start = matcher.start();
|
||||||
int end = matcher.end();
|
int end = matcher.end();
|
||||||
clauseRangeSet.add(Range.closed(start, end));
|
clauseRangeSet.add(Range.closedOpen(start, end));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ package com.taosdata.jdbc.utils;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public class UtilsTest {
|
public class UtilsTest {
|
||||||
|
|
@ -32,7 +34,7 @@ public class UtilsTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getNativeSqlReplaceQuestionMarks() {
|
public void lowerCase() {
|
||||||
// given
|
// given
|
||||||
String nativeSql = "insert into ?.? (ts, temperature, humidity) using ?.? tags(?,?) values(now, ?, ?)";
|
String nativeSql = "insert into ?.? (ts, temperature, humidity) using ?.? tags(?,?) values(now, ?, ?)";
|
||||||
Object[] parameters = Stream.of("test", "t1", "test", "weather", "beijing", 1, 12.2, 4).toArray();
|
Object[] parameters = Stream.of("test", "t1", "test", "weather", "beijing", 1, 12.2, 4).toArray();
|
||||||
|
|
@ -46,7 +48,7 @@ public class UtilsTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getNativeSqlReplaceQuestionMarks2() {
|
public void upperCase() {
|
||||||
// given
|
// given
|
||||||
String nativeSql = "INSERT INTO ? (TS,CURRENT,VOLTAGE,PHASE) USING METERS TAGS (?) VALUES (?,?,?,?)";
|
String nativeSql = "INSERT INTO ? (TS,CURRENT,VOLTAGE,PHASE) USING METERS TAGS (?) VALUES (?,?,?,?)";
|
||||||
Object[] parameters = Stream.of("d1", 1, 123, 3.14, 220, 4).toArray();
|
Object[] parameters = Stream.of("d1", 1, 123, 3.14, 220, 4).toArray();
|
||||||
|
|
@ -59,9 +61,49 @@ public class UtilsTest {
|
||||||
Assert.assertEquals(expected, actual);
|
Assert.assertEquals(expected, actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void multiValues() {
|
||||||
|
// given
|
||||||
|
String nativeSql = "INSERT INTO ? (TS,CURRENT,VOLTAGE,PHASE) USING METERS TAGS (?) VALUES (?,?,?,?),(?,?,?,?)";
|
||||||
|
Object[] parameters = Stream.of("d1", 1, 100, 3.14, "abc", 4, 200, 3.1415, "xyz", 5).toArray();
|
||||||
|
|
||||||
|
// when
|
||||||
|
String actual = Utils.getNativeSql(nativeSql, parameters);
|
||||||
|
|
||||||
|
// then
|
||||||
|
String expected = "INSERT INTO d1 (TS,CURRENT,VOLTAGE,PHASE) USING METERS TAGS (1) VALUES (100,3.14,'abc',4),(200,3.1415,'xyz',5)";
|
||||||
|
Assert.assertEquals(expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getNativeSqlReplaceNothing() {
|
public void lineTerminator() {
|
||||||
|
// given
|
||||||
|
String nativeSql = "INSERT INTO ? (TS,CURRENT,VOLTAGE,PHASE) USING METERS TAGS (?) VALUES (?,?,\r\n?,?),(?,?,?,?)";
|
||||||
|
Object[] parameters = Stream.of("d1", 1, 100, 3.14, "abc", 4, 200, 3.1415, "xyz", 5).toArray();
|
||||||
|
|
||||||
|
// when
|
||||||
|
String actual = Utils.getNativeSql(nativeSql, parameters);
|
||||||
|
|
||||||
|
// then
|
||||||
|
String expected = "INSERT INTO d1 (TS,CURRENT,VOLTAGE,PHASE) USING METERS TAGS (1) VALUES (100,3.14,\r\n'abc',4),(200,3.1415,'xyz',5)";
|
||||||
|
Assert.assertEquals(expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void lineTerminatorAndMultiValues() {
|
||||||
|
String nativeSql = "INSERT Into ? TAGS(?) VALUES(?,?,\r\n?,?),(?,? ,\r\n?,?) t? tags (?) Values (?,?,?\r\n,?),(?,?,?,?) t? Tags(?) values (?,?,?,?) , (?,?,?,?)";
|
||||||
|
Object[] parameters = Stream.of("t1", "abc", 100, 1.1, "xxx", "xxx", 200, 2.2, "xxx", "xxx", 2, "bcd", 300, 3.3, "xxx", "xxx", 400, 4.4, "xxx", "xxx", 3, "cde", 500, 5.5, "xxx", "xxx", 600, 6.6, "xxx", "xxx").toArray();
|
||||||
|
|
||||||
|
// when
|
||||||
|
String actual = Utils.getNativeSql(nativeSql, parameters);
|
||||||
|
|
||||||
|
// then
|
||||||
|
String expected = "INSERT Into t1 TAGS('abc') VALUES(100,1.1,\r\n'xxx','xxx'),(200,2.2 ,\r\n'xxx','xxx') t2 tags ('bcd') Values (300,3.3,'xxx'\r\n,'xxx'),(400,4.4,'xxx','xxx') t3 Tags('cde') values (500,5.5,'xxx','xxx') , (600,6.6,'xxx','xxx')";
|
||||||
|
Assert.assertEquals(expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void replaceNothing() {
|
||||||
// given
|
// given
|
||||||
String nativeSql = "insert into test.t1 (ts, temperature, humidity) using test.weather tags('beijing',1) values(now, 12.2, 4)";
|
String nativeSql = "insert into test.t1 (ts, temperature, humidity) using test.weather tags('beijing',1) values(now, 12.2, 4)";
|
||||||
|
|
||||||
|
|
@ -73,7 +115,7 @@ public class UtilsTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getNativeSqlReplaceNothing2() {
|
public void replaceNothing2() {
|
||||||
// given
|
// given
|
||||||
String nativeSql = "insert into test.t1 (ts, temperature, humidity) using test.weather tags('beijing',1) values(now, 12.2, 4)";
|
String nativeSql = "insert into test.t1 (ts, temperature, humidity) using test.weather tags('beijing',1) values(now, 12.2, 4)";
|
||||||
Object[] parameters = Stream.of("test", "t1", "test", "weather", "beijing", 1, 12.2, 4).toArray();
|
Object[] parameters = Stream.of("test", "t1", "test", "weather", "beijing", 1, 12.2, 4).toArray();
|
||||||
|
|
@ -86,7 +128,7 @@ public class UtilsTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getNativeSqlReplaceNothing3() {
|
public void replaceNothing3() {
|
||||||
// given
|
// given
|
||||||
String nativeSql = "insert into ?.? (ts, temperature, humidity) using ?.? tags(?,?) values(now, ?, ?)";
|
String nativeSql = "insert into ?.? (ts, temperature, humidity) using ?.? tags(?,?) values(now, ?, ?)";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -476,15 +476,17 @@ static void cqProcessStreamRes(void *param, TAOS_RES *tres, TAOS_ROW row) {
|
||||||
|
|
||||||
cDebug("vgId:%d, id:%d CQ:%s stream result is ready", pContext->vgId, pObj->tid, pObj->sqlStr);
|
cDebug("vgId:%d, id:%d CQ:%s stream result is ready", pContext->vgId, pObj->tid, pObj->sqlStr);
|
||||||
|
|
||||||
int32_t size = sizeof(SWalHead) + sizeof(SSubmitMsg) + sizeof(SSubmitBlk) + TD_DATA_ROW_HEAD_SIZE + pObj->rowSize;
|
int32_t size = sizeof(SWalHead) + sizeof(SSubmitMsg) + sizeof(SSubmitBlk) + TD_MEM_ROW_DATA_HEAD_SIZE + pObj->rowSize;
|
||||||
char *buffer = calloc(size, 1);
|
char *buffer = calloc(size, 1);
|
||||||
|
|
||||||
SWalHead *pHead = (SWalHead *)buffer;
|
SWalHead *pHead = (SWalHead *)buffer;
|
||||||
SSubmitMsg *pMsg = (SSubmitMsg *) (buffer + sizeof(SWalHead));
|
SSubmitMsg *pMsg = (SSubmitMsg *) (buffer + sizeof(SWalHead));
|
||||||
SSubmitBlk *pBlk = (SSubmitBlk *) (buffer + sizeof(SWalHead) + sizeof(SSubmitMsg));
|
SSubmitBlk *pBlk = (SSubmitBlk *) (buffer + sizeof(SWalHead) + sizeof(SSubmitMsg));
|
||||||
|
|
||||||
SDataRow trow = (SDataRow)pBlk->data;
|
SMemRow trow = (SMemRow)pBlk->data;
|
||||||
tdInitDataRow(trow, pSchema);
|
SDataRow dataRow = (SDataRow)memRowDataBody(trow);
|
||||||
|
memRowSetType(trow, SMEM_ROW_DATA);
|
||||||
|
tdInitDataRow(dataRow, pSchema);
|
||||||
|
|
||||||
for (int32_t i = 0; i < pSchema->numOfCols; i++) {
|
for (int32_t i = 0; i < pSchema->numOfCols; i++) {
|
||||||
STColumn *c = pSchema->columns + i;
|
STColumn *c = pSchema->columns + i;
|
||||||
|
|
@ -500,9 +502,9 @@ static void cqProcessStreamRes(void *param, TAOS_RES *tres, TAOS_ROW row) {
|
||||||
memcpy((char *)val + sizeof(VarDataLenT), buf, len);
|
memcpy((char *)val + sizeof(VarDataLenT), buf, len);
|
||||||
varDataLen(val) = len;
|
varDataLen(val) = len;
|
||||||
}
|
}
|
||||||
tdAppendColVal(trow, val, c->type, c->bytes, c->offset);
|
tdAppendColVal(dataRow, val, c->type, c->offset);
|
||||||
}
|
}
|
||||||
pBlk->dataLen = htonl(dataRowLen(trow));
|
pBlk->dataLen = htonl(memRowDataTLen(trow));
|
||||||
pBlk->schemaLen = 0;
|
pBlk->schemaLen = 0;
|
||||||
|
|
||||||
pBlk->uid = htobe64(pObj->uid);
|
pBlk->uid = htobe64(pObj->uid);
|
||||||
|
|
@ -511,7 +513,7 @@ static void cqProcessStreamRes(void *param, TAOS_RES *tres, TAOS_ROW row) {
|
||||||
pBlk->sversion = htonl(pSchema->version);
|
pBlk->sversion = htonl(pSchema->version);
|
||||||
pBlk->padding = 0;
|
pBlk->padding = 0;
|
||||||
|
|
||||||
pHead->len = sizeof(SSubmitMsg) + sizeof(SSubmitBlk) + dataRowLen(trow);
|
pHead->len = sizeof(SSubmitMsg) + sizeof(SSubmitBlk) + memRowDataTLen(trow);
|
||||||
|
|
||||||
pMsg->header.vgId = htonl(pContext->vgId);
|
pMsg->header.vgId = htonl(pContext->vgId);
|
||||||
pMsg->header.contLen = htonl(pHead->len);
|
pMsg->header.contLen = htonl(pHead->len);
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ ELSE ()
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
ADD_EXECUTABLE(taosd ${SRC})
|
ADD_EXECUTABLE(taosd ${SRC})
|
||||||
TARGET_LINK_LIBRARIES(taosd mnode monitor http tsdb twal vnode cJson lz4 balance sync ${LINK_JEMALLOC})
|
TARGET_LINK_LIBRARIES(taosd mnode monitor http tsdb twal vnode cJson lua lz4 balance sync ${LINK_JEMALLOC})
|
||||||
|
|
||||||
IF (TD_SOMODE_STATIC)
|
IF (TD_SOMODE_STATIC)
|
||||||
TARGET_LINK_LIBRARIES(taosd taos_static)
|
TARGET_LINK_LIBRARIES(taosd taos_static)
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@
|
||||||
#include "dnodeShell.h"
|
#include "dnodeShell.h"
|
||||||
#include "dnodeTelemetry.h"
|
#include "dnodeTelemetry.h"
|
||||||
#include "module.h"
|
#include "module.h"
|
||||||
|
#include "qScript.h"
|
||||||
#include "mnode.h"
|
#include "mnode.h"
|
||||||
|
|
||||||
#if !defined(_MODULE) || !defined(_TD_LINUX)
|
#if !defined(_MODULE) || !defined(_TD_LINUX)
|
||||||
|
|
@ -84,6 +85,7 @@ static SStep tsDnodeSteps[] = {
|
||||||
{"dnode-shell", dnodeInitShell, dnodeCleanupShell},
|
{"dnode-shell", dnodeInitShell, dnodeCleanupShell},
|
||||||
{"dnode-statustmr", dnodeInitStatusTimer,dnodeCleanupStatusTimer},
|
{"dnode-statustmr", dnodeInitStatusTimer,dnodeCleanupStatusTimer},
|
||||||
{"dnode-telemetry", dnodeInitTelemetry, dnodeCleanupTelemetry},
|
{"dnode-telemetry", dnodeInitTelemetry, dnodeCleanupTelemetry},
|
||||||
|
{"dnode-script", scriptEnvPoolInit, scriptEnvPoolCleanup},
|
||||||
};
|
};
|
||||||
|
|
||||||
static SStep tsDnodeCompactSteps[] = {
|
static SStep tsDnodeCompactSteps[] = {
|
||||||
|
|
|
||||||
|
|
@ -48,9 +48,11 @@ int32_t dnodeInitShell() {
|
||||||
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_DROP_DNODE] = dnodeDispatchToMWriteQueue;
|
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_DROP_DNODE] = dnodeDispatchToMWriteQueue;
|
||||||
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_CREATE_DB] = dnodeDispatchToMWriteQueue;
|
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_CREATE_DB] = dnodeDispatchToMWriteQueue;
|
||||||
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_CREATE_TP] = dnodeDispatchToMWriteQueue;
|
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_CREATE_TP] = dnodeDispatchToMWriteQueue;
|
||||||
|
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_CREATE_FUNCTION] = dnodeDispatchToMWriteQueue;
|
||||||
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_DROP_DB] = dnodeDispatchToMWriteQueue;
|
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_DROP_DB] = dnodeDispatchToMWriteQueue;
|
||||||
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_SYNC_DB] = dnodeDispatchToMWriteQueue;
|
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_SYNC_DB] = dnodeDispatchToMWriteQueue;
|
||||||
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_DROP_TP] = dnodeDispatchToMWriteQueue;
|
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_DROP_TP] = dnodeDispatchToMWriteQueue;
|
||||||
|
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_DROP_FUNCTION] = dnodeDispatchToMWriteQueue;
|
||||||
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_ALTER_DB] = dnodeDispatchToMWriteQueue;
|
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_ALTER_DB] = dnodeDispatchToMWriteQueue;
|
||||||
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_ALTER_TP] = dnodeDispatchToMWriteQueue;
|
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_ALTER_TP] = dnodeDispatchToMWriteQueue;
|
||||||
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_CREATE_TABLE]= dnodeDispatchToMWriteQueue;
|
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_CREATE_TABLE]= dnodeDispatchToMWriteQueue;
|
||||||
|
|
@ -72,6 +74,7 @@ int32_t dnodeInitShell() {
|
||||||
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_TABLES_META] = dnodeDispatchToMReadQueue;
|
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_TABLES_META] = dnodeDispatchToMReadQueue;
|
||||||
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_SHOW] = dnodeDispatchToMReadQueue;
|
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_SHOW] = dnodeDispatchToMReadQueue;
|
||||||
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_RETRIEVE] = dnodeDispatchToMReadQueue;
|
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_RETRIEVE] = dnodeDispatchToMReadQueue;
|
||||||
|
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_RETRIEVE_FUNC] = dnodeDispatchToMReadQueue;
|
||||||
|
|
||||||
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_NETWORK_TEST] = dnodeSendStartupStep;
|
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_NETWORK_TEST] = dnodeSendStartupStep;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -202,12 +202,12 @@ static void *dnodeProcessVWriteQueue(void *wparam) {
|
||||||
for (int32_t i = 0; i < numOfMsgs; ++i) {
|
for (int32_t i = 0; i < numOfMsgs; ++i) {
|
||||||
taosGetQitem(pWorker->qall, &qtype, (void **)&pWrite);
|
taosGetQitem(pWorker->qall, &qtype, (void **)&pWrite);
|
||||||
dTrace("msg:%p, app:%p type:%s will be processed in vwrite queue, qtype:%s hver:%" PRIu64, pWrite,
|
dTrace("msg:%p, app:%p type:%s will be processed in vwrite queue, qtype:%s hver:%" PRIu64, pWrite,
|
||||||
pWrite->rpcMsg.ahandle, taosMsg[pWrite->pHead.msgType], qtypeStr[qtype], pWrite->pHead.version);
|
pWrite->rpcMsg.ahandle, taosMsg[pWrite->walHead.msgType], qtypeStr[qtype], pWrite->walHead.version);
|
||||||
|
|
||||||
pWrite->code = vnodeProcessWrite(pVnode, &pWrite->pHead, qtype, pWrite);
|
pWrite->code = vnodeProcessWrite(pVnode, &pWrite->walHead, qtype, pWrite);
|
||||||
if (pWrite->code <= 0) atomic_add_fetch_32(&pWrite->processedCount, 1);
|
if (pWrite->code <= 0) atomic_add_fetch_32(&pWrite->processedCount, 1);
|
||||||
if (pWrite->code > 0) pWrite->code = 0;
|
if (pWrite->code > 0) pWrite->code = 0;
|
||||||
if (pWrite->code == 0 && pWrite->pHead.msgType != TSDB_MSG_TYPE_SUBMIT) forceFsync = true;
|
if (pWrite->code == 0 && pWrite->walHead.msgType != TSDB_MSG_TYPE_SUBMIT) forceFsync = true;
|
||||||
|
|
||||||
dTrace("msg:%p is processed in vwrite queue, code:0x%x", pWrite, pWrite->code);
|
dTrace("msg:%p is processed in vwrite queue, code:0x%x", pWrite, pWrite->code);
|
||||||
}
|
}
|
||||||
|
|
@ -222,7 +222,7 @@ static void *dnodeProcessVWriteQueue(void *wparam) {
|
||||||
dnodeSendRpcVWriteRsp(pVnode, pWrite, pWrite->code);
|
dnodeSendRpcVWriteRsp(pVnode, pWrite, pWrite->code);
|
||||||
} else {
|
} else {
|
||||||
if (qtype == TAOS_QTYPE_FWD) {
|
if (qtype == TAOS_QTYPE_FWD) {
|
||||||
vnodeConfirmForward(pVnode, pWrite->pHead.version, pWrite->code, pWrite->pHead.msgType != TSDB_MSG_TYPE_SUBMIT);
|
vnodeConfirmForward(pVnode, pWrite->walHead.version, pWrite->code, pWrite->walHead.msgType != TSDB_MSG_TYPE_SUBMIT);
|
||||||
}
|
}
|
||||||
if (pWrite->rspRet.rsp) {
|
if (pWrite->rspRet.rsp) {
|
||||||
rpcFreeCont(pWrite->rspRet.rsp);
|
rpcFreeCont(pWrite->rspRet.rsp);
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ typedef void* qinfo_t;
|
||||||
* @param qinfo
|
* @param qinfo
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
int32_t qCreateQueryInfo(void* tsdb, int32_t vgId, SQueryTableMsg* pQueryTableMsg, qinfo_t* qinfo, uint64_t *qId);
|
int32_t qCreateQueryInfo(void* tsdb, int32_t vgId, SQueryTableMsg* pQueryTableMsg, qinfo_t* qinfo, uint64_t qId);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -180,12 +180,16 @@ do { \
|
||||||
// this is the length of its string representation, including the terminator zero
|
// this is the length of its string representation, including the terminator zero
|
||||||
#define TSDB_ACCT_ID_LEN 11
|
#define TSDB_ACCT_ID_LEN 11
|
||||||
|
|
||||||
#define TSDB_MAX_COLUMNS 1024
|
#define TSDB_MAX_COLUMNS 4096
|
||||||
#define TSDB_MIN_COLUMNS 2 //PRIMARY COLUMN(timestamp) + other columns
|
#define TSDB_MIN_COLUMNS 2 //PRIMARY COLUMN(timestamp) + other columns
|
||||||
|
|
||||||
#define TSDB_NODE_NAME_LEN 64
|
#define TSDB_NODE_NAME_LEN 64
|
||||||
#define TSDB_TABLE_NAME_LEN 193 // it is a null-terminated string
|
#define TSDB_TABLE_NAME_LEN 193 // it is a null-terminated string
|
||||||
#define TSDB_DB_NAME_LEN 33
|
#define TSDB_DB_NAME_LEN 33
|
||||||
|
#define TSDB_FUNC_NAME_LEN 65
|
||||||
|
#define TSDB_FUNC_CODE_LEN (65535 - 512)
|
||||||
|
#define TSDB_FUNC_BUF_SIZE 512
|
||||||
|
#define TSDB_TYPE_STR_MAX_LEN 32
|
||||||
#define TSDB_TABLE_FNAME_LEN (TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN + TSDB_TABLE_NAME_LEN)
|
#define TSDB_TABLE_FNAME_LEN (TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN + TSDB_TABLE_NAME_LEN)
|
||||||
#define TSDB_COL_NAME_LEN 65
|
#define TSDB_COL_NAME_LEN 65
|
||||||
#define TSDB_MAX_SAVED_SQL_LEN TSDB_MAX_COLUMNS * 64
|
#define TSDB_MAX_SAVED_SQL_LEN TSDB_MAX_COLUMNS * 64
|
||||||
|
|
@ -195,7 +199,13 @@ do { \
|
||||||
|
|
||||||
#define TSDB_APPNAME_LEN TSDB_UNI_LEN
|
#define TSDB_APPNAME_LEN TSDB_UNI_LEN
|
||||||
|
|
||||||
#define TSDB_MAX_BYTES_PER_ROW 16384
|
/**
|
||||||
|
* In some scenarios uint16_t (0~65535) is used to store the row len.
|
||||||
|
* - Firstly, we use 65531(65535 - 4), as the SDataRow/SKVRow contains 4 bits header.
|
||||||
|
* - Secondly, if all cols are VarDataT type except primary key, we need 4 bits to store the offset, thus
|
||||||
|
* the final value is 65531-(4096-1)*4 = 49151.
|
||||||
|
*/
|
||||||
|
#define TSDB_MAX_BYTES_PER_ROW 49151
|
||||||
#define TSDB_MAX_TAGS_LEN 16384
|
#define TSDB_MAX_TAGS_LEN 16384
|
||||||
#define TSDB_MAX_TAGS 128
|
#define TSDB_MAX_TAGS 128
|
||||||
#define TSDB_MAX_TAG_CONDITIONS 1024
|
#define TSDB_MAX_TAG_CONDITIONS 1024
|
||||||
|
|
@ -323,8 +333,9 @@ do { \
|
||||||
#define TSDB_MAX_JOIN_TABLE_NUM 10
|
#define TSDB_MAX_JOIN_TABLE_NUM 10
|
||||||
#define TSDB_MAX_UNION_CLAUSE 5
|
#define TSDB_MAX_UNION_CLAUSE 5
|
||||||
|
|
||||||
#define TSDB_MAX_BINARY_LEN (TSDB_MAX_BYTES_PER_ROW-TSDB_KEYSIZE)
|
#define TSDB_MAX_FIELD_LEN 16384
|
||||||
#define TSDB_MAX_NCHAR_LEN (TSDB_MAX_BYTES_PER_ROW-TSDB_KEYSIZE)
|
#define TSDB_MAX_BINARY_LEN (TSDB_MAX_FIELD_LEN-TSDB_KEYSIZE) // keep 16384
|
||||||
|
#define TSDB_MAX_NCHAR_LEN (TSDB_MAX_FIELD_LEN-TSDB_KEYSIZE) // keep 16384
|
||||||
#define PRIMARYKEY_TIMESTAMP_COL_INDEX 0
|
#define PRIMARYKEY_TIMESTAMP_COL_INDEX 0
|
||||||
|
|
||||||
#define TSDB_MAX_RPC_THREADS 5
|
#define TSDB_MAX_RPC_THREADS 5
|
||||||
|
|
@ -332,6 +343,10 @@ do { \
|
||||||
#define TSDB_QUERY_TYPE_NON_TYPE 0x00u // none type
|
#define TSDB_QUERY_TYPE_NON_TYPE 0x00u // none type
|
||||||
#define TSDB_QUERY_TYPE_FREE_RESOURCE 0x01u // free qhandle at vnode
|
#define TSDB_QUERY_TYPE_FREE_RESOURCE 0x01u // free qhandle at vnode
|
||||||
|
|
||||||
|
#define TSDB_UDF_TYPE_SCALAR 1
|
||||||
|
#define TSDB_UDF_TYPE_AGGREGATE 2
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 1. ordinary sub query for select * from super_table
|
* 1. ordinary sub query for select * from super_table
|
||||||
* 2. all sqlobj generated by createSubqueryObj with this flag
|
* 2. all sqlobj generated by createSubqueryObj with this flag
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,7 @@ int32_t* taosGetErrno();
|
||||||
#define TSDB_CODE_TSC_DB_NOT_SELECTED TAOS_DEF_ERROR_CODE(0, 0x0217) //"Database not specified or available")
|
#define TSDB_CODE_TSC_DB_NOT_SELECTED TAOS_DEF_ERROR_CODE(0, 0x0217) //"Database not specified or available")
|
||||||
#define TSDB_CODE_TSC_INVALID_TABLE_NAME TAOS_DEF_ERROR_CODE(0, 0x0218) //"Table does not exist")
|
#define TSDB_CODE_TSC_INVALID_TABLE_NAME TAOS_DEF_ERROR_CODE(0, 0x0218) //"Table does not exist")
|
||||||
#define TSDB_CODE_TSC_EXCEED_SQL_LIMIT TAOS_DEF_ERROR_CODE(0, 0x0219) //"SQL statement too long check maxSQLLength config")
|
#define TSDB_CODE_TSC_EXCEED_SQL_LIMIT TAOS_DEF_ERROR_CODE(0, 0x0219) //"SQL statement too long check maxSQLLength config")
|
||||||
|
#define TSDB_CODE_TSC_FILE_EMPTY TAOS_DEF_ERROR_CODE(0, 0x021A) //"File is empty")
|
||||||
|
|
||||||
// mnode
|
// mnode
|
||||||
#define TSDB_CODE_MND_MSG_NOT_PROCESSED TAOS_DEF_ERROR_CODE(0, 0x0300) //"Message not processed")
|
#define TSDB_CODE_MND_MSG_NOT_PROCESSED TAOS_DEF_ERROR_CODE(0, 0x0300) //"Message not processed")
|
||||||
|
|
@ -174,6 +175,13 @@ int32_t* taosGetErrno();
|
||||||
#define TSDB_CODE_MND_INVALID_STABLE_NAME TAOS_DEF_ERROR_CODE(0, 0x036D) //"Super table does not exist")
|
#define TSDB_CODE_MND_INVALID_STABLE_NAME TAOS_DEF_ERROR_CODE(0, 0x036D) //"Super table does not exist")
|
||||||
#define TSDB_CODE_MND_INVALID_CREATE_TABLE_MSG TAOS_DEF_ERROR_CODE(0, 0x036E) //"Invalid create table message")
|
#define TSDB_CODE_MND_INVALID_CREATE_TABLE_MSG TAOS_DEF_ERROR_CODE(0, 0x036E) //"Invalid create table message")
|
||||||
|
|
||||||
|
#define TSDB_CODE_MND_INVALID_FUNC_NAME TAOS_DEF_ERROR_CODE(0, 0x0370) //"Invalid func name")
|
||||||
|
#define TSDB_CODE_MND_INVALID_FUNC_LEN TAOS_DEF_ERROR_CODE(0, 0x0371) //"Invalid func length")
|
||||||
|
#define TSDB_CODE_MND_INVALID_FUNC_CODE TAOS_DEF_ERROR_CODE(0, 0x0372) //"Invalid func code")
|
||||||
|
#define TSDB_CODE_MND_FUNC_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x0373) //"Func already exists")
|
||||||
|
#define TSDB_CODE_MND_INVALID_FUNC TAOS_DEF_ERROR_CODE(0, 0x0374) //"Invalid func")
|
||||||
|
#define TSDB_CODE_MND_INVALID_FUNC_BUFSIZE TAOS_DEF_ERROR_CODE(0, 0x0375) //"Invalid func bufSize")
|
||||||
|
|
||||||
#define TSDB_CODE_MND_DB_NOT_SELECTED TAOS_DEF_ERROR_CODE(0, 0x0380) //"Database not specified or available")
|
#define TSDB_CODE_MND_DB_NOT_SELECTED TAOS_DEF_ERROR_CODE(0, 0x0380) //"Database not specified or available")
|
||||||
#define TSDB_CODE_MND_DB_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x0381) //"Database already exists")
|
#define TSDB_CODE_MND_DB_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x0381) //"Database already exists")
|
||||||
#define TSDB_CODE_MND_INVALID_DB_OPTION TAOS_DEF_ERROR_CODE(0, 0x0382) //"Invalid database options")
|
#define TSDB_CODE_MND_INVALID_DB_OPTION TAOS_DEF_ERROR_CODE(0, 0x0382) //"Invalid database options")
|
||||||
|
|
@ -261,6 +269,7 @@ int32_t* taosGetErrno();
|
||||||
#define TSDB_CODE_QRY_TOO_MANY_TIMEWINDOW TAOS_DEF_ERROR_CODE(0, 0x070A) //"Too many time window in query")
|
#define TSDB_CODE_QRY_TOO_MANY_TIMEWINDOW TAOS_DEF_ERROR_CODE(0, 0x070A) //"Too many time window in query")
|
||||||
#define TSDB_CODE_QRY_NOT_ENOUGH_BUFFER TAOS_DEF_ERROR_CODE(0, 0x070B) //"Query buffer limit has reached")
|
#define TSDB_CODE_QRY_NOT_ENOUGH_BUFFER TAOS_DEF_ERROR_CODE(0, 0x070B) //"Query buffer limit has reached")
|
||||||
#define TSDB_CODE_QRY_INCONSISTAN TAOS_DEF_ERROR_CODE(0, 0x070C) //"File inconsistency in replica")
|
#define TSDB_CODE_QRY_INCONSISTAN TAOS_DEF_ERROR_CODE(0, 0x070C) //"File inconsistency in replica")
|
||||||
|
#define TSDB_CODE_QRY_SYS_ERROR TAOS_DEF_ERROR_CODE(0, 0x070D) //"System error")
|
||||||
|
|
||||||
|
|
||||||
// grant
|
// grant
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,9 @@ TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_DROP_USER, "drop-user" )
|
||||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_CREATE_DNODE, "create-dnode" )
|
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_CREATE_DNODE, "create-dnode" )
|
||||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_DROP_DNODE, "drop-dnode" )
|
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_DROP_DNODE, "drop-dnode" )
|
||||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_CREATE_DB, "create-db" )
|
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_CREATE_DB, "create-db" )
|
||||||
|
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_CREATE_FUNCTION, "create-function" )
|
||||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_DROP_DB, "drop-db" )
|
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_DROP_DB, "drop-db" )
|
||||||
|
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_DROP_FUNCTION, "drop-function" )
|
||||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_USE_DB, "use-db" )
|
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_USE_DB, "use-db" )
|
||||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_ALTER_DB, "alter-db" )
|
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_ALTER_DB, "alter-db" )
|
||||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_SYNC_DB, "sync-db-replica" )
|
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_SYNC_DB, "sync-db-replica" )
|
||||||
|
|
@ -96,7 +98,7 @@ TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_KILL_STREAM, "kill-stream" )
|
||||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_KILL_CONN, "kill-conn" )
|
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_KILL_CONN, "kill-conn" )
|
||||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_CONFIG_DNODE, "cm-config-dnode" )
|
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_CONFIG_DNODE, "cm-config-dnode" )
|
||||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_HEARTBEAT, "heartbeat" )
|
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_HEARTBEAT, "heartbeat" )
|
||||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_DUMMY8, "dummy8" )
|
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_RETRIEVE_FUNC, "retrieve-func" )
|
||||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_DUMMY9, "dummy9" )
|
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_DUMMY9, "dummy9" )
|
||||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_DUMMY10, "dummy10" )
|
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_DUMMY10, "dummy10" )
|
||||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_DUMMY11, "dummy11" )
|
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_DUMMY11, "dummy11" )
|
||||||
|
|
@ -153,6 +155,7 @@ enum _mgmt_table {
|
||||||
TSDB_MGMT_TABLE_STREAMTABLES,
|
TSDB_MGMT_TABLE_STREAMTABLES,
|
||||||
TSDB_MGMT_TABLE_CLUSTER,
|
TSDB_MGMT_TABLE_CLUSTER,
|
||||||
TSDB_MGMT_TABLE_TP,
|
TSDB_MGMT_TABLE_TP,
|
||||||
|
TSDB_MGMT_TABLE_FUNCTION,
|
||||||
TSDB_MGMT_TABLE_MAX,
|
TSDB_MGMT_TABLE_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -507,6 +510,9 @@ typedef struct {
|
||||||
int32_t prevResultLen; // previous result length
|
int32_t prevResultLen; // previous result length
|
||||||
int32_t numOfOperator;
|
int32_t numOfOperator;
|
||||||
int32_t tableScanOperator;// table scan operator. -1 means no scan operator
|
int32_t tableScanOperator;// table scan operator. -1 means no scan operator
|
||||||
|
int32_t udfNum; // number of udf function
|
||||||
|
int32_t udfContentOffset;
|
||||||
|
int32_t udfContentLen;
|
||||||
SColumnInfo tableCols[];
|
SColumnInfo tableCols[];
|
||||||
} SQueryTableMsg;
|
} SQueryTableMsg;
|
||||||
|
|
||||||
|
|
@ -571,6 +577,41 @@ typedef struct {
|
||||||
int8_t reserve[5];
|
int8_t reserve[5];
|
||||||
} SCreateDbMsg, SAlterDbMsg;
|
} SCreateDbMsg, SAlterDbMsg;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char name[TSDB_FUNC_NAME_LEN];
|
||||||
|
char path[PATH_MAX];
|
||||||
|
int32_t funcType;
|
||||||
|
uint8_t outputType;
|
||||||
|
int16_t outputLen;
|
||||||
|
int32_t bufSize;
|
||||||
|
int32_t codeLen;
|
||||||
|
char code[];
|
||||||
|
} SCreateFuncMsg;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int32_t num;
|
||||||
|
char name[];
|
||||||
|
} SRetrieveFuncMsg;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char name[TSDB_FUNC_NAME_LEN];
|
||||||
|
int32_t funcType;
|
||||||
|
int8_t resType;
|
||||||
|
int16_t resBytes;
|
||||||
|
int32_t bufSize;
|
||||||
|
int32_t len;
|
||||||
|
char content[];
|
||||||
|
} SFunctionInfoMsg;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int32_t num;
|
||||||
|
char content[];
|
||||||
|
} SUdfFuncMsg;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char name[TSDB_FUNC_NAME_LEN];
|
||||||
|
} SDropFuncMsg;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char db[TSDB_TABLE_FNAME_LEN];
|
char db[TSDB_TABLE_FNAME_LEN];
|
||||||
uint8_t ignoreNotExists;
|
uint8_t ignoreNotExists;
|
||||||
|
|
@ -710,8 +751,10 @@ typedef struct {
|
||||||
} STableInfoMsg;
|
} STableInfoMsg;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
uint8_t metaClone; // create local clone of the cached table meta
|
||||||
int32_t numOfVgroups;
|
int32_t numOfVgroups;
|
||||||
int32_t numOfTables;
|
int32_t numOfTables;
|
||||||
|
int32_t numOfUdfs;
|
||||||
char tableNames[];
|
char tableNames[];
|
||||||
} SMultiTableInfoMsg;
|
} SMultiTableInfoMsg;
|
||||||
|
|
||||||
|
|
@ -762,9 +805,11 @@ typedef struct STableMetaMsg {
|
||||||
typedef struct SMultiTableMeta {
|
typedef struct SMultiTableMeta {
|
||||||
int32_t numOfTables;
|
int32_t numOfTables;
|
||||||
int32_t numOfVgroup;
|
int32_t numOfVgroup;
|
||||||
uint32_t contLen:31;
|
int32_t numOfUdf;
|
||||||
uint8_t compressed:1; // denote if compressed or not
|
int32_t contLen;
|
||||||
|
uint8_t compressed; // denote if compressed or not
|
||||||
uint32_t rawLen; // size before compress
|
uint32_t rawLen; // size before compress
|
||||||
|
uint8_t metaClone; // make meta clone after retrieve meta from mnode
|
||||||
char meta[];
|
char meta[];
|
||||||
} SMultiTableMeta;
|
} SMultiTableMeta;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -62,149 +62,154 @@
|
||||||
#define TK_SHOW 44
|
#define TK_SHOW 44
|
||||||
#define TK_DATABASES 45
|
#define TK_DATABASES 45
|
||||||
#define TK_TOPICS 46
|
#define TK_TOPICS 46
|
||||||
#define TK_MNODES 47
|
#define TK_FUNCTIONS 47
|
||||||
#define TK_DNODES 48
|
#define TK_MNODES 48
|
||||||
#define TK_ACCOUNTS 49
|
#define TK_DNODES 49
|
||||||
#define TK_USERS 50
|
#define TK_ACCOUNTS 50
|
||||||
#define TK_MODULES 51
|
#define TK_USERS 51
|
||||||
#define TK_QUERIES 52
|
#define TK_MODULES 52
|
||||||
#define TK_CONNECTIONS 53
|
#define TK_QUERIES 53
|
||||||
#define TK_STREAMS 54
|
#define TK_CONNECTIONS 54
|
||||||
#define TK_VARIABLES 55
|
#define TK_STREAMS 55
|
||||||
#define TK_SCORES 56
|
#define TK_VARIABLES 56
|
||||||
#define TK_GRANTS 57
|
#define TK_SCORES 57
|
||||||
#define TK_VNODES 58
|
#define TK_GRANTS 58
|
||||||
#define TK_IPTOKEN 59
|
#define TK_VNODES 59
|
||||||
#define TK_DOT 60
|
#define TK_IPTOKEN 60
|
||||||
#define TK_CREATE 61
|
#define TK_DOT 61
|
||||||
#define TK_TABLE 62
|
#define TK_CREATE 62
|
||||||
#define TK_STABLE 63
|
#define TK_TABLE 63
|
||||||
#define TK_DATABASE 64
|
#define TK_STABLE 64
|
||||||
#define TK_TABLES 65
|
#define TK_DATABASE 65
|
||||||
#define TK_STABLES 66
|
#define TK_TABLES 66
|
||||||
#define TK_VGROUPS 67
|
#define TK_STABLES 67
|
||||||
#define TK_DROP 68
|
#define TK_VGROUPS 68
|
||||||
#define TK_TOPIC 69
|
#define TK_DROP 69
|
||||||
#define TK_DNODE 70
|
#define TK_TOPIC 70
|
||||||
#define TK_USER 71
|
#define TK_FUNCTION 71
|
||||||
#define TK_ACCOUNT 72
|
#define TK_DNODE 72
|
||||||
#define TK_USE 73
|
#define TK_USER 73
|
||||||
#define TK_DESCRIBE 74
|
#define TK_ACCOUNT 74
|
||||||
#define TK_ALTER 75
|
#define TK_USE 75
|
||||||
#define TK_PASS 76
|
#define TK_DESCRIBE 76
|
||||||
#define TK_PRIVILEGE 77
|
#define TK_ALTER 77
|
||||||
#define TK_LOCAL 78
|
#define TK_PASS 78
|
||||||
#define TK_COMPACT 79
|
#define TK_PRIVILEGE 79
|
||||||
#define TK_LP 80
|
#define TK_LOCAL 80
|
||||||
#define TK_RP 81
|
#define TK_COMPACT 81
|
||||||
#define TK_IF 82
|
#define TK_LP 82
|
||||||
#define TK_EXISTS 83
|
#define TK_RP 83
|
||||||
#define TK_PPS 84
|
#define TK_IF 84
|
||||||
#define TK_TSERIES 85
|
#define TK_EXISTS 85
|
||||||
#define TK_DBS 86
|
#define TK_AS 86
|
||||||
#define TK_STORAGE 87
|
#define TK_OUTPUTTYPE 87
|
||||||
#define TK_QTIME 88
|
#define TK_AGGREGATE 88
|
||||||
#define TK_CONNS 89
|
#define TK_BUFSIZE 89
|
||||||
#define TK_STATE 90
|
#define TK_PPS 90
|
||||||
#define TK_COMMA 91
|
#define TK_TSERIES 91
|
||||||
#define TK_KEEP 92
|
#define TK_DBS 92
|
||||||
#define TK_CACHE 93
|
#define TK_STORAGE 93
|
||||||
#define TK_REPLICA 94
|
#define TK_QTIME 94
|
||||||
#define TK_QUORUM 95
|
#define TK_CONNS 95
|
||||||
#define TK_DAYS 96
|
#define TK_STATE 96
|
||||||
#define TK_MINROWS 97
|
#define TK_COMMA 97
|
||||||
#define TK_MAXROWS 98
|
#define TK_KEEP 98
|
||||||
#define TK_BLOCKS 99
|
#define TK_CACHE 99
|
||||||
#define TK_CTIME 100
|
#define TK_REPLICA 100
|
||||||
#define TK_WAL 101
|
#define TK_QUORUM 101
|
||||||
#define TK_FSYNC 102
|
#define TK_DAYS 102
|
||||||
#define TK_COMP 103
|
#define TK_MINROWS 103
|
||||||
#define TK_PRECISION 104
|
#define TK_MAXROWS 104
|
||||||
#define TK_UPDATE 105
|
#define TK_BLOCKS 105
|
||||||
#define TK_CACHELAST 106
|
#define TK_CTIME 106
|
||||||
#define TK_PARTITIONS 107
|
#define TK_WAL 107
|
||||||
#define TK_UNSIGNED 108
|
#define TK_FSYNC 108
|
||||||
#define TK_TAGS 109
|
#define TK_COMP 109
|
||||||
#define TK_USING 110
|
#define TK_PRECISION 110
|
||||||
#define TK_AS 111
|
#define TK_UPDATE 111
|
||||||
#define TK_NULL 112
|
#define TK_CACHELAST 112
|
||||||
#define TK_NOW 113
|
#define TK_PARTITIONS 113
|
||||||
#define TK_SELECT 114
|
#define TK_UNSIGNED 114
|
||||||
#define TK_UNION 115
|
#define TK_TAGS 115
|
||||||
#define TK_ALL 116
|
#define TK_USING 116
|
||||||
#define TK_DISTINCT 117
|
#define TK_NULL 117
|
||||||
#define TK_FROM 118
|
#define TK_NOW 118
|
||||||
#define TK_VARIABLE 119
|
#define TK_SELECT 119
|
||||||
#define TK_INTERVAL 120
|
#define TK_UNION 120
|
||||||
#define TK_SESSION 121
|
#define TK_ALL 121
|
||||||
#define TK_STATE_WINDOW 122
|
#define TK_DISTINCT 122
|
||||||
#define TK_FILL 123
|
#define TK_FROM 123
|
||||||
#define TK_SLIDING 124
|
#define TK_VARIABLE 124
|
||||||
#define TK_ORDER 125
|
#define TK_INTERVAL 125
|
||||||
#define TK_BY 126
|
#define TK_SESSION 126
|
||||||
#define TK_ASC 127
|
#define TK_STATE_WINDOW 127
|
||||||
#define TK_DESC 128
|
#define TK_FILL 128
|
||||||
#define TK_GROUP 129
|
#define TK_SLIDING 129
|
||||||
#define TK_HAVING 130
|
#define TK_ORDER 130
|
||||||
#define TK_LIMIT 131
|
#define TK_BY 131
|
||||||
#define TK_OFFSET 132
|
#define TK_ASC 132
|
||||||
#define TK_SLIMIT 133
|
#define TK_DESC 133
|
||||||
#define TK_SOFFSET 134
|
#define TK_GROUP 134
|
||||||
#define TK_WHERE 135
|
#define TK_HAVING 135
|
||||||
#define TK_RESET 136
|
#define TK_LIMIT 136
|
||||||
#define TK_QUERY 137
|
#define TK_OFFSET 137
|
||||||
#define TK_SYNCDB 138
|
#define TK_SLIMIT 138
|
||||||
#define TK_ADD 139
|
#define TK_SOFFSET 139
|
||||||
#define TK_COLUMN 140
|
#define TK_WHERE 140
|
||||||
#define TK_MODIFY 141
|
#define TK_RESET 141
|
||||||
#define TK_TAG 142
|
#define TK_QUERY 142
|
||||||
#define TK_CHANGE 143
|
#define TK_SYNCDB 143
|
||||||
#define TK_SET 144
|
#define TK_ADD 144
|
||||||
#define TK_KILL 145
|
#define TK_COLUMN 145
|
||||||
#define TK_CONNECTION 146
|
#define TK_MODIFY 146
|
||||||
#define TK_STREAM 147
|
#define TK_TAG 147
|
||||||
#define TK_COLON 148
|
#define TK_CHANGE 148
|
||||||
#define TK_ABORT 149
|
#define TK_SET 149
|
||||||
#define TK_AFTER 150
|
#define TK_KILL 150
|
||||||
#define TK_ATTACH 151
|
#define TK_CONNECTION 151
|
||||||
#define TK_BEFORE 152
|
#define TK_STREAM 152
|
||||||
#define TK_BEGIN 153
|
#define TK_COLON 153
|
||||||
#define TK_CASCADE 154
|
#define TK_ABORT 154
|
||||||
#define TK_CLUSTER 155
|
#define TK_AFTER 155
|
||||||
#define TK_CONFLICT 156
|
#define TK_ATTACH 156
|
||||||
#define TK_COPY 157
|
#define TK_BEFORE 157
|
||||||
#define TK_DEFERRED 158
|
#define TK_BEGIN 158
|
||||||
#define TK_DELIMITERS 159
|
#define TK_CASCADE 159
|
||||||
#define TK_DETACH 160
|
#define TK_CLUSTER 160
|
||||||
#define TK_EACH 161
|
#define TK_CONFLICT 161
|
||||||
#define TK_END 162
|
#define TK_COPY 162
|
||||||
#define TK_EXPLAIN 163
|
#define TK_DEFERRED 163
|
||||||
#define TK_FAIL 164
|
#define TK_DELIMITERS 164
|
||||||
#define TK_FOR 165
|
#define TK_DETACH 165
|
||||||
#define TK_IGNORE 166
|
#define TK_EACH 166
|
||||||
#define TK_IMMEDIATE 167
|
#define TK_END 167
|
||||||
#define TK_INITIALLY 168
|
#define TK_EXPLAIN 168
|
||||||
#define TK_INSTEAD 169
|
#define TK_FAIL 169
|
||||||
#define TK_MATCH 170
|
#define TK_FOR 170
|
||||||
#define TK_KEY 171
|
#define TK_IGNORE 171
|
||||||
#define TK_OF 172
|
#define TK_IMMEDIATE 172
|
||||||
#define TK_RAISE 173
|
#define TK_INITIALLY 173
|
||||||
#define TK_REPLACE 174
|
#define TK_INSTEAD 174
|
||||||
#define TK_RESTRICT 175
|
#define TK_MATCH 175
|
||||||
#define TK_ROW 176
|
#define TK_KEY 176
|
||||||
#define TK_STATEMENT 177
|
#define TK_OF 177
|
||||||
#define TK_TRIGGER 178
|
#define TK_RAISE 178
|
||||||
#define TK_VIEW 179
|
#define TK_REPLACE 179
|
||||||
#define TK_SEMI 180
|
#define TK_RESTRICT 180
|
||||||
#define TK_NONE 181
|
#define TK_ROW 181
|
||||||
#define TK_PREV 182
|
#define TK_STATEMENT 182
|
||||||
#define TK_LINEAR 183
|
#define TK_TRIGGER 183
|
||||||
#define TK_IMPORT 184
|
#define TK_VIEW 184
|
||||||
#define TK_TBNAME 185
|
#define TK_SEMI 185
|
||||||
#define TK_JOIN 186
|
#define TK_NONE 186
|
||||||
#define TK_INSERT 187
|
#define TK_PREV 187
|
||||||
#define TK_INTO 188
|
#define TK_LINEAR 188
|
||||||
#define TK_VALUES 189
|
#define TK_IMPORT 189
|
||||||
|
#define TK_TBNAME 190
|
||||||
|
#define TK_JOIN 191
|
||||||
|
#define TK_INSERT 192
|
||||||
|
#define TK_INTO 193
|
||||||
|
#define TK_VALUES 194
|
||||||
|
|
||||||
|
|
||||||
#define TK_SPACE 300
|
#define TK_SPACE 300
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,9 @@ extern "C" {
|
||||||
|
|
||||||
// ----------------- For variable data types such as TSDB_DATA_TYPE_BINARY and TSDB_DATA_TYPE_NCHAR
|
// ----------------- For variable data types such as TSDB_DATA_TYPE_BINARY and TSDB_DATA_TYPE_NCHAR
|
||||||
typedef int32_t VarDataOffsetT;
|
typedef int32_t VarDataOffsetT;
|
||||||
typedef int16_t VarDataLenT;
|
typedef int16_t VarDataLenT; // maxVarDataLen: 32767
|
||||||
|
typedef uint16_t TDRowLenT; // not including overhead: 0 ~ 65535
|
||||||
|
typedef uint32_t TDRowTLenT; // total length, including overhead
|
||||||
|
|
||||||
typedef struct tstr {
|
typedef struct tstr {
|
||||||
VarDataLenT len;
|
VarDataLenT len;
|
||||||
|
|
@ -28,6 +30,10 @@ typedef struct tstr {
|
||||||
#define varDataSetLen(v, _len) (((VarDataLenT *)(v))[0] = (VarDataLenT) (_len))
|
#define varDataSetLen(v, _len) (((VarDataLenT *)(v))[0] = (VarDataLenT) (_len))
|
||||||
#define IS_VAR_DATA_TYPE(t) (((t) == TSDB_DATA_TYPE_BINARY) || ((t) == TSDB_DATA_TYPE_NCHAR))
|
#define IS_VAR_DATA_TYPE(t) (((t) == TSDB_DATA_TYPE_BINARY) || ((t) == TSDB_DATA_TYPE_NCHAR))
|
||||||
|
|
||||||
|
#define varDataNetLen(v) (htons(((VarDataLenT *)(v))[0]))
|
||||||
|
#define varDataNetTLen(v) (sizeof(VarDataLenT) + varDataNetLen(v))
|
||||||
|
|
||||||
|
|
||||||
// this data type is internally used only in 'in' query to hold the values
|
// this data type is internally used only in 'in' query to hold the values
|
||||||
#define TSDB_DATA_TYPE_ARRAY (1000)
|
#define TSDB_DATA_TYPE_ARRAY (1000)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ typedef struct {
|
||||||
SRpcMsg rpcMsg;
|
SRpcMsg rpcMsg;
|
||||||
SRspRet rspRet;
|
SRspRet rspRet;
|
||||||
char reserveForSync[24];
|
char reserveForSync[24];
|
||||||
SWalHead pHead;
|
SWalHead walHead;
|
||||||
} SVWriteMsg;
|
} SVWriteMsg;
|
||||||
|
|
||||||
// vnodeStatus
|
// vnodeStatus
|
||||||
|
|
|
||||||
|
|
@ -19,9 +19,9 @@ ELSE ()
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
IF (TD_SOMODE_STATIC)
|
IF (TD_SOMODE_STATIC)
|
||||||
TARGET_LINK_LIBRARIES(shell taos_static ${LINK_JEMALLOC})
|
TARGET_LINK_LIBRARIES(shell taos_static lua ${LINK_JEMALLOC})
|
||||||
ELSE ()
|
ELSE ()
|
||||||
TARGET_LINK_LIBRARIES(shell taos ${LINK_JEMALLOC})
|
TARGET_LINK_LIBRARIES(shell taos lua ${LINK_JEMALLOC})
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
SET_TARGET_PROPERTIES(shell PROPERTIES OUTPUT_NAME taos)
|
SET_TARGET_PROPERTIES(shell PROPERTIES OUTPUT_NAME taos)
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ IF (TD_LINUX)
|
||||||
ADD_EXECUTABLE(taosdemo ${SRC})
|
ADD_EXECUTABLE(taosdemo ${SRC})
|
||||||
|
|
||||||
IF (TD_SOMODE_STATIC)
|
IF (TD_SOMODE_STATIC)
|
||||||
TARGET_LINK_LIBRARIES(taosdemo taos_static cJson ${LINK_JEMALLOC})
|
TARGET_LINK_LIBRARIES(taosdemo taos_static cJson lua ${LINK_JEMALLOC})
|
||||||
ELSE ()
|
ELSE ()
|
||||||
TARGET_LINK_LIBRARIES(taosdemo taos cJson ${LINK_JEMALLOC})
|
TARGET_LINK_LIBRARIES(taosdemo taos cJson ${LINK_JEMALLOC})
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
@ -76,9 +76,9 @@ ELSEIF (TD_WINDOWS)
|
||||||
ADD_EXECUTABLE(taosdemo ${SRC})
|
ADD_EXECUTABLE(taosdemo ${SRC})
|
||||||
SET_SOURCE_FILES_PROPERTIES(./taosdemo.c PROPERTIES COMPILE_FLAGS -w)
|
SET_SOURCE_FILES_PROPERTIES(./taosdemo.c PROPERTIES COMPILE_FLAGS -w)
|
||||||
IF (TD_SOMODE_STATIC)
|
IF (TD_SOMODE_STATIC)
|
||||||
TARGET_LINK_LIBRARIES(taosdemo taos_static cJson)
|
TARGET_LINK_LIBRARIES(taosdemo taos_static cJson lua)
|
||||||
ELSE ()
|
ELSE ()
|
||||||
TARGET_LINK_LIBRARIES(taosdemo taos cJson)
|
TARGET_LINK_LIBRARIES(taosdemo taos cJson lua)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
ELSEIF (TD_DARWIN)
|
ELSEIF (TD_DARWIN)
|
||||||
# missing a few dependencies, such as <argp.h>
|
# missing a few dependencies, such as <argp.h>
|
||||||
|
|
@ -86,9 +86,9 @@ ELSEIF (TD_DARWIN)
|
||||||
ADD_EXECUTABLE(taosdemo ${SRC})
|
ADD_EXECUTABLE(taosdemo ${SRC})
|
||||||
|
|
||||||
IF (TD_SOMODE_STATIC)
|
IF (TD_SOMODE_STATIC)
|
||||||
TARGET_LINK_LIBRARIES(taosdemo taos_static cJson)
|
TARGET_LINK_LIBRARIES(taosdemo taos_static cJson lua)
|
||||||
ELSE ()
|
ELSE ()
|
||||||
TARGET_LINK_LIBRARIES(taosdemo taos cJson)
|
TARGET_LINK_LIBRARIES(taosdemo taos cJson lua)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,7 @@
|
||||||
#include "tutil.h"
|
#include "tutil.h"
|
||||||
|
|
||||||
#define STMT_IFACE_ENABLED 1
|
#define STMT_IFACE_ENABLED 1
|
||||||
|
#define NANO_SECOND_ENABLED 1
|
||||||
|
|
||||||
#define REQ_EXTRA_BUF_LEN 1024
|
#define REQ_EXTRA_BUF_LEN 1024
|
||||||
#define RESP_BUF_LEN 4096
|
#define RESP_BUF_LEN 4096
|
||||||
|
|
@ -66,13 +67,6 @@ extern char configDir[];
|
||||||
|
|
||||||
#define STR_INSERT_INTO "INSERT INTO "
|
#define STR_INSERT_INTO "INSERT INTO "
|
||||||
|
|
||||||
enum TEST_MODE {
|
|
||||||
INSERT_TEST, // 0
|
|
||||||
QUERY_TEST, // 1
|
|
||||||
SUBSCRIBE_TEST, // 2
|
|
||||||
INVAID_TEST
|
|
||||||
};
|
|
||||||
|
|
||||||
#define MAX_RECORDS_PER_REQ 32766
|
#define MAX_RECORDS_PER_REQ 32766
|
||||||
|
|
||||||
#define HEAD_BUFF_LEN TSDB_MAX_COLUMNS*24 // 16*MAX_COLUMNS + (192+32)*2 + insert into ..
|
#define HEAD_BUFF_LEN TSDB_MAX_COLUMNS*24 // 16*MAX_COLUMNS + (192+32)*2 + insert into ..
|
||||||
|
|
@ -105,6 +99,13 @@ enum TEST_MODE {
|
||||||
#define DEFAULT_TIMESTAMP_STEP 1
|
#define DEFAULT_TIMESTAMP_STEP 1
|
||||||
|
|
||||||
|
|
||||||
|
enum TEST_MODE {
|
||||||
|
INSERT_TEST, // 0
|
||||||
|
QUERY_TEST, // 1
|
||||||
|
SUBSCRIBE_TEST, // 2
|
||||||
|
INVAID_TEST
|
||||||
|
};
|
||||||
|
|
||||||
typedef enum CREATE_SUB_TALBE_MOD_EN {
|
typedef enum CREATE_SUB_TALBE_MOD_EN {
|
||||||
PRE_CREATE_SUBTBL,
|
PRE_CREATE_SUBTBL,
|
||||||
AUTO_CREATE_SUBTBL,
|
AUTO_CREATE_SUBTBL,
|
||||||
|
|
@ -228,7 +229,7 @@ typedef struct SArguments_S {
|
||||||
int64_t num_of_DPT;
|
int64_t num_of_DPT;
|
||||||
int abort;
|
int abort;
|
||||||
uint32_t disorderRatio; // 0: no disorder, >0: x%
|
uint32_t disorderRatio; // 0: no disorder, >0: x%
|
||||||
int disorderRange; // ms or us by database precision
|
int disorderRange; // ms, us or ns. accordig to database precision
|
||||||
uint32_t method_of_delete;
|
uint32_t method_of_delete;
|
||||||
char ** arg_list;
|
char ** arg_list;
|
||||||
uint64_t totalInsertRows;
|
uint64_t totalInsertRows;
|
||||||
|
|
@ -259,7 +260,7 @@ typedef struct SSuperTable_S {
|
||||||
// int multiThreadWriteOneTbl; // 0: no, 1: yes
|
// int multiThreadWriteOneTbl; // 0: no, 1: yes
|
||||||
uint32_t interlaceRows; //
|
uint32_t interlaceRows; //
|
||||||
int disorderRatio; // 0: no disorder, >0: x%
|
int disorderRatio; // 0: no disorder, >0: x%
|
||||||
int disorderRange; // ms or us by database precision
|
int disorderRange; // ms, us or ns. according to database precision
|
||||||
uint64_t maxSqlLen; //
|
uint64_t maxSqlLen; //
|
||||||
|
|
||||||
uint64_t insertInterval; // insert interval, will override global insert interval
|
uint64_t insertInterval; // insert interval, will override global insert interval
|
||||||
|
|
@ -637,7 +638,7 @@ static FILE * g_fpOfInsertResult = NULL;
|
||||||
|
|
||||||
#define performancePrint(fmt, ...) \
|
#define performancePrint(fmt, ...) \
|
||||||
do { if (g_args.performance_print) \
|
do { if (g_args.performance_print) \
|
||||||
fprintf(stderr, "VERB: "fmt, __VA_ARGS__); } while(0)
|
fprintf(stderr, "PERF: "fmt, __VA_ARGS__); } while(0)
|
||||||
|
|
||||||
#define errorPrint(fmt, ...) \
|
#define errorPrint(fmt, ...) \
|
||||||
do { fprintf(stderr, "ERROR: "fmt, __VA_ARGS__); } while(0)
|
do { fprintf(stderr, "ERROR: "fmt, __VA_ARGS__); } while(0)
|
||||||
|
|
@ -1140,7 +1141,6 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) {
|
||||||
if (arguments->disorderRatio) {
|
if (arguments->disorderRatio) {
|
||||||
printf("# Data order: %d\n", arguments->disorderRatio);
|
printf("# Data order: %d\n", arguments->disorderRatio);
|
||||||
printf("# Data out of order rate: %d\n", arguments->disorderRange);
|
printf("# Data out of order rate: %d\n", arguments->disorderRange);
|
||||||
|
|
||||||
}
|
}
|
||||||
printf("# Delete method: %d\n", arguments->method_of_delete);
|
printf("# Delete method: %d\n", arguments->method_of_delete);
|
||||||
printf("# Answer yes when prompt: %d\n", arguments->answer_yes);
|
printf("# Answer yes when prompt: %d\n", arguments->answer_yes);
|
||||||
|
|
@ -1513,7 +1513,10 @@ static int printfInsertMeta() {
|
||||||
}
|
}
|
||||||
if (g_Dbs.db[i].dbCfg.precision[0] != 0) {
|
if (g_Dbs.db[i].dbCfg.precision[0] != 0) {
|
||||||
if ((0 == strncasecmp(g_Dbs.db[i].dbCfg.precision, "ms", 2))
|
if ((0 == strncasecmp(g_Dbs.db[i].dbCfg.precision, "ms", 2))
|
||||||
|| (0 == strncasecmp(g_Dbs.db[i].dbCfg.precision, "us", 2))) {
|
#if NANO_SECOND_ENABLED == 1
|
||||||
|
|| (0 == strncasecmp(g_Dbs.db[i].dbCfg.precision, "us", 2))
|
||||||
|
#endif
|
||||||
|
|| (0 == strncasecmp(g_Dbs.db[i].dbCfg.precision, "ns", 2))) {
|
||||||
printf(" precision: \033[33m%s\033[0m\n",
|
printf(" precision: \033[33m%s\033[0m\n",
|
||||||
g_Dbs.db[i].dbCfg.precision);
|
g_Dbs.db[i].dbCfg.precision);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1703,6 +1706,9 @@ static void printfInsertMetaToFile(FILE* fp) {
|
||||||
}
|
}
|
||||||
if (g_Dbs.db[i].dbCfg.precision[0] != 0) {
|
if (g_Dbs.db[i].dbCfg.precision[0] != 0) {
|
||||||
if ((0 == strncasecmp(g_Dbs.db[i].dbCfg.precision, "ms", 2))
|
if ((0 == strncasecmp(g_Dbs.db[i].dbCfg.precision, "ms", 2))
|
||||||
|
#if NANO_SECOND_ENABLED == 1
|
||||||
|
|| (0 == strncasecmp(g_Dbs.db[i].dbCfg.precision, "ns", 2))
|
||||||
|
#endif
|
||||||
|| (0 == strncasecmp(g_Dbs.db[i].dbCfg.precision, "us", 2))) {
|
|| (0 == strncasecmp(g_Dbs.db[i].dbCfg.precision, "us", 2))) {
|
||||||
fprintf(fp, " precision: %s\n",
|
fprintf(fp, " precision: %s\n",
|
||||||
g_Dbs.db[i].dbCfg.precision);
|
g_Dbs.db[i].dbCfg.precision);
|
||||||
|
|
@ -1903,10 +1909,12 @@ static void printfQueryMeta() {
|
||||||
|
|
||||||
static char* formatTimestamp(char* buf, int64_t val, int precision) {
|
static char* formatTimestamp(char* buf, int64_t val, int precision) {
|
||||||
time_t tt;
|
time_t tt;
|
||||||
if (precision == TSDB_TIME_PRECISION_NANO) {
|
if (precision == TSDB_TIME_PRECISION_MICRO) {
|
||||||
tt = (time_t)(val / 1000000000);
|
|
||||||
} else if (precision == TSDB_TIME_PRECISION_MICRO) {
|
|
||||||
tt = (time_t)(val / 1000000);
|
tt = (time_t)(val / 1000000);
|
||||||
|
#if NANO_SECOND_ENABLED == 1
|
||||||
|
} if (precision == TSDB_TIME_PRECISION_NANO) {
|
||||||
|
tt = (time_t)(val / 1000000000);
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
tt = (time_t)(val / 1000);
|
tt = (time_t)(val / 1000);
|
||||||
}
|
}
|
||||||
|
|
@ -1926,10 +1934,12 @@ static char* formatTimestamp(char* buf, int64_t val, int precision) {
|
||||||
struct tm* ptm = localtime(&tt);
|
struct tm* ptm = localtime(&tt);
|
||||||
size_t pos = strftime(buf, 32, "%Y-%m-%d %H:%M:%S", ptm);
|
size_t pos = strftime(buf, 32, "%Y-%m-%d %H:%M:%S", ptm);
|
||||||
|
|
||||||
if (precision == TSDB_TIME_PRECISION_NANO) {
|
if (precision == TSDB_TIME_PRECISION_MICRO) {
|
||||||
sprintf(buf + pos, ".%09d", (int)(val % 1000000000));
|
|
||||||
} else if (precision == TSDB_TIME_PRECISION_MICRO) {
|
|
||||||
sprintf(buf + pos, ".%06d", (int)(val % 1000000));
|
sprintf(buf + pos, ".%06d", (int)(val % 1000000));
|
||||||
|
#if NANO_SECOND_ENABLED == 1
|
||||||
|
} else if (precision == TSDB_TIME_PRECISION_NANO) {
|
||||||
|
sprintf(buf + pos, ".%09d", (int)(val % 1000000000));
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
sprintf(buf + pos, ".%03d", (int)(val % 1000));
|
sprintf(buf + pos, ".%03d", (int)(val % 1000));
|
||||||
}
|
}
|
||||||
|
|
@ -2185,7 +2195,6 @@ static void printfQuerySystemInfo(TAOS * taos) {
|
||||||
snprintf(buffer, MAX_QUERY_SQL_LENGTH, "show %s.stables;", dbInfos[i]->name);
|
snprintf(buffer, MAX_QUERY_SQL_LENGTH, "show %s.stables;", dbInfos[i]->name);
|
||||||
res = taos_query(taos, buffer);
|
res = taos_query(taos, buffer);
|
||||||
xDumpResultToFile(filename, res);
|
xDumpResultToFile(filename, res);
|
||||||
|
|
||||||
free(dbInfos[i]);
|
free(dbInfos[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2806,7 +2815,7 @@ static int createSuperTable(
|
||||||
if (strcasecmp(dataType, "BINARY") == 0) {
|
if (strcasecmp(dataType, "BINARY") == 0) {
|
||||||
if ((g_args.demo_mode) && (tagIndex == 1)) {
|
if ((g_args.demo_mode) && (tagIndex == 1)) {
|
||||||
len += snprintf(tags + len, STRING_LEN - len,
|
len += snprintf(tags + len, STRING_LEN - len,
|
||||||
"loction BINARY(%d), ",
|
"location BINARY(%d), ",
|
||||||
superTbl->tags[tagIndex].dataLen);
|
superTbl->tags[tagIndex].dataLen);
|
||||||
} else {
|
} else {
|
||||||
len += snprintf(tags + len, STRING_LEN - len, "t%d %s(%d), ",
|
len += snprintf(tags + len, STRING_LEN - len, "t%d %s(%d), ",
|
||||||
|
|
@ -2953,6 +2962,10 @@ static int createDatabasesAndStables() {
|
||||||
" fsync %d", g_Dbs.db[i].dbCfg.fsync);
|
" fsync %d", g_Dbs.db[i].dbCfg.fsync);
|
||||||
}
|
}
|
||||||
if ((0 == strncasecmp(g_Dbs.db[i].dbCfg.precision, "ms", strlen("ms")))
|
if ((0 == strncasecmp(g_Dbs.db[i].dbCfg.precision, "ms", strlen("ms")))
|
||||||
|
#if NANO_SECOND_ENABLED == 1
|
||||||
|
|| (0 == strncasecmp(g_Dbs.db[i].dbCfg.precision,
|
||||||
|
"ns", strlen("ns")))
|
||||||
|
#endif
|
||||||
|| (0 == strncasecmp(g_Dbs.db[i].dbCfg.precision,
|
|| (0 == strncasecmp(g_Dbs.db[i].dbCfg.precision,
|
||||||
"us", strlen("us")))) {
|
"us", strlen("us")))) {
|
||||||
dataLen += snprintf(command + dataLen, BUFFER_SIZE - dataLen,
|
dataLen += snprintf(command + dataLen, BUFFER_SIZE - dataLen,
|
||||||
|
|
@ -3183,8 +3196,10 @@ static void createChildTables() {
|
||||||
if (g_Dbs.db[i].superTblCount > 0) {
|
if (g_Dbs.db[i].superTblCount > 0) {
|
||||||
// with super table
|
// with super table
|
||||||
for (int j = 0; j < g_Dbs.db[i].superTblCount; j++) {
|
for (int j = 0; j < g_Dbs.db[i].superTblCount; j++) {
|
||||||
if ((AUTO_CREATE_SUBTBL == g_Dbs.db[i].superTbls[j].autoCreateTable)
|
if ((AUTO_CREATE_SUBTBL
|
||||||
|| (TBL_ALREADY_EXISTS == g_Dbs.db[i].superTbls[j].childTblExists)) {
|
== g_Dbs.db[i].superTbls[j].autoCreateTable)
|
||||||
|
|| (TBL_ALREADY_EXISTS
|
||||||
|
== g_Dbs.db[i].superTbls[j].childTblExists)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
verbosePrint("%s() LN%d: %s\n", __func__, __LINE__,
|
verbosePrint("%s() LN%d: %s\n", __func__, __LINE__,
|
||||||
|
|
@ -4156,6 +4171,22 @@ static bool getMetaFromInsertJsonFile(cJSON* root) {
|
||||||
goto PARSE_OVER;
|
goto PARSE_OVER;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
cJSON* insertRows = cJSON_GetObjectItem(stbInfo, "insert_rows");
|
||||||
|
if (insertRows && insertRows->type == cJSON_Number) {
|
||||||
|
if (insertRows->valueint < 0) {
|
||||||
|
errorPrint("%s() LN%d, failed to read json, insert_rows input mistake\n",
|
||||||
|
__func__, __LINE__);
|
||||||
|
goto PARSE_OVER;
|
||||||
|
}
|
||||||
|
g_Dbs.db[i].superTbls[j].insertRows = insertRows->valueint;
|
||||||
|
} else if (!insertRows) {
|
||||||
|
g_Dbs.db[i].superTbls[j].insertRows = 0x7FFFFFFFFFFFFFFF;
|
||||||
|
} else {
|
||||||
|
errorPrint("%s() LN%d, failed to read json, insert_rows input mistake\n",
|
||||||
|
__func__, __LINE__);
|
||||||
|
goto PARSE_OVER;
|
||||||
|
}
|
||||||
|
|
||||||
cJSON* stbInterlaceRows = cJSON_GetObjectItem(stbInfo, "interlace_rows");
|
cJSON* stbInterlaceRows = cJSON_GetObjectItem(stbInfo, "interlace_rows");
|
||||||
if (stbInterlaceRows && stbInterlaceRows->type == cJSON_Number) {
|
if (stbInterlaceRows && stbInterlaceRows->type == cJSON_Number) {
|
||||||
if (stbInterlaceRows->valueint < 0) {
|
if (stbInterlaceRows->valueint < 0) {
|
||||||
|
|
@ -4164,15 +4195,15 @@ static bool getMetaFromInsertJsonFile(cJSON* root) {
|
||||||
goto PARSE_OVER;
|
goto PARSE_OVER;
|
||||||
}
|
}
|
||||||
g_Dbs.db[i].superTbls[j].interlaceRows = stbInterlaceRows->valueint;
|
g_Dbs.db[i].superTbls[j].interlaceRows = stbInterlaceRows->valueint;
|
||||||
// rows per table need be less than insert batch
|
|
||||||
if (g_Dbs.db[i].superTbls[j].interlaceRows > g_args.num_of_RPR) {
|
if (g_Dbs.db[i].superTbls[j].interlaceRows > g_Dbs.db[i].superTbls[j].insertRows) {
|
||||||
printf("NOTICE: db[%d].superTbl[%d]'s interlace rows value %u > num_of_records_per_req %u\n\n",
|
printf("NOTICE: db[%d].superTbl[%d]'s interlace rows value %u > insert_rows %"PRId64"\n\n",
|
||||||
i, j, g_Dbs.db[i].superTbls[j].interlaceRows,
|
i, j, g_Dbs.db[i].superTbls[j].interlaceRows,
|
||||||
g_args.num_of_RPR);
|
g_Dbs.db[i].superTbls[j].insertRows);
|
||||||
printf(" interlace rows value will be set to num_of_records_per_req %u\n\n",
|
printf(" interlace rows value will be set to insert_rows %"PRId64"\n\n",
|
||||||
g_args.num_of_RPR);
|
g_Dbs.db[i].superTbls[j].insertRows);
|
||||||
prompt();
|
prompt();
|
||||||
g_Dbs.db[i].superTbls[j].interlaceRows = g_args.num_of_RPR;
|
g_Dbs.db[i].superTbls[j].interlaceRows = g_Dbs.db[i].superTbls[j].insertRows;
|
||||||
}
|
}
|
||||||
} else if (!stbInterlaceRows) {
|
} else if (!stbInterlaceRows) {
|
||||||
g_Dbs.db[i].superTbls[j].interlaceRows = 0; // 0 means progressive mode, > 0 mean interlace mode. max value is less or equ num_of_records_per_req
|
g_Dbs.db[i].superTbls[j].interlaceRows = 0; // 0 means progressive mode, > 0 mean interlace mode. max value is less or equ num_of_records_per_req
|
||||||
|
|
@ -4209,22 +4240,6 @@ static bool getMetaFromInsertJsonFile(cJSON* root) {
|
||||||
goto PARSE_OVER;
|
goto PARSE_OVER;
|
||||||
}
|
}
|
||||||
|
|
||||||
cJSON* insertRows = cJSON_GetObjectItem(stbInfo, "insert_rows");
|
|
||||||
if (insertRows && insertRows->type == cJSON_Number) {
|
|
||||||
if (insertRows->valueint < 0) {
|
|
||||||
errorPrint("%s() LN%d, failed to read json, insert_rows input mistake\n",
|
|
||||||
__func__, __LINE__);
|
|
||||||
goto PARSE_OVER;
|
|
||||||
}
|
|
||||||
g_Dbs.db[i].superTbls[j].insertRows = insertRows->valueint;
|
|
||||||
} else if (!insertRows) {
|
|
||||||
g_Dbs.db[i].superTbls[j].insertRows = 0x7FFFFFFFFFFFFFFF;
|
|
||||||
} else {
|
|
||||||
errorPrint("%s() LN%d, failed to read json, insert_rows input mistake\n",
|
|
||||||
__func__, __LINE__);
|
|
||||||
goto PARSE_OVER;
|
|
||||||
}
|
|
||||||
|
|
||||||
cJSON* insertInterval = cJSON_GetObjectItem(stbInfo, "insert_interval");
|
cJSON* insertInterval = cJSON_GetObjectItem(stbInfo, "insert_interval");
|
||||||
if (insertInterval && insertInterval->type == cJSON_Number) {
|
if (insertInterval && insertInterval->type == cJSON_Number) {
|
||||||
g_Dbs.db[i].superTbls[j].insertInterval = insertInterval->valueint;
|
g_Dbs.db[i].superTbls[j].insertInterval = insertInterval->valueint;
|
||||||
|
|
@ -4981,12 +4996,22 @@ static int64_t generateData(char *recBuf, char **data_type,
|
||||||
bool b = rand_bool() & 1;
|
bool b = rand_bool() & 1;
|
||||||
pstr += sprintf(pstr, ",%s", b ? "true" : "false");
|
pstr += sprintf(pstr, ",%s", b ? "true" : "false");
|
||||||
} else if (strcasecmp(data_type[i % columnCount], "BINARY") == 0) {
|
} else if (strcasecmp(data_type[i % columnCount], "BINARY") == 0) {
|
||||||
char *s = malloc(lenOfBinary);
|
char *s = malloc(lenOfBinary + 1);
|
||||||
|
if (s == NULL) {
|
||||||
|
errorPrint("%s() LN%d, memory allocation %d bytes failed\n",
|
||||||
|
__func__, __LINE__, lenOfBinary + 1);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
rand_string(s, lenOfBinary);
|
rand_string(s, lenOfBinary);
|
||||||
pstr += sprintf(pstr, ",\"%s\"", s);
|
pstr += sprintf(pstr, ",\"%s\"", s);
|
||||||
free(s);
|
free(s);
|
||||||
} else if (strcasecmp(data_type[i % columnCount], "NCHAR") == 0) {
|
} else if (strcasecmp(data_type[i % columnCount], "NCHAR") == 0) {
|
||||||
char *s = malloc(lenOfBinary);
|
char *s = malloc(lenOfBinary + 1);
|
||||||
|
if (s == NULL) {
|
||||||
|
errorPrint("%s() LN%d, memory allocation %d bytes failed\n",
|
||||||
|
__func__, __LINE__, lenOfBinary + 1);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
rand_string(s, lenOfBinary);
|
rand_string(s, lenOfBinary);
|
||||||
pstr += sprintf(pstr, ",\"%s\"", s);
|
pstr += sprintf(pstr, ",\"%s\"", s);
|
||||||
free(s);
|
free(s);
|
||||||
|
|
@ -5143,12 +5168,18 @@ static int32_t generateDataTailWithoutStb(
|
||||||
char **data_type = g_args.datatype;
|
char **data_type = g_args.datatype;
|
||||||
int lenOfBinary = g_args.len_of_binary;
|
int lenOfBinary = g_args.len_of_binary;
|
||||||
|
|
||||||
|
if (g_args.disorderRatio) {
|
||||||
retLen = generateData(data, data_type,
|
retLen = generateData(data, data_type,
|
||||||
startTime + getTSRandTail(
|
startTime + getTSRandTail(
|
||||||
(int64_t) DEFAULT_TIMESTAMP_STEP, k,
|
(int64_t) DEFAULT_TIMESTAMP_STEP, k,
|
||||||
g_args.disorderRatio,
|
g_args.disorderRatio,
|
||||||
g_args.disorderRange),
|
g_args.disorderRange),
|
||||||
lenOfBinary);
|
lenOfBinary);
|
||||||
|
} else {
|
||||||
|
retLen = generateData(data, data_type,
|
||||||
|
startTime + (int64_t) (DEFAULT_TIMESTAMP_STEP* k),
|
||||||
|
lenOfBinary);
|
||||||
|
}
|
||||||
|
|
||||||
if (len > remainderBufLen)
|
if (len > remainderBufLen)
|
||||||
break;
|
break;
|
||||||
|
|
@ -5207,7 +5238,7 @@ static int32_t generateStbDataTail(
|
||||||
verbosePrint("%s() LN%d batch=%u buflen=%"PRId64"\n",
|
verbosePrint("%s() LN%d batch=%u buflen=%"PRId64"\n",
|
||||||
__func__, __LINE__, batch, remainderBufLen);
|
__func__, __LINE__, batch, remainderBufLen);
|
||||||
|
|
||||||
int32_t k = 0;
|
int32_t k;
|
||||||
for (k = 0; k < batch;) {
|
for (k = 0; k < batch;) {
|
||||||
char data[MAX_DATA_SIZE];
|
char data[MAX_DATA_SIZE];
|
||||||
memset(data, 0, MAX_DATA_SIZE);
|
memset(data, 0, MAX_DATA_SIZE);
|
||||||
|
|
@ -5215,12 +5246,18 @@ static int32_t generateStbDataTail(
|
||||||
int64_t lenOfRow = 0;
|
int64_t lenOfRow = 0;
|
||||||
|
|
||||||
if (tsRand) {
|
if (tsRand) {
|
||||||
|
if (superTblInfo->disorderRatio > 0) {
|
||||||
lenOfRow = generateStbRowData(superTblInfo, data,
|
lenOfRow = generateStbRowData(superTblInfo, data,
|
||||||
startTime + getTSRandTail(
|
startTime + getTSRandTail(
|
||||||
superTblInfo->timeStampStep, k,
|
superTblInfo->timeStampStep, k,
|
||||||
superTblInfo->disorderRatio,
|
superTblInfo->disorderRatio,
|
||||||
superTblInfo->disorderRange)
|
superTblInfo->disorderRange)
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
lenOfRow = generateStbRowData(superTblInfo, data,
|
||||||
|
startTime + superTblInfo->timeStampStep * k
|
||||||
|
);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
lenOfRow = getRowDataFromSample(
|
lenOfRow = getRowDataFromSample(
|
||||||
data,
|
data,
|
||||||
|
|
@ -5656,10 +5693,15 @@ static int32_t prepareStmtWithoutStb(
|
||||||
|
|
||||||
bind_ts = (int64_t *)ptr;
|
bind_ts = (int64_t *)ptr;
|
||||||
bind->buffer_type = TSDB_DATA_TYPE_TIMESTAMP;
|
bind->buffer_type = TSDB_DATA_TYPE_TIMESTAMP;
|
||||||
|
|
||||||
|
if (g_args.disorderRatio) {
|
||||||
*bind_ts = startTime + getTSRandTail(
|
*bind_ts = startTime + getTSRandTail(
|
||||||
(int64_t)DEFAULT_TIMESTAMP_STEP, k,
|
(int64_t)DEFAULT_TIMESTAMP_STEP, k,
|
||||||
g_args.disorderRatio,
|
g_args.disorderRatio,
|
||||||
g_args.disorderRange);
|
g_args.disorderRange);
|
||||||
|
} else {
|
||||||
|
*bind_ts = startTime + (int64_t)(DEFAULT_TIMESTAMP_STEP * k);
|
||||||
|
}
|
||||||
bind->buffer_length = sizeof(int64_t);
|
bind->buffer_length = sizeof(int64_t);
|
||||||
bind->buffer = bind_ts;
|
bind->buffer = bind_ts;
|
||||||
bind->length = &bind->buffer_length;
|
bind->length = &bind->buffer_length;
|
||||||
|
|
@ -5744,7 +5786,7 @@ static int32_t prepareStbStmt(
|
||||||
|
|
||||||
bind_ts = (int64_t *)ptr;
|
bind_ts = (int64_t *)ptr;
|
||||||
bind->buffer_type = TSDB_DATA_TYPE_TIMESTAMP;
|
bind->buffer_type = TSDB_DATA_TYPE_TIMESTAMP;
|
||||||
if (sourceRand) {
|
if (stbInfo->disorderRatio) {
|
||||||
*bind_ts = startTime + getTSRandTail(
|
*bind_ts = startTime + getTSRandTail(
|
||||||
stbInfo->timeStampStep, k,
|
stbInfo->timeStampStep, k,
|
||||||
stbInfo->disorderRatio,
|
stbInfo->disorderRatio,
|
||||||
|
|
@ -5811,6 +5853,7 @@ static int32_t prepareStbStmt(
|
||||||
if (!sourceRand) {
|
if (!sourceRand) {
|
||||||
(*pSamplePos) ++;
|
(*pSamplePos) ++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (recordFrom >= insertRows) {
|
if (recordFrom >= insertRows) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -5820,6 +5863,43 @@ static int32_t prepareStbStmt(
|
||||||
free(bindArray);
|
free(bindArray);
|
||||||
return k;
|
return k;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t prepareStbStmtInterlace(
|
||||||
|
SSuperTable *stbInfo,
|
||||||
|
TAOS_STMT *stmt,
|
||||||
|
char *tableName, uint32_t batch,
|
||||||
|
uint64_t insertRows,
|
||||||
|
uint64_t recordFrom,
|
||||||
|
int64_t startTime,
|
||||||
|
int64_t *pSamplePos)
|
||||||
|
{
|
||||||
|
return prepareStbStmt(
|
||||||
|
stbInfo,
|
||||||
|
stmt,
|
||||||
|
tableName,
|
||||||
|
batch,
|
||||||
|
insertRows, 0, startTime,
|
||||||
|
pSamplePos);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t prepareStbStmtProgressive(
|
||||||
|
SSuperTable *stbInfo,
|
||||||
|
TAOS_STMT *stmt,
|
||||||
|
char *tableName, uint32_t batch,
|
||||||
|
uint64_t insertRows,
|
||||||
|
uint64_t recordFrom,
|
||||||
|
int64_t startTime,
|
||||||
|
int64_t *pSamplePos)
|
||||||
|
{
|
||||||
|
return prepareStbStmt(
|
||||||
|
stbInfo,
|
||||||
|
stmt,
|
||||||
|
tableName,
|
||||||
|
g_args.num_of_RPR,
|
||||||
|
insertRows, recordFrom, startTime,
|
||||||
|
pSamplePos);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int32_t generateStbProgressiveData(
|
static int32_t generateStbProgressiveData(
|
||||||
|
|
@ -5893,7 +5973,9 @@ static void printStatPerThread(threadInfo *pThreadInfo)
|
||||||
pThreadInfo->threadID,
|
pThreadInfo->threadID,
|
||||||
pThreadInfo->totalInsertRows,
|
pThreadInfo->totalInsertRows,
|
||||||
pThreadInfo->totalAffectedRows,
|
pThreadInfo->totalAffectedRows,
|
||||||
(pThreadInfo->totalDelay)?(double)((pThreadInfo->totalAffectedRows / (pThreadInfo->totalDelay)/1000.0)): FLT_MAX);
|
(pThreadInfo->totalDelay/1000.0)?
|
||||||
|
(double)(pThreadInfo->totalAffectedRows/(pThreadInfo->totalDelay/1000.0)):
|
||||||
|
FLT_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
// sync write interlace data
|
// sync write interlace data
|
||||||
|
|
@ -5992,7 +6074,7 @@ static void* syncWriteInterlace(threadInfo *pThreadInfo) {
|
||||||
|
|
||||||
uint32_t recOfBatch = 0;
|
uint32_t recOfBatch = 0;
|
||||||
|
|
||||||
for (uint32_t i = 0; i < batchPerTblTimes; i ++) {
|
for (uint64_t i = 0; i < batchPerTblTimes; i ++) {
|
||||||
char tableName[TSDB_TABLE_NAME_LEN];
|
char tableName[TSDB_TABLE_NAME_LEN];
|
||||||
|
|
||||||
getTableName(tableName, pThreadInfo, tableSeq);
|
getTableName(tableName, pThreadInfo, tableSeq);
|
||||||
|
|
@ -6009,7 +6091,7 @@ static void* syncWriteInterlace(threadInfo *pThreadInfo) {
|
||||||
if (superTblInfo) {
|
if (superTblInfo) {
|
||||||
if (superTblInfo->iface == STMT_IFACE) {
|
if (superTblInfo->iface == STMT_IFACE) {
|
||||||
#if STMT_IFACE_ENABLED == 1
|
#if STMT_IFACE_ENABLED == 1
|
||||||
generated = prepareStbStmt(
|
generated = prepareStbStmtInterlace(
|
||||||
superTblInfo,
|
superTblInfo,
|
||||||
pThreadInfo->stmt,
|
pThreadInfo->stmt,
|
||||||
tableName,
|
tableName,
|
||||||
|
|
@ -6238,7 +6320,7 @@ static void* syncWriteProgressive(threadInfo *pThreadInfo) {
|
||||||
if (superTblInfo) {
|
if (superTblInfo) {
|
||||||
if (superTblInfo->iface == STMT_IFACE) {
|
if (superTblInfo->iface == STMT_IFACE) {
|
||||||
#if STMT_IFACE_ENABLED == 1
|
#if STMT_IFACE_ENABLED == 1
|
||||||
generated = prepareStbStmt(
|
generated = prepareStbStmtProgressive(
|
||||||
superTblInfo,
|
superTblInfo,
|
||||||
pThreadInfo->stmt,
|
pThreadInfo->stmt,
|
||||||
tableName,
|
tableName,
|
||||||
|
|
@ -6480,8 +6562,10 @@ static void startMultiThreadInsertData(int threads, char* db_name,
|
||||||
timePrec = TSDB_TIME_PRECISION_MILLI;
|
timePrec = TSDB_TIME_PRECISION_MILLI;
|
||||||
} else if (0 == strncasecmp(precision, "us", 2)) {
|
} else if (0 == strncasecmp(precision, "us", 2)) {
|
||||||
timePrec = TSDB_TIME_PRECISION_MICRO;
|
timePrec = TSDB_TIME_PRECISION_MICRO;
|
||||||
|
#if NANO_SECOND_ENABLED == 1
|
||||||
} else if (0 == strncasecmp(precision, "ns", 2)) {
|
} else if (0 == strncasecmp(precision, "ns", 2)) {
|
||||||
timePrec = TSDB_TIME_PRECISION_NANO;
|
timePrec = TSDB_TIME_PRECISION_NANO;
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
errorPrint("Not support precision: %s\n", precision);
|
errorPrint("Not support precision: %s\n", precision);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
|
|
@ -6668,13 +6752,26 @@ static void startMultiThreadInsertData(int threads, char* db_name,
|
||||||
|
|
||||||
char buffer[3000];
|
char buffer[3000];
|
||||||
char *pstr = buffer;
|
char *pstr = buffer;
|
||||||
pstr += sprintf(pstr, "INSERT INTO ? values(?");
|
|
||||||
|
if ((superTblInfo)
|
||||||
|
&& (AUTO_CREATE_SUBTBL
|
||||||
|
== superTblInfo->autoCreateTable)) {
|
||||||
|
pstr += sprintf(pstr, "INSERT INTO ? USING %s TAGS(?",
|
||||||
|
superTblInfo->sTblName);
|
||||||
|
for (int tag = 0; tag < (superTblInfo->tagCount - 1); tag ++ ) {
|
||||||
|
pstr += sprintf(pstr, ",?");
|
||||||
|
}
|
||||||
|
pstr += sprintf(pstr, ") VALUES(?");
|
||||||
|
} else {
|
||||||
|
pstr += sprintf(pstr, "INSERT INTO ? VALUES(?");
|
||||||
|
}
|
||||||
|
|
||||||
for (int col = 0; col < columnCount; col ++) {
|
for (int col = 0; col < columnCount; col ++) {
|
||||||
pstr += sprintf(pstr, ",?");
|
pstr += sprintf(pstr, ",?");
|
||||||
}
|
}
|
||||||
pstr += sprintf(pstr, ")");
|
pstr += sprintf(pstr, ")");
|
||||||
|
|
||||||
|
debugPrint("%s() LN%d, buffer: %s", __func__, __LINE__, buffer);
|
||||||
int ret = taos_stmt_prepare(pThreadInfo->stmt, buffer, 0);
|
int ret = taos_stmt_prepare(pThreadInfo->stmt, buffer, 0);
|
||||||
if (ret != 0){
|
if (ret != 0){
|
||||||
errorPrint("failed to execute taos_stmt_prepare. return 0x%x. reason: %s\n",
|
errorPrint("failed to execute taos_stmt_prepare. return 0x%x. reason: %s\n",
|
||||||
|
|
@ -6758,34 +6855,40 @@ static void startMultiThreadInsertData(int threads, char* db_name,
|
||||||
int64_t end = taosGetTimestampMs();
|
int64_t end = taosGetTimestampMs();
|
||||||
int64_t t = end - start;
|
int64_t t = end - start;
|
||||||
|
|
||||||
|
double tInMs = t/1000.0;
|
||||||
|
|
||||||
if (superTblInfo) {
|
if (superTblInfo) {
|
||||||
fprintf(stderr, "Spent %.2f seconds to insert rows: %"PRIu64", affected rows: %"PRIu64" with %d thread(s) into %s.%s. %.2f records/second\n\n",
|
fprintf(stderr, "Spent %.2f seconds to insert rows: %"PRIu64", affected rows: %"PRIu64" with %d thread(s) into %s.%s. %.2f records/second\n\n",
|
||||||
t / 1000.0, superTblInfo->totalInsertRows,
|
tInMs, superTblInfo->totalInsertRows,
|
||||||
superTblInfo->totalAffectedRows,
|
superTblInfo->totalAffectedRows,
|
||||||
threads, db_name, superTblInfo->sTblName,
|
threads, db_name, superTblInfo->sTblName,
|
||||||
(double)superTblInfo->totalInsertRows / (t / 1000.0));
|
(tInMs)?
|
||||||
|
(double)(superTblInfo->totalInsertRows/tInMs):FLT_MAX);
|
||||||
|
|
||||||
if (g_fpOfInsertResult) {
|
if (g_fpOfInsertResult) {
|
||||||
fprintf(g_fpOfInsertResult,
|
fprintf(g_fpOfInsertResult,
|
||||||
"Spent %.2f seconds to insert rows: %"PRIu64", affected rows: %"PRIu64" with %d thread(s) into %s.%s. %.2f records/second\n\n",
|
"Spent %.2f seconds to insert rows: %"PRIu64", affected rows: %"PRIu64" with %d thread(s) into %s.%s. %.2f records/second\n\n",
|
||||||
t / 1000.0, superTblInfo->totalInsertRows,
|
tInMs, superTblInfo->totalInsertRows,
|
||||||
superTblInfo->totalAffectedRows,
|
superTblInfo->totalAffectedRows,
|
||||||
threads, db_name, superTblInfo->sTblName,
|
threads, db_name, superTblInfo->sTblName,
|
||||||
(double)superTblInfo->totalInsertRows / (t / 1000.0));
|
(tInMs)?
|
||||||
|
(double)(superTblInfo->totalInsertRows/tInMs):FLT_MAX);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Spent %.2f seconds to insert rows: %"PRIu64", affected rows: %"PRIu64" with %d thread(s) into %s %.2f records/second\n\n",
|
fprintf(stderr, "Spent %.2f seconds to insert rows: %"PRIu64", affected rows: %"PRIu64" with %d thread(s) into %s %.2f records/second\n\n",
|
||||||
t / 1000.0, g_args.totalInsertRows,
|
tInMs, g_args.totalInsertRows,
|
||||||
g_args.totalAffectedRows,
|
g_args.totalAffectedRows,
|
||||||
threads, db_name,
|
threads, db_name,
|
||||||
(double)g_args.totalInsertRows / (t / 1000.0));
|
(tInMs)?
|
||||||
|
(double)(g_args.totalInsertRows/tInMs):FLT_MAX);
|
||||||
if (g_fpOfInsertResult) {
|
if (g_fpOfInsertResult) {
|
||||||
fprintf(g_fpOfInsertResult,
|
fprintf(g_fpOfInsertResult,
|
||||||
"Spent %.2f seconds to insert rows: %"PRIu64", affected rows: %"PRIu64" with %d thread(s) into %s %.2f records/second\n\n",
|
"Spent %.2f seconds to insert rows: %"PRIu64", affected rows: %"PRIu64" with %d thread(s) into %s %.2f records/second\n\n",
|
||||||
t * 1000.0, g_args.totalInsertRows,
|
tInMs, g_args.totalInsertRows,
|
||||||
g_args.totalAffectedRows,
|
g_args.totalAffectedRows,
|
||||||
threads, db_name,
|
threads, db_name,
|
||||||
(double)g_args.totalInsertRows / (t / 1000.0));
|
(tInMs)?
|
||||||
|
(double)(g_args.totalInsertRows/tInMs):FLT_MAX);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -214,6 +214,23 @@ typedef struct SUserObj {
|
||||||
struct SAcctObj * pAcct;
|
struct SAcctObj * pAcct;
|
||||||
} SUserObj;
|
} SUserObj;
|
||||||
|
|
||||||
|
typedef struct SFuncObj {
|
||||||
|
char name[TSDB_FUNC_NAME_LEN];
|
||||||
|
char path[128];
|
||||||
|
int32_t contLen;
|
||||||
|
char cont[TSDB_FUNC_CODE_LEN];
|
||||||
|
int32_t funcType;
|
||||||
|
int32_t bufSize;
|
||||||
|
int64_t createdTime;
|
||||||
|
uint8_t resType;
|
||||||
|
int16_t resBytes;
|
||||||
|
int64_t sig; // partial md5 sign
|
||||||
|
int16_t type; // [lua script|so|js]
|
||||||
|
int8_t reserved[64];
|
||||||
|
int8_t updateEnd[4];
|
||||||
|
int32_t refCount;
|
||||||
|
} SFuncObj;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int64_t totalStorage; // Total storage wrtten from this account
|
int64_t totalStorage; // Total storage wrtten from this account
|
||||||
int64_t compStorage; // Compressed storage on disk
|
int64_t compStorage; // Compressed storage on disk
|
||||||
|
|
@ -258,7 +275,7 @@ typedef struct {
|
||||||
void * pIter;
|
void * pIter;
|
||||||
void ** ppShow;
|
void ** ppShow;
|
||||||
int16_t offset[TSDB_MAX_COLUMNS];
|
int16_t offset[TSDB_MAX_COLUMNS];
|
||||||
int16_t bytes[TSDB_MAX_COLUMNS];
|
int32_t bytes[TSDB_MAX_COLUMNS];
|
||||||
int32_t numOfReads;
|
int32_t numOfReads;
|
||||||
int8_t maxReplica;
|
int8_t maxReplica;
|
||||||
int8_t reserved0[1];
|
int8_t reserved0[1];
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* 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_MNODE_FUNC_H
|
||||||
|
#define TDENGINE_MNODE_FUNC_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
#include "mnodeDef.h"
|
||||||
|
|
||||||
|
int32_t mnodeInitFuncs();
|
||||||
|
void mnodeCleanupFuncs();
|
||||||
|
|
||||||
|
SFuncObj *mnodeGetFunc(char *name);
|
||||||
|
void * mnodeGetNextFunc(void *pIter, SFuncObj **pFunc);
|
||||||
|
void mnodeCancelGetNextFunc(void *pIter);
|
||||||
|
|
||||||
|
void mnodeIncFuncRef(SFuncObj *pFunc);
|
||||||
|
void mnodeDecFuncRef(SFuncObj *pFunc);
|
||||||
|
|
||||||
|
int32_t mnodeCreateFunc(SAcctObj *pAcct, char *name, int32_t codeLen, char *code, char *path, uint8_t outputType, int16_t outputLen, int32_t funcType, int32_t bufSize, SMnodeMsg *pMsg);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -33,7 +33,8 @@ typedef enum {
|
||||||
SDB_TABLE_VGROUP = 6,
|
SDB_TABLE_VGROUP = 6,
|
||||||
SDB_TABLE_STABLE = 7,
|
SDB_TABLE_STABLE = 7,
|
||||||
SDB_TABLE_CTABLE = 8,
|
SDB_TABLE_CTABLE = 8,
|
||||||
SDB_TABLE_MAX = 9
|
SDB_TABLE_FUNC = 9,
|
||||||
|
SDB_TABLE_MAX = 10
|
||||||
} ESdbTable;
|
} ESdbTable;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|
|
||||||
|
|
@ -554,6 +554,9 @@ void mnodeCleanupDbs() {
|
||||||
tsDbSdb = NULL;
|
tsDbSdb = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int32_t mnodeGetDbMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn) {
|
static int32_t mnodeGetDbMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn) {
|
||||||
int32_t cols = 0;
|
int32_t cols = 0;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,485 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define _DEFAULT_SOURCE
|
||||||
|
#include "os.h"
|
||||||
|
#include "trpc.h"
|
||||||
|
#include "tutil.h"
|
||||||
|
#include "tglobal.h"
|
||||||
|
#include "tgrant.h"
|
||||||
|
#include "tdataformat.h"
|
||||||
|
#include "tkey.h"
|
||||||
|
#include "mnode.h"
|
||||||
|
#include "dnode.h"
|
||||||
|
#include "mnodeDef.h"
|
||||||
|
#include "mnodeInt.h"
|
||||||
|
#include "mnodeAcct.h"
|
||||||
|
#include "mnodeUser.h"
|
||||||
|
#include "mnodeMnode.h"
|
||||||
|
#include "mnodeSdb.h"
|
||||||
|
#include "mnodeShow.h"
|
||||||
|
#include "mnodeFunc.h"
|
||||||
|
#include "mnodeWrite.h"
|
||||||
|
#include "mnodeRead.h"
|
||||||
|
#include "mnodePeer.h"
|
||||||
|
|
||||||
|
int64_t tsFuncRid = -1;
|
||||||
|
static void * tsFuncSdb = NULL;
|
||||||
|
static int32_t tsFuncUpdateSize = 0;
|
||||||
|
static int32_t mnodeGetFuncMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn);
|
||||||
|
static int32_t mnodeRetrieveFuncs(SShowObj *pShow, char *data, int32_t rows, void *pConn);
|
||||||
|
static int32_t mnodeProcessRetrieveFuncImplMsg(SMnodeMsg *pMsg);
|
||||||
|
static int32_t mnodeProcessCreateFuncMsg(SMnodeMsg *pMsg);
|
||||||
|
static int32_t mnodeProcessDropFuncMsg(SMnodeMsg *pMsg);
|
||||||
|
|
||||||
|
static int32_t mnodeFuncActionDestroy(SSdbRow *pRow) {
|
||||||
|
tfree(pRow->pObj);
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mnodeFuncActionInsert(SSdbRow *pRow) {
|
||||||
|
SFuncObj *pFunc = pRow->pObj;
|
||||||
|
|
||||||
|
mTrace("func:%s, contLen: %d, insert into sdb", pFunc->name, pFunc->contLen);
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mnodeFuncActionDelete(SSdbRow *pRow) {
|
||||||
|
SFuncObj *pFunc = pRow->pObj;
|
||||||
|
|
||||||
|
mTrace("func:%s, length: %d, delete from sdb", pFunc->name, pFunc->contLen);
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mnodeFuncActionUpdate(SSdbRow *pRow) {
|
||||||
|
SFuncObj *pFunc = pRow->pObj;
|
||||||
|
|
||||||
|
SFuncObj *pSaved = mnodeGetFunc(pFunc->name);
|
||||||
|
if (pFunc != pSaved) {
|
||||||
|
memcpy(pSaved, pFunc, tsFuncUpdateSize);
|
||||||
|
free(pFunc);
|
||||||
|
}
|
||||||
|
|
||||||
|
mnodeDecFuncRef(pSaved);
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mnodeFuncActionEncode(SSdbRow *pRow) {
|
||||||
|
SFuncObj *pFunc = pRow->pObj;
|
||||||
|
|
||||||
|
memcpy(pRow->rowData, pFunc, tsFuncUpdateSize);
|
||||||
|
pRow->rowSize = tsFuncUpdateSize;
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mnodeFuncActionDecode(SSdbRow *pRow) {
|
||||||
|
SFuncObj *pFunc = (SFuncObj *)calloc(1, sizeof(SFuncObj));
|
||||||
|
if (pFunc == NULL) return TSDB_CODE_MND_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
memcpy(pFunc, pRow->rowData, tsFuncUpdateSize);
|
||||||
|
pRow->pObj = pFunc;
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mnodeFuncActionRestored() {
|
||||||
|
int64_t numOfRows = sdbGetNumOfRows(tsFuncSdb);
|
||||||
|
|
||||||
|
if (numOfRows <= 0 && dnodeIsFirstDeploy()) {
|
||||||
|
mInfo("dnode first deploy, func restored.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mnodeInitFuncs() {
|
||||||
|
SFuncObj tObj;
|
||||||
|
tsFuncUpdateSize = (int32_t)((int8_t *)tObj.updateEnd - (int8_t *)&tObj);
|
||||||
|
|
||||||
|
SSdbTableDesc desc = {
|
||||||
|
.id = SDB_TABLE_FUNC,
|
||||||
|
.name = "funcs",
|
||||||
|
.hashSessions = TSDB_DEFAULT_USERS_HASH_SIZE,
|
||||||
|
.maxRowSize = tsFuncUpdateSize,
|
||||||
|
.refCountPos = (int32_t)((int8_t *)(&tObj.refCount) - (int8_t *)&tObj),
|
||||||
|
.keyType = SDB_KEY_STRING,
|
||||||
|
.fpInsert = mnodeFuncActionInsert,
|
||||||
|
.fpDelete = mnodeFuncActionDelete,
|
||||||
|
.fpUpdate = mnodeFuncActionUpdate,
|
||||||
|
.fpEncode = mnodeFuncActionEncode,
|
||||||
|
.fpDecode = mnodeFuncActionDecode,
|
||||||
|
.fpDestroy = mnodeFuncActionDestroy,
|
||||||
|
.fpRestored = mnodeFuncActionRestored
|
||||||
|
};
|
||||||
|
|
||||||
|
tsFuncRid = sdbOpenTable(&desc);
|
||||||
|
tsFuncSdb = sdbGetTableByRid(tsFuncRid);
|
||||||
|
if (tsFuncSdb == NULL) {
|
||||||
|
mError("table:%s, failed to create hash", desc.name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
mnodeAddWriteMsgHandle(TSDB_MSG_TYPE_CM_CREATE_FUNCTION, mnodeProcessCreateFuncMsg);
|
||||||
|
mnodeAddWriteMsgHandle(TSDB_MSG_TYPE_CM_DROP_FUNCTION, mnodeProcessDropFuncMsg);
|
||||||
|
mnodeAddReadMsgHandle(TSDB_MSG_TYPE_CM_RETRIEVE_FUNC, mnodeProcessRetrieveFuncImplMsg);
|
||||||
|
|
||||||
|
mnodeAddShowMetaHandle(TSDB_MGMT_TABLE_FUNCTION, mnodeGetFuncMeta);
|
||||||
|
mnodeAddShowRetrieveHandle(TSDB_MGMT_TABLE_FUNCTION, mnodeRetrieveFuncs);
|
||||||
|
mnodeAddShowFreeIterHandle(TSDB_MGMT_TABLE_FUNCTION, mnodeCancelGetNextFunc);
|
||||||
|
|
||||||
|
mDebug("table:%s, hash is created", desc.name);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mnodeCleanupFuncs() {
|
||||||
|
sdbCloseTable(tsFuncRid);
|
||||||
|
tsFuncSdb = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SFuncObj *mnodeGetFunc(char *name) {
|
||||||
|
return (SFuncObj *)sdbGetRow(tsFuncSdb, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *mnodeGetNextFunc(void *pIter, SFuncObj **pFunc) {
|
||||||
|
return sdbFetchRow(tsFuncSdb, pIter, (void **)pFunc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mnodeCancelGetNextFunc(void *pIter) {
|
||||||
|
sdbFreeIter(tsFuncSdb, pIter);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mnodeIncFuncRef(SFuncObj *pFunc) {
|
||||||
|
sdbIncRef(tsFuncSdb, pFunc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mnodeDecFuncRef(SFuncObj *pFunc) {
|
||||||
|
sdbDecRef(tsFuncSdb, pFunc);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
static int32_t mnodeUpdateFunc(SFuncObj *pFunc, void *pMsg) {
|
||||||
|
SSdbRow row = {
|
||||||
|
.type = SDB_OPER_GLOBAL,
|
||||||
|
.pTable = tsFuncSdb,
|
||||||
|
.pObj = pFunc,
|
||||||
|
.pMsg = pMsg
|
||||||
|
};
|
||||||
|
|
||||||
|
int32_t code = sdbUpdateRow(&row);
|
||||||
|
if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) {
|
||||||
|
mError("func:%s, failed to alter by %s, reason:%s", pFunc->name, mnodeGetUserFromMsg(pMsg), tstrerror(code));
|
||||||
|
} else {
|
||||||
|
mLInfo("func:%s, is altered by %s", pFunc->name, mnodeGetUserFromMsg(pMsg));
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
int32_t mnodeCreateFunc(SAcctObj *pAcct, char *name, int32_t codeLen, char *codeScript, char *path, uint8_t outputType, int16_t outputLen, int32_t funcType, int32_t bufSize, SMnodeMsg *pMsg) {
|
||||||
|
if (grantCheck(TSDB_GRANT_TIME) != TSDB_CODE_SUCCESS) {
|
||||||
|
return TSDB_CODE_GRANT_EXPIRED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pMsg->pUser->writeAuth) {
|
||||||
|
return TSDB_CODE_MND_NO_RIGHTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t code = acctCheck(pAcct, ACCT_GRANT_USER);
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
code = grantCheck(TSDB_GRANT_USER);
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name[0] == 0) {
|
||||||
|
return TSDB_CODE_MND_INVALID_FUNC_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (codeScript[0] == 0) {
|
||||||
|
return TSDB_CODE_MND_INVALID_FUNC_CODE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (codeLen < 0 || codeLen > TSDB_FUNC_CODE_LEN) {
|
||||||
|
return TSDB_CODE_MND_INVALID_FUNC_CODE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bufSize < 0 || bufSize > TSDB_FUNC_BUF_SIZE) {
|
||||||
|
return TSDB_CODE_MND_INVALID_FUNC_BUFSIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
SFuncObj *pFunc = mnodeGetFunc(name);
|
||||||
|
if (pFunc != NULL) {
|
||||||
|
mDebug("func:%s, is already there", name);
|
||||||
|
mnodeDecFuncRef(pFunc);
|
||||||
|
return TSDB_CODE_MND_FUNC_ALREADY_EXIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
pFunc = calloc(1, sizeof(SFuncObj));
|
||||||
|
tstrncpy(pFunc->name, name, TSDB_FUNC_NAME_LEN);
|
||||||
|
tstrncpy(pFunc->path, path, tListLen(pFunc->path));
|
||||||
|
memcpy(pFunc->cont, codeScript, codeLen);
|
||||||
|
pFunc->contLen = codeLen;
|
||||||
|
pFunc->createdTime = taosGetTimestampMs();
|
||||||
|
pFunc->resType = outputType;
|
||||||
|
pFunc->resBytes = outputLen;
|
||||||
|
pFunc->funcType = funcType;
|
||||||
|
pFunc->bufSize = bufSize;
|
||||||
|
pFunc->sig = 0;
|
||||||
|
pFunc->type = 1; //lua script, refactor
|
||||||
|
|
||||||
|
SSdbRow row = {
|
||||||
|
.type = SDB_OPER_GLOBAL,
|
||||||
|
.pTable = tsFuncSdb,
|
||||||
|
.pObj = pFunc,
|
||||||
|
.rowSize = sizeof(SFuncObj),
|
||||||
|
.pMsg = pMsg
|
||||||
|
};
|
||||||
|
|
||||||
|
code = sdbInsertRow(&row);
|
||||||
|
if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) {
|
||||||
|
mError("func:%s, failed to create by %s, reason:%s", pFunc->name, mnodeGetUserFromMsg(pMsg), tstrerror(code));
|
||||||
|
tfree(pFunc);
|
||||||
|
} else {
|
||||||
|
mLInfo("func:%s, is created by %s", pFunc->name, mnodeGetUserFromMsg(pMsg));
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mnodeDropFunc(SFuncObj *pFunc, void *pMsg) {
|
||||||
|
SSdbRow row = {
|
||||||
|
.type = SDB_OPER_GLOBAL,
|
||||||
|
.pTable = tsFuncSdb,
|
||||||
|
.pObj = pFunc,
|
||||||
|
.pMsg = pMsg
|
||||||
|
};
|
||||||
|
|
||||||
|
int32_t code = sdbDeleteRow(&row);
|
||||||
|
if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) {
|
||||||
|
mError("func:%s, failed to drop by %s, reason:%s", pFunc->name, mnodeGetUserFromMsg(pMsg), tstrerror(code));
|
||||||
|
} else {
|
||||||
|
mLInfo("func:%s, is dropped by %s", pFunc->name, mnodeGetUserFromMsg(pMsg));
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mnodeGetFuncsNum() {
|
||||||
|
return (int32_t)sdbGetNumOfRows(tsFuncSdb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mnodeGetFuncMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn) {
|
||||||
|
SUserObj *pUser = mnodeGetUserFromConn(pConn);
|
||||||
|
if (pUser == NULL) {
|
||||||
|
return TSDB_CODE_MND_NO_USER_FROM_CONN;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t cols = 0;
|
||||||
|
SSchema *pSchema = pMeta->schema;
|
||||||
|
|
||||||
|
pShow->bytes[cols] = TSDB_FUNC_NAME_LEN + VARSTR_HEADER_SIZE;
|
||||||
|
pSchema[cols].type = TSDB_DATA_TYPE_BINARY;
|
||||||
|
strcpy(pSchema[cols].name, "name");
|
||||||
|
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||||
|
cols++;
|
||||||
|
|
||||||
|
pShow->bytes[cols] = PATH_MAX + VARSTR_HEADER_SIZE;
|
||||||
|
pSchema[cols].type = TSDB_DATA_TYPE_BINARY;
|
||||||
|
strcpy(pSchema[cols].name, "path");
|
||||||
|
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||||
|
cols++;
|
||||||
|
|
||||||
|
pShow->bytes[cols] = 4;
|
||||||
|
pSchema[cols].type = TSDB_DATA_TYPE_INT;
|
||||||
|
strcpy(pSchema[cols].name, "aggregate");
|
||||||
|
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||||
|
cols++;
|
||||||
|
|
||||||
|
pShow->bytes[cols] = TSDB_TYPE_STR_MAX_LEN + VARSTR_HEADER_SIZE;
|
||||||
|
pSchema[cols].type = TSDB_DATA_TYPE_BINARY;
|
||||||
|
strcpy(pSchema[cols].name, "outputtype");
|
||||||
|
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||||
|
cols++;
|
||||||
|
|
||||||
|
pShow->bytes[cols] = 8;
|
||||||
|
pSchema[cols].type = TSDB_DATA_TYPE_TIMESTAMP;
|
||||||
|
strcpy(pSchema[cols].name, "create_time");
|
||||||
|
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||||
|
cols++;
|
||||||
|
|
||||||
|
pShow->bytes[cols] = 4;
|
||||||
|
pSchema[cols].type = TSDB_DATA_TYPE_INT;
|
||||||
|
strcpy(pSchema[cols].name, "code_len");
|
||||||
|
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||||
|
cols++;
|
||||||
|
|
||||||
|
pShow->bytes[cols] = 4;
|
||||||
|
pSchema[cols].type = TSDB_DATA_TYPE_INT;
|
||||||
|
strcpy(pSchema[cols].name, "bufsize");
|
||||||
|
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||||
|
cols++;
|
||||||
|
|
||||||
|
pMeta->numOfColumns = htons(cols);
|
||||||
|
strcpy(pMeta->tableFname, "show funcs");
|
||||||
|
pShow->numOfColumns = cols;
|
||||||
|
|
||||||
|
pShow->offset[0] = 0;
|
||||||
|
for (int32_t i = 1; i < cols; ++i) {
|
||||||
|
pShow->offset[i] = pShow->offset[i - 1] + pShow->bytes[i - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
pShow->numOfRows = mnodeGetFuncsNum();
|
||||||
|
pShow->rowSize = pShow->offset[cols - 1] + pShow->bytes[cols - 1];
|
||||||
|
|
||||||
|
mnodeDecUserRef(pUser);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void* mnodeGenTypeStr(char *buf, int32_t buflen, uint8_t type, int16_t len) {
|
||||||
|
char *msg = "unknown";
|
||||||
|
if (type >= sizeof(tDataTypes)/sizeof(tDataTypes[0])) {
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == TSDB_DATA_TYPE_NCHAR || type == TSDB_DATA_TYPE_BINARY) {
|
||||||
|
int32_t bytes = len > 0 ? (int)(len - VARSTR_HEADER_SIZE) : len;
|
||||||
|
|
||||||
|
snprintf(buf, buflen - 1, "%s(%d)", tDataTypes[type].name, type == TSDB_DATA_TYPE_NCHAR ? bytes/4 : bytes);
|
||||||
|
buf[buflen - 1] = 0;
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
return tDataTypes[type].name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mnodeRetrieveFuncs(SShowObj *pShow, char *data, int32_t rows, void *pConn) {
|
||||||
|
int32_t numOfRows = 0;
|
||||||
|
SFuncObj *pFunc = NULL;
|
||||||
|
int32_t cols = 0;
|
||||||
|
char *pWrite;
|
||||||
|
char buf[TSDB_TYPE_STR_MAX_LEN];
|
||||||
|
|
||||||
|
while (numOfRows < rows) {
|
||||||
|
pShow->pIter = mnodeGetNextFunc(pShow->pIter, &pFunc);
|
||||||
|
if (pFunc == NULL) break;
|
||||||
|
|
||||||
|
cols = 0;
|
||||||
|
|
||||||
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
|
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, pFunc->name, pShow->bytes[cols]);
|
||||||
|
cols++;
|
||||||
|
|
||||||
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
|
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, pFunc->path, pShow->bytes[cols]);
|
||||||
|
cols++;
|
||||||
|
|
||||||
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
|
*(int32_t *)pWrite = pFunc->funcType == TSDB_UDF_TYPE_AGGREGATE ? 1 : 0;
|
||||||
|
cols++;
|
||||||
|
|
||||||
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
|
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, mnodeGenTypeStr(buf, TSDB_TYPE_STR_MAX_LEN, pFunc->resType, pFunc->resBytes), pShow->bytes[cols]);
|
||||||
|
cols++;
|
||||||
|
|
||||||
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
|
*(int64_t *)pWrite = pFunc->createdTime;
|
||||||
|
cols++;
|
||||||
|
|
||||||
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
|
*(int32_t *)pWrite = pFunc->contLen;
|
||||||
|
cols++;
|
||||||
|
|
||||||
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
|
*(int32_t *)pWrite = pFunc->bufSize;
|
||||||
|
cols++;
|
||||||
|
|
||||||
|
numOfRows++;
|
||||||
|
mnodeDecFuncRef(pFunc);
|
||||||
|
}
|
||||||
|
|
||||||
|
mnodeVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow);
|
||||||
|
pShow->numOfReads += numOfRows;
|
||||||
|
return numOfRows;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mnodeProcessCreateFuncMsg(SMnodeMsg *pMsg) {
|
||||||
|
SCreateFuncMsg *pCreate = pMsg->rpcMsg.pCont;
|
||||||
|
pCreate->codeLen = htonl(pCreate->codeLen);
|
||||||
|
pCreate->outputLen = htons(pCreate->outputLen);
|
||||||
|
pCreate->funcType = htonl(pCreate->funcType);
|
||||||
|
pCreate->bufSize = htonl(pCreate->bufSize);
|
||||||
|
|
||||||
|
return mnodeCreateFunc(pMsg->pUser->pAcct, pCreate->name, pCreate->codeLen, pCreate->code, pCreate->path, pCreate->outputType, pCreate->outputLen, pCreate->funcType, pCreate->bufSize, pMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mnodeProcessDropFuncMsg(SMnodeMsg *pMsg) {
|
||||||
|
SDropFuncMsg *pDrop = pMsg->rpcMsg.pCont;
|
||||||
|
|
||||||
|
SFuncObj *pFunc = mnodeGetFunc(pDrop->name);
|
||||||
|
if (pFunc == NULL) {
|
||||||
|
return TSDB_CODE_MND_INVALID_FUNC;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mnodeDropFunc(pFunc, pMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mnodeProcessRetrieveFuncImplMsg(SMnodeMsg *pMsg) {
|
||||||
|
SRetrieveFuncMsg *pInfo = pMsg->rpcMsg.pCont;
|
||||||
|
pInfo->num = htonl(pInfo->num);
|
||||||
|
|
||||||
|
int32_t t = sizeof(SUdfFuncMsg) + (sizeof(SFunctionInfoMsg) + TSDB_FUNC_CODE_LEN) * pInfo->num + 16384;
|
||||||
|
|
||||||
|
SUdfFuncMsg *pFuncMsg = rpcMallocCont(t);
|
||||||
|
pFuncMsg->num = htonl(pInfo->num);
|
||||||
|
char* pOutput = pFuncMsg->content;
|
||||||
|
tstr* name = (tstr*) pInfo->name;
|
||||||
|
|
||||||
|
for(int32_t i = 0; i < pInfo->num; ++i) {
|
||||||
|
char buf[TSDB_FUNC_NAME_LEN] = {0};
|
||||||
|
tstrncpy(buf, name->data, htons(name->len) + 1);
|
||||||
|
|
||||||
|
SFuncObj* pFuncObj = mnodeGetFunc(buf);
|
||||||
|
if (pFuncObj == NULL) {
|
||||||
|
mError("function %s does not exist", buf);
|
||||||
|
return TSDB_CODE_MND_INVALID_FUNC;
|
||||||
|
}
|
||||||
|
|
||||||
|
SFunctionInfoMsg* pFuncInfo = (SFunctionInfoMsg*) pOutput;
|
||||||
|
|
||||||
|
strcpy(pFuncInfo->name, buf);
|
||||||
|
pFuncInfo->len = htonl(pFuncObj->contLen);
|
||||||
|
memcpy(pFuncInfo->content, pFuncObj->cont, pFuncObj->contLen);
|
||||||
|
|
||||||
|
pFuncInfo->funcType = htonl(pFuncObj->funcType);
|
||||||
|
pFuncInfo->resType = pFuncObj->resType;
|
||||||
|
pFuncInfo->resBytes = htons(pFuncObj->resBytes);
|
||||||
|
pFuncInfo->bufSize = htonl(pFuncObj->bufSize);
|
||||||
|
|
||||||
|
pOutput += sizeof(SFunctionInfoMsg) + pFuncObj->contLen;
|
||||||
|
name =(tstr *)((char *)name + sizeof(*name) + htons(name->len));
|
||||||
|
}
|
||||||
|
|
||||||
|
pMsg->rpcRsp.rsp = pFuncMsg;
|
||||||
|
pMsg->rpcRsp.len = (int32_t)(pOutput - (char*)pFuncMsg);
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
@ -32,6 +32,7 @@
|
||||||
#include "mnodeSdb.h"
|
#include "mnodeSdb.h"
|
||||||
#include "mnodeVgroup.h"
|
#include "mnodeVgroup.h"
|
||||||
#include "mnodeUser.h"
|
#include "mnodeUser.h"
|
||||||
|
#include "mnodeFunc.h"
|
||||||
#include "mnodeTable.h"
|
#include "mnodeTable.h"
|
||||||
#include "mnodeCluster.h"
|
#include "mnodeCluster.h"
|
||||||
#include "mnodeShow.h"
|
#include "mnodeShow.h"
|
||||||
|
|
@ -46,6 +47,7 @@ static SStep tsMnodeSteps[] = {
|
||||||
{"cluster", mnodeInitCluster, mnodeCleanupCluster},
|
{"cluster", mnodeInitCluster, mnodeCleanupCluster},
|
||||||
{"accts", mnodeInitAccts, mnodeCleanupAccts},
|
{"accts", mnodeInitAccts, mnodeCleanupAccts},
|
||||||
{"users", mnodeInitUsers, mnodeCleanupUsers},
|
{"users", mnodeInitUsers, mnodeCleanupUsers},
|
||||||
|
{"funcs", mnodeInitFuncs, mnodeCleanupFuncs},
|
||||||
{"dnodes", mnodeInitDnodes, mnodeCleanupDnodes},
|
{"dnodes", mnodeInitDnodes, mnodeCleanupDnodes},
|
||||||
{"dbs", mnodeInitDbs, mnodeCleanupDbs},
|
{"dbs", mnodeInitDbs, mnodeCleanupDbs},
|
||||||
{"vgroups", mnodeInitVgroups, mnodeCleanupVgroups},
|
{"vgroups", mnodeInitVgroups, mnodeCleanupVgroups},
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@
|
||||||
#include "mnodeWrite.h"
|
#include "mnodeWrite.h"
|
||||||
#include "mnodeRead.h"
|
#include "mnodeRead.h"
|
||||||
#include "mnodePeer.h"
|
#include "mnodePeer.h"
|
||||||
|
#include "mnodeFunc.h"
|
||||||
|
|
||||||
#define ALTER_CTABLE_RETRY_TIMES 3
|
#define ALTER_CTABLE_RETRY_TIMES 3
|
||||||
#define CREATE_CTABLE_RETRY_TIMES 10
|
#define CREATE_CTABLE_RETRY_TIMES 10
|
||||||
|
|
@ -104,6 +105,20 @@ static void mnodeDestroyChildTable(SCTableObj *pTable) {
|
||||||
tfree(pTable);
|
tfree(pTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char* mnodeGetTableShowPattern(SShowObj *pShow) {
|
||||||
|
char* pattern = NULL;
|
||||||
|
if (pShow != NULL && pShow->payloadLen > 0) {
|
||||||
|
pattern = (char*)malloc(pShow->payloadLen + 1);
|
||||||
|
if (pattern == NULL) {
|
||||||
|
terrno = TSDB_CODE_QRY_OUT_OF_MEMORY;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
memcpy(pattern, pShow->payload, pShow->payloadLen);
|
||||||
|
pattern[pShow->payloadLen] = 0;
|
||||||
|
}
|
||||||
|
return pattern;
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t mnodeChildTableActionDestroy(SSdbRow *pRow) {
|
static int32_t mnodeChildTableActionDestroy(SSdbRow *pRow) {
|
||||||
mnodeDestroyChildTable(pRow->pObj);
|
mnodeDestroyChildTable(pRow->pObj);
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
|
@ -1620,6 +1635,11 @@ int32_t mnodeRetrieveShowSuperTables(SShowObj *pShow, char *data, int32_t rows,
|
||||||
SPatternCompareInfo info = PATTERN_COMPARE_INFO_INITIALIZER;
|
SPatternCompareInfo info = PATTERN_COMPARE_INFO_INITIALIZER;
|
||||||
char stableName[TSDB_TABLE_NAME_LEN] = {0};
|
char stableName[TSDB_TABLE_NAME_LEN] = {0};
|
||||||
|
|
||||||
|
char* pattern = mnodeGetTableShowPattern(pShow);
|
||||||
|
if (pShow->payloadLen > 0 && pattern == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
while (numOfRows < rows) {
|
while (numOfRows < rows) {
|
||||||
pShow->pIter = mnodeGetNextSuperTable(pShow->pIter, &pTable);
|
pShow->pIter = mnodeGetNextSuperTable(pShow->pIter, &pTable);
|
||||||
if (pTable == NULL) break;
|
if (pTable == NULL) break;
|
||||||
|
|
@ -1631,7 +1651,7 @@ int32_t mnodeRetrieveShowSuperTables(SShowObj *pShow, char *data, int32_t rows,
|
||||||
memset(stableName, 0, tListLen(stableName));
|
memset(stableName, 0, tListLen(stableName));
|
||||||
mnodeExtractTableName(pTable->info.tableId, stableName);
|
mnodeExtractTableName(pTable->info.tableId, stableName);
|
||||||
|
|
||||||
if (pShow->payloadLen > 0 && patternMatch(pShow->payload, stableName, sizeof(stableName) - 1, &info) != TSDB_PATTERN_MATCH) {
|
if (pShow->payloadLen > 0 && patternMatch(pattern, stableName, sizeof(stableName) - 1, &info) != TSDB_PATTERN_MATCH) {
|
||||||
mnodeDecTableRef(pTable);
|
mnodeDecTableRef(pTable);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -1671,6 +1691,7 @@ int32_t mnodeRetrieveShowSuperTables(SShowObj *pShow, char *data, int32_t rows,
|
||||||
|
|
||||||
mnodeVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow);
|
mnodeVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow);
|
||||||
mnodeDecDbRef(pDb);
|
mnodeDecDbRef(pDb);
|
||||||
|
free(pattern);
|
||||||
|
|
||||||
return numOfRows;
|
return numOfRows;
|
||||||
}
|
}
|
||||||
|
|
@ -2906,6 +2927,7 @@ static int32_t mnodeProcessMultiTableMetaMsg(SMnodeMsg *pMsg) {
|
||||||
|
|
||||||
pInfo->numOfTables = htonl(pInfo->numOfTables);
|
pInfo->numOfTables = htonl(pInfo->numOfTables);
|
||||||
pInfo->numOfVgroups = htonl(pInfo->numOfVgroups);
|
pInfo->numOfVgroups = htonl(pInfo->numOfVgroups);
|
||||||
|
pInfo->numOfUdfs = htonl(pInfo->numOfUdfs);
|
||||||
|
|
||||||
int32_t contLen = pMsg->rpcMsg.contLen - sizeof(SMultiTableInfoMsg);
|
int32_t contLen = pMsg->rpcMsg.contLen - sizeof(SMultiTableInfoMsg);
|
||||||
|
|
||||||
|
|
@ -2914,9 +2936,9 @@ static int32_t mnodeProcessMultiTableMetaMsg(SMnodeMsg *pMsg) {
|
||||||
char* str = strndup(pInfo->tableNames, contLen);
|
char* str = strndup(pInfo->tableNames, contLen);
|
||||||
char** nameList = strsplit(str, ",", &num);
|
char** nameList = strsplit(str, ",", &num);
|
||||||
SArray* pList = taosArrayInit(4, POINTER_BYTES);
|
SArray* pList = taosArrayInit(4, POINTER_BYTES);
|
||||||
SMultiTableMeta *pMultiMeta = NULL;
|
|
||||||
|
|
||||||
if (num != pInfo->numOfTables + pInfo->numOfVgroups) {
|
SMultiTableMeta *pMultiMeta = NULL;
|
||||||
|
if (num != pInfo->numOfTables + pInfo->numOfVgroups + pInfo->numOfUdfs) {
|
||||||
mError("msg:%p, app:%p, failed to get multi-tableMeta, msg inconsistent", pMsg, pMsg->rpcMsg.ahandle);
|
mError("msg:%p, app:%p, failed to get multi-tableMeta, msg inconsistent", pMsg, pMsg->rpcMsg.ahandle);
|
||||||
code = TSDB_CODE_MND_INVALID_TABLE_NAME;
|
code = TSDB_CODE_MND_INVALID_TABLE_NAME;
|
||||||
goto _end;
|
goto _end;
|
||||||
|
|
@ -2991,8 +3013,10 @@ static int32_t mnodeProcessMultiTableMetaMsg(SMnodeMsg *pMsg) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t tableNum = pInfo->numOfTables + pInfo->numOfVgroups;
|
||||||
|
|
||||||
// add the additional super table names that needs the vgroup info
|
// add the additional super table names that needs the vgroup info
|
||||||
for(;t < num; ++t) {
|
for(;t < tableNum; ++t) {
|
||||||
taosArrayPush(pList, &nameList[t]);
|
taosArrayPush(pList, &nameList[t]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3023,6 +3047,36 @@ static int32_t mnodeProcessMultiTableMetaMsg(SMnodeMsg *pMsg) {
|
||||||
pMultiMeta->contLen = (int32_t) (msg - (char*) pMultiMeta);
|
pMultiMeta->contLen = (int32_t) (msg - (char*) pMultiMeta);
|
||||||
|
|
||||||
pMultiMeta->numOfTables = htonl(pMultiMeta->numOfTables);
|
pMultiMeta->numOfTables = htonl(pMultiMeta->numOfTables);
|
||||||
|
|
||||||
|
// add the user-defined-function information
|
||||||
|
for(int32_t i = 0; i < pInfo->numOfUdfs; ++i, ++t) {
|
||||||
|
char buf[TSDB_FUNC_NAME_LEN] = {0};
|
||||||
|
strcpy(buf, nameList[t]);
|
||||||
|
|
||||||
|
SFuncObj* pFuncObj = mnodeGetFunc(buf);
|
||||||
|
if (pFuncObj == NULL) {
|
||||||
|
mError("function %s does not exist", buf);
|
||||||
|
code = TSDB_CODE_MND_INVALID_FUNC;
|
||||||
|
goto _end;
|
||||||
|
}
|
||||||
|
|
||||||
|
SFunctionInfoMsg* pFuncInfo = (SFunctionInfoMsg*) msg;
|
||||||
|
|
||||||
|
strcpy(pFuncInfo->name, buf);
|
||||||
|
pFuncInfo->len = htonl(pFuncObj->contLen);
|
||||||
|
memcpy(pFuncInfo->content, pFuncObj->cont, pFuncObj->contLen);
|
||||||
|
|
||||||
|
pFuncInfo->funcType = htonl(pFuncObj->funcType);
|
||||||
|
pFuncInfo->resType = pFuncObj->resType;
|
||||||
|
pFuncInfo->resBytes = htons(pFuncObj->resBytes);
|
||||||
|
pFuncInfo->bufSize = htonl(pFuncObj->bufSize);
|
||||||
|
|
||||||
|
msg += sizeof(SFunctionInfoMsg) + pFuncObj->contLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
pMultiMeta->contLen = (int32_t) (msg - (char*) pMultiMeta);
|
||||||
|
pMultiMeta->numOfUdf = htonl(pInfo->numOfUdfs);
|
||||||
|
|
||||||
pMsg->rpcRsp.rsp = pMultiMeta;
|
pMsg->rpcRsp.rsp = pMultiMeta;
|
||||||
pMsg->rpcRsp.len = pMultiMeta->contLen;
|
pMsg->rpcRsp.len = pMultiMeta->contLen;
|
||||||
code = TSDB_CODE_SUCCESS;
|
code = TSDB_CODE_SUCCESS;
|
||||||
|
|
@ -3033,11 +3087,13 @@ static int32_t mnodeProcessMultiTableMetaMsg(SMnodeMsg *pMsg) {
|
||||||
goto _end;
|
goto _end;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t len = tsCompressString(pMultiMeta->meta, (int32_t)pMultiMeta->contLen - sizeof(SMultiTableMeta), 1,
|
int32_t dataLen = (int32_t)pMultiMeta->contLen - sizeof(SMultiTableMeta);
|
||||||
tmp + sizeof(SMultiTableMeta), (int32_t)pMultiMeta->contLen - sizeof(SMultiTableMeta) + 2, ONE_STAGE_COMP, NULL, 0);
|
int32_t len = tsCompressString(pMultiMeta->meta, dataLen, 1, tmp + sizeof(SMultiTableMeta), (int32_t)dataLen + 2,
|
||||||
|
ONE_STAGE_COMP, NULL, 0);
|
||||||
|
|
||||||
|
pMultiMeta->metaClone = pInfo->metaClone;
|
||||||
pMultiMeta->rawLen = pMultiMeta->contLen;
|
pMultiMeta->rawLen = pMultiMeta->contLen;
|
||||||
if (len == -1 || len + sizeof(SMultiTableMeta) >= pMultiMeta->contLen + 2) { // compress failed, do not compress this binary data
|
if (len == -1 || len >= dataLen + 2) { // compress failed, do not compress this binary data
|
||||||
pMultiMeta->compressed = 0;
|
pMultiMeta->compressed = 0;
|
||||||
memcpy(tmp, pMultiMeta, sizeof(SMultiTableMeta) + pMultiMeta->contLen);
|
memcpy(tmp, pMultiMeta, sizeof(SMultiTableMeta) + pMultiMeta->contLen);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -3157,16 +3213,10 @@ static int32_t mnodeRetrieveShowTables(SShowObj *pShow, char *data, int32_t rows
|
||||||
char prefix[64] = {0};
|
char prefix[64] = {0};
|
||||||
int32_t prefixLen = (int32_t)tableIdPrefix(pDb->name, prefix, 64);
|
int32_t prefixLen = (int32_t)tableIdPrefix(pDb->name, prefix, 64);
|
||||||
|
|
||||||
char* pattern = NULL;
|
char* pattern = mnodeGetTableShowPattern(pShow);
|
||||||
if (pShow->payloadLen > 0) {
|
if (pShow->payloadLen > 0 && pattern == NULL) {
|
||||||
pattern = (char*)malloc(pShow->payloadLen + 1);
|
|
||||||
if (pattern == NULL) {
|
|
||||||
terrno = TSDB_CODE_QRY_OUT_OF_MEMORY;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
memcpy(pattern, pShow->payload, pShow->payloadLen);
|
|
||||||
pattern[pShow->payloadLen] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (numOfRows < rows) {
|
while (numOfRows < rows) {
|
||||||
pShow->pIter = mnodeGetNextChildTable(pShow->pIter, &pTable);
|
pShow->pIter = mnodeGetNextChildTable(pShow->pIter, &pTable);
|
||||||
|
|
@ -3397,6 +3447,11 @@ static int32_t mnodeRetrieveStreamTables(SShowObj *pShow, char *data, int32_t ro
|
||||||
strcat(prefix, TS_PATH_DELIMITER);
|
strcat(prefix, TS_PATH_DELIMITER);
|
||||||
int32_t prefixLen = (int32_t)strlen(prefix);
|
int32_t prefixLen = (int32_t)strlen(prefix);
|
||||||
|
|
||||||
|
char* pattern = mnodeGetTableShowPattern(pShow);
|
||||||
|
if (pShow->payloadLen > 0 && pattern == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
while (numOfRows < rows) {
|
while (numOfRows < rows) {
|
||||||
pShow->pIter = mnodeGetNextChildTable(pShow->pIter, &pTable);
|
pShow->pIter = mnodeGetNextChildTable(pShow->pIter, &pTable);
|
||||||
if (pTable == NULL) break;
|
if (pTable == NULL) break;
|
||||||
|
|
@ -3412,7 +3467,7 @@ static int32_t mnodeRetrieveStreamTables(SShowObj *pShow, char *data, int32_t ro
|
||||||
// pattern compare for table name
|
// pattern compare for table name
|
||||||
mnodeExtractTableName(pTable->info.tableId, tableName);
|
mnodeExtractTableName(pTable->info.tableId, tableName);
|
||||||
|
|
||||||
if (pShow->payloadLen > 0 && patternMatch(pShow->payload, tableName, sizeof(tableName) - 1, &info) != TSDB_PATTERN_MATCH) {
|
if (pShow->payloadLen > 0 && patternMatch(pattern, tableName, sizeof(tableName) - 1, &info) != TSDB_PATTERN_MATCH) {
|
||||||
mnodeDecTableRef(pTable);
|
mnodeDecTableRef(pTable);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -3444,6 +3499,7 @@ static int32_t mnodeRetrieveStreamTables(SShowObj *pShow, char *data, int32_t ro
|
||||||
|
|
||||||
mnodeVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow);
|
mnodeVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow);
|
||||||
mnodeDecDbRef(pDb);
|
mnodeDecDbRef(pDb);
|
||||||
|
free(pattern);
|
||||||
|
|
||||||
return numOfRows;
|
return numOfRows;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ extern "C" {
|
||||||
#include "osSysinfo.h"
|
#include "osSysinfo.h"
|
||||||
#include "osTime.h"
|
#include "osTime.h"
|
||||||
#include "osTimer.h"
|
#include "osTimer.h"
|
||||||
|
#include "osSystem.h"
|
||||||
|
|
||||||
void osInit();
|
void osInit();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -77,6 +77,7 @@ extern "C" {
|
||||||
#include "osEok.h"
|
#include "osEok.h"
|
||||||
#else
|
#else
|
||||||
#include <argp.h>
|
#include <argp.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
#include <endian.h>
|
#include <endian.h>
|
||||||
#include <linux/sysctl.h>
|
#include <linux/sysctl.h>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* 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_OS_SYSTEM_H
|
||||||
|
#define TDENGINE_OS_SYSTEM_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void* taosLoadDll(const char *filename);
|
||||||
|
void* taosLoadSym(void* handle, char* name);
|
||||||
|
void taosCloseDll(void *handle);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define _DEFAULT_SOURCE
|
||||||
|
#include "os.h"
|
||||||
|
#include "tglobal.h"
|
||||||
|
#include "tulog.h"
|
||||||
|
|
||||||
|
void* taosLoadDll(const char *filename) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* taosLoadSym(void* handle, char* name) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void taosCloseDll(void *handle) {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -4,4 +4,4 @@ PROJECT(TDengine)
|
||||||
AUX_SOURCE_DIRECTORY(. SRC)
|
AUX_SOURCE_DIRECTORY(. SRC)
|
||||||
ADD_LIBRARY(oslinux ${SRC})
|
ADD_LIBRARY(oslinux ${SRC})
|
||||||
|
|
||||||
TARGET_LINK_LIBRARIES(oslinux m rt z)
|
TARGET_LINK_LIBRARIES(oslinux m rt z dl)
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define _DEFAULT_SOURCE
|
||||||
|
#include "os.h"
|
||||||
|
#include "tconfig.h"
|
||||||
|
#include "tglobal.h"
|
||||||
|
#include "tulog.h"
|
||||||
|
|
||||||
|
void* taosLoadDll(const char *filename) {
|
||||||
|
void *handle = dlopen (filename, RTLD_LAZY);
|
||||||
|
if (!handle) {
|
||||||
|
uError("load dll:%s failed, error:%s", filename, dlerror());
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
uDebug("dll %s loaded", filename);
|
||||||
|
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* taosLoadSym(void* handle, char* name) {
|
||||||
|
void* sym = dlsym(handle, name);
|
||||||
|
char* error = NULL;
|
||||||
|
|
||||||
|
if ((error = dlerror()) != NULL) {
|
||||||
|
uWarn("load sym:%s failed, error:%s", name, dlerror());
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
uDebug("sym %s loaded", name)
|
||||||
|
|
||||||
|
return sym;
|
||||||
|
}
|
||||||
|
|
||||||
|
void taosCloseDll(void *handle) {
|
||||||
|
if (handle) {
|
||||||
|
dlclose(handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define _DEFAULT_SOURCE
|
||||||
|
#include "os.h"
|
||||||
|
#include "tglobal.h"
|
||||||
|
#include "tulog.h"
|
||||||
|
|
||||||
|
void* taosLoadDll(const char *filename) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* taosLoadSym(void* handle, char* name) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void taosCloseDll(void *handle) {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
#define HTTP_PARSER_H
|
#define HTTP_PARSER_H
|
||||||
#include "httpGzip.h"
|
#include "httpGzip.h"
|
||||||
|
|
||||||
#define HTTP_MAX_URL 5 // http url stack size
|
#define HTTP_MAX_URL 6 // http url stack size
|
||||||
|
|
||||||
#define HTTP_CODE_CONTINUE 100
|
#define HTTP_CODE_CONTINUE 100
|
||||||
#define HTTP_CODE_SWITCHING_PROTOCOL 101
|
#define HTTP_CODE_SWITCHING_PROTOCOL 101
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,90 @@ bool restProcessSqlRequest(HttpContext* pContext, int32_t timestampFmt) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define REST_FUNC_URL_POS 2
|
||||||
|
#define REST_OUTP_URL_POS 3
|
||||||
|
#define REST_AGGR_URL_POS 4
|
||||||
|
#define REST_BUFF_URL_POS 5
|
||||||
|
|
||||||
|
#define HTTP_FUNC_LEN 32
|
||||||
|
#define HTTP_OUTP_LEN 16
|
||||||
|
#define HTTP_AGGR_LEN 2
|
||||||
|
#define HTTP_BUFF_LEN 32
|
||||||
|
|
||||||
|
static int udfSaveFile(const char *fname, const char *content, long len) {
|
||||||
|
int fd = open(fname, O_WRONLY | O_CREAT | O_EXCL | O_BINARY, 0755);
|
||||||
|
if (fd < 0)
|
||||||
|
return -1;
|
||||||
|
if (taosWrite(fd, (void *)content, len) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool restProcessUdfRequest(HttpContext* pContext) {
|
||||||
|
HttpParser* pParser = pContext->parser;
|
||||||
|
if (pParser->path[REST_FUNC_URL_POS].pos >= HTTP_FUNC_LEN || pParser->path[REST_FUNC_URL_POS].pos <= 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pParser->path[REST_OUTP_URL_POS].pos >= HTTP_OUTP_LEN || pParser->path[REST_OUTP_URL_POS].pos <= 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pParser->path[REST_AGGR_URL_POS].pos >= HTTP_AGGR_LEN || pParser->path[REST_AGGR_URL_POS].pos <= 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pParser->path[REST_BUFF_URL_POS].pos >= HTTP_BUFF_LEN || pParser->path[REST_BUFF_URL_POS].pos <= 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* sql = pContext->parser->body.str;
|
||||||
|
int len = pContext->parser->body.pos;
|
||||||
|
if (sql == NULL) {
|
||||||
|
httpSendErrorResp(pContext, TSDB_CODE_HTTP_NO_SQL_INPUT);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
char udfDir[256] = {0};
|
||||||
|
char buf[64] = "udf-";
|
||||||
|
char funcName[64] = {0};
|
||||||
|
int aggr = 0;
|
||||||
|
char outputType[16] = {0};
|
||||||
|
char buffSize[32] = {0};
|
||||||
|
|
||||||
|
tstrncpy(funcName, pParser->path[REST_FUNC_URL_POS].str, HTTP_FUNC_LEN);
|
||||||
|
tstrncpy(buf + 4, funcName, HTTP_FUNC_LEN);
|
||||||
|
|
||||||
|
if (pParser->path[REST_AGGR_URL_POS].str[0] != '0') {
|
||||||
|
aggr = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
tstrncpy(outputType, pParser->path[REST_OUTP_URL_POS].str, HTTP_OUTP_LEN);
|
||||||
|
tstrncpy(buffSize, pParser->path[REST_BUFF_URL_POS].str, HTTP_BUFF_LEN);
|
||||||
|
|
||||||
|
taosGetTmpfilePath(funcName, udfDir);
|
||||||
|
|
||||||
|
udfSaveFile(udfDir, sql, len);
|
||||||
|
|
||||||
|
tfree(sql);
|
||||||
|
pContext->parser->body.str = malloc(1024);
|
||||||
|
sql = pContext->parser->body.str;
|
||||||
|
int sqlLen = sprintf(sql, "create %s function %s as \"%s\" outputtype %s bufsize %s",
|
||||||
|
aggr == 1 ? "aggregate" : " ", funcName, udfDir, outputType, buffSize);
|
||||||
|
|
||||||
|
pContext->parser->body.pos = sqlLen;
|
||||||
|
pContext->parser->body.size = sqlLen + 1;
|
||||||
|
|
||||||
|
HttpSqlCmd* cmd = &(pContext->singleCmd);
|
||||||
|
cmd->nativSql = sql;
|
||||||
|
|
||||||
|
pContext->reqType = HTTP_REQTYPE_SINGLE_SQL;
|
||||||
|
pContext->encodeMethod = &restEncodeSqlLocalTimeStringMethod;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool restProcessRequest(struct HttpContext* pContext) {
|
bool restProcessRequest(struct HttpContext* pContext) {
|
||||||
if (httpUrlMatch(pContext, REST_ACTION_URL_POS, "login")) {
|
if (httpUrlMatch(pContext, REST_ACTION_URL_POS, "login")) {
|
||||||
restGetUserFromUrl(pContext);
|
restGetUserFromUrl(pContext);
|
||||||
|
|
@ -138,6 +222,8 @@ bool restProcessRequest(struct HttpContext* pContext) {
|
||||||
return restProcessSqlRequest(pContext, REST_TIMESTAMP_FMT_UTC_STRING);
|
return restProcessSqlRequest(pContext, REST_TIMESTAMP_FMT_UTC_STRING);
|
||||||
} else if (httpUrlMatch(pContext, REST_ACTION_URL_POS, "login")) {
|
} else if (httpUrlMatch(pContext, REST_ACTION_URL_POS, "login")) {
|
||||||
return restProcessLoginRequest(pContext);
|
return restProcessLoginRequest(pContext);
|
||||||
|
} else if (httpUrlMatch(pContext, REST_ACTION_URL_POS, "udf")) {
|
||||||
|
return restProcessUdfRequest(pContext);
|
||||||
} else {
|
} else {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,14 +8,14 @@ INCLUDE_DIRECTORIES(inc)
|
||||||
AUX_SOURCE_DIRECTORY(src SRC)
|
AUX_SOURCE_DIRECTORY(src SRC)
|
||||||
ADD_LIBRARY(query ${SRC})
|
ADD_LIBRARY(query ${SRC})
|
||||||
SET_SOURCE_FILES_PROPERTIES(src/sql.c PROPERTIES COMPILE_FLAGS -w)
|
SET_SOURCE_FILES_PROPERTIES(src/sql.c PROPERTIES COMPILE_FLAGS -w)
|
||||||
TARGET_LINK_LIBRARIES(query tsdb tutil)
|
TARGET_LINK_LIBRARIES(query tsdb tutil lua)
|
||||||
|
|
||||||
IF (TD_LINUX)
|
IF (TD_LINUX)
|
||||||
TARGET_LINK_LIBRARIES(query m rt)
|
TARGET_LINK_LIBRARIES(query m rt lua)
|
||||||
ADD_SUBDIRECTORY(tests)
|
ADD_SUBDIRECTORY(tests)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
IF (TD_DARWIN)
|
IF (TD_DARWIN)
|
||||||
TARGET_LINK_LIBRARIES(query m)
|
TARGET_LINK_LIBRARIES(query m lua)
|
||||||
ADD_SUBDIRECTORY(tests)
|
ADD_SUBDIRECTORY(tests)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ extern "C" {
|
||||||
#include "trpc.h"
|
#include "trpc.h"
|
||||||
#include "tvariant.h"
|
#include "tvariant.h"
|
||||||
#include "tsdb.h"
|
#include "tsdb.h"
|
||||||
|
#include "qUdf.h"
|
||||||
|
|
||||||
#define TSDB_FUNC_INVALID_ID -1
|
#define TSDB_FUNC_INVALID_ID -1
|
||||||
#define TSDB_FUNC_COUNT 0
|
#define TSDB_FUNC_COUNT 0
|
||||||
|
|
@ -201,10 +202,8 @@ typedef struct SAggFunctionInfo {
|
||||||
int8_t stableFuncId; // transfer function for super table query
|
int8_t stableFuncId; // transfer function for super table query
|
||||||
uint16_t status;
|
uint16_t status;
|
||||||
|
|
||||||
bool (*init)(SQLFunctionCtx *pCtx); // setup the execute environment
|
bool (*init)(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResultCellInfo); // setup the execute environment
|
||||||
|
|
||||||
void (*xFunction)(SQLFunctionCtx *pCtx); // blocks version function
|
void (*xFunction)(SQLFunctionCtx *pCtx); // blocks version function
|
||||||
// void (*xFunctionF)(SQLFunctionCtx *pCtx, int32_t position); // single-row function version, todo merge with blockwise function
|
|
||||||
|
|
||||||
// finalizer must be called after all xFunction has been executed to generated final result.
|
// finalizer must be called after all xFunction has been executed to generated final result.
|
||||||
void (*xFinalize)(SQLFunctionCtx *pCtx);
|
void (*xFinalize)(SQLFunctionCtx *pCtx);
|
||||||
|
|
@ -216,7 +215,7 @@ typedef struct SAggFunctionInfo {
|
||||||
#define GET_RES_INFO(ctx) ((ctx)->resultInfo)
|
#define GET_RES_INFO(ctx) ((ctx)->resultInfo)
|
||||||
|
|
||||||
int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionId, int32_t param, int16_t *type,
|
int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionId, int32_t param, int16_t *type,
|
||||||
int16_t *len, int32_t *interBytes, int16_t extLength, bool isSuperTable);
|
int16_t *len, int32_t *interBytes, int16_t extLength, bool isSuperTable, SUdfInfo* pUdfInfo);
|
||||||
int32_t isValidFunction(const char* name, int32_t len);
|
int32_t isValidFunction(const char* name, int32_t len);
|
||||||
|
|
||||||
#define IS_STREAM_QUERY_VALID(x) (((x)&TSDB_FUNCSTATE_STREAM) != 0)
|
#define IS_STREAM_QUERY_VALID(x) (((x)&TSDB_FUNCSTATE_STREAM) != 0)
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@
|
||||||
#include "tarray.h"
|
#include "tarray.h"
|
||||||
#include "tlockfree.h"
|
#include "tlockfree.h"
|
||||||
#include "tsdb.h"
|
#include "tsdb.h"
|
||||||
|
#include "qUdf.h"
|
||||||
|
|
||||||
struct SColumnFilterElem;
|
struct SColumnFilterElem;
|
||||||
typedef bool (*__filter_func_t)(struct SColumnFilterElem* pFilter, const char* val1, const char* val2, int16_t type);
|
typedef bool (*__filter_func_t)(struct SColumnFilterElem* pFilter, const char* val1, const char* val2, int16_t type);
|
||||||
|
|
@ -257,6 +258,7 @@ typedef struct SQueryAttr {
|
||||||
SMemRef memRef;
|
SMemRef memRef;
|
||||||
STableGroupInfo tableGroupInfo; // table <tid, last_key> list SArray<STableKeyInfo>
|
STableGroupInfo tableGroupInfo; // table <tid, last_key> list SArray<STableKeyInfo>
|
||||||
int32_t vgId;
|
int32_t vgId;
|
||||||
|
SArray *pUdfInfo; // no need to free
|
||||||
} SQueryAttr;
|
} SQueryAttr;
|
||||||
|
|
||||||
typedef SSDataBlock* (*__operator_fn_t)(void* param, bool* newgroup);
|
typedef SSDataBlock* (*__operator_fn_t)(void* param, bool* newgroup);
|
||||||
|
|
@ -297,6 +299,7 @@ typedef struct SQueryRuntimeEnv {
|
||||||
STableQueryInfo *current;
|
STableQueryInfo *current;
|
||||||
SRspResultInfo resultInfo;
|
SRspResultInfo resultInfo;
|
||||||
SHashObj *pTableRetrieveTsMap;
|
SHashObj *pTableRetrieveTsMap;
|
||||||
|
SUdfInfo *pUdfInfo;
|
||||||
} SQueryRuntimeEnv;
|
} SQueryRuntimeEnv;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
|
@ -392,6 +395,7 @@ typedef struct SQueryParam {
|
||||||
SGroupbyExpr *pGroupbyExpr;
|
SGroupbyExpr *pGroupbyExpr;
|
||||||
int32_t tableScanOperator;
|
int32_t tableScanOperator;
|
||||||
SArray *pOperator;
|
SArray *pOperator;
|
||||||
|
SUdfInfo *pUdfInfo;
|
||||||
} SQueryParam;
|
} SQueryParam;
|
||||||
|
|
||||||
typedef struct STableScanInfo {
|
typedef struct STableScanInfo {
|
||||||
|
|
@ -531,6 +535,7 @@ typedef struct SMultiwayMergeInfo {
|
||||||
|
|
||||||
bool hasPrev;
|
bool hasPrev;
|
||||||
bool groupMix;
|
bool groupMix;
|
||||||
|
SArray *udfInfo;
|
||||||
} SMultiwayMergeInfo;
|
} SMultiwayMergeInfo;
|
||||||
|
|
||||||
void appendUpstream(SOperatorInfo* p, SOperatorInfo* pUpstream);
|
void appendUpstream(SOperatorInfo* p, SOperatorInfo* pUpstream);
|
||||||
|
|
@ -553,8 +558,8 @@ SOperatorInfo* createDistinctOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperat
|
||||||
SOperatorInfo* createTableBlockInfoScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv);
|
SOperatorInfo* createTableBlockInfoScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv);
|
||||||
SOperatorInfo* createMultiwaySortOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SExprInfo* pExpr, int32_t numOfOutput,
|
SOperatorInfo* createMultiwaySortOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SExprInfo* pExpr, int32_t numOfOutput,
|
||||||
int32_t numOfRows, void* merger, bool groupMix);
|
int32_t numOfRows, void* merger, bool groupMix);
|
||||||
|
SOperatorInfo* createGlobalAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, void* param, SArray* pUdfInfo);
|
||||||
SOperatorInfo* createStatewindowOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
SOperatorInfo* createStatewindowOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
||||||
SOperatorInfo* createGlobalAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, void* param);
|
|
||||||
SOperatorInfo* createSLimitOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, void* merger);
|
SOperatorInfo* createSLimitOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, void* merger);
|
||||||
SOperatorInfo* createFilterOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr,
|
SOperatorInfo* createFilterOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr,
|
||||||
int32_t numOfOutput, SColumnInfo* pCols, int32_t numOfFilter);
|
int32_t numOfOutput, SColumnInfo* pCols, int32_t numOfFilter);
|
||||||
|
|
@ -578,18 +583,19 @@ void setInputDataBlock(SOperatorInfo* pOperator, SQLFunctionCtx* pCtx, SSDataBlo
|
||||||
int32_t getNumOfResult(SQueryRuntimeEnv *pRuntimeEnv, SQLFunctionCtx* pCtx, int32_t numOfOutput);
|
int32_t getNumOfResult(SQueryRuntimeEnv *pRuntimeEnv, SQLFunctionCtx* pCtx, int32_t numOfOutput);
|
||||||
void finalizeQueryResult(SOperatorInfo* pOperator, SQLFunctionCtx* pCtx, SResultRowInfo* pResultRowInfo, int32_t* rowCellInfoOffset);
|
void finalizeQueryResult(SOperatorInfo* pOperator, SQLFunctionCtx* pCtx, SResultRowInfo* pResultRowInfo, int32_t* rowCellInfoOffset);
|
||||||
void updateOutputBuf(SOptrBasicInfo* pBInfo, int32_t *bufCapacity, int32_t numOfInputRows);
|
void updateOutputBuf(SOptrBasicInfo* pBInfo, int32_t *bufCapacity, int32_t numOfInputRows);
|
||||||
|
void clearOutputBuf(SOptrBasicInfo* pBInfo, int32_t *bufCapacity);
|
||||||
|
|
||||||
void freeParam(SQueryParam *param);
|
void freeParam(SQueryParam *param);
|
||||||
int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param);
|
int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param);
|
||||||
int32_t createQueryFunc(SQueriedTableInfo* pTableInfo, int32_t numOfOutput, SExprInfo** pExprInfo,
|
int32_t createQueryFunc(SQueriedTableInfo* pTableInfo, int32_t numOfOutput, SExprInfo** pExprInfo,
|
||||||
SSqlExpr** pExprMsg, SColumnInfo* pTagCols, int32_t queryType, void* pMsg);
|
SSqlExpr** pExprMsg, SColumnInfo* pTagCols, int32_t queryType, void* pMsg, SUdfInfo* pUdfInfo);
|
||||||
|
|
||||||
int32_t createIndirectQueryFuncExprFromMsg(SQueryTableMsg *pQueryMsg, int32_t numOfOutput, SExprInfo **pExprInfo,
|
int32_t createIndirectQueryFuncExprFromMsg(SQueryTableMsg *pQueryMsg, int32_t numOfOutput, SExprInfo **pExprInfo,
|
||||||
SSqlExpr **pExpr, SExprInfo *prevExpr);
|
SSqlExpr **pExpr, SExprInfo *prevExpr, SUdfInfo *pUdfInfo);
|
||||||
|
|
||||||
SGroupbyExpr *createGroupbyExprFromMsg(SQueryTableMsg *pQueryMsg, SColIndex *pColIndex, int32_t *code);
|
SGroupbyExpr *createGroupbyExprFromMsg(SQueryTableMsg *pQueryMsg, SColIndex *pColIndex, int32_t *code);
|
||||||
SQInfo *createQInfoImpl(SQueryTableMsg *pQueryMsg, SGroupbyExpr *pGroupbyExpr, SExprInfo *pExprs,
|
SQInfo *createQInfoImpl(SQueryTableMsg *pQueryMsg, SGroupbyExpr *pGroupbyExpr, SExprInfo *pExprs,
|
||||||
SExprInfo *pSecExprs, STableGroupInfo *pTableGroupInfo, SColumnInfo* pTagCols, int32_t vgId, char* sql, uint64_t qId);
|
SExprInfo *pSecExprs, STableGroupInfo *pTableGroupInfo, SColumnInfo* pTagCols, int32_t vgId, char* sql, uint64_t qId, SUdfInfo* pUdfInfo);
|
||||||
|
|
||||||
int32_t initQInfo(STsBufInfo* pTsBufInfo, void* tsdb, void* sourceOptr, SQInfo* pQInfo, SQueryParam* param, char* start,
|
int32_t initQInfo(STsBufInfo* pTsBufInfo, void* tsdb, void* sourceOptr, SQInfo* pQInfo, SQueryParam* param, char* start,
|
||||||
int32_t prevResultLen, void* merger);
|
int32_t prevResultLen, void* merger);
|
||||||
|
|
@ -608,6 +614,8 @@ bool doBuildResCheck(SQInfo* pQInfo);
|
||||||
void setQueryStatus(SQueryRuntimeEnv *pRuntimeEnv, int8_t status);
|
void setQueryStatus(SQueryRuntimeEnv *pRuntimeEnv, int8_t status);
|
||||||
|
|
||||||
bool onlyQueryTags(SQueryAttr* pQueryAttr);
|
bool onlyQueryTags(SQueryAttr* pQueryAttr);
|
||||||
|
void destroyUdfInfo(SUdfInfo* pUdfInfo);
|
||||||
|
|
||||||
bool isValidQInfo(void *param);
|
bool isValidQInfo(void *param);
|
||||||
|
|
||||||
int32_t doDumpQueryResult(SQInfo *pQInfo, char *data);
|
int32_t doDumpQueryResult(SQInfo *pQInfo, char *data);
|
||||||
|
|
@ -625,4 +633,6 @@ void freeQueryAttr(SQueryAttr *pQuery);
|
||||||
|
|
||||||
int32_t getMaximumIdleDurationSec();
|
int32_t getMaximumIdleDurationSec();
|
||||||
|
|
||||||
|
void doInvokeUdf(SUdfInfo* pUdfInfo, SQLFunctionCtx *pCtx, int32_t idx, int32_t type);
|
||||||
|
|
||||||
#endif // TDENGINE_QEXECUTOR_H
|
#endif // TDENGINE_QEXECUTOR_H
|
||||||
|
|
|
||||||
|
|
@ -77,13 +77,13 @@ typedef struct tFilePagesItem {
|
||||||
|
|
||||||
typedef struct SSchemaEx {
|
typedef struct SSchemaEx {
|
||||||
struct SSchema field;
|
struct SSchema field;
|
||||||
int16_t offset;
|
int32_t offset;
|
||||||
} SSchemaEx;
|
} SSchemaEx;
|
||||||
|
|
||||||
typedef struct SColumnModel {
|
typedef struct SColumnModel {
|
||||||
int32_t capacity;
|
int32_t capacity;
|
||||||
int32_t numOfCols;
|
int32_t numOfCols;
|
||||||
int16_t rowSize;
|
int32_t rowSize;
|
||||||
SSchemaEx *pFields;
|
SSchemaEx *pFields;
|
||||||
} SColumnModel;
|
} SColumnModel;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,82 @@
|
||||||
|
/*
|
||||||
|
* 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_QSCRIPT_H
|
||||||
|
#define TDENGINE_QSCRIPT_H
|
||||||
|
|
||||||
|
#include <lua.h>
|
||||||
|
#include <lauxlib.h>
|
||||||
|
#include <lualib.h>
|
||||||
|
|
||||||
|
#include "tutil.h"
|
||||||
|
#include "hash.h"
|
||||||
|
#include "tlist.h"
|
||||||
|
#include "qUdf.h"
|
||||||
|
|
||||||
|
#define MAX_FUNC_NAME 64
|
||||||
|
|
||||||
|
#define USER_FUNC_NAME "funcName"
|
||||||
|
#define USER_FUNC_NAME_LIMIT 48
|
||||||
|
|
||||||
|
enum ScriptState {
|
||||||
|
SCRIPT_STATE_INIT,
|
||||||
|
SCRIPT_STATE_ADD,
|
||||||
|
SCRIPT_STATE_MERGE,
|
||||||
|
SCRIPT_STATE_FINALIZE
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
SHashObj *funcId; //func already registed in lua_env, may be no use
|
||||||
|
lua_State *lua_state; // lua env
|
||||||
|
} ScriptEnv;
|
||||||
|
|
||||||
|
typedef struct ScriptCtx {
|
||||||
|
char funcName[USER_FUNC_NAME_LIMIT];
|
||||||
|
int8_t state;
|
||||||
|
ScriptEnv *pEnv;
|
||||||
|
int8_t isAgg; // agg function or not
|
||||||
|
|
||||||
|
// init value of udf script
|
||||||
|
int8_t resType;
|
||||||
|
int16_t resBytes;
|
||||||
|
|
||||||
|
int32_t numOfOutput;
|
||||||
|
int32_t offset;
|
||||||
|
|
||||||
|
} ScriptCtx;
|
||||||
|
|
||||||
|
int taosLoadScriptInit(void *pInit);
|
||||||
|
void taosLoadScriptNormal(void *pInit, char *pInput, int16_t iType, int16_t iBytes, int32_t numOfRows,
|
||||||
|
int64_t *ptsList, int64_t key, char* pOutput, char *ptsOutput, int32_t *numOfOutput, int16_t oType, int16_t oBytes);
|
||||||
|
void taosLoadScriptFinalize(void *pInit, int64_t key, char *pOutput, int32_t *output);
|
||||||
|
void taosLoadScriptMerge(void *pCtx, char* data, int32_t numOfRows, char* dataOutput, int32_t* numOfOutput);
|
||||||
|
void taosLoadScriptDestroy(void *pInit);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
SList *scriptEnvs; //
|
||||||
|
int32_t mSize; // pool limit
|
||||||
|
int32_t cSize; // current available size
|
||||||
|
pthread_mutex_t mutex;
|
||||||
|
} ScriptEnvPool;
|
||||||
|
|
||||||
|
ScriptCtx* createScriptCtx(char *str, int8_t resType, int16_t resBytes);
|
||||||
|
void destroyScriptCtx(void *pScriptCtx);
|
||||||
|
|
||||||
|
int32_t scriptEnvPoolInit();
|
||||||
|
void scriptEnvPoolCleanup();
|
||||||
|
bool isValidScript(char *script, int32_t len);
|
||||||
|
|
||||||
|
#endif //TDENGINE_QSCRIPT_H
|
||||||
|
|
@ -182,6 +182,15 @@ typedef struct SCreateDbInfo {
|
||||||
int16_t partitions;
|
int16_t partitions;
|
||||||
} SCreateDbInfo;
|
} SCreateDbInfo;
|
||||||
|
|
||||||
|
typedef struct SCreateFuncInfo {
|
||||||
|
SStrToken name;
|
||||||
|
SStrToken path;
|
||||||
|
int32_t type;
|
||||||
|
int32_t bufSize;
|
||||||
|
TAOS_FIELD output;
|
||||||
|
} SCreateFuncInfo;
|
||||||
|
|
||||||
|
|
||||||
typedef struct SCreateAcctInfo {
|
typedef struct SCreateAcctInfo {
|
||||||
int32_t maxUsers;
|
int32_t maxUsers;
|
||||||
int32_t maxDbs;
|
int32_t maxDbs;
|
||||||
|
|
@ -216,6 +225,7 @@ typedef struct SMiscInfo {
|
||||||
union {
|
union {
|
||||||
SCreateDbInfo dbOpt;
|
SCreateDbInfo dbOpt;
|
||||||
SCreateAcctInfo acctOpt;
|
SCreateAcctInfo acctOpt;
|
||||||
|
SCreateFuncInfo funcOpt;
|
||||||
SShowInfo showOpt;
|
SShowInfo showOpt;
|
||||||
SStrToken id;
|
SStrToken id;
|
||||||
};
|
};
|
||||||
|
|
@ -226,6 +236,7 @@ typedef struct SSqlInfo {
|
||||||
bool valid;
|
bool valid;
|
||||||
SArray *list; // todo refactor
|
SArray *list; // todo refactor
|
||||||
char msg[256];
|
char msg[256];
|
||||||
|
SArray *funcs;
|
||||||
union {
|
union {
|
||||||
SCreateTableSql *pCreateTableInfo;
|
SCreateTableSql *pCreateTableInfo;
|
||||||
SAlterTableInfo *pAlterInfo;
|
SAlterTableInfo *pAlterInfo;
|
||||||
|
|
@ -271,6 +282,7 @@ SRelationInfo *addSubqueryElem(SRelationInfo* pRelationInfo, SArray* pSub, SStrT
|
||||||
// sql expr leaf node
|
// sql expr leaf node
|
||||||
tSqlExpr *tSqlExprCreateIdValue(SStrToken *pToken, int32_t optrType);
|
tSqlExpr *tSqlExprCreateIdValue(SStrToken *pToken, int32_t optrType);
|
||||||
tSqlExpr *tSqlExprCreateFunction(SArray *pParam, SStrToken *pFuncToken, SStrToken *endToken, int32_t optType);
|
tSqlExpr *tSqlExprCreateFunction(SArray *pParam, SStrToken *pFuncToken, SStrToken *endToken, int32_t optType);
|
||||||
|
SArray *tStrTokenAppend(SArray *pList, SStrToken *pToken);
|
||||||
|
|
||||||
tSqlExpr *tSqlExprCreate(tSqlExpr *pLeft, tSqlExpr *pRight, int32_t optrType);
|
tSqlExpr *tSqlExprCreate(tSqlExpr *pLeft, tSqlExpr *pRight, int32_t optrType);
|
||||||
tSqlExpr *tSqlExprClone(tSqlExpr *pSrc);
|
tSqlExpr *tSqlExprClone(tSqlExpr *pSrc);
|
||||||
|
|
|
||||||
|
|
@ -125,6 +125,10 @@ typedef struct SQueryInfo {
|
||||||
int32_t round; // 0/1/....
|
int32_t round; // 0/1/....
|
||||||
int32_t bufLen;
|
int32_t bufLen;
|
||||||
char* buf;
|
char* buf;
|
||||||
|
|
||||||
|
bool udfCopy;
|
||||||
|
SArray *pUdfInfo;
|
||||||
|
|
||||||
struct SQInfo *pQInfo; // global merge operator
|
struct SQInfo *pQInfo; // global merge operator
|
||||||
struct SQueryAttr *pQueryAttr; // query object
|
struct SQueryAttr *pQueryAttr; // query object
|
||||||
|
|
||||||
|
|
@ -141,6 +145,7 @@ typedef struct SQueryInfo {
|
||||||
bool onlyTagQuery;
|
bool onlyTagQuery;
|
||||||
bool orderProjectQuery;
|
bool orderProjectQuery;
|
||||||
bool stateWindow;
|
bool stateWindow;
|
||||||
|
bool globalMerge;
|
||||||
} SQueryInfo;
|
} SQueryInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* 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_QUDF_H
|
||||||
|
#define TDENGINE_QUDF_H
|
||||||
|
|
||||||
|
enum { TSDB_UDF_FUNC_NORMAL = 0, TSDB_UDF_FUNC_INIT, TSDB_UDF_FUNC_FINALIZE, TSDB_UDF_FUNC_MERGE, TSDB_UDF_FUNC_DESTROY, TSDB_UDF_FUNC_MAX_NUM };
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct SUdfInit{
|
||||||
|
int32_t maybe_null; /* 1 if function can return NULL */
|
||||||
|
uint32_t decimals; /* for real functions */
|
||||||
|
uint64_t length; /* For string functions */
|
||||||
|
char *ptr; /* free pointer for function data */
|
||||||
|
int32_t const_item; /* 0 if result is independent of arguments */
|
||||||
|
|
||||||
|
// script like lua/javascript
|
||||||
|
void* script_ctx;
|
||||||
|
void (*destroyCtxFunc)(void *script_ctx);
|
||||||
|
} SUdfInit;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct SUdfInfo {
|
||||||
|
int32_t functionId; // system assigned function id
|
||||||
|
int32_t funcType; // scalar function or aggregate function
|
||||||
|
int8_t resType; // result type
|
||||||
|
int16_t resBytes; // result byte
|
||||||
|
int32_t contLen; // content length
|
||||||
|
int32_t bufSize; //interbuf size
|
||||||
|
char *name; // function name
|
||||||
|
void *handle; // handle loaded in mem
|
||||||
|
void *funcs[TSDB_UDF_FUNC_MAX_NUM]; // function ptr
|
||||||
|
|
||||||
|
// for script like lua/javascript only
|
||||||
|
int isScript;
|
||||||
|
void *pScriptCtx;
|
||||||
|
|
||||||
|
SUdfInit init;
|
||||||
|
char *content;
|
||||||
|
char *path;
|
||||||
|
} SUdfInfo;
|
||||||
|
|
||||||
|
//script
|
||||||
|
|
||||||
|
typedef int32_t (*scriptInitFunc)(void *pCtx);
|
||||||
|
typedef void (*scriptNormalFunc)(void *pCtx, char* data, int16_t iType, int16_t iBytes, int32_t numOfRows,
|
||||||
|
int64_t* ptList, int64_t key, char* dataOutput, char* tsOutput, int32_t* numOfOutput, int16_t oType, int16_t oBytes);
|
||||||
|
typedef void (*scriptFinalizeFunc)(void *pCtx, int64_t key, char* dataOutput, int32_t* numOfOutput);
|
||||||
|
typedef void (*scriptMergeFunc)(void *pCtx, char* data, int32_t numOfRows, char* dataOutput, int32_t* numOfOutput);
|
||||||
|
typedef void (*scriptDestroyFunc)(void* pCtx);
|
||||||
|
|
||||||
|
// dynamic lib
|
||||||
|
typedef void (*udfNormalFunc)(char* data, int16_t itype, int16_t iBytes, int32_t numOfRows, int64_t* ts, char* dataOutput, char* interBuf,
|
||||||
|
char* tsOutput, int32_t* numOfOutput, int16_t oType, int16_t oBytes, SUdfInit* buf);
|
||||||
|
typedef int32_t (*udfInitFunc)(SUdfInit* data);
|
||||||
|
typedef void (*udfFinalizeFunc)(char* dataOutput, char *interBuf, int32_t* numOfOutput, SUdfInit* buf);
|
||||||
|
typedef void (*udfMergeFunc)(char* data, int32_t numOfRows, char* dataOutput, int32_t* numOfOutput, SUdfInit* buf);
|
||||||
|
typedef void (*udfDestroyFunc)(SUdfInit* buf);
|
||||||
|
|
||||||
|
|
||||||
|
#endif // TDENGINE_QUDF_H
|
||||||
|
|
@ -66,7 +66,8 @@ static FORCE_INLINE SResultRow *getResultRow(SResultRowInfo *pResultRowInfo, int
|
||||||
return pResultRowInfo->pResult[slot];
|
return pResultRowInfo->pResult[slot];
|
||||||
}
|
}
|
||||||
|
|
||||||
static FORCE_INLINE char *getPosInResultPage(SQueryAttr *pQueryAttr, tFilePage* page, int32_t rowOffset, int16_t offset) {
|
static FORCE_INLINE char* getPosInResultPage(SQueryAttr* pQueryAttr, tFilePage* page, int32_t rowOffset,
|
||||||
|
int32_t offset) {
|
||||||
assert(rowOffset >= 0 && pQueryAttr != NULL);
|
assert(rowOffset >= 0 && pQueryAttr != NULL);
|
||||||
|
|
||||||
int32_t numOfRows = (int32_t)GET_ROW_PARAM_FOR_MULTIOUTPUT(pQueryAttr, pQueryAttr->topBotQuery, pQueryAttr->stableQuery);
|
int32_t numOfRows = (int32_t)GET_ROW_PARAM_FOR_MULTIOUTPUT(pQueryAttr, pQueryAttr->topBotQuery, pQueryAttr->stableQuery);
|
||||||
|
|
@ -104,4 +105,6 @@ int32_t getNumOfTotalRes(SGroupResInfo* pGroupResInfo);
|
||||||
|
|
||||||
int32_t mergeIntoGroupResult(SGroupResInfo* pGroupResInfo, SQueryRuntimeEnv *pRuntimeEnv, int32_t* offset);
|
int32_t mergeIntoGroupResult(SGroupResInfo* pGroupResInfo, SQueryRuntimeEnv *pRuntimeEnv, int32_t* offset);
|
||||||
|
|
||||||
|
int32_t initUdfInfo(SUdfInfo* pUdfInfo);
|
||||||
|
|
||||||
#endif // TDENGINE_QUERYUTIL_H
|
#endif // TDENGINE_QUERYUTIL_H
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,7 @@ program ::= cmd. {}
|
||||||
//////////////////////////////////THE SHOW STATEMENT///////////////////////////////////////////
|
//////////////////////////////////THE SHOW STATEMENT///////////////////////////////////////////
|
||||||
cmd ::= SHOW DATABASES. { setShowOptions(pInfo, TSDB_MGMT_TABLE_DB, 0, 0);}
|
cmd ::= SHOW DATABASES. { setShowOptions(pInfo, TSDB_MGMT_TABLE_DB, 0, 0);}
|
||||||
cmd ::= SHOW TOPICS. { setShowOptions(pInfo, TSDB_MGMT_TABLE_TP, 0, 0);}
|
cmd ::= SHOW TOPICS. { setShowOptions(pInfo, TSDB_MGMT_TABLE_TP, 0, 0);}
|
||||||
|
cmd ::= SHOW FUNCTIONS. { setShowOptions(pInfo, TSDB_MGMT_TABLE_FUNCTION, 0, 0);}
|
||||||
cmd ::= SHOW MNODES. { setShowOptions(pInfo, TSDB_MGMT_TABLE_MNODE, 0, 0);}
|
cmd ::= SHOW MNODES. { setShowOptions(pInfo, TSDB_MGMT_TABLE_MNODE, 0, 0);}
|
||||||
cmd ::= SHOW DNODES. { setShowOptions(pInfo, TSDB_MGMT_TABLE_DNODE, 0, 0);}
|
cmd ::= SHOW DNODES. { setShowOptions(pInfo, TSDB_MGMT_TABLE_DNODE, 0, 0);}
|
||||||
cmd ::= SHOW ACCOUNTS. { setShowOptions(pInfo, TSDB_MGMT_TABLE_ACCT, 0, 0);}
|
cmd ::= SHOW ACCOUNTS. { setShowOptions(pInfo, TSDB_MGMT_TABLE_ACCT, 0, 0);}
|
||||||
|
|
@ -147,6 +148,7 @@ cmd ::= DROP STABLE ifexists(Y) ids(X) cpxName(Z). {
|
||||||
|
|
||||||
cmd ::= DROP DATABASE ifexists(Y) ids(X). { setDropDbTableInfo(pInfo, TSDB_SQL_DROP_DB, &X, &Y, TSDB_DB_TYPE_DEFAULT, -1); }
|
cmd ::= DROP DATABASE ifexists(Y) ids(X). { setDropDbTableInfo(pInfo, TSDB_SQL_DROP_DB, &X, &Y, TSDB_DB_TYPE_DEFAULT, -1); }
|
||||||
cmd ::= DROP TOPIC ifexists(Y) ids(X). { setDropDbTableInfo(pInfo, TSDB_SQL_DROP_DB, &X, &Y, TSDB_DB_TYPE_TOPIC, -1); }
|
cmd ::= DROP TOPIC ifexists(Y) ids(X). { setDropDbTableInfo(pInfo, TSDB_SQL_DROP_DB, &X, &Y, TSDB_DB_TYPE_TOPIC, -1); }
|
||||||
|
cmd ::= DROP FUNCTION ids(X). { setDropFuncInfo(pInfo, TSDB_SQL_DROP_FUNCTION, &X); }
|
||||||
|
|
||||||
cmd ::= DROP DNODE ids(X). { setDCLSqlElems(pInfo, TSDB_SQL_DROP_DNODE, 1, &X); }
|
cmd ::= DROP DNODE ids(X). { setDCLSqlElems(pInfo, TSDB_SQL_DROP_DNODE, 1, &X); }
|
||||||
cmd ::= DROP USER ids(X). { setDCLSqlElems(pInfo, TSDB_SQL_DROP_USER, 1, &X); }
|
cmd ::= DROP USER ids(X). { setDCLSqlElems(pInfo, TSDB_SQL_DROP_USER, 1, &X); }
|
||||||
|
|
@ -200,8 +202,13 @@ cmd ::= CREATE ACCOUNT ids(X) PASS ids(Y) acct_optr(Z).
|
||||||
{ setCreateAcctSql(pInfo, TSDB_SQL_CREATE_ACCT, &X, &Y, &Z);}
|
{ setCreateAcctSql(pInfo, TSDB_SQL_CREATE_ACCT, &X, &Y, &Z);}
|
||||||
cmd ::= CREATE DATABASE ifnotexists(Z) ids(X) db_optr(Y). { setCreateDbInfo(pInfo, TSDB_SQL_CREATE_DB, &X, &Y, &Z);}
|
cmd ::= CREATE DATABASE ifnotexists(Z) ids(X) db_optr(Y). { setCreateDbInfo(pInfo, TSDB_SQL_CREATE_DB, &X, &Y, &Z);}
|
||||||
cmd ::= CREATE TOPIC ifnotexists(Z) ids(X) topic_optr(Y). { setCreateDbInfo(pInfo, TSDB_SQL_CREATE_DB, &X, &Y, &Z);}
|
cmd ::= CREATE TOPIC ifnotexists(Z) ids(X) topic_optr(Y). { setCreateDbInfo(pInfo, TSDB_SQL_CREATE_DB, &X, &Y, &Z);}
|
||||||
|
cmd ::= CREATE FUNCTION ids(X) AS ids(Y) OUTPUTTYPE typename(Z) bufsize(B). { setCreateFuncInfo(pInfo, TSDB_SQL_CREATE_FUNCTION, &X, &Y, &Z, &B, 1);}
|
||||||
|
cmd ::= CREATE AGGREGATE FUNCTION ids(X) AS ids(Y) OUTPUTTYPE typename(Z) bufsize(B). { setCreateFuncInfo(pInfo, TSDB_SQL_CREATE_FUNCTION, &X, &Y, &Z, &B, 2);}
|
||||||
cmd ::= CREATE USER ids(X) PASS ids(Y). { setCreateUserSql(pInfo, &X, &Y);}
|
cmd ::= CREATE USER ids(X) PASS ids(Y). { setCreateUserSql(pInfo, &X, &Y);}
|
||||||
|
|
||||||
|
bufsize(Y) ::= . { Y.n = 0; }
|
||||||
|
bufsize(Y) ::= BUFSIZE INTEGER(X). { Y = X; }
|
||||||
|
|
||||||
pps(Y) ::= . { Y.n = 0; }
|
pps(Y) ::= . { Y.n = 0; }
|
||||||
pps(Y) ::= PPS INTEGER(X). { Y = X; }
|
pps(Y) ::= PPS INTEGER(X). { Y = X; }
|
||||||
|
|
||||||
|
|
@ -704,10 +711,10 @@ expr(A) ::= BOOL(X). { A = tSqlExprCreateIdValue(&X, TK_BOOL);}
|
||||||
expr(A) ::= NULL(X). { A = tSqlExprCreateIdValue(&X, TK_NULL);}
|
expr(A) ::= NULL(X). { A = tSqlExprCreateIdValue(&X, TK_NULL);}
|
||||||
|
|
||||||
// ordinary functions: min(x), max(x), top(k, 20)
|
// ordinary functions: min(x), max(x), top(k, 20)
|
||||||
expr(A) ::= ID(X) LP exprlist(Y) RP(E). { A = tSqlExprCreateFunction(Y, &X, &E, X.type); }
|
expr(A) ::= ID(X) LP exprlist(Y) RP(E). { tStrTokenAppend(pInfo->funcs, &X); A = tSqlExprCreateFunction(Y, &X, &E, X.type); }
|
||||||
|
|
||||||
// for parsing sql functions with wildcard for parameters. e.g., count(*)/first(*)/last(*) operation
|
// for parsing sql functions with wildcard for parameters. e.g., count(*)/first(*)/last(*) operation
|
||||||
expr(A) ::= ID(X) LP STAR RP(Y). { A = tSqlExprCreateFunction(NULL, &X, &Y, X.type); }
|
expr(A) ::= ID(X) LP STAR RP(Y). { tStrTokenAppend(pInfo->funcs, &X); A = tSqlExprCreateFunction(NULL, &X, &Y, X.type); }
|
||||||
|
|
||||||
// is (not) null expression
|
// is (not) null expression
|
||||||
expr(A) ::= expr(X) IS NULL. {A = tSqlExprCreate(X, NULL, TK_ISNULL);}
|
expr(A) ::= expr(X) IS NULL. {A = tSqlExprCreate(X, NULL, TK_ISNULL);}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@
|
||||||
#include "qPercentile.h"
|
#include "qPercentile.h"
|
||||||
#include "qTsbuf.h"
|
#include "qTsbuf.h"
|
||||||
#include "queryLog.h"
|
#include "queryLog.h"
|
||||||
|
#include "qUdf.h"
|
||||||
|
|
||||||
#define GET_INPUT_DATA_LIST(x) ((char *)((x)->pInput))
|
#define GET_INPUT_DATA_LIST(x) ((char *)((x)->pInput))
|
||||||
#define GET_INPUT_DATA(x, y) (GET_INPUT_DATA_LIST(x) + (y) * (x)->inputBytes)
|
#define GET_INPUT_DATA(x, y) (GET_INPUT_DATA_LIST(x) + (y) * (x)->inputBytes)
|
||||||
|
|
@ -169,12 +170,13 @@ typedef struct SDerivInfo {
|
||||||
} SDerivInfo;
|
} SDerivInfo;
|
||||||
|
|
||||||
int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionId, int32_t param, int16_t *type,
|
int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionId, int32_t param, int16_t *type,
|
||||||
int16_t *bytes, int32_t *interBytes, int16_t extLength, bool isSuperTable) {
|
int16_t *bytes, int32_t *interBytes, int16_t extLength, bool isSuperTable, SUdfInfo* pUdfInfo) {
|
||||||
if (!isValidDataType(dataType)) {
|
if (!isValidDataType(dataType)) {
|
||||||
qError("Illegal data type %d or data type length %d", dataType, dataBytes);
|
qError("Illegal data type %d or data type length %d", dataType, dataBytes);
|
||||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (functionId == TSDB_FUNC_TS || functionId == TSDB_FUNC_TS_DUMMY || functionId == TSDB_FUNC_TAG_DUMMY ||
|
if (functionId == TSDB_FUNC_TS || functionId == TSDB_FUNC_TS_DUMMY || functionId == TSDB_FUNC_TAG_DUMMY ||
|
||||||
functionId == TSDB_FUNC_DIFF || functionId == TSDB_FUNC_PRJ || functionId == TSDB_FUNC_TAGPRJ ||
|
functionId == TSDB_FUNC_DIFF || functionId == TSDB_FUNC_PRJ || functionId == TSDB_FUNC_TAGPRJ ||
|
||||||
functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_INTERP) {
|
functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_INTERP) {
|
||||||
|
|
@ -234,6 +236,20 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isSuperTable) {
|
if (isSuperTable) {
|
||||||
|
if (functionId < 0) {
|
||||||
|
if (pUdfInfo->bufSize > 0) {
|
||||||
|
*type = TSDB_DATA_TYPE_BINARY;
|
||||||
|
*bytes = pUdfInfo->bufSize;
|
||||||
|
*interBytes = *bytes;
|
||||||
|
} else {
|
||||||
|
*type = pUdfInfo->resType;
|
||||||
|
*bytes = pUdfInfo->resBytes;
|
||||||
|
*interBytes = *bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
if (functionId == TSDB_FUNC_MIN || functionId == TSDB_FUNC_MAX) {
|
if (functionId == TSDB_FUNC_MIN || functionId == TSDB_FUNC_MAX) {
|
||||||
*type = TSDB_DATA_TYPE_BINARY;
|
*type = TSDB_DATA_TYPE_BINARY;
|
||||||
*bytes = (int16_t)(dataBytes + DATA_SET_FLAG_SIZE);
|
*bytes = (int16_t)(dataBytes + DATA_SET_FLAG_SIZE);
|
||||||
|
|
@ -314,6 +330,19 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (functionId < 0) {
|
||||||
|
*type = pUdfInfo->resType;
|
||||||
|
*bytes = pUdfInfo->resBytes;
|
||||||
|
|
||||||
|
if (pUdfInfo->bufSize > 0) {
|
||||||
|
*interBytes = pUdfInfo->bufSize;
|
||||||
|
} else {
|
||||||
|
*interBytes = *bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
if (functionId == TSDB_FUNC_AVG) {
|
if (functionId == TSDB_FUNC_AVG) {
|
||||||
*type = TSDB_DATA_TYPE_DOUBLE;
|
*type = TSDB_DATA_TYPE_DOUBLE;
|
||||||
*bytes = sizeof(double);
|
*bytes = sizeof(double);
|
||||||
|
|
@ -390,14 +419,13 @@ int32_t isValidFunction(const char* name, int32_t len) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool function_setup(SQLFunctionCtx *pCtx) {
|
static bool function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResultInfo) {
|
||||||
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
|
if (pResultInfo->initialized) {
|
||||||
if (pResInfo->initialized) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(pCtx->pOutput, 0, (size_t)pCtx->outputBytes);
|
memset(pCtx->pOutput, 0, (size_t)pCtx->outputBytes);
|
||||||
initResultInfo(pResInfo, pCtx->interBufBytes);
|
initResultInfo(pResultInfo, pCtx->interBufBytes);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -985,8 +1013,8 @@ static void minMax_function(SQLFunctionCtx *pCtx, char *pOutput, int32_t isMin,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool min_func_setup(SQLFunctionCtx *pCtx) {
|
static bool min_func_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResultInfo) {
|
||||||
if (!function_setup(pCtx)) {
|
if (!function_setup(pCtx, pResultInfo)) {
|
||||||
return false; // not initialized since it has been initialized
|
return false; // not initialized since it has been initialized
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1030,8 +1058,8 @@ static bool min_func_setup(SQLFunctionCtx *pCtx) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool max_func_setup(SQLFunctionCtx *pCtx) {
|
static bool max_func_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResultInfo) {
|
||||||
if (!function_setup(pCtx)) {
|
if (!function_setup(pCtx, pResultInfo)) {
|
||||||
return false; // not initialized since it has been initialized
|
return false; // not initialized since it has been initialized
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1435,8 +1463,8 @@ static void stddev_dst_finalizer(SQLFunctionCtx *pCtx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////
|
||||||
static bool first_last_function_setup(SQLFunctionCtx *pCtx) {
|
static bool first_last_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResInfo) {
|
||||||
if (!function_setup(pCtx)) {
|
if (!function_setup(pCtx, pResInfo)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2073,14 +2101,13 @@ bool topbot_datablock_filter(SQLFunctionCtx *pCtx, const char *minval, const cha
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool top_bottom_function_setup(SQLFunctionCtx *pCtx) {
|
static bool top_bottom_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResInfo) {
|
||||||
if (!function_setup(pCtx)) {
|
if (!function_setup(pCtx, pResInfo)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
STopBotInfo *pInfo = getTopBotOutputInfo(pCtx);
|
STopBotInfo *pInfo = getTopBotOutputInfo(pCtx);
|
||||||
buildTopBotStruct(pInfo, pCtx);
|
buildTopBotStruct(pInfo, pCtx);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2229,14 +2256,13 @@ static void top_bottom_func_finalizer(SQLFunctionCtx *pCtx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
static bool percentile_function_setup(SQLFunctionCtx *pCtx) {
|
static bool percentile_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResultInfo) {
|
||||||
if (!function_setup(pCtx)) {
|
if (!function_setup(pCtx, pResultInfo)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// in the first round, get the min-max value of all involved data
|
// in the first round, get the min-max value of all involved data
|
||||||
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
|
SPercentileInfo *pInfo = GET_ROWCELL_INTERBUF(pResultInfo);
|
||||||
SPercentileInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
|
||||||
SET_DOUBLE_VAL(&pInfo->minval, DBL_MAX);
|
SET_DOUBLE_VAL(&pInfo->minval, DBL_MAX);
|
||||||
SET_DOUBLE_VAL(&pInfo->maxval, -DBL_MAX);
|
SET_DOUBLE_VAL(&pInfo->maxval, -DBL_MAX);
|
||||||
pInfo->numOfElems = 0;
|
pInfo->numOfElems = 0;
|
||||||
|
|
@ -2367,8 +2393,8 @@ static SAPercentileInfo *getAPerctInfo(SQLFunctionCtx *pCtx) {
|
||||||
return pInfo;
|
return pInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool apercentile_function_setup(SQLFunctionCtx *pCtx) {
|
static bool apercentile_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResultInfo) {
|
||||||
if (!function_setup(pCtx)) {
|
if (!function_setup(pCtx, pResultInfo)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2477,12 +2503,11 @@ static void apercentile_finalizer(SQLFunctionCtx *pCtx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
static bool leastsquares_function_setup(SQLFunctionCtx *pCtx) {
|
static bool leastsquares_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResInfo) {
|
||||||
if (!function_setup(pCtx)) {
|
if (!function_setup(pCtx, pResInfo)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SResultRowCellInfo * pResInfo = GET_RES_INFO(pCtx);
|
|
||||||
SLeastsquaresInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
SLeastsquaresInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||||
|
|
||||||
// 2*3 matrix
|
// 2*3 matrix
|
||||||
|
|
@ -2706,8 +2731,8 @@ enum {
|
||||||
INITIAL_VALUE_NOT_ASSIGNED = 0,
|
INITIAL_VALUE_NOT_ASSIGNED = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool diff_function_setup(SQLFunctionCtx *pCtx) {
|
static bool diff_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResInfo) {
|
||||||
if (!function_setup(pCtx)) {
|
if (!function_setup(pCtx, pResInfo)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2716,14 +2741,13 @@ static bool diff_function_setup(SQLFunctionCtx *pCtx) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool deriv_function_setup(SQLFunctionCtx *pCtx) {
|
static bool deriv_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResultInfo) {
|
||||||
if (!function_setup(pCtx)) {
|
if (!function_setup(pCtx, pResultInfo)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// diff function require the value is set to -1
|
// diff function require the value is set to -1
|
||||||
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
|
SDerivInfo* pDerivInfo = GET_ROWCELL_INTERBUF(pResultInfo);
|
||||||
SDerivInfo* pDerivInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
|
||||||
|
|
||||||
pDerivInfo->ignoreNegative = pCtx->param[1].i64;
|
pDerivInfo->ignoreNegative = pCtx->param[1].i64;
|
||||||
pDerivInfo->prevTs = -1;
|
pDerivInfo->prevTs = -1;
|
||||||
|
|
@ -3130,12 +3154,12 @@ static void arithmetic_function(SQLFunctionCtx *pCtx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
static bool spread_function_setup(SQLFunctionCtx *pCtx) {
|
static bool spread_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResInfo) {
|
||||||
if (!function_setup(pCtx)) {
|
if (!function_setup(pCtx, pResInfo)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SSpreadInfo *pInfo = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
|
SSpreadInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||||
|
|
||||||
// this is the server-side setup function in client-side, the secondary merge do not need this procedure
|
// this is the server-side setup function in client-side, the secondary merge do not need this procedure
|
||||||
if (pCtx->currentStage == MERGE_STAGE) {
|
if (pCtx->currentStage == MERGE_STAGE) {
|
||||||
|
|
@ -3289,13 +3313,11 @@ void spread_function_finalizer(SQLFunctionCtx *pCtx) {
|
||||||
* param[2]: end time
|
* param[2]: end time
|
||||||
* @param pCtx
|
* @param pCtx
|
||||||
*/
|
*/
|
||||||
static bool twa_function_setup(SQLFunctionCtx *pCtx) {
|
static bool twa_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResInfo) {
|
||||||
if (!function_setup(pCtx)) {
|
if (!function_setup(pCtx, pResInfo)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
|
|
||||||
|
|
||||||
STwaInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
STwaInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||||
pInfo->p.key = INT64_MIN;
|
pInfo->p.key = INT64_MIN;
|
||||||
pInfo->win = TSWINDOW_INITIALIZER;
|
pInfo->win = TSWINDOW_INITIALIZER;
|
||||||
|
|
@ -3726,14 +3748,12 @@ static void interp_function(SQLFunctionCtx *pCtx) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ts_comp_function_setup(SQLFunctionCtx *pCtx) {
|
static bool ts_comp_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResInfo) {
|
||||||
if (!function_setup(pCtx)) {
|
if (!function_setup(pCtx, pResInfo)) {
|
||||||
return false; // not initialized since it has been initialized
|
return false; // not initialized since it has been initialized
|
||||||
}
|
}
|
||||||
|
|
||||||
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
|
|
||||||
STSCompInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
STSCompInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||||
|
|
||||||
pInfo->pTSBuf = tsBufCreate(false, pCtx->order);
|
pInfo->pTSBuf = tsBufCreate(false, pCtx->order);
|
||||||
pInfo->pTSBuf->tsOrder = pCtx->order;
|
pInfo->pTSBuf->tsOrder = pCtx->order;
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -3816,13 +3836,11 @@ static double do_calc_rate(const SRateInfo* pRateInfo, double tickPerSec) {
|
||||||
return (duration > 0)? ((double)diff) / (duration/tickPerSec):0.0;
|
return (duration > 0)? ((double)diff) / (duration/tickPerSec):0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool rate_function_setup(SQLFunctionCtx *pCtx) {
|
static bool rate_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResInfo) {
|
||||||
if (!function_setup(pCtx)) {
|
if (!function_setup(pCtx, pResInfo)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
|
|
||||||
|
|
||||||
SRateInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
SRateInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||||
pInfo->correctionValue = 0;
|
pInfo->correctionValue = 0;
|
||||||
pInfo->firstKey = INT64_MIN;
|
pInfo->firstKey = INT64_MIN;
|
||||||
|
|
@ -3964,7 +3982,7 @@ void blockInfo_func(SQLFunctionCtx* pCtx) {
|
||||||
|
|
||||||
int32_t len = *(int32_t*) pCtx->pInput;
|
int32_t len = *(int32_t*) pCtx->pInput;
|
||||||
blockDistInfoFromBinary((char*)pCtx->pInput + sizeof(int32_t), len, pDist);
|
blockDistInfoFromBinary((char*)pCtx->pInput + sizeof(int32_t), len, pDist);
|
||||||
pDist->rowSize = (int16_t) pCtx->param[0].i64;
|
pDist->rowSize = (uint16_t)pCtx->param[0].i64;
|
||||||
|
|
||||||
memcpy(pCtx->pOutput, pCtx->pInput, sizeof(int32_t) + len);
|
memcpy(pCtx->pOutput, pCtx->pInput, sizeof(int32_t) + len);
|
||||||
|
|
||||||
|
|
@ -4111,7 +4129,7 @@ void blockinfo_func_finalizer(SQLFunctionCtx* pCtx) {
|
||||||
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
|
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
|
||||||
STableBlockDist* pDist = (STableBlockDist*) GET_ROWCELL_INTERBUF(pResInfo);
|
STableBlockDist* pDist = (STableBlockDist*) GET_ROWCELL_INTERBUF(pResInfo);
|
||||||
|
|
||||||
pDist->rowSize = (int16_t)pCtx->param[0].i64;
|
pDist->rowSize = (uint16_t)pCtx->param[0].i64;
|
||||||
generateBlockDistResult(pDist, pCtx->pOutput);
|
generateBlockDistResult(pDist, pCtx->pOutput);
|
||||||
|
|
||||||
// cannot set the numOfIteratedElems again since it is set during previous iteration
|
// cannot set the numOfIteratedElems again since it is set during previous iteration
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@
|
||||||
#include "ttype.h"
|
#include "ttype.h"
|
||||||
#include "tcompare.h"
|
#include "tcompare.h"
|
||||||
#include "tscompression.h"
|
#include "tscompression.h"
|
||||||
|
#include "qScript.h"
|
||||||
|
|
||||||
#define IS_MASTER_SCAN(runtime) ((runtime)->scanFlag == MASTER_SCAN)
|
#define IS_MASTER_SCAN(runtime) ((runtime)->scanFlag == MASTER_SCAN)
|
||||||
#define IS_REVERSE_SCAN(runtime) ((runtime)->scanFlag == REVERSE_SCAN)
|
#define IS_REVERSE_SCAN(runtime) ((runtime)->scanFlag == REVERSE_SCAN)
|
||||||
|
|
@ -780,6 +781,79 @@ static int32_t getNumOfRowsInTimeWindow(SQueryRuntimeEnv* pRuntimeEnv, SDataBloc
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void doInvokeUdf(SUdfInfo* pUdfInfo, SQLFunctionCtx *pCtx, int32_t idx, int32_t type) {
|
||||||
|
int32_t output = 0;
|
||||||
|
|
||||||
|
if (pUdfInfo == NULL || pUdfInfo->funcs[type] == NULL) {
|
||||||
|
qError("empty udf function, type:%d", type);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug("invoke udf function:%s,%p", pUdfInfo->name, pUdfInfo->funcs[type]);
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case TSDB_UDF_FUNC_NORMAL:
|
||||||
|
if (pUdfInfo->isScript) {
|
||||||
|
(*(scriptNormalFunc)pUdfInfo->funcs[TSDB_UDF_FUNC_NORMAL])(pUdfInfo->pScriptCtx,
|
||||||
|
(char *)pCtx->pInput + idx * pCtx->inputType, pCtx->inputType, pCtx->inputBytes, pCtx->size, pCtx->ptsList, pCtx->startTs, pCtx->pOutput,
|
||||||
|
(char *)pCtx->ptsOutputBuf, &output, pCtx->outputType, pCtx->outputBytes);
|
||||||
|
} else {
|
||||||
|
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
|
||||||
|
|
||||||
|
void *interBuf = (void *)GET_ROWCELL_INTERBUF(pResInfo);
|
||||||
|
|
||||||
|
(*(udfNormalFunc)pUdfInfo->funcs[TSDB_UDF_FUNC_NORMAL])((char *)pCtx->pInput + idx * pCtx->inputType, pCtx->inputType, pCtx->inputBytes, pCtx->size, pCtx->ptsList,
|
||||||
|
pCtx->pOutput, interBuf, (char *)pCtx->ptsOutputBuf, &output, pCtx->outputType, pCtx->outputBytes, &pUdfInfo->init);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pUdfInfo->funcType == TSDB_UDF_TYPE_AGGREGATE) {
|
||||||
|
pCtx->resultInfo->numOfRes = output;
|
||||||
|
} else {
|
||||||
|
pCtx->resultInfo->numOfRes += output;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pCtx->resultInfo->numOfRes > 0) {
|
||||||
|
pCtx->resultInfo->hasResult = DATA_SET_FLAG;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TSDB_UDF_FUNC_MERGE:
|
||||||
|
if (pUdfInfo->isScript) {
|
||||||
|
(*(scriptMergeFunc)pUdfInfo->funcs[TSDB_UDF_FUNC_MERGE])(pUdfInfo->pScriptCtx, pCtx->pInput, pCtx->size, pCtx->pOutput, &output);
|
||||||
|
} else {
|
||||||
|
(*(udfMergeFunc)pUdfInfo->funcs[TSDB_UDF_FUNC_MERGE])(pCtx->pInput, pCtx->size, pCtx->pOutput, &output, &pUdfInfo->init);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the output value exist
|
||||||
|
pCtx->resultInfo->numOfRes = output;
|
||||||
|
if (output > 0) {
|
||||||
|
pCtx->resultInfo->hasResult = DATA_SET_FLAG;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TSDB_UDF_FUNC_FINALIZE: {
|
||||||
|
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
|
||||||
|
void *interBuf = (void *)GET_ROWCELL_INTERBUF(pResInfo);
|
||||||
|
if (pUdfInfo->isScript) {
|
||||||
|
(*(scriptFinalizeFunc)pUdfInfo->funcs[TSDB_UDF_FUNC_FINALIZE])(pUdfInfo->pScriptCtx, pCtx->startTs, pCtx->pOutput, &output);
|
||||||
|
} else {
|
||||||
|
(*(udfFinalizeFunc)pUdfInfo->funcs[TSDB_UDF_FUNC_FINALIZE])(pCtx->pOutput, interBuf, &output, &pUdfInfo->init);
|
||||||
|
}
|
||||||
|
// set the output value exist
|
||||||
|
pCtx->resultInfo->numOfRes = output;
|
||||||
|
if (output > 0) {
|
||||||
|
pCtx->resultInfo->hasResult = DATA_SET_FLAG;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
static void doApplyFunctions(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx, STimeWindow* pWin, int32_t offset,
|
static void doApplyFunctions(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx, STimeWindow* pWin, int32_t offset,
|
||||||
int32_t forwardStep, TSKEY* tsCol, int32_t numOfTotal, int32_t numOfOutput) {
|
int32_t forwardStep, TSKEY* tsCol, int32_t numOfTotal, int32_t numOfOutput) {
|
||||||
SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr;
|
SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr;
|
||||||
|
|
@ -789,7 +863,7 @@ static void doApplyFunctions(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx
|
||||||
pCtx[k].size = forwardStep;
|
pCtx[k].size = forwardStep;
|
||||||
pCtx[k].startTs = pWin->skey;
|
pCtx[k].startTs = pWin->skey;
|
||||||
|
|
||||||
// keep it temprarily
|
// keep it temporarialy
|
||||||
char* start = pCtx[k].pInput;
|
char* start = pCtx[k].pInput;
|
||||||
|
|
||||||
int32_t pos = (QUERY_IS_ASC_QUERY(pQueryAttr)) ? offset : offset - (forwardStep - 1);
|
int32_t pos = (QUERY_IS_ASC_QUERY(pQueryAttr)) ? offset : offset - (forwardStep - 1);
|
||||||
|
|
@ -807,8 +881,14 @@ static void doApplyFunctions(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx
|
||||||
pCtx[k].preAggVals.isSet = false;
|
pCtx[k].preAggVals.isSet = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t functionId = pCtx[k].functionId;
|
||||||
if (functionNeedToExecute(pRuntimeEnv, &pCtx[k])) {
|
if (functionNeedToExecute(pRuntimeEnv, &pCtx[k])) {
|
||||||
aAggs[pCtx[k].functionId].xFunction(&pCtx[k]);
|
if (functionId < 0) { // load the script and exec, pRuntimeEnv->pUdfInfo
|
||||||
|
SUdfInfo* pUdfInfo = pRuntimeEnv->pUdfInfo;
|
||||||
|
doInvokeUdf(pUdfInfo, &pCtx[k], 0, TSDB_UDF_FUNC_NORMAL);
|
||||||
|
} else {
|
||||||
|
aAggs[functionId].xFunction(&pCtx[k]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// restore it
|
// restore it
|
||||||
|
|
@ -1018,6 +1098,13 @@ static void doSetInputDataBlock(SOperatorInfo* pOperator, SQLFunctionCtx* pCtx,
|
||||||
pCtx[i].pInput = p->pData;
|
pCtx[i].pInput = p->pData;
|
||||||
assert(p->info.colId == pColIndex->colId && pCtx[i].inputType == p->info.type);
|
assert(p->info.colId == pColIndex->colId && pCtx[i].inputType == p->info.type);
|
||||||
|
|
||||||
|
if (pCtx[i].functionId < 0) {
|
||||||
|
SColumnInfoData* tsInfo = taosArrayGet(pBlock->pDataBlock, 0);
|
||||||
|
pCtx[i].ptsList = (int64_t*) tsInfo->pData;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t status = aAggs[pCtx[i].functionId].status;
|
uint32_t status = aAggs[pCtx[i].functionId].status;
|
||||||
if ((status & (TSDB_FUNCSTATE_SELECTIVITY | TSDB_FUNCSTATE_NEED_TS)) != 0) {
|
if ((status & (TSDB_FUNCSTATE_SELECTIVITY | TSDB_FUNCSTATE_NEED_TS)) != 0) {
|
||||||
SColumnInfoData* tsInfo = taosArrayGet(pBlock->pDataBlock, 0);
|
SColumnInfoData* tsInfo = taosArrayGet(pBlock->pDataBlock, 0);
|
||||||
|
|
@ -1050,7 +1137,14 @@ static void doAggregateImpl(SOperatorInfo* pOperator, TSKEY startTs, SQLFunction
|
||||||
for (int32_t k = 0; k < pOperator->numOfOutput; ++k) {
|
for (int32_t k = 0; k < pOperator->numOfOutput; ++k) {
|
||||||
if (functionNeedToExecute(pRuntimeEnv, &pCtx[k])) {
|
if (functionNeedToExecute(pRuntimeEnv, &pCtx[k])) {
|
||||||
pCtx[k].startTs = startTs;// this can be set during create the struct
|
pCtx[k].startTs = startTs;// this can be set during create the struct
|
||||||
aAggs[pCtx[k].functionId].xFunction(&pCtx[k]);
|
|
||||||
|
int32_t functionId = pCtx[k].functionId;
|
||||||
|
if (functionId < 0) {
|
||||||
|
SUdfInfo* pUdfInfo = pRuntimeEnv->pUdfInfo;
|
||||||
|
doInvokeUdf(pUdfInfo, &pCtx[k], 0, TSDB_UDF_FUNC_NORMAL);
|
||||||
|
} else {
|
||||||
|
aAggs[functionId].xFunction(&pCtx[k]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1066,9 +1160,17 @@ static void projectApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SQLFunctionCtx
|
||||||
pCtx[k].order = TSDB_ORDER_ASC;
|
pCtx[k].order = TSDB_ORDER_ASC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pCtx[k].startTs = pQueryAttr->window.skey;
|
||||||
|
|
||||||
|
if (pCtx[k].functionId < 0) {
|
||||||
|
// load the script and exec
|
||||||
|
SUdfInfo* pUdfInfo = pRuntimeEnv->pUdfInfo;
|
||||||
|
doInvokeUdf(pUdfInfo, &pCtx[k], 0, TSDB_UDF_FUNC_NORMAL);
|
||||||
|
} else {
|
||||||
aAggs[pCtx[k].functionId].xFunction(&pCtx[k]);
|
aAggs[pCtx[k].functionId].xFunction(&pCtx[k]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void doTimeWindowInterpolation(SOperatorInfo* pOperator, SOptrBasicInfo* pInfo, SArray* pDataBlock, TSKEY prevTs,
|
void doTimeWindowInterpolation(SOperatorInfo* pOperator, SOptrBasicInfo* pInfo, SArray* pDataBlock, TSKEY prevTs,
|
||||||
int32_t prevRowIndex, TSKEY curTs, int32_t curRowIndex, TSKEY windowKey, int32_t type) {
|
int32_t prevRowIndex, TSKEY curTs, int32_t curRowIndex, TSKEY windowKey, int32_t type) {
|
||||||
|
|
@ -1953,7 +2055,7 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int32_t numOf
|
||||||
|
|
||||||
case OP_GlobalAggregate: {
|
case OP_GlobalAggregate: {
|
||||||
pRuntimeEnv->proot = createGlobalAggregateOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr3,
|
pRuntimeEnv->proot = createGlobalAggregateOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr3,
|
||||||
pQueryAttr->numOfExpr3, merger);
|
pQueryAttr->numOfExpr3, merger, pQueryAttr->pUdfInfo);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2024,6 +2126,8 @@ static void teardownQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv) {
|
||||||
tfree(pRuntimeEnv->sasArray);
|
tfree(pRuntimeEnv->sasArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
destroyUdfInfo(pRuntimeEnv->pUdfInfo);
|
||||||
|
|
||||||
destroyResultBuf(pRuntimeEnv->pResultBuf);
|
destroyResultBuf(pRuntimeEnv->pResultBuf);
|
||||||
doFreeQueryHandle(pRuntimeEnv);
|
doFreeQueryHandle(pRuntimeEnv);
|
||||||
|
|
||||||
|
|
@ -2703,11 +2807,16 @@ static uint32_t doFilterByBlockTimeWindow(STableScanInfo* pTableScanInfo, SSData
|
||||||
int32_t colId = pTableScanInfo->pExpr[i].base.colInfo.colId;
|
int32_t colId = pTableScanInfo->pExpr[i].base.colInfo.colId;
|
||||||
|
|
||||||
// group by + first/last should not apply the first/last block filter
|
// group by + first/last should not apply the first/last block filter
|
||||||
|
if (functionId < 0) {
|
||||||
|
status |= BLK_DATA_ALL_NEEDED;
|
||||||
|
return status;
|
||||||
|
} else {
|
||||||
status |= aAggs[functionId].dataReqFunc(&pTableScanInfo->pCtx[i], &pBlock->info.window, colId);
|
status |= aAggs[functionId].dataReqFunc(&pTableScanInfo->pCtx[i], &pBlock->info.window, colId);
|
||||||
if ((status & BLK_DATA_ALL_NEEDED) == BLK_DATA_ALL_NEEDED) {
|
if ((status & BLK_DATA_ALL_NEEDED) == BLK_DATA_ALL_NEEDED) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
@ -3299,6 +3408,21 @@ void updateOutputBuf(SOptrBasicInfo* pBInfo, int32_t *bufCapacity, int32_t numOf
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void clearOutputBuf(SOptrBasicInfo* pBInfo, int32_t *bufCapacity) {
|
||||||
|
SSDataBlock* pDataBlock = pBInfo->pRes;
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < pDataBlock->info.numOfCols; ++i) {
|
||||||
|
SColumnInfoData *pColInfo = taosArrayGet(pDataBlock->pDataBlock, i);
|
||||||
|
|
||||||
|
int32_t functionId = pBInfo->pCtx[i].functionId;
|
||||||
|
if (functionId < 0) {
|
||||||
|
memset(pBInfo->pCtx[i].pOutput, 0, pColInfo->info.bytes * (*bufCapacity));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void initCtxOutputBuffer(SQLFunctionCtx* pCtx, int32_t size) {
|
void initCtxOutputBuffer(SQLFunctionCtx* pCtx, int32_t size) {
|
||||||
for (int32_t j = 0; j < size; ++j) {
|
for (int32_t j = 0; j < size; ++j) {
|
||||||
SResultRowCellInfo* pResInfo = GET_RES_INFO(&pCtx[j]);
|
SResultRowCellInfo* pResInfo = GET_RES_INFO(&pCtx[j]);
|
||||||
|
|
@ -3306,7 +3430,11 @@ void initCtxOutputBuffer(SQLFunctionCtx* pCtx, int32_t size) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
aAggs[pCtx[j].functionId].init(&pCtx[j]);
|
if (pCtx[j].functionId < 0) { // todo udf initialization
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
aAggs[pCtx[j].functionId].init(&pCtx[j], pCtx[j].resultInfo);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3361,8 +3489,14 @@ void finalizeQueryResult(SOperatorInfo* pOperator, SQLFunctionCtx* pCtx, SResult
|
||||||
setResultOutputBuf(pRuntimeEnv, buf, pCtx, numOfOutput, rowCellInfoOffset);
|
setResultOutputBuf(pRuntimeEnv, buf, pCtx, numOfOutput, rowCellInfoOffset);
|
||||||
|
|
||||||
for (int32_t j = 0; j < numOfOutput; ++j) {
|
for (int32_t j = 0; j < numOfOutput; ++j) {
|
||||||
|
pCtx[j].startTs = buf->win.skey;
|
||||||
|
if (pCtx[j].functionId < 0) {
|
||||||
|
doInvokeUdf(pRuntimeEnv->pUdfInfo, &pCtx[j], 0, TSDB_UDF_FUNC_FINALIZE);
|
||||||
|
} else {
|
||||||
aAggs[pCtx[j].functionId].xFinalize(&pCtx[j]);
|
aAggs[pCtx[j].functionId].xFinalize(&pCtx[j]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* set the number of output results for group by normal columns, the number of output rows usually is 1 except
|
* set the number of output results for group by normal columns, the number of output rows usually is 1 except
|
||||||
|
|
@ -3373,10 +3507,14 @@ void finalizeQueryResult(SOperatorInfo* pOperator, SQLFunctionCtx* pCtx, SResult
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
for (int32_t j = 0; j < numOfOutput; ++j) {
|
for (int32_t j = 0; j < numOfOutput; ++j) {
|
||||||
|
if (pCtx[j].functionId < 0) {
|
||||||
|
doInvokeUdf(pRuntimeEnv->pUdfInfo, &pCtx[j], 0, TSDB_UDF_FUNC_FINALIZE);
|
||||||
|
} else {
|
||||||
aAggs[pCtx[j].functionId].xFinalize(&pCtx[j]);
|
aAggs[pCtx[j].functionId].xFinalize(&pCtx[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static bool hasMainOutput(SQueryAttr *pQueryAttr) {
|
static bool hasMainOutput(SQueryAttr *pQueryAttr) {
|
||||||
for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) {
|
for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) {
|
||||||
|
|
@ -3445,7 +3583,7 @@ void setResultRowOutputBufInitCtx(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pRe
|
||||||
// Note: pResult->pos[i]->num == 0, there is only fixed number of results for each group
|
// Note: pResult->pos[i]->num == 0, there is only fixed number of results for each group
|
||||||
tFilePage* bufPage = getResBufPage(pRuntimeEnv->pResultBuf, pResult->pageId);
|
tFilePage* bufPage = getResBufPage(pRuntimeEnv->pResultBuf, pResult->pageId);
|
||||||
|
|
||||||
int16_t offset = 0;
|
int32_t offset = 0;
|
||||||
for (int32_t i = 0; i < numOfOutput; ++i) {
|
for (int32_t i = 0; i < numOfOutput; ++i) {
|
||||||
pCtx[i].resultInfo = getResultCell(pResult, i, rowCellInfoOffset);
|
pCtx[i].resultInfo = getResultCell(pResult, i, rowCellInfoOffset);
|
||||||
|
|
||||||
|
|
@ -3459,12 +3597,16 @@ void setResultRowOutputBufInitCtx(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pRe
|
||||||
offset += pCtx[i].outputBytes;
|
offset += pCtx[i].outputBytes;
|
||||||
|
|
||||||
int32_t functionId = pCtx[i].functionId;
|
int32_t functionId = pCtx[i].functionId;
|
||||||
if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM || functionId == TSDB_FUNC_DIFF || functionId == TSDB_FUNC_DERIVATIVE) {
|
if (functionId < 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM || functionId == TSDB_FUNC_DIFF) {
|
||||||
pCtx[i].ptsOutputBuf = pCtx[0].pOutput;
|
pCtx[i].ptsOutputBuf = pCtx[0].pOutput;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pResInfo->initialized) {
|
if (!pResInfo->initialized) {
|
||||||
aAggs[functionId].init(&pCtx[i]);
|
aAggs[functionId].init(&pCtx[i], pResInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3755,7 +3897,7 @@ static int32_t doCopyToSDataBlock(SQueryRuntimeEnv* pRuntimeEnv, SGroupResInfo*
|
||||||
|
|
||||||
tFilePage *page = getResBufPage(pRuntimeEnv->pResultBuf, pRow->pageId);
|
tFilePage *page = getResBufPage(pRuntimeEnv->pResultBuf, pRow->pageId);
|
||||||
|
|
||||||
int16_t offset = 0;
|
int32_t offset = 0;
|
||||||
for (int32_t j = 0; j < pBlock->info.numOfCols; ++j) {
|
for (int32_t j = 0; j < pBlock->info.numOfCols; ++j) {
|
||||||
SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, j);
|
SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, j);
|
||||||
int32_t bytes = pColInfoData->info.bytes;
|
int32_t bytes = pColInfoData->info.bytes;
|
||||||
|
|
@ -4923,7 +5065,7 @@ static void destroySlimitOperatorInfo(void* param, int32_t numOfOutput) {
|
||||||
}
|
}
|
||||||
|
|
||||||
SOperatorInfo* createGlobalAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream,
|
SOperatorInfo* createGlobalAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream,
|
||||||
SExprInfo* pExpr, int32_t numOfOutput, void* param) {
|
SExprInfo* pExpr, int32_t numOfOutput, void* param, SArray* pUdfInfo) {
|
||||||
SMultiwayMergeInfo* pInfo = calloc(1, sizeof(SMultiwayMergeInfo));
|
SMultiwayMergeInfo* pInfo = calloc(1, sizeof(SMultiwayMergeInfo));
|
||||||
|
|
||||||
pInfo->resultRowFactor =
|
pInfo->resultRowFactor =
|
||||||
|
|
@ -4933,6 +5075,7 @@ SOperatorInfo* createGlobalAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv,
|
||||||
|
|
||||||
pInfo->pMerge = param;
|
pInfo->pMerge = param;
|
||||||
pInfo->bufCapacity = 4096;
|
pInfo->bufCapacity = 4096;
|
||||||
|
pInfo->udfInfo = pUdfInfo;
|
||||||
|
|
||||||
pInfo->binfo.pRes = createOutputBuf(pExpr, numOfOutput, pInfo->bufCapacity * pInfo->resultRowFactor);
|
pInfo->binfo.pRes = createOutputBuf(pExpr, numOfOutput, pInfo->bufCapacity * pInfo->resultRowFactor);
|
||||||
pInfo->binfo.pCtx = createSQLFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pInfo->binfo.rowCellInfoOffset);
|
pInfo->binfo.pCtx = createSQLFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pInfo->binfo.rowCellInfoOffset);
|
||||||
|
|
@ -6690,6 +6833,9 @@ int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param) {
|
||||||
pQueryMsg->sw.primaryColId = htonl(pQueryMsg->sw.primaryColId);
|
pQueryMsg->sw.primaryColId = htonl(pQueryMsg->sw.primaryColId);
|
||||||
pQueryMsg->tableScanOperator = htonl(pQueryMsg->tableScanOperator);
|
pQueryMsg->tableScanOperator = htonl(pQueryMsg->tableScanOperator);
|
||||||
pQueryMsg->numOfOperator = htonl(pQueryMsg->numOfOperator);
|
pQueryMsg->numOfOperator = htonl(pQueryMsg->numOfOperator);
|
||||||
|
pQueryMsg->udfContentOffset = htonl(pQueryMsg->udfContentOffset);
|
||||||
|
pQueryMsg->udfContentLen = htonl(pQueryMsg->udfContentLen);
|
||||||
|
pQueryMsg->udfNum = htonl(pQueryMsg->udfNum);
|
||||||
|
|
||||||
// query msg safety check
|
// query msg safety check
|
||||||
if (!validateQueryMsg(pQueryMsg)) {
|
if (!validateQueryMsg(pQueryMsg)) {
|
||||||
|
|
@ -6933,6 +7079,33 @@ int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param) {
|
||||||
pMsg += sizeof(int32_t);
|
pMsg += sizeof(int32_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pQueryMsg->udfContentLen > 0) {
|
||||||
|
param->pUdfInfo = calloc(1, sizeof(SUdfInfo));
|
||||||
|
param->pUdfInfo->contLen = pQueryMsg->udfContentLen;
|
||||||
|
|
||||||
|
pMsg = (char*)pQueryMsg + pQueryMsg->udfContentOffset;
|
||||||
|
param->pUdfInfo->resType = *(int8_t*) pMsg;
|
||||||
|
pMsg += sizeof(int8_t);
|
||||||
|
|
||||||
|
param->pUdfInfo->resBytes = htons(*(int16_t*)pMsg);
|
||||||
|
pMsg += sizeof(int16_t);
|
||||||
|
|
||||||
|
tstr* name = (tstr*)(pMsg);
|
||||||
|
param->pUdfInfo->name = strndup(name->data, name->len);
|
||||||
|
|
||||||
|
pMsg += varDataTLen(name);
|
||||||
|
param->pUdfInfo->funcType = htonl(*(int32_t*)pMsg);
|
||||||
|
pMsg += sizeof(int32_t);
|
||||||
|
|
||||||
|
param->pUdfInfo->bufSize = htonl(*(int32_t*)pMsg);
|
||||||
|
pMsg += sizeof(int32_t);
|
||||||
|
|
||||||
|
param->pUdfInfo->content = malloc(pQueryMsg->udfContentLen);
|
||||||
|
memcpy(param->pUdfInfo->content, pMsg, pQueryMsg->udfContentLen);
|
||||||
|
|
||||||
|
pMsg += pQueryMsg->udfContentLen;
|
||||||
|
}
|
||||||
|
|
||||||
param->sql = strndup(pMsg, pQueryMsg->sqlstrLen);
|
param->sql = strndup(pMsg, pQueryMsg->sqlstrLen);
|
||||||
|
|
||||||
SQueriedTableInfo info = { .numOfTags = pQueryMsg->numOfTags, .numOfCols = pQueryMsg->numOfCols, .colList = pQueryMsg->tableCols};
|
SQueriedTableInfo info = { .numOfTags = pQueryMsg->numOfTags, .numOfCols = pQueryMsg->numOfCols, .colList = pQueryMsg->tableCols};
|
||||||
|
|
@ -7023,7 +7196,7 @@ static int32_t updateOutputBufForTopBotQuery(SQueriedTableInfo* pTableInfo, SCol
|
||||||
} else {
|
} else {
|
||||||
SColumnInfo* pCol = &pTableInfo->colList[j];
|
SColumnInfo* pCol = &pTableInfo->colList[j];
|
||||||
int32_t ret = getResultDataInfo(pCol->type, pCol->bytes, functId, (int32_t)pExprs[i].base.param[0].i64,
|
int32_t ret = getResultDataInfo(pCol->type, pCol->bytes, functId, (int32_t)pExprs[i].base.param[0].i64,
|
||||||
&pExprs[i].base.resType, &pExprs[i].base.resBytes, &pExprs[i].base.interBytes, tagLen, superTable);
|
&pExprs[i].base.resType, &pExprs[i].base.resBytes, &pExprs[i].base.interBytes, tagLen, superTable, NULL);
|
||||||
assert(ret == TSDB_CODE_SUCCESS);
|
assert(ret == TSDB_CODE_SUCCESS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -7032,12 +7205,138 @@ static int32_t updateOutputBufForTopBotQuery(SQueriedTableInfo* pTableInfo, SCol
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void destroyUdfInfo(SUdfInfo* pUdfInfo) {
|
||||||
|
if (pUdfInfo == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pUdfInfo->funcs[TSDB_UDF_FUNC_DESTROY]) {
|
||||||
|
if (pUdfInfo->isScript) {
|
||||||
|
(*(scriptDestroyFunc)pUdfInfo->funcs[TSDB_UDF_FUNC_DESTROY])(pUdfInfo->pScriptCtx);
|
||||||
|
tfree(pUdfInfo->content);
|
||||||
|
}else{
|
||||||
|
(*(udfDestroyFunc)pUdfInfo->funcs[TSDB_UDF_FUNC_DESTROY])(&pUdfInfo->init);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tfree(pUdfInfo->name);
|
||||||
|
|
||||||
|
if (pUdfInfo->path) {
|
||||||
|
unlink(pUdfInfo->path);
|
||||||
|
}
|
||||||
|
|
||||||
|
tfree(pUdfInfo->path);
|
||||||
|
tfree(pUdfInfo->content);
|
||||||
|
taosCloseDll(pUdfInfo->handle);
|
||||||
|
tfree(pUdfInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char* getUdfFuncName(char* name, int type) {
|
||||||
|
char* funcname = calloc(1, TSDB_FUNCTIONS_NAME_MAX_LENGTH + 10);
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case TSDB_UDF_FUNC_NORMAL:
|
||||||
|
strcpy(funcname, name);
|
||||||
|
break;
|
||||||
|
case TSDB_UDF_FUNC_INIT:
|
||||||
|
sprintf(funcname, "%s_init", name);
|
||||||
|
break;
|
||||||
|
case TSDB_UDF_FUNC_FINALIZE:
|
||||||
|
sprintf(funcname, "%s_finalize", name);
|
||||||
|
break;
|
||||||
|
case TSDB_UDF_FUNC_MERGE:
|
||||||
|
sprintf(funcname, "%s_merge", name);
|
||||||
|
break;
|
||||||
|
case TSDB_UDF_FUNC_DESTROY:
|
||||||
|
sprintf(funcname, "%s_destroy", name);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return funcname;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t initUdfInfo(SUdfInfo* pUdfInfo) {
|
||||||
|
if (pUdfInfo == NULL) {
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
//qError("script len: %d", pUdfInfo->contLen);
|
||||||
|
if (isValidScript(pUdfInfo->content, pUdfInfo->contLen)) {
|
||||||
|
pUdfInfo->isScript = 1;
|
||||||
|
pUdfInfo->pScriptCtx = createScriptCtx(pUdfInfo->content, pUdfInfo->resType, pUdfInfo->resBytes);
|
||||||
|
if (pUdfInfo->pScriptCtx == NULL) {
|
||||||
|
return TSDB_CODE_QRY_SYS_ERROR;
|
||||||
|
}
|
||||||
|
tfree(pUdfInfo->content);
|
||||||
|
|
||||||
|
pUdfInfo->funcs[TSDB_UDF_FUNC_INIT] = taosLoadScriptInit;
|
||||||
|
if (pUdfInfo->funcs[TSDB_UDF_FUNC_INIT] == NULL
|
||||||
|
|| (*(scriptInitFunc)pUdfInfo->funcs[TSDB_UDF_FUNC_INIT])(pUdfInfo->pScriptCtx) != TSDB_CODE_SUCCESS) {
|
||||||
|
return TSDB_CODE_QRY_SYS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
pUdfInfo->funcs[TSDB_UDF_FUNC_NORMAL] = taosLoadScriptNormal;
|
||||||
|
|
||||||
|
if (pUdfInfo->funcType == TSDB_UDF_TYPE_AGGREGATE) {
|
||||||
|
pUdfInfo->funcs[TSDB_UDF_FUNC_FINALIZE] = taosLoadScriptFinalize;
|
||||||
|
pUdfInfo->funcs[TSDB_UDF_FUNC_MERGE] = taosLoadScriptMerge;
|
||||||
|
}
|
||||||
|
pUdfInfo->funcs[TSDB_UDF_FUNC_DESTROY] = taosLoadScriptDestroy;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
char path[PATH_MAX] = {0};
|
||||||
|
taosGetTmpfilePath("script", path);
|
||||||
|
|
||||||
|
FILE* file = fopen(path, "w+");
|
||||||
|
|
||||||
|
// TODO check for failure of flush to disk
|
||||||
|
/*size_t t = */ fwrite(pUdfInfo->content, pUdfInfo->contLen, 1, file);
|
||||||
|
fclose(file);
|
||||||
|
tfree(pUdfInfo->content);
|
||||||
|
|
||||||
|
pUdfInfo->path = strdup(path);
|
||||||
|
|
||||||
|
pUdfInfo->handle = taosLoadDll(path);
|
||||||
|
|
||||||
|
if (NULL == pUdfInfo->handle) {
|
||||||
|
return TSDB_CODE_QRY_SYS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
pUdfInfo->funcs[TSDB_UDF_FUNC_NORMAL] = taosLoadSym(pUdfInfo->handle, getUdfFuncName(pUdfInfo->name, TSDB_UDF_FUNC_NORMAL));
|
||||||
|
if (NULL == pUdfInfo->funcs[TSDB_UDF_FUNC_NORMAL]) {
|
||||||
|
return TSDB_CODE_QRY_SYS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
pUdfInfo->funcs[TSDB_UDF_FUNC_INIT] = taosLoadSym(pUdfInfo->handle, getUdfFuncName(pUdfInfo->name, TSDB_UDF_FUNC_INIT));
|
||||||
|
|
||||||
|
if (pUdfInfo->funcType == TSDB_UDF_TYPE_AGGREGATE) {
|
||||||
|
pUdfInfo->funcs[TSDB_UDF_FUNC_FINALIZE] = taosLoadSym(pUdfInfo->handle, getUdfFuncName(pUdfInfo->name, TSDB_UDF_FUNC_FINALIZE));
|
||||||
|
pUdfInfo->funcs[TSDB_UDF_FUNC_MERGE] = taosLoadSym(pUdfInfo->handle, getUdfFuncName(pUdfInfo->name, TSDB_UDF_FUNC_MERGE));
|
||||||
|
}
|
||||||
|
|
||||||
|
pUdfInfo->funcs[TSDB_UDF_FUNC_DESTROY] = taosLoadSym(pUdfInfo->handle, getUdfFuncName(pUdfInfo->name, TSDB_UDF_FUNC_DESTROY));
|
||||||
|
|
||||||
|
if (pUdfInfo->funcs[TSDB_UDF_FUNC_INIT]) {
|
||||||
|
return (*(udfInitFunc)pUdfInfo->funcs[TSDB_UDF_FUNC_INIT])(&pUdfInfo->init);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO tag length should be passed from client, refactor
|
// TODO tag length should be passed from client, refactor
|
||||||
int32_t createQueryFunc(SQueriedTableInfo* pTableInfo, int32_t numOfOutput, SExprInfo** pExprInfo,
|
int32_t createQueryFunc(SQueriedTableInfo* pTableInfo, int32_t numOfOutput, SExprInfo** pExprInfo,
|
||||||
SSqlExpr** pExprMsg, SColumnInfo* pTagCols, int32_t queryType, void* pMsg) {
|
SSqlExpr** pExprMsg, SColumnInfo* pTagCols, int32_t queryType, void* pMsg, SUdfInfo* pUdfInfo) {
|
||||||
*pExprInfo = NULL;
|
*pExprInfo = NULL;
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
|
||||||
|
code = initUdfInfo(pUdfInfo);
|
||||||
|
if (code) {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
SExprInfo *pExprs = (SExprInfo *)calloc(numOfOutput, sizeof(SExprInfo));
|
SExprInfo *pExprs = (SExprInfo *)calloc(numOfOutput, sizeof(SExprInfo));
|
||||||
if (pExprs == NULL) {
|
if (pExprs == NULL) {
|
||||||
return TSDB_CODE_QRY_OUT_OF_MEMORY;
|
return TSDB_CODE_QRY_OUT_OF_MEMORY;
|
||||||
|
|
@ -7126,7 +7425,7 @@ int32_t createQueryFunc(SQueriedTableInfo* pTableInfo, int32_t numOfOutput, SExp
|
||||||
|
|
||||||
// todo remove it
|
// todo remove it
|
||||||
if (getResultDataInfo(type, bytes, pExprs[i].base.functionId, param, &pExprs[i].base.resType, &pExprs[i].base.resBytes,
|
if (getResultDataInfo(type, bytes, pExprs[i].base.functionId, param, &pExprs[i].base.resType, &pExprs[i].base.resBytes,
|
||||||
&pExprs[i].base.interBytes, 0, isSuperTable) != TSDB_CODE_SUCCESS) {
|
&pExprs[i].base.interBytes, 0, isSuperTable, pUdfInfo) != TSDB_CODE_SUCCESS) {
|
||||||
tfree(pExprs);
|
tfree(pExprs);
|
||||||
return TSDB_CODE_QRY_INVALID_MSG;
|
return TSDB_CODE_QRY_INVALID_MSG;
|
||||||
}
|
}
|
||||||
|
|
@ -7147,7 +7446,7 @@ int32_t createQueryFunc(SQueriedTableInfo* pTableInfo, int32_t numOfOutput, SExp
|
||||||
|
|
||||||
// todo refactor
|
// todo refactor
|
||||||
int32_t createIndirectQueryFuncExprFromMsg(SQueryTableMsg* pQueryMsg, int32_t numOfOutput, SExprInfo** pExprInfo,
|
int32_t createIndirectQueryFuncExprFromMsg(SQueryTableMsg* pQueryMsg, int32_t numOfOutput, SExprInfo** pExprInfo,
|
||||||
SSqlExpr** pExpr, SExprInfo* prevExpr) {
|
SSqlExpr** pExpr, SExprInfo* prevExpr, SUdfInfo *pUdfInfo) {
|
||||||
*pExprInfo = NULL;
|
*pExprInfo = NULL;
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
|
||||||
|
|
@ -7192,7 +7491,7 @@ int32_t createIndirectQueryFuncExprFromMsg(SQueryTableMsg* pQueryMsg, int32_t nu
|
||||||
|
|
||||||
int32_t param = (int32_t)pExprs[i].base.param[0].i64;
|
int32_t param = (int32_t)pExprs[i].base.param[0].i64;
|
||||||
if (getResultDataInfo(type, bytes, pExprs[i].base.functionId, param, &pExprs[i].base.resType, &pExprs[i].base.resBytes,
|
if (getResultDataInfo(type, bytes, pExprs[i].base.functionId, param, &pExprs[i].base.resType, &pExprs[i].base.resBytes,
|
||||||
&pExprs[i].base.interBytes, 0, isSuperTable) != TSDB_CODE_SUCCESS) {
|
&pExprs[i].base.interBytes, 0, isSuperTable, pUdfInfo) != TSDB_CODE_SUCCESS) {
|
||||||
tfree(pExprs);
|
tfree(pExprs);
|
||||||
return TSDB_CODE_QRY_INVALID_MSG;
|
return TSDB_CODE_QRY_INVALID_MSG;
|
||||||
}
|
}
|
||||||
|
|
@ -7378,7 +7677,7 @@ FORCE_INLINE bool checkQIdEqual(void *qHandle, uint64_t qId) {
|
||||||
|
|
||||||
SQInfo* createQInfoImpl(SQueryTableMsg* pQueryMsg, SGroupbyExpr* pGroupbyExpr, SExprInfo* pExprs,
|
SQInfo* createQInfoImpl(SQueryTableMsg* pQueryMsg, SGroupbyExpr* pGroupbyExpr, SExprInfo* pExprs,
|
||||||
SExprInfo* pSecExprs, STableGroupInfo* pTableGroupInfo, SColumnInfo* pTagCols, int32_t vgId,
|
SExprInfo* pSecExprs, STableGroupInfo* pTableGroupInfo, SColumnInfo* pTagCols, int32_t vgId,
|
||||||
char* sql, uint64_t qId) {
|
char* sql, uint64_t qId, SUdfInfo* pUdfInfo) {
|
||||||
int16_t numOfCols = pQueryMsg->numOfCols;
|
int16_t numOfCols = pQueryMsg->numOfCols;
|
||||||
int16_t numOfOutput = pQueryMsg->numOfOutput;
|
int16_t numOfOutput = pQueryMsg->numOfOutput;
|
||||||
|
|
||||||
|
|
@ -7389,6 +7688,8 @@ SQInfo* createQInfoImpl(SQueryTableMsg* pQueryMsg, SGroupbyExpr* pGroupbyExpr, S
|
||||||
|
|
||||||
pQInfo->qId = qId;
|
pQInfo->qId = qId;
|
||||||
|
|
||||||
|
pQInfo->runtimeEnv.pUdfInfo = pUdfInfo;
|
||||||
|
|
||||||
// to make sure third party won't overwrite this structure
|
// to make sure third party won't overwrite this structure
|
||||||
pQInfo->signature = pQInfo;
|
pQInfo->signature = pQInfo;
|
||||||
SQueryAttr* pQueryAttr = &pQInfo->query;
|
SQueryAttr* pQueryAttr = &pQInfo->query;
|
||||||
|
|
@ -7412,6 +7713,7 @@ SQInfo* createQInfoImpl(SQueryTableMsg* pQueryMsg, SGroupbyExpr* pGroupbyExpr, S
|
||||||
pQueryAttr->prjInfo.vgroupLimit = pQueryMsg->vgroupLimit;
|
pQueryAttr->prjInfo.vgroupLimit = pQueryMsg->vgroupLimit;
|
||||||
pQueryAttr->prjInfo.ts = (pQueryMsg->order == TSDB_ORDER_ASC)? INT64_MIN:INT64_MAX;
|
pQueryAttr->prjInfo.ts = (pQueryMsg->order == TSDB_ORDER_ASC)? INT64_MIN:INT64_MAX;
|
||||||
pQueryAttr->sw = pQueryMsg->sw;
|
pQueryAttr->sw = pQueryMsg->sw;
|
||||||
|
pQueryAttr->vgId = vgId;
|
||||||
|
|
||||||
pQueryAttr->stableQuery = pQueryMsg->stableQuery;
|
pQueryAttr->stableQuery = pQueryMsg->stableQuery;
|
||||||
pQueryAttr->topBotQuery = pQueryMsg->topBotQuery;
|
pQueryAttr->topBotQuery = pQueryMsg->topBotQuery;
|
||||||
|
|
@ -7444,7 +7746,6 @@ SQInfo* createQInfoImpl(SQueryTableMsg* pQueryMsg, SGroupbyExpr* pGroupbyExpr, S
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculate the result row size
|
|
||||||
for (int16_t col = 0; col < numOfOutput; ++col) {
|
for (int16_t col = 0; col < numOfOutput; ++col) {
|
||||||
assert(pExprs[col].base.resBytes > 0);
|
assert(pExprs[col].base.resBytes > 0);
|
||||||
pQueryAttr->resultRowSize += pExprs[col].base.resBytes;
|
pQueryAttr->resultRowSize += pExprs[col].base.resBytes;
|
||||||
|
|
@ -7465,6 +7766,20 @@ SQInfo* createQInfoImpl(SQueryTableMsg* pQueryMsg, SGroupbyExpr* pGroupbyExpr, S
|
||||||
goto _cleanup;
|
goto _cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pSecExprs != NULL) {
|
||||||
|
int32_t resultRowSize = 0;
|
||||||
|
|
||||||
|
// calculate the result row size
|
||||||
|
for (int16_t col = 0; col < pQueryAttr->numOfExpr2; ++col) {
|
||||||
|
assert(pSecExprs[col].base.resBytes > 0);
|
||||||
|
resultRowSize += pSecExprs[col].base.resBytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resultRowSize > pQueryAttr->resultRowSize) {
|
||||||
|
pQueryAttr->resultRowSize = resultRowSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (pQueryAttr->fillType != TSDB_FILL_NONE) {
|
if (pQueryAttr->fillType != TSDB_FILL_NONE) {
|
||||||
pQueryAttr->fillVal = malloc(sizeof(int64_t) * pQueryAttr->numOfOutput);
|
pQueryAttr->fillVal = malloc(sizeof(int64_t) * pQueryAttr->numOfOutput);
|
||||||
if (pQueryAttr->fillVal == NULL) {
|
if (pQueryAttr->fillVal == NULL) {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,443 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "os.h"
|
||||||
|
#include "qScript.h"
|
||||||
|
#include "ttype.h"
|
||||||
|
#include "tstrbuild.h"
|
||||||
|
#include "queryLog.h"
|
||||||
|
#include "ttokendef.h"
|
||||||
|
|
||||||
|
static ScriptEnvPool *pool = NULL;
|
||||||
|
|
||||||
|
static ScriptEnv* getScriptEnvFromPool();
|
||||||
|
static void addScriptEnvToPool(ScriptEnv *pEnv);
|
||||||
|
|
||||||
|
static lua_State* createLuaEnv();
|
||||||
|
static void destroyLuaEnv(lua_State *state);
|
||||||
|
|
||||||
|
static void destroyScriptEnv(ScriptEnv *pEnv);
|
||||||
|
|
||||||
|
static void luaValueToTaosType(lua_State *lua, char *interBuf, int32_t *numOfOutput, int16_t oType, int16_t oBytes);
|
||||||
|
static void taosValueToLuaType(lua_State *lua, int32_t type, char *val);
|
||||||
|
|
||||||
|
static bool hasBaseFuncDefinedInScript(lua_State *lua, const char *funcPrefix, int32_t len);
|
||||||
|
|
||||||
|
static int userlib_exampleFunc(lua_State *lua) {
|
||||||
|
double op1 = luaL_checknumber(lua,1);
|
||||||
|
double op2 = luaL_checknumber(lua,2);
|
||||||
|
lua_pushnumber(lua, op1 * op2);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
void luaRegisterLibFunc(lua_State *lua) {
|
||||||
|
lua_register(lua, "exampleFunc", userlib_exampleFunc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void luaLoadLib(lua_State *lua, const char *libname, lua_CFunction luafunc) {
|
||||||
|
lua_pushcfunction(lua, luafunc);
|
||||||
|
lua_pushstring(lua, libname);
|
||||||
|
lua_call(lua, 1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
LUALIB_API int (luaopen_cjson) (lua_State *L);
|
||||||
|
LUALIB_API int (luaopen_struct) (lua_State *L);
|
||||||
|
LUALIB_API int (luaopen_cmsgpack) (lua_State *L);
|
||||||
|
LUALIB_API int (luaopen_bit) (lua_State *L);
|
||||||
|
|
||||||
|
|
||||||
|
static void luaLoadLibraries(lua_State *lua) {
|
||||||
|
luaLoadLib(lua, "", luaopen_base);
|
||||||
|
luaLoadLib(lua, LUA_TABLIBNAME, luaopen_table);
|
||||||
|
luaLoadLib(lua, LUA_STRLIBNAME, luaopen_string);
|
||||||
|
luaLoadLib(lua, LUA_MATHLIBNAME, luaopen_math);
|
||||||
|
luaLoadLib(lua, LUA_DBLIBNAME, luaopen_debug);
|
||||||
|
}
|
||||||
|
static void luaRemoveUnsupportedFunctions(lua_State *lua) {
|
||||||
|
lua_pushnil(lua);
|
||||||
|
lua_setglobal(lua,"loadfile");
|
||||||
|
lua_pushnil(lua);
|
||||||
|
lua_setglobal(lua,"dofile");
|
||||||
|
}
|
||||||
|
void taosValueToLuaType(lua_State *lua, int32_t type, char *val) {
|
||||||
|
//TODO(dengyihao): handle more data type
|
||||||
|
if (IS_SIGNED_NUMERIC_TYPE(type) || type == TSDB_DATA_TYPE_BOOL) {
|
||||||
|
int64_t v;
|
||||||
|
GET_TYPED_DATA(v, int64_t, type, val);
|
||||||
|
lua_pushnumber(lua, (lua_Number)v);
|
||||||
|
} else if (IS_UNSIGNED_NUMERIC_TYPE(type)) {
|
||||||
|
uint64_t v;
|
||||||
|
GET_TYPED_DATA(v, uint64_t, type, val);
|
||||||
|
lua_pushnumber(lua,(lua_Number)v);
|
||||||
|
} else if (IS_FLOAT_TYPE(type)) {
|
||||||
|
double v;
|
||||||
|
GET_TYPED_DATA(v, double, type, val);
|
||||||
|
lua_pushnumber(lua,v);
|
||||||
|
} else if (type == TSDB_DATA_TYPE_BINARY) {
|
||||||
|
lua_pushlstring(lua, val, varDataLen(val));
|
||||||
|
} else if (type == TSDB_DATA_TYPE_NCHAR) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int taosLoadScriptInit(void* pInit) {
|
||||||
|
ScriptCtx *pCtx = pInit;
|
||||||
|
char funcName[MAX_FUNC_NAME] = {0};
|
||||||
|
sprintf(funcName, "%s_init", pCtx->funcName);
|
||||||
|
|
||||||
|
lua_State* lua = pCtx->pEnv->lua_state;
|
||||||
|
lua_getglobal(lua, funcName);
|
||||||
|
if (lua_pcall(lua, 0, -1, 0)) {
|
||||||
|
lua_pop(lua, -1);
|
||||||
|
}
|
||||||
|
lua_setglobal(lua, "global");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
void taosLoadScriptNormal(void *pInit, char *pInput, int16_t iType, int16_t iBytes, int32_t numOfRows,
|
||||||
|
int64_t *ptsList, int64_t key, char* pOutput, char *ptsOutput, int32_t *numOfOutput, int16_t oType, int16_t oBytes) {
|
||||||
|
ScriptCtx* pCtx = pInit;
|
||||||
|
char funcName[MAX_FUNC_NAME] = {0};
|
||||||
|
sprintf(funcName, "%s_add", pCtx->funcName);
|
||||||
|
|
||||||
|
lua_State* lua = pCtx->pEnv->lua_state;
|
||||||
|
lua_getglobal(lua, funcName);
|
||||||
|
|
||||||
|
// first param of script;
|
||||||
|
lua_newtable(lua);
|
||||||
|
int32_t offset = 0;
|
||||||
|
for (int32_t i = 0; i < numOfRows; i++) {
|
||||||
|
taosValueToLuaType(lua, iType, pInput + offset);
|
||||||
|
lua_rawseti(lua, -2, i+1);
|
||||||
|
offset += iBytes;
|
||||||
|
}
|
||||||
|
int isGlobalState = false;
|
||||||
|
lua_getglobal(lua, "global");
|
||||||
|
if (lua_istable(lua, -1)) {
|
||||||
|
isGlobalState = true;
|
||||||
|
}
|
||||||
|
lua_pushnumber(lua, (lua_Number)key);
|
||||||
|
// do call lua script
|
||||||
|
if (lua_pcall(lua, 3, 1, 0) != 0) {
|
||||||
|
qError("SCRIPT ERROR: %s", lua_tostring(lua, -1));
|
||||||
|
lua_pop(lua, -1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int tNumOfOutput = 0;
|
||||||
|
if (isGlobalState == false) {
|
||||||
|
luaValueToTaosType(lua, pOutput, &tNumOfOutput, oType, oBytes);
|
||||||
|
} else {
|
||||||
|
lua_setglobal(lua, "global");
|
||||||
|
}
|
||||||
|
*numOfOutput = tNumOfOutput;
|
||||||
|
}
|
||||||
|
|
||||||
|
void taosLoadScriptMerge(void *pInit, char* data, int32_t numOfRows, char* pOutput, int32_t* numOfOutput) {
|
||||||
|
ScriptCtx *pCtx = pInit;
|
||||||
|
char funcName[MAX_FUNC_NAME] = {0};
|
||||||
|
sprintf(funcName, "%s_merge", pCtx->funcName);
|
||||||
|
|
||||||
|
lua_State* lua = pCtx->pEnv->lua_state;
|
||||||
|
lua_getglobal(lua, funcName);
|
||||||
|
if (!lua_isfunction(lua, -1)) {
|
||||||
|
qError("SCRIPT ERROR: %s", lua_tostring(lua, -1));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_getglobal(lua, "global");
|
||||||
|
if (lua_pcall(lua, 1, 1, 0) != 0) {
|
||||||
|
qError("SCRIPT ERROR: %s", lua_tostring(lua, -1));
|
||||||
|
lua_pop(lua, -1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int tNumOfOutput = 0;
|
||||||
|
luaValueToTaosType(lua, pOutput, &tNumOfOutput, pCtx->resType, pCtx->resBytes);
|
||||||
|
*numOfOutput = tNumOfOutput;
|
||||||
|
}
|
||||||
|
|
||||||
|
//do not support agg now
|
||||||
|
void taosLoadScriptFinalize(void *pInit,int64_t key, char *pOutput, int32_t* numOfOutput) {
|
||||||
|
ScriptCtx *pCtx = pInit;
|
||||||
|
char funcName[MAX_FUNC_NAME] = {0};
|
||||||
|
sprintf(funcName, "%s_finalize", pCtx->funcName);
|
||||||
|
|
||||||
|
lua_State* lua = pCtx->pEnv->lua_state;
|
||||||
|
lua_getglobal(lua, funcName);
|
||||||
|
if (!lua_isfunction(lua, -1)) {
|
||||||
|
qError("SCRIPT ERROR: %s", lua_tostring(lua, -1));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_getglobal(lua, "global");
|
||||||
|
|
||||||
|
lua_pushnumber(lua, (lua_Number)key);
|
||||||
|
if (lua_pcall(lua, 2, 2, 0) != 0) {
|
||||||
|
qError("SCRIPT ERROR: %s", lua_tostring(lua, -1));
|
||||||
|
lua_pop(lua, -1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
lua_setglobal(lua, "global");
|
||||||
|
int tNumOfOutput = 0;
|
||||||
|
luaValueToTaosType(lua, pOutput, &tNumOfOutput, pCtx->resType, pCtx->resBytes);
|
||||||
|
*numOfOutput = tNumOfOutput;
|
||||||
|
}
|
||||||
|
|
||||||
|
void taosLoadScriptDestroy(void *pInit) {
|
||||||
|
destroyScriptCtx(pInit);
|
||||||
|
}
|
||||||
|
|
||||||
|
ScriptCtx* createScriptCtx(char *script, int8_t resType, int16_t resBytes) {
|
||||||
|
ScriptCtx *pCtx = (ScriptCtx *)calloc(1, sizeof(ScriptCtx));
|
||||||
|
pCtx->state = SCRIPT_STATE_INIT;
|
||||||
|
pCtx->pEnv = getScriptEnvFromPool(); //
|
||||||
|
pCtx->resType = resType;
|
||||||
|
pCtx->resBytes = resBytes;
|
||||||
|
|
||||||
|
if (pCtx->pEnv == NULL) {
|
||||||
|
destroyScriptCtx(pCtx);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_State *lua = pCtx->pEnv->lua_state;
|
||||||
|
if (luaL_dostring(lua, script)) {
|
||||||
|
lua_pop(lua, 1);
|
||||||
|
qError("dynamic load script failed");
|
||||||
|
destroyScriptCtx(pCtx);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
lua_getglobal(lua, USER_FUNC_NAME);
|
||||||
|
const char *name = lua_tostring(lua, -1);
|
||||||
|
if (name == NULL) {
|
||||||
|
lua_pop(lua, 1);
|
||||||
|
qError("SCRIPT ERROR: invalid script");
|
||||||
|
destroyScriptCtx(pCtx);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
memcpy(pCtx->funcName, name, strlen(name));
|
||||||
|
lua_pop(lua, 1);
|
||||||
|
|
||||||
|
return pCtx;
|
||||||
|
}
|
||||||
|
void destroyScriptCtx(void *pCtx) {
|
||||||
|
if (pCtx == NULL) return;
|
||||||
|
addScriptEnvToPool(((ScriptCtx *)pCtx)->pEnv);
|
||||||
|
free(pCtx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void luaValueToTaosType(lua_State *lua, char *interBuf, int32_t *numOfOutput, int16_t oType, int16_t oBytes) {
|
||||||
|
int t = lua_type(lua,-1);
|
||||||
|
int32_t sz = 0;
|
||||||
|
switch (t) {
|
||||||
|
case LUA_TSTRING:
|
||||||
|
//TODO(yihaodeng): handle str type
|
||||||
|
{
|
||||||
|
const char *v = lua_tostring(lua, -1);
|
||||||
|
memcpy(interBuf, v, strlen(v));
|
||||||
|
sz = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LUA_TBOOLEAN:
|
||||||
|
{
|
||||||
|
double v = lua_tonumber(lua, -1);
|
||||||
|
memcpy(interBuf, (char *)&v, oBytes);
|
||||||
|
sz = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LUA_TNUMBER:
|
||||||
|
{
|
||||||
|
if (oType == TSDB_DATA_TYPE_FLOAT) {
|
||||||
|
float v = (float)lua_tonumber(lua, -1);
|
||||||
|
memcpy(interBuf, (char *)&v, oBytes);
|
||||||
|
sz = 1;
|
||||||
|
} else if (oType == TSDB_DATA_TYPE_DOUBLE) {
|
||||||
|
double v = (double)lua_tonumber(lua, -1);
|
||||||
|
memcpy(interBuf, (char *)&v, oBytes);
|
||||||
|
sz = 1;
|
||||||
|
} else if (oType == TSDB_DATA_TYPE_BIGINT) {
|
||||||
|
int64_t v = (int64_t)lua_tonumber(lua, -1);
|
||||||
|
memcpy(interBuf, (char *)&v, oBytes);
|
||||||
|
sz = 1;
|
||||||
|
} else if (oType <= TSDB_DATA_TYPE_INT) {
|
||||||
|
int32_t v = (int32_t)lua_tonumber(lua, -1);
|
||||||
|
memcpy(interBuf, (char *)&v, oBytes);
|
||||||
|
sz = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LUA_TTABLE:
|
||||||
|
{
|
||||||
|
lua_pushnil(lua);
|
||||||
|
int32_t offset = 0;
|
||||||
|
while(lua_next(lua, -2)) {
|
||||||
|
int32_t v = (int32_t)lua_tonumber(lua, -1);
|
||||||
|
memcpy(interBuf + offset, (char *)&v, oBytes);
|
||||||
|
offset += oBytes;
|
||||||
|
lua_pop(lua, 1);
|
||||||
|
sz += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
setNull(interBuf, oType, oBytes);
|
||||||
|
sz = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
lua_pop(lua,1); // pop ret value from script
|
||||||
|
*numOfOutput = sz;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
*Initialize the scripting environment.
|
||||||
|
*/
|
||||||
|
lua_State* createLuaEnv() {
|
||||||
|
lua_State *lua = lua_open();
|
||||||
|
luaLoadLibraries(lua);
|
||||||
|
luaRemoveUnsupportedFunctions(lua);
|
||||||
|
|
||||||
|
// register func in external lib
|
||||||
|
luaRegisterLibFunc(lua);
|
||||||
|
|
||||||
|
{
|
||||||
|
char *errh_func = "local dbg = debug\n"
|
||||||
|
"function __taos__err__handler(err)\n"
|
||||||
|
" local i = dbg.getinfo(2,'nSl')\n"
|
||||||
|
" if i and i.what == 'C' then\n"
|
||||||
|
" i = dbg.getinfo(3,'nSl')\n"
|
||||||
|
" end\n"
|
||||||
|
" if i then\n"
|
||||||
|
" return i.source .. ':' .. i.currentline .. ': ' .. err\n"
|
||||||
|
" else\n"
|
||||||
|
" return err\n"
|
||||||
|
" end\n"
|
||||||
|
"end\n";
|
||||||
|
luaL_loadbuffer(lua,errh_func,strlen(errh_func),"@err_handler_def");
|
||||||
|
lua_pcall(lua,0,0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return lua;
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroyLuaEnv(lua_State *lua) {
|
||||||
|
lua_close(lua);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t scriptEnvPoolInit() {
|
||||||
|
const int size = 10; // configure or not
|
||||||
|
pool = malloc(sizeof(ScriptEnvPool));
|
||||||
|
pthread_mutex_init(&pool->mutex, NULL);
|
||||||
|
|
||||||
|
pool->scriptEnvs = tdListNew(sizeof(ScriptEnv *));
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
ScriptEnv *env = malloc(sizeof(ScriptEnv));
|
||||||
|
env->funcId = taosHashInit(1024, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_ENTRY_LOCK);;
|
||||||
|
env->lua_state = createLuaEnv();
|
||||||
|
tdListAppend(pool->scriptEnvs, (void *)(&env));
|
||||||
|
}
|
||||||
|
pool->mSize = size;
|
||||||
|
pool->cSize = size;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void scriptEnvPoolCleanup() {
|
||||||
|
if (pool == NULL) return;
|
||||||
|
|
||||||
|
SListNode *pNode = NULL;
|
||||||
|
while ((pNode = tdListPopHead(pool->scriptEnvs)) != NULL) {
|
||||||
|
ScriptEnv *pEnv = NULL;
|
||||||
|
tdListNodeGetData(pool->scriptEnvs, pNode, (void *)(&pEnv));
|
||||||
|
destroyScriptEnv(pEnv);
|
||||||
|
listNodeFree(pNode);
|
||||||
|
}
|
||||||
|
tdListFree(pool->scriptEnvs);
|
||||||
|
pthread_mutex_destroy(&pool->mutex);
|
||||||
|
free(pool);
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroyScriptEnv(ScriptEnv *pEnv) {
|
||||||
|
destroyLuaEnv(pEnv->lua_state);
|
||||||
|
taosHashCleanup(pEnv->funcId);
|
||||||
|
free(pEnv);
|
||||||
|
}
|
||||||
|
|
||||||
|
ScriptEnv* getScriptEnvFromPool() {
|
||||||
|
ScriptEnv *pEnv = NULL;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&pool->mutex);
|
||||||
|
if (pool->cSize <= 0) {
|
||||||
|
pthread_mutex_unlock(&pool->mutex);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
SListNode *pNode = tdListPopHead(pool->scriptEnvs);
|
||||||
|
tdListNodeGetData(pool->scriptEnvs, pNode, (void *)(&pEnv));
|
||||||
|
listNodeFree(pNode);
|
||||||
|
|
||||||
|
pool->cSize--;
|
||||||
|
pthread_mutex_unlock(&pool->mutex);
|
||||||
|
return pEnv;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addScriptEnvToPool(ScriptEnv *pEnv) {
|
||||||
|
if (pEnv == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pthread_mutex_lock(&pool->mutex);
|
||||||
|
lua_settop(pEnv->lua_state, 0);
|
||||||
|
tdListAppend(pool->scriptEnvs, (void *)(&pEnv));
|
||||||
|
pool->cSize++;
|
||||||
|
pthread_mutex_unlock(&pool->mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hasBaseFuncDefinedInScript(lua_State *lua, const char *funcPrefix, int32_t len) {
|
||||||
|
bool ret = true;
|
||||||
|
char funcName[MAX_FUNC_NAME];
|
||||||
|
memcpy(funcName, funcPrefix, len);
|
||||||
|
|
||||||
|
const char *base[] = {"_init", "_add"};
|
||||||
|
for (int i = 0; (i < sizeof(base)/sizeof(base[0])) && (ret == true); i++) {
|
||||||
|
memcpy(funcName + len, base[i], strlen(base[i]));
|
||||||
|
memset(funcName + len + strlen(base[i]), 0, MAX_FUNC_NAME - len - strlen(base[i]));
|
||||||
|
lua_getglobal(lua, funcName);
|
||||||
|
ret = lua_isfunction(lua, -1); // exsit function or not
|
||||||
|
lua_pop(lua, 1);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isValidScript(char *script, int32_t len) {
|
||||||
|
ScriptEnv *pEnv = getScriptEnvFromPool(); //
|
||||||
|
if (pEnv == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
lua_State *lua = pEnv->lua_state;
|
||||||
|
if (len < strlen(script)) {
|
||||||
|
script[len] = 0;
|
||||||
|
}
|
||||||
|
if (luaL_dostring(lua, script)) {
|
||||||
|
lua_pop(lua, 1);
|
||||||
|
addScriptEnvToPool(pEnv);
|
||||||
|
qError("error at %s and %d", script, (int)(strlen(script)));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
lua_getglobal(lua, USER_FUNC_NAME);
|
||||||
|
const char *name = lua_tostring(lua, -1);
|
||||||
|
if (name == NULL || strlen(name) >= USER_FUNC_NAME_LIMIT) {
|
||||||
|
lua_pop(lua, 1);
|
||||||
|
addScriptEnvToPool(pEnv);
|
||||||
|
qError("error at %s name: %s, len = %d", script, name, (int)(strlen(name)));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool ret = hasBaseFuncDefinedInScript(lua, name, (int32_t)strlen(name));
|
||||||
|
lua_pop(lua, 1); // pop
|
||||||
|
addScriptEnvToPool(pEnv);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -28,6 +28,7 @@ SSqlInfo qSqlParse(const char *pStr) {
|
||||||
|
|
||||||
SSqlInfo sqlInfo = {0};
|
SSqlInfo sqlInfo = {0};
|
||||||
sqlInfo.valid = true;
|
sqlInfo.valid = true;
|
||||||
|
sqlInfo.funcs = taosArrayInit(4, sizeof(SStrToken));
|
||||||
|
|
||||||
int32_t i = 0;
|
int32_t i = 0;
|
||||||
while (1) {
|
while (1) {
|
||||||
|
|
@ -120,6 +121,19 @@ void tSqlExprListDestroy(SArray *pList) {
|
||||||
taosArrayDestroyEx(pList, freeExprElem);
|
taosArrayDestroyEx(pList, freeExprElem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SArray *tStrTokenAppend(SArray *pList, SStrToken *pToken) {
|
||||||
|
if (pList == NULL) {
|
||||||
|
pList = taosArrayInit(4, sizeof(tVariantListItem));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pToken) {
|
||||||
|
taosArrayPush(pList, pToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
return pList;
|
||||||
|
}
|
||||||
|
|
||||||
tSqlExpr *tSqlExprCreateIdValue(SStrToken *pToken, int32_t optrType) {
|
tSqlExpr *tSqlExprCreateIdValue(SStrToken *pToken, int32_t optrType) {
|
||||||
tSqlExpr *pSqlExpr = calloc(1, sizeof(tSqlExpr));
|
tSqlExpr *pSqlExpr = calloc(1, sizeof(tSqlExpr));
|
||||||
|
|
||||||
|
|
@ -146,7 +160,8 @@ tSqlExpr *tSqlExprCreateIdValue(SStrToken *pToken, int32_t optrType) {
|
||||||
pSqlExpr->type = SQL_NODE_VALUE;
|
pSqlExpr->type = SQL_NODE_VALUE;
|
||||||
pSqlExpr->flags |= 1 << EXPR_FLAG_NS_TIMESTAMP;
|
pSqlExpr->flags |= 1 << EXPR_FLAG_NS_TIMESTAMP;
|
||||||
} else if (optrType == TK_VARIABLE) {
|
} else if (optrType == TK_VARIABLE) {
|
||||||
// use nanosecond by default TODO set value after getting database precision
|
// use nanosecond by default
|
||||||
|
// TODO set value after getting database precision
|
||||||
int32_t ret = parseAbsoluteDuration(pToken->z, pToken->n, &pSqlExpr->value.i64, TSDB_TIME_PRECISION_NANO);
|
int32_t ret = parseAbsoluteDuration(pToken->z, pToken->n, &pSqlExpr->value.i64, TSDB_TIME_PRECISION_NANO);
|
||||||
if (ret != TSDB_CODE_SUCCESS) {
|
if (ret != TSDB_CODE_SUCCESS) {
|
||||||
terrno = TSDB_CODE_TSC_SQL_SYNTAX_ERROR;
|
terrno = TSDB_CODE_TSC_SQL_SYNTAX_ERROR;
|
||||||
|
|
@ -922,8 +937,8 @@ void* destroyCreateTableSql(SCreateTableSql* pCreate) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SqlInfoDestroy(SSqlInfo *pInfo) {
|
void SqlInfoDestroy(SSqlInfo *pInfo) {
|
||||||
if (pInfo == NULL) return;
|
if (pInfo == NULL) return;;
|
||||||
|
taosArrayDestroy(pInfo->funcs);
|
||||||
if (pInfo->type == TSDB_SQL_SELECT) {
|
if (pInfo->type == TSDB_SQL_SELECT) {
|
||||||
destroyAllSqlNode(pInfo->list);
|
destroyAllSqlNode(pInfo->list);
|
||||||
} else if (pInfo->type == TSDB_SQL_CREATE_TABLE) {
|
} else if (pInfo->type == TSDB_SQL_CREATE_TABLE) {
|
||||||
|
|
@ -1018,6 +1033,18 @@ void setDropDbTableInfo(SSqlInfo *pInfo, int32_t type, SStrToken* pToken, SStrTo
|
||||||
pInfo->pMiscInfo->tableType = tableType;
|
pInfo->pMiscInfo->tableType = tableType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setDropFuncInfo(SSqlInfo *pInfo, int32_t type, SStrToken* pToken) {
|
||||||
|
pInfo->type = type;
|
||||||
|
|
||||||
|
if (pInfo->pMiscInfo == NULL) {
|
||||||
|
pInfo->pMiscInfo = (SMiscInfo *)calloc(1, sizeof(SMiscInfo));
|
||||||
|
pInfo->pMiscInfo->a = taosArrayInit(4, sizeof(SStrToken));
|
||||||
|
}
|
||||||
|
|
||||||
|
taosArrayPush(pInfo->pMiscInfo->a, pToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void setShowOptions(SSqlInfo *pInfo, int32_t type, SStrToken* prefix, SStrToken* pPatterns) {
|
void setShowOptions(SSqlInfo *pInfo, int32_t type, SStrToken* prefix, SStrToken* pPatterns) {
|
||||||
if (pInfo->pMiscInfo == NULL) {
|
if (pInfo->pMiscInfo == NULL) {
|
||||||
pInfo->pMiscInfo = calloc(1, sizeof(SMiscInfo));
|
pInfo->pMiscInfo = calloc(1, sizeof(SMiscInfo));
|
||||||
|
|
@ -1052,6 +1079,24 @@ void setCreateDbInfo(SSqlInfo *pInfo, int32_t type, SStrToken *pToken, SCreateDb
|
||||||
pInfo->pMiscInfo->dbOpt.ignoreExists = pIgExists->n; // sql.y has: ifnotexists(X) ::= IF NOT EXISTS. {X.n = 1;}
|
pInfo->pMiscInfo->dbOpt.ignoreExists = pIgExists->n; // sql.y has: ifnotexists(X) ::= IF NOT EXISTS. {X.n = 1;}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setCreateFuncInfo(SSqlInfo *pInfo, int32_t type, SStrToken *pName, SStrToken *pPath, TAOS_FIELD *output, SStrToken* bufSize, int32_t funcType) {
|
||||||
|
pInfo->type = type;
|
||||||
|
if (pInfo->pMiscInfo == NULL) {
|
||||||
|
pInfo->pMiscInfo = calloc(1, sizeof(SMiscInfo));
|
||||||
|
}
|
||||||
|
|
||||||
|
pInfo->pMiscInfo->funcOpt.name = *pName;
|
||||||
|
pInfo->pMiscInfo->funcOpt.path = *pPath;
|
||||||
|
pInfo->pMiscInfo->funcOpt.output = *output;
|
||||||
|
pInfo->pMiscInfo->funcOpt.type = funcType;
|
||||||
|
if (bufSize->n > 0) {
|
||||||
|
pInfo->pMiscInfo->funcOpt.bufSize = strtol(bufSize->z, NULL, 10);
|
||||||
|
} else {
|
||||||
|
pInfo->pMiscInfo->funcOpt.bufSize = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void setCreateAcctSql(SSqlInfo *pInfo, int32_t type, SStrToken *pName, SStrToken *pPwd, SCreateAcctInfo *pAcctInfo) {
|
void setCreateAcctSql(SSqlInfo *pInfo, int32_t type, SStrToken *pName, SStrToken *pPwd, SCreateAcctInfo *pAcctInfo) {
|
||||||
pInfo->type = type;
|
pInfo->type = type;
|
||||||
if (pInfo->pMiscInfo == NULL) {
|
if (pInfo->pMiscInfo == NULL) {
|
||||||
|
|
|
||||||
|
|
@ -267,6 +267,10 @@ static void writeDataToDisk(STSBuf* pTSBuf) {
|
||||||
if (pBlock->tag.nType == TSDB_DATA_TYPE_BINARY || pBlock->tag.nType == TSDB_DATA_TYPE_NCHAR) {
|
if (pBlock->tag.nType == TSDB_DATA_TYPE_BINARY || pBlock->tag.nType == TSDB_DATA_TYPE_NCHAR) {
|
||||||
metaLen += (int32_t)fwrite(&pBlock->tag.nLen, 1, sizeof(pBlock->tag.nLen), pTSBuf->f);
|
metaLen += (int32_t)fwrite(&pBlock->tag.nLen, 1, sizeof(pBlock->tag.nLen), pTSBuf->f);
|
||||||
metaLen += (int32_t)fwrite(pBlock->tag.pz, 1, (size_t)pBlock->tag.nLen, pTSBuf->f);
|
metaLen += (int32_t)fwrite(pBlock->tag.pz, 1, (size_t)pBlock->tag.nLen, pTSBuf->f);
|
||||||
|
} else if (pBlock->tag.nType == TSDB_DATA_TYPE_FLOAT) {
|
||||||
|
metaLen += (int32_t)fwrite(&pBlock->tag.nLen, 1, sizeof(pBlock->tag.nLen), pTSBuf->f);
|
||||||
|
float tfloat = (float)pBlock->tag.dKey;
|
||||||
|
metaLen += (int32_t)fwrite(&tfloat, 1, (size_t) pBlock->tag.nLen, pTSBuf->f);
|
||||||
} else if (pBlock->tag.nType != TSDB_DATA_TYPE_NULL) {
|
} else if (pBlock->tag.nType != TSDB_DATA_TYPE_NULL) {
|
||||||
metaLen += (int32_t)fwrite(&pBlock->tag.nLen, 1, sizeof(pBlock->tag.nLen), pTSBuf->f);
|
metaLen += (int32_t)fwrite(&pBlock->tag.nLen, 1, sizeof(pBlock->tag.nLen), pTSBuf->f);
|
||||||
metaLen += (int32_t)fwrite(&pBlock->tag.i64, 1, (size_t) pBlock->tag.nLen, pTSBuf->f);
|
metaLen += (int32_t)fwrite(&pBlock->tag.i64, 1, (size_t) pBlock->tag.nLen, pTSBuf->f);
|
||||||
|
|
@ -351,6 +355,11 @@ STSBlock* readDataFromDisk(STSBuf* pTSBuf, int32_t order, bool decomp) {
|
||||||
|
|
||||||
sz = fread(pBlock->tag.pz, (size_t)pBlock->tag.nLen, 1, pTSBuf->f);
|
sz = fread(pBlock->tag.pz, (size_t)pBlock->tag.nLen, 1, pTSBuf->f);
|
||||||
UNUSED(sz);
|
UNUSED(sz);
|
||||||
|
} else if (pBlock->tag.nType == TSDB_DATA_TYPE_FLOAT) {
|
||||||
|
float tfloat = 0;
|
||||||
|
sz = fread(&tfloat, (size_t) pBlock->tag.nLen, 1, pTSBuf->f);
|
||||||
|
pBlock->tag.dKey = (double)tfloat;
|
||||||
|
UNUSED(sz);
|
||||||
} else if (pBlock->tag.nType != TSDB_DATA_TYPE_NULL) { //TODO check the return value
|
} else if (pBlock->tag.nType != TSDB_DATA_TYPE_NULL) { //TODO check the return value
|
||||||
sz = fread(&pBlock->tag.i64, (size_t) pBlock->tag.nLen, 1, pTSBuf->f);
|
sz = fread(&pBlock->tag.i64, (size_t) pBlock->tag.nLen, 1, pTSBuf->f);
|
||||||
UNUSED(sz);
|
UNUSED(sz);
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ void freeParam(SQueryParam *param) {
|
||||||
tfree(param->prevResult);
|
tfree(param->prevResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t qCreateQueryInfo(void* tsdb, int32_t vgId, SQueryTableMsg* pQueryMsg, qinfo_t* pQInfo, uint64_t *qId) {
|
int32_t qCreateQueryInfo(void* tsdb, int32_t vgId, SQueryTableMsg* pQueryMsg, qinfo_t* pQInfo, uint64_t qId) {
|
||||||
assert(pQueryMsg != NULL && tsdb != NULL);
|
assert(pQueryMsg != NULL && tsdb != NULL);
|
||||||
|
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
|
@ -93,12 +93,12 @@ int32_t qCreateQueryInfo(void* tsdb, int32_t vgId, SQueryTableMsg* pQueryMsg, qi
|
||||||
|
|
||||||
SQueriedTableInfo info = { .numOfTags = pQueryMsg->numOfTags, .numOfCols = pQueryMsg->numOfCols, .colList = pQueryMsg->tableCols};
|
SQueriedTableInfo info = { .numOfTags = pQueryMsg->numOfTags, .numOfCols = pQueryMsg->numOfCols, .colList = pQueryMsg->tableCols};
|
||||||
if ((code = createQueryFunc(&info, pQueryMsg->numOfOutput, ¶m.pExprs, param.pExpr, param.pTagColumnInfo,
|
if ((code = createQueryFunc(&info, pQueryMsg->numOfOutput, ¶m.pExprs, param.pExpr, param.pTagColumnInfo,
|
||||||
pQueryMsg->queryType, pQueryMsg)) != TSDB_CODE_SUCCESS) {
|
pQueryMsg->queryType, pQueryMsg, param.pUdfInfo)) != TSDB_CODE_SUCCESS) {
|
||||||
goto _over;
|
goto _over;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (param.pSecExpr != NULL) {
|
if (param.pSecExpr != NULL) {
|
||||||
if ((code = createIndirectQueryFuncExprFromMsg(pQueryMsg, pQueryMsg->secondStageOutput, ¶m.pSecExprs, param.pSecExpr, param.pExprs)) != TSDB_CODE_SUCCESS) {
|
if ((code = createIndirectQueryFuncExprFromMsg(pQueryMsg, pQueryMsg->secondStageOutput, ¶m.pSecExprs, param.pSecExpr, param.pExprs, param.pUdfInfo)) != TSDB_CODE_SUCCESS) {
|
||||||
goto _over;
|
goto _over;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -162,18 +162,14 @@ int32_t qCreateQueryInfo(void* tsdb, int32_t vgId, SQueryTableMsg* pQueryMsg, qi
|
||||||
|
|
||||||
assert(pQueryMsg->stableQuery == isSTableQuery);
|
assert(pQueryMsg->stableQuery == isSTableQuery);
|
||||||
(*pQInfo) = createQInfoImpl(pQueryMsg, param.pGroupbyExpr, param.pExprs, param.pSecExprs, &tableGroupInfo,
|
(*pQInfo) = createQInfoImpl(pQueryMsg, param.pGroupbyExpr, param.pExprs, param.pSecExprs, &tableGroupInfo,
|
||||||
param.pTagColumnInfo, vgId, param.sql, *qId);
|
param.pTagColumnInfo, vgId, param.sql, qId, param.pUdfInfo);
|
||||||
|
|
||||||
param.sql = NULL;
|
param.sql = NULL;
|
||||||
param.pExprs = NULL;
|
param.pExprs = NULL;
|
||||||
param.pSecExprs = NULL;
|
param.pSecExprs = NULL;
|
||||||
param.pGroupbyExpr = NULL;
|
param.pGroupbyExpr = NULL;
|
||||||
param.pTagColumnInfo = NULL;
|
param.pTagColumnInfo = NULL;
|
||||||
|
param.pUdfInfo = NULL;
|
||||||
if ((*pQInfo) == NULL) {
|
|
||||||
code = TSDB_CODE_QRY_OUT_OF_MEMORY;
|
|
||||||
goto _over;
|
|
||||||
}
|
|
||||||
|
|
||||||
code = initQInfo(&pQueryMsg->tsBuf, tsdb, NULL, *pQInfo, ¶m, (char*)pQueryMsg, pQueryMsg->prevResultLen, NULL);
|
code = initQInfo(&pQueryMsg->tsBuf, tsdb, NULL, *pQInfo, ¶m, (char*)pQueryMsg, pQueryMsg->prevResultLen, NULL);
|
||||||
|
|
||||||
|
|
@ -182,6 +178,8 @@ int32_t qCreateQueryInfo(void* tsdb, int32_t vgId, SQueryTableMsg* pQueryMsg, qi
|
||||||
taosArrayDestroy(param.pGroupbyExpr->columnInfo);
|
taosArrayDestroy(param.pGroupbyExpr->columnInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
destroyUdfInfo(param.pUdfInfo);
|
||||||
|
|
||||||
taosArrayDestroy(param.pTableIdList);
|
taosArrayDestroy(param.pTableIdList);
|
||||||
param.pTableIdList = NULL;
|
param.pTableIdList = NULL;
|
||||||
|
|
||||||
|
|
|
||||||
3304
src/query/src/sql.c
3304
src/query/src/sql.c
File diff suppressed because it is too large
Load Diff
|
|
@ -71,27 +71,27 @@ int tsdbLoadDataFromCache(STable* pTable, SSkipListIterator* pIter, TSKEY maxK
|
||||||
TKEY* filterKeys, int nFilterKeys, bool keepDup, SMergeInfo* pMergeInfo);
|
TKEY* filterKeys, int nFilterKeys, bool keepDup, SMergeInfo* pMergeInfo);
|
||||||
void* tsdbCommitData(STsdbRepo* pRepo);
|
void* tsdbCommitData(STsdbRepo* pRepo);
|
||||||
|
|
||||||
static FORCE_INLINE SDataRow tsdbNextIterRow(SSkipListIterator* pIter) {
|
static FORCE_INLINE SMemRow tsdbNextIterRow(SSkipListIterator* pIter) {
|
||||||
if (pIter == NULL) return NULL;
|
if (pIter == NULL) return NULL;
|
||||||
|
|
||||||
SSkipListNode* node = tSkipListIterGet(pIter);
|
SSkipListNode* node = tSkipListIterGet(pIter);
|
||||||
if (node == NULL) return NULL;
|
if (node == NULL) return NULL;
|
||||||
|
|
||||||
return (SDataRow)SL_GET_NODE_DATA(node);
|
return (SMemRow)SL_GET_NODE_DATA(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
static FORCE_INLINE TSKEY tsdbNextIterKey(SSkipListIterator* pIter) {
|
static FORCE_INLINE TSKEY tsdbNextIterKey(SSkipListIterator* pIter) {
|
||||||
SDataRow row = tsdbNextIterRow(pIter);
|
SMemRow row = tsdbNextIterRow(pIter);
|
||||||
if (row == NULL) return TSDB_DATA_TIMESTAMP_NULL;
|
if (row == NULL) return TSDB_DATA_TIMESTAMP_NULL;
|
||||||
|
|
||||||
return dataRowKey(row);
|
return memRowKey(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
static FORCE_INLINE TKEY tsdbNextIterTKey(SSkipListIterator* pIter) {
|
static FORCE_INLINE TKEY tsdbNextIterTKey(SSkipListIterator* pIter) {
|
||||||
SDataRow row = tsdbNextIterRow(pIter);
|
SMemRow row = tsdbNextIterRow(pIter);
|
||||||
if (row == NULL) return TKEY_NULL;
|
if (row == NULL) return TKEY_NULL;
|
||||||
|
|
||||||
return dataRowTKey(row);
|
return memRowTKey(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* _TD_TSDB_MEMTABLE_H_ */
|
#endif /* _TD_TSDB_MEMTABLE_H_ */
|
||||||
|
|
@ -32,7 +32,7 @@ typedef struct STable {
|
||||||
void* eventHandler; // TODO
|
void* eventHandler; // TODO
|
||||||
void* streamHandler; // TODO
|
void* streamHandler; // TODO
|
||||||
TSKEY lastKey;
|
TSKEY lastKey;
|
||||||
SDataRow lastRow;
|
SMemRow lastRow;
|
||||||
char* sql;
|
char* sql;
|
||||||
void* cqhandle;
|
void* cqhandle;
|
||||||
SRWLatch latch; // TODO: implementa latch functions
|
SRWLatch latch; // TODO: implementa latch functions
|
||||||
|
|
@ -148,7 +148,7 @@ static FORCE_INLINE STSchema *tsdbGetTableTagSchema(STable *pTable) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static FORCE_INLINE TSKEY tsdbGetTableLastKeyImpl(STable* pTable) {
|
static FORCE_INLINE TSKEY tsdbGetTableLastKeyImpl(STable* pTable) {
|
||||||
ASSERT(pTable->lastRow == NULL || pTable->lastKey == dataRowKey(pTable->lastRow));
|
ASSERT((pTable->lastRow == NULL) || (pTable->lastKey == memRowKey(pTable->lastRow)));
|
||||||
return pTable->lastKey;
|
return pTable->lastKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -920,7 +920,8 @@ int tsdbWriteBlockImpl(STsdbRepo *pRepo, STable *pTable, SDFile *pDFile, SDataCo
|
||||||
SDataCol * pDataCol = pDataCols->cols + ncol;
|
SDataCol * pDataCol = pDataCols->cols + ncol;
|
||||||
SBlockCol *pBlockCol = pBlockData->cols + nColsNotAllNull;
|
SBlockCol *pBlockCol = pBlockData->cols + nColsNotAllNull;
|
||||||
|
|
||||||
if (isNEleNull(pDataCol, rowsToWrite)) { // all data to commit are NULL, just ignore it
|
// if (isNEleNull(pDataCol, rowsToWrite)) { // all data to commit are NULL, just ignore it
|
||||||
|
if (isAllRowsNull(pDataCol)) { // all data to commit are NULL, just ignore it
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1264,12 +1265,12 @@ static void tsdbLoadAndMergeFromCache(SDataCols *pDataCols, int *iter, SCommitIt
|
||||||
while (true) {
|
while (true) {
|
||||||
key1 = (*iter >= pDataCols->numOfRows) ? INT64_MAX : dataColsKeyAt(pDataCols, *iter);
|
key1 = (*iter >= pDataCols->numOfRows) ? INT64_MAX : dataColsKeyAt(pDataCols, *iter);
|
||||||
bool isRowDel = false;
|
bool isRowDel = false;
|
||||||
SDataRow row = tsdbNextIterRow(pCommitIter->pIter);
|
SMemRow row = tsdbNextIterRow(pCommitIter->pIter);
|
||||||
if (row == NULL || dataRowKey(row) > maxKey) {
|
if (row == NULL || memRowKey(row) > maxKey) {
|
||||||
key2 = INT64_MAX;
|
key2 = INT64_MAX;
|
||||||
} else {
|
} else {
|
||||||
key2 = dataRowKey(row);
|
key2 = memRowKey(row);
|
||||||
isRowDel = dataRowDeleted(row);
|
isRowDel = memRowDeleted(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key1 == INT64_MAX && key2 == INT64_MAX) break;
|
if (key1 == INT64_MAX && key2 == INT64_MAX) break;
|
||||||
|
|
@ -1284,24 +1285,24 @@ static void tsdbLoadAndMergeFromCache(SDataCols *pDataCols, int *iter, SCommitIt
|
||||||
(*iter)++;
|
(*iter)++;
|
||||||
} else if (key1 > key2) {
|
} else if (key1 > key2) {
|
||||||
if (!isRowDel) {
|
if (!isRowDel) {
|
||||||
if (pSchema == NULL || schemaVersion(pSchema) != dataRowVersion(row)) {
|
if (pSchema == NULL || schemaVersion(pSchema) != memRowVersion(row)) {
|
||||||
pSchema = tsdbGetTableSchemaImpl(pCommitIter->pTable, false, false, dataRowVersion(row));
|
pSchema = tsdbGetTableSchemaImpl(pCommitIter->pTable, false, false, memRowVersion(row));
|
||||||
ASSERT(pSchema != NULL);
|
ASSERT(pSchema != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
tdAppendDataRowToDataCol(row, pSchema, pTarget);
|
tdAppendMemRowToDataCol(row, pSchema, pTarget);
|
||||||
}
|
}
|
||||||
|
|
||||||
tSkipListIterNext(pCommitIter->pIter);
|
tSkipListIterNext(pCommitIter->pIter);
|
||||||
} else {
|
} else {
|
||||||
if (update) {
|
if (update) {
|
||||||
if (!isRowDel) {
|
if (!isRowDel) {
|
||||||
if (pSchema == NULL || schemaVersion(pSchema) != dataRowVersion(row)) {
|
if (pSchema == NULL || schemaVersion(pSchema) != memRowVersion(row)) {
|
||||||
pSchema = tsdbGetTableSchemaImpl(pCommitIter->pTable, false, false, dataRowVersion(row));
|
pSchema = tsdbGetTableSchemaImpl(pCommitIter->pTable, false, false, memRowVersion(row));
|
||||||
ASSERT(pSchema != NULL);
|
ASSERT(pSchema != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
tdAppendDataRowToDataCol(row, pSchema, pTarget);
|
tdAppendMemRowToDataCol(row, pSchema, pTarget);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ASSERT(!isRowDel);
|
ASSERT(!isRowDel);
|
||||||
|
|
|
||||||
|
|
@ -641,7 +641,7 @@ static int tsdbRestoreLastColumns(STsdbRepo *pRepo, STable *pTable, SReadH* pRea
|
||||||
int numColumns;
|
int numColumns;
|
||||||
int32_t blockIdx;
|
int32_t blockIdx;
|
||||||
SDataStatis* pBlockStatis = NULL;
|
SDataStatis* pBlockStatis = NULL;
|
||||||
SDataRow row = NULL;
|
SMemRow row = NULL;
|
||||||
// restore last column data with last schema
|
// restore last column data with last schema
|
||||||
|
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
@ -657,13 +657,15 @@ static int tsdbRestoreLastColumns(STsdbRepo *pRepo, STable *pTable, SReadH* pRea
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
row = taosTMalloc(dataRowMaxBytesFromSchema(pSchema));
|
row = taosTMalloc(memRowMaxBytesFromSchema(pSchema));
|
||||||
if (row == NULL) {
|
if (row == NULL) {
|
||||||
terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
|
terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
|
||||||
err = -1;
|
err = -1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
tdInitDataRow(row, pSchema);
|
|
||||||
|
memRowSetType(row, SMEM_ROW_DATA);
|
||||||
|
tdInitDataRow(memRowDataBody(row), pSchema);
|
||||||
|
|
||||||
// first load block index info
|
// first load block index info
|
||||||
if (tsdbLoadBlockInfo(pReadh, NULL) < 0) {
|
if (tsdbLoadBlockInfo(pReadh, NULL) < 0) {
|
||||||
|
|
@ -720,9 +722,9 @@ static int tsdbRestoreLastColumns(STsdbRepo *pRepo, STable *pTable, SReadH* pRea
|
||||||
// OK,let's load row from backward to get not-null column
|
// OK,let's load row from backward to get not-null column
|
||||||
for (int32_t rowId = pBlock->numOfRows - 1; rowId >= 0; rowId--) {
|
for (int32_t rowId = pBlock->numOfRows - 1; rowId >= 0; rowId--) {
|
||||||
SDataCol *pDataCol = pReadh->pDCols[0]->cols + i;
|
SDataCol *pDataCol = pReadh->pDCols[0]->cols + i;
|
||||||
tdAppendColVal(row, tdGetColDataOfRow(pDataCol, rowId), pCol->type, pCol->bytes, pCol->offset);
|
tdAppendColVal(memRowDataBody(row), tdGetColDataOfRow(pDataCol, rowId), pCol->type, pCol->offset);
|
||||||
//SDataCol *pDataCol = readh.pDCols[0]->cols + j;
|
//SDataCol *pDataCol = readh.pDCols[0]->cols + j;
|
||||||
void* value = tdGetRowDataOfCol(row, (int8_t)pCol->type, TD_DATA_ROW_HEAD_SIZE + pCol->offset);
|
void *value = tdGetRowDataOfCol(memRowDataBody(row), (int8_t)pCol->type, TD_DATA_ROW_HEAD_SIZE + pCol->offset);
|
||||||
if (isNull(value, pCol->type)) {
|
if (isNull(value, pCol->type)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -742,8 +744,8 @@ static int tsdbRestoreLastColumns(STsdbRepo *pRepo, STable *pTable, SReadH* pRea
|
||||||
// save row ts(in column 0)
|
// save row ts(in column 0)
|
||||||
pDataCol = pReadh->pDCols[0]->cols + 0;
|
pDataCol = pReadh->pDCols[0]->cols + 0;
|
||||||
pCol = schemaColAt(pSchema, 0);
|
pCol = schemaColAt(pSchema, 0);
|
||||||
tdAppendColVal(row, tdGetColDataOfRow(pDataCol, rowId), pCol->type, pCol->bytes, pCol->offset);
|
tdAppendColVal(memRowDataBody(row), tdGetColDataOfRow(pDataCol, rowId), pCol->type, pCol->offset);
|
||||||
pLastCol->ts = dataRowKey(row);
|
pLastCol->ts = memRowKey(row);
|
||||||
|
|
||||||
pTable->restoreColumnNum += 1;
|
pTable->restoreColumnNum += 1;
|
||||||
|
|
||||||
|
|
@ -779,17 +781,17 @@ static int tsdbRestoreLastRow(STsdbRepo *pRepo, STable *pTable, SReadH* pReadh,
|
||||||
// Get the data in row
|
// Get the data in row
|
||||||
|
|
||||||
STSchema *pSchema = tsdbGetTableSchema(pTable);
|
STSchema *pSchema = tsdbGetTableSchema(pTable);
|
||||||
pTable->lastRow = taosTMalloc(dataRowMaxBytesFromSchema(pSchema));
|
pTable->lastRow = taosTMalloc(memRowMaxBytesFromSchema(pSchema));
|
||||||
if (pTable->lastRow == NULL) {
|
if (pTable->lastRow == NULL) {
|
||||||
terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
|
terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
memRowSetType(pTable->lastRow, SMEM_ROW_DATA);
|
||||||
tdInitDataRow(pTable->lastRow, pSchema);
|
tdInitDataRow(memRowDataBody(pTable->lastRow), pSchema);
|
||||||
for (int icol = 0; icol < schemaNCols(pSchema); icol++) {
|
for (int icol = 0; icol < schemaNCols(pSchema); icol++) {
|
||||||
STColumn *pCol = schemaColAt(pSchema, icol);
|
STColumn *pCol = schemaColAt(pSchema, icol);
|
||||||
SDataCol *pDataCol = pReadh->pDCols[0]->cols + icol;
|
SDataCol *pDataCol = pReadh->pDCols[0]->cols + icol;
|
||||||
tdAppendColVal(pTable->lastRow, tdGetColDataOfRow(pDataCol, pBlock->numOfRows - 1), pCol->type, pCol->bytes,
|
tdAppendColVal(memRowDataBody(pTable->lastRow), tdGetColDataOfRow(pDataCol, pBlock->numOfRows - 1), pCol->type,
|
||||||
pCol->offset);
|
pCol->offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int32_t totalLen;
|
int32_t totalLen;
|
||||||
int32_t len;
|
int32_t len;
|
||||||
SDataRow row;
|
SMemRow row;
|
||||||
} SSubmitBlkIter;
|
} SSubmitBlkIter;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
@ -36,20 +36,19 @@ static STableData *tsdbNewTableData(STsdbCfg *pCfg, STable *pTable);
|
||||||
static void tsdbFreeTableData(STableData *pTableData);
|
static void tsdbFreeTableData(STableData *pTableData);
|
||||||
static char * tsdbGetTsTupleKey(const void *data);
|
static char * tsdbGetTsTupleKey(const void *data);
|
||||||
static int tsdbAdjustMemMaxTables(SMemTable *pMemTable, int maxTables);
|
static int tsdbAdjustMemMaxTables(SMemTable *pMemTable, int maxTables);
|
||||||
static int tsdbAppendTableRowToCols(STable *pTable, SDataCols *pCols, STSchema **ppSchema, SDataRow row);
|
static int tsdbAppendTableRowToCols(STable *pTable, SDataCols *pCols, STSchema **ppSchema, SMemRow row);
|
||||||
static int tsdbInitSubmitBlkIter(SSubmitBlk *pBlock, SSubmitBlkIter *pIter);
|
static int tsdbInitSubmitBlkIter(SSubmitBlk *pBlock, SSubmitBlkIter *pIter);
|
||||||
static SDataRow tsdbGetSubmitBlkNext(SSubmitBlkIter *pIter);
|
static SMemRow tsdbGetSubmitBlkNext(SSubmitBlkIter *pIter);
|
||||||
static int tsdbScanAndConvertSubmitMsg(STsdbRepo *pRepo, SSubmitMsg *pMsg);
|
static int tsdbScanAndConvertSubmitMsg(STsdbRepo *pRepo, SSubmitMsg *pMsg);
|
||||||
static int tsdbInsertDataToTable(STsdbRepo *pRepo, SSubmitBlk *pBlock, int32_t *affectedrows);
|
static int tsdbInsertDataToTable(STsdbRepo *pRepo, SSubmitBlk *pBlock, int32_t *affectedrows);
|
||||||
static int tsdbCopyRowToMem(STsdbRepo *pRepo, SDataRow row, STable *pTable, void **ppRow);
|
static int tsdbCopyRowToMem(STsdbRepo *pRepo, SMemRow row, STable *pTable, void **ppRow);
|
||||||
static int tsdbInitSubmitMsgIter(SSubmitMsg *pMsg, SSubmitMsgIter *pIter);
|
static int tsdbInitSubmitMsgIter(SSubmitMsg *pMsg, SSubmitMsgIter *pIter);
|
||||||
static int tsdbGetSubmitMsgNext(SSubmitMsgIter *pIter, SSubmitBlk **pPBlock);
|
static int tsdbGetSubmitMsgNext(SSubmitMsgIter *pIter, SSubmitBlk **pPBlock);
|
||||||
static int tsdbCheckTableSchema(STsdbRepo *pRepo, SSubmitBlk *pBlock, STable *pTable);
|
static int tsdbCheckTableSchema(STsdbRepo *pRepo, SSubmitBlk *pBlock, STable *pTable);
|
||||||
static int tsdbInsertDataToTableImpl(STsdbRepo *pRepo, STable *pTable, void **rows, int rowCounter);
|
static int tsdbInsertDataToTableImpl(STsdbRepo *pRepo, STable *pTable, void **rows, int rowCounter);
|
||||||
static void tsdbFreeRows(STsdbRepo *pRepo, void **rows, int rowCounter);
|
static void tsdbFreeRows(STsdbRepo *pRepo, void **rows, int rowCounter);
|
||||||
static int tsdbUpdateTableLatestInfo(STsdbRepo *pRepo, STable *pTable, SDataRow row);
|
static int tsdbUpdateTableLatestInfo(STsdbRepo *pRepo, STable *pTable, SMemRow row);
|
||||||
|
static FORCE_INLINE int tsdbCheckRowRange(STsdbRepo *pRepo, STable *pTable, SMemRow row, TSKEY minKey, TSKEY maxKey,
|
||||||
static FORCE_INLINE int tsdbCheckRowRange(STsdbRepo *pRepo, STable *pTable, SDataRow row, TSKEY minKey, TSKEY maxKey,
|
|
||||||
TSKEY now);
|
TSKEY now);
|
||||||
|
|
||||||
int32_t tsdbInsertData(STsdbRepo *repo, SSubmitMsg *pMsg, SShellSubmitRspMsg *pRsp) {
|
int32_t tsdbInsertData(STsdbRepo *repo, SSubmitMsg *pMsg, SShellSubmitRspMsg *pRsp) {
|
||||||
|
|
@ -354,7 +353,7 @@ int tsdbLoadDataFromCache(STable *pTable, SSkipListIterator *pIter, TSKEY maxKey
|
||||||
TSKEY fKey = 0;
|
TSKEY fKey = 0;
|
||||||
bool isRowDel = false;
|
bool isRowDel = false;
|
||||||
int filterIter = 0;
|
int filterIter = 0;
|
||||||
SDataRow row = NULL;
|
SMemRow row = NULL;
|
||||||
SMergeInfo mInfo;
|
SMergeInfo mInfo;
|
||||||
|
|
||||||
if (pMergeInfo == NULL) pMergeInfo = &mInfo;
|
if (pMergeInfo == NULL) pMergeInfo = &mInfo;
|
||||||
|
|
@ -365,12 +364,12 @@ int tsdbLoadDataFromCache(STable *pTable, SSkipListIterator *pIter, TSKEY maxKey
|
||||||
if (pCols) tdResetDataCols(pCols);
|
if (pCols) tdResetDataCols(pCols);
|
||||||
|
|
||||||
row = tsdbNextIterRow(pIter);
|
row = tsdbNextIterRow(pIter);
|
||||||
if (row == NULL || dataRowKey(row) > maxKey) {
|
if (row == NULL || memRowKey(row) > maxKey) {
|
||||||
rowKey = INT64_MAX;
|
rowKey = INT64_MAX;
|
||||||
isRowDel = false;
|
isRowDel = false;
|
||||||
} else {
|
} else {
|
||||||
rowKey = dataRowKey(row);
|
rowKey = memRowKey(row);
|
||||||
isRowDel = dataRowDeleted(row);
|
isRowDel = memRowDeleted(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filterIter >= nFilterKeys) {
|
if (filterIter >= nFilterKeys) {
|
||||||
|
|
@ -407,12 +406,12 @@ int tsdbLoadDataFromCache(STable *pTable, SSkipListIterator *pIter, TSKEY maxKey
|
||||||
|
|
||||||
tSkipListIterNext(pIter);
|
tSkipListIterNext(pIter);
|
||||||
row = tsdbNextIterRow(pIter);
|
row = tsdbNextIterRow(pIter);
|
||||||
if (row == NULL || dataRowKey(row) > maxKey) {
|
if (row == NULL || memRowKey(row) > maxKey) {
|
||||||
rowKey = INT64_MAX;
|
rowKey = INT64_MAX;
|
||||||
isRowDel = false;
|
isRowDel = false;
|
||||||
} else {
|
} else {
|
||||||
rowKey = dataRowKey(row);
|
rowKey = memRowKey(row);
|
||||||
isRowDel = dataRowDeleted(row);
|
isRowDel = memRowDeleted(row);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (isRowDel) {
|
if (isRowDel) {
|
||||||
|
|
@ -437,12 +436,12 @@ int tsdbLoadDataFromCache(STable *pTable, SSkipListIterator *pIter, TSKEY maxKey
|
||||||
|
|
||||||
tSkipListIterNext(pIter);
|
tSkipListIterNext(pIter);
|
||||||
row = tsdbNextIterRow(pIter);
|
row = tsdbNextIterRow(pIter);
|
||||||
if (row == NULL || dataRowKey(row) > maxKey) {
|
if (row == NULL || memRowKey(row) > maxKey) {
|
||||||
rowKey = INT64_MAX;
|
rowKey = INT64_MAX;
|
||||||
isRowDel = false;
|
isRowDel = false;
|
||||||
} else {
|
} else {
|
||||||
rowKey = dataRowKey(row);
|
rowKey = memRowKey(row);
|
||||||
isRowDel = dataRowDeleted(row);
|
isRowDel = memRowDeleted(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
filterIter++;
|
filterIter++;
|
||||||
|
|
@ -548,7 +547,7 @@ static void tsdbFreeTableData(STableData *pTableData) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *tsdbGetTsTupleKey(const void *data) { return dataRowTuple((SDataRow)data); }
|
static char *tsdbGetTsTupleKey(const void *data) { return memRowTuple((SMemRow)data); }
|
||||||
|
|
||||||
static int tsdbAdjustMemMaxTables(SMemTable *pMemTable, int maxTables) {
|
static int tsdbAdjustMemMaxTables(SMemTable *pMemTable, int maxTables) {
|
||||||
ASSERT(pMemTable->maxTables < maxTables);
|
ASSERT(pMemTable->maxTables < maxTables);
|
||||||
|
|
@ -572,17 +571,17 @@ static int tsdbAdjustMemMaxTables(SMemTable *pMemTable, int maxTables) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tsdbAppendTableRowToCols(STable *pTable, SDataCols *pCols, STSchema **ppSchema, SDataRow row) {
|
static int tsdbAppendTableRowToCols(STable *pTable, SDataCols *pCols, STSchema **ppSchema, SMemRow row) {
|
||||||
if (pCols) {
|
if (pCols) {
|
||||||
if (*ppSchema == NULL || schemaVersion(*ppSchema) != dataRowVersion(row)) {
|
if (*ppSchema == NULL || schemaVersion(*ppSchema) != memRowVersion(row)) {
|
||||||
*ppSchema = tsdbGetTableSchemaImpl(pTable, false, false, dataRowVersion(row));
|
*ppSchema = tsdbGetTableSchemaImpl(pTable, false, false, memRowVersion(row));
|
||||||
if (*ppSchema == NULL) {
|
if (*ppSchema == NULL) {
|
||||||
ASSERT(false);
|
ASSERT(false);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tdAppendDataRowToDataCol(row, *ppSchema, pCols);
|
tdAppendMemRowToDataCol(row, *ppSchema, pCols);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -592,31 +591,32 @@ static int tsdbInitSubmitBlkIter(SSubmitBlk *pBlock, SSubmitBlkIter *pIter) {
|
||||||
if (pBlock->dataLen <= 0) return -1;
|
if (pBlock->dataLen <= 0) return -1;
|
||||||
pIter->totalLen = pBlock->dataLen;
|
pIter->totalLen = pBlock->dataLen;
|
||||||
pIter->len = 0;
|
pIter->len = 0;
|
||||||
pIter->row = (SDataRow)(pBlock->data+pBlock->schemaLen);
|
pIter->row = (SMemRow)(pBlock->data + pBlock->schemaLen);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDataRow tsdbGetSubmitBlkNext(SSubmitBlkIter *pIter) {
|
static SMemRow tsdbGetSubmitBlkNext(SSubmitBlkIter *pIter) {
|
||||||
SDataRow row = pIter->row;
|
SMemRow row = pIter->row; // firstly, get current row
|
||||||
if (row == NULL) return NULL;
|
if (row == NULL) return NULL;
|
||||||
|
|
||||||
pIter->len += dataRowLen(row);
|
pIter->len += memRowTLen(row);
|
||||||
if (pIter->len >= pIter->totalLen) {
|
if (pIter->len >= pIter->totalLen) { // reach the end
|
||||||
pIter->row = NULL;
|
pIter->row = NULL;
|
||||||
} else {
|
} else {
|
||||||
pIter->row = (char *)row + dataRowLen(row);
|
pIter->row = (char *)row + memRowTLen(row); // secondly, move to next row
|
||||||
}
|
}
|
||||||
|
|
||||||
return row;
|
return row;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FORCE_INLINE int tsdbCheckRowRange(STsdbRepo *pRepo, STable *pTable, SDataRow row, TSKEY minKey, TSKEY maxKey,
|
static FORCE_INLINE int tsdbCheckRowRange(STsdbRepo *pRepo, STable *pTable, SMemRow row, TSKEY minKey, TSKEY maxKey,
|
||||||
TSKEY now) {
|
TSKEY now) {
|
||||||
if (dataRowKey(row) < minKey || dataRowKey(row) > maxKey) {
|
TSKEY rowKey = memRowKey(row);
|
||||||
|
if (rowKey < minKey || rowKey > maxKey) {
|
||||||
tsdbError("vgId:%d table %s tid %d uid %" PRIu64 " timestamp is out of range! now %" PRId64 " minKey %" PRId64
|
tsdbError("vgId:%d table %s tid %d uid %" PRIu64 " timestamp is out of range! now %" PRId64 " minKey %" PRId64
|
||||||
" maxKey %" PRId64 " row key %" PRId64,
|
" maxKey %" PRId64 " row key %" PRId64,
|
||||||
REPO_ID(pRepo), TABLE_CHAR_NAME(pTable), TABLE_TID(pTable), TABLE_UID(pTable), now, minKey, maxKey,
|
REPO_ID(pRepo), TABLE_CHAR_NAME(pTable), TABLE_TID(pTable), TABLE_UID(pTable), now, minKey, maxKey,
|
||||||
dataRowKey(row));
|
rowKey);
|
||||||
terrno = TSDB_CODE_TDB_TIMESTAMP_OUT_OF_RANGE;
|
terrno = TSDB_CODE_TDB_TIMESTAMP_OUT_OF_RANGE;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -630,7 +630,7 @@ static int tsdbScanAndConvertSubmitMsg(STsdbRepo *pRepo, SSubmitMsg *pMsg) {
|
||||||
SSubmitMsgIter msgIter = {0};
|
SSubmitMsgIter msgIter = {0};
|
||||||
SSubmitBlk * pBlock = NULL;
|
SSubmitBlk * pBlock = NULL;
|
||||||
SSubmitBlkIter blkIter = {0};
|
SSubmitBlkIter blkIter = {0};
|
||||||
SDataRow row = NULL;
|
SMemRow row = NULL;
|
||||||
TSKEY now = taosGetTimestamp(pRepo->config.precision);
|
TSKEY now = taosGetTimestamp(pRepo->config.precision);
|
||||||
TSKEY minKey = now - tsTickPerDay[pRepo->config.precision] * pRepo->config.keep;
|
TSKEY minKey = now - tsTickPerDay[pRepo->config.precision] * pRepo->config.keep;
|
||||||
TSKEY maxKey = now + tsTickPerDay[pRepo->config.precision] * pRepo->config.daysPerFile;
|
TSKEY maxKey = now + tsTickPerDay[pRepo->config.precision] * pRepo->config.daysPerFile;
|
||||||
|
|
@ -698,7 +698,7 @@ static int tsdbInsertDataToTable(STsdbRepo *pRepo, SSubmitBlk *pBlock, int32_t *
|
||||||
int64_t points = 0;
|
int64_t points = 0;
|
||||||
STable * pTable = NULL;
|
STable * pTable = NULL;
|
||||||
SSubmitBlkIter blkIter = {0};
|
SSubmitBlkIter blkIter = {0};
|
||||||
SDataRow row = NULL;
|
SMemRow row = NULL;
|
||||||
void * rows[TSDB_MAX_INSERT_BATCH] = {0};
|
void * rows[TSDB_MAX_INSERT_BATCH] = {0};
|
||||||
int rowCounter = 0;
|
int rowCounter = 0;
|
||||||
|
|
||||||
|
|
@ -744,10 +744,10 @@ _err:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tsdbCopyRowToMem(STsdbRepo *pRepo, SDataRow row, STable *pTable, void **ppRow) {
|
static int tsdbCopyRowToMem(STsdbRepo *pRepo, SMemRow row, STable *pTable, void **ppRow) {
|
||||||
STsdbCfg * pCfg = &pRepo->config;
|
STsdbCfg * pCfg = &pRepo->config;
|
||||||
TKEY tkey = dataRowTKey(row);
|
TKEY tkey = memRowTKey(row);
|
||||||
TSKEY key = dataRowKey(row);
|
TSKEY key = memRowKey(row);
|
||||||
bool isRowDelete = TKEY_IS_DELETED(tkey);
|
bool isRowDelete = TKEY_IS_DELETED(tkey);
|
||||||
|
|
||||||
if (isRowDelete) {
|
if (isRowDelete) {
|
||||||
|
|
@ -765,15 +765,15 @@ static int tsdbCopyRowToMem(STsdbRepo *pRepo, SDataRow row, STable *pTable, void
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void *pRow = tsdbAllocBytes(pRepo, dataRowLen(row));
|
void *pRow = tsdbAllocBytes(pRepo, memRowTLen(row));
|
||||||
if (pRow == NULL) {
|
if (pRow == NULL) {
|
||||||
tsdbError("vgId:%d failed to insert row with key %" PRId64 " to table %s while allocate %d bytes since %s",
|
tsdbError("vgId:%d failed to insert row with key %" PRId64 " to table %s while allocate %" PRIu32 " bytes since %s",
|
||||||
REPO_ID(pRepo), key, TABLE_CHAR_NAME(pTable), dataRowLen(row), tstrerror(terrno));
|
REPO_ID(pRepo), key, TABLE_CHAR_NAME(pTable), memRowTLen(row), tstrerror(terrno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
dataRowCpy(pRow, row);
|
memRowCpy(pRow, row);
|
||||||
ppRow[0] = pRow;
|
ppRow[0] = pRow; // save the memory address of data rows
|
||||||
|
|
||||||
tsdbTrace("vgId:%d a row is %s table %s tid %d uid %" PRIu64 " key %" PRIu64, REPO_ID(pRepo),
|
tsdbTrace("vgId:%d a row is %s table %s tid %d uid %" PRIu64 " key %" PRIu64, REPO_ID(pRepo),
|
||||||
isRowDelete ? "deleted from" : "updated in", TABLE_CHAR_NAME(pTable), TABLE_TID(pTable), TABLE_UID(pTable),
|
isRowDelete ? "deleted from" : "updated in", TABLE_CHAR_NAME(pTable), TABLE_TID(pTable), TABLE_UID(pTable),
|
||||||
|
|
@ -932,13 +932,15 @@ static int tsdbInsertDataToTableImpl(STsdbRepo *pRepo, STable *pTable, void **ro
|
||||||
int64_t osize = SL_SIZE(pTableData->pData);
|
int64_t osize = SL_SIZE(pTableData->pData);
|
||||||
tSkipListPutBatch(pTableData->pData, rows, rowCounter);
|
tSkipListPutBatch(pTableData->pData, rows, rowCounter);
|
||||||
int64_t dsize = SL_SIZE(pTableData->pData) - osize;
|
int64_t dsize = SL_SIZE(pTableData->pData) - osize;
|
||||||
|
TSKEY keyFirstRow = memRowKey(rows[0]);
|
||||||
|
TSKEY keyLastRow = memRowKey(rows[rowCounter - 1]);
|
||||||
|
|
||||||
if (pMemTable->keyFirst > dataRowKey(rows[0])) pMemTable->keyFirst = dataRowKey(rows[0]);
|
if (pMemTable->keyFirst > keyFirstRow) pMemTable->keyFirst = keyFirstRow;
|
||||||
if (pMemTable->keyLast < dataRowKey(rows[rowCounter - 1])) pMemTable->keyLast = dataRowKey(rows[rowCounter - 1]);
|
if (pMemTable->keyLast < keyLastRow) pMemTable->keyLast = keyLastRow;
|
||||||
pMemTable->numOfRows += dsize;
|
pMemTable->numOfRows += dsize;
|
||||||
|
|
||||||
if (pTableData->keyFirst > dataRowKey(rows[0])) pTableData->keyFirst = dataRowKey(rows[0]);
|
if (pTableData->keyFirst > keyFirstRow) pTableData->keyFirst = keyFirstRow;
|
||||||
if (pTableData->keyLast < dataRowKey(rows[rowCounter - 1])) pTableData->keyLast = dataRowKey(rows[rowCounter - 1]);
|
if (pTableData->keyLast < keyLastRow) pTableData->keyLast = keyLastRow;
|
||||||
pTableData->numOfRows += dsize;
|
pTableData->numOfRows += dsize;
|
||||||
|
|
||||||
// update table latest info
|
// update table latest info
|
||||||
|
|
@ -954,8 +956,8 @@ static void tsdbFreeRows(STsdbRepo *pRepo, void **rows, int rowCounter) {
|
||||||
STsdbBufPool *pBufPool = pRepo->pPool;
|
STsdbBufPool *pBufPool = pRepo->pPool;
|
||||||
|
|
||||||
for (int i = rowCounter - 1; i >= 0; --i) {
|
for (int i = rowCounter - 1; i >= 0; --i) {
|
||||||
SDataRow row = (SDataRow)rows[i];
|
SMemRow row = (SMemRow)rows[i];
|
||||||
int bytes = (int)dataRowLen(row);
|
int bytes = (int)memRowTLen(row);
|
||||||
|
|
||||||
if (pRepo->mem->extraBuffList == NULL) {
|
if (pRepo->mem->extraBuffList == NULL) {
|
||||||
STsdbBufBlock *pBufBlock = tsdbGetCurrBufBlock(pRepo);
|
STsdbBufBlock *pBufBlock = tsdbGetCurrBufBlock(pRepo);
|
||||||
|
|
@ -988,21 +990,23 @@ static void tsdbFreeRows(STsdbRepo *pRepo, void **rows, int rowCounter) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void updateTableLatestColumn(STsdbRepo *pRepo, STable *pTable, SDataRow row) {
|
static void updateTableLatestColumn(STsdbRepo *pRepo, STable *pTable, SMemRow row) {
|
||||||
tsdbDebug("vgId:%d updateTableLatestColumn, %s row version:%d", REPO_ID(pRepo), pTable->name->data, dataRowVersion(row));
|
tsdbDebug("vgId:%d updateTableLatestColumn, %s row version:%d", REPO_ID(pRepo), pTable->name->data,
|
||||||
|
memRowVersion(row));
|
||||||
|
|
||||||
STSchema* pSchema = tsdbGetTableLatestSchema(pTable);
|
STSchema* pSchema = tsdbGetTableLatestSchema(pTable);
|
||||||
if (tsdbUpdateLastColSchema(pTable, pSchema) < 0) {
|
if (tsdbUpdateLastColSchema(pTable, pSchema) < 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pSchema = tsdbGetTableSchemaByVersion(pTable, dataRowVersion(row));
|
pSchema = tsdbGetTableSchemaByVersion(pTable, memRowVersion(row));
|
||||||
if (pSchema == NULL) {
|
if (pSchema == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDataCol *pLatestCols = pTable->lastCols;
|
SDataCol *pLatestCols = pTable->lastCols;
|
||||||
|
|
||||||
|
bool isDataRow = isDataRow(row);
|
||||||
for (int16_t j = 0; j < schemaNCols(pSchema); j++) {
|
for (int16_t j = 0; j < schemaNCols(pSchema); j++) {
|
||||||
STColumn *pTCol = schemaColAt(pSchema, j);
|
STColumn *pTCol = schemaColAt(pSchema, j);
|
||||||
// ignore not exist colId
|
// ignore not exist colId
|
||||||
|
|
@ -1011,8 +1015,20 @@ static void updateTableLatestColumn(STsdbRepo *pRepo, STable *pTable, SDataRow r
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* value = tdGetRowDataOfCol(row, (int8_t)pTCol->type, TD_DATA_ROW_HEAD_SIZE + pSchema->columns[j].offset);
|
void *value = NULL;
|
||||||
if (isNull(value, pTCol->type)) {
|
|
||||||
|
if (isDataRow) {
|
||||||
|
value = tdGetRowDataOfCol(memRowDataBody(row), (int8_t)pTCol->type,
|
||||||
|
TD_DATA_ROW_HEAD_SIZE + pSchema->columns[j].offset);
|
||||||
|
} else {
|
||||||
|
// SKVRow
|
||||||
|
SColIdx *pColIdx = tdGetKVRowIdxOfCol(memRowKvBody(row), pTCol->colId);
|
||||||
|
if (pColIdx) {
|
||||||
|
value = tdGetKvRowDataOfCol(memRowKvBody(row), pColIdx->offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((value == NULL) || isNull(value, pTCol->type)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1027,11 +1043,11 @@ static void updateTableLatestColumn(STsdbRepo *pRepo, STable *pTable, SDataRow r
|
||||||
|
|
||||||
memcpy(pDataCol->pData, value, pDataCol->bytes);
|
memcpy(pDataCol->pData, value, pDataCol->bytes);
|
||||||
//tsdbInfo("updateTableLatestColumn vgId:%d cache column %d for %d,%s", REPO_ID(pRepo), j, pDataCol->bytes, (char*)pDataCol->pData);
|
//tsdbInfo("updateTableLatestColumn vgId:%d cache column %d for %d,%s", REPO_ID(pRepo), j, pDataCol->bytes, (char*)pDataCol->pData);
|
||||||
pDataCol->ts = dataRowKey(row);
|
pDataCol->ts = memRowKey(row);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tsdbUpdateTableLatestInfo(STsdbRepo *pRepo, STable *pTable, SDataRow row) {
|
static int tsdbUpdateTableLatestInfo(STsdbRepo *pRepo, STable *pTable, SMemRow row) {
|
||||||
STsdbCfg *pCfg = &pRepo->config;
|
STsdbCfg *pCfg = &pRepo->config;
|
||||||
|
|
||||||
// if cacheLastRow config has been reset, free the lastRow
|
// if cacheLastRow config has been reset, free the lastRow
|
||||||
|
|
@ -1042,31 +1058,31 @@ static int tsdbUpdateTableLatestInfo(STsdbRepo *pRepo, STable *pTable, SDataRow
|
||||||
TSDB_WUNLOCK_TABLE(pTable);
|
TSDB_WUNLOCK_TABLE(pTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tsdbGetTableLastKeyImpl(pTable) < dataRowKey(row)) {
|
if (tsdbGetTableLastKeyImpl(pTable) < memRowKey(row)) {
|
||||||
if (CACHE_LAST_ROW(pCfg) || pTable->lastRow != NULL) {
|
if (CACHE_LAST_ROW(pCfg) || pTable->lastRow != NULL) {
|
||||||
SDataRow nrow = pTable->lastRow;
|
SMemRow nrow = pTable->lastRow;
|
||||||
if (taosTSizeof(nrow) < dataRowLen(row)) {
|
if (taosTSizeof(nrow) < memRowTLen(row)) {
|
||||||
SDataRow orow = nrow;
|
SMemRow orow = nrow;
|
||||||
nrow = taosTMalloc(dataRowLen(row));
|
nrow = taosTMalloc(memRowTLen(row));
|
||||||
if (nrow == NULL) {
|
if (nrow == NULL) {
|
||||||
terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
|
terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
dataRowCpy(nrow, row);
|
memRowCpy(nrow, row);
|
||||||
TSDB_WLOCK_TABLE(pTable);
|
TSDB_WLOCK_TABLE(pTable);
|
||||||
pTable->lastKey = dataRowKey(row);
|
pTable->lastKey = memRowKey(row);
|
||||||
pTable->lastRow = nrow;
|
pTable->lastRow = nrow;
|
||||||
TSDB_WUNLOCK_TABLE(pTable);
|
TSDB_WUNLOCK_TABLE(pTable);
|
||||||
taosTZfree(orow);
|
taosTZfree(orow);
|
||||||
} else {
|
} else {
|
||||||
TSDB_WLOCK_TABLE(pTable);
|
TSDB_WLOCK_TABLE(pTable);
|
||||||
pTable->lastKey = dataRowKey(row);
|
pTable->lastKey = memRowKey(row);
|
||||||
dataRowCpy(nrow, row);
|
memRowCpy(nrow, row);
|
||||||
TSDB_WUNLOCK_TABLE(pTable);
|
TSDB_WUNLOCK_TABLE(pTable);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
pTable->lastKey = dataRowKey(row);
|
pTable->lastKey = memRowKey(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CACHE_LAST_NULL_COLUMN(pCfg)) {
|
if (CACHE_LAST_NULL_COLUMN(pCfg)) {
|
||||||
|
|
|
||||||
|
|
@ -147,7 +147,7 @@ typedef struct STableGroupSupporter {
|
||||||
static STimeWindow updateLastrowForEachGroup(STableGroupInfo *groupList);
|
static STimeWindow updateLastrowForEachGroup(STableGroupInfo *groupList);
|
||||||
static int32_t checkForCachedLastRow(STsdbQueryHandle* pQueryHandle, STableGroupInfo *groupList);
|
static int32_t checkForCachedLastRow(STsdbQueryHandle* pQueryHandle, STableGroupInfo *groupList);
|
||||||
static int32_t checkForCachedLast(STsdbQueryHandle* pQueryHandle);
|
static int32_t checkForCachedLast(STsdbQueryHandle* pQueryHandle);
|
||||||
static int32_t tsdbGetCachedLastRow(STable* pTable, SDataRow* pRes, TSKEY* lastKey);
|
static int32_t tsdbGetCachedLastRow(STable* pTable, SMemRow* pRes, TSKEY* lastKey);
|
||||||
|
|
||||||
static void changeQueryHandleForInterpQuery(TsdbQueryHandleT pHandle);
|
static void changeQueryHandleForInterpQuery(TsdbQueryHandleT pHandle);
|
||||||
static void doMergeTwoLevelData(STsdbQueryHandle* pQueryHandle, STableCheckInfo* pCheckInfo, SBlock* pBlock);
|
static void doMergeTwoLevelData(STsdbQueryHandle* pQueryHandle, STableCheckInfo* pCheckInfo, SBlock* pBlock);
|
||||||
|
|
@ -734,8 +734,8 @@ static bool initTableMemIterator(STsdbQueryHandle* pHandle, STableCheckInfo* pCh
|
||||||
SSkipListNode* node = tSkipListIterGet(pCheckInfo->iter);
|
SSkipListNode* node = tSkipListIterGet(pCheckInfo->iter);
|
||||||
assert(node != NULL);
|
assert(node != NULL);
|
||||||
|
|
||||||
SDataRow row = (SDataRow)SL_GET_NODE_DATA(node);
|
SMemRow row = (SMemRow)SL_GET_NODE_DATA(node);
|
||||||
TSKEY key = dataRowKey(row); // first timestamp in buffer
|
TSKEY key = memRowKey(row); // first timestamp in buffer
|
||||||
tsdbDebug("%p uid:%" PRId64 ", tid:%d check data in mem from skey:%" PRId64 ", order:%d, ts range in buf:%" PRId64
|
tsdbDebug("%p uid:%" PRId64 ", tid:%d check data in mem from skey:%" PRId64 ", order:%d, ts range in buf:%" PRId64
|
||||||
"-%" PRId64 ", lastKey:%" PRId64 ", numOfRows:%"PRId64", 0x%"PRIx64,
|
"-%" PRId64 ", lastKey:%" PRId64 ", numOfRows:%"PRId64", 0x%"PRIx64,
|
||||||
pHandle, pCheckInfo->tableId.uid, pCheckInfo->tableId.tid, key, order, pMem->keyFirst, pMem->keyLast,
|
pHandle, pCheckInfo->tableId.uid, pCheckInfo->tableId.tid, key, order, pMem->keyFirst, pMem->keyLast,
|
||||||
|
|
@ -756,8 +756,8 @@ static bool initTableMemIterator(STsdbQueryHandle* pHandle, STableCheckInfo* pCh
|
||||||
SSkipListNode* node = tSkipListIterGet(pCheckInfo->iiter);
|
SSkipListNode* node = tSkipListIterGet(pCheckInfo->iiter);
|
||||||
assert(node != NULL);
|
assert(node != NULL);
|
||||||
|
|
||||||
SDataRow row = (SDataRow)SL_GET_NODE_DATA(node);
|
SMemRow row = (SMemRow)SL_GET_NODE_DATA(node);
|
||||||
TSKEY key = dataRowKey(row); // first timestamp in buffer
|
TSKEY key = memRowKey(row); // first timestamp in buffer
|
||||||
tsdbDebug("%p uid:%" PRId64 ", tid:%d check data in imem from skey:%" PRId64 ", order:%d, ts range in buf:%" PRId64
|
tsdbDebug("%p uid:%" PRId64 ", tid:%d check data in imem from skey:%" PRId64 ", order:%d, ts range in buf:%" PRId64
|
||||||
"-%" PRId64 ", lastKey:%" PRId64 ", numOfRows:%"PRId64", 0x%"PRIx64,
|
"-%" PRId64 ", lastKey:%" PRId64 ", numOfRows:%"PRId64", 0x%"PRIx64,
|
||||||
pHandle, pCheckInfo->tableId.uid, pCheckInfo->tableId.tid, key, order, pIMem->keyFirst, pIMem->keyLast,
|
pHandle, pCheckInfo->tableId.uid, pCheckInfo->tableId.tid, key, order, pIMem->keyFirst, pIMem->keyLast,
|
||||||
|
|
@ -781,19 +781,19 @@ static void destroyTableMemIterator(STableCheckInfo* pCheckInfo) {
|
||||||
tSkipListDestroyIter(pCheckInfo->iiter);
|
tSkipListDestroyIter(pCheckInfo->iiter);
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDataRow getSDataRowInTableMem(STableCheckInfo* pCheckInfo, int32_t order, int32_t update) {
|
static SMemRow getSDataRowInTableMem(STableCheckInfo* pCheckInfo, int32_t order, int32_t update) {
|
||||||
SDataRow rmem = NULL, rimem = NULL;
|
SMemRow rmem = NULL, rimem = NULL;
|
||||||
if (pCheckInfo->iter) {
|
if (pCheckInfo->iter) {
|
||||||
SSkipListNode* node = tSkipListIterGet(pCheckInfo->iter);
|
SSkipListNode* node = tSkipListIterGet(pCheckInfo->iter);
|
||||||
if (node != NULL) {
|
if (node != NULL) {
|
||||||
rmem = (SDataRow)SL_GET_NODE_DATA(node);
|
rmem = (SMemRow)SL_GET_NODE_DATA(node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pCheckInfo->iiter) {
|
if (pCheckInfo->iiter) {
|
||||||
SSkipListNode* node = tSkipListIterGet(pCheckInfo->iiter);
|
SSkipListNode* node = tSkipListIterGet(pCheckInfo->iiter);
|
||||||
if (node != NULL) {
|
if (node != NULL) {
|
||||||
rimem = (SDataRow)SL_GET_NODE_DATA(node);
|
rimem = (SMemRow)SL_GET_NODE_DATA(node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -811,8 +811,8 @@ static SDataRow getSDataRowInTableMem(STableCheckInfo* pCheckInfo, int32_t order
|
||||||
return rimem;
|
return rimem;
|
||||||
}
|
}
|
||||||
|
|
||||||
TSKEY r1 = dataRowKey(rmem);
|
TSKEY r1 = memRowKey(rmem);
|
||||||
TSKEY r2 = dataRowKey(rimem);
|
TSKEY r2 = memRowKey(rimem);
|
||||||
|
|
||||||
if (r1 == r2) { // data ts are duplicated, ignore the data in mem
|
if (r1 == r2) { // data ts are duplicated, ignore the data in mem
|
||||||
if (!update) {
|
if (!update) {
|
||||||
|
|
@ -891,12 +891,12 @@ static bool hasMoreDataInCache(STsdbQueryHandle* pHandle) {
|
||||||
initTableMemIterator(pHandle, pCheckInfo);
|
initTableMemIterator(pHandle, pCheckInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDataRow row = getSDataRowInTableMem(pCheckInfo, pHandle->order, pCfg->update);
|
SMemRow row = getSDataRowInTableMem(pCheckInfo, pHandle->order, pCfg->update);
|
||||||
if (row == NULL) {
|
if (row == NULL) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
pCheckInfo->lastKey = dataRowKey(row); // first timestamp in buffer
|
pCheckInfo->lastKey = memRowKey(row); // first timestamp in buffer
|
||||||
tsdbDebug("%p uid:%" PRId64", tid:%d check data in buffer from skey:%" PRId64 ", order:%d, 0x%"PRIx64, pHandle,
|
tsdbDebug("%p uid:%" PRId64", tid:%d check data in buffer from skey:%" PRId64 ", order:%d, 0x%"PRIx64, pHandle,
|
||||||
pCheckInfo->tableId.uid, pCheckInfo->tableId.tid, pCheckInfo->lastKey, pHandle->order, pHandle->qId);
|
pCheckInfo->tableId.uid, pCheckInfo->tableId.tid, pCheckInfo->lastKey, pHandle->order, pHandle->qId);
|
||||||
|
|
||||||
|
|
@ -1155,11 +1155,11 @@ static int32_t handleDataMergeIfNeeded(STsdbQueryHandle* pQueryHandle, SBlock* p
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
|
||||||
/*bool hasData = */ initTableMemIterator(pQueryHandle, pCheckInfo);
|
/*bool hasData = */ initTableMemIterator(pQueryHandle, pCheckInfo);
|
||||||
SDataRow row = getSDataRowInTableMem(pCheckInfo, pQueryHandle->order, pCfg->update);
|
SMemRow row = getSDataRowInTableMem(pCheckInfo, pQueryHandle->order, pCfg->update);
|
||||||
|
|
||||||
assert(cur->pos >= 0 && cur->pos <= binfo.rows);
|
assert(cur->pos >= 0 && cur->pos <= binfo.rows);
|
||||||
|
|
||||||
TSKEY key = (row != NULL)? dataRowKey(row):TSKEY_INITIAL_VAL;
|
TSKEY key = (row != NULL) ? memRowKey(row) : TSKEY_INITIAL_VAL;
|
||||||
if (key != TSKEY_INITIAL_VAL) {
|
if (key != TSKEY_INITIAL_VAL) {
|
||||||
tsdbDebug("%p key in mem:%"PRId64", 0x%"PRIx64, pQueryHandle, key, pQueryHandle->qId);
|
tsdbDebug("%p key in mem:%"PRId64", 0x%"PRIx64, pQueryHandle, key, pQueryHandle->qId);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1401,7 +1401,7 @@ int32_t doCopyRowsFromFileBlock(STsdbQueryHandle* pQueryHandle, int32_t capacity
|
||||||
|
|
||||||
// todo refactor, only copy one-by-one
|
// todo refactor, only copy one-by-one
|
||||||
for (int32_t k = start; k < num + start; ++k) {
|
for (int32_t k = start; k < num + start; ++k) {
|
||||||
char* p = tdGetColDataOfRow(src, k);
|
const char* p = tdGetColDataOfRow(src, k);
|
||||||
memcpy(dst, p, varDataTLen(p));
|
memcpy(dst, p, varDataTLen(p));
|
||||||
dst += bytes;
|
dst += bytes;
|
||||||
}
|
}
|
||||||
|
|
@ -1452,20 +1452,24 @@ int32_t doCopyRowsFromFileBlock(STsdbQueryHandle* pQueryHandle, int32_t capacity
|
||||||
return numOfRows + num;
|
return numOfRows + num;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void copyOneRowFromMem(STsdbQueryHandle* pQueryHandle, int32_t capacity, int32_t numOfRows, SDataRow row,
|
static void copyOneRowFromMem(STsdbQueryHandle* pQueryHandle, int32_t capacity, int32_t numOfRows, SMemRow row,
|
||||||
int32_t numOfCols, STable* pTable, STSchema* pSchema) {
|
int32_t numOfCols, STable* pTable, STSchema* pSchema) {
|
||||||
char* pData = NULL;
|
char* pData = NULL;
|
||||||
|
|
||||||
// the schema version info is embeded in SDataRow
|
// the schema version info is embedded in SDataRow, and use latest schema version for SKVRow
|
||||||
int32_t numOfRowCols = 0;
|
int32_t numOfRowCols = 0;
|
||||||
if (pSchema == NULL) {
|
if (pSchema == NULL) {
|
||||||
pSchema = tsdbGetTableSchemaByVersion(pTable, dataRowVersion(row));
|
pSchema = tsdbGetTableSchemaByVersion(pTable, memRowVersion(row));
|
||||||
numOfRowCols = schemaNCols(pSchema);
|
numOfRowCols = schemaNCols(pSchema);
|
||||||
} else {
|
} else {
|
||||||
numOfRowCols = schemaNCols(pSchema);
|
numOfRowCols = schemaNCols(pSchema);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t i = 0, j = 0;
|
int32_t i = 0;
|
||||||
|
|
||||||
|
if (isDataRow(row)) {
|
||||||
|
SDataRow dataRow = memRowDataBody(row);
|
||||||
|
int32_t j = 0;
|
||||||
while (i < numOfCols && j < numOfRowCols) {
|
while (i < numOfCols && j < numOfRowCols) {
|
||||||
SColumnInfoData* pColInfo = taosArrayGet(pQueryHandle->pColumns, i);
|
SColumnInfoData* pColInfo = taosArrayGet(pQueryHandle->pColumns, i);
|
||||||
if (pSchema->columns[j].colId < pColInfo->info.colId) {
|
if (pSchema->columns[j].colId < pColInfo->info.colId) {
|
||||||
|
|
@ -1480,7 +1484,8 @@ static void copyOneRowFromMem(STsdbQueryHandle* pQueryHandle, int32_t capacity,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pSchema->columns[j].colId == pColInfo->info.colId) {
|
if (pSchema->columns[j].colId == pColInfo->info.colId) {
|
||||||
void* value = tdGetRowDataOfCol(row, (int8_t)pColInfo->info.type, TD_DATA_ROW_HEAD_SIZE + pSchema->columns[j].offset);
|
void* value =
|
||||||
|
tdGetRowDataOfCol(dataRow, (int8_t)pColInfo->info.type, TD_DATA_ROW_HEAD_SIZE + pSchema->columns[j].offset);
|
||||||
switch (pColInfo->info.type) {
|
switch (pColInfo->info.type) {
|
||||||
case TSDB_DATA_TYPE_BINARY:
|
case TSDB_DATA_TYPE_BINARY:
|
||||||
case TSDB_DATA_TYPE_NCHAR:
|
case TSDB_DATA_TYPE_NCHAR:
|
||||||
|
|
@ -1532,6 +1537,83 @@ static void copyOneRowFromMem(STsdbQueryHandle* pQueryHandle, int32_t capacity,
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (isKvRow(row)) {
|
||||||
|
SKVRow kvRow = memRowKvBody(row);
|
||||||
|
int32_t k = 0;
|
||||||
|
int32_t nKvRowCols = kvRowNCols(kvRow);
|
||||||
|
|
||||||
|
while (i < numOfCols && k < nKvRowCols) {
|
||||||
|
SColumnInfoData* pColInfo = taosArrayGet(pQueryHandle->pColumns, i);
|
||||||
|
SColIdx* pColIdx = kvRowColIdxAt(kvRow, k);
|
||||||
|
|
||||||
|
if (pColIdx->colId < pColInfo->info.colId) {
|
||||||
|
++k;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ASCENDING_TRAVERSE(pQueryHandle->order)) {
|
||||||
|
pData = (char*)pColInfo->pData + numOfRows * pColInfo->info.bytes;
|
||||||
|
} else {
|
||||||
|
pData = (char*)pColInfo->pData + (capacity - numOfRows - 1) * pColInfo->info.bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pColIdx->colId == pColInfo->info.colId) {
|
||||||
|
// offset of pColIdx for SKVRow including the TD_KV_ROW_HEAD_SIZE
|
||||||
|
void* value = tdGetKvRowDataOfCol(kvRow, pColIdx->offset);
|
||||||
|
switch (pColInfo->info.type) {
|
||||||
|
case TSDB_DATA_TYPE_BINARY:
|
||||||
|
case TSDB_DATA_TYPE_NCHAR:
|
||||||
|
memcpy(pData, value, varDataTLen(value));
|
||||||
|
break;
|
||||||
|
case TSDB_DATA_TYPE_NULL:
|
||||||
|
case TSDB_DATA_TYPE_BOOL:
|
||||||
|
case TSDB_DATA_TYPE_TINYINT:
|
||||||
|
case TSDB_DATA_TYPE_UTINYINT:
|
||||||
|
*(uint8_t*)pData = *(uint8_t*)value;
|
||||||
|
break;
|
||||||
|
case TSDB_DATA_TYPE_SMALLINT:
|
||||||
|
case TSDB_DATA_TYPE_USMALLINT:
|
||||||
|
*(uint16_t*)pData = *(uint16_t*)value;
|
||||||
|
break;
|
||||||
|
case TSDB_DATA_TYPE_INT:
|
||||||
|
case TSDB_DATA_TYPE_UINT:
|
||||||
|
*(uint32_t*)pData = *(uint32_t*)value;
|
||||||
|
break;
|
||||||
|
case TSDB_DATA_TYPE_BIGINT:
|
||||||
|
case TSDB_DATA_TYPE_UBIGINT:
|
||||||
|
*(uint64_t*)pData = *(uint64_t*)value;
|
||||||
|
break;
|
||||||
|
case TSDB_DATA_TYPE_FLOAT:
|
||||||
|
SET_FLOAT_PTR(pData, value);
|
||||||
|
break;
|
||||||
|
case TSDB_DATA_TYPE_DOUBLE:
|
||||||
|
SET_DOUBLE_PTR(pData, value);
|
||||||
|
break;
|
||||||
|
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||||
|
if (pColInfo->info.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) {
|
||||||
|
*(TSKEY*)pData = tdGetKey(*(TKEY*)value);
|
||||||
|
} else {
|
||||||
|
*(TSKEY*)pData = *(TSKEY*)value;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
memcpy(pData, value, pColInfo->info.bytes);
|
||||||
|
}
|
||||||
|
++k;
|
||||||
|
++i;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// If (pColInfo->info.colId < pColIdx->colId), it is NULL data
|
||||||
|
if (pColInfo->info.type == TSDB_DATA_TYPE_BINARY || pColInfo->info.type == TSDB_DATA_TYPE_NCHAR) {
|
||||||
|
setVardataNull(pData, pColInfo->info.type);
|
||||||
|
} else {
|
||||||
|
setNull(pData, pColInfo->info.type, pColInfo->info.bytes);
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ASSERT(0);
|
||||||
|
}
|
||||||
|
|
||||||
while (i < numOfCols) { // the remain columns are all null data
|
while (i < numOfCols) { // the remain columns are all null data
|
||||||
SColumnInfoData* pColInfo = taosArrayGet(pQueryHandle->pColumns, i);
|
SColumnInfoData* pColInfo = taosArrayGet(pQueryHandle->pColumns, i);
|
||||||
|
|
@ -1550,7 +1632,6 @@ static void copyOneRowFromMem(STsdbQueryHandle* pQueryHandle, int32_t capacity,
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void moveDataToFront(STsdbQueryHandle* pQueryHandle, int32_t numOfRows, int32_t numOfCols) {
|
static void moveDataToFront(STsdbQueryHandle* pQueryHandle, int32_t numOfRows, int32_t numOfCols) {
|
||||||
if (numOfRows == 0 || ASCENDING_TRAVERSE(pQueryHandle->order)) {
|
if (numOfRows == 0 || ASCENDING_TRAVERSE(pQueryHandle->order)) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -1730,12 +1811,12 @@ static void doMergeTwoLevelData(STsdbQueryHandle* pQueryHandle, STableCheckInfo*
|
||||||
} else if (pCheckInfo->iter != NULL || pCheckInfo->iiter != NULL) {
|
} else if (pCheckInfo->iter != NULL || pCheckInfo->iiter != NULL) {
|
||||||
SSkipListNode* node = NULL;
|
SSkipListNode* node = NULL;
|
||||||
do {
|
do {
|
||||||
SDataRow row = getSDataRowInTableMem(pCheckInfo, pQueryHandle->order, pCfg->update);
|
SMemRow row = getSDataRowInTableMem(pCheckInfo, pQueryHandle->order, pCfg->update);
|
||||||
if (row == NULL) {
|
if (row == NULL) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
TSKEY key = dataRowKey(row);
|
TSKEY key = memRowKey(row);
|
||||||
if ((key > pQueryHandle->window.ekey && ASCENDING_TRAVERSE(pQueryHandle->order)) ||
|
if ((key > pQueryHandle->window.ekey && ASCENDING_TRAVERSE(pQueryHandle->order)) ||
|
||||||
(key < pQueryHandle->window.ekey && !ASCENDING_TRAVERSE(pQueryHandle->order))) {
|
(key < pQueryHandle->window.ekey && !ASCENDING_TRAVERSE(pQueryHandle->order))) {
|
||||||
break;
|
break;
|
||||||
|
|
@ -1748,9 +1829,9 @@ static void doMergeTwoLevelData(STsdbQueryHandle* pQueryHandle, STableCheckInfo*
|
||||||
|
|
||||||
if ((key < tsArray[pos] && ASCENDING_TRAVERSE(pQueryHandle->order)) ||
|
if ((key < tsArray[pos] && ASCENDING_TRAVERSE(pQueryHandle->order)) ||
|
||||||
(key > tsArray[pos] && !ASCENDING_TRAVERSE(pQueryHandle->order))) {
|
(key > tsArray[pos] && !ASCENDING_TRAVERSE(pQueryHandle->order))) {
|
||||||
if (rv != dataRowVersion(row)) {
|
if (rv != memRowVersion(row)) {
|
||||||
pSchema = tsdbGetTableSchemaByVersion(pTable, dataRowVersion(row));
|
pSchema = tsdbGetTableSchemaByVersion(pTable, memRowVersion(row));
|
||||||
rv = dataRowVersion(row);
|
rv = memRowVersion(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
copyOneRowFromMem(pQueryHandle, pQueryHandle->outputCapacity, numOfRows, row, numOfCols, pTable, pSchema);
|
copyOneRowFromMem(pQueryHandle, pQueryHandle->outputCapacity, numOfRows, row, numOfCols, pTable, pSchema);
|
||||||
|
|
@ -1766,9 +1847,9 @@ static void doMergeTwoLevelData(STsdbQueryHandle* pQueryHandle, STableCheckInfo*
|
||||||
moveToNextRowInMem(pCheckInfo);
|
moveToNextRowInMem(pCheckInfo);
|
||||||
} else if (key == tsArray[pos]) { // data in buffer has the same timestamp of data in file block, ignore it
|
} else if (key == tsArray[pos]) { // data in buffer has the same timestamp of data in file block, ignore it
|
||||||
if (pCfg->update) {
|
if (pCfg->update) {
|
||||||
if (rv != dataRowVersion(row)) {
|
if (rv != memRowVersion(row)) {
|
||||||
pSchema = tsdbGetTableSchemaByVersion(pTable, dataRowVersion(row));
|
pSchema = tsdbGetTableSchemaByVersion(pTable, memRowVersion(row));
|
||||||
rv = dataRowVersion(row);
|
rv = memRowVersion(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
copyOneRowFromMem(pQueryHandle, pQueryHandle->outputCapacity, numOfRows, row, numOfCols, pTable, pSchema);
|
copyOneRowFromMem(pQueryHandle, pQueryHandle->outputCapacity, numOfRows, row, numOfCols, pTable, pSchema);
|
||||||
|
|
@ -1820,8 +1901,10 @@ static void doMergeTwoLevelData(STsdbQueryHandle* pQueryHandle, STableCheckInfo*
|
||||||
* copy them all to result buffer, since it may be overlapped with file data block.
|
* copy them all to result buffer, since it may be overlapped with file data block.
|
||||||
*/
|
*/
|
||||||
if (node == NULL ||
|
if (node == NULL ||
|
||||||
((dataRowKey((SDataRow)SL_GET_NODE_DATA(node)) > pQueryHandle->window.ekey) && ASCENDING_TRAVERSE(pQueryHandle->order)) ||
|
((memRowKey((SMemRow)SL_GET_NODE_DATA(node)) > pQueryHandle->window.ekey) &&
|
||||||
((dataRowKey((SDataRow)SL_GET_NODE_DATA(node)) < pQueryHandle->window.ekey) && !ASCENDING_TRAVERSE(pQueryHandle->order))) {
|
ASCENDING_TRAVERSE(pQueryHandle->order)) ||
|
||||||
|
((memRowKey((SMemRow)SL_GET_NODE_DATA(node)) < pQueryHandle->window.ekey) &&
|
||||||
|
!ASCENDING_TRAVERSE(pQueryHandle->order))) {
|
||||||
// no data in cache or data in cache is greater than the ekey of time window, load data from file block
|
// no data in cache or data in cache is greater than the ekey of time window, load data from file block
|
||||||
if (cur->win.skey == TSKEY_INITIAL_VAL) {
|
if (cur->win.skey == TSKEY_INITIAL_VAL) {
|
||||||
cur->win.skey = tsArray[pos];
|
cur->win.skey = tsArray[pos];
|
||||||
|
|
@ -2407,12 +2490,12 @@ static int tsdbReadRowsFromCache(STableCheckInfo* pCheckInfo, TSKEY maxKey, int
|
||||||
STSchema* pSchema = NULL;
|
STSchema* pSchema = NULL;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
SDataRow row = getSDataRowInTableMem(pCheckInfo, pQueryHandle->order, pCfg->update);
|
SMemRow row = getSDataRowInTableMem(pCheckInfo, pQueryHandle->order, pCfg->update);
|
||||||
if (row == NULL) {
|
if (row == NULL) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
TSKEY key = dataRowKey(row);
|
TSKEY key = memRowKey(row);
|
||||||
if ((key > maxKey && ASCENDING_TRAVERSE(pQueryHandle->order)) || (key < maxKey && !ASCENDING_TRAVERSE(pQueryHandle->order))) {
|
if ((key > maxKey && ASCENDING_TRAVERSE(pQueryHandle->order)) || (key < maxKey && !ASCENDING_TRAVERSE(pQueryHandle->order))) {
|
||||||
tsdbDebug("%p key:%"PRIu64" beyond qrange:%"PRId64" - %"PRId64", no more data in buffer", pQueryHandle, key, pQueryHandle->window.skey,
|
tsdbDebug("%p key:%"PRIu64" beyond qrange:%"PRId64" - %"PRId64", no more data in buffer", pQueryHandle, key, pQueryHandle->window.skey,
|
||||||
pQueryHandle->window.ekey);
|
pQueryHandle->window.ekey);
|
||||||
|
|
@ -2425,9 +2508,9 @@ static int tsdbReadRowsFromCache(STableCheckInfo* pCheckInfo, TSKEY maxKey, int
|
||||||
}
|
}
|
||||||
|
|
||||||
win->ekey = key;
|
win->ekey = key;
|
||||||
if (rv != dataRowVersion(row)) {
|
if (rv != memRowVersion(row)) {
|
||||||
pSchema = tsdbGetTableSchemaByVersion(pTable, dataRowVersion(row));
|
pSchema = tsdbGetTableSchemaByVersion(pTable, memRowVersion(row));
|
||||||
rv = dataRowVersion(row);
|
rv = memRowVersion(row);
|
||||||
}
|
}
|
||||||
copyOneRowFromMem(pQueryHandle, maxRowsToRead, numOfRows, row, numOfCols, pTable, pSchema);
|
copyOneRowFromMem(pQueryHandle, maxRowsToRead, numOfRows, row, numOfCols, pTable, pSchema);
|
||||||
|
|
||||||
|
|
@ -2544,7 +2627,7 @@ static bool loadCachedLastRow(STsdbQueryHandle* pQueryHandle) {
|
||||||
|
|
||||||
SQueryFilePos* cur = &pQueryHandle->cur;
|
SQueryFilePos* cur = &pQueryHandle->cur;
|
||||||
|
|
||||||
SDataRow pRow = NULL;
|
SMemRow pRow = NULL;
|
||||||
TSKEY key = TSKEY_INITIAL_VAL;
|
TSKEY key = TSKEY_INITIAL_VAL;
|
||||||
int32_t step = ASCENDING_TRAVERSE(pQueryHandle->order)? 1:-1;
|
int32_t step = ASCENDING_TRAVERSE(pQueryHandle->order)? 1:-1;
|
||||||
|
|
||||||
|
|
@ -2954,7 +3037,7 @@ bool tsdbGetExternalRow(TsdbQueryHandleT pHandle) {
|
||||||
* if lastRow == NULL, return TSDB_CODE_TDB_NO_CACHE_LAST_ROW
|
* if lastRow == NULL, return TSDB_CODE_TDB_NO_CACHE_LAST_ROW
|
||||||
* else set pRes and return TSDB_CODE_SUCCESS and save lastKey
|
* else set pRes and return TSDB_CODE_SUCCESS and save lastKey
|
||||||
*/
|
*/
|
||||||
int32_t tsdbGetCachedLastRow(STable* pTable, SDataRow* pRes, TSKEY* lastKey) {
|
int32_t tsdbGetCachedLastRow(STable* pTable, SMemRow* pRes, TSKEY* lastKey) {
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
|
||||||
TSDB_RLOCK_TABLE(pTable);
|
TSDB_RLOCK_TABLE(pTable);
|
||||||
|
|
@ -2965,7 +3048,7 @@ int32_t tsdbGetCachedLastRow(STable* pTable, SDataRow* pRes, TSKEY* lastKey) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pRes) {
|
if (pRes) {
|
||||||
*pRes = tdDataRowDup(pTable->lastRow);
|
*pRes = tdMemRowDup(pTable->lastRow);
|
||||||
if (*pRes == NULL) {
|
if (*pRes == NULL) {
|
||||||
code = TSDB_CODE_TDB_OUT_OF_MEMORY;
|
code = TSDB_CODE_TDB_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
@ -3698,6 +3781,10 @@ static void* doFreeColumnInfoData(SArray* pColumnInfoData) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void* destroyTableCheckInfo(SArray* pTableCheckInfo) {
|
static void* destroyTableCheckInfo(SArray* pTableCheckInfo) {
|
||||||
|
if (pTableCheckInfo == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
size_t size = taosArrayGetSize(pTableCheckInfo);
|
size_t size = taosArrayGetSize(pTableCheckInfo);
|
||||||
for (int32_t i = 0; i < size; ++i) {
|
for (int32_t i = 0; i < size; ++i) {
|
||||||
STableCheckInfo* p = taosArrayGet(pTableCheckInfo, i);
|
STableCheckInfo* p = taosArrayGet(pTableCheckInfo, i);
|
||||||
|
|
|
||||||
|
|
@ -55,10 +55,10 @@ static int insertData(SInsertInfo *pInfo) {
|
||||||
for (int j = 0; j < schemaNCols(pInfo->pSchema); j++) {
|
for (int j = 0; j < schemaNCols(pInfo->pSchema); j++) {
|
||||||
STColumn *pTCol = schemaColAt(pInfo->pSchema, j);
|
STColumn *pTCol = schemaColAt(pInfo->pSchema, j);
|
||||||
if (j == 0) { // Just for timestamp
|
if (j == 0) { // Just for timestamp
|
||||||
tdAppendColVal(row, (void *)(&start_time), pTCol->type, pTCol->bytes, pTCol->offset);
|
tdAppendColVal(row, (void *)(&start_time), pTCol->type, pTCol->offset);
|
||||||
} else { // For int
|
} else { // For int
|
||||||
int val = 10;
|
int val = 10;
|
||||||
tdAppendColVal(row, (void *)(&val), pTCol->type, pTCol->bytes, pTCol->offset);
|
tdAppendColVal(row, (void *)(&val), pTCol->type, pTCol->offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pBlock->dataLen += dataRowLen(row);
|
pBlock->dataLen += dataRowLen(row);
|
||||||
|
|
|
||||||
|
|
@ -109,11 +109,12 @@ TAOS_DEFINE_ERROR(TSDB_CODE_TSC_SQL_SYNTAX_ERROR, "Syntax error in SQL")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_TSC_DB_NOT_SELECTED, "Database not specified or available")
|
TAOS_DEFINE_ERROR(TSDB_CODE_TSC_DB_NOT_SELECTED, "Database not specified or available")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_TSC_INVALID_TABLE_NAME, "Table does not exist")
|
TAOS_DEFINE_ERROR(TSDB_CODE_TSC_INVALID_TABLE_NAME, "Table does not exist")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_TSC_EXCEED_SQL_LIMIT, "SQL statement too long, check maxSQLLength config")
|
TAOS_DEFINE_ERROR(TSDB_CODE_TSC_EXCEED_SQL_LIMIT, "SQL statement too long, check maxSQLLength config")
|
||||||
|
TAOS_DEFINE_ERROR(TSDB_CODE_TSC_FILE_EMPTY, "File is empty")
|
||||||
|
|
||||||
// mnode
|
// mnode
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_MSG_NOT_PROCESSED, "Message not processed")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_MSG_NOT_PROCESSED, "Message not processed")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_ACTION_IN_PROGRESS, "Message is progressing")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_ACTION_IN_PROGRESS, "Message is progressing")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_ACTION_NEED_REPROCESSED, "Messag need to be reprocessed")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_ACTION_NEED_REPROCESSED, "Message need to be reprocessed")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_NO_RIGHTS, "Insufficient privilege for operation")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_NO_RIGHTS, "Insufficient privilege for operation")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_APP_ERROR, "Unexpected generic error in mnode")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_APP_ERROR, "Unexpected generic error in mnode")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_CONNECTION, "Invalid message connection")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_CONNECTION, "Invalid message connection")
|
||||||
|
|
@ -183,6 +184,13 @@ TAOS_DEFINE_ERROR(TSDB_CODE_MND_FIELD_NOT_EXIST, "Field does not exist"
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_STABLE_NAME, "Super table does not exist")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_STABLE_NAME, "Super table does not exist")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_CREATE_TABLE_MSG, "Invalid create table message")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_CREATE_TABLE_MSG, "Invalid create table message")
|
||||||
|
|
||||||
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_FUNC_NAME, "Invalid func name")
|
||||||
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_FUNC_LEN, "Invalid func length")
|
||||||
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_FUNC_CODE, "Invalid func code")
|
||||||
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_FUNC_ALREADY_EXIST, "Func already exists")
|
||||||
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_FUNC, "Invalid func")
|
||||||
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_FUNC_BUFSIZE, "Invalid func bufSize")
|
||||||
|
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_DB_NOT_SELECTED, "Database not specified or available")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_DB_NOT_SELECTED, "Database not specified or available")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_DB_ALREADY_EXIST, "Database already exists")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_DB_ALREADY_EXIST, "Database already exists")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_DB_OPTION, "Invalid database options")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_DB_OPTION, "Invalid database options")
|
||||||
|
|
@ -269,6 +277,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_QRY_IN_EXEC, "Multiple retrieval of
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_TOO_MANY_TIMEWINDOW, "Too many time window in query")
|
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_TOO_MANY_TIMEWINDOW, "Too many time window in query")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_NOT_ENOUGH_BUFFER, "Query buffer limit has reached")
|
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_NOT_ENOUGH_BUFFER, "Query buffer limit has reached")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_INCONSISTAN, "File inconsistance in replica")
|
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_INCONSISTAN, "File inconsistance in replica")
|
||||||
|
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_SYS_ERROR, "System error")
|
||||||
|
|
||||||
|
|
||||||
// grant
|
// grant
|
||||||
|
|
|
||||||
|
|
@ -546,7 +546,6 @@ static FORCE_INLINE int32_t getSkipListNodeRandomHeight(SSkipList *pSkipList) {
|
||||||
const uint32_t factor = 4;
|
const uint32_t factor = 4;
|
||||||
|
|
||||||
int32_t n = 1;
|
int32_t n = 1;
|
||||||
|
|
||||||
#if defined(_TD_WINDOWS_64) || defined(_TD_WINDOWS_32)
|
#if defined(_TD_WINDOWS_64) || defined(_TD_WINDOWS_32)
|
||||||
while ((rand() % factor) == 0 && n <= pSkipList->maxLevel) {
|
while ((rand() % factor) == 0 && n <= pSkipList->maxLevel) {
|
||||||
#else
|
#else
|
||||||
|
|
|
||||||
|
|
@ -220,7 +220,12 @@ static SKeyword keywordTable[] = {
|
||||||
{"TOPIC", TK_TOPIC},
|
{"TOPIC", TK_TOPIC},
|
||||||
{"TOPICS", TK_TOPICS},
|
{"TOPICS", TK_TOPICS},
|
||||||
{"COMPACT", TK_COMPACT},
|
{"COMPACT", TK_COMPACT},
|
||||||
{"MODIFY", TK_MODIFY}
|
{"MODIFY", TK_MODIFY},
|
||||||
|
{"FUNCTION", TK_FUNCTION},
|
||||||
|
{"FUNCTIONS", TK_FUNCTIONS},
|
||||||
|
{"OUTPUTTYPE", TK_OUTPUTTYPE},
|
||||||
|
{"AGGREGATE", TK_AGGREGATE},
|
||||||
|
{"BUFSIZE", TK_BUFSIZE},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char isIdChar[] = {
|
static const char isIdChar[] = {
|
||||||
|
|
|
||||||
|
|
@ -231,7 +231,7 @@ static int32_t vnodeProcessQueryMsg(SVnodeObj *pVnode, SVReadMsg *pRead) {
|
||||||
if (contLen != 0) {
|
if (contLen != 0) {
|
||||||
qinfo_t pQInfo = NULL;
|
qinfo_t pQInfo = NULL;
|
||||||
uint64_t qId = genQueryId();
|
uint64_t qId = genQueryId();
|
||||||
code = qCreateQueryInfo(pVnode->tsdb, pVnode->vgId, pQueryTableMsg, &pQInfo, &qId);
|
code = qCreateQueryInfo(pVnode->tsdb, pVnode->vgId, pQueryTableMsg, &pQInfo, qId);
|
||||||
|
|
||||||
SQueryTableRsp *pRsp = (SQueryTableRsp *)rpcMallocCont(sizeof(SQueryTableRsp));
|
SQueryTableRsp *pRsp = (SQueryTableRsp *)rpcMallocCont(sizeof(SQueryTableRsp));
|
||||||
pRsp->code = code;
|
pRsp->code = code;
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,7 @@ int32_t vnodeProcessWrite(void *vparam, void *wparam, int32_t qtype, void *rpara
|
||||||
|
|
||||||
// forward to peers, even it is WAL/FWD, it shall be called to update version in sync
|
// forward to peers, even it is WAL/FWD, it shall be called to update version in sync
|
||||||
int32_t syncCode = 0;
|
int32_t syncCode = 0;
|
||||||
bool force = (pWrite == NULL ? false : pWrite->pHead.msgType != TSDB_MSG_TYPE_SUBMIT);
|
bool force = (pWrite == NULL ? false : pWrite->walHead.msgType != TSDB_MSG_TYPE_SUBMIT);
|
||||||
syncCode = syncForwardToPeer(pVnode->sync, pHead, pWrite, qtype, force);
|
syncCode = syncForwardToPeer(pVnode->sync, pHead, pWrite, qtype, force);
|
||||||
if (syncCode < 0) {
|
if (syncCode < 0) {
|
||||||
pHead->version = 0;
|
pHead->version = 0;
|
||||||
|
|
@ -237,7 +237,7 @@ static SVWriteMsg *vnodeBuildVWriteMsg(SVnodeObj *pVnode, SWalHead *pHead, int32
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t size = sizeof(SVWriteMsg) + sizeof(SWalHead) + pHead->len;
|
int32_t size = sizeof(SVWriteMsg) + pHead->len;
|
||||||
SVWriteMsg *pWrite = taosAllocateQitem(size);
|
SVWriteMsg *pWrite = taosAllocateQitem(size);
|
||||||
if (pWrite == NULL) {
|
if (pWrite == NULL) {
|
||||||
terrno = TSDB_CODE_VND_OUT_OF_MEMORY;
|
terrno = TSDB_CODE_VND_OUT_OF_MEMORY;
|
||||||
|
|
@ -248,7 +248,7 @@ static SVWriteMsg *vnodeBuildVWriteMsg(SVnodeObj *pVnode, SWalHead *pHead, int32
|
||||||
pWrite->rpcMsg = *pRpcMsg;
|
pWrite->rpcMsg = *pRpcMsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(&pWrite->pHead, pHead, sizeof(SWalHead) + pHead->len);
|
memcpy(&pWrite->walHead, pHead, sizeof(SWalHead) + pHead->len);
|
||||||
pWrite->pVnode = pVnode;
|
pWrite->pVnode = pVnode;
|
||||||
pWrite->qtype = qtype;
|
pWrite->qtype = qtype;
|
||||||
|
|
||||||
|
|
@ -286,7 +286,7 @@ static int32_t vnodeWriteToWQueueImp(SVWriteMsg *pWrite) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t queued = atomic_add_fetch_32(&pVnode->queuedWMsg, 1);
|
int32_t queued = atomic_add_fetch_32(&pVnode->queuedWMsg, 1);
|
||||||
int64_t queuedSize = atomic_add_fetch_64(&pVnode->queuedWMsgSize, pWrite->pHead.len);
|
int64_t queuedSize = atomic_add_fetch_64(&pVnode->queuedWMsgSize, pWrite->walHead.len);
|
||||||
|
|
||||||
if (queued > MAX_QUEUED_MSG_NUM || queuedSize > MAX_QUEUED_MSG_SIZE) {
|
if (queued > MAX_QUEUED_MSG_NUM || queuedSize > MAX_QUEUED_MSG_SIZE) {
|
||||||
int32_t ms = (queued / MAX_QUEUED_MSG_NUM) * 10 + 3;
|
int32_t ms = (queued / MAX_QUEUED_MSG_NUM) * 10 + 3;
|
||||||
|
|
@ -330,7 +330,7 @@ void vnodeFreeFromWQueue(void *vparam, SVWriteMsg *pWrite) {
|
||||||
SVnodeObj *pVnode = vparam;
|
SVnodeObj *pVnode = vparam;
|
||||||
if (pVnode) {
|
if (pVnode) {
|
||||||
int32_t queued = atomic_sub_fetch_32(&pVnode->queuedWMsg, 1);
|
int32_t queued = atomic_sub_fetch_32(&pVnode->queuedWMsg, 1);
|
||||||
int64_t queuedSize = atomic_sub_fetch_64(&pVnode->queuedWMsgSize, pWrite->pHead.len);
|
int64_t queuedSize = atomic_sub_fetch_64(&pVnode->queuedWMsgSize, pWrite->walHead.len);
|
||||||
|
|
||||||
vTrace("vgId:%d, msg:%p, app:%p, free from vwqueue, queued:%d size:%" PRId64, pVnode->vgId, pWrite,
|
vTrace("vgId:%d, msg:%p, app:%p, free from vwqueue, queued:%d size:%" PRId64, pVnode->vgId, pWrite,
|
||||||
pWrite->rpcMsg.ahandle, queued, queuedSize);
|
pWrite->rpcMsg.ahandle, queued, queuedSize);
|
||||||
|
|
|
||||||
|
|
@ -36,9 +36,16 @@ static int32_t walInitObj(SWal *pWal);
|
||||||
static void walFreeObj(void *pWal);
|
static void walFreeObj(void *pWal);
|
||||||
|
|
||||||
int32_t walInit() {
|
int32_t walInit() {
|
||||||
|
int32_t code = 0;
|
||||||
tsWal.refId = taosOpenRef(TSDB_MIN_VNODES, walFreeObj);
|
tsWal.refId = taosOpenRef(TSDB_MIN_VNODES, walFreeObj);
|
||||||
|
|
||||||
int32_t code = walCreateThread();
|
code = pthread_mutex_init(&tsWal.mutex, NULL);
|
||||||
|
if (code) {
|
||||||
|
wError("failed to init wal mutex since %s", tstrerror(code));
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
code = walCreateThread();
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
wError("failed to init wal module since %s", tstrerror(code));
|
wError("failed to init wal module since %s", tstrerror(code));
|
||||||
return code;
|
return code;
|
||||||
|
|
@ -51,6 +58,7 @@ int32_t walInit() {
|
||||||
void walCleanUp() {
|
void walCleanUp() {
|
||||||
walStopThread();
|
walStopThread();
|
||||||
taosCloseRef(tsWal.refId);
|
taosCloseRef(tsWal.refId);
|
||||||
|
pthread_mutex_destroy(&tsWal.mutex);
|
||||||
wInfo("wal module is cleaned up");
|
wInfo("wal module is cleaned up");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -183,10 +191,15 @@ static void walFsyncAll() {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *walThreadFunc(void *param) {
|
static void *walThreadFunc(void *param) {
|
||||||
|
int stop = 0;
|
||||||
while (1) {
|
while (1) {
|
||||||
walUpdateSeq();
|
walUpdateSeq();
|
||||||
walFsyncAll();
|
walFsyncAll();
|
||||||
if (tsWal.stop) break;
|
|
||||||
|
pthread_mutex_lock(&tsWal.mutex);
|
||||||
|
stop = tsWal.stop;
|
||||||
|
pthread_mutex_unlock(&tsWal.mutex);
|
||||||
|
if (stop) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -209,7 +222,10 @@ static int32_t walCreateThread() {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void walStopThread() {
|
static void walStopThread() {
|
||||||
|
pthread_mutex_lock(&tsWal.mutex);
|
||||||
tsWal.stop = 1;
|
tsWal.stop = 1;
|
||||||
|
pthread_mutex_unlock(&tsWal.mutex);
|
||||||
|
|
||||||
if (taosCheckPthreadValid(tsWal.thread)) {
|
if (taosCheckPthreadValid(tsWal.thread)) {
|
||||||
pthread_join(tsWal.thread, NULL);
|
pthread_join(tsWal.thread, NULL);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,13 +8,13 @@ IF (TD_LINUX)
|
||||||
ADD_EXECUTABLE(subscribe subscribe.c)
|
ADD_EXECUTABLE(subscribe subscribe.c)
|
||||||
TARGET_LINK_LIBRARIES(subscribe taos_static trpc tutil pthread )
|
TARGET_LINK_LIBRARIES(subscribe taos_static trpc tutil pthread )
|
||||||
ADD_EXECUTABLE(epoll epoll.c)
|
ADD_EXECUTABLE(epoll epoll.c)
|
||||||
TARGET_LINK_LIBRARIES(epoll taos_static trpc tutil pthread )
|
TARGET_LINK_LIBRARIES(epoll taos_static trpc tutil pthread lua)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
IF (TD_DARWIN)
|
IF (TD_DARWIN)
|
||||||
INCLUDE_DIRECTORIES(. ${TD_COMMUNITY_DIR}/src/inc ${TD_COMMUNITY_DIR}/src/client/inc ${TD_COMMUNITY_DIR}/inc)
|
INCLUDE_DIRECTORIES(. ${TD_COMMUNITY_DIR}/src/inc ${TD_COMMUNITY_DIR}/src/client/inc ${TD_COMMUNITY_DIR}/inc)
|
||||||
AUX_SOURCE_DIRECTORY(. SRC)
|
AUX_SOURCE_DIRECTORY(. SRC)
|
||||||
ADD_EXECUTABLE(demo demo.c)
|
ADD_EXECUTABLE(demo demo.c)
|
||||||
TARGET_LINK_LIBRARIES(demo taos_static trpc tutil pthread )
|
TARGET_LINK_LIBRARIES(demo taos_static trpc tutil pthread lua)
|
||||||
ADD_EXECUTABLE(epoll epoll.c)
|
ADD_EXECUTABLE(epoll epoll.c)
|
||||||
TARGET_LINK_LIBRARIES(epoll taos_static trpc tutil pthread )
|
TARGET_LINK_LIBRARIES(epoll taos_static trpc tutil pthread lua)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -352,7 +352,7 @@ python3 ./test.py -f alter/alter_debugFlag.py
|
||||||
python3 ./test.py -f query/queryBetweenAnd.py
|
python3 ./test.py -f query/queryBetweenAnd.py
|
||||||
python3 ./test.py -f tag_lite/alter_tag.py
|
python3 ./test.py -f tag_lite/alter_tag.py
|
||||||
|
|
||||||
python3 test.py -f tools/taosdemoAllTest/taosdemoTestInsertWithJson.py
|
# python3 test.py -f tools/taosdemoAllTest/taosdemoTestInsertWithJson.py
|
||||||
python3 test.py -f tools/taosdemoAllTest/taosdemoTestQueryWithJson.py
|
python3 test.py -f tools/taosdemoAllTest/taosdemoTestQueryWithJson.py
|
||||||
python3 test.py -f tools/taosdemoAllTest/TD-4985/query-limit-offset.py
|
python3 test.py -f tools/taosdemoAllTest/TD-4985/query-limit-offset.py
|
||||||
python3 ./test.py -f tag_lite/drop_auto_create.py
|
python3 ./test.py -f tag_lite/drop_auto_create.py
|
||||||
|
|
|
||||||
|
|
@ -160,22 +160,23 @@ class TDTestCase:
|
||||||
tdSql.checkData(0,9,9.000000000)
|
tdSql.checkData(0,9,9.000000000)
|
||||||
tdSql.checkData(0,10,'2020-09-13 20:26:40.009')
|
tdSql.checkData(0,10,'2020-09-13 20:26:40.009')
|
||||||
|
|
||||||
|
# incorrect result, not support nest > 2
|
||||||
sql = '''select last_row(*) from
|
sql = '''select last_row(*) from
|
||||||
((select * from table_0) union all
|
((select * from table_0) union all
|
||||||
(select * from table_1) union all
|
(select * from table_1) union all
|
||||||
(select * from table_2));'''
|
(select * from table_2));'''
|
||||||
tdSql.query(sql)
|
tdSql.error(sql)
|
||||||
tdSql.checkRows(1)
|
#tdSql.checkRows(1)
|
||||||
tdSql.checkData(0,1,self.num-1)
|
#tdSql.checkData(0,1,self.num-1)
|
||||||
tdSql.checkData(0,2,self.num-1)
|
#tdSql.checkData(0,2,self.num-1)
|
||||||
tdSql.checkData(0,3,self.num-1)
|
#tdSql.checkData(0,3,self.num-1)
|
||||||
tdSql.checkData(0,4,self.num-1)
|
#tdSql.checkData(0,4,self.num-1)
|
||||||
tdSql.checkData(0,5,'False')
|
#tdSql.checkData(0,5,'False')
|
||||||
tdSql.checkData(0,6,'binary.9')
|
#tdSql.checkData(0,6,'binary.9')
|
||||||
tdSql.checkData(0,7,'nchar.9')
|
#tdSql.checkData(0,7,'nchar.9')
|
||||||
tdSql.checkData(0,8,9.00000)
|
#tdSql.checkData(0,8,9.00000)
|
||||||
tdSql.checkData(0,9,9.000000000)
|
#tdSql.checkData(0,9,9.000000000)
|
||||||
tdSql.checkData(0,10,'2020-09-13 20:26:40.009')
|
#tdSql.checkData(0,10,'2020-09-13 20:26:40.009')
|
||||||
|
|
||||||
# bug 5055
|
# bug 5055
|
||||||
# sql = '''select last_row(*) from
|
# sql = '''select last_row(*) from
|
||||||
|
|
@ -189,18 +190,18 @@ class TDTestCase:
|
||||||
((select last_row(*) from table_0) union all
|
((select last_row(*) from table_0) union all
|
||||||
(select last_row(*) from table_1) union all
|
(select last_row(*) from table_1) union all
|
||||||
(select last_row(*) from table_2));'''
|
(select last_row(*) from table_2));'''
|
||||||
tdSql.query(sql)
|
tdSql.error(sql)
|
||||||
tdSql.checkRows(1)
|
#tdSql.checkRows(1)
|
||||||
tdSql.checkData(0,1,self.num-1)
|
#tdSql.checkData(0,1,self.num-1)
|
||||||
tdSql.checkData(0,2,self.num-1)
|
#tdSql.checkData(0,2,self.num-1)
|
||||||
tdSql.checkData(0,3,self.num-1)
|
#tdSql.checkData(0,3,self.num-1)
|
||||||
tdSql.checkData(0,4,self.num-1)
|
#tdSql.checkData(0,4,self.num-1)
|
||||||
tdSql.checkData(0,5,'False')
|
#tdSql.checkData(0,5,'False')
|
||||||
tdSql.checkData(0,6,'binary.9')
|
#tdSql.checkData(0,6,'binary.9')
|
||||||
tdSql.checkData(0,7,'nchar.9')
|
#tdSql.checkData(0,7,'nchar.9')
|
||||||
tdSql.checkData(0,8,9.00000)
|
#tdSql.checkData(0,8,9.00000)
|
||||||
tdSql.checkData(0,9,9.000000000)
|
#tdSql.checkData(0,9,9.000000000)
|
||||||
tdSql.checkData(0,10,'2020-09-13 20:26:40.009')
|
#tdSql.checkData(0,10,'2020-09-13 20:26:40.009')
|
||||||
|
|
||||||
# bug 5055
|
# bug 5055
|
||||||
# sql = '''select last_row(*) from
|
# sql = '''select last_row(*) from
|
||||||
|
|
@ -214,18 +215,18 @@ class TDTestCase:
|
||||||
((select * from table_0 limit 5 offset 5) union all
|
((select * from table_0 limit 5 offset 5) union all
|
||||||
(select * from table_1 limit 5 offset 5) union all
|
(select * from table_1 limit 5 offset 5) union all
|
||||||
(select * from regular_table_1 limit 5 offset 5));'''
|
(select * from regular_table_1 limit 5 offset 5));'''
|
||||||
tdSql.query(sql)
|
tdSql.error(sql)
|
||||||
tdSql.checkRows(1)
|
#tdSql.checkRows(1)
|
||||||
tdSql.checkData(0,1,self.num-1)
|
#tdSql.checkData(0,1,self.num-1)
|
||||||
tdSql.checkData(0,2,self.num-1)
|
#tdSql.checkData(0,2,self.num-1)
|
||||||
tdSql.checkData(0,3,self.num-1)
|
#tdSql.checkData(0,3,self.num-1)
|
||||||
tdSql.checkData(0,4,self.num-1)
|
#tdSql.checkData(0,4,self.num-1)
|
||||||
tdSql.checkData(0,5,'False')
|
#tdSql.checkData(0,5,'False')
|
||||||
tdSql.checkData(0,6,'binary.9')
|
#tdSql.checkData(0,6,'binary.9')
|
||||||
tdSql.checkData(0,7,'nchar.9')
|
#tdSql.checkData(0,7,'nchar.9')
|
||||||
tdSql.checkData(0,8,9.00000)
|
#tdSql.checkData(0,8,9.00000)
|
||||||
tdSql.checkData(0,9,9.000000000)
|
#tdSql.checkData(0,9,9.000000000)
|
||||||
tdSql.checkData(0,10,'2020-09-13 20:26:40.009')
|
#tdSql.checkData(0,10,'2020-09-13 20:26:40.009')
|
||||||
|
|
||||||
|
|
||||||
sql = '''select last_row(*) from
|
sql = '''select last_row(*) from
|
||||||
|
|
|
||||||
|
|
@ -77,6 +77,7 @@ class taosdemoQueryPerformace:
|
||||||
sql = "select last(*) from meters"
|
sql = "select last(*) from meters"
|
||||||
tableid = 9
|
tableid = 9
|
||||||
cursor.execute("create table if not exists %s%d using %s tags(%d, '%s')" % (self.tbPerfix, tableid, self.stbName, tableid, sql))
|
cursor.execute("create table if not exists %s%d using %s tags(%d, '%s')" % (self.tbPerfix, tableid, self.stbName, tableid, sql))
|
||||||
|
|
||||||
cursor.close()
|
cursor.close()
|
||||||
|
|
||||||
def query(self):
|
def query(self):
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ class TDTestCase:
|
||||||
|
|
||||||
print("==============step3")
|
print("==============step3")
|
||||||
tdLog.info("check int & binary")
|
tdLog.info("check int & binary")
|
||||||
tdSql.error("create table anal2 (ts timestamp ,i binary(16371),j int)")
|
# tdSql.error("create table anal2 (ts timestamp ,i binary(16371),j int)")
|
||||||
tdSql.execute("create table anal2 (ts timestamp ,i binary(16370),j int)")
|
tdSql.execute("create table anal2 (ts timestamp ,i binary(16370),j int)")
|
||||||
tdSql.execute("create table anal3 (ts timestamp ,i binary(16366), j int, k int)")
|
tdSql.execute("create table anal3 (ts timestamp ,i binary(16366), j int, k int)")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||||
|
1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||||
|
2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||||
|
3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||||
|
4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||||
|
5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||||
|
6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||||
|
7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||||
|
8,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||||
|
9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||||
|
|
|
@ -0,0 +1,112 @@
|
||||||
|
{
|
||||||
|
"filetype": "insert",
|
||||||
|
"cfgdir": "/etc/taos",
|
||||||
|
"host": "127.0.0.1",
|
||||||
|
"port": 6030,
|
||||||
|
"user": "root",
|
||||||
|
"password": "taosdata",
|
||||||
|
"thread_count": 10,
|
||||||
|
"thread_count_create_tbl": 10,
|
||||||
|
"result_file": "./insert_res.txt",
|
||||||
|
"confirm_parameter_prompt": "no",
|
||||||
|
"insert_interval": 0,
|
||||||
|
"interlace_rows": 10,
|
||||||
|
"num_of_records_per_req": 1,
|
||||||
|
"max_sql_len": 102400000,
|
||||||
|
"databases": [{
|
||||||
|
"dbinfo": {
|
||||||
|
"name": "db",
|
||||||
|
"drop": "yes",
|
||||||
|
"replica": 1,
|
||||||
|
"days": 10,
|
||||||
|
"cache": 50,
|
||||||
|
"blocks": 8,
|
||||||
|
"precision": "ms",
|
||||||
|
"keep": 365,
|
||||||
|
"minRows": 100,
|
||||||
|
"maxRows": 4096,
|
||||||
|
"comp":2,
|
||||||
|
"walLevel":1,
|
||||||
|
"cachelast":0,
|
||||||
|
"quorum":1,
|
||||||
|
"fsync":3000,
|
||||||
|
"update": 0
|
||||||
|
},
|
||||||
|
"super_tables": [{
|
||||||
|
"name": "stb_old",
|
||||||
|
"child_table_exists":"no",
|
||||||
|
"childtable_count": 10,
|
||||||
|
"childtable_prefix": "stb_old_",
|
||||||
|
"auto_create_table": "no",
|
||||||
|
"batch_create_tbl_num": 5,
|
||||||
|
"data_source": "sample",
|
||||||
|
"insert_mode": "taosc",
|
||||||
|
"insert_rows": 100,
|
||||||
|
"childtable_limit": 0,
|
||||||
|
"childtable_offset":0,
|
||||||
|
"multi_thread_write_one_tbl": "no",
|
||||||
|
"interlace_rows": 0,
|
||||||
|
"insert_interval":0,
|
||||||
|
"max_sql_len": 1024000,
|
||||||
|
"disorder_ratio": 0,
|
||||||
|
"disorder_range": 1000,
|
||||||
|
"timestamp_step": 1,
|
||||||
|
"start_timestamp": "2020-10-01 00:00:00.000",
|
||||||
|
"sample_format": "csv",
|
||||||
|
"sample_file": "./tools/taosdemoAllTest/TD-5213/insertSigcolumnsNum4096.csv",
|
||||||
|
"tags_file": "",
|
||||||
|
"columns": [{"type": "INT","count":4000}, {"type": "BINARY", "len": 16, "count":1}],
|
||||||
|
"tags": [{"type": "TINYINT", "count":2}, {"type": "BINARY", "len": 16, "count":1}]
|
||||||
|
},{
|
||||||
|
"name": "stb_new",
|
||||||
|
"child_table_exists":"no",
|
||||||
|
"childtable_count": 10,
|
||||||
|
"childtable_prefix": "stb_new_",
|
||||||
|
"auto_create_table": "no",
|
||||||
|
"batch_create_tbl_num": 5,
|
||||||
|
"data_source": "rand",
|
||||||
|
"insert_mode": "taosc",
|
||||||
|
"insert_rows": 100,
|
||||||
|
"childtable_limit": 0,
|
||||||
|
"childtable_offset":0,
|
||||||
|
"multi_thread_write_one_tbl": "no",
|
||||||
|
"interlace_rows": 0,
|
||||||
|
"insert_interval":0,
|
||||||
|
"max_sql_len": 1024000,
|
||||||
|
"disorder_ratio": 0,
|
||||||
|
"disorder_range": 1000,
|
||||||
|
"timestamp_step": 1,
|
||||||
|
"start_timestamp": "2020-10-01 00:00:00.000",
|
||||||
|
"sample_format": "csv",
|
||||||
|
"sample_file": "./tools/taosdemoAllTest/sample.csv",
|
||||||
|
"tags_file": "",
|
||||||
|
"columns": [{"type": "DOUBLE","count":1020}],
|
||||||
|
"tags": [{"type": "TINYINT", "count":2}, {"type": "BINARY", "len": 16, "count":1}]
|
||||||
|
},{
|
||||||
|
"name": "stb_int",
|
||||||
|
"child_table_exists":"no",
|
||||||
|
"childtable_count": 10,
|
||||||
|
"childtable_prefix": "stb_int_",
|
||||||
|
"auto_create_table": "no",
|
||||||
|
"batch_create_tbl_num": 5,
|
||||||
|
"data_source": "rand",
|
||||||
|
"insert_mode": "taosc",
|
||||||
|
"insert_rows": 100,
|
||||||
|
"childtable_limit": 0,
|
||||||
|
"childtable_offset":0,
|
||||||
|
"multi_thread_write_one_tbl": "no",
|
||||||
|
"interlace_rows": 0,
|
||||||
|
"insert_interval":0,
|
||||||
|
"max_sql_len": 1024000,
|
||||||
|
"disorder_ratio": 0,
|
||||||
|
"disorder_range": 1000,
|
||||||
|
"timestamp_step": 1,
|
||||||
|
"start_timestamp": "2020-10-01 00:00:00.000",
|
||||||
|
"sample_format": "csv",
|
||||||
|
"sample_file": "./tools/taosdemoAllTest/sample.csv",
|
||||||
|
"tags_file": "",
|
||||||
|
"columns": [{"type": "int","count":1020}],
|
||||||
|
"tags": [{"type": "TINYINT", "count":2}, {"type": "BINARY", "len": 16, "count":1}]
|
||||||
|
}]
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,137 @@
|
||||||
|
###################################################################
|
||||||
|
# Copyright (c) 2016 by TAOS Technologies, Inc.
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# This file is proprietary and confidential to TAOS Technologies.
|
||||||
|
# No part of this file may be reproduced, stored, transmitted,
|
||||||
|
# disclosed or used in any form or by any means other than as
|
||||||
|
# expressly provided by the written permission from Jianhui Tao
|
||||||
|
#
|
||||||
|
###################################################################
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
from util.log import *
|
||||||
|
from util.cases import *
|
||||||
|
from util.sql import *
|
||||||
|
from util.dnodes import *
|
||||||
|
|
||||||
|
|
||||||
|
class TDTestCase:
|
||||||
|
def init(self, conn, logSql):
|
||||||
|
tdLog.debug("start to execute %s" % __file__)
|
||||||
|
tdSql.init(conn.cursor(), logSql)
|
||||||
|
|
||||||
|
def getBuildPath(self):
|
||||||
|
selfPath = os.path.dirname(os.path.realpath(__file__))
|
||||||
|
|
||||||
|
if ("community" in selfPath):
|
||||||
|
projPath = selfPath[:selfPath.find("community")]
|
||||||
|
else:
|
||||||
|
projPath = selfPath[:selfPath.find("tests")]
|
||||||
|
|
||||||
|
for root, dirs, files in os.walk(projPath):
|
||||||
|
if ("taosd" in files):
|
||||||
|
rootRealPath = os.path.dirname(os.path.realpath(root))
|
||||||
|
if ("packaging" not in rootRealPath):
|
||||||
|
buildPath = root[:len(root)-len("/build/bin")]
|
||||||
|
break
|
||||||
|
return buildPath
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
buildPath = self.getBuildPath()
|
||||||
|
if (buildPath == ""):
|
||||||
|
tdLog.exit("taosd not found!")
|
||||||
|
else:
|
||||||
|
tdLog.info("taosd found in %s" % buildPath)
|
||||||
|
binPath = buildPath+ "/build/bin/"
|
||||||
|
|
||||||
|
# insert: create one or mutiple tables per sql and insert multiple rows per sql
|
||||||
|
# test case for https://jira.taosdata.com:18080/browse/TD-5213
|
||||||
|
os.system("%staosdemo -f tools/taosdemoAllTest/TD-5213/insertSigcolumnsNum4096.json -y " % binPath)
|
||||||
|
tdSql.execute("use db")
|
||||||
|
tdSql.query("select count (tbname) from stb_old")
|
||||||
|
tdSql.checkData(0, 0, 10)
|
||||||
|
|
||||||
|
# tdSql.query("select * from stb_old")
|
||||||
|
# tdSql.checkRows(10)
|
||||||
|
# tdSql.checkCols(1024)
|
||||||
|
|
||||||
|
# tdSql.query("select count (tbname) from stb_new")
|
||||||
|
# tdSql.checkData(0, 0, 10)
|
||||||
|
|
||||||
|
# tdSql.query("select * from stb_new")
|
||||||
|
# tdSql.checkRows(10)
|
||||||
|
# tdSql.checkCols(4096)
|
||||||
|
|
||||||
|
# tdLog.info("stop dnode to commit data to disk")
|
||||||
|
# tdDnodes.stop(1)
|
||||||
|
# tdDnodes.start(1)
|
||||||
|
|
||||||
|
#regular table
|
||||||
|
sql = "create table tb(ts timestamp, "
|
||||||
|
for i in range(1022):
|
||||||
|
sql += "col%d binary(14), " % (i + 1)
|
||||||
|
sql += "col1023 binary(22))"
|
||||||
|
tdSql.execute(sql)
|
||||||
|
|
||||||
|
for i in range(4):
|
||||||
|
sql = "insert into tb values(%d, "
|
||||||
|
for j in range(1022):
|
||||||
|
str = "'%s', " % self.get_random_string(14)
|
||||||
|
sql += str
|
||||||
|
sql += "'%s')" % self.get_random_string(22)
|
||||||
|
tdSql.execute(sql % (self.ts + i))
|
||||||
|
|
||||||
|
time.sleep(10)
|
||||||
|
tdSql.query("select count(*) from tb")
|
||||||
|
tdSql.checkData(0, 0, 4)
|
||||||
|
|
||||||
|
tdDnodes.stop(1)
|
||||||
|
tdDnodes.start(1)
|
||||||
|
|
||||||
|
time.sleep(1)
|
||||||
|
tdSql.query("select count(*) from tb")
|
||||||
|
tdSql.checkData(0, 0, 4)
|
||||||
|
|
||||||
|
|
||||||
|
sql = "create table tb1(ts timestamp, "
|
||||||
|
for i in range(4094):
|
||||||
|
sql += "col%d binary(14), " % (i + 1)
|
||||||
|
sql += "col4095 binary(22))"
|
||||||
|
tdSql.execute(sql)
|
||||||
|
|
||||||
|
for i in range(4):
|
||||||
|
sql = "insert into tb1 values(%d, "
|
||||||
|
for j in range(4094):
|
||||||
|
str = "'%s', " % self.get_random_string(14)
|
||||||
|
sql += str
|
||||||
|
sql += "'%s')" % self.get_random_string(22)
|
||||||
|
tdSql.execute(sql % (self.ts + i))
|
||||||
|
|
||||||
|
time.sleep(10)
|
||||||
|
tdSql.query("select count(*) from tb1")
|
||||||
|
tdSql.checkData(0, 0, 4)
|
||||||
|
|
||||||
|
tdDnodes.stop(1)
|
||||||
|
tdDnodes.start(1)
|
||||||
|
|
||||||
|
time.sleep(1)
|
||||||
|
tdSql.query("select count(*) from tb1")
|
||||||
|
tdSql.checkData(0, 0, 4)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#os.system("rm -rf tools/taosdemoAllTest/TD-5213/insertSigcolumnsNum4096.py.sql")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
tdSql.close()
|
||||||
|
tdLog.success("%s successfully executed" % __file__)
|
||||||
|
|
||||||
|
|
||||||
|
tdCases.addWindows(__file__, TDTestCase())
|
||||||
|
tdCases.addLinux(__file__, TDTestCase())
|
||||||
|
|
@ -19,7 +19,6 @@ import json
|
||||||
from util.log import tdLog
|
from util.log import tdLog
|
||||||
from util.sql import tdSql
|
from util.sql import tdSql
|
||||||
|
|
||||||
|
|
||||||
class taosdemoPerformace:
|
class taosdemoPerformace:
|
||||||
def __init__(self, commitID, dbName):
|
def __init__(self, commitID, dbName):
|
||||||
self.commitID = commitID
|
self.commitID = commitID
|
||||||
|
|
@ -124,6 +123,7 @@ class taosdemoPerformace:
|
||||||
|
|
||||||
def insertData(self):
|
def insertData(self):
|
||||||
tdSql.prepare()
|
tdSql.prepare()
|
||||||
|
|
||||||
buildPath = self.getBuildPath()
|
buildPath = self.getBuildPath()
|
||||||
if (buildPath == ""):
|
if (buildPath == ""):
|
||||||
tdLog.exit("taosdemo not found!")
|
tdLog.exit("taosdemo not found!")
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,6 @@ class TDTestCase:
|
||||||
# 6--days,7--keep0,keep1,keep, 12--block,
|
# 6--days,7--keep0,keep1,keep, 12--block,
|
||||||
|
|
||||||
isCommunity = self.checkCommunity()
|
isCommunity = self.checkCommunity()
|
||||||
|
|
||||||
print("iscommunity: %d" % isCommunity)
|
print("iscommunity: %d" % isCommunity)
|
||||||
for i in range(len(dbresult)):
|
for i in range(len(dbresult)):
|
||||||
if dbresult[i][0] == 'db':
|
if dbresult[i][0] == 'db':
|
||||||
|
|
|
||||||
|
|
@ -1132,4 +1132,19 @@ if $data92 != t1 then
|
||||||
return -1
|
return -1
|
||||||
endi
|
endi
|
||||||
|
|
||||||
|
print =========================>TD-5190
|
||||||
|
sql select stddev(f1) from st1 where ts>'2021-07-01 1:1:1' and ts<'2021-07-30 00:00:00' interval(1d) fill(NULL);
|
||||||
|
if $rows != 29 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
if $data00 != @21-07-01 00:00:00.000@ then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
if $data01 != NULL then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
|
||||||
sql select derivative(test_column_alias_name, 1s, 0) from (select avg(k) test_column_alias_name from t1 interval(1s));
|
sql select derivative(test_column_alias_name, 1s, 0) from (select avg(k) test_column_alias_name from t1 interval(1s));
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ run general/parser/create_tb.sim
|
||||||
run general/parser/dbtbnameValidate.sim
|
run general/parser/dbtbnameValidate.sim
|
||||||
run general/parser/fill.sim
|
run general/parser/fill.sim
|
||||||
run general/parser/fill_stb.sim
|
run general/parser/fill_stb.sim
|
||||||
run general/parser/fill_us.sim
|
#run general/parser/fill_us.sim #
|
||||||
run general/parser/first_last.sim
|
run general/parser/first_last.sim
|
||||||
run general/parser/import_commit1.sim
|
run general/parser/import_commit1.sim
|
||||||
run general/parser/import_commit2.sim
|
run general/parser/import_commit2.sim
|
||||||
|
|
@ -39,7 +39,6 @@ run general/parser/slimit1.sim
|
||||||
run general/parser/slimit_alter_tags.sim
|
run general/parser/slimit_alter_tags.sim
|
||||||
run general/parser/tbnameIn.sim
|
run general/parser/tbnameIn.sim
|
||||||
run general/parser/join.sim
|
run general/parser/join.sim
|
||||||
#run general/parser/join_multitables.sim
|
|
||||||
run general/parser/join_multivnode.sim
|
run general/parser/join_multivnode.sim
|
||||||
run general/parser/join_manyblocks.sim
|
run general/parser/join_manyblocks.sim
|
||||||
run general/parser/projection_limit_offset.sim
|
run general/parser/projection_limit_offset.sim
|
||||||
|
|
@ -61,5 +60,9 @@ run general/parser/slimit_alter_tags.sim
|
||||||
run general/parser/binary_escapeCharacter.sim
|
run general/parser/binary_escapeCharacter.sim
|
||||||
run general/parser/between_and.sim
|
run general/parser/between_and.sim
|
||||||
run general/parser/last_cache.sim
|
run general/parser/last_cache.sim
|
||||||
|
run general/parser/slimit_alter_tags.sim
|
||||||
|
run general/parser/udf.sim
|
||||||
|
run general/parser/udf_dll.sim
|
||||||
|
run general/parser/udf_dll_stable.sim
|
||||||
run general/parser/nestquery.sim
|
run general/parser/nestquery.sim
|
||||||
run general/parser/precision_ns.sim
|
run general/parser/precision_ns.sim
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue