Merge branch '3.0' into feature/3.0_glzhao
This commit is contained in:
commit
424ff4a685
|
@ -46,7 +46,7 @@ ENDIF ()
|
|||
|
||||
IF (TD_WINDOWS)
|
||||
MESSAGE("${Yellow} set compiler flag for Windows! ${ColourReset}")
|
||||
SET(COMMON_FLAGS "/w /D_WIN32")
|
||||
SET(COMMON_FLAGS "/w /D_WIN32 /Zi")
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /MANIFEST:NO")
|
||||
# IF (MSVC AND (MSVC_VERSION GREATER_EQUAL 1900))
|
||||
# SET(COMMON_FLAGS "${COMMON_FLAGS} /Wv:18")
|
||||
|
@ -71,8 +71,8 @@ ELSE ()
|
|||
ENDIF ()
|
||||
|
||||
IF (${SANITIZER} MATCHES "true")
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror -Werror=return-type -fPIC -gdwarf-2 -fsanitize=address -fsanitize=undefined -fsanitize-recover=all -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fno-sanitize=null -fno-sanitize=alignment -static-libasan -g3")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wno-literal-suffix -Werror=return-type -fPIC -gdwarf-2 -fsanitize=address -fsanitize=undefined -fsanitize-recover=all -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fno-sanitize=null -fno-sanitize=alignment -static-libasan -g3")
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror -Werror=return-type -fPIC -gdwarf-2 -fsanitize=address -fsanitize=undefined -fsanitize-recover=all -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fno-sanitize=null -fno-sanitize=alignment -g3")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wno-literal-suffix -Werror=return-type -fPIC -gdwarf-2 -fsanitize=address -fsanitize=undefined -fsanitize-recover=all -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fno-sanitize=null -fno-sanitize=alignment -g3")
|
||||
MESSAGE(STATUS "Will compile with Address Sanitizer!")
|
||||
ELSE ()
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror -Werror=return-type -fPIC -gdwarf-2 -g3")
|
||||
|
|
|
@ -100,8 +100,10 @@ endif(${BUILD_WITH_NURAFT})
|
|||
|
||||
# addr2line
|
||||
if(${BUILD_ADDR2LINE})
|
||||
cat("${TD_SUPPORT_DIR}/libdwarf_CMakeLists.txt.in" ${CONTRIB_TMP_FILE})
|
||||
cat("${TD_SUPPORT_DIR}/addr2line_CMakeLists.txt.in" ${CONTRIB_TMP_FILE})
|
||||
if(NOT ${TD_WINDOWS})
|
||||
cat("${TD_SUPPORT_DIR}/libdwarf_CMakeLists.txt.in" ${CONTRIB_TMP_FILE})
|
||||
cat("${TD_SUPPORT_DIR}/addr2line_CMakeLists.txt.in" ${CONTRIB_TMP_FILE})
|
||||
endif(NOT ${TD_WINDOWS})
|
||||
endif(${BUILD_ADDR2LINE})
|
||||
|
||||
# download dependencies
|
||||
|
@ -335,45 +337,47 @@ endif(${BUILD_WITH_SQLITE})
|
|||
|
||||
# addr2line
|
||||
if(${BUILD_ADDR2LINE})
|
||||
check_include_file( "sys/types.h" HAVE_SYS_TYPES_H)
|
||||
check_include_file( "sys/stat.h" HAVE_SYS_STAT_H )
|
||||
check_include_file( "inttypes.h" HAVE_INTTYPES_H )
|
||||
check_include_file( "stddef.h" HAVE_STDDEF_H )
|
||||
check_include_file( "stdlib.h" HAVE_STDLIB_H )
|
||||
check_include_file( "string.h" HAVE_STRING_H )
|
||||
check_include_file( "memory.h" HAVE_MEMORY_H )
|
||||
check_include_file( "strings.h" HAVE_STRINGS_H )
|
||||
check_include_file( "stdint.h" HAVE_STDINT_H )
|
||||
check_include_file( "unistd.h" HAVE_UNISTD_H )
|
||||
check_include_file( "sgidefs.h" HAVE_SGIDEFS_H )
|
||||
check_include_file( "stdafx.h" HAVE_STDAFX_H )
|
||||
check_include_file( "elf.h" HAVE_ELF_H )
|
||||
check_include_file( "libelf.h" HAVE_LIBELF_H )
|
||||
check_include_file( "libelf/libelf.h" HAVE_LIBELF_LIBELF_H)
|
||||
check_include_file( "alloca.h" HAVE_ALLOCA_H )
|
||||
check_include_file( "elfaccess.h" HAVE_ELFACCESS_H)
|
||||
check_include_file( "sys/elf_386.h" HAVE_SYS_ELF_386_H )
|
||||
check_include_file( "sys/elf_amd64.h" HAVE_SYS_ELF_AMD64_H)
|
||||
check_include_file( "sys/elf_sparc.h" HAVE_SYS_ELF_SPARC_H)
|
||||
check_include_file( "sys/ia64/elf.h" HAVE_SYS_IA64_ELF_H )
|
||||
set(VERSION 0.3.1)
|
||||
set(PACKAGE_VERSION "\"${VERSION}\"")
|
||||
configure_file(libdwarf/cmake/config.h.cmake config.h)
|
||||
file(GLOB_RECURSE LIBDWARF_SOURCES "libdwarf/src/lib/libdwarf/*.c")
|
||||
add_library(libdwarf STATIC ${LIBDWARF_SOURCES})
|
||||
set_target_properties(libdwarf PROPERTIES OUTPUT_NAME "libdwarf")
|
||||
if(HAVE_LIBELF_H OR HAVE_LIBELF_LIBELF_H)
|
||||
target_link_libraries(libdwarf PUBLIC libelf)
|
||||
endif()
|
||||
target_include_directories(libdwarf SYSTEM PUBLIC "libdwarf/src/lib/libdwarf" ${CMAKE_CURRENT_BINARY_DIR})
|
||||
file(READ "addr2line/addr2line.c" ADDR2LINE_CONTENT)
|
||||
string(REPLACE "static int" "int" ADDR2LINE_CONTENT "${ADDR2LINE_CONTENT}")
|
||||
string(REPLACE "static void" "void" ADDR2LINE_CONTENT "${ADDR2LINE_CONTENT}")
|
||||
string(REPLACE "main(" "main_addr2line(" ADDR2LINE_CONTENT "${ADDR2LINE_CONTENT}")
|
||||
file(WRITE "addr2line/addr2line.c" "${ADDR2LINE_CONTENT}")
|
||||
add_library(addr2line STATIC "addr2line/addr2line.c")
|
||||
target_link_libraries(addr2line PUBLIC libdwarf dl z)
|
||||
target_include_directories(addr2line PUBLIC "libdwarf/src/lib/libdwarf" )
|
||||
if(NOT ${TD_WINDOWS})
|
||||
check_include_file( "sys/types.h" HAVE_SYS_TYPES_H)
|
||||
check_include_file( "sys/stat.h" HAVE_SYS_STAT_H )
|
||||
check_include_file( "inttypes.h" HAVE_INTTYPES_H )
|
||||
check_include_file( "stddef.h" HAVE_STDDEF_H )
|
||||
check_include_file( "stdlib.h" HAVE_STDLIB_H )
|
||||
check_include_file( "string.h" HAVE_STRING_H )
|
||||
check_include_file( "memory.h" HAVE_MEMORY_H )
|
||||
check_include_file( "strings.h" HAVE_STRINGS_H )
|
||||
check_include_file( "stdint.h" HAVE_STDINT_H )
|
||||
check_include_file( "unistd.h" HAVE_UNISTD_H )
|
||||
check_include_file( "sgidefs.h" HAVE_SGIDEFS_H )
|
||||
check_include_file( "stdafx.h" HAVE_STDAFX_H )
|
||||
check_include_file( "elf.h" HAVE_ELF_H )
|
||||
check_include_file( "libelf.h" HAVE_LIBELF_H )
|
||||
check_include_file( "libelf/libelf.h" HAVE_LIBELF_LIBELF_H)
|
||||
check_include_file( "alloca.h" HAVE_ALLOCA_H )
|
||||
check_include_file( "elfaccess.h" HAVE_ELFACCESS_H)
|
||||
check_include_file( "sys/elf_386.h" HAVE_SYS_ELF_386_H )
|
||||
check_include_file( "sys/elf_amd64.h" HAVE_SYS_ELF_AMD64_H)
|
||||
check_include_file( "sys/elf_sparc.h" HAVE_SYS_ELF_SPARC_H)
|
||||
check_include_file( "sys/ia64/elf.h" HAVE_SYS_IA64_ELF_H )
|
||||
set(VERSION 0.3.1)
|
||||
set(PACKAGE_VERSION "\"${VERSION}\"")
|
||||
configure_file(libdwarf/cmake/config.h.cmake config.h)
|
||||
file(GLOB_RECURSE LIBDWARF_SOURCES "libdwarf/src/lib/libdwarf/*.c")
|
||||
add_library(libdwarf STATIC ${LIBDWARF_SOURCES})
|
||||
set_target_properties(libdwarf PROPERTIES OUTPUT_NAME "libdwarf")
|
||||
if(HAVE_LIBELF_H OR HAVE_LIBELF_LIBELF_H)
|
||||
target_link_libraries(libdwarf PUBLIC libelf)
|
||||
endif()
|
||||
target_include_directories(libdwarf SYSTEM PUBLIC "libdwarf/src/lib/libdwarf" ${CMAKE_CURRENT_BINARY_DIR})
|
||||
file(READ "addr2line/addr2line.c" ADDR2LINE_CONTENT)
|
||||
string(REPLACE "static int" "int" ADDR2LINE_CONTENT "${ADDR2LINE_CONTENT}")
|
||||
string(REPLACE "static void" "void" ADDR2LINE_CONTENT "${ADDR2LINE_CONTENT}")
|
||||
string(REPLACE "main(" "main_addr2line(" ADDR2LINE_CONTENT "${ADDR2LINE_CONTENT}")
|
||||
file(WRITE "addr2line/addr2line.c" "${ADDR2LINE_CONTENT}")
|
||||
add_library(addr2line STATIC "addr2line/addr2line.c")
|
||||
target_link_libraries(addr2line PUBLIC libdwarf dl z)
|
||||
target_include_directories(addr2line PUBLIC "libdwarf/src/lib/libdwarf" )
|
||||
endif(NOT ${TD_WINDOWS})
|
||||
endif(${BUILD_ADDR2LINE})
|
||||
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ import CSAsyncQuery from "../../07-develop/04-query-data/_cs_async.mdx"
|
|||
|
||||
`TDengine.Connector` 是 TDengine 提供的 C# 语言连接器。C# 开发人员可以通过它开发存取 TDengine 集群数据的 C# 应用软件。
|
||||
|
||||
`TDengine.Connector` 连接器支持通过 TDengine 客户端驱动(taosc)建立与 TDengine 运行实例的连接,提供数据写入、查询、订阅、schemaless 数据写入、参数绑定接口数据写入等功能 `TDengine.Connector` 目前暂未提供 REST 连接方式,用户可以参考 [RESTful APIs](https://docs.taosdata.com//reference/restful-api/) 文档自行编写。
|
||||
`TDengine.Connector` 连接器支持通过 TDengine 客户端驱动(taosc)建立与 TDengine 运行实例的连接,提供数据写入、查询、订阅、schemaless 数据写入、参数绑定接口数据写入等功能 `TDengine.Connector` 目前暂未提供 REST 连接方式,用户可以参考 [REST API](/reference/rest-api/) 文档自行编写。
|
||||
|
||||
本文介绍如何在 Linux 或 Windows 环境中安装 `TDengine.Connector`,并通过 `TDengine.Connector` 连接 TDengine 集群,进行数据写入、查询等基本操作。
|
||||
|
||||
|
|
|
@ -4,24 +4,24 @@ sidebar_label: Documentation Home
|
|||
slug: /
|
||||
---
|
||||
|
||||
TDengine is a [high-performance](https://tdengine.com/fast), [scalable](https://tdengine.com/scalable) time series database with [SQL support](https://tdengine.com/sql-support). This document is the TDengine user manual. It introduces the basic concepts, installation, features, SQL, APIs, operation, maintenance, kernel design, etc. It’s written mainly for architects, developers and system administrators.
|
||||
TDengine is a [high-performance](https://tdengine.com/fast), [scalable](https://tdengine.com/scalable) time series database with [SQL support](https://tdengine.com/sql-support). This document is the TDengine user manual. It introduces the basic, as well as novel concepts, in TDengine, and also talks in detail about installation, features, SQL, APIs, operation, maintenance, kernel design and other topics. It’s written mainly for architects, developers and system administrators.
|
||||
|
||||
To get a global view about TDengine, like feature list, benchmarks, and competitive advantages, please browse through section [Introduction](./intro).
|
||||
To get an overview of TDengine, such as a feature list, benchmarks, and competitive advantages, please browse through the [Introduction](./intro) section.
|
||||
|
||||
TDengine makes full use of the characteristics of time series data, proposes the concepts of "one table for one data collection point" and "super table", and designs an innovative storage engine, which greatly improves the efficiency of data ingestion, querying and storage. To understand the new concepts and use TDengine in the right way, please read [“Concepts”](./concept) thoroughly.
|
||||
TDengine greatly improves the efficiency of data ingestion, querying and storage by exploiting the characteristics of time series data, introducing the novel concepts of "one table for one data collection point" and "super table", and designing an innovative storage engine. To understand the new concepts in TDengine and make full use of the features and capabilities of TDengine, please read [“Concepts”](./concept) thoroughly.
|
||||
|
||||
If you are a developer, please read the [“Developer Guide”](./develop) carefully. This section introduces the database connection, data modeling, data ingestion, query, continuous query, cache, data subscription, user-defined function, etc. in detail. Sample code is provided for a variety of programming languages. In most cases, you can just copy and paste the sample code, make a few changes to accommodate your application, and it will work.
|
||||
If you are a developer, please read the [“Developer Guide”](./develop) carefully. This section introduces the database connection, data modeling, data ingestion, query, continuous query, cache, data subscription, user-defined functions, and other functionality in detail. Sample code is provided for a variety of programming languages. In most cases, you can just copy and paste the sample code, make a few changes to accommodate your application, and it will work.
|
||||
|
||||
We live in the era of big data, and scale-up is unable to meet the growing business needs. Any modern data system must have the ability to scale out, and clustering has become an indispensable feature of big data systems. The TDengine team has not only developed the cluster feature, they also decided to open source this important feature. To learn how to deploy, manage and maintain a TDengine cluster please refer to ["Cluster"](./cluster).
|
||||
We live in the era of big data, and scale-up is unable to meet the growing needs of business. Any modern data system must have the ability to scale out, and clustering has become an indispensable feature of big data systems. Not only did the TDengine team develop the cluster feature, but also decided to open source this important feature. To learn how to deploy, manage and maintain a TDengine cluster please refer to ["cluster"](./cluster).
|
||||
|
||||
TDengine uses SQL as its query language, which greatly reduces learning costs and migration costs. In addition to the standard SQL, TDengine has extensions to support time series data scenarios better, such as roll up, interpolation, time weighted average, etc. The ["SQL Reference"](./taos-sql) chapter describes the SQL syntax in detail, and lists the various supported commands and functions.
|
||||
TDengine uses ubiquitious SQL as its query language, which greatly reduces learning costs and migration costs. In addition to the standard SQL, TDengine has extensions to better support time series data analysis. These extensions include functions such as roll up, interpolation and time weighted average, among many others. The ["SQL Reference"](./taos-sql) chapter describes the SQL syntax in detail, and lists the various supported commands and functions.
|
||||
|
||||
If you are a system administrator who cares about installation, upgrade, fault tolerance, disaster recovery, data import, data export, system configuration, how to monitor whether TDengine is running healthily, and how to improve system performance, please refer to the ["Administration"](./operation) thoroughly.
|
||||
If you are a system administrator who cares about installation, upgrade, fault tolerance, disaster recovery, data import, data export, system configuration, how to monitor whether TDengine is running healthily, and how to improve system performance, please refer to, and thoroughly read the ["Administration"](./operation) section.
|
||||
|
||||
If you want to know more about TDengine tools, REST API, and connectors for various programming languages, please see the ["Reference"](./reference) chapter.
|
||||
If you want to know more about TDengine tools, the REST API, and connectors for various programming languages, please see the ["Reference"](./reference) chapter.
|
||||
|
||||
If you are very interested in the internal design of TDengine, please read the chapter ["Inside TDengine”](./tdinternal), which introduces the cluster design, data partitioning, sharding, writing, and reading processes in detail. If you want to study TDengine code or even contribute code, please read this chapter carefully.
|
||||
|
||||
TDengine is an open source database, you are welcome to be a part of TDengine. If you find any errors in the documentation, or the description is not clear, please click "Edit this page" at the bottom of each page to edit it directly.
|
||||
TDengine is an open source database, and we would love for you to be a part of TDengine. If you find any errors in the documentation, or see parts where more clarity or elaboration is needed, please click "Edit this page" at the bottom of each page to edit it directly.
|
||||
|
||||
Together, we make a difference.
|
||||
|
|
|
@ -19,7 +19,7 @@ import CSAsyncQuery from "../../07-develop/04-query-data/_cs_async.mdx"
|
|||
|
||||
`TDengine.Connector` is a C# language connector provided by TDengine that allows C# developers to develop C# applications that access TDengine cluster data.
|
||||
|
||||
The `TDengine.Connector` connector supports connect to TDengine instances via the TDengine client driver (taosc), providing data writing, querying, subscription, schemaless writing, bind interface, etc. The `TDengine.Connector` currently does not provide a REST connection interface. Developers can write their RESTful application by referring to the [RESTful APIs](https://docs.taosdata.com//reference/restful-api/) documentation.
|
||||
The `TDengine.Connector` connector supports connect to TDengine instances via the TDengine client driver (taosc), providing data writing, querying, subscription, schemaless writing, bind interface, etc. The `TDengine.Connector` currently does not provide a REST connection interface. Developers can write their RESTful application by referring to the [REST API](/reference/rest-api/) documentation.
|
||||
|
||||
This article describes how to install `TDengine.Connector` in a Linux or Windows environment and connect to TDengine clusters via `TDengine.Connector` to perform basic operations such as data writing and querying.
|
||||
|
||||
|
|
|
@ -82,9 +82,7 @@ int32_t create_stream() {
|
|||
/*const char* sql = "select sum(k) from tu1 interval(10m)";*/
|
||||
/*pRes = tmq_create_stream(pConn, "stream1", "out1", sql);*/
|
||||
pRes = taos_query(
|
||||
pConn,
|
||||
"create stream stream1 trigger at_once into outstb as select _wstartts, min(k), max(k), sum(k) as sum_of_k "
|
||||
"from tu1 interval(10m)");
|
||||
pConn, "create stream stream1 trigger at_once into outstb as select _wstartts, sum(k) from tu1 interval(10m)");
|
||||
if (taos_errno(pRes) != 0) {
|
||||
printf("failed to create stream stream1, reason:%s\n", taos_errstr(pRes));
|
||||
return -1;
|
||||
|
|
|
@ -96,6 +96,7 @@ extern char *qtypeStr[];
|
|||
#define TSDB_PORT_HTTP 11
|
||||
|
||||
#undef TD_DEBUG_PRINT_ROW
|
||||
#undef TD_DEBUG_PRINT_TSDB_LOAD_DCOLS
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -244,12 +244,12 @@ typedef struct {
|
|||
const void* pMsg;
|
||||
} SSubmitMsgIter;
|
||||
|
||||
int32_t tInitSubmitMsgIter(const SSubmitReq* pMsg, SSubmitMsgIter* pIter);
|
||||
int32_t tInitSubmitMsgIter(SSubmitReq* pMsg, SSubmitMsgIter* pIter);
|
||||
int32_t tGetSubmitMsgNext(SSubmitMsgIter* pIter, SSubmitBlk** pPBlock);
|
||||
int32_t tInitSubmitBlkIter(SSubmitMsgIter* pMsgIter, SSubmitBlk* pBlock, SSubmitBlkIter* pIter);
|
||||
STSRow* tGetSubmitBlkNext(SSubmitBlkIter* pIter);
|
||||
// for debug
|
||||
int32_t tPrintFixedSchemaSubmitReq(const SSubmitReq* pReq, STSchema* pSchema);
|
||||
int32_t tPrintFixedSchemaSubmitReq(SSubmitReq* pReq, STSchema* pSchema);
|
||||
|
||||
typedef struct {
|
||||
int32_t code;
|
||||
|
@ -1697,7 +1697,7 @@ int32_t tDecodeSRSmaParam(SDecoder* pCoder, SRSmaParam* pRSmaParam);
|
|||
|
||||
// TDMT_VND_CREATE_STB ==============
|
||||
typedef struct SVCreateStbReq {
|
||||
const char* name;
|
||||
char* name;
|
||||
tb_uid_t suid;
|
||||
int8_t rollup;
|
||||
SSchemaWrapper schema;
|
||||
|
@ -1710,8 +1710,8 @@ int tDecodeSVCreateStbReq(SDecoder* pCoder, SVCreateStbReq* pReq);
|
|||
|
||||
// TDMT_VND_DROP_STB ==============
|
||||
typedef struct SVDropStbReq {
|
||||
const char* name;
|
||||
tb_uid_t suid;
|
||||
char* name;
|
||||
tb_uid_t suid;
|
||||
} SVDropStbReq;
|
||||
|
||||
int32_t tEncodeSVDropStbReq(SEncoder* pCoder, const SVDropStbReq* pReq);
|
||||
|
@ -1720,16 +1720,16 @@ int32_t tDecodeSVDropStbReq(SDecoder* pCoder, SVDropStbReq* pReq);
|
|||
// TDMT_VND_CREATE_TABLE ==============
|
||||
#define TD_CREATE_IF_NOT_EXISTS 0x1
|
||||
typedef struct SVCreateTbReq {
|
||||
int32_t flags;
|
||||
tb_uid_t uid;
|
||||
int64_t ctime;
|
||||
const char* name;
|
||||
int32_t ttl;
|
||||
int8_t type;
|
||||
int32_t flags;
|
||||
tb_uid_t uid;
|
||||
int64_t ctime;
|
||||
char* name;
|
||||
int32_t ttl;
|
||||
int8_t type;
|
||||
union {
|
||||
struct {
|
||||
tb_uid_t suid;
|
||||
const uint8_t* pTag;
|
||||
tb_uid_t suid;
|
||||
uint8_t* pTag;
|
||||
} ctb;
|
||||
struct {
|
||||
SSchemaWrapper schema;
|
||||
|
@ -1777,8 +1777,8 @@ int32_t tDeserializeSVCreateTbBatchRsp(void* buf, int32_t bufLen, SVCreateTbBatc
|
|||
|
||||
// TDMT_VND_DROP_TABLE =================
|
||||
typedef struct {
|
||||
const char* name;
|
||||
int8_t igNotExists;
|
||||
char* name;
|
||||
int8_t igNotExists;
|
||||
} SVDropTbReq;
|
||||
|
||||
typedef struct {
|
||||
|
@ -1809,9 +1809,9 @@ int32_t tDecodeSVDropTbBatchRsp(SDecoder* pCoder, SVDropTbBatchRsp* pRsp);
|
|||
|
||||
// TDMT_VND_ALTER_TABLE =====================
|
||||
typedef struct {
|
||||
const char* tbName;
|
||||
int8_t action;
|
||||
const char* colName;
|
||||
char* tbName;
|
||||
int8_t action;
|
||||
char* colName;
|
||||
// TSDB_ALTER_TABLE_ADD_COLUMN
|
||||
int8_t type;
|
||||
int8_t flags;
|
||||
|
@ -1820,17 +1820,17 @@ typedef struct {
|
|||
// TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES
|
||||
int32_t colModBytes;
|
||||
// TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME
|
||||
const char* colNewName;
|
||||
char* colNewName;
|
||||
// TSDB_ALTER_TABLE_UPDATE_TAG_VAL
|
||||
const char* tagName;
|
||||
int8_t isNull;
|
||||
uint32_t nTagVal;
|
||||
const uint8_t* pTagVal;
|
||||
char* tagName;
|
||||
int8_t isNull;
|
||||
uint32_t nTagVal;
|
||||
uint8_t* pTagVal;
|
||||
// TSDB_ALTER_TABLE_UPDATE_OPTIONS
|
||||
int8_t updateTTL;
|
||||
int32_t newTTL;
|
||||
int8_t updateComment;
|
||||
const char* newComment;
|
||||
int8_t updateTTL;
|
||||
int32_t newTTL;
|
||||
int8_t updateComment;
|
||||
char* newComment;
|
||||
} SVAlterTbReq;
|
||||
|
||||
int32_t tEncodeSVAlterTbReq(SEncoder* pEncoder, const SVAlterTbReq* pReq);
|
||||
|
@ -2020,7 +2020,7 @@ static FORCE_INLINE void tFreeClientHbBatchRsp(void* pRsp) {
|
|||
|
||||
int32_t tSerializeSClientHbBatchRsp(void* buf, int32_t bufLen, const SClientHbBatchRsp* pBatchRsp);
|
||||
int32_t tDeserializeSClientHbBatchRsp(void* buf, int32_t bufLen, SClientHbBatchRsp* pBatchRsp);
|
||||
void tFreeSClientHbBatchRsp(SClientHbBatchRsp *pBatchRsp);
|
||||
void tFreeSClientHbBatchRsp(SClientHbBatchRsp* pBatchRsp);
|
||||
|
||||
static FORCE_INLINE int32_t tEncodeSKv(SEncoder* pEncoder, const SKv* pKv) {
|
||||
if (tEncodeI32(pEncoder, pKv->key) < 0) return -1;
|
||||
|
@ -2255,20 +2255,20 @@ int32_t tSerializeSMDropSmaReq(void* buf, int32_t bufLen, SMDropSmaReq* pReq);
|
|||
int32_t tDeserializeSMDropSmaReq(void* buf, int32_t bufLen, SMDropSmaReq* pReq);
|
||||
|
||||
typedef struct {
|
||||
int8_t version; // for compatibility(default 0)
|
||||
int8_t intervalUnit; // MACRO: TIME_UNIT_XXX
|
||||
int8_t slidingUnit; // MACRO: TIME_UNIT_XXX
|
||||
int8_t timezoneInt; // sma data expired if timezone changes.
|
||||
char indexName[TSDB_INDEX_NAME_LEN];
|
||||
int32_t exprLen;
|
||||
int32_t tagsFilterLen;
|
||||
int64_t indexUid;
|
||||
tb_uid_t tableUid; // super/child/common table uid
|
||||
int64_t interval;
|
||||
int64_t offset; // use unit by precision of DB
|
||||
int64_t sliding;
|
||||
const char* expr; // sma expression
|
||||
const char* tagsFilter;
|
||||
int8_t version; // for compatibility(default 0)
|
||||
int8_t intervalUnit; // MACRO: TIME_UNIT_XXX
|
||||
int8_t slidingUnit; // MACRO: TIME_UNIT_XXX
|
||||
int8_t timezoneInt; // sma data expired if timezone changes.
|
||||
char indexName[TSDB_INDEX_NAME_LEN];
|
||||
int32_t exprLen;
|
||||
int32_t tagsFilterLen;
|
||||
int64_t indexUid;
|
||||
tb_uid_t tableUid; // super/child/common table uid
|
||||
int64_t interval;
|
||||
int64_t offset; // use unit by precision of DB
|
||||
int64_t sliding;
|
||||
char* expr; // sma expression
|
||||
char* tagsFilter;
|
||||
} STSma; // Time-range-wise SMA
|
||||
|
||||
typedef STSma SVCreateTSmaReq;
|
||||
|
@ -2596,12 +2596,12 @@ static FORCE_INLINE void tDeleteSMqAskEpRsp(SMqAskEpRsp* pRsp) {
|
|||
|
||||
#define TD_AUTO_CREATE_TABLE 0x1
|
||||
typedef struct {
|
||||
int64_t suid;
|
||||
int64_t uid;
|
||||
int32_t sver;
|
||||
uint32_t nData;
|
||||
const uint8_t* pData;
|
||||
SVCreateTbReq cTbReq;
|
||||
int64_t suid;
|
||||
int64_t uid;
|
||||
int32_t sver;
|
||||
uint32_t nData;
|
||||
uint8_t* pData;
|
||||
SVCreateTbReq cTbReq;
|
||||
} SVSubmitBlk;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -158,6 +158,7 @@ enum {
|
|||
TD_DEF_MSG_TYPE(TDMT_MND_DROP_INDEX, "mnode-drop-index", NULL, NULL)
|
||||
TD_DEF_MSG_TYPE(TDMT_MND_GET_DB_CFG, "mnode-get-db-cfg", NULL, NULL)
|
||||
TD_DEF_MSG_TYPE(TDMT_MND_GET_INDEX, "mnode-get-index", NULL, NULL)
|
||||
TD_DEF_MSG_TYPE(TDMT_MND_APPLY_MSG, "mnode-apply-msg", NULL, NULL)
|
||||
|
||||
// Requests handled by VNODE
|
||||
TD_NEW_MSG_SEG(TDMT_VND_MSG)
|
||||
|
|
|
@ -30,7 +30,7 @@ typedef uint64_t TDRowVerT;
|
|||
typedef int16_t col_id_t;
|
||||
typedef int8_t col_type_t;
|
||||
typedef int32_t col_bytes_t;
|
||||
typedef uint16_t schema_ver_t;
|
||||
typedef int32_t schema_ver_t;
|
||||
typedef int32_t func_id_t;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
|
|
@ -89,6 +89,7 @@ int32_t mndGetLoad(SMnode *pMnode, SMnodeLoad *pLoad);
|
|||
* @return int32_t 0 for success, -1 for failure.
|
||||
*/
|
||||
int32_t mndProcessMsg(SRpcMsg *pMsg);
|
||||
int32_t mndProcessSyncMsg(SRpcMsg *pMsg);
|
||||
|
||||
/**
|
||||
* @brief Generate machine code
|
||||
|
|
|
@ -304,13 +304,16 @@ int32_t sdbGetMaxId(SSdb *pSdb, ESdbType type);
|
|||
int64_t sdbGetTableVer(SSdb *pSdb, ESdbType type);
|
||||
|
||||
/**
|
||||
* @brief Update the version of sdb
|
||||
* @brief Update the index of sdb
|
||||
*
|
||||
* @param pSdb The sdb object.
|
||||
* @param val The update value of the version.
|
||||
* @return int32_t The current version of sdb
|
||||
* @param index The update value of the apply index.
|
||||
* @return int32_t The current index of sdb
|
||||
*/
|
||||
int64_t sdbUpdateVer(SSdb *pSdb, int32_t val);
|
||||
void sdbSetApplyIndex(SSdb *pSdb, int64_t index);
|
||||
int64_t sdbGetApplyIndex(SSdb *pSdb);
|
||||
void sdbSetApplyTerm(SSdb *pSdb, int64_t term);
|
||||
int64_t sdbGetApplyTerm(SSdb *pSdb);
|
||||
|
||||
SSdbRaw *sdbAllocRaw(ESdbType type, int8_t sver, int32_t dataLen);
|
||||
void sdbFreeRaw(SSdbRaw *pRaw);
|
||||
|
@ -339,6 +342,7 @@ typedef struct SSdb {
|
|||
char *tmpDir;
|
||||
int64_t lastCommitVer;
|
||||
int64_t curVer;
|
||||
int64_t curTerm;
|
||||
int64_t tableVer[SDB_MAX];
|
||||
int64_t maxId[SDB_MAX];
|
||||
EKeyType keyTypes[SDB_MAX];
|
||||
|
|
|
@ -46,24 +46,34 @@ typedef enum {
|
|||
AUTH_TYPE_OTHER,
|
||||
} AUTH_TYPE;
|
||||
|
||||
typedef struct SUserAuthInfo {
|
||||
char user[TSDB_USER_LEN];
|
||||
char dbFName[TSDB_DB_FNAME_LEN];
|
||||
AUTH_TYPE type;
|
||||
} SUserAuthInfo;
|
||||
|
||||
typedef struct SCatalogReq {
|
||||
SArray *pTableName; // element is SNAME
|
||||
SArray *pUdf; // udf name
|
||||
SArray *pTableMeta; // element is SNAME
|
||||
SArray *pDbVgroup; // element is db full name
|
||||
SArray *pTableHash; // element is SNAME
|
||||
SArray *pUdf; // element is udf name
|
||||
SArray *pDbCfg; // element is db full name
|
||||
SArray *pIndex; // element is index name
|
||||
SArray *pUser; // element is SUserAuthInfo
|
||||
bool qNodeRequired; // valid qnode
|
||||
} SCatalogReq;
|
||||
|
||||
typedef struct SMetaData {
|
||||
SArray *pTableMeta; // STableMeta array
|
||||
SArray *pVgroupInfo; // SVgroupInfo list
|
||||
SArray *pUdfList; // udf info list
|
||||
SArray *pQnodeList; // qnode list, SArray<SQueryNodeAddr>
|
||||
SArray *pTableMeta; // SArray<STableMeta>
|
||||
SArray *pDbVgroup; // SArray<SArray<SVgroupInfo>*>
|
||||
SArray *pTableHash; // SArray<SVgroupInfo>
|
||||
SArray *pUdfList; // SArray<SFuncInfo>
|
||||
SArray *pDbCfg; // SArray<SDbCfgInfo>
|
||||
SArray *pIndex; // SArray<SIndexInfo>
|
||||
SArray *pUser; // SArray<bool>
|
||||
SArray *pQnodeList; // SArray<SQueryNodeAddr>
|
||||
} SMetaData;
|
||||
|
||||
typedef struct STbSVersion {
|
||||
char* tbFName;
|
||||
int32_t sver;
|
||||
} STbSVersion;
|
||||
|
||||
typedef struct SCatalogCfg {
|
||||
uint32_t maxTblCacheNum;
|
||||
uint32_t maxDBCacheNum;
|
||||
|
@ -88,6 +98,11 @@ typedef struct SDbVgVersion {
|
|||
int32_t numOfTable; // unit is TSDB_TABLE_NUM_UNIT
|
||||
} SDbVgVersion;
|
||||
|
||||
typedef struct STbSVersion {
|
||||
char* tbFName;
|
||||
int32_t sver;
|
||||
} STbSVersion;
|
||||
|
||||
typedef struct SUserAuthVersion {
|
||||
char user[TSDB_USER_LEN];
|
||||
int32_t version;
|
||||
|
@ -96,6 +111,8 @@ typedef struct SUserAuthVersion {
|
|||
typedef SDbCfgRsp SDbCfgInfo;
|
||||
typedef SUserIndexRsp SIndexInfo;
|
||||
|
||||
typedef void (*catalogCallback)(SMetaData* pResult, void* param, int32_t code);
|
||||
|
||||
int32_t catalogInit(SCatalogCfg *cfg);
|
||||
|
||||
/**
|
||||
|
@ -131,7 +148,7 @@ int32_t catalogUpdateDBVgInfo(SCatalog* pCatalog, const char* dbName, uint64_t d
|
|||
|
||||
int32_t catalogRemoveDB(SCatalog* pCatalog, const char* dbName, uint64_t dbId);
|
||||
|
||||
int32_t catalogRemoveTableMeta(SCatalog* pCtg, const SName* pTableName);
|
||||
int32_t catalogRemoveTableMeta(SCatalog* pCtg, SName* pTableName);
|
||||
|
||||
int32_t catalogRemoveStbMeta(SCatalog* pCtg, const char* dbFName, uint64_t dbId, const char* stbName, uint64_t suid);
|
||||
|
||||
|
@ -241,9 +258,9 @@ int32_t catalogGetExpiredUsers(SCatalog* pCtg, SUserAuthVersion **users, uint32_
|
|||
|
||||
int32_t catalogGetDBCfg(SCatalog* pCtg, void *pRpc, const SEpSet* pMgmtEps, const char* dbFName, SDbCfgInfo* pDbCfg);
|
||||
|
||||
int32_t catalogGetIndexInfo(SCatalog* pCtg, void *pRpc, const SEpSet* pMgmtEps, const char* indexName, SIndexInfo* pInfo);
|
||||
int32_t catalogGetIndexMeta(SCatalog* pCtg, void *pRpc, const SEpSet* pMgmtEps, const char* indexName, SIndexInfo* pInfo);
|
||||
|
||||
int32_t catalogGetUdfInfo(SCatalog* pCtg, void *pRpc, const SEpSet* pMgmtEps, const char* funcName, SFuncInfo** pInfo);
|
||||
int32_t catalogGetUdfInfo(SCatalog* pCtg, void *pRpc, const SEpSet* pMgmtEps, const char* funcName, SFuncInfo* pInfo);
|
||||
|
||||
int32_t catalogChkAuth(SCatalog* pCtg, void *pRpc, const SEpSet* pMgmtEps, const char* user, const char* dbFName, AUTH_TYPE type, bool *pass);
|
||||
|
||||
|
|
|
@ -146,7 +146,8 @@ bool fmIsBuiltinFunc(const char* pFunc);
|
|||
|
||||
bool fmIsAggFunc(int32_t funcId);
|
||||
bool fmIsScalarFunc(int32_t funcId);
|
||||
bool fmIsNonstandardSQLFunc(int32_t funcId);
|
||||
bool fmIsVectorFunc(int32_t funcId);
|
||||
bool fmIsIndefiniteRowsFunc(int32_t funcId);
|
||||
bool fmIsStringFunc(int32_t funcId);
|
||||
bool fmIsDatetimeFunc(int32_t funcId);
|
||||
bool fmIsSelectFunc(int32_t funcId);
|
||||
|
|
|
@ -16,9 +16,11 @@
|
|||
#ifndef _TD_INDEX_H_
|
||||
#define _TD_INDEX_H_
|
||||
|
||||
#include "nodes.h"
|
||||
#include "os.h"
|
||||
#include "taoserror.h"
|
||||
#include "tarray.h"
|
||||
#include "tglobal.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -189,6 +191,12 @@ void indexTermDestroy(SIndexTerm* p);
|
|||
*/
|
||||
void indexInit();
|
||||
|
||||
/* index filter */
|
||||
typedef enum { SFLT_NOT_INDEX, SFLT_COARSE_INDEX, SFLT_ACCURATE_INDEX } SIdxFltStatus;
|
||||
|
||||
SIdxFltStatus idxGetFltStatus(SNode* pFilterNode);
|
||||
|
||||
int32_t doFilterTag(const SNode* pFilterNode, SArray* result);
|
||||
/*
|
||||
* destory index env
|
||||
*
|
||||
|
|
|
@ -59,10 +59,10 @@ extern "C" {
|
|||
for (SListCell* cell = (NULL != (list) ? (list)->pHead : NULL); \
|
||||
(NULL != cell ? (node = &(cell->pNode), true) : (node = NULL, false)); cell = cell->pNext)
|
||||
|
||||
#define DESTORY_LIST(list) \
|
||||
do { \
|
||||
nodesDestroyList(list); \
|
||||
list = NULL; \
|
||||
#define DESTORY_LIST(list) \
|
||||
do { \
|
||||
nodesDestroyList((list)); \
|
||||
(list) = NULL; \
|
||||
} while (0)
|
||||
|
||||
typedef enum ENodeType {
|
||||
|
@ -96,6 +96,7 @@ typedef enum ENodeType {
|
|||
QUERY_NODE_EXPLAIN_OPTIONS,
|
||||
QUERY_NODE_STREAM_OPTIONS,
|
||||
QUERY_NODE_TOPIC_OPTIONS,
|
||||
QUERY_NODE_LEFT_VALUE,
|
||||
|
||||
// Statement nodes are used in parser and planner module.
|
||||
QUERY_NODE_SET_OPERATOR,
|
||||
|
|
|
@ -54,6 +54,7 @@ typedef struct SScanLogicNode {
|
|||
int64_t sliding;
|
||||
int8_t intervalUnit;
|
||||
int8_t slidingUnit;
|
||||
SNode* pTagCond;
|
||||
} SScanLogicNode;
|
||||
|
||||
typedef struct SJoinLogicNode {
|
||||
|
@ -343,6 +344,7 @@ typedef struct SSubplan {
|
|||
SNodeList* pParents; // the data destination subplan, get data from current subplan
|
||||
SPhysiNode* pNode; // physical plan of current subplan
|
||||
SDataSinkNode* pDataSink; // data of the subplan flow into the datasink
|
||||
SNode* pTagCond;
|
||||
} SSubplan;
|
||||
|
||||
typedef enum EExplainMode { EXPLAIN_MODE_DISABLE = 1, EXPLAIN_MODE_STATIC, EXPLAIN_MODE_ANALYZE } EExplainMode;
|
||||
|
|
|
@ -81,6 +81,7 @@ typedef struct SValueNode {
|
|||
char* literal;
|
||||
bool isDuration;
|
||||
bool translate;
|
||||
bool notReserved;
|
||||
int16_t placeholderNo;
|
||||
union {
|
||||
bool b;
|
||||
|
@ -93,6 +94,10 @@ typedef struct SValueNode {
|
|||
char unit;
|
||||
} SValueNode;
|
||||
|
||||
typedef struct SLeftValueNode {
|
||||
ENodeType type;
|
||||
} SLeftValueNode;
|
||||
|
||||
typedef struct SOperatorNode {
|
||||
SExprNode node; // QUERY_NODE_OPERATOR
|
||||
EOperatorType opType;
|
||||
|
@ -236,7 +241,7 @@ typedef struct SSelectStmt {
|
|||
bool isTimeOrderQuery;
|
||||
bool hasAggFuncs;
|
||||
bool hasRepeatScanFuncs;
|
||||
bool hasNonstdSQLFunc;
|
||||
bool hasIndefiniteRowsFunc;
|
||||
} SSelectStmt;
|
||||
|
||||
typedef enum ESetOperatorType { SET_OP_TYPE_UNION_ALL = 1, SET_OP_TYPE_UNION } ESetOperatorType;
|
||||
|
|
|
@ -114,17 +114,12 @@ static FORCE_INLINE void streamDataSubmitRefDec(SStreamDataSubmit* pDataSubmit)
|
|||
int32_t streamDataBlockEncode(void** buf, const SStreamDataBlock* pOutput);
|
||||
void* streamDataBlockDecode(const void* buf, SStreamDataBlock* pInput);
|
||||
|
||||
typedef struct {
|
||||
void* inputHandle;
|
||||
void* executor;
|
||||
} SStreamRunner;
|
||||
|
||||
typedef struct {
|
||||
int8_t parallelizable;
|
||||
char* qmsg;
|
||||
// followings are not applicable to encoder and decoder
|
||||
int8_t numOfRunners;
|
||||
SStreamRunner* runners;
|
||||
void* inputHandle;
|
||||
void* executor;
|
||||
} STaskExec;
|
||||
|
||||
typedef struct {
|
||||
|
@ -320,17 +315,15 @@ int32_t streamEnqueueDataSubmit(SStreamTask* pTask, SStreamDataSubmit* input);
|
|||
int32_t streamEnqueueDataBlk(SStreamTask* pTask, SStreamDataBlock* input);
|
||||
int32_t streamDequeueOutput(SStreamTask* pTask, void** output);
|
||||
|
||||
int32_t streamExecTask(SStreamTask* pTask, SMsgCb* pMsgCb, const void* input, int32_t inputType, int32_t workId);
|
||||
|
||||
int32_t streamTaskRun(SStreamTask* pTask);
|
||||
|
||||
int32_t streamTaskHandleInput(SStreamTask* pTask, void* data);
|
||||
|
||||
int32_t streamTaskProcessRunReq(SStreamTask* pTask, SMsgCb* pMsgCb);
|
||||
int32_t streamTaskProcessDispatchReq(SStreamTask* pTask, SMsgCb* pMsgCb, SStreamDispatchReq* pReq, SRpcMsg* pMsg);
|
||||
int32_t streamTaskProcessDispatchRsp(SStreamTask* pTask, SMsgCb* pMsgCb, SStreamDispatchRsp* pRsp);
|
||||
int32_t streamTaskProcessRecoverReq(SStreamTask* pTask, SMsgCb* pMsgCb, SStreamTaskRecoverReq* pReq, SRpcMsg* pMsg);
|
||||
int32_t streamTaskProcessRecoverRsp(SStreamTask* pTask, SStreamTaskRecoverRsp* pRsp);
|
||||
int32_t streamProcessDispatchReq(SStreamTask* pTask, SMsgCb* pMsgCb, SStreamDispatchReq* pReq, SRpcMsg* pMsg);
|
||||
int32_t streamProcessDispatchRsp(SStreamTask* pTask, SMsgCb* pMsgCb, SStreamDispatchRsp* pRsp);
|
||||
int32_t streamProcessRecoverReq(SStreamTask* pTask, SMsgCb* pMsgCb, SStreamTaskRecoverReq* pReq, SRpcMsg* pMsg);
|
||||
int32_t streamProcessRecoverRsp(SStreamTask* pTask, SStreamTaskRecoverRsp* pRsp);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -78,6 +78,8 @@ typedef struct SFsmCbMeta {
|
|||
int32_t code;
|
||||
ESyncState state;
|
||||
uint64_t seqNum;
|
||||
SyncTerm term;
|
||||
SyncTerm currentTerm;
|
||||
} SFsmCbMeta;
|
||||
|
||||
typedef struct SSyncFSM {
|
||||
|
@ -85,6 +87,7 @@ typedef struct SSyncFSM {
|
|||
void (*FpCommitCb)(struct SSyncFSM* pFsm, const SRpcMsg* pMsg, SFsmCbMeta cbMeta);
|
||||
void (*FpPreCommitCb)(struct SSyncFSM* pFsm, const SRpcMsg* pMsg, SFsmCbMeta cbMeta);
|
||||
void (*FpRollBackCb)(struct SSyncFSM* pFsm, const SRpcMsg* pMsg, SFsmCbMeta cbMeta);
|
||||
void (*FpRestoreFinish)(struct SSyncFSM* pFsm);
|
||||
int32_t (*FpGetSnapshot)(struct SSyncFSM* pFsm, SSnapshot* pSnapshot);
|
||||
int32_t (*FpRestoreSnapshot)(struct SSyncFSM* pFsm, const SSnapshot* snapshot);
|
||||
} SSyncFSM;
|
||||
|
@ -117,7 +120,6 @@ typedef struct SSyncLogStore {
|
|||
|
||||
} SSyncLogStore;
|
||||
|
||||
|
||||
typedef struct SSyncInfo {
|
||||
SyncGroupId vgId;
|
||||
SSyncCfg syncCfg;
|
||||
|
|
|
@ -28,7 +28,7 @@ extern "C" {
|
|||
#define TAOS_CONN_CLIENT 1
|
||||
#define IsReq(pMsg) (pMsg->msgType & 1U)
|
||||
|
||||
extern int tsRpcHeadSize;
|
||||
extern int32_t tsRpcHeadSize;
|
||||
|
||||
typedef struct {
|
||||
uint32_t clientIp;
|
||||
|
@ -69,10 +69,10 @@ typedef struct SRpcInit {
|
|||
char localFqdn[TSDB_FQDN_LEN];
|
||||
uint16_t localPort; // local port
|
||||
char * label; // for debug purpose
|
||||
int numOfThreads; // number of threads to handle connections
|
||||
int sessions; // number of sessions allowed
|
||||
int32_t numOfThreads; // number of threads to handle connections
|
||||
int32_t sessions; // number of sessions allowed
|
||||
int8_t connType; // TAOS_CONN_UDP, TAOS_CONN_TCPC, TAOS_CONN_TCPS
|
||||
int idleTime; // milliseconds, 0 means idle timer is disabled
|
||||
int32_t idleTime; // milliseconds, 0 means idle timer is disabled
|
||||
|
||||
// the following is for client app ecurity only
|
||||
char *user; // user name
|
||||
|
@ -108,9 +108,9 @@ int32_t rpcInit();
|
|||
void rpcCleanup();
|
||||
void * rpcOpen(const SRpcInit *pRpc);
|
||||
void rpcClose(void *);
|
||||
void * rpcMallocCont(int contLen);
|
||||
void * rpcMallocCont(int32_t contLen);
|
||||
void rpcFreeCont(void *pCont);
|
||||
void * rpcReallocCont(void *ptr, int contLen);
|
||||
void * rpcReallocCont(void *ptr, int32_t contLen);
|
||||
|
||||
// Because taosd supports multi-process mode
|
||||
// These functions should not be used on the server side
|
||||
|
@ -121,10 +121,10 @@ void rpcRegisterBrokenLinkArg(SRpcMsg *msg);
|
|||
void rpcReleaseHandle(void *handle, int8_t type); // just release client conn to rpc instance, no close sock
|
||||
|
||||
// These functions will not be called in the child process
|
||||
void rpcSendRedirectRsp(void *pConn, const SEpSet *pEpSet);
|
||||
void rpcSendRequestWithCtx(void *thandle, const SEpSet *pEpSet, SRpcMsg *pMsg, int64_t *rid, SRpcCtx *ctx);
|
||||
int rpcGetConnInfo(void *thandle, SRpcConnInfo *pInfo);
|
||||
void rpcSendRecv(void *shandle, SEpSet *pEpSet, SRpcMsg *pReq, SRpcMsg *pRsp);
|
||||
void rpcSendRedirectRsp(void *pConn, const SEpSet *pEpSet);
|
||||
void rpcSendRequestWithCtx(void *thandle, const SEpSet *pEpSet, SRpcMsg *pMsg, int64_t *rid, SRpcCtx *ctx);
|
||||
int32_t rpcGetConnInfo(void *thandle, SRpcConnInfo *pInfo);
|
||||
void rpcSendRecv(void *shandle, SEpSet *pEpSet, SRpcMsg *pReq, SRpcMsg *pRsp);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -253,6 +253,7 @@ int32_t* taosGetErrno();
|
|||
#define TSDB_CODE_MND_TRANS_INVALID_STAGE TAOS_DEF_ERROR_CODE(0, 0x03D2)
|
||||
#define TSDB_CODE_MND_TRANS_CONFLICT TAOS_DEF_ERROR_CODE(0, 0x03D3)
|
||||
#define TSDB_CODE_MND_TRANS_UNKNOW_ERROR TAOS_DEF_ERROR_CODE(0, 0x03D4)
|
||||
#define TSDB_CODE_MND_TRANS_CLOG_IS_NULL TAOS_DEF_ERROR_CODE(0, 0x03D5)
|
||||
|
||||
// mnode-mq
|
||||
#define TSDB_CODE_MND_TOPIC_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x03E0)
|
||||
|
@ -638,6 +639,7 @@ int32_t* taosGetErrno();
|
|||
#define TSDB_CODE_PAR_NOT_ALLOWED_FUNC TAOS_DEF_ERROR_CODE(0, 0x264F)
|
||||
#define TSDB_CODE_PAR_NOT_ALLOWED_WIN_QUERY TAOS_DEF_ERROR_CODE(0, 0x2650)
|
||||
#define TSDB_CODE_PAR_INVALID_DROP_COL TAOS_DEF_ERROR_CODE(0, 0x2651)
|
||||
#define TSDB_CODE_PAR_INVALID_COL_JSON TAOS_DEF_ERROR_CODE(0, 0x2652)
|
||||
|
||||
//planner
|
||||
#define TSDB_CODE_PLAN_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x2700)
|
||||
|
|
|
@ -132,6 +132,7 @@ typedef enum EOperatorType {
|
|||
OP_TYPE_MOD,
|
||||
// unary arithmetic operator
|
||||
OP_TYPE_MINUS,
|
||||
OP_TYPE_ASSIGN,
|
||||
|
||||
// bit operator
|
||||
OP_TYPE_BIT_AND,
|
||||
|
@ -233,6 +234,7 @@ typedef enum ELogicConditionType {
|
|||
#define TSDB_MAX_TAG_CONDITIONS 1024
|
||||
|
||||
#define TSDB_MAX_JSON_TAG_LEN 16384
|
||||
#define TSDB_MAX_JSON_KEY_LEN 256
|
||||
|
||||
#define TSDB_AUTH_LEN 16
|
||||
#define TSDB_PASSWORD_LEN 32
|
||||
|
|
|
@ -39,11 +39,11 @@ typedef struct {
|
|||
} SEncoder;
|
||||
|
||||
typedef struct {
|
||||
const uint8_t* data;
|
||||
uint32_t size;
|
||||
uint32_t pos;
|
||||
SCoderMem* mList;
|
||||
SDecoderNode* dStack;
|
||||
uint8_t* data;
|
||||
uint32_t size;
|
||||
uint32_t pos;
|
||||
SCoderMem* mList;
|
||||
SDecoderNode* dStack;
|
||||
} SDecoder;
|
||||
|
||||
#define tPut(TYPE, BUF, VAL) ((TYPE*)(BUF))[0] = (VAL)
|
||||
|
@ -82,7 +82,7 @@ typedef struct {
|
|||
do { \
|
||||
SEncoder coder = {0}; \
|
||||
tEncoderInit(&coder, NULL, 0); \
|
||||
if ((E)(&coder, S) == 0) { \
|
||||
if ((E)(&coder, S) >= 0) { \
|
||||
SIZE = coder.pos; \
|
||||
RET = 0; \
|
||||
} else { \
|
||||
|
@ -120,7 +120,7 @@ static int32_t tEncodeCStrWithLen(SEncoder* pCoder, const char* val, uint32_t le
|
|||
static int32_t tEncodeCStr(SEncoder* pCoder, const char* val);
|
||||
|
||||
/* ------------------------ DECODE ------------------------ */
|
||||
void tDecoderInit(SDecoder* pCoder, const uint8_t* data, uint32_t size);
|
||||
void tDecoderInit(SDecoder* pCoder, uint8_t* data, uint32_t size);
|
||||
void tDecoderClear(SDecoder* SDecoder);
|
||||
int32_t tStartDecode(SDecoder* pCoder);
|
||||
void tEndDecode(SDecoder* pCoder);
|
||||
|
@ -141,9 +141,9 @@ static int32_t tDecodeU64v(SDecoder* pCoder, uint64_t* val);
|
|||
static int32_t tDecodeI64v(SDecoder* pCoder, int64_t* val);
|
||||
static int32_t tDecodeFloat(SDecoder* pCoder, float* val);
|
||||
static int32_t tDecodeDouble(SDecoder* pCoder, double* val);
|
||||
static int32_t tDecodeBinary(SDecoder* pCoder, const uint8_t** val, uint32_t* len);
|
||||
static int32_t tDecodeCStrAndLen(SDecoder* pCoder, const char** val, uint32_t* len);
|
||||
static int32_t tDecodeCStr(SDecoder* pCoder, const char** val);
|
||||
static int32_t tDecodeBinary(SDecoder* pCoder, uint8_t** val, uint32_t* len);
|
||||
static int32_t tDecodeCStrAndLen(SDecoder* pCoder, char** val, uint32_t* len);
|
||||
static int32_t tDecodeCStr(SDecoder* pCoder, char** val);
|
||||
static int32_t tDecodeCStrTo(SDecoder* pCoder, char* val);
|
||||
|
||||
/* ------------------------ IMPL ------------------------ */
|
||||
|
@ -317,7 +317,7 @@ static FORCE_INLINE int32_t tDecodeI16v(SDecoder* pCoder, int16_t* val) {
|
|||
if (tDecodeU16v(pCoder, &tval) < 0) {
|
||||
return -1;
|
||||
}
|
||||
*val = ZIGZAGD(int16_t, tval);
|
||||
if (val) *val = ZIGZAGD(int16_t, tval);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -331,7 +331,7 @@ static FORCE_INLINE int32_t tDecodeI32v(SDecoder* pCoder, int32_t* val) {
|
|||
if (tDecodeU32v(pCoder, &tval) < 0) {
|
||||
return -1;
|
||||
}
|
||||
*val = ZIGZAGD(int32_t, tval);
|
||||
if (val) *val = ZIGZAGD(int32_t, tval);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -345,7 +345,7 @@ static FORCE_INLINE int32_t tDecodeI64v(SDecoder* pCoder, int64_t* val) {
|
|||
if (tDecodeU64v(pCoder, &tval) < 0) {
|
||||
return -1;
|
||||
}
|
||||
*val = ZIGZAGD(int64_t, tval);
|
||||
if (val) *val = ZIGZAGD(int64_t, tval);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -377,7 +377,7 @@ static FORCE_INLINE int32_t tDecodeDouble(SDecoder* pCoder, double* val) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tDecodeBinary(SDecoder* pCoder, const uint8_t** val, uint32_t* len) {
|
||||
static FORCE_INLINE int32_t tDecodeBinary(SDecoder* pCoder, uint8_t** val, uint32_t* len) {
|
||||
if (tDecodeU32v(pCoder, len) < 0) return -1;
|
||||
|
||||
if (TD_CODER_CHECK_CAPACITY_FAILED(pCoder, *len)) return -1;
|
||||
|
@ -389,20 +389,20 @@ static FORCE_INLINE int32_t tDecodeBinary(SDecoder* pCoder, const uint8_t** val,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tDecodeCStrAndLen(SDecoder* pCoder, const char** val, uint32_t* len) {
|
||||
if (tDecodeBinary(pCoder, (const uint8_t**)val, len) < 0) return -1;
|
||||
static FORCE_INLINE int32_t tDecodeCStrAndLen(SDecoder* pCoder, char** val, uint32_t* len) {
|
||||
if (tDecodeBinary(pCoder, (uint8_t**)val, len) < 0) return -1;
|
||||
(*len) -= 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tDecodeCStr(SDecoder* pCoder, const char** val) {
|
||||
static FORCE_INLINE int32_t tDecodeCStr(SDecoder* pCoder, char** val) {
|
||||
uint32_t len;
|
||||
return tDecodeCStrAndLen(pCoder, val, &len);
|
||||
}
|
||||
|
||||
static int32_t tDecodeCStrTo(SDecoder* pCoder, char* val) {
|
||||
const char* pStr;
|
||||
uint32_t len;
|
||||
char* pStr;
|
||||
uint32_t len;
|
||||
if (tDecodeCStrAndLen(pCoder, &pStr, &len) < 0) return -1;
|
||||
|
||||
memcpy(val, pStr, len + 1);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -121,7 +121,7 @@ struct SAppInstInfo {
|
|||
SCorEpSet mgmtEp;
|
||||
SInstanceSummary summary;
|
||||
SList* pConnList; // STscObj linked list
|
||||
int64_t clusterId;
|
||||
uint64_t clusterId;
|
||||
void* pTransporter;
|
||||
SAppHbMgr* pAppHbMgr;
|
||||
};
|
||||
|
@ -286,6 +286,8 @@ void initMsgHandleFp();
|
|||
TAOS* taos_connect_internal(const char* ip, const char* user, const char* pass, const char* auth, const char* db,
|
||||
uint16_t port, int connType);
|
||||
|
||||
SRequestObj* launchQuery(STscObj* pTscObj, const char* sql, int sqlLen);
|
||||
|
||||
int32_t parseSql(SRequestObj* pRequest, bool topicQuery, SQuery** pQuery, SStmtCallback* pStmtCb);
|
||||
|
||||
int32_t getPlan(SRequestObj* pRequest, SQuery* pQuery, SQueryPlan** pPlan, SArray* pNodeList);
|
||||
|
|
|
@ -866,8 +866,7 @@ static char* parseTagDatatoJson(void* p) {
|
|||
if (j == 0) {
|
||||
if (*val == TSDB_DATA_TYPE_NULL) {
|
||||
string = taosMemoryCalloc(1, 8);
|
||||
sprintf(varDataVal(string), "%s", TSDB_DATA_NULL_STR_L);
|
||||
varDataSetLen(string, strlen(varDataVal(string)));
|
||||
sprintf(string, "%s", TSDB_DATA_NULL_STR_L);
|
||||
goto end;
|
||||
}
|
||||
continue;
|
||||
|
@ -1003,7 +1002,7 @@ static int32_t doConvertUCS4(SReqResultInfo* pResultInfo, int32_t numOfRows, int
|
|||
length = 0;
|
||||
}
|
||||
varDataSetLen(dst, length + CHAR_BYTES * 2);
|
||||
*(char*)(varDataVal(dst), length + CHAR_BYTES) = '\"';
|
||||
*(char*)POINTER_SHIFT(varDataVal(dst), length + CHAR_BYTES) = '\"';
|
||||
} else if (jsonInnerType == TSDB_DATA_TYPE_DOUBLE) {
|
||||
double jsonVd = *(double*)(jsonInnerData);
|
||||
sprintf(varDataVal(dst), "%.9lf", jsonVd);
|
||||
|
|
|
@ -565,10 +565,32 @@ const char *taos_get_server_info(TAOS *taos) {
|
|||
|
||||
void taos_query_a(TAOS *taos, const char *sql, __taos_async_fn_t fp, void *param) {
|
||||
if (taos == NULL || sql == NULL) {
|
||||
// todo directly call fp
|
||||
fp(param, NULL, TSDB_CODE_INVALID_PARA);
|
||||
return;
|
||||
}
|
||||
|
||||
taos_query_l(taos, sql, (int32_t)strlen(sql));
|
||||
SRequestObj* pRequest = NULL;
|
||||
int32_t retryNum = 0;
|
||||
int32_t code = 0;
|
||||
|
||||
size_t sqlLen = strlen(sql);
|
||||
|
||||
while (retryNum++ < REQUEST_MAX_TRY_TIMES) {
|
||||
pRequest = launchQuery(taos, sql, sqlLen);
|
||||
if (pRequest == NULL || TSDB_CODE_SUCCESS == pRequest->code || !NEED_CLIENT_HANDLE_ERROR(pRequest->code)) {
|
||||
break;
|
||||
}
|
||||
|
||||
code = refreshMeta(taos, pRequest);
|
||||
if (code) {
|
||||
pRequest->code = code;
|
||||
break;
|
||||
}
|
||||
|
||||
destroyRequest(pRequest);
|
||||
}
|
||||
|
||||
fp(param, pRequest, code);
|
||||
}
|
||||
|
||||
void taos_fetch_rows_a(TAOS_RES *res, __taos_async_fn_t fp, void *param) {
|
||||
|
|
|
@ -125,10 +125,10 @@ int32_t processUseDbRsp(void* param, const SDataBuf* pMsg, int32_t code) {
|
|||
struct SCatalog* pCatalog = NULL;
|
||||
|
||||
if (usedbRsp.vgVersion >= 0) {
|
||||
int32_t code1 = catalogGetHandle(pRequest->pTscObj->pAppInfo->clusterId, &pCatalog);
|
||||
uint64_t clusterId = pRequest->pTscObj->pAppInfo->clusterId;
|
||||
int32_t code1 = catalogGetHandle(clusterId, &pCatalog);
|
||||
if (code1 != TSDB_CODE_SUCCESS) {
|
||||
tscWarn("catalogGetHandle failed, clusterId:%" PRIx64 ", error:%s", pRequest->pTscObj->pAppInfo->clusterId,
|
||||
tstrerror(code1));
|
||||
tscWarn("0x%" PRIx64 "catalogGetHandle failed, clusterId:%" PRIx64 ", error:%s", pRequest->requestId, clusterId, tstrerror(code1));
|
||||
} else {
|
||||
catalogRemoveDB(pCatalog, usedbRsp.db, usedbRsp.uid);
|
||||
}
|
||||
|
@ -158,7 +158,7 @@ int32_t processUseDbRsp(void* param, const SDataBuf* pMsg, int32_t code) {
|
|||
if (output.dbVgroup) taosHashCleanup(output.dbVgroup->vgHash);
|
||||
taosMemoryFreeClear(output.dbVgroup);
|
||||
|
||||
tscError("failed to build use db output since %s", terrstr());
|
||||
tscError("0x%" PRIx64" failed to build use db output since %s", pRequest->requestId, terrstr());
|
||||
} else if (output.dbVgroup) {
|
||||
struct SCatalog* pCatalog = NULL;
|
||||
|
||||
|
|
|
@ -1538,7 +1538,7 @@ int32_t buildSubmitReqFromDataBlock(SSubmitReq** pReq, const SArray* pDataBlocks
|
|||
int32_t msgLen = sizeof(SSubmitReq);
|
||||
int32_t numOfBlks = 0;
|
||||
SRowBuilder rb = {0};
|
||||
tdSRowInit(&rb, 0); // TODO: use the latest version
|
||||
tdSRowInit(&rb, pTSchema->version); // TODO: use the latest version
|
||||
|
||||
for (int32_t i = 0; i < sz; ++i) {
|
||||
SSDataBlock* pDataBlock = taosArrayGet(pDataBlocks, i);
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#undef TD_MSG_SEG_CODE_
|
||||
#include "tmsgdef.h"
|
||||
|
||||
int32_t tInitSubmitMsgIter(const SSubmitReq *pMsg, SSubmitMsgIter *pIter) {
|
||||
int32_t tInitSubmitMsgIter(SSubmitReq *pMsg, SSubmitMsgIter *pIter) {
|
||||
if (pMsg == NULL) {
|
||||
terrno = TSDB_CODE_TDB_SUBMIT_MSG_MSSED_UP;
|
||||
return -1;
|
||||
|
@ -102,7 +102,7 @@ STSRow *tGetSubmitBlkNext(SSubmitBlkIter *pIter) {
|
|||
}
|
||||
}
|
||||
|
||||
int32_t tPrintFixedSchemaSubmitReq(const SSubmitReq *pReq, STSchema *pTschema) {
|
||||
int32_t tPrintFixedSchemaSubmitReq(SSubmitReq *pReq, STSchema *pTschema) {
|
||||
SSubmitMsgIter msgIter = {0};
|
||||
if (tInitSubmitMsgIter(pReq, &msgIter) < 0) return -1;
|
||||
while (true) {
|
||||
|
@ -3817,7 +3817,7 @@ int tDecodeSVCreateStbReq(SDecoder *pCoder, SVCreateStbReq *pReq) {
|
|||
|
||||
STSchema *tdGetSTSChemaFromSSChema(SSchema **pSchema, int32_t nCols) {
|
||||
STSchemaBuilder schemaBuilder = {0};
|
||||
if (tdInitTSchemaBuilder(&schemaBuilder, 0) < 0) {
|
||||
if (tdInitTSchemaBuilder(&schemaBuilder, 1) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -924,7 +924,7 @@ void tdSRowPrint(STSRow *row, STSchema *pSchema, const char *tag) {
|
|||
STSRowIter iter = {0};
|
||||
tdSTSRowIterInit(&iter, pSchema);
|
||||
tdSTSRowIterReset(&iter, row);
|
||||
printf("%s >>>", tag);
|
||||
printf("%s >>>type:%d,sver:%d ", tag, (int32_t)TD_ROW_TYPE(row), (int32_t)TD_ROW_SVER(row));
|
||||
for (int i = 0; i < pSchema->numOfCols; ++i) {
|
||||
STColumn *stCol = pSchema->columns + i;
|
||||
SCellVal sVal = {255, NULL};
|
||||
|
|
|
@ -24,19 +24,22 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
typedef struct SMnodeMgmt {
|
||||
SDnodeData *pData;
|
||||
SMnode *pMnode;
|
||||
SMsgCb msgCb;
|
||||
const char *path;
|
||||
const char *name;
|
||||
SSingleWorker queryWorker;
|
||||
SSingleWorker readWorker;
|
||||
SSingleWorker writeWorker;
|
||||
SSingleWorker syncWorker;
|
||||
SSingleWorker monitorWorker;
|
||||
SReplica replicas[TSDB_MAX_REPLICA];
|
||||
int8_t replica;
|
||||
int8_t selfIndex;
|
||||
SDnodeData *pData;
|
||||
SMnode *pMnode;
|
||||
SMsgCb msgCb;
|
||||
const char *path;
|
||||
const char *name;
|
||||
SSingleWorker queryWorker;
|
||||
SSingleWorker readWorker;
|
||||
SSingleWorker writeWorker;
|
||||
SSingleWorker syncWorker;
|
||||
SSingleWorker monitorWorker;
|
||||
SReplica replicas[TSDB_MAX_REPLICA];
|
||||
int8_t replica;
|
||||
int8_t selfIndex;
|
||||
bool stopped;
|
||||
int32_t refCount;
|
||||
TdThreadRwlock lock;
|
||||
} SMnodeMgmt;
|
||||
|
||||
// mmFile.c
|
||||
|
@ -45,6 +48,8 @@ int32_t mmWriteFile(SMnodeMgmt *pMgmt, SDCreateMnodeReq *pMsg, bool deployed);
|
|||
|
||||
// mmInt.c
|
||||
int32_t mmAlter(SMnodeMgmt *pMgmt, SDAlterMnodeReq *pMsg);
|
||||
int32_t mmAcquire(SMnodeMgmt *pMgmt);
|
||||
void mmRelease(SMnodeMgmt *pMgmt);
|
||||
|
||||
// mmHandle.c
|
||||
SArray *mmGetMsgHandles();
|
||||
|
|
|
@ -237,6 +237,16 @@ SArray *mmGetMsgHandles() {
|
|||
if (dmSetMgmtHandle(pArray, TDMT_VND_SYNC_VNODE_RSP, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_VND_COMPACT_VNODE_RSP, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||
|
||||
if (dmSetMgmtHandle(pArray, TDMT_VND_SYNC_TIMEOUT, mmPutNodeMsgToSyncQueue, 1) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_VND_SYNC_PING, mmPutNodeMsgToSyncQueue, 1) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_VND_SYNC_PING_REPLY, mmPutNodeMsgToSyncQueue, 1) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_VND_SYNC_CLIENT_REQUEST, mmPutNodeMsgToSyncQueue, 1) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_VND_SYNC_CLIENT_REQUEST_REPLY, mmPutNodeMsgToSyncQueue, 1) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_VND_SYNC_REQUEST_VOTE, mmPutNodeMsgToSyncQueue, 1) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_VND_SYNC_REQUEST_VOTE_REPLY, mmPutNodeMsgToSyncQueue, 1) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_VND_SYNC_APPEND_ENTRIES, mmPutNodeMsgToSyncQueue, 1) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_VND_SYNC_APPEND_ENTRIES_REPLY, mmPutNodeMsgToSyncQueue, 1) == NULL) goto _OVER;
|
||||
|
||||
code = 0;
|
||||
|
||||
_OVER:
|
||||
|
|
|
@ -110,6 +110,7 @@ static void mmClose(SMnodeMgmt *pMgmt) {
|
|||
if (pMgmt->pMnode != NULL) {
|
||||
mmStopWorker(pMgmt);
|
||||
mndClose(pMgmt->pMnode);
|
||||
taosThreadRwlockDestroy(&pMgmt->lock);
|
||||
pMgmt->pMnode = NULL;
|
||||
}
|
||||
|
||||
|
@ -122,6 +123,11 @@ static int32_t mmOpen(SMgmtInputOpt *pInput, SMgmtOutputOpt *pOutput) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (syncInit() != 0) {
|
||||
dError("failed to init sync since %s", terrstr());
|
||||
return -1;
|
||||
}
|
||||
|
||||
SMnodeMgmt *pMgmt = taosMemoryCalloc(1, sizeof(SMnodeMgmt));
|
||||
if (pMgmt == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
|
@ -137,6 +143,7 @@ static int32_t mmOpen(SMgmtInputOpt *pInput, SMgmtOutputOpt *pOutput) {
|
|||
pMgmt->msgCb.queueFps[WRITE_QUEUE] = (PutToQueueFp)mmPutRpcMsgToWriteQueue;
|
||||
pMgmt->msgCb.queueFps[SYNC_QUEUE] = (PutToQueueFp)mmPutRpcMsgToSyncQueue;
|
||||
pMgmt->msgCb.mgmt = pMgmt;
|
||||
taosThreadRwlockInit(&pMgmt->lock, NULL);
|
||||
|
||||
bool deployed = false;
|
||||
if (mmReadFile(pMgmt, &deployed) != 0) {
|
||||
|
@ -206,3 +213,22 @@ SMgmtFunc mmGetMgmtFunc() {
|
|||
|
||||
return mgmtFunc;
|
||||
}
|
||||
|
||||
int32_t mmAcquire(SMnodeMgmt *pMgmt) {
|
||||
int32_t code = 0;
|
||||
|
||||
taosThreadRwlockRdlock(&pMgmt->lock);
|
||||
if (pMgmt->stopped) {
|
||||
code = -1;
|
||||
} else {
|
||||
atomic_add_fetch_32(&pMgmt->refCount, 1);
|
||||
}
|
||||
taosThreadRwlockUnlock(&pMgmt->lock);
|
||||
return code;
|
||||
}
|
||||
|
||||
void mmRelease(SMnodeMgmt *pMgmt) {
|
||||
taosThreadRwlockRdlock(&pMgmt->lock);
|
||||
atomic_sub_fetch_32(&pMgmt->refCount, 1);
|
||||
taosThreadRwlockUnlock(&pMgmt->lock);
|
||||
}
|
|
@ -56,6 +56,12 @@ static void mmProcessQueue(SQueueInfo *pInfo, SRpcMsg *pMsg) {
|
|||
taosFreeQitem(pMsg);
|
||||
}
|
||||
|
||||
static void mmProcessSyncQueue(SQueueInfo *pInfo, SRpcMsg *pMsg) {
|
||||
SMnodeMgmt *pMgmt = pInfo->ahandle;
|
||||
pMsg->info.node = pMgmt->pMnode;
|
||||
mndProcessSyncMsg(pMsg);
|
||||
}
|
||||
|
||||
static int32_t mmPutNodeMsgToWorker(SSingleWorker *pWorker, SRpcMsg *pMsg) {
|
||||
dTrace("msg:%p, put into worker %s, type:%s", pMsg, pWorker->name, TMSG_INFO(pMsg->msgType));
|
||||
taosWriteQitem(pWorker->queue, pMsg);
|
||||
|
@ -105,7 +111,10 @@ int32_t mmPutRpcMsgToReadQueue(SMnodeMgmt *pMgmt, SRpcMsg *pMsg) {
|
|||
}
|
||||
|
||||
int32_t mmPutRpcMsgToSyncQueue(SMnodeMgmt *pMgmt, SRpcMsg *pMsg) {
|
||||
return mmPutRpcMsgToWorker(&pMgmt->syncWorker, pMsg);
|
||||
if (mmAcquire(pMgmt) != 0) return -1;
|
||||
int32_t code = mmPutRpcMsgToWorker(&pMgmt->syncWorker, pMsg);
|
||||
mmRelease(pMgmt);
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t mmStartWorker(SMnodeMgmt *pMgmt) {
|
||||
|
@ -149,7 +158,7 @@ int32_t mmStartWorker(SMnodeMgmt *pMgmt) {
|
|||
.min = 1,
|
||||
.max = 1,
|
||||
.name = "mnode-sync",
|
||||
.fp = (FItem)mmProcessQueue,
|
||||
.fp = (FItem)mmProcessSyncQueue,
|
||||
.param = pMgmt,
|
||||
};
|
||||
if (tSingleWorkerInit(&pMgmt->syncWorker, &sCfg) != 0) {
|
||||
|
@ -174,6 +183,11 @@ int32_t mmStartWorker(SMnodeMgmt *pMgmt) {
|
|||
}
|
||||
|
||||
void mmStopWorker(SMnodeMgmt *pMgmt) {
|
||||
taosThreadRwlockWrlock(&pMgmt->lock);
|
||||
pMgmt->stopped = 1;
|
||||
taosThreadRwlockUnlock(&pMgmt->lock);
|
||||
while (pMgmt->refCount > 0) taosMsleep(10);
|
||||
|
||||
tSingleWorkerCleanup(&pMgmt->monitorWorker);
|
||||
tSingleWorkerCleanup(&pMgmt->queryWorker);
|
||||
tSingleWorkerCleanup(&pMgmt->readWorker);
|
||||
|
|
|
@ -113,6 +113,8 @@ static void vmProcessWriteQueue(SQueueInfo *pInfo, STaosQall *qall, int32_t numO
|
|||
SRpcMsg *pMsg = *(SRpcMsg **)taosArrayGet(pArray, i);
|
||||
SRpcMsg rsp = {.info = pMsg->info};
|
||||
|
||||
vnodePreprocessReq(pVnode->pImpl, pMsg);
|
||||
|
||||
int32_t ret = syncPropose(vnodeGetSyncHandle(pVnode->pImpl), pMsg, false);
|
||||
if (ret == TAOS_SYNC_PROPOSE_NOT_LEADER) {
|
||||
dTrace("msg:%p, is redirect since not leader, vgId:%d ", pMsg, pVnode->vgId);
|
||||
|
|
|
@ -4,7 +4,7 @@ target_link_libraries(
|
|||
dmnodeTest sut
|
||||
)
|
||||
|
||||
add_test(
|
||||
NAME dmnodeTest
|
||||
COMMAND dmnodeTest
|
||||
)
|
||||
#add_test(
|
||||
# NAME dmnodeTest
|
||||
# COMMAND dmnodeTest
|
||||
#)
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "mndDef.h"
|
||||
|
||||
#include "sdb.h"
|
||||
#include "syncTools.h"
|
||||
#include "tcache.h"
|
||||
#include "tdatablock.h"
|
||||
#include "tglobal.h"
|
||||
|
@ -31,12 +32,14 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
// clang-format off
|
||||
#define mFatal(...) { if (mDebugFlag & DEBUG_FATAL) { taosPrintLog("MND FATAL ", DEBUG_FATAL, 255, __VA_ARGS__); }}
|
||||
#define mError(...) { if (mDebugFlag & DEBUG_ERROR) { taosPrintLog("MND ERROR ", DEBUG_ERROR, 255, __VA_ARGS__); }}
|
||||
#define mWarn(...) { if (mDebugFlag & DEBUG_WARN) { taosPrintLog("MND WARN ", DEBUG_WARN, 255, __VA_ARGS__); }}
|
||||
#define mInfo(...) { if (mDebugFlag & DEBUG_INFO) { taosPrintLog("MND ", DEBUG_INFO, 255, __VA_ARGS__); }}
|
||||
#define mDebug(...) { if (mDebugFlag & DEBUG_DEBUG) { taosPrintLog("MND ", DEBUG_DEBUG, mDebugFlag, __VA_ARGS__); }}
|
||||
#define mTrace(...) { if (mDebugFlag & DEBUG_TRACE) { taosPrintLog("MND ", DEBUG_TRACE, mDebugFlag, __VA_ARGS__); }}
|
||||
// clang-format on
|
||||
|
||||
#define SYSTABLE_SCH_TABLE_NAME_LEN ((TSDB_TABLE_NAME_LEN - 1) + VARSTR_HEADER_SIZE)
|
||||
#define SYSTABLE_SCH_DB_NAME_LEN ((TSDB_DB_NAME_LEN - 1) + VARSTR_HEADER_SIZE)
|
||||
|
@ -72,10 +75,11 @@ typedef struct {
|
|||
} STelemMgmt;
|
||||
|
||||
typedef struct {
|
||||
int32_t errCode;
|
||||
sem_t syncSem;
|
||||
SWal *pWal;
|
||||
SSyncNode *pSyncNode;
|
||||
int32_t errCode;
|
||||
bool restored;
|
||||
sem_t syncSem;
|
||||
int64_t sync;
|
||||
ESyncState state;
|
||||
} SSyncMgmt;
|
||||
|
||||
|
|
|
@ -26,6 +26,8 @@ int32_t mndInitSync(SMnode *pMnode);
|
|||
void mndCleanupSync(SMnode *pMnode);
|
||||
bool mndIsMaster(SMnode *pMnode);
|
||||
int32_t mndSyncPropose(SMnode *pMnode, SSdbRaw *pRaw);
|
||||
void mndSyncStart(SMnode *pMnode);
|
||||
void mndSyncStop(SMnode *pMnode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ int32_t mndDropTopicByDB(SMnode *pMnode, STrans *pTrans, SDbObj *pDb);
|
|||
|
||||
const char *mndTopicGetShowName(const char topic[TSDB_TOPIC_FNAME_LEN]);
|
||||
|
||||
int32_t mndSetTopicRedoLogs(SMnode *pMnode, STrans *pTrans, SMqTopicObj *pTopic);
|
||||
int32_t mndSetTopicCommitLogs(SMnode *pMnode, STrans *pTrans, SMqTopicObj *pTopic);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -419,7 +419,7 @@ static int32_t mndProcessSubscribeReq(SRpcMsg *pMsg) {
|
|||
SMqTopicObj topicObj = {0};
|
||||
memcpy(&topicObj, pTopic, sizeof(SMqTopicObj));
|
||||
topicObj.refConsumerCnt = pTopic->refConsumerCnt + 1;
|
||||
if (mndSetTopicRedoLogs(pMnode, pTrans, &topicObj) != 0) goto SUBSCRIBE_OVER;
|
||||
if (mndSetTopicCommitLogs(pMnode, pTrans, &topicObj) != 0) goto SUBSCRIBE_OVER;
|
||||
|
||||
mndReleaseTopic(pMnode, pTopic);
|
||||
}
|
||||
|
|
|
@ -448,13 +448,13 @@ static int32_t mndCreateDnode(SMnode *pMnode, SRpcMsg *pReq, SCreateDnodeReq *pC
|
|||
}
|
||||
mDebug("trans:%d, used to create dnode:%s", pTrans->id, dnodeObj.ep);
|
||||
|
||||
SSdbRaw *pRedoRaw = mndDnodeActionEncode(&dnodeObj);
|
||||
if (pRedoRaw == NULL || mndTransAppendRedolog(pTrans, pRedoRaw) != 0) {
|
||||
mError("trans:%d, failed to append redo log since %s", pTrans->id, terrstr());
|
||||
SSdbRaw *pCommitRaw = mndDnodeActionEncode(&dnodeObj);
|
||||
if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
|
||||
mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
|
||||
mndTransDrop(pTrans);
|
||||
return -1;
|
||||
}
|
||||
sdbSetRawStatus(pRedoRaw, SDB_STATUS_READY);
|
||||
sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
|
||||
|
||||
if (mndTransPrepare(pMnode, pTrans) != 0) {
|
||||
mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
|
||||
|
@ -524,13 +524,13 @@ static int32_t mndDropDnode(SMnode *pMnode, SRpcMsg *pReq, SDnodeObj *pDnode) {
|
|||
}
|
||||
mDebug("trans:%d, used to drop dnode:%d", pTrans->id, pDnode->id);
|
||||
|
||||
SSdbRaw *pRedoRaw = mndDnodeActionEncode(pDnode);
|
||||
if (pRedoRaw == NULL || mndTransAppendRedolog(pTrans, pRedoRaw) != 0) {
|
||||
mError("trans:%d, failed to append redo log since %s", pTrans->id, terrstr());
|
||||
SSdbRaw *pCommitRaw = mndDnodeActionEncode(pDnode);
|
||||
if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
|
||||
mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
|
||||
mndTransDrop(pTrans);
|
||||
return -1;
|
||||
}
|
||||
sdbSetRawStatus(pRedoRaw, SDB_STATUS_DROPPED);
|
||||
sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED);
|
||||
|
||||
if (mndTransPrepare(pMnode, pTrans) != 0) {
|
||||
mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
|
||||
|
|
|
@ -153,6 +153,7 @@ int32_t mndCreateOffsets(STrans *pTrans, const char *cgroup, const char *topicNa
|
|||
return -1;
|
||||
}
|
||||
sdbSetRawStatus(pOffsetRaw, SDB_STATUS_READY);
|
||||
// commit log or redo log?
|
||||
if (mndTransAppendRedolog(pTrans, pOffsetRaw) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -188,7 +189,7 @@ static int32_t mndProcessCommitOffsetReq(SRpcMsg *pMsg) {
|
|||
pOffsetObj->offset = pOffset->offset;
|
||||
SSdbRaw *pOffsetRaw = mndOffsetActionEncode(pOffsetObj);
|
||||
sdbSetRawStatus(pOffsetRaw, SDB_STATUS_READY);
|
||||
mndTransAppendRedolog(pTrans, pOffsetRaw);
|
||||
mndTransAppendCommitlog(pTrans, pOffsetRaw);
|
||||
if (create) {
|
||||
taosMemoryFree(pOffsetObj);
|
||||
} else {
|
||||
|
|
|
@ -743,9 +743,7 @@ static int32_t mndCreateStb(SMnode *pMnode, SRpcMsg *pReq, SMCreateStbReq *pCrea
|
|||
|
||||
mDebug("trans:%d, used to create stb:%s", pTrans->id, pCreate->name);
|
||||
|
||||
if (mndBuildStbFromReq(pMnode, &stbObj, pCreate, pDb) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
if (mndBuildStbFromReq(pMnode, &stbObj, pCreate, pDb) != 0) goto _OVER;
|
||||
|
||||
if (mndAddStbToTrans(pMnode, pTrans, pDb, &stbObj) < 0) goto _OVER;
|
||||
|
||||
|
|
|
@ -279,13 +279,13 @@ int32_t mndAddStreamToTrans(SMnode *pMnode, SStreamObj *pStream, const char *ast
|
|||
}
|
||||
mDebug("trans:%d, used to create stream:%s", pTrans->id, pStream->name);
|
||||
|
||||
SSdbRaw *pRedoRaw = mndStreamActionEncode(pStream);
|
||||
if (pRedoRaw == NULL || mndTransAppendRedolog(pTrans, pRedoRaw) != 0) {
|
||||
mError("trans:%d, failed to append redo log since %s", pTrans->id, terrstr());
|
||||
SSdbRaw *pCommitRaw = mndStreamActionEncode(pStream);
|
||||
if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
|
||||
mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
|
||||
mndTransDrop(pTrans);
|
||||
return -1;
|
||||
}
|
||||
sdbSetRawStatus(pRedoRaw, SDB_STATUS_READY);
|
||||
sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -479,7 +479,7 @@ static int32_t mndPersistRebResult(SMnode *pMnode, SRpcMsg *pMsg, const SMqRebOu
|
|||
SMqTopicObj topicObj = {0};
|
||||
memcpy(&topicObj, pTopic, sizeof(SMqTopicObj));
|
||||
topicObj.refConsumerCnt = pTopic->refConsumerCnt - consumerNum;
|
||||
if (mndSetTopicRedoLogs(pMnode, pTrans, &topicObj) != 0) goto REB_FAIL;
|
||||
if (mndSetTopicCommitLogs(pMnode, pTrans, &topicObj) != 0) goto REB_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,10 +17,60 @@
|
|||
#include "mndSync.h"
|
||||
#include "mndTrans.h"
|
||||
|
||||
static int32_t mndInitWal(SMnode *pMnode) {
|
||||
int32_t mndSyncEqMsg(const SMsgCb *msgcb, SRpcMsg *pMsg) {
|
||||
int32_t code = tmsgPutToQueue(msgcb, SYNC_QUEUE, pMsg);
|
||||
if (code != 0) {
|
||||
rpcFreeCont(pMsg->pCont);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t mndSyncSendMsg(const SEpSet *pEpSet, SRpcMsg *pMsg) { return tmsgSendReq(pEpSet, pMsg); }
|
||||
|
||||
void mndSyncCommitMsg(struct SSyncFSM *pFsm, const SRpcMsg *pMsg, SFsmCbMeta cbMeta) {
|
||||
SMnode *pMnode = pFsm->data;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
SSyncMgmt *pMgmt = &pMnode->syncMgmt;
|
||||
SSdbRaw *pRaw = pMsg->pCont;
|
||||
|
||||
mTrace("ver:%" PRId64 ", apply raw:%p to sdb, role:%s", cbMeta.index, pRaw, syncStr(cbMeta.state));
|
||||
sdbWriteWithoutFree(pSdb, pRaw);
|
||||
sdbSetApplyIndex(pSdb, cbMeta.index);
|
||||
sdbSetApplyTerm(pSdb, cbMeta.term);
|
||||
if (cbMeta.state == TAOS_SYNC_STATE_LEADER) {
|
||||
tsem_post(&pMgmt->syncSem);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t mndSyncGetSnapshot(struct SSyncFSM *pFsm, SSnapshot *pSnapshot) {
|
||||
SMnode *pMnode = pFsm->data;
|
||||
pSnapshot->lastApplyIndex = sdbGetApplyIndex(pMnode->pSdb);
|
||||
pSnapshot->lastApplyTerm = sdbGetApplyTerm(pMnode->pSdb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mndRestoreFinish(struct SSyncFSM *pFsm) {
|
||||
SMnode *pMnode = pFsm->data;
|
||||
mndTransPullup(pMnode);
|
||||
pMnode->syncMgmt.restored = true;
|
||||
}
|
||||
|
||||
SSyncFSM *mndSyncMakeFsm(SMnode *pMnode) {
|
||||
SSyncFSM *pFsm = taosMemoryCalloc(1, sizeof(SSyncFSM));
|
||||
pFsm->data = pMnode;
|
||||
pFsm->FpCommitCb = mndSyncCommitMsg;
|
||||
pFsm->FpPreCommitCb = NULL;
|
||||
pFsm->FpRollBackCb = NULL;
|
||||
pFsm->FpGetSnapshot = mndSyncGetSnapshot;
|
||||
pFsm->FpRestoreFinish = mndRestoreFinish;
|
||||
pFsm->FpRestoreSnapshot = NULL;
|
||||
return pFsm;
|
||||
}
|
||||
|
||||
int32_t mndInitSync(SMnode *pMnode) {
|
||||
SSyncMgmt *pMgmt = &pMnode->syncMgmt;
|
||||
|
||||
char path[PATH_MAX] = {0};
|
||||
char path[PATH_MAX + 20] = {0};
|
||||
snprintf(path, sizeof(path), "%s%swal", pMnode->path, TD_DIRSEP);
|
||||
SWalCfg cfg = {
|
||||
.vgId = 1,
|
||||
|
@ -31,164 +81,88 @@ static int32_t mndInitWal(SMnode *pMnode) {
|
|||
.retentionSize = -1,
|
||||
.level = TAOS_WAL_FSYNC,
|
||||
};
|
||||
|
||||
pMgmt->pWal = walOpen(path, &cfg);
|
||||
if (pMgmt->pWal == NULL) return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mndCloseWal(SMnode *pMnode) {
|
||||
SSyncMgmt *pMgmt = &pMnode->syncMgmt;
|
||||
if (pMgmt->pWal != NULL) {
|
||||
walClose(pMgmt->pWal);
|
||||
pMgmt->pWal = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t mndRestoreWal(SMnode *pMnode) {
|
||||
SWal *pWal = pMnode->syncMgmt.pWal;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
int64_t lastSdbVer = sdbUpdateVer(pSdb, 0);
|
||||
int32_t code = -1;
|
||||
|
||||
SWalReadHandle *pHandle = walOpenReadHandle(pWal);
|
||||
if (pHandle == NULL) return -1;
|
||||
|
||||
int64_t first = walGetFirstVer(pWal);
|
||||
int64_t last = walGetLastVer(pWal);
|
||||
mDebug("start to restore wal, sdbver:%" PRId64 ", first:%" PRId64 " last:%" PRId64, lastSdbVer, first, last);
|
||||
|
||||
first = TMAX(lastSdbVer + 1, first);
|
||||
for (int64_t ver = first; ver >= 0 && ver <= last; ++ver) {
|
||||
if (walReadWithHandle(pHandle, ver) < 0) {
|
||||
mError("ver:%" PRId64 ", failed to read from wal since %s", ver, terrstr());
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
SWalHead *pHead = pHandle->pHead;
|
||||
int64_t sdbVer = sdbUpdateVer(pSdb, 0);
|
||||
if (sdbVer + 1 != ver) {
|
||||
terrno = TSDB_CODE_SDB_INVALID_WAl_VER;
|
||||
mError("ver:%" PRId64 ", failed to write to sdb, since inconsistent with sdbver:%" PRId64, ver, sdbVer);
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
mTrace("ver:%" PRId64 ", will be restored, content:%p", ver, pHead->head.body);
|
||||
if (sdbWriteWithoutFree(pSdb, (void *)pHead->head.body) < 0) {
|
||||
mError("ver:%" PRId64 ", failed to write to sdb since %s", ver, terrstr());
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
sdbUpdateVer(pSdb, 1);
|
||||
mDebug("ver:%" PRId64 ", is restored", ver);
|
||||
}
|
||||
|
||||
int64_t sdbVer = sdbUpdateVer(pSdb, 0);
|
||||
mDebug("restore wal finished, sdbver:%" PRId64, sdbVer);
|
||||
|
||||
mndTransPullup(pMnode);
|
||||
sdbVer = sdbUpdateVer(pSdb, 0);
|
||||
mDebug("pullup trans finished, sdbver:%" PRId64, sdbVer);
|
||||
|
||||
if (sdbVer != lastSdbVer) {
|
||||
mInfo("sdb restored from %" PRId64 " to %" PRId64 ", write file", lastSdbVer, sdbVer);
|
||||
if (sdbWriteFile(pSdb) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
if (walCommit(pWal, sdbVer) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
if (walBeginSnapshot(pWal, sdbVer) < 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
if (walEndSnapshot(pWal) < 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
}
|
||||
|
||||
code = 0;
|
||||
|
||||
_OVER:
|
||||
walCloseReadHandle(pHandle);
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t mndInitSync(SMnode *pMnode) {
|
||||
SSyncMgmt *pMgmt = &pMnode->syncMgmt;
|
||||
tsem_init(&pMgmt->syncSem, 0, 0);
|
||||
|
||||
if (mndInitWal(pMnode) < 0) {
|
||||
if (pMgmt->pWal == NULL) {
|
||||
mError("failed to open wal since %s", terrstr());
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mndRestoreWal(pMnode) < 0) {
|
||||
mError("failed to restore wal since %s", terrstr());
|
||||
SSyncInfo syncInfo = {.vgId = 1, .FpSendMsg = mndSyncSendMsg, .FpEqMsg = mndSyncEqMsg};
|
||||
snprintf(syncInfo.path, sizeof(syncInfo.path), "%s%ssync", pMnode->path, TD_DIRSEP);
|
||||
syncInfo.pWal = pMgmt->pWal;
|
||||
syncInfo.pFsm = mndSyncMakeFsm(pMnode);
|
||||
|
||||
SSyncCfg *pCfg = &syncInfo.syncCfg;
|
||||
pCfg->replicaNum = pMnode->replica;
|
||||
pCfg->myIndex = pMnode->selfIndex;
|
||||
for (int32_t i = 0; i < pMnode->replica; ++i) {
|
||||
SNodeInfo *pNode = &pCfg->nodeInfo[i];
|
||||
tstrncpy(pNode->nodeFqdn, pMnode->replicas[i].fqdn, sizeof(pNode->nodeFqdn));
|
||||
pNode->nodePort = pMnode->replicas[i].port;
|
||||
}
|
||||
|
||||
tsem_init(&pMgmt->syncSem, 0, 0);
|
||||
pMgmt->sync = syncOpen(&syncInfo);
|
||||
if (pMgmt->sync <= 0) {
|
||||
mError("failed to open sync since %s", terrstr());
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pMnode->selfId == 1) {
|
||||
pMgmt->state = TAOS_SYNC_STATE_LEADER;
|
||||
}
|
||||
pMgmt->pSyncNode = NULL;
|
||||
mDebug("mnode sync is opened, id:%" PRId64, pMgmt->sync);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mndCleanupSync(SMnode *pMnode) {
|
||||
SSyncMgmt *pMgmt = &pMnode->syncMgmt;
|
||||
syncStop(pMgmt->sync);
|
||||
mDebug("sync:%" PRId64 " is stopped", pMgmt->sync);
|
||||
|
||||
tsem_destroy(&pMgmt->syncSem);
|
||||
mndCloseWal(pMnode);
|
||||
}
|
||||
if (pMgmt->pWal != NULL) {
|
||||
walClose(pMgmt->pWal);
|
||||
}
|
||||
|
||||
static int32_t mndSyncApplyCb(struct SSyncFSM *fsm, SyncIndex index, const SSyncBuffer *buf, void *pData) {
|
||||
SMnode *pMnode = pData;
|
||||
SSyncMgmt *pMgmt = &pMnode->syncMgmt;
|
||||
|
||||
pMgmt->errCode = 0;
|
||||
tsem_post(&pMgmt->syncSem);
|
||||
|
||||
return 0;
|
||||
memset(pMgmt, 0, sizeof(SSyncMgmt));
|
||||
}
|
||||
|
||||
int32_t mndSyncPropose(SMnode *pMnode, SSdbRaw *pRaw) {
|
||||
SWal *pWal = pMnode->syncMgmt.pWal;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
|
||||
int64_t ver = sdbUpdateVer(pSdb, 1);
|
||||
if (walWrite(pWal, ver, 1, pRaw, sdbGetRawTotalSize(pRaw)) < 0) {
|
||||
sdbUpdateVer(pSdb, -1);
|
||||
mError("ver:%" PRId64 ", failed to write raw:%p to wal since %s", ver, pRaw, terrstr());
|
||||
return -1;
|
||||
}
|
||||
|
||||
mTrace("ver:%" PRId64 ", write to wal, raw:%p", ver, pRaw);
|
||||
walCommit(pWal, ver);
|
||||
walFsync(pWal, true);
|
||||
|
||||
#if 1
|
||||
return 0;
|
||||
#else
|
||||
if (pMnode->replica == 1) return 0;
|
||||
|
||||
SSyncMgmt *pMgmt = &pMnode->syncMgmt;
|
||||
pMgmt->errCode = 0;
|
||||
|
||||
SSyncBuffer buf = {.data = pRaw, .len = sdbGetRawTotalSize(pRaw)};
|
||||
SRpcMsg rsp = {.code = TDMT_MND_APPLY_MSG, .contLen = sdbGetRawTotalSize(pRaw)};
|
||||
rsp.pCont = rpcMallocCont(rsp.contLen);
|
||||
if (rsp.pCont == NULL) return -1;
|
||||
memcpy(rsp.pCont, pRaw, rsp.contLen);
|
||||
|
||||
bool isWeak = false;
|
||||
int32_t code = syncPropose(pMgmt->pSyncNode, &buf, pMnode, isWeak);
|
||||
const bool isWeak = false;
|
||||
int32_t code = syncPropose(pMgmt->sync, &rsp, isWeak);
|
||||
if (code == 0) {
|
||||
tsem_wait(&pMgmt->syncSem);
|
||||
} else if (code == TAOS_SYNC_PROPOSE_NOT_LEADER) {
|
||||
terrno = TSDB_CODE_APP_NOT_READY;
|
||||
} else if (code == TAOS_SYNC_PROPOSE_OTHER_ERROR) {
|
||||
terrno = TSDB_CODE_SYN_INTERNAL_ERROR;
|
||||
} else {
|
||||
terrno = TSDB_CODE_APP_ERROR;
|
||||
}
|
||||
|
||||
if (code != 0) return code;
|
||||
|
||||
tsem_wait(&pMgmt->syncSem);
|
||||
return pMgmt->errCode;
|
||||
#endif
|
||||
}
|
||||
|
||||
void mndSyncStart(SMnode *pMnode) {
|
||||
SSyncMgmt *pMgmt = &pMnode->syncMgmt;
|
||||
syncSetMsgCb(pMgmt->sync, &pMnode->msgCb);
|
||||
syncStart(pMgmt->sync);
|
||||
mDebug("sync:%" PRId64 " is started", pMgmt->sync);
|
||||
}
|
||||
|
||||
void mndSyncStop(SMnode *pMnode) {}
|
||||
|
||||
bool mndIsMaster(SMnode *pMnode) {
|
||||
SSyncMgmt *pMgmt = &pMnode->syncMgmt;
|
||||
return pMgmt->state == TAOS_SYNC_STATE_LEADER;
|
||||
pMgmt->state = syncGetMyRole(pMgmt->sync);
|
||||
|
||||
return (pMgmt->state == TAOS_SYNC_STATE_LEADER) && (pMnode->syncMgmt.restored);
|
||||
}
|
||||
|
|
|
@ -386,14 +386,14 @@ static int32_t mndCreateTopic(SMnode *pMnode, SRpcMsg *pReq, SCMCreateTopicReq *
|
|||
}
|
||||
mDebug("trans:%d, used to create topic:%s", pTrans->id, pCreate->name);
|
||||
|
||||
SSdbRaw *pRedoRaw = mndTopicActionEncode(&topicObj);
|
||||
if (pRedoRaw == NULL || mndTransAppendRedolog(pTrans, pRedoRaw) != 0) {
|
||||
mError("trans:%d, failed to append redo log since %s", pTrans->id, terrstr());
|
||||
SSdbRaw *pCommitRaw = mndTopicActionEncode(&topicObj);
|
||||
if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
|
||||
mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
|
||||
taosMemoryFreeClear(topicObj.physicalPlan);
|
||||
mndTransDrop(pTrans);
|
||||
return -1;
|
||||
}
|
||||
sdbSetRawStatus(pRedoRaw, SDB_STATUS_READY);
|
||||
sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
|
||||
|
||||
if (mndTransPrepare(pMnode, pTrans) != 0) {
|
||||
mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
|
||||
|
@ -473,13 +473,13 @@ CREATE_TOPIC_OVER:
|
|||
}
|
||||
|
||||
static int32_t mndDropTopic(SMnode *pMnode, STrans *pTrans, SRpcMsg *pReq, SMqTopicObj *pTopic) {
|
||||
SSdbRaw *pRedoRaw = mndTopicActionEncode(pTopic);
|
||||
if (pRedoRaw == NULL || mndTransAppendRedolog(pTrans, pRedoRaw) != 0) {
|
||||
mError("trans:%d, failed to append redo log since %s", pTrans->id, terrstr());
|
||||
SSdbRaw *pCommitRaw = mndTopicActionEncode(pTopic);
|
||||
if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
|
||||
mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
|
||||
mndTransDrop(pTrans);
|
||||
return -1;
|
||||
}
|
||||
sdbSetRawStatus(pRedoRaw, SDB_STATUS_DROPPED);
|
||||
sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED);
|
||||
|
||||
if (mndTransPrepare(pMnode, pTrans) != 0) {
|
||||
mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
|
||||
|
@ -627,11 +627,11 @@ static int32_t mndRetrieveTopic(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBl
|
|||
return numOfRows;
|
||||
}
|
||||
|
||||
int32_t mndSetTopicRedoLogs(SMnode *pMnode, STrans *pTrans, SMqTopicObj *pTopic) {
|
||||
SSdbRaw *pRedoRaw = mndTopicActionEncode(pTopic);
|
||||
if (pRedoRaw == NULL) return -1;
|
||||
if (mndTransAppendCommitlog(pTrans, pRedoRaw) != 0) return -1;
|
||||
if (sdbSetRawStatus(pRedoRaw, SDB_STATUS_READY) != 0) return -1;
|
||||
int32_t mndSetTopicCommitLogs(SMnode *pMnode, STrans *pTrans, SMqTopicObj *pTopic) {
|
||||
SSdbRaw *pCommitRaw = mndTopicActionEncode(pTopic);
|
||||
if (pCommitRaw == NULL) return -1;
|
||||
if (mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) return -1;
|
||||
if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY) != 0) return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -682,13 +682,6 @@ static int32_t mndTransSync(SMnode *pMnode, STrans *pTrans) {
|
|||
}
|
||||
|
||||
mDebug("trans:%d, sync finished", pTrans->id);
|
||||
|
||||
code = sdbWrite(pMnode->pSdb, pRaw);
|
||||
if (code != 0) {
|
||||
mError("trans:%d, failed to write sdb since %s", pTrans->id, terrstr());
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -768,6 +761,12 @@ int32_t mndTransPrepare(SMnode *pMnode, STrans *pTrans) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (taosArrayGetSize(pTrans->commitLogs) <= 0) {
|
||||
terrno = TSDB_CODE_MND_TRANS_CLOG_IS_NULL;
|
||||
mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
|
||||
return -1;
|
||||
}
|
||||
|
||||
mDebug("trans:%d, prepare transaction", pTrans->id);
|
||||
if (mndTransSync(pMnode, pTrans) != 0) {
|
||||
mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
|
||||
|
@ -1080,6 +1079,8 @@ static bool mndTransPerformRedoLogStage(SMnode *pMnode, STrans *pTrans) {
|
|||
}
|
||||
|
||||
static bool mndTransPerformRedoActionStage(SMnode *pMnode, STrans *pTrans) {
|
||||
if (!mndIsMaster(pMnode)) return false;
|
||||
|
||||
bool continueExec = true;
|
||||
int32_t code = mndTransExecuteRedoActions(pMnode, pTrans);
|
||||
|
||||
|
@ -1169,6 +1170,8 @@ static bool mndTransPerformUndoLogStage(SMnode *pMnode, STrans *pTrans) {
|
|||
}
|
||||
|
||||
static bool mndTransPerformUndoActionStage(SMnode *pMnode, STrans *pTrans) {
|
||||
if (!mndIsMaster(pMnode)) return false;
|
||||
|
||||
bool continueExec = true;
|
||||
int32_t code = mndTransExecuteUndoActions(pMnode, pTrans);
|
||||
|
||||
|
@ -1350,19 +1353,35 @@ _OVER:
|
|||
return code;
|
||||
}
|
||||
|
||||
void mndTransPullup(SMnode *pMnode) {
|
||||
STrans *pTrans = NULL;
|
||||
void *pIter = NULL;
|
||||
static int32_t mndCompareTransId(int32_t *pTransId1, int32_t *pTransId2) { return *pTransId1 >= *pTransId2 ? 1 : 0; }
|
||||
|
||||
void mndTransPullup(SMnode *pMnode) {
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
SArray *pArray = taosArrayInit(sdbGetSize(pSdb, SDB_TRANS), sizeof(int32_t));
|
||||
if (pArray == NULL) return;
|
||||
|
||||
void *pIter = NULL;
|
||||
while (1) {
|
||||
STrans *pTrans = NULL;
|
||||
pIter = sdbFetch(pMnode->pSdb, SDB_TRANS, pIter, (void **)&pTrans);
|
||||
if (pIter == NULL) break;
|
||||
taosArrayPush(pArray, &pTrans->id);
|
||||
sdbRelease(pSdb, pTrans);
|
||||
}
|
||||
|
||||
mndTransExecute(pMnode, pTrans);
|
||||
sdbRelease(pMnode->pSdb, pTrans);
|
||||
taosArraySort(pArray, (__compar_fn_t)mndCompareTransId);
|
||||
|
||||
for (int32_t i = 0; i < taosArrayGetSize(pArray); ++i) {
|
||||
int32_t *pTransId = taosArrayGet(pArray, i);
|
||||
STrans *pTrans = mndAcquireTrans(pMnode, *pTransId);
|
||||
if (pTrans != NULL) {
|
||||
mndTransExecute(pMnode, pTrans);
|
||||
}
|
||||
mndReleaseTrans(pMnode, pTrans);
|
||||
}
|
||||
|
||||
sdbWriteFile(pMnode->pSdb);
|
||||
taosArrayDestroy(pArray);
|
||||
}
|
||||
|
||||
static int32_t mndRetrieveTrans(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
|
||||
|
|
|
@ -272,13 +272,13 @@ static int32_t mndCreateUser(SMnode *pMnode, char *acct, SCreateUserReq *pCreate
|
|||
}
|
||||
mDebug("trans:%d, used to create user:%s", pTrans->id, pCreate->user);
|
||||
|
||||
SSdbRaw *pRedoRaw = mndUserActionEncode(&userObj);
|
||||
if (pRedoRaw == NULL || mndTransAppendRedolog(pTrans, pRedoRaw) != 0) {
|
||||
mError("trans:%d, failed to append redo log since %s", pTrans->id, terrstr());
|
||||
SSdbRaw *pCommitRaw = mndUserActionEncode(&userObj);
|
||||
if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
|
||||
mError("trans:%d, failed to commit redo log since %s", pTrans->id, terrstr());
|
||||
mndTransDrop(pTrans);
|
||||
return -1;
|
||||
}
|
||||
sdbSetRawStatus(pRedoRaw, SDB_STATUS_READY);
|
||||
sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
|
||||
|
||||
if (mndTransPrepare(pMnode, pTrans) != 0) {
|
||||
mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
|
||||
|
@ -352,13 +352,13 @@ static int32_t mndAlterUser(SMnode *pMnode, SUserObj *pOld, SUserObj *pNew, SRpc
|
|||
}
|
||||
mDebug("trans:%d, used to alter user:%s", pTrans->id, pOld->user);
|
||||
|
||||
SSdbRaw *pRedoRaw = mndUserActionEncode(pNew);
|
||||
if (pRedoRaw == NULL || mndTransAppendRedolog(pTrans, pRedoRaw) != 0) {
|
||||
mError("trans:%d, failed to append redo log since %s", pTrans->id, terrstr());
|
||||
SSdbRaw *pCommitRaw = mndUserActionEncode(pNew);
|
||||
if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
|
||||
mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
|
||||
mndTransDrop(pTrans);
|
||||
return -1;
|
||||
}
|
||||
sdbSetRawStatus(pRedoRaw, SDB_STATUS_READY);
|
||||
sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
|
||||
|
||||
if (mndTransPrepare(pMnode, pTrans) != 0) {
|
||||
mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
|
||||
|
@ -559,13 +559,13 @@ static int32_t mndDropUser(SMnode *pMnode, SRpcMsg *pReq, SUserObj *pUser) {
|
|||
}
|
||||
mDebug("trans:%d, used to drop user:%s", pTrans->id, pUser->user);
|
||||
|
||||
SSdbRaw *pRedoRaw = mndUserActionEncode(pUser);
|
||||
if (pRedoRaw == NULL || mndTransAppendRedolog(pTrans, pRedoRaw) != 0) {
|
||||
mError("trans:%d, failed to append redo log since %s", pTrans->id, terrstr());
|
||||
SSdbRaw *pCommitRaw = mndUserActionEncode(pUser);
|
||||
if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
|
||||
mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
|
||||
mndTransDrop(pTrans);
|
||||
return -1;
|
||||
}
|
||||
sdbSetRawStatus(pRedoRaw, SDB_STATUS_DROPPED);
|
||||
sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED);
|
||||
|
||||
if (mndTransPrepare(pMnode, pTrans) != 0) {
|
||||
mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
|
||||
|
|
|
@ -86,7 +86,6 @@ static void *mndThreadFp(void *param) {
|
|||
lastTime++;
|
||||
taosMsleep(100);
|
||||
if (pMnode->stopped) break;
|
||||
if (!mndIsMaster(pMnode)) continue;
|
||||
|
||||
if (lastTime % (tsTransPullupInterval * 10) == 0) {
|
||||
mndPullupTrans(pMnode);
|
||||
|
@ -336,9 +335,107 @@ int32_t mndAlter(SMnode *pMnode, const SMnodeOpt *pOption) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t mndStart(SMnode *pMnode) { return mndInitTimer(pMnode); }
|
||||
int32_t mndStart(SMnode *pMnode) {
|
||||
mndSyncStart(pMnode);
|
||||
return mndInitTimer(pMnode);
|
||||
}
|
||||
|
||||
void mndStop(SMnode *pMnode) { return mndCleanupTimer(pMnode); }
|
||||
void mndStop(SMnode *pMnode) {
|
||||
mndSyncStop(pMnode);
|
||||
return mndCleanupTimer(pMnode);
|
||||
}
|
||||
|
||||
int32_t mndProcessSyncMsg(SRpcMsg *pMsg) {
|
||||
SMnode *pMnode = pMsg->info.node;
|
||||
void *ahandle = pMsg->info.ahandle;
|
||||
int32_t ret = TAOS_SYNC_PROPOSE_OTHER_ERROR;
|
||||
|
||||
if (syncEnvIsStart()) {
|
||||
SSyncNode *pSyncNode = syncNodeAcquire(pMnode->syncMgmt.sync);
|
||||
assert(pSyncNode != NULL);
|
||||
|
||||
ESyncState state = syncGetMyRole(pMnode->syncMgmt.sync);
|
||||
SyncTerm currentTerm = syncGetMyTerm(pMnode->syncMgmt.sync);
|
||||
|
||||
SMsgHead *pHead = pMsg->pCont;
|
||||
|
||||
char logBuf[512];
|
||||
char *syncNodeStr = sync2SimpleStr(pMnode->syncMgmt.sync);
|
||||
snprintf(logBuf, sizeof(logBuf), "==vnodeProcessSyncReq== msgType:%d, syncNode: %s", pMsg->msgType, syncNodeStr);
|
||||
syncRpcMsgLog2(logBuf, pMsg);
|
||||
taosMemoryFree(syncNodeStr);
|
||||
|
||||
SRpcMsg *pRpcMsg = pMsg;
|
||||
|
||||
if (pRpcMsg->msgType == TDMT_VND_SYNC_TIMEOUT) {
|
||||
SyncTimeout *pSyncMsg = syncTimeoutFromRpcMsg2(pRpcMsg);
|
||||
assert(pSyncMsg != NULL);
|
||||
|
||||
ret = syncNodeOnTimeoutCb(pSyncNode, pSyncMsg);
|
||||
syncTimeoutDestroy(pSyncMsg);
|
||||
|
||||
} else if (pRpcMsg->msgType == TDMT_VND_SYNC_PING) {
|
||||
SyncPing *pSyncMsg = syncPingFromRpcMsg2(pRpcMsg);
|
||||
assert(pSyncMsg != NULL);
|
||||
|
||||
ret = syncNodeOnPingCb(pSyncNode, pSyncMsg);
|
||||
syncPingDestroy(pSyncMsg);
|
||||
|
||||
} else if (pRpcMsg->msgType == TDMT_VND_SYNC_PING_REPLY) {
|
||||
SyncPingReply *pSyncMsg = syncPingReplyFromRpcMsg2(pRpcMsg);
|
||||
assert(pSyncMsg != NULL);
|
||||
|
||||
ret = syncNodeOnPingReplyCb(pSyncNode, pSyncMsg);
|
||||
syncPingReplyDestroy(pSyncMsg);
|
||||
|
||||
} else if (pRpcMsg->msgType == TDMT_VND_SYNC_CLIENT_REQUEST) {
|
||||
SyncClientRequest *pSyncMsg = syncClientRequestFromRpcMsg2(pRpcMsg);
|
||||
assert(pSyncMsg != NULL);
|
||||
|
||||
ret = syncNodeOnClientRequestCb(pSyncNode, pSyncMsg);
|
||||
syncClientRequestDestroy(pSyncMsg);
|
||||
|
||||
} else if (pRpcMsg->msgType == TDMT_VND_SYNC_REQUEST_VOTE) {
|
||||
SyncRequestVote *pSyncMsg = syncRequestVoteFromRpcMsg2(pRpcMsg);
|
||||
assert(pSyncMsg != NULL);
|
||||
|
||||
ret = syncNodeOnRequestVoteCb(pSyncNode, pSyncMsg);
|
||||
syncRequestVoteDestroy(pSyncMsg);
|
||||
|
||||
} else if (pRpcMsg->msgType == TDMT_VND_SYNC_REQUEST_VOTE_REPLY) {
|
||||
SyncRequestVoteReply *pSyncMsg = syncRequestVoteReplyFromRpcMsg2(pRpcMsg);
|
||||
assert(pSyncMsg != NULL);
|
||||
|
||||
ret = syncNodeOnRequestVoteReplyCb(pSyncNode, pSyncMsg);
|
||||
syncRequestVoteReplyDestroy(pSyncMsg);
|
||||
|
||||
} else if (pRpcMsg->msgType == TDMT_VND_SYNC_APPEND_ENTRIES) {
|
||||
SyncAppendEntries *pSyncMsg = syncAppendEntriesFromRpcMsg2(pRpcMsg);
|
||||
assert(pSyncMsg != NULL);
|
||||
|
||||
ret = syncNodeOnAppendEntriesCb(pSyncNode, pSyncMsg);
|
||||
syncAppendEntriesDestroy(pSyncMsg);
|
||||
|
||||
} else if (pRpcMsg->msgType == TDMT_VND_SYNC_APPEND_ENTRIES_REPLY) {
|
||||
SyncAppendEntriesReply *pSyncMsg = syncAppendEntriesReplyFromRpcMsg2(pRpcMsg);
|
||||
assert(pSyncMsg != NULL);
|
||||
|
||||
ret = syncNodeOnAppendEntriesReplyCb(pSyncNode, pSyncMsg);
|
||||
syncAppendEntriesReplyDestroy(pSyncMsg);
|
||||
|
||||
} else {
|
||||
mError("==mndProcessSyncMsg== error msg type:%d", pRpcMsg->msgType);
|
||||
ret = TAOS_SYNC_PROPOSE_OTHER_ERROR;
|
||||
}
|
||||
|
||||
syncNodeRelease(pSyncNode);
|
||||
} else {
|
||||
mError("==mndProcessSyncMsg== error syncEnv stop");
|
||||
ret = TAOS_SYNC_PROPOSE_OTHER_ERROR;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t mndProcessMsg(SRpcMsg *pMsg) {
|
||||
SMnode *pMnode = pMsg->info.node;
|
||||
|
@ -346,7 +443,8 @@ int32_t mndProcessMsg(SRpcMsg *pMsg) {
|
|||
mTrace("msg:%p, will be processed, type:%s app:%p", pMsg, TMSG_INFO(pMsg->msgType), ahandle);
|
||||
|
||||
if (IsReq(pMsg)) {
|
||||
if (!mndIsMaster(pMnode)) {
|
||||
if (!mndIsMaster(pMnode) && pMsg->msgType != TDMT_MND_TRANS_TIMER && pMsg->msgType != TDMT_MND_MQ_TIMER &&
|
||||
pMsg->msgType != TDMT_MND_TELEM_TIMER) {
|
||||
terrno = TSDB_CODE_APP_NOT_READY;
|
||||
mDebug("msg:%p, failed to process since %s, app:%p", pMsg, terrstr(), ahandle);
|
||||
return -1;
|
||||
|
|
|
@ -493,9 +493,8 @@ TEST_F(MndTestSdb, 01_Write_Str) {
|
|||
ASSERT_EQ(sdbGetSize(pSdb, SDB_USER), 2);
|
||||
ASSERT_EQ(sdbGetMaxId(pSdb, SDB_USER), -1);
|
||||
ASSERT_EQ(sdbGetTableVer(pSdb, SDB_USER), 2 );
|
||||
ASSERT_EQ(sdbUpdateVer(pSdb, 0), -1);
|
||||
ASSERT_EQ(sdbUpdateVer(pSdb, 1), 0);
|
||||
ASSERT_EQ(sdbUpdateVer(pSdb, -1), -1);
|
||||
sdbSetApplyIndex(pSdb, -1);
|
||||
ASSERT_EQ(sdbGetApplyIndex(pSdb), -1);
|
||||
ASSERT_EQ(mnode.insertTimes, 2);
|
||||
ASSERT_EQ(mnode.deleteTimes, 0);
|
||||
|
||||
|
@ -537,9 +536,6 @@ TEST_F(MndTestSdb, 01_Write_Str) {
|
|||
|
||||
ASSERT_EQ(sdbGetSize(pSdb, SDB_USER), 3);
|
||||
ASSERT_EQ(sdbGetTableVer(pSdb, SDB_USER), 4);
|
||||
ASSERT_EQ(sdbUpdateVer(pSdb, 0), -1);
|
||||
ASSERT_EQ(sdbUpdateVer(pSdb, 1), 0);
|
||||
ASSERT_EQ(sdbUpdateVer(pSdb, -1), -1);
|
||||
ASSERT_EQ(mnode.insertTimes, 3);
|
||||
ASSERT_EQ(mnode.deleteTimes, 0);
|
||||
|
||||
|
@ -704,8 +700,9 @@ TEST_F(MndTestSdb, 01_Write_Str) {
|
|||
}
|
||||
|
||||
// write version
|
||||
ASSERT_EQ(sdbUpdateVer(pSdb, 1), 0);
|
||||
ASSERT_EQ(sdbUpdateVer(pSdb, 1), 1);
|
||||
sdbSetApplyIndex(pSdb, 0);
|
||||
sdbSetApplyIndex(pSdb, 1);
|
||||
ASSERT_EQ(sdbGetApplyIndex(pSdb), 1);
|
||||
ASSERT_EQ(sdbWriteFile(pSdb), 0);
|
||||
ASSERT_EQ(sdbWriteFile(pSdb), 0);
|
||||
|
||||
|
@ -775,7 +772,7 @@ TEST_F(MndTestSdb, 01_Read_Str) {
|
|||
ASSERT_EQ(sdbGetSize(pSdb, SDB_USER), 2);
|
||||
ASSERT_EQ(sdbGetMaxId(pSdb, SDB_USER), -1);
|
||||
ASSERT_EQ(sdbGetTableVer(pSdb, SDB_USER), 5);
|
||||
ASSERT_EQ(sdbUpdateVer(pSdb, 0), 1);
|
||||
ASSERT_EQ(sdbGetApplyIndex(pSdb), 1);
|
||||
ASSERT_EQ(mnode.insertTimes, 4);
|
||||
ASSERT_EQ(mnode.deleteTimes, 0);
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ target_include_directories(
|
|||
PUBLIC "${TD_SOURCE_DIR}/include/dnode/mnode"
|
||||
PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../inc"
|
||||
)
|
||||
add_test(
|
||||
NAME transTest2
|
||||
COMMAND transTest2
|
||||
)
|
||||
#add_test(
|
||||
# NAME transTest2
|
||||
# COMMAND transTest2
|
||||
#)
|
||||
|
|
|
@ -23,6 +23,11 @@ int32_t sendReq(const SEpSet *pEpSet, SRpcMsg *pMsg) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
int32_t putToQueue(void *pMgmt, SRpcMsg *pMsg) {
|
||||
terrno = TSDB_CODE_INVALID_PTR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
class MndTestTrans2 : public ::testing::Test {
|
||||
protected:
|
||||
static void InitLog() {
|
||||
|
@ -55,6 +60,9 @@ class MndTestTrans2 : public ::testing::Test {
|
|||
msgCb.reportStartupFp = reportStartup;
|
||||
msgCb.sendReqFp = sendReq;
|
||||
msgCb.sendRspFp = sendRsp;
|
||||
msgCb.queueFps[SYNC_QUEUE] = putToQueue;
|
||||
msgCb.queueFps[WRITE_QUEUE] = putToQueue;
|
||||
msgCb.queueFps[READ_QUEUE] = putToQueue;
|
||||
msgCb.mgmt = (SMgmtWrapper *)(&msgCb); // hack
|
||||
tmsgSetDefault(&msgCb);
|
||||
|
||||
|
@ -77,6 +85,7 @@ class MndTestTrans2 : public ::testing::Test {
|
|||
static void SetUpTestSuite() {
|
||||
InitLog();
|
||||
walInit();
|
||||
syncInit();
|
||||
InitMnode();
|
||||
}
|
||||
|
||||
|
|
|
@ -31,11 +31,9 @@ SSdb *sdbInit(SSdbOpt *pOption) {
|
|||
char path[PATH_MAX + 100] = {0};
|
||||
snprintf(path, sizeof(path), "%s%sdata", pOption->path, TD_DIRSEP);
|
||||
pSdb->currDir = strdup(path);
|
||||
snprintf(path, sizeof(path), "%s%ssync", pOption->path, TD_DIRSEP);
|
||||
pSdb->syncDir = strdup(path);
|
||||
snprintf(path, sizeof(path), "%s%stmp", pOption->path, TD_DIRSEP);
|
||||
pSdb->tmpDir = strdup(path);
|
||||
if (pSdb->currDir == NULL || pSdb->currDir == NULL || pSdb->currDir == NULL) {
|
||||
if (pSdb->currDir == NULL || pSdb->tmpDir == NULL) {
|
||||
sdbCleanup(pSdb);
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
mError("failed to init sdb since %s", terrstr());
|
||||
|
@ -55,6 +53,7 @@ SSdb *sdbInit(SSdbOpt *pOption) {
|
|||
}
|
||||
|
||||
pSdb->curVer = -1;
|
||||
pSdb->curTerm = -1;
|
||||
pSdb->lastCommitVer = -1;
|
||||
pSdb->pMnode = pOption->pMnode;
|
||||
mDebug("sdb init successfully");
|
||||
|
@ -149,12 +148,6 @@ static int32_t sdbCreateDir(SSdb *pSdb) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (taosMkDir(pSdb->syncDir) != 0) {
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
mError("failed to create dir:%s since %s", pSdb->syncDir, terrstr());
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (taosMkDir(pSdb->tmpDir) != 0) {
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
mError("failed to create dir:%s since %s", pSdb->tmpDir, terrstr());
|
||||
|
@ -164,4 +157,10 @@ static int32_t sdbCreateDir(SSdb *pSdb) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int64_t sdbUpdateVer(SSdb *pSdb, int32_t val) { return atomic_add_fetch_64(&pSdb->curVer, val); }
|
||||
void sdbSetApplyIndex(SSdb *pSdb, int64_t index) { pSdb->curVer = index; }
|
||||
|
||||
int64_t sdbGetApplyIndex(SSdb *pSdb) { return pSdb->curVer; }
|
||||
|
||||
void sdbSetApplyTerm(SSdb *pSdb, int64_t term) { pSdb->curTerm = term; }
|
||||
|
||||
int64_t sdbGetApplyTerm(SSdb *pSdb) { return pSdb->curTerm; }
|
||||
|
|
|
@ -65,6 +65,16 @@ static int32_t sdbReadFileHead(SSdb *pSdb, TdFilePtr pFile) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
ret = taosReadFile(pFile, &pSdb->curTerm, sizeof(int64_t));
|
||||
if (ret < 0) {
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
return -1;
|
||||
}
|
||||
if (ret != sizeof(int64_t)) {
|
||||
terrno = TSDB_CODE_FILE_CORRUPTED;
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < SDB_TABLE_SIZE; ++i) {
|
||||
int64_t maxId = 0;
|
||||
ret = taosReadFile(pFile, &maxId, sizeof(int64_t));
|
||||
|
@ -123,6 +133,11 @@ static int32_t sdbWriteFileHead(SSdb *pSdb, TdFilePtr pFile) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (taosWriteFile(pFile, &pSdb->curTerm, sizeof(int64_t)) != sizeof(int64_t)) {
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < SDB_TABLE_SIZE; ++i) {
|
||||
int64_t maxId = 0;
|
||||
if (i < SDB_MAX) {
|
||||
|
@ -182,6 +197,7 @@ int32_t sdbReadFile(SSdb *pSdb) {
|
|||
if (sdbReadFileHead(pSdb, pFile) != 0) {
|
||||
mError("failed to read file:%s head since %s", file, terrstr());
|
||||
pSdb->curVer = -1;
|
||||
pSdb->curTerm = -1;
|
||||
taosMemoryFree(pRaw);
|
||||
taosCloseFile(&pFile);
|
||||
return -1;
|
||||
|
@ -256,8 +272,8 @@ static int32_t sdbWriteFileImp(SSdb *pSdb) {
|
|||
char curfile[PATH_MAX] = {0};
|
||||
snprintf(curfile, sizeof(curfile), "%s%ssdb.data", pSdb->currDir, TD_DIRSEP);
|
||||
|
||||
mDebug("start to write file:%s, current ver:%" PRId64 ", commit ver:%" PRId64, curfile, pSdb->curVer,
|
||||
pSdb->lastCommitVer);
|
||||
mDebug("start to write file:%s, current ver:%" PRId64 " term:%" PRId64 ", commit ver:%" PRId64, curfile, pSdb->curVer,
|
||||
pSdb->curTerm, pSdb->lastCommitVer);
|
||||
|
||||
TdFilePtr pFile = taosOpenFile(tmpfile, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC);
|
||||
if (pFile == NULL) {
|
||||
|
@ -350,7 +366,7 @@ static int32_t sdbWriteFileImp(SSdb *pSdb) {
|
|||
mError("failed to write file:%s since %s", curfile, tstrerror(code));
|
||||
} else {
|
||||
pSdb->lastCommitVer = pSdb->curVer;
|
||||
mDebug("write file:%s successfully, ver:%" PRId64, curfile, pSdb->lastCommitVer);
|
||||
mDebug("write file:%s successfully, ver:%" PRId64 " term:%" PRId64, curfile, pSdb->lastCommitVer, pSdb->curTerm);
|
||||
}
|
||||
|
||||
terrno = code;
|
||||
|
|
|
@ -57,9 +57,7 @@ void sndMetaDelete(SStreamMeta *pMeta) {
|
|||
}
|
||||
|
||||
int32_t sndMetaDeployTask(SStreamMeta *pMeta, SStreamTask *pTask) {
|
||||
for (int i = 0; i < pTask->exec.numOfRunners; i++) {
|
||||
pTask->exec.runners[i].executor = qCreateStreamExecTaskInfo(pTask->exec.qmsg, NULL);
|
||||
}
|
||||
pTask->exec.executor = qCreateStreamExecTaskInfo(pTask->exec.qmsg, NULL);
|
||||
return taosHashPut(pMeta->pHash, &pTask->taskId, sizeof(int32_t), pTask, sizeof(void *));
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,6 @@ target_sources(
|
|||
# tq
|
||||
"src/tq/tq.c"
|
||||
"src/tq/tqCommit.c"
|
||||
"src/tq/tqMetaStore.c"
|
||||
"src/tq/tqOffset.c"
|
||||
"src/tq/tqPush.c"
|
||||
"src/tq/tqRead.c"
|
||||
|
|
|
@ -51,7 +51,7 @@ int32_t vnodeCreate(const char *path, SVnodeCfg *pCfg, STfs *pTfs);
|
|||
void vnodeDestroy(const char *path, STfs *pTfs);
|
||||
SVnode *vnodeOpen(const char *path, STfs *pTfs, SMsgCb msgCb);
|
||||
void vnodeClose(SVnode *pVnode);
|
||||
int32_t vnodePreprocessWriteReqs(SVnode *pVnode, SArray *pMsgs, int64_t *version);
|
||||
int32_t vnodePreprocessReq(SVnode *pVnode, SRpcMsg *pMsg);
|
||||
int32_t vnodeProcessWriteReq(SVnode *pVnode, SRpcMsg *pMsg, int64_t version, SRpcMsg *pRsp);
|
||||
int32_t vnodeProcessCMsg(SVnode *pVnode, SRpcMsg *pMsg, SRpcMsg **pRsp);
|
||||
int32_t vnodeProcessSyncReq(SVnode *pVnode, SRpcMsg *pMsg, SRpcMsg **pRsp);
|
||||
|
@ -126,7 +126,7 @@ STqReadHandle *tqInitSubmitMsgScanner(SMeta *pMeta);
|
|||
void tqReadHandleSetColIdList(STqReadHandle *pReadHandle, SArray *pColIdList);
|
||||
int32_t tqReadHandleSetTbUidList(STqReadHandle *pHandle, const SArray *tbUidList);
|
||||
int32_t tqReadHandleAddTbUidList(STqReadHandle *pHandle, const SArray *tbUidList);
|
||||
int32_t tqReadHandleRemoveTbUidList(STqReadHandle* pHandle, const SArray* tbUidList);
|
||||
int32_t tqReadHandleRemoveTbUidList(STqReadHandle *pHandle, const SArray *tbUidList);
|
||||
|
||||
int32_t tqReadHandleSetMsg(STqReadHandle *pHandle, SSubmitReq *pMsg, int64_t ver);
|
||||
bool tqNextDataBlock(STqReadHandle *pHandle);
|
||||
|
@ -174,20 +174,20 @@ typedef struct {
|
|||
} STableKeyInfo;
|
||||
|
||||
struct SMetaEntry {
|
||||
int64_t version;
|
||||
int8_t type;
|
||||
tb_uid_t uid;
|
||||
const char *name;
|
||||
int64_t version;
|
||||
int8_t type;
|
||||
tb_uid_t uid;
|
||||
char *name;
|
||||
union {
|
||||
struct {
|
||||
SSchemaWrapper schema;
|
||||
SSchemaWrapper schemaTag;
|
||||
} stbEntry;
|
||||
struct {
|
||||
int64_t ctime;
|
||||
int32_t ttlDays;
|
||||
tb_uid_t suid;
|
||||
const uint8_t *pTags;
|
||||
int64_t ctime;
|
||||
int32_t ttlDays;
|
||||
tb_uid_t suid;
|
||||
uint8_t *pTags;
|
||||
} ctbEntry;
|
||||
struct {
|
||||
int64_t ctime;
|
||||
|
|
|
@ -20,9 +20,9 @@
|
|||
|
||||
#include "executor.h"
|
||||
#include "os.h"
|
||||
#include "tcache.h"
|
||||
#include "thash.h"
|
||||
#include "tmsg.h"
|
||||
#include "tqueue.h"
|
||||
#include "trpc.h"
|
||||
#include "ttimer.h"
|
||||
#include "wal.h"
|
||||
|
@ -41,45 +41,6 @@ extern "C" {
|
|||
#define tqTrace(...) do { if (tqDebugFlag & DEBUG_TRACE) { taosPrintLog("TQ ", DEBUG_TRACE, tqDebugFlag, __VA_ARGS__); }} while(0)
|
||||
// clang-format on
|
||||
|
||||
#define TQ_BUFFER_SIZE 4
|
||||
|
||||
#define TQ_BUCKET_MASK 0xFF
|
||||
#define TQ_BUCKET_SIZE 256
|
||||
|
||||
#define TQ_PAGE_SIZE 4096
|
||||
// key + offset + size
|
||||
#define TQ_IDX_SIZE 24
|
||||
// 4096 / 24
|
||||
#define TQ_MAX_IDX_ONE_PAGE 170
|
||||
// 24 * 170
|
||||
#define TQ_IDX_PAGE_BODY_SIZE 4080
|
||||
// 4096 - 4080
|
||||
#define TQ_IDX_PAGE_HEAD_SIZE 16
|
||||
|
||||
#define TQ_ACTION_CONST 0
|
||||
#define TQ_ACTION_INUSE 1
|
||||
#define TQ_ACTION_INUSE_CONT 2
|
||||
#define TQ_ACTION_INTXN 3
|
||||
|
||||
#define TQ_SVER 0
|
||||
|
||||
// TODO: inplace mode is not implemented
|
||||
#define TQ_UPDATE_INPLACE 0
|
||||
#define TQ_UPDATE_APPEND 1
|
||||
|
||||
#define TQ_DUP_INTXN_REWRITE 0
|
||||
#define TQ_DUP_INTXN_REJECT 2
|
||||
|
||||
static inline bool tqUpdateAppend(int32_t tqConfigFlag) { return tqConfigFlag & TQ_UPDATE_APPEND; }
|
||||
|
||||
static inline bool tqDupIntxnReject(int32_t tqConfigFlag) { return tqConfigFlag & TQ_DUP_INTXN_REJECT; }
|
||||
|
||||
static const int8_t TQ_CONST_DELETE = TQ_ACTION_CONST;
|
||||
|
||||
#define TQ_DELETE_TOKEN (void*)&TQ_CONST_DELETE
|
||||
|
||||
typedef enum { TQ_ITEM_READY, TQ_ITEM_PROCESS, TQ_ITEM_EMPTY } STqItemStatus;
|
||||
|
||||
typedef struct STqOffsetCfg STqOffsetCfg;
|
||||
typedef struct STqOffsetStore STqOffsetStore;
|
||||
|
||||
|
@ -98,53 +59,6 @@ struct STqReadHandle {
|
|||
STSchema* pSchema;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int16_t ver;
|
||||
int16_t action;
|
||||
int32_t checksum;
|
||||
int64_t ssize;
|
||||
char content[];
|
||||
} STqSerializedHead;
|
||||
|
||||
typedef int32_t (*FTqSerialize)(const void* pObj, STqSerializedHead** ppHead);
|
||||
typedef int32_t (*FTqDeserialize)(void* self, const STqSerializedHead* pHead, void** ppObj);
|
||||
typedef void (*FTqDelete)(void*);
|
||||
|
||||
typedef struct {
|
||||
int64_t key;
|
||||
int64_t offset;
|
||||
int64_t serializedSize;
|
||||
void* valueInUse;
|
||||
void* valueInTxn;
|
||||
} STqMetaHandle;
|
||||
|
||||
typedef struct STqMetaList {
|
||||
STqMetaHandle handle;
|
||||
struct STqMetaList* next;
|
||||
// struct STqMetaList* inTxnPrev;
|
||||
// struct STqMetaList* inTxnNext;
|
||||
struct STqMetaList* unpersistPrev;
|
||||
struct STqMetaList* unpersistNext;
|
||||
} STqMetaList;
|
||||
|
||||
typedef struct {
|
||||
STQ* pTq;
|
||||
STqMetaList* bucket[TQ_BUCKET_SIZE];
|
||||
// a table head
|
||||
STqMetaList* unpersistHead;
|
||||
// topics that are not connectted
|
||||
STqMetaList* unconnectTopic;
|
||||
|
||||
TdFilePtr pFile;
|
||||
TdFilePtr pIdxFile;
|
||||
|
||||
char* dirPath;
|
||||
int32_t tqConfigFlag;
|
||||
FTqSerialize pSerializer;
|
||||
FTqDeserialize pDeserializer;
|
||||
FTqDelete pDeleter;
|
||||
} STqMetaStore;
|
||||
|
||||
typedef struct {
|
||||
int64_t consumerId;
|
||||
int32_t epoch;
|
||||
|
@ -172,15 +86,17 @@ typedef struct {
|
|||
qTaskInfo_t task[5];
|
||||
} STqExec;
|
||||
|
||||
int32_t tEncodeSTqExec(SEncoder* pEncoder, const STqExec* pExec);
|
||||
int32_t tDecodeSTqExec(SDecoder* pDecoder, STqExec* pExec);
|
||||
|
||||
struct STQ {
|
||||
char* path;
|
||||
// STqMetaStore* tqMeta;
|
||||
char* path;
|
||||
SHashObj* pushMgr; // consumerId -> STqExec*
|
||||
SHashObj* execs; // subKey -> STqExec
|
||||
SHashObj* pStreamTasks;
|
||||
SVnode* pVnode;
|
||||
SWal* pWal;
|
||||
// TDB* pTdb;
|
||||
TDB* pTdb;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
|
@ -188,89 +104,12 @@ typedef struct {
|
|||
tmr_h timer;
|
||||
} STqMgmt;
|
||||
|
||||
static STqMgmt tqMgmt;
|
||||
|
||||
typedef struct {
|
||||
int8_t status;
|
||||
int64_t offset;
|
||||
qTaskInfo_t task;
|
||||
STqReadHandle* pReadHandle;
|
||||
} STqTaskItem;
|
||||
|
||||
// new version
|
||||
typedef struct {
|
||||
int64_t firstOffset;
|
||||
int64_t lastOffset;
|
||||
STqTaskItem output[TQ_BUFFER_SIZE];
|
||||
} STqBuffer;
|
||||
|
||||
typedef struct {
|
||||
char topicName[TSDB_TOPIC_FNAME_LEN];
|
||||
char* sql;
|
||||
char* logicalPlan;
|
||||
char* physicalPlan;
|
||||
char* qmsg;
|
||||
STqBuffer buffer;
|
||||
SWalReadHandle* pReadhandle;
|
||||
} STqTopic;
|
||||
|
||||
typedef struct {
|
||||
int64_t consumerId;
|
||||
int32_t epoch;
|
||||
char cgroup[TSDB_TOPIC_FNAME_LEN];
|
||||
SArray* topics; // SArray<STqTopic>
|
||||
} STqConsumer;
|
||||
|
||||
typedef struct {
|
||||
int8_t type;
|
||||
int8_t nodeType;
|
||||
int8_t reserved[6];
|
||||
int64_t streamId;
|
||||
qTaskInfo_t task;
|
||||
// TODO sync function
|
||||
} STqStreamPusher;
|
||||
|
||||
typedef struct {
|
||||
int8_t inited;
|
||||
tmr_h timer;
|
||||
} STqPushMgmt;
|
||||
|
||||
static STqPushMgmt tqPushMgmt;
|
||||
static STqMgmt tqMgmt = {0};
|
||||
|
||||
// init once
|
||||
int tqInit();
|
||||
void tqCleanUp();
|
||||
|
||||
// open in each vnode
|
||||
// required by vnode
|
||||
|
||||
int32_t tqSerializeConsumer(const STqConsumer*, STqSerializedHead**);
|
||||
int32_t tqDeserializeConsumer(STQ*, const STqSerializedHead*, STqConsumer**);
|
||||
|
||||
static int FORCE_INLINE tqQueryExecuting(int32_t status) { return status; }
|
||||
|
||||
// tqMetaStore.h
|
||||
STqMetaStore* tqStoreOpen(STQ* pTq, const char* path, FTqSerialize pSerializer, FTqDeserialize pDeserializer,
|
||||
FTqDelete pDeleter, int32_t tqConfigFlag);
|
||||
int32_t tqStoreClose(STqMetaStore*);
|
||||
// int32_t tqStoreDelete(TqMetaStore*);
|
||||
// int32_t tqStoreCommitAll(TqMetaStore*);
|
||||
int32_t tqStorePersist(STqMetaStore*);
|
||||
// clean deleted idx and data from persistent file
|
||||
int32_t tqStoreCompact(STqMetaStore*);
|
||||
|
||||
void* tqHandleGet(STqMetaStore*, int64_t key);
|
||||
// make it unpersist
|
||||
void* tqHandleTouchGet(STqMetaStore*, int64_t key);
|
||||
int32_t tqHandleMovePut(STqMetaStore*, int64_t key, void* value);
|
||||
int32_t tqHandleCopyPut(STqMetaStore*, int64_t key, void* value, size_t vsize);
|
||||
// delete committed kv pair
|
||||
// notice that a delete action still needs to be committed
|
||||
int32_t tqHandleDel(STqMetaStore*, int64_t key);
|
||||
int32_t tqHandlePurge(STqMetaStore*, int64_t key);
|
||||
int32_t tqHandleCommit(STqMetaStore*, int64_t key);
|
||||
int32_t tqHandleAbort(STqMetaStore*, int64_t key);
|
||||
|
||||
// tqOffset
|
||||
STqOffsetStore* STqOffsetOpen(STqOffsetCfg*);
|
||||
void STqOffsetClose(STqOffsetStore*);
|
||||
|
|
|
@ -104,7 +104,7 @@ int tsdbOpen(SVnode* pVnode, STsdb** ppTsdb, const char* dir, STsdbKeep
|
|||
int tsdbClose(STsdb** pTsdb);
|
||||
int tsdbBegin(STsdb* pTsdb);
|
||||
int tsdbCommit(STsdb* pTsdb);
|
||||
int tsdbScanAndConvertSubmitMsg(STsdb* pTsdb, const SSubmitReq* pMsg);
|
||||
int tsdbScanAndConvertSubmitMsg(STsdb* pTsdb, SSubmitReq* pMsg);
|
||||
int tsdbInsertData(STsdb* pTsdb, int64_t version, SSubmitReq* pMsg, SSubmitRsp* pRsp);
|
||||
int tsdbInsertTableData(STsdb* pTsdb, SSubmitMsgIter* pMsgIter, SSubmitBlk* pBlock, SSubmitBlkRsp* pRsp);
|
||||
tsdbReaderT* tsdbQueryTables(SVnode* pVnode, SQueryTableDataCond* pCond, STableGroupInfo* groupList, uint64_t qId,
|
||||
|
@ -123,11 +123,7 @@ int32_t tqProcessVgChangeReq(STQ* pTq, char* msg, int32_t msgLen);
|
|||
int32_t tqProcessVgDeleteReq(STQ* pTq, char* msg, int32_t msgLen);
|
||||
int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg, int32_t workerId);
|
||||
int32_t tqProcessTaskDeploy(STQ* pTq, char* msg, int32_t msgLen);
|
||||
#if 0
|
||||
int32_t tqProcessTaskExec(STQ* pTq, char* msg, int32_t msgLen, int32_t workerId);
|
||||
int32_t tqProcessStreamTrigger(STQ* pTq, void* data, int32_t dataLen, int32_t workerId);
|
||||
#endif
|
||||
int32_t tqProcessStreamTriggerNew(STQ* pTq, SSubmitReq* data);
|
||||
int32_t tqProcessStreamTrigger(STQ* pTq, SSubmitReq* data);
|
||||
int32_t tqProcessTaskRunReq(STQ* pTq, SRpcMsg* pMsg);
|
||||
int32_t tqProcessTaskDispatchReq(STQ* pTq, SRpcMsg* pMsg);
|
||||
int32_t tqProcessTaskRecoverReq(STQ* pTq, SRpcMsg* pMsg);
|
||||
|
|
|
@ -278,12 +278,13 @@ STSchema *metaGetTbTSchema(SMeta *pMeta, tb_uid_t uid, int32_t sver) {
|
|||
pSW = metaGetTableSchema(pMeta, quid, sver, 0);
|
||||
if (!pSW) return NULL;
|
||||
|
||||
tdInitTSchemaBuilder(&sb, 0);
|
||||
tdInitTSchemaBuilder(&sb, sver);
|
||||
for (int i = 0; i < pSW->nCols; i++) {
|
||||
pSchema = pSW->pSchema + i;
|
||||
tdAddColToSchema(&sb, pSchema->type, pSchema->flags, pSchema->colId, pSchema->bytes);
|
||||
}
|
||||
pTSchema = tdGetSchemaFromBuilder(&sb);
|
||||
|
||||
tdDestroyTSchemaBuilder(&sb);
|
||||
|
||||
taosMemoryFree(pSW->pSchema);
|
||||
|
|
|
@ -30,9 +30,9 @@ int metaCreateSTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq) {
|
|||
int vLen = 0;
|
||||
const void *pKey = NULL;
|
||||
const void *pVal = NULL;
|
||||
void * pBuf = NULL;
|
||||
void *pBuf = NULL;
|
||||
int32_t szBuf = 0;
|
||||
void * p = NULL;
|
||||
void *p = NULL;
|
||||
SMetaReader mr = {0};
|
||||
|
||||
// validate req
|
||||
|
@ -71,9 +71,9 @@ _err:
|
|||
}
|
||||
|
||||
int metaDropSTable(SMeta *pMeta, int64_t verison, SVDropStbReq *pReq) {
|
||||
TBC * pNameIdxc = NULL;
|
||||
TBC * pUidIdxc = NULL;
|
||||
TBC * pCtbIdxc = NULL;
|
||||
TBC *pNameIdxc = NULL;
|
||||
TBC *pUidIdxc = NULL;
|
||||
TBC *pCtbIdxc = NULL;
|
||||
SCtbIdxKey *pCtbIdxKey;
|
||||
const void *pKey = NULL;
|
||||
int nKey;
|
||||
|
@ -134,8 +134,8 @@ _err:
|
|||
int metaAlterSTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq) {
|
||||
SMetaEntry oStbEntry = {0};
|
||||
SMetaEntry nStbEntry = {0};
|
||||
TBC * pUidIdxc = NULL;
|
||||
TBC * pTbDbc = NULL;
|
||||
TBC *pUidIdxc = NULL;
|
||||
TBC *pTbDbc = NULL;
|
||||
const void *pData;
|
||||
int nData;
|
||||
int64_t oversion;
|
||||
|
@ -165,7 +165,9 @@ int metaAlterSTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq) {
|
|||
ret = tdbTbcGet(pTbDbc, NULL, NULL, &pData, &nData);
|
||||
ASSERT(ret == 0);
|
||||
|
||||
tDecoderInit(&dc, pData, nData);
|
||||
oStbEntry.pBuf = taosMemoryMalloc(nData);
|
||||
memcpy(oStbEntry.pBuf, pData, nData);
|
||||
tDecoderInit(&dc, oStbEntry.pBuf, nData);
|
||||
metaDecodeEntry(&dc, &oStbEntry);
|
||||
|
||||
nStbEntry.version = version;
|
||||
|
@ -193,6 +195,7 @@ int metaAlterSTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq) {
|
|||
// update uid index
|
||||
tdbTbcUpsert(pUidIdxc, &pReq->suid, sizeof(tb_uid_t), &version, sizeof(version), 0);
|
||||
|
||||
if (oStbEntry.pBuf) taosMemoryFree(oStbEntry.pBuf);
|
||||
metaULock(pMeta);
|
||||
tDecoderClear(&dc);
|
||||
tdbTbcClose(pTbDbc);
|
||||
|
@ -220,9 +223,6 @@ int metaCreateTable(SMeta *pMeta, int64_t version, SVCreateTbReq *pReq) {
|
|||
terrno = TSDB_CODE_TDB_TABLE_ALREADY_EXIST;
|
||||
metaReaderClear(&mr);
|
||||
return -1;
|
||||
} else {
|
||||
pReq->uid = tGenIdPI64();
|
||||
pReq->ctime = taosGetTimestampMs();
|
||||
}
|
||||
metaReaderClear(&mr);
|
||||
|
||||
|
@ -256,9 +256,9 @@ _err:
|
|||
}
|
||||
|
||||
int metaDropTable(SMeta *pMeta, int64_t version, SVDropTbReq *pReq, SArray *tbUids) {
|
||||
TBC * pTbDbc = NULL;
|
||||
TBC * pUidIdxc = NULL;
|
||||
TBC * pNameIdxc = NULL;
|
||||
TBC *pTbDbc = NULL;
|
||||
TBC *pUidIdxc = NULL;
|
||||
TBC *pNameIdxc = NULL;
|
||||
const void *pData;
|
||||
int nData;
|
||||
tb_uid_t uid;
|
||||
|
@ -377,14 +377,14 @@ int metaDropTable(SMeta *pMeta, int64_t version, SVDropTbReq *pReq, SArray *tbUi
|
|||
}
|
||||
|
||||
static int metaAlterTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pAlterTbReq) {
|
||||
void * pVal = NULL;
|
||||
void *pVal = NULL;
|
||||
int nVal = 0;
|
||||
const void * pData = NULL;
|
||||
const void *pData = NULL;
|
||||
int nData = 0;
|
||||
int ret = 0;
|
||||
tb_uid_t uid;
|
||||
int64_t oversion;
|
||||
SSchema * pColumn = NULL;
|
||||
SSchema *pColumn = NULL;
|
||||
SMetaEntry entry = {0};
|
||||
SSchemaWrapper *pSchema;
|
||||
int c;
|
||||
|
@ -420,7 +420,9 @@ static int metaAlterTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pAl
|
|||
|
||||
// get table entry
|
||||
SDecoder dc = {0};
|
||||
tDecoderInit(&dc, pData, nData);
|
||||
entry.pBuf = taosMemoryMalloc(nData);
|
||||
memcpy(entry.pBuf, pData, nData);
|
||||
tDecoderInit(&dc, entry.pBuf, nData);
|
||||
ret = metaDecodeEntry(&dc, &entry);
|
||||
ASSERT(ret == 0);
|
||||
|
||||
|
@ -530,7 +532,7 @@ _err:
|
|||
static int metaUpdateTableTagVal(SMeta *pMeta, int64_t version, SVAlterTbReq *pAlterTbReq) {
|
||||
SMetaEntry ctbEntry = {0};
|
||||
SMetaEntry stbEntry = {0};
|
||||
void * pVal = NULL;
|
||||
void *pVal = NULL;
|
||||
int nVal = 0;
|
||||
int ret;
|
||||
int c;
|
||||
|
@ -561,7 +563,7 @@ static int metaUpdateTableTagVal(SMeta *pMeta, int64_t version, SVAlterTbReq *pA
|
|||
oversion = *(int64_t *)pData;
|
||||
|
||||
// search table.db
|
||||
TBC * pTbDbc = NULL;
|
||||
TBC *pTbDbc = NULL;
|
||||
SDecoder dc1 = {0};
|
||||
SDecoder dc2 = {0};
|
||||
|
||||
|
@ -585,7 +587,7 @@ static int metaUpdateTableTagVal(SMeta *pMeta, int64_t version, SVAlterTbReq *pA
|
|||
metaDecodeEntry(&dc2, &stbEntry);
|
||||
|
||||
SSchemaWrapper *pTagSchema = &stbEntry.stbEntry.schemaTag;
|
||||
SSchema * pColumn = NULL;
|
||||
SSchema *pColumn = NULL;
|
||||
int32_t iCol = 0;
|
||||
for (;;) {
|
||||
pColumn = NULL;
|
||||
|
@ -605,31 +607,39 @@ static int metaUpdateTableTagVal(SMeta *pMeta, int64_t version, SVAlterTbReq *pA
|
|||
if (iCol == 0) {
|
||||
// TODO : need to update tag index
|
||||
}
|
||||
|
||||
ctbEntry.version = version;
|
||||
SKVRowBuilder kvrb = {0};
|
||||
const SKVRow pOldTag = (const SKVRow)ctbEntry.ctbEntry.pTags;
|
||||
SKVRow pNewTag = NULL;
|
||||
if(pTagSchema->nCols == 1 && pTagSchema->pSchema[0].type == TSDB_DATA_TYPE_JSON){
|
||||
ctbEntry.ctbEntry.pTags = taosMemoryMalloc(pAlterTbReq->nTagVal);
|
||||
if(ctbEntry.ctbEntry.pTags == NULL){
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _err;
|
||||
}
|
||||
memcpy((void*)ctbEntry.ctbEntry.pTags, pAlterTbReq->pTagVal, pAlterTbReq->nTagVal);
|
||||
}else{
|
||||
SKVRowBuilder kvrb = {0};
|
||||
const SKVRow pOldTag = (const SKVRow)ctbEntry.ctbEntry.pTags;
|
||||
SKVRow pNewTag = NULL;
|
||||
|
||||
tdInitKVRowBuilder(&kvrb);
|
||||
for (int32_t i = 0; i < pTagSchema->nCols; i++) {
|
||||
SSchema *pCol = &pTagSchema->pSchema[i];
|
||||
if (iCol == i) {
|
||||
tdAddColToKVRow(&kvrb, pCol->colId, pAlterTbReq->pTagVal, pAlterTbReq->nTagVal);
|
||||
} else {
|
||||
void *p = tdGetKVRowValOfCol(pOldTag, pCol->colId);
|
||||
if (p) {
|
||||
if (IS_VAR_DATA_TYPE(pCol->type)) {
|
||||
tdAddColToKVRow(&kvrb, pCol->colId, p, varDataTLen(p));
|
||||
} else {
|
||||
tdAddColToKVRow(&kvrb, pCol->colId, p, pCol->bytes);
|
||||
tdInitKVRowBuilder(&kvrb);
|
||||
for (int32_t i = 0; i < pTagSchema->nCols; i++) {
|
||||
SSchema *pCol = &pTagSchema->pSchema[i];
|
||||
if (iCol == i) {
|
||||
tdAddColToKVRow(&kvrb, pCol->colId, pAlterTbReq->pTagVal, pAlterTbReq->nTagVal);
|
||||
} else {
|
||||
void *p = tdGetKVRowValOfCol(pOldTag, pCol->colId);
|
||||
if (p) {
|
||||
if (IS_VAR_DATA_TYPE(pCol->type)) {
|
||||
tdAddColToKVRow(&kvrb, pCol->colId, p, varDataTLen(p));
|
||||
} else {
|
||||
tdAddColToKVRow(&kvrb, pCol->colId, p, pCol->bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ctbEntry.ctbEntry.pTags = tdGetKVRowFromBuilder(&kvrb);
|
||||
tdDestroyKVRowBuilder(&kvrb);
|
||||
ctbEntry.ctbEntry.pTags = tdGetKVRowFromBuilder(&kvrb);
|
||||
tdDestroyKVRowBuilder(&kvrb);
|
||||
}
|
||||
|
||||
// save to table.db
|
||||
metaSaveToTbDb(pMeta, &ctbEntry);
|
||||
|
@ -639,6 +649,7 @@ static int metaUpdateTableTagVal(SMeta *pMeta, int64_t version, SVAlterTbReq *pA
|
|||
|
||||
tDecoderClear(&dc1);
|
||||
tDecoderClear(&dc2);
|
||||
if (ctbEntry.ctbEntry.pTags) taosMemoryFree((void*)ctbEntry.ctbEntry.pTags);
|
||||
if (ctbEntry.pBuf) taosMemoryFree(ctbEntry.pBuf);
|
||||
if (stbEntry.pBuf) tdbFree(stbEntry.pBuf);
|
||||
tdbTbcClose(pTbDbc);
|
||||
|
@ -681,8 +692,8 @@ int metaAlterTable(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq) {
|
|||
|
||||
static int metaSaveToTbDb(SMeta *pMeta, const SMetaEntry *pME) {
|
||||
STbDbKey tbDbKey;
|
||||
void * pKey = NULL;
|
||||
void * pVal = NULL;
|
||||
void *pKey = NULL;
|
||||
void *pVal = NULL;
|
||||
int kLen = 0;
|
||||
int vLen = 0;
|
||||
SEncoder coder = {0};
|
||||
|
@ -797,14 +808,14 @@ static void metaDestroyTagIdxKey(STagIdxKey *pTagIdxKey) {
|
|||
}
|
||||
|
||||
static int metaUpdateTagIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry) {
|
||||
void * pData = NULL;
|
||||
void *pData = NULL;
|
||||
int nData = 0;
|
||||
STbDbKey tbDbKey = {0};
|
||||
SMetaEntry stbEntry = {0};
|
||||
STagIdxKey * pTagIdxKey = NULL;
|
||||
STagIdxKey *pTagIdxKey = NULL;
|
||||
int32_t nTagIdxKey;
|
||||
const SSchema *pTagColumn; // = &stbEntry.stbEntry.schema.pSchema[0];
|
||||
const void * pTagData = NULL; //
|
||||
const void *pTagData = NULL; //
|
||||
SDecoder dc = {0};
|
||||
|
||||
// get super table
|
||||
|
@ -846,7 +857,7 @@ static int metaUpdateTagIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry) {
|
|||
|
||||
static int metaSaveToSkmDb(SMeta *pMeta, const SMetaEntry *pME) {
|
||||
SEncoder coder = {0};
|
||||
void * pVal = NULL;
|
||||
void *pVal = NULL;
|
||||
int vLen = 0;
|
||||
int rcode = 0;
|
||||
SSkmDbKey skmDbKey = {0};
|
||||
|
|
|
@ -14,14 +14,37 @@
|
|||
*/
|
||||
|
||||
#include "tq.h"
|
||||
#include "tqueue.h"
|
||||
|
||||
int32_t tqInit() {
|
||||
//
|
||||
int8_t old;
|
||||
while (1) {
|
||||
old = atomic_val_compare_exchange_8(&tqMgmt.inited, 0, 2);
|
||||
if (old != 2) break;
|
||||
}
|
||||
|
||||
if (old == 0) {
|
||||
tqMgmt.timer = taosTmrInit(10000, 100, 10000, "TQ");
|
||||
if (tqMgmt.timer == NULL) {
|
||||
atomic_store_8(&tqMgmt.inited, 0);
|
||||
return -1;
|
||||
}
|
||||
atomic_store_8(&tqMgmt.inited, 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void tqCleanUp() {}
|
||||
void tqCleanUp() {
|
||||
int8_t old;
|
||||
while (1) {
|
||||
old = atomic_val_compare_exchange_8(&tqMgmt.inited, 1, 2);
|
||||
if (old != 2) break;
|
||||
}
|
||||
|
||||
if (old == 1) {
|
||||
taosTmrCleanUp(tqMgmt.timer);
|
||||
atomic_store_8(&tqMgmt.inited, 0);
|
||||
}
|
||||
}
|
||||
|
||||
STQ* tqOpen(const char* path, SVnode* pVnode, SWal* pWal) {
|
||||
STQ* pTq = taosMemoryMalloc(sizeof(STQ));
|
||||
|
@ -32,18 +55,9 @@ STQ* tqOpen(const char* path, SVnode* pVnode, SWal* pWal) {
|
|||
pTq->path = strdup(path);
|
||||
pTq->pVnode = pVnode;
|
||||
pTq->pWal = pWal;
|
||||
/*if (tdbOpen(path, 4096, 1, &pTq->pTdb) < 0) {*/
|
||||
/*ASSERT(0);*/
|
||||
/*}*/
|
||||
|
||||
#if 0
|
||||
pTq->tqMeta = tqStoreOpen(pTq, path, (FTqSerialize)tqSerializeConsumer, (FTqDeserialize)tqDeserializeConsumer,
|
||||
(FTqDelete)taosMemoryFree, 0);
|
||||
if (pTq->tqMeta == NULL) {
|
||||
taosMemoryFree(pTq);
|
||||
return NULL;
|
||||
if (tdbOpen(path, 4096, 1, &pTq->pTdb) < 0) {
|
||||
ASSERT(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
pTq->execs = taosHashInit(64, MurmurHash3_32, true, HASH_ENTRY_LOCK);
|
||||
|
||||
|
@ -60,53 +74,45 @@ void tqClose(STQ* pTq) {
|
|||
taosHashCleanup(pTq->execs);
|
||||
taosHashCleanup(pTq->pStreamTasks);
|
||||
taosHashCleanup(pTq->pushMgr);
|
||||
tdbClose(pTq->pTdb);
|
||||
taosMemoryFree(pTq);
|
||||
}
|
||||
// TODO
|
||||
}
|
||||
|
||||
static void tdSRowDemo() {
|
||||
#define DEMO_N_COLS 3
|
||||
|
||||
int16_t schemaVersion = 0;
|
||||
int32_t numOfCols = DEMO_N_COLS; // ts + int
|
||||
SRowBuilder rb = {0};
|
||||
|
||||
SSchema schema[DEMO_N_COLS] = {
|
||||
{.type = TSDB_DATA_TYPE_TIMESTAMP, .colId = 1, .name = "ts", .bytes = 8, .flags = COL_SMA_ON},
|
||||
{.type = TSDB_DATA_TYPE_INT, .colId = 2, .name = "c1", .bytes = 4, .flags = COL_SMA_ON},
|
||||
{.type = TSDB_DATA_TYPE_INT, .colId = 3, .name = "c2", .bytes = 4, .flags = COL_SMA_ON}};
|
||||
|
||||
SSchema* pSchema = schema;
|
||||
STSchema* pTSChema = tdGetSTSChemaFromSSChema(&pSchema, numOfCols);
|
||||
|
||||
tdSRowInit(&rb, schemaVersion);
|
||||
tdSRowSetTpInfo(&rb, numOfCols, pTSChema->flen);
|
||||
int32_t maxLen = TD_ROW_MAX_BYTES_FROM_SCHEMA(pTSChema);
|
||||
void* row = taosMemoryCalloc(1, maxLen); // make sure the buffer is enough
|
||||
|
||||
// set row buf
|
||||
tdSRowResetBuf(&rb, row);
|
||||
|
||||
for (int32_t idx = 0; idx < pTSChema->numOfCols; ++idx) {
|
||||
STColumn* pColumn = pTSChema->columns + idx;
|
||||
if (idx == 0) {
|
||||
int64_t tsKey = 1651234567;
|
||||
tdAppendColValToRow(&rb, pColumn->colId, pColumn->type, TD_VTYPE_NORM, &tsKey, true, pColumn->offset, idx);
|
||||
} else if (idx == 1) {
|
||||
int32_t val1 = 10;
|
||||
tdAppendColValToRow(&rb, pColumn->colId, pColumn->type, TD_VTYPE_NORM, &val1, true, pColumn->offset, idx);
|
||||
} else {
|
||||
tdAppendColValToRow(&rb, pColumn->colId, pColumn->type, TD_VTYPE_NONE, NULL, true, pColumn->offset, idx);
|
||||
}
|
||||
int32_t tEncodeSTqExec(SEncoder* pEncoder, const STqExec* pExec) {
|
||||
if (tStartEncode(pEncoder) < 0) return -1;
|
||||
if (tEncodeCStr(pEncoder, pExec->subKey) < 0) return -1;
|
||||
if (tEncodeI64(pEncoder, pExec->consumerId) < 0) return -1;
|
||||
if (tEncodeI32(pEncoder, pExec->epoch) < 0) return -1;
|
||||
if (tEncodeI8(pEncoder, pExec->subType) < 0) return -1;
|
||||
if (tEncodeI8(pEncoder, pExec->withTbName) < 0) return -1;
|
||||
if (tEncodeI8(pEncoder, pExec->withSchema) < 0) return -1;
|
||||
if (tEncodeI8(pEncoder, pExec->withTag) < 0) return -1;
|
||||
if (pExec->subType == TOPIC_SUB_TYPE__TABLE) {
|
||||
if (tEncodeCStr(pEncoder, pExec->qmsg) < 0) return -1;
|
||||
// TODO encode modified exec
|
||||
}
|
||||
|
||||
// print
|
||||
tdSRowPrint(row, pTSChema, __func__);
|
||||
|
||||
taosMemoryFree(pTSChema);
|
||||
tEndEncode(pEncoder);
|
||||
return pEncoder->pos;
|
||||
}
|
||||
|
||||
int32_t tDecodeSTqExec(SDecoder* pDecoder, STqExec* pExec) {
|
||||
if (tStartDecode(pDecoder) < 0) return -1;
|
||||
if (tDecodeCStrTo(pDecoder, pExec->subKey) < 0) return -1;
|
||||
if (tDecodeI64(pDecoder, &pExec->consumerId) < 0) return -1;
|
||||
if (tDecodeI32(pDecoder, &pExec->epoch) < 0) return -1;
|
||||
if (tDecodeI8(pDecoder, &pExec->subType) < 0) return -1;
|
||||
if (tDecodeI8(pDecoder, &pExec->withTbName) < 0) return -1;
|
||||
if (tDecodeI8(pDecoder, &pExec->withSchema) < 0) return -1;
|
||||
if (tDecodeI8(pDecoder, &pExec->withTag) < 0) return -1;
|
||||
if (pExec->subType == TOPIC_SUB_TYPE__TABLE) {
|
||||
if (tDecodeCStrAlloc(pDecoder, &pExec->qmsg) < 0) return -1;
|
||||
// TODO decode modified exec
|
||||
}
|
||||
tEndDecode(pDecoder);
|
||||
return 0;
|
||||
}
|
||||
int32_t tqUpdateTbUidList(STQ* pTq, const SArray* tbUidList, bool isAdd) {
|
||||
void* pIter = NULL;
|
||||
while (1) {
|
||||
|
@ -261,166 +267,26 @@ int32_t tqPushMsgNew(STQ* pTq, void* msg, int32_t msgLen, tmsg_t msgType, int64_
|
|||
}
|
||||
|
||||
int tqPushMsg(STQ* pTq, void* msg, int32_t msgLen, tmsg_t msgType, int64_t ver) {
|
||||
if (msgType != TDMT_VND_SUBMIT) return 0;
|
||||
if (msgType == TDMT_VND_SUBMIT) {
|
||||
if (taosHashGetSize(pTq->pStreamTasks) == 0) return 0;
|
||||
|
||||
// make sure msgType == TDMT_VND_SUBMIT
|
||||
if (tdUpdateExpireWindow(pTq->pVnode->pSma, msg, ver) != 0) {
|
||||
return -1;
|
||||
if (tdUpdateExpireWindow(pTq->pVnode->pSma, msg, ver) != 0) {
|
||||
// TODO handle sma error
|
||||
}
|
||||
void* data = taosMemoryMalloc(msgLen);
|
||||
if (data == NULL) {
|
||||
return -1;
|
||||
}
|
||||
memcpy(data, msg, msgLen);
|
||||
|
||||
tqProcessStreamTrigger(pTq, data);
|
||||
}
|
||||
|
||||
if (taosHashGetSize(pTq->pStreamTasks) == 0) return 0;
|
||||
|
||||
void* data = taosMemoryMalloc(msgLen);
|
||||
if (data == NULL) {
|
||||
return -1;
|
||||
}
|
||||
memcpy(data, msg, msgLen);
|
||||
|
||||
tqProcessStreamTriggerNew(pTq, data);
|
||||
|
||||
#if 0
|
||||
SRpcMsg req = {
|
||||
.msgType = TDMT_VND_STREAM_TRIGGER,
|
||||
.pCont = data,
|
||||
.contLen = msgLen,
|
||||
};
|
||||
|
||||
tmsgPutToQueue(&pTq->pVnode->msgCb, FETCH_QUEUE, &req);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tqCommit(STQ* pTq) {
|
||||
// do nothing
|
||||
/*return tqStorePersist(pTq->tqMeta);*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tqGetTopicHandleSize(const STqTopic* pTopic) {
|
||||
return strlen(pTopic->topicName) + strlen(pTopic->sql) + strlen(pTopic->physicalPlan) + strlen(pTopic->qmsg) +
|
||||
sizeof(int64_t) * 3;
|
||||
}
|
||||
|
||||
int32_t tqGetConsumerHandleSize(const STqConsumer* pConsumer) {
|
||||
int num = taosArrayGetSize(pConsumer->topics);
|
||||
int32_t sz = 0;
|
||||
for (int i = 0; i < num; i++) {
|
||||
STqTopic* pTopic = taosArrayGet(pConsumer->topics, i);
|
||||
sz += tqGetTopicHandleSize(pTopic);
|
||||
}
|
||||
return sz;
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tEncodeSTqTopic(void** buf, const STqTopic* pTopic) {
|
||||
int32_t tlen = 0;
|
||||
tlen += taosEncodeString(buf, pTopic->topicName);
|
||||
/*tlen += taosEncodeString(buf, pTopic->sql);*/
|
||||
/*tlen += taosEncodeString(buf, pTopic->physicalPlan);*/
|
||||
tlen += taosEncodeString(buf, pTopic->qmsg);
|
||||
/*tlen += taosEncodeFixedI64(buf, pTopic->persistedOffset);*/
|
||||
/*tlen += taosEncodeFixedI64(buf, pTopic->committedOffset);*/
|
||||
/*tlen += taosEncodeFixedI64(buf, pTopic->currentOffset);*/
|
||||
return tlen;
|
||||
}
|
||||
|
||||
static FORCE_INLINE const void* tDecodeSTqTopic(const void* buf, STqTopic* pTopic) {
|
||||
buf = taosDecodeStringTo(buf, pTopic->topicName);
|
||||
/*buf = taosDecodeString(buf, &pTopic->sql);*/
|
||||
/*buf = taosDecodeString(buf, &pTopic->physicalPlan);*/
|
||||
buf = taosDecodeString(buf, &pTopic->qmsg);
|
||||
/*buf = taosDecodeFixedI64(buf, &pTopic->persistedOffset);*/
|
||||
/*buf = taosDecodeFixedI64(buf, &pTopic->committedOffset);*/
|
||||
/*buf = taosDecodeFixedI64(buf, &pTopic->currentOffset);*/
|
||||
return buf;
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tEncodeSTqConsumer(void** buf, const STqConsumer* pConsumer) {
|
||||
int32_t sz;
|
||||
|
||||
int32_t tlen = 0;
|
||||
tlen += taosEncodeFixedI64(buf, pConsumer->consumerId);
|
||||
tlen += taosEncodeFixedI32(buf, pConsumer->epoch);
|
||||
tlen += taosEncodeString(buf, pConsumer->cgroup);
|
||||
sz = taosArrayGetSize(pConsumer->topics);
|
||||
tlen += taosEncodeFixedI32(buf, sz);
|
||||
for (int32_t i = 0; i < sz; i++) {
|
||||
STqTopic* pTopic = taosArrayGet(pConsumer->topics, i);
|
||||
tlen += tEncodeSTqTopic(buf, pTopic);
|
||||
}
|
||||
return tlen;
|
||||
}
|
||||
|
||||
static FORCE_INLINE const void* tDecodeSTqConsumer(const void* buf, STqConsumer* pConsumer) {
|
||||
int32_t sz;
|
||||
|
||||
buf = taosDecodeFixedI64(buf, &pConsumer->consumerId);
|
||||
buf = taosDecodeFixedI32(buf, &pConsumer->epoch);
|
||||
buf = taosDecodeStringTo(buf, pConsumer->cgroup);
|
||||
buf = taosDecodeFixedI32(buf, &sz);
|
||||
pConsumer->topics = taosArrayInit(sz, sizeof(STqTopic));
|
||||
if (pConsumer->topics == NULL) return NULL;
|
||||
for (int32_t i = 0; i < sz; i++) {
|
||||
STqTopic pTopic;
|
||||
buf = tDecodeSTqTopic(buf, &pTopic);
|
||||
taosArrayPush(pConsumer->topics, &pTopic);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
int tqSerializeConsumer(const STqConsumer* pConsumer, STqSerializedHead** ppHead) {
|
||||
int32_t sz = tEncodeSTqConsumer(NULL, pConsumer);
|
||||
|
||||
if (sz > (*ppHead)->ssize) {
|
||||
void* tmpPtr = taosMemoryRealloc(*ppHead, sizeof(STqSerializedHead) + sz);
|
||||
if (tmpPtr == NULL) {
|
||||
taosMemoryFree(*ppHead);
|
||||
terrno = TSDB_CODE_TQ_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
*ppHead = tmpPtr;
|
||||
(*ppHead)->ssize = sz;
|
||||
}
|
||||
|
||||
void* ptr = (*ppHead)->content;
|
||||
void* abuf = ptr;
|
||||
tEncodeSTqConsumer(&abuf, pConsumer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tqDeserializeConsumer(STQ* pTq, const STqSerializedHead* pHead, STqConsumer** ppConsumer) {
|
||||
const void* str = pHead->content;
|
||||
*ppConsumer = taosMemoryCalloc(1, sizeof(STqConsumer));
|
||||
if (*ppConsumer == NULL) {
|
||||
terrno = TSDB_CODE_TQ_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
if (tDecodeSTqConsumer(str, *ppConsumer) == NULL) {
|
||||
terrno = TSDB_CODE_TQ_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
STqConsumer* pConsumer = *ppConsumer;
|
||||
int32_t sz = taosArrayGetSize(pConsumer->topics);
|
||||
for (int32_t i = 0; i < sz; i++) {
|
||||
STqTopic* pTopic = taosArrayGet(pConsumer->topics, i);
|
||||
pTopic->pReadhandle = walOpenReadHandle(pTq->pWal);
|
||||
if (pTopic->pReadhandle == NULL) {
|
||||
ASSERT(false);
|
||||
}
|
||||
for (int j = 0; j < TQ_BUFFER_SIZE; j++) {
|
||||
pTopic->buffer.output[j].status = 0;
|
||||
STqReadHandle* pReadHandle = tqInitSubmitMsgScanner(pTq->pVnode->pMeta);
|
||||
SReadHandle handle = {
|
||||
.reader = pReadHandle,
|
||||
.meta = pTq->pVnode->pMeta,
|
||||
.pMsgCb = &pTq->pVnode->msgCb,
|
||||
};
|
||||
pTopic->buffer.output[j].pReadHandle = pReadHandle;
|
||||
pTopic->buffer.output[j].task = qCreateStreamExecTaskInfo(pTopic->qmsg, &handle);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -685,213 +551,6 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg, int32_t workerId) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg, int32_t workerId) {
|
||||
SMqPollReq* pReq = pMsg->pCont;
|
||||
int64_t consumerId = pReq->consumerId;
|
||||
int64_t fetchOffset;
|
||||
int64_t blockingTime = pReq->blockingTime;
|
||||
int32_t reqEpoch = pReq->epoch;
|
||||
|
||||
if (pReq->currentOffset == TMQ_CONF__RESET_OFFSET__EARLIEAST) {
|
||||
fetchOffset = walGetFirstVer(pTq->pWal);
|
||||
} else if (pReq->currentOffset == TMQ_CONF__RESET_OFFSET__LATEST) {
|
||||
fetchOffset = walGetLastVer(pTq->pWal);
|
||||
} else {
|
||||
fetchOffset = pReq->currentOffset + 1;
|
||||
}
|
||||
|
||||
tqDebug("tmq poll: consumer %ld (epoch %d) recv poll req in vg %d, req %ld %ld", consumerId, pReq->epoch,
|
||||
TD_VID(pTq->pVnode), pReq->currentOffset, fetchOffset);
|
||||
|
||||
SMqPollRspV2 rspV2 = {0};
|
||||
rspV2.dataLen = 0;
|
||||
|
||||
STqConsumer* pConsumer = tqHandleGet(pTq->tqMeta, consumerId);
|
||||
if (pConsumer == NULL) {
|
||||
vWarn("tmq poll: consumer %ld (epoch %d) not found in vg %d", consumerId, pReq->epoch, TD_VID(pTq->pVnode));
|
||||
pMsg->pCont = NULL;
|
||||
pMsg->contLen = 0;
|
||||
pMsg->code = -1;
|
||||
tmsgSendRsp(pMsg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t consumerEpoch = atomic_load_32(&pConsumer->epoch);
|
||||
while (consumerEpoch < reqEpoch) {
|
||||
consumerEpoch = atomic_val_compare_exchange_32(&pConsumer->epoch, consumerEpoch, reqEpoch);
|
||||
}
|
||||
|
||||
STqTopic* pTopic = NULL;
|
||||
int32_t topicSz = taosArrayGetSize(pConsumer->topics);
|
||||
for (int32_t i = 0; i < topicSz; i++) {
|
||||
STqTopic* topic = taosArrayGet(pConsumer->topics, i);
|
||||
// TODO race condition
|
||||
ASSERT(pConsumer->consumerId == consumerId);
|
||||
if (strcmp(topic->topicName, pReq->topic) == 0) {
|
||||
pTopic = topic;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pTopic == NULL) {
|
||||
vWarn("tmq poll: consumer %ld (epoch %d) topic %s not found in vg %d", consumerId, pReq->epoch, pReq->topic,
|
||||
TD_VID(pTq->pVnode));
|
||||
pMsg->pCont = NULL;
|
||||
pMsg->contLen = 0;
|
||||
pMsg->code = -1;
|
||||
tmsgSendRsp(pMsg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
tqDebug("poll topic %s from consumer %ld (epoch %d) vg %d", pTopic->topicName, consumerId, pReq->epoch,
|
||||
TD_VID(pTq->pVnode));
|
||||
|
||||
rspV2.reqOffset = pReq->currentOffset;
|
||||
rspV2.skipLogNum = 0;
|
||||
|
||||
while (1) {
|
||||
/*if (fetchOffset > walGetLastVer(pTq->pWal) || walReadWithHandle(pTopic->pReadhandle, fetchOffset) < 0) {*/
|
||||
// TODO
|
||||
consumerEpoch = atomic_load_32(&pConsumer->epoch);
|
||||
if (consumerEpoch > reqEpoch) {
|
||||
tqDebug("tmq poll: consumer %ld (epoch %d) vg %d offset %ld, found new consumer epoch %d discard req epoch %d",
|
||||
consumerId, pReq->epoch, TD_VID(pTq->pVnode), fetchOffset, consumerEpoch, reqEpoch);
|
||||
break;
|
||||
}
|
||||
SWalReadHead* pHead;
|
||||
if (walReadWithHandle_s(pTopic->pReadhandle, fetchOffset, &pHead) < 0) {
|
||||
// TODO: no more log, set timer to wait blocking time
|
||||
// if data inserted during waiting, launch query and
|
||||
// response to user
|
||||
tqDebug("tmq poll: consumer %ld (epoch %d) vg %d offset %ld, no more log to return", consumerId, pReq->epoch,
|
||||
TD_VID(pTq->pVnode), fetchOffset);
|
||||
break;
|
||||
}
|
||||
tqDebug("tmq poll: consumer %ld (epoch %d) iter log, vg %d offset %ld msgType %d", consumerId, pReq->epoch,
|
||||
TD_VID(pTq->pVnode), fetchOffset, pHead->msgType);
|
||||
/*int8_t pos = fetchOffset % TQ_BUFFER_SIZE;*/
|
||||
/*pHead = pTopic->pReadhandle->pHead;*/
|
||||
if (pHead->msgType == TDMT_VND_SUBMIT) {
|
||||
SSubmitReq* pCont = (SSubmitReq*)&pHead->body;
|
||||
qTaskInfo_t task = pTopic->buffer.output[workerId].task;
|
||||
ASSERT(task);
|
||||
qSetStreamInput(task, pCont, STREAM_DATA_TYPE_SUBMIT_BLOCK);
|
||||
SArray* pRes = taosArrayInit(0, sizeof(SSDataBlock));
|
||||
while (1) {
|
||||
SSDataBlock* pDataBlock = NULL;
|
||||
uint64_t ts;
|
||||
if (qExecTask(task, &pDataBlock, &ts) < 0) {
|
||||
ASSERT(false);
|
||||
}
|
||||
if (pDataBlock == NULL) {
|
||||
/*pos = fetchOffset % TQ_BUFFER_SIZE;*/
|
||||
break;
|
||||
}
|
||||
|
||||
taosArrayPush(pRes, pDataBlock);
|
||||
}
|
||||
|
||||
if (taosArrayGetSize(pRes) == 0) {
|
||||
tqDebug("tmq poll: consumer %ld (epoch %d) iter log, vg %d skip log %ld since not wanted", consumerId,
|
||||
pReq->epoch, TD_VID(pTq->pVnode), fetchOffset);
|
||||
fetchOffset++;
|
||||
rspV2.skipLogNum++;
|
||||
taosArrayDestroy(pRes);
|
||||
continue;
|
||||
}
|
||||
rspV2.rspOffset = fetchOffset;
|
||||
|
||||
int32_t blockSz = taosArrayGetSize(pRes);
|
||||
int32_t dataBlockStrLen = 0;
|
||||
for (int32_t i = 0; i < blockSz; i++) {
|
||||
SSDataBlock* pBlock = taosArrayGet(pRes, i);
|
||||
dataBlockStrLen += sizeof(SRetrieveTableRsp) + blockGetEncodeSize(pBlock);
|
||||
}
|
||||
|
||||
void* dataBlockBuf = taosMemoryMalloc(dataBlockStrLen);
|
||||
if (dataBlockBuf == NULL) {
|
||||
pMsg->code = -1;
|
||||
taosMemoryFree(pHead);
|
||||
}
|
||||
|
||||
rspV2.blockData = dataBlockBuf;
|
||||
|
||||
int32_t pos;
|
||||
rspV2.blockPos = taosArrayInit(blockSz, sizeof(int32_t));
|
||||
for (int32_t i = 0; i < blockSz; i++) {
|
||||
pos = 0;
|
||||
SSDataBlock* pBlock = taosArrayGet(pRes, i);
|
||||
SRetrieveTableRsp* pRetrieve = (SRetrieveTableRsp*)dataBlockBuf;
|
||||
pRetrieve->useconds = 0;
|
||||
pRetrieve->precision = 0;
|
||||
pRetrieve->compressed = 0;
|
||||
pRetrieve->completed = 1;
|
||||
pRetrieve->numOfRows = htonl(pBlock->info.rows);
|
||||
blockCompressEncode(pBlock, pRetrieve->data, &pos, pBlock->info.numOfCols, false);
|
||||
taosArrayPush(rspV2.blockPos, &rspV2.dataLen);
|
||||
|
||||
int32_t totLen = sizeof(SRetrieveTableRsp) + pos;
|
||||
pRetrieve->compLen = htonl(totLen);
|
||||
rspV2.dataLen += totLen;
|
||||
dataBlockBuf = POINTER_SHIFT(dataBlockBuf, totLen);
|
||||
}
|
||||
ASSERT(POINTER_DISTANCE(dataBlockBuf, rspV2.blockData) <= dataBlockStrLen);
|
||||
|
||||
int32_t msgLen = sizeof(SMqRspHead) + tEncodeSMqPollRspV2(NULL, &rspV2);
|
||||
void* buf = rpcMallocCont(msgLen);
|
||||
|
||||
((SMqRspHead*)buf)->mqMsgType = TMQ_MSG_TYPE__POLL_RSP;
|
||||
((SMqRspHead*)buf)->epoch = pReq->epoch;
|
||||
((SMqRspHead*)buf)->consumerId = consumerId;
|
||||
|
||||
void* msgBodyBuf = POINTER_SHIFT(buf, sizeof(SMqRspHead));
|
||||
tEncodeSMqPollRspV2(&msgBodyBuf, &rspV2);
|
||||
|
||||
/*rsp.pBlockData = pRes;*/
|
||||
|
||||
/*taosArrayDestroyEx(rsp.pBlockData, (void (*)(void*))tDeleteSSDataBlock);*/
|
||||
SRpcMsg resp = {.info = pMsg->info, pCont = buf, .contLen = msgLen, .code = 0};
|
||||
tqDebug("vg %d offset %ld msgType %d from consumer %ld (epoch %d) actual rsp", TD_VID(pTq->pVnode), fetchOffset,
|
||||
pHead->msgType, consumerId, pReq->epoch);
|
||||
tmsgSendRsp(&resp);
|
||||
taosMemoryFree(pHead);
|
||||
return 0;
|
||||
} else {
|
||||
taosMemoryFree(pHead);
|
||||
fetchOffset++;
|
||||
rspV2.skipLogNum++;
|
||||
}
|
||||
}
|
||||
|
||||
/*if (blockingTime != 0) {*/
|
||||
/*tqAddClientPusher(pTq->tqPushMgr, pMsg, consumerId, blockingTime);*/
|
||||
/*} else {*/
|
||||
|
||||
rspV2.rspOffset = fetchOffset - 1;
|
||||
|
||||
int32_t tlen = sizeof(SMqRspHead) + tEncodeSMqPollRspV2(NULL, &rspV2);
|
||||
void* buf = rpcMallocCont(tlen);
|
||||
if (buf == NULL) {
|
||||
pMsg->code = -1;
|
||||
return -1;
|
||||
}
|
||||
((SMqRspHead*)buf)->mqMsgType = TMQ_MSG_TYPE__POLL_RSP;
|
||||
((SMqRspHead*)buf)->epoch = pReq->epoch;
|
||||
((SMqRspHead*)buf)->consumerId = consumerId;
|
||||
|
||||
void* abuf = POINTER_SHIFT(buf, sizeof(SMqRspHead));
|
||||
tEncodeSMqPollRspV2(&abuf, &rspV2);
|
||||
|
||||
SRpcMsg resp = {.info = pMsg->info, .pCont = buf, .contLen = tlen, .code = 0};
|
||||
tmsgSendRsp(&resp);
|
||||
tqDebug("vg %d offset %ld from consumer %ld (epoch %d) not rsp", TD_VID(pTq->pVnode), fetchOffset, consumerId,
|
||||
pReq->epoch);
|
||||
/*}*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int32_t tqProcessVgDeleteReq(STQ* pTq, char* msg, int32_t msgLen) {
|
||||
SMqVDeleteReq* pReq = (SMqVDeleteReq*)msg;
|
||||
|
||||
|
@ -981,55 +640,6 @@ void tqTableSink(SStreamTask* pTask, void* vnode, int64_t ver, void* data) {
|
|||
ASSERT(tmsgPutToQueue(&pVnode->msgCb, WRITE_QUEUE, &msg) == 0);
|
||||
}
|
||||
|
||||
int32_t tqExpandTask(STQ* pTq, SStreamTask* pTask, int32_t parallel) {
|
||||
pTask->status = TASK_STATUS__IDLE;
|
||||
pTask->inputStatus = TASK_INPUT_STATUS__NORMAL;
|
||||
pTask->outputStatus = TASK_OUTPUT_STATUS__NORMAL;
|
||||
|
||||
pTask->inputQ = taosOpenQueue();
|
||||
pTask->outputQ = taosOpenQueue();
|
||||
pTask->inputQAll = taosAllocateQall();
|
||||
pTask->outputQAll = taosAllocateQall();
|
||||
|
||||
if (pTask->inputQ == NULL || pTask->outputQ == NULL || pTask->inputQAll == NULL || pTask->outputQAll == NULL)
|
||||
goto FAIL;
|
||||
|
||||
if (pTask->execType != TASK_EXEC__NONE) {
|
||||
// expand runners
|
||||
pTask->exec.numOfRunners = parallel;
|
||||
pTask->exec.runners = taosMemoryCalloc(parallel, sizeof(SStreamRunner));
|
||||
if (pTask->exec.runners == NULL) {
|
||||
goto FAIL;
|
||||
}
|
||||
for (int32_t i = 0; i < parallel; i++) {
|
||||
STqReadHandle* pStreamReader = tqInitSubmitMsgScanner(pTq->pVnode->pMeta);
|
||||
SReadHandle handle = {
|
||||
.reader = pStreamReader,
|
||||
.meta = pTq->pVnode->pMeta,
|
||||
.pMsgCb = &pTq->pVnode->msgCb,
|
||||
.vnode = pTq->pVnode,
|
||||
};
|
||||
pTask->exec.runners[i].inputHandle = pStreamReader;
|
||||
pTask->exec.runners[i].executor = qCreateStreamExecTaskInfo(pTask->exec.qmsg, &handle);
|
||||
ASSERT(pTask->exec.runners[i].executor);
|
||||
}
|
||||
}
|
||||
|
||||
if (pTask->sinkType == TASK_SINK__TABLE) {
|
||||
pTask->tbSink.vnode = pTq->pVnode;
|
||||
pTask->tbSink.tbSinkFunc = tqTableSink;
|
||||
}
|
||||
|
||||
return 0;
|
||||
FAIL:
|
||||
if (pTask->inputQ) taosCloseQueue(pTask->inputQ);
|
||||
if (pTask->outputQ) taosCloseQueue(pTask->outputQ);
|
||||
if (pTask->inputQAll) taosFreeQall(pTask->inputQAll);
|
||||
if (pTask->outputQAll) taosFreeQall(pTask->outputQAll);
|
||||
if (pTask) taosMemoryFree(pTask);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t tqProcessTaskDeploy(STQ* pTq, char* msg, int32_t msgLen) {
|
||||
SStreamTask* pTask = taosMemoryCalloc(1, sizeof(SStreamTask));
|
||||
if (pTask == NULL) {
|
||||
|
@ -1042,9 +652,31 @@ int32_t tqProcessTaskDeploy(STQ* pTq, char* msg, int32_t msgLen) {
|
|||
}
|
||||
tDecoderClear(&decoder);
|
||||
|
||||
pTask->status = TASK_STATUS__IDLE;
|
||||
pTask->inputStatus = TASK_INPUT_STATUS__NORMAL;
|
||||
pTask->outputStatus = TASK_OUTPUT_STATUS__NORMAL;
|
||||
|
||||
pTask->inputQ = taosOpenQueue();
|
||||
pTask->outputQ = taosOpenQueue();
|
||||
pTask->inputQAll = taosAllocateQall();
|
||||
pTask->outputQAll = taosAllocateQall();
|
||||
|
||||
if (pTask->inputQ == NULL || pTask->outputQ == NULL || pTask->inputQAll == NULL || pTask->outputQAll == NULL)
|
||||
goto FAIL;
|
||||
|
||||
// exec
|
||||
if (tqExpandTask(pTq, pTask, 4) < 0) {
|
||||
ASSERT(0);
|
||||
if (pTask->execType != TASK_EXEC__NONE) {
|
||||
// expand runners
|
||||
STqReadHandle* pStreamReader = tqInitSubmitMsgScanner(pTq->pVnode->pMeta);
|
||||
SReadHandle handle = {
|
||||
.reader = pStreamReader,
|
||||
.meta = pTq->pVnode->pMeta,
|
||||
.pMsgCb = &pTq->pVnode->msgCb,
|
||||
.vnode = pTq->pVnode,
|
||||
};
|
||||
pTask->exec.inputHandle = pStreamReader;
|
||||
pTask->exec.executor = qCreateStreamExecTaskInfo(pTask->exec.qmsg, &handle);
|
||||
ASSERT(pTask->exec.executor);
|
||||
}
|
||||
|
||||
// sink
|
||||
|
@ -1052,8 +684,12 @@ int32_t tqProcessTaskDeploy(STQ* pTq, char* msg, int32_t msgLen) {
|
|||
if (pTask->sinkType == TASK_SINK__SMA) {
|
||||
pTask->smaSink.smaSink = smaHandleRes;
|
||||
} else if (pTask->sinkType == TASK_SINK__TABLE) {
|
||||
pTask->tbSink.vnode = pTq->pVnode;
|
||||
pTask->tbSink.tbSinkFunc = tqTableSink;
|
||||
|
||||
ASSERT(pTask->tbSink.pSchemaWrapper);
|
||||
ASSERT(pTask->tbSink.pSchemaWrapper->pSchema);
|
||||
|
||||
pTask->tbSink.pTSchema =
|
||||
tdGetSTSChemaFromSSChema(&pTask->tbSink.pSchemaWrapper->pSchema, pTask->tbSink.pSchemaWrapper->nCols);
|
||||
ASSERT(pTask->tbSink.pTSchema);
|
||||
|
@ -1061,94 +697,17 @@ int32_t tqProcessTaskDeploy(STQ* pTq, char* msg, int32_t msgLen) {
|
|||
|
||||
taosHashPut(pTq->pStreamTasks, &pTask->taskId, sizeof(int32_t), pTask, sizeof(SStreamTask));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tqProcessStreamTrigger(STQ* pTq, void* data, int32_t dataLen, int32_t workerId) {
|
||||
void* pIter = NULL;
|
||||
|
||||
while (1) {
|
||||
pIter = taosHashIterate(pTq->pStreamTasks, pIter);
|
||||
if (pIter == NULL) break;
|
||||
SStreamTask* pTask = (SStreamTask*)pIter;
|
||||
|
||||
if (streamExecTask(pTask, &pTq->pVnode->msgCb, data, STREAM_DATA_TYPE_SUBMIT_BLOCK, workerId) < 0) {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
int32_t tqProcessStreamTriggerNew(STQ* pTq, SSubmitReq* data) {
|
||||
SStreamDataSubmit* pSubmit = NULL;
|
||||
|
||||
// build data
|
||||
pSubmit = taosAllocateQitem(sizeof(SStreamDataSubmit), DEF_QITEM);
|
||||
if (pSubmit == NULL) return -1;
|
||||
pSubmit->dataRef = taosMemoryMalloc(sizeof(int32_t));
|
||||
if (pSubmit->dataRef == NULL) goto FAIL;
|
||||
*pSubmit->dataRef = 1;
|
||||
pSubmit->data = data;
|
||||
pSubmit->type = STREAM_INPUT__DATA_BLOCK;
|
||||
|
||||
void* pIter = NULL;
|
||||
while (1) {
|
||||
pIter = taosHashIterate(pTq->pStreamTasks, pIter);
|
||||
if (pIter == NULL) break;
|
||||
SStreamTask* pTask = (SStreamTask*)pIter;
|
||||
if (pTask->inputType == TASK_INPUT_TYPE__SUMBIT_BLOCK) {
|
||||
streamEnqueueDataSubmit(pTask, pSubmit);
|
||||
// TODO cal back pressure
|
||||
}
|
||||
// check run
|
||||
int8_t execStatus = atomic_load_8(&pTask->status);
|
||||
if (execStatus == TASK_STATUS__IDLE || execStatus == TASK_STATUS__CLOSING) {
|
||||
SStreamTaskRunReq* pReq = taosMemoryMalloc(sizeof(SStreamTaskRunReq));
|
||||
if (pReq == NULL) continue;
|
||||
// TODO: do we need htonl?
|
||||
pReq->head.vgId = pTq->pVnode->config.vgId;
|
||||
pReq->streamId = pTask->streamId;
|
||||
pReq->taskId = pTask->taskId;
|
||||
SRpcMsg msg = {
|
||||
.msgType = 0,
|
||||
.pCont = pReq,
|
||||
.contLen = sizeof(SStreamTaskRunReq),
|
||||
};
|
||||
tmsgPutToQueue(&pTq->pVnode->msgCb, FETCH_QUEUE, &msg);
|
||||
}
|
||||
}
|
||||
streamDataSubmitRefDec(pSubmit);
|
||||
|
||||
return 0;
|
||||
FAIL:
|
||||
if (pSubmit) {
|
||||
if (pSubmit->dataRef) {
|
||||
taosMemoryFree(pSubmit->dataRef);
|
||||
}
|
||||
taosFreeQitem(pSubmit);
|
||||
}
|
||||
if (pTask->inputQ) taosCloseQueue(pTask->inputQ);
|
||||
if (pTask->outputQ) taosCloseQueue(pTask->outputQ);
|
||||
if (pTask->inputQAll) taosFreeQall(pTask->inputQAll);
|
||||
if (pTask->outputQAll) taosFreeQall(pTask->outputQAll);
|
||||
if (pTask) taosMemoryFree(pTask);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
int32_t tqProcessTaskExec(STQ* pTq, char* msg, int32_t msgLen, int32_t workerId) {
|
||||
SStreamTaskExecReq req;
|
||||
tDecodeSStreamTaskExecReq(msg, &req);
|
||||
|
||||
int32_t taskId = req.taskId;
|
||||
ASSERT(taskId);
|
||||
|
||||
SStreamTask* pTask = taosHashGet(pTq->pStreamTasks, &taskId, sizeof(int32_t));
|
||||
ASSERT(pTask);
|
||||
|
||||
if (streamExecTask(pTask, &pTq->pVnode->msgCb, req.data, STREAM_DATA_TYPE_SSDATA_BLOCK, workerId) < 0) {
|
||||
// TODO
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tqProcessStreamTriggerNew(STQ* pTq, SSubmitReq* pReq) {
|
||||
int32_t tqProcessStreamTrigger(STQ* pTq, SSubmitReq* pReq) {
|
||||
void* pIter = NULL;
|
||||
bool failed = false;
|
||||
|
||||
|
@ -1234,7 +793,7 @@ int32_t tqProcessTaskDispatchReq(STQ* pTq, SRpcMsg* pMsg) {
|
|||
SStreamDispatchReq* pReq = pMsg->pCont;
|
||||
int32_t taskId = pReq->taskId;
|
||||
SStreamTask* pTask = taosHashGet(pTq->pStreamTasks, &taskId, sizeof(int32_t));
|
||||
streamTaskProcessDispatchReq(pTask, &pTq->pVnode->msgCb, pReq, pMsg);
|
||||
streamProcessDispatchReq(pTask, &pTq->pVnode->msgCb, pReq, pMsg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1242,7 +801,7 @@ int32_t tqProcessTaskRecoverReq(STQ* pTq, SRpcMsg* pMsg) {
|
|||
SStreamTaskRecoverReq* pReq = pMsg->pCont;
|
||||
int32_t taskId = pReq->taskId;
|
||||
SStreamTask* pTask = taosHashGet(pTq->pStreamTasks, &taskId, sizeof(int32_t));
|
||||
streamTaskProcessRecoverReq(pTask, &pTq->pVnode->msgCb, pReq, pMsg);
|
||||
streamProcessRecoverReq(pTask, &pTq->pVnode->msgCb, pReq, pMsg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1250,7 +809,7 @@ int32_t tqProcessTaskDispatchRsp(STQ* pTq, SRpcMsg* pMsg) {
|
|||
SStreamDispatchRsp* pRsp = pMsg->pCont;
|
||||
int32_t taskId = pRsp->taskId;
|
||||
SStreamTask* pTask = taosHashGet(pTq->pStreamTasks, &taskId, sizeof(int32_t));
|
||||
streamTaskProcessDispatchRsp(pTask, &pTq->pVnode->msgCb, pRsp);
|
||||
streamProcessDispatchRsp(pTask, &pTq->pVnode->msgCb, pRsp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1258,6 +817,6 @@ int32_t tqProcessTaskRecoverRsp(STQ* pTq, SRpcMsg* pMsg) {
|
|||
SStreamTaskRecoverRsp* pRsp = pMsg->pCont;
|
||||
int32_t taskId = pRsp->taskId;
|
||||
SStreamTask* pTask = taosHashGet(pTq->pStreamTasks, &taskId, sizeof(int32_t));
|
||||
streamTaskProcessRecoverRsp(pTask, pRsp);
|
||||
streamProcessRecoverRsp(pTask, pRsp);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,622 +0,0 @@
|
|||
/*
|
||||
* 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 "tq.h"
|
||||
// #include <fcntl.h>
|
||||
// #include <string.h>
|
||||
// #include <unistd.h>
|
||||
// #include "osDir.h"
|
||||
|
||||
#define TQ_META_NAME "tq.meta"
|
||||
#define TQ_IDX_NAME "tq.idx"
|
||||
|
||||
static int32_t tqHandlePutCommitted(STqMetaStore*, int64_t key, void* value);
|
||||
static void* tqHandleGetUncommitted(STqMetaStore*, int64_t key);
|
||||
|
||||
static inline void tqLinkUnpersist(STqMetaStore* pMeta, STqMetaList* pNode) {
|
||||
if (pNode->unpersistNext == NULL) {
|
||||
pNode->unpersistNext = pMeta->unpersistHead->unpersistNext;
|
||||
pNode->unpersistPrev = pMeta->unpersistHead;
|
||||
pMeta->unpersistHead->unpersistNext->unpersistPrev = pNode;
|
||||
pMeta->unpersistHead->unpersistNext = pNode;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int64_t tqSeekLastPage(TdFilePtr pFile) {
|
||||
int offset = taosLSeekFile(pFile, 0, SEEK_END);
|
||||
int pageNo = offset / TQ_PAGE_SIZE;
|
||||
int curPageOffset = pageNo * TQ_PAGE_SIZE;
|
||||
return taosLSeekFile(pFile, curPageOffset, SEEK_SET);
|
||||
}
|
||||
|
||||
// TODO: the struct is tightly coupled with index entry
|
||||
typedef struct STqIdxPageHead {
|
||||
int16_t writeOffset;
|
||||
int8_t unused[14];
|
||||
} STqIdxPageHead;
|
||||
|
||||
typedef struct STqIdxPageBuf {
|
||||
STqIdxPageHead head;
|
||||
char buffer[TQ_IDX_PAGE_BODY_SIZE];
|
||||
} STqIdxPageBuf;
|
||||
|
||||
static inline int tqReadLastPage(TdFilePtr pFile, STqIdxPageBuf* pBuf) {
|
||||
int offset = tqSeekLastPage(pFile);
|
||||
int nBytes;
|
||||
if ((nBytes = taosReadFile(pFile, pBuf, TQ_PAGE_SIZE)) == -1) {
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
return -1;
|
||||
}
|
||||
if (nBytes == 0) {
|
||||
memset(pBuf, 0, TQ_PAGE_SIZE);
|
||||
pBuf->head.writeOffset = TQ_IDX_PAGE_HEAD_SIZE;
|
||||
}
|
||||
ASSERT(nBytes == 0 || nBytes == pBuf->head.writeOffset);
|
||||
|
||||
return taosLSeekFile(pFile, offset, SEEK_SET);
|
||||
}
|
||||
|
||||
STqMetaStore* tqStoreOpen(STQ* pTq, const char* path, FTqSerialize serializer, FTqDeserialize deserializer,
|
||||
FTqDelete deleter, int32_t tqConfigFlag) {
|
||||
STqMetaStore* pMeta = taosMemoryCalloc(1, sizeof(STqMetaStore));
|
||||
if (pMeta == NULL) {
|
||||
terrno = TSDB_CODE_TQ_OUT_OF_MEMORY;
|
||||
return NULL;
|
||||
}
|
||||
pMeta->pTq = pTq;
|
||||
|
||||
// concat data file name and index file name
|
||||
size_t pathLen = strlen(path);
|
||||
pMeta->dirPath = taosMemoryMalloc(pathLen + 1);
|
||||
if (pMeta->dirPath == NULL) {
|
||||
terrno = TSDB_CODE_TQ_OUT_OF_MEMORY;
|
||||
taosMemoryFree(pMeta);
|
||||
return NULL;
|
||||
}
|
||||
strcpy(pMeta->dirPath, path);
|
||||
|
||||
char* name = taosMemoryMalloc(pathLen + 10);
|
||||
|
||||
strcpy(name, path);
|
||||
if (!taosDirExist(name) && taosMkDir(name) != 0) {
|
||||
terrno = TSDB_CODE_TQ_FAILED_TO_CREATE_DIR;
|
||||
tqError("failed to create dir:%s since %s ", name, terrstr());
|
||||
}
|
||||
strcat(name, "/" TQ_IDX_NAME);
|
||||
TdFilePtr pIdxFile = taosOpenFile(name, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_READ);
|
||||
if (pIdxFile == NULL) {
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
tqError("failed to open file:%s since %s ", name, terrstr());
|
||||
// free memory
|
||||
taosMemoryFree(name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pMeta->pIdxFile = pIdxFile;
|
||||
pMeta->unpersistHead = taosMemoryCalloc(1, sizeof(STqMetaList));
|
||||
if (pMeta->unpersistHead == NULL) {
|
||||
terrno = TSDB_CODE_TQ_OUT_OF_MEMORY;
|
||||
taosMemoryFree(name);
|
||||
return NULL;
|
||||
}
|
||||
pMeta->unpersistHead->unpersistNext = pMeta->unpersistHead->unpersistPrev = pMeta->unpersistHead;
|
||||
|
||||
strcpy(name, path);
|
||||
strcat(name, "/" TQ_META_NAME);
|
||||
TdFilePtr pFile = taosOpenFile(name, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_READ);
|
||||
if (pFile == NULL) {
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
tqError("failed to open file:%s since %s", name, terrstr());
|
||||
taosMemoryFree(name);
|
||||
return NULL;
|
||||
}
|
||||
taosMemoryFree(name);
|
||||
|
||||
pMeta->pFile = pFile;
|
||||
|
||||
pMeta->pSerializer = serializer;
|
||||
pMeta->pDeserializer = deserializer;
|
||||
pMeta->pDeleter = deleter;
|
||||
pMeta->tqConfigFlag = tqConfigFlag;
|
||||
|
||||
// read idx file and load into memory
|
||||
STqIdxPageBuf idxBuf;
|
||||
STqSerializedHead* serializedObj = taosMemoryMalloc(TQ_PAGE_SIZE);
|
||||
if (serializedObj == NULL) {
|
||||
terrno = TSDB_CODE_TQ_OUT_OF_MEMORY;
|
||||
}
|
||||
int idxRead;
|
||||
int allocated = TQ_PAGE_SIZE;
|
||||
bool readEnd = false;
|
||||
while ((idxRead = taosReadFile(pIdxFile, &idxBuf, TQ_PAGE_SIZE))) {
|
||||
if (idxRead == -1) {
|
||||
// TODO: handle error
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
tqError("failed to read tq index file since %s", terrstr());
|
||||
}
|
||||
ASSERT(idxBuf.head.writeOffset == idxRead);
|
||||
// loop read every entry
|
||||
for (int i = 0; i < idxBuf.head.writeOffset - TQ_IDX_PAGE_HEAD_SIZE; i += TQ_IDX_SIZE) {
|
||||
STqMetaList* pNode = taosMemoryCalloc(1, sizeof(STqMetaList));
|
||||
if (pNode == NULL) {
|
||||
terrno = TSDB_CODE_TQ_OUT_OF_MEMORY;
|
||||
// TODO: free memory
|
||||
}
|
||||
memcpy(&pNode->handle, &idxBuf.buffer[i], TQ_IDX_SIZE);
|
||||
|
||||
taosLSeekFile(pFile, pNode->handle.offset, SEEK_SET);
|
||||
if (allocated < pNode->handle.serializedSize) {
|
||||
void* ptr = taosMemoryRealloc(serializedObj, pNode->handle.serializedSize);
|
||||
if (ptr == NULL) {
|
||||
terrno = TSDB_CODE_TQ_OUT_OF_MEMORY;
|
||||
// TODO: free memory
|
||||
}
|
||||
serializedObj = ptr;
|
||||
allocated = pNode->handle.serializedSize;
|
||||
}
|
||||
serializedObj->ssize = pNode->handle.serializedSize;
|
||||
if (taosReadFile(pFile, serializedObj, pNode->handle.serializedSize) != pNode->handle.serializedSize) {
|
||||
// TODO: read error
|
||||
}
|
||||
if (serializedObj->action == TQ_ACTION_INUSE) {
|
||||
if (serializedObj->ssize != sizeof(STqSerializedHead)) {
|
||||
pMeta->pDeserializer(pTq, serializedObj, &pNode->handle.valueInUse);
|
||||
} else {
|
||||
pNode->handle.valueInUse = TQ_DELETE_TOKEN;
|
||||
}
|
||||
} else if (serializedObj->action == TQ_ACTION_INTXN) {
|
||||
if (serializedObj->ssize != sizeof(STqSerializedHead)) {
|
||||
pMeta->pDeserializer(pTq, serializedObj, &pNode->handle.valueInTxn);
|
||||
} else {
|
||||
pNode->handle.valueInTxn = TQ_DELETE_TOKEN;
|
||||
}
|
||||
} else if (serializedObj->action == TQ_ACTION_INUSE_CONT) {
|
||||
if (serializedObj->ssize != sizeof(STqSerializedHead)) {
|
||||
pMeta->pDeserializer(pTq, serializedObj, &pNode->handle.valueInUse);
|
||||
} else {
|
||||
pNode->handle.valueInUse = TQ_DELETE_TOKEN;
|
||||
}
|
||||
STqSerializedHead* ptr = POINTER_SHIFT(serializedObj, serializedObj->ssize);
|
||||
if (ptr->ssize != sizeof(STqSerializedHead)) {
|
||||
pMeta->pDeserializer(pTq, ptr, &pNode->handle.valueInTxn);
|
||||
} else {
|
||||
pNode->handle.valueInTxn = TQ_DELETE_TOKEN;
|
||||
}
|
||||
} else {
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
// put into list
|
||||
int bucketKey = pNode->handle.key & TQ_BUCKET_MASK;
|
||||
STqMetaList* pBucketNode = pMeta->bucket[bucketKey];
|
||||
if (pBucketNode == NULL) {
|
||||
pMeta->bucket[bucketKey] = pNode;
|
||||
} else if (pBucketNode->handle.key == pNode->handle.key) {
|
||||
pNode->next = pBucketNode->next;
|
||||
pMeta->bucket[bucketKey] = pNode;
|
||||
} else {
|
||||
while (pBucketNode->next && pBucketNode->next->handle.key != pNode->handle.key) {
|
||||
pBucketNode = pBucketNode->next;
|
||||
}
|
||||
if (pBucketNode->next) {
|
||||
ASSERT(pBucketNode->next->handle.key == pNode->handle.key);
|
||||
STqMetaList* pNodeFound = pBucketNode->next;
|
||||
pNode->next = pNodeFound->next;
|
||||
pBucketNode->next = pNode;
|
||||
pBucketNode = pNodeFound;
|
||||
} else {
|
||||
pNode->next = pMeta->bucket[bucketKey];
|
||||
pMeta->bucket[bucketKey] = pNode;
|
||||
pBucketNode = NULL;
|
||||
}
|
||||
}
|
||||
if (pBucketNode) {
|
||||
if (pBucketNode->handle.valueInUse && pBucketNode->handle.valueInUse != TQ_DELETE_TOKEN) {
|
||||
pMeta->pDeleter(pBucketNode->handle.valueInUse);
|
||||
}
|
||||
if (pBucketNode->handle.valueInTxn && pBucketNode->handle.valueInTxn != TQ_DELETE_TOKEN) {
|
||||
pMeta->pDeleter(pBucketNode->handle.valueInTxn);
|
||||
}
|
||||
taosMemoryFree(pBucketNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
taosMemoryFree(serializedObj);
|
||||
return pMeta;
|
||||
}
|
||||
|
||||
int32_t tqStoreClose(STqMetaStore* pMeta) {
|
||||
// commit data and idx
|
||||
tqStorePersist(pMeta);
|
||||
ASSERT(pMeta->unpersistHead && pMeta->unpersistHead->next == NULL);
|
||||
taosCloseFile(&pMeta->pFile);
|
||||
taosCloseFile(&pMeta->pIdxFile);
|
||||
// free memory
|
||||
for (int i = 0; i < TQ_BUCKET_SIZE; i++) {
|
||||
STqMetaList* pNode = pMeta->bucket[i];
|
||||
while (pNode) {
|
||||
ASSERT(pNode->unpersistNext == NULL);
|
||||
ASSERT(pNode->unpersistPrev == NULL);
|
||||
if (pNode->handle.valueInTxn && pNode->handle.valueInTxn != TQ_DELETE_TOKEN) {
|
||||
pMeta->pDeleter(pNode->handle.valueInTxn);
|
||||
}
|
||||
if (pNode->handle.valueInUse && pNode->handle.valueInUse != TQ_DELETE_TOKEN) {
|
||||
pMeta->pDeleter(pNode->handle.valueInUse);
|
||||
}
|
||||
STqMetaList* next = pNode->next;
|
||||
taosMemoryFree(pNode);
|
||||
pNode = next;
|
||||
}
|
||||
}
|
||||
taosMemoryFree(pMeta->dirPath);
|
||||
taosMemoryFree(pMeta->unpersistHead);
|
||||
taosMemoryFree(pMeta);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tqStoreDelete(STqMetaStore* pMeta) {
|
||||
taosCloseFile(&pMeta->pFile);
|
||||
taosCloseFile(&pMeta->pIdxFile);
|
||||
// free memory
|
||||
for (int i = 0; i < TQ_BUCKET_SIZE; i++) {
|
||||
STqMetaList* pNode = pMeta->bucket[i];
|
||||
pMeta->bucket[i] = NULL;
|
||||
while (pNode) {
|
||||
if (pNode->handle.valueInTxn && pNode->handle.valueInTxn != TQ_DELETE_TOKEN) {
|
||||
pMeta->pDeleter(pNode->handle.valueInTxn);
|
||||
}
|
||||
if (pNode->handle.valueInUse && pNode->handle.valueInUse != TQ_DELETE_TOKEN) {
|
||||
pMeta->pDeleter(pNode->handle.valueInUse);
|
||||
}
|
||||
STqMetaList* next = pNode->next;
|
||||
taosMemoryFree(pNode);
|
||||
pNode = next;
|
||||
}
|
||||
}
|
||||
taosMemoryFree(pMeta->unpersistHead);
|
||||
taosRemoveDir(pMeta->dirPath);
|
||||
taosMemoryFree(pMeta->dirPath);
|
||||
taosMemoryFree(pMeta);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tqStorePersist(STqMetaStore* pMeta) {
|
||||
STqIdxPageBuf idxBuf;
|
||||
int64_t* bufPtr = (int64_t*)idxBuf.buffer;
|
||||
STqMetaList* pHead = pMeta->unpersistHead;
|
||||
STqMetaList* pNode = pHead->unpersistNext;
|
||||
STqSerializedHead* pSHead = taosMemoryMalloc(sizeof(STqSerializedHead));
|
||||
if (pSHead == NULL) {
|
||||
terrno = TSDB_CODE_TQ_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
pSHead->ver = TQ_SVER;
|
||||
pSHead->checksum = 0;
|
||||
pSHead->ssize = sizeof(STqSerializedHead);
|
||||
/*int allocatedSize = sizeof(STqSerializedHead);*/
|
||||
int offset = taosLSeekFile(pMeta->pFile, 0, SEEK_CUR);
|
||||
|
||||
tqReadLastPage(pMeta->pIdxFile, &idxBuf);
|
||||
|
||||
if (idxBuf.head.writeOffset == TQ_PAGE_SIZE) {
|
||||
taosLSeekFile(pMeta->pIdxFile, 0, SEEK_END);
|
||||
memset(&idxBuf, 0, TQ_PAGE_SIZE);
|
||||
idxBuf.head.writeOffset = TQ_IDX_PAGE_HEAD_SIZE;
|
||||
} else {
|
||||
bufPtr = POINTER_SHIFT(&idxBuf, idxBuf.head.writeOffset);
|
||||
}
|
||||
|
||||
while (pHead != pNode) {
|
||||
int nBytes = 0;
|
||||
|
||||
if (pNode->handle.valueInUse) {
|
||||
if (pNode->handle.valueInTxn) {
|
||||
pSHead->action = TQ_ACTION_INUSE_CONT;
|
||||
} else {
|
||||
pSHead->action = TQ_ACTION_INUSE;
|
||||
}
|
||||
|
||||
if (pNode->handle.valueInUse == TQ_DELETE_TOKEN) {
|
||||
pSHead->ssize = sizeof(STqSerializedHead);
|
||||
} else {
|
||||
pMeta->pSerializer(pNode->handle.valueInUse, &pSHead);
|
||||
}
|
||||
nBytes = taosWriteFile(pMeta->pFile, pSHead, pSHead->ssize);
|
||||
ASSERT(nBytes == pSHead->ssize);
|
||||
}
|
||||
|
||||
if (pNode->handle.valueInTxn) {
|
||||
pSHead->action = TQ_ACTION_INTXN;
|
||||
if (pNode->handle.valueInTxn == TQ_DELETE_TOKEN) {
|
||||
pSHead->ssize = sizeof(STqSerializedHead);
|
||||
} else {
|
||||
pMeta->pSerializer(pNode->handle.valueInTxn, &pSHead);
|
||||
}
|
||||
int nBytesTxn = taosWriteFile(pMeta->pFile, pSHead, pSHead->ssize);
|
||||
ASSERT(nBytesTxn == pSHead->ssize);
|
||||
nBytes += nBytesTxn;
|
||||
}
|
||||
pNode->handle.offset = offset;
|
||||
offset += nBytes;
|
||||
|
||||
// write idx file
|
||||
// TODO: endian check and convert
|
||||
*(bufPtr++) = pNode->handle.key;
|
||||
*(bufPtr++) = pNode->handle.offset;
|
||||
*(bufPtr++) = (int64_t)nBytes;
|
||||
idxBuf.head.writeOffset += TQ_IDX_SIZE;
|
||||
|
||||
if (idxBuf.head.writeOffset >= TQ_PAGE_SIZE) {
|
||||
nBytes = taosWriteFile(pMeta->pIdxFile, &idxBuf, TQ_PAGE_SIZE);
|
||||
// TODO: handle error with tfile
|
||||
ASSERT(nBytes == TQ_PAGE_SIZE);
|
||||
memset(&idxBuf, 0, TQ_PAGE_SIZE);
|
||||
idxBuf.head.writeOffset = TQ_IDX_PAGE_HEAD_SIZE;
|
||||
bufPtr = (int64_t*)&idxBuf.buffer;
|
||||
}
|
||||
// remove from unpersist list
|
||||
pHead->unpersistNext = pNode->unpersistNext;
|
||||
pHead->unpersistNext->unpersistPrev = pHead;
|
||||
pNode->unpersistPrev = pNode->unpersistNext = NULL;
|
||||
pNode = pHead->unpersistNext;
|
||||
|
||||
// remove from bucket
|
||||
if (pNode->handle.valueInUse == TQ_DELETE_TOKEN && pNode->handle.valueInTxn == NULL) {
|
||||
int bucketKey = pNode->handle.key & TQ_BUCKET_MASK;
|
||||
STqMetaList* pBucketHead = pMeta->bucket[bucketKey];
|
||||
if (pBucketHead == pNode) {
|
||||
pMeta->bucket[bucketKey] = pNode->next;
|
||||
} else {
|
||||
STqMetaList* pBucketNode = pBucketHead;
|
||||
while (pBucketNode->next != NULL && pBucketNode->next != pNode) {
|
||||
pBucketNode = pBucketNode->next;
|
||||
}
|
||||
// impossible for pBucket->next == NULL
|
||||
ASSERT(pBucketNode->next == pNode);
|
||||
pBucketNode->next = pNode->next;
|
||||
}
|
||||
taosMemoryFree(pNode);
|
||||
}
|
||||
}
|
||||
|
||||
// write left bytes
|
||||
taosMemoryFree(pSHead);
|
||||
// TODO: write new version in tfile
|
||||
if ((char*)bufPtr != idxBuf.buffer) {
|
||||
int nBytes = taosWriteFile(pMeta->pIdxFile, &idxBuf, idxBuf.head.writeOffset);
|
||||
// TODO: handle error in tfile
|
||||
ASSERT(nBytes == idxBuf.head.writeOffset);
|
||||
}
|
||||
// TODO: using fsync in tfile
|
||||
taosFsyncFile(pMeta->pIdxFile);
|
||||
taosFsyncFile(pMeta->pFile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t tqHandlePutCommitted(STqMetaStore* pMeta, int64_t key, void* value) {
|
||||
int64_t bucketKey = key & TQ_BUCKET_MASK;
|
||||
STqMetaList* pNode = pMeta->bucket[bucketKey];
|
||||
while (pNode) {
|
||||
if (pNode->handle.key == key) {
|
||||
if (pNode->handle.valueInUse && pNode->handle.valueInUse != TQ_DELETE_TOKEN) {
|
||||
pMeta->pDeleter(pNode->handle.valueInUse);
|
||||
}
|
||||
// change pointer ownership
|
||||
pNode->handle.valueInUse = value;
|
||||
return 0;
|
||||
} else {
|
||||
pNode = pNode->next;
|
||||
}
|
||||
}
|
||||
STqMetaList* pNewNode = taosMemoryCalloc(1, sizeof(STqMetaList));
|
||||
if (pNewNode == NULL) {
|
||||
terrno = TSDB_CODE_TQ_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
pNewNode->handle.key = key;
|
||||
pNewNode->handle.valueInUse = value;
|
||||
pNewNode->next = pMeta->bucket[bucketKey];
|
||||
// put into unpersist list
|
||||
pNewNode->unpersistPrev = pMeta->unpersistHead;
|
||||
pNewNode->unpersistNext = pMeta->unpersistHead->unpersistNext;
|
||||
pMeta->unpersistHead->unpersistNext->unpersistPrev = pNewNode;
|
||||
pMeta->unpersistHead->unpersistNext = pNewNode;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* tqHandleGet(STqMetaStore* pMeta, int64_t key) {
|
||||
int64_t bucketKey = key & TQ_BUCKET_MASK;
|
||||
STqMetaList* pNode = pMeta->bucket[bucketKey];
|
||||
while (pNode) {
|
||||
if (pNode->handle.key == key) {
|
||||
if (pNode->handle.valueInUse != NULL && pNode->handle.valueInUse != TQ_DELETE_TOKEN) {
|
||||
return pNode->handle.valueInUse;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
pNode = pNode->next;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void* tqHandleTouchGet(STqMetaStore* pMeta, int64_t key) {
|
||||
int64_t bucketKey = key & TQ_BUCKET_MASK;
|
||||
STqMetaList* pNode = pMeta->bucket[bucketKey];
|
||||
while (pNode) {
|
||||
if (pNode->handle.key == key) {
|
||||
if (pNode->handle.valueInUse != NULL && pNode->handle.valueInUse != TQ_DELETE_TOKEN) {
|
||||
tqLinkUnpersist(pMeta, pNode);
|
||||
return pNode->handle.valueInUse;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
pNode = pNode->next;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline int32_t tqHandlePutImpl(STqMetaStore* pMeta, int64_t key, void* value) {
|
||||
int64_t bucketKey = key & TQ_BUCKET_MASK;
|
||||
STqMetaList* pNode = pMeta->bucket[bucketKey];
|
||||
while (pNode) {
|
||||
if (pNode->handle.key == key) {
|
||||
if (pNode->handle.valueInTxn) {
|
||||
if (tqDupIntxnReject(pMeta->tqConfigFlag)) {
|
||||
terrno = TSDB_CODE_TQ_META_KEY_DUP_IN_TXN;
|
||||
return -1;
|
||||
}
|
||||
if (pNode->handle.valueInTxn != TQ_DELETE_TOKEN) {
|
||||
pMeta->pDeleter(pNode->handle.valueInTxn);
|
||||
}
|
||||
}
|
||||
pNode->handle.valueInTxn = value;
|
||||
tqLinkUnpersist(pMeta, pNode);
|
||||
return 0;
|
||||
} else {
|
||||
pNode = pNode->next;
|
||||
}
|
||||
}
|
||||
STqMetaList* pNewNode = taosMemoryCalloc(1, sizeof(STqMetaList));
|
||||
if (pNewNode == NULL) {
|
||||
terrno = TSDB_CODE_TQ_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
pNewNode->handle.key = key;
|
||||
pNewNode->handle.valueInTxn = value;
|
||||
pNewNode->next = pMeta->bucket[bucketKey];
|
||||
pMeta->bucket[bucketKey] = pNewNode;
|
||||
tqLinkUnpersist(pMeta, pNewNode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tqHandleMovePut(STqMetaStore* pMeta, int64_t key, void* value) { return tqHandlePutImpl(pMeta, key, value); }
|
||||
|
||||
int32_t tqHandleCopyPut(STqMetaStore* pMeta, int64_t key, void* value, size_t vsize) {
|
||||
void* vmem = taosMemoryMalloc(vsize);
|
||||
if (vmem == NULL) {
|
||||
terrno = TSDB_CODE_TQ_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
memcpy(vmem, value, vsize);
|
||||
return tqHandlePutImpl(pMeta, key, vmem);
|
||||
}
|
||||
|
||||
static void* tqHandleGetUncommitted(STqMetaStore* pMeta, int64_t key) {
|
||||
int64_t bucketKey = key & TQ_BUCKET_MASK;
|
||||
STqMetaList* pNode = pMeta->bucket[bucketKey];
|
||||
while (pNode) {
|
||||
if (pNode->handle.key == key) {
|
||||
if (pNode->handle.valueInTxn != NULL && pNode->handle.valueInTxn != TQ_DELETE_TOKEN) {
|
||||
return pNode->handle.valueInTxn;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
pNode = pNode->next;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int32_t tqHandleCommit(STqMetaStore* pMeta, int64_t key) {
|
||||
int64_t bucketKey = key & TQ_BUCKET_MASK;
|
||||
STqMetaList* pNode = pMeta->bucket[bucketKey];
|
||||
while (pNode) {
|
||||
if (pNode->handle.key == key) {
|
||||
if (pNode->handle.valueInTxn == NULL) {
|
||||
terrno = TSDB_CODE_TQ_META_KEY_NOT_IN_TXN;
|
||||
return -1;
|
||||
}
|
||||
if (pNode->handle.valueInUse && pNode->handle.valueInUse != TQ_DELETE_TOKEN) {
|
||||
pMeta->pDeleter(pNode->handle.valueInUse);
|
||||
}
|
||||
pNode->handle.valueInUse = pNode->handle.valueInTxn;
|
||||
pNode->handle.valueInTxn = NULL;
|
||||
tqLinkUnpersist(pMeta, pNode);
|
||||
return 0;
|
||||
} else {
|
||||
pNode = pNode->next;
|
||||
}
|
||||
}
|
||||
terrno = TSDB_CODE_TQ_META_NO_SUCH_KEY;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t tqHandleAbort(STqMetaStore* pMeta, int64_t key) {
|
||||
int64_t bucketKey = key & TQ_BUCKET_MASK;
|
||||
STqMetaList* pNode = pMeta->bucket[bucketKey];
|
||||
while (pNode) {
|
||||
if (pNode->handle.key == key) {
|
||||
if (pNode->handle.valueInTxn) {
|
||||
if (pNode->handle.valueInTxn != TQ_DELETE_TOKEN) {
|
||||
pMeta->pDeleter(pNode->handle.valueInTxn);
|
||||
}
|
||||
pNode->handle.valueInTxn = NULL;
|
||||
tqLinkUnpersist(pMeta, pNode);
|
||||
return 0;
|
||||
}
|
||||
terrno = TSDB_CODE_TQ_META_KEY_NOT_IN_TXN;
|
||||
return -1;
|
||||
} else {
|
||||
pNode = pNode->next;
|
||||
}
|
||||
}
|
||||
terrno = TSDB_CODE_TQ_META_NO_SUCH_KEY;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t tqHandleDel(STqMetaStore* pMeta, int64_t key) {
|
||||
int64_t bucketKey = key & TQ_BUCKET_MASK;
|
||||
STqMetaList* pNode = pMeta->bucket[bucketKey];
|
||||
while (pNode) {
|
||||
if (pNode->handle.key == key) {
|
||||
if (pNode->handle.valueInTxn != TQ_DELETE_TOKEN) {
|
||||
if (pNode->handle.valueInTxn) {
|
||||
pMeta->pDeleter(pNode->handle.valueInTxn);
|
||||
}
|
||||
|
||||
pNode->handle.valueInTxn = TQ_DELETE_TOKEN;
|
||||
tqLinkUnpersist(pMeta, pNode);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
pNode = pNode->next;
|
||||
}
|
||||
}
|
||||
terrno = TSDB_CODE_TQ_META_NO_SUCH_KEY;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t tqHandlePurge(STqMetaStore* pMeta, int64_t key) {
|
||||
int64_t bucketKey = key & TQ_BUCKET_MASK;
|
||||
STqMetaList* pNode = pMeta->bucket[bucketKey];
|
||||
while (pNode) {
|
||||
if (pNode->handle.key == key) {
|
||||
pNode->handle.valueInUse = TQ_DELETE_TOKEN;
|
||||
tqLinkUnpersist(pMeta, pNode);
|
||||
return 0;
|
||||
} else {
|
||||
pNode = pNode->next;
|
||||
}
|
||||
}
|
||||
terrno = TSDB_CODE_TQ_META_NO_SUCH_KEY;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// TODO: clean deleted idx and data from persistent file
|
||||
int32_t tqStoreCompact(STqMetaStore* pMeta) { return 0; }
|
|
@ -38,7 +38,7 @@ struct SMemTable {
|
|||
|
||||
struct SMemSkipListNode {
|
||||
int8_t level;
|
||||
SMemSkipListNode *forwards[1]; // Windows does not allow 0
|
||||
SMemSkipListNode *forwards[1]; // Windows does not allow 0
|
||||
};
|
||||
|
||||
struct SMemSkipList {
|
||||
|
@ -46,7 +46,7 @@ struct SMemSkipList {
|
|||
int8_t maxLevel;
|
||||
int8_t level;
|
||||
int32_t size;
|
||||
SMemSkipListNode pHead[1]; // Windows does not allow 0
|
||||
SMemSkipListNode pHead[1]; // Windows does not allow 0
|
||||
};
|
||||
|
||||
struct SMemData {
|
||||
|
@ -217,7 +217,7 @@ int32_t tsdbInsertData2(SMemTable *pMemTb, int64_t version, const SVSubmitBlk *p
|
|||
if (tDecodeIsEnd(&dc)) break;
|
||||
|
||||
// decode row
|
||||
if (tDecodeBinary(&dc, (const uint8_t **)&tRow.pRow, &tRow.szRow) < 0) {
|
||||
if (tDecodeBinary(&dc, (uint8_t **)&tRow.pRow, &tRow.szRow) < 0) {
|
||||
terrno = TSDB_CODE_INVALID_MSG;
|
||||
return -1;
|
||||
}
|
||||
|
@ -273,7 +273,7 @@ static FORCE_INLINE int32_t tsdbEncodeRow(SEncoder *pEncoder, const STsdbRow *pR
|
|||
|
||||
static FORCE_INLINE int32_t tsdbDecodeRow(SDecoder *pDecoder, STsdbRow *pRow) {
|
||||
if (tDecodeI64(pDecoder, &pRow->version) < 0) return -1;
|
||||
if (tDecodeBinary(pDecoder, (const uint8_t **)&pRow->pRow, &pRow->szRow) < 0) return -1;
|
||||
if (tDecodeBinary(pDecoder, (uint8_t **)&pRow->pRow, &pRow->szRow) < 0) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1638,9 +1638,7 @@ static int32_t mergeTwoRowFromMem(STsdbReadHandle* pTsdbReadHandle, int32_t capa
|
|||
int32_t numOfColsOfRow1 = 0;
|
||||
|
||||
if (pSchema1 == NULL) {
|
||||
// pSchema1 = metaGetTbTSchema(REPO_META(pTsdbReadHandle->pTsdb), uid, TD_ROW_SVER(row1));
|
||||
// TODO: use the real schemaVersion
|
||||
pSchema1 = metaGetTbTSchema(REPO_META(pTsdbReadHandle->pTsdb), uid, 1);
|
||||
pSchema1 = metaGetTbTSchema(REPO_META(pTsdbReadHandle->pTsdb), uid, TD_ROW_SVER(row1));
|
||||
}
|
||||
|
||||
#ifdef TD_DEBUG_PRINT_ROW
|
||||
|
@ -1657,9 +1655,7 @@ static int32_t mergeTwoRowFromMem(STsdbReadHandle* pTsdbReadHandle, int32_t capa
|
|||
if (row2) {
|
||||
isRow2DataRow = TD_IS_TP_ROW(row2);
|
||||
if (pSchema2 == NULL) {
|
||||
// pSchema2 = metaGetTbTSchema(REPO_META(pTsdbReadHandle->pTsdb), uid, TD_ROW_SVER(row2));
|
||||
// TODO: use the real schemaVersion
|
||||
pSchema2 = metaGetTbTSchema(REPO_META(pTsdbReadHandle->pTsdb), uid, 1);
|
||||
pSchema2 = metaGetTbTSchema(REPO_META(pTsdbReadHandle->pTsdb), uid, TD_ROW_SVER(row2));
|
||||
}
|
||||
if (isRow2DataRow) {
|
||||
numOfColsOfRow2 = schemaNCols(pSchema2);
|
||||
|
|
|
@ -252,6 +252,45 @@ static FORCE_INLINE void tsdbSwapDataCols(SDataCols *pDest, SDataCols *pSrc) {
|
|||
pSrc->cols = pCols;
|
||||
}
|
||||
|
||||
static void printTsdbLoadBlkData(SReadH *readh, SDataCols *pDCols, SBlock *pBlock, const char *tag, int32_t ln) {
|
||||
printf("%s:%d:%" PRIi64 " ================\n", tag, ln, taosGetSelfPthreadId());
|
||||
if (pBlock) {
|
||||
SDFile *pHeadf = TSDB_READ_HEAD_FILE(readh);
|
||||
printf("%s:%d:%" PRIi64 ":%p:%d %s\n", tag, ln, taosGetSelfPthreadId(), pBlock, (int32_t)pBlock->len,
|
||||
pHeadf->f.aname);
|
||||
SDFile *pDFile = pBlock->last ? TSDB_READ_LAST_FILE(readh) : TSDB_READ_DATA_FILE(readh);
|
||||
printf("%s:%d:%" PRIi64 ":%p:%d %s\n", tag, ln, taosGetSelfPthreadId(), pBlock, (int32_t)pBlock->len,
|
||||
pDFile->f.aname);
|
||||
}
|
||||
SDataCol *pDCol = pDCols->cols + 0;
|
||||
if (TSKEY_MIN == *(int64_t *)pDCol->pData) {
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
int rows = pDCols->numOfRows;
|
||||
for (int r = 0; r < rows; ++r) {
|
||||
if (pBlock) {
|
||||
printf("%s:%d:%" PRIi64 ":%p:%d rows[%d][%d] ", tag, ln, taosGetSelfPthreadId(), pBlock, (int32_t)pBlock->len,
|
||||
rows, r);
|
||||
} else {
|
||||
printf("%s:%d:%" PRIi64 ":%s rows[%d][%d] ", tag, ln, taosGetSelfPthreadId(), "=== merge === ", rows, r);
|
||||
}
|
||||
|
||||
int nDataCols = pDCols->numOfCols;
|
||||
int j = 0;
|
||||
SCellVal sVal = {0};
|
||||
while (j < nDataCols) {
|
||||
SDataCol *pDataCol = pDCols->cols + j;
|
||||
tdGetColDataOfRow(&sVal, pDataCol, r, pDCols->bitmapMode);
|
||||
tdSCellValPrint(&sVal, pDataCol->type);
|
||||
++j;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
int tsdbLoadBlockData(SReadH *pReadh, SBlock *pBlock, SBlockInfo *pBlkInfo) {
|
||||
ASSERT(pBlock->numOfSubBlocks > 0);
|
||||
STsdbCfg *pCfg = REPO_CFG(pReadh->pRepo);
|
||||
|
@ -266,15 +305,23 @@ int tsdbLoadBlockData(SReadH *pReadh, SBlock *pBlock, SBlockInfo *pBlkInfo) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
if (tsdbLoadBlockDataImpl(pReadh, iBlock, pReadh->pDCols[0], TSDB_BITMODE_ONE_BIT) < 0) return -1;
|
||||
#ifdef TD_DEBUG_PRINT_TSDB_LOAD_DCOLS
|
||||
printTsdbLoadBlkData(pReadh, pReadh->pDCols[0], iBlock, __func__, __LINE__);
|
||||
#endif
|
||||
for (int i = 1; i < pBlock->numOfSubBlocks; i++) {
|
||||
iBlock++;
|
||||
if (tsdbLoadBlockDataImpl(pReadh, iBlock, pReadh->pDCols[1], TSDB_BITMODE_DEFAULT) < 0) return -1;
|
||||
#ifdef TD_DEBUG_PRINT_TSDB_LOAD_DCOLS
|
||||
printTsdbLoadBlkData(pReadh, pReadh->pDCols[1], iBlock, __func__, __LINE__);
|
||||
#endif
|
||||
// TODO: use the real maxVersion to replace the UINT64_MAX to support Multi-Version
|
||||
if (tdMergeDataCols(pReadh->pDCols[0], pReadh->pDCols[1], pReadh->pDCols[1]->numOfRows, NULL,
|
||||
TD_SUPPORT_UPDATE(update), TD_VER_MAX) < 0)
|
||||
return -1;
|
||||
#ifdef TD_DEBUG_PRINT_TSDB_LOAD_DCOLS
|
||||
printTsdbLoadBlkData(pReadh, pReadh->pDCols[0], iBlock, " === MERGE === ", __LINE__);
|
||||
#endif
|
||||
}
|
||||
// if ((pBlock->numOfSubBlocks == 1) && (iBlock->hasDupKey)) { // TODO: use this line
|
||||
if (pBlock->numOfSubBlocks == 1) {
|
||||
|
@ -286,6 +333,9 @@ int tsdbLoadBlockData(SReadH *pReadh, SBlock *pBlock, SBlockInfo *pBlkInfo) {
|
|||
}
|
||||
tsdbSwapDataCols(pReadh->pDCols[0], pReadh->pDCols[1]);
|
||||
ASSERT(pReadh->pDCols[0]->bitmapMode != 0);
|
||||
#ifdef TD_DEBUG_PRINT_TSDB_LOAD_DCOLS
|
||||
printTsdbLoadBlkData(pReadh, pReadh->pDCols[0], iBlock, " === UPDATE FILTER === ", __LINE__);
|
||||
#endif
|
||||
}
|
||||
|
||||
ASSERT(pReadh->pDCols[0]->numOfRows <= pBlock->numOfRows);
|
||||
|
@ -295,6 +345,53 @@ int tsdbLoadBlockData(SReadH *pReadh, SBlock *pBlock, SBlockInfo *pBlkInfo) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void printTsdbLoadBlkDataCols(SReadH *readh, SDataCols *pDCols, SBlock *pBlock, const int16_t *colIds,
|
||||
int numOfColsIds, const char *tag, int32_t ln) {
|
||||
printf("%s:%d:%" PRIi64 " ================\n", tag, ln, taosGetSelfPthreadId());
|
||||
if (pBlock) {
|
||||
SDFile *pHeadf = TSDB_READ_HEAD_FILE(readh);
|
||||
printf("%s:%d:%" PRIi64 ":%p:%d %s\n", tag, ln, taosGetSelfPthreadId(), pBlock, (int32_t)pBlock->len,
|
||||
pHeadf->f.aname);
|
||||
SDFile *pDFile = pBlock->last ? TSDB_READ_LAST_FILE(readh) : TSDB_READ_DATA_FILE(readh);
|
||||
printf("%s:%d:%" PRIi64 ":%p:%d %s\n", tag, ln, taosGetSelfPthreadId(), pBlock, (int32_t)pBlock->len,
|
||||
pDFile->f.aname);
|
||||
}
|
||||
|
||||
int rows = pDCols->numOfRows;
|
||||
for (int r = 0; r < rows; ++r) {
|
||||
if (pBlock) {
|
||||
printf("%s:%d:%" PRIi64 ":%p:%d rows[%d][%d] ", tag, ln, taosGetSelfPthreadId(), pBlock, (int32_t)pBlock->len,
|
||||
rows, r);
|
||||
} else {
|
||||
printf("%s:%d:%" PRIi64 ":%s rows[%d][%d] ", tag, ln, taosGetSelfPthreadId(), "=== merge === ", rows, r);
|
||||
}
|
||||
|
||||
int nDataCols = pDCols->numOfCols;
|
||||
int j = 0, k = 0;
|
||||
SCellVal sVal = {0};
|
||||
while (j < nDataCols) {
|
||||
if (k >= numOfColsIds) break;
|
||||
SDataCol *pDataCol = pDCols->cols + j;
|
||||
int16_t colId1 = pDataCol->colId;
|
||||
int16_t colId2 = *(colIds + k);
|
||||
if (colId1 < colId2) {
|
||||
++j;
|
||||
} else if (colId1 > colId2) {
|
||||
++k; // colId2 not exists in SDataCols
|
||||
printf("NotExists ");
|
||||
} else {
|
||||
tdGetColDataOfRow(&sVal, pDataCol, r, pDCols->bitmapMode);
|
||||
tdSCellValPrint(&sVal, pDataCol->type);
|
||||
++j;
|
||||
++k;
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
// TODO: filter by Multi-Version
|
||||
int tsdbLoadBlockDataCols(SReadH *pReadh, SBlock *pBlock, SBlockInfo *pBlkInfo, const int16_t *colIds, int numOfColsIds,
|
||||
bool mergeBitmap) {
|
||||
|
@ -310,14 +407,25 @@ int tsdbLoadBlockDataCols(SReadH *pReadh, SBlock *pBlock, SBlockInfo *pBlkInfo,
|
|||
}
|
||||
}
|
||||
|
||||
if (tsdbLoadBlockDataColsImpl(pReadh, iBlock, pReadh->pDCols[0], colIds, numOfColsIds, TSDB_BITMODE_ONE_BIT) < 0) return -1;
|
||||
if (tsdbLoadBlockDataColsImpl(pReadh, iBlock, pReadh->pDCols[0], colIds, numOfColsIds, TSDB_BITMODE_ONE_BIT) < 0)
|
||||
return -1;
|
||||
#ifdef TD_DEBUG_PRINT_TSDB_LOAD_DCOLS
|
||||
printTsdbLoadBlkDataCols(pReadh, pReadh->pDCols[0], iBlock, colIds, numOfColsIds, __func__, __LINE__);
|
||||
#endif
|
||||
for (int i = 1; i < pBlock->numOfSubBlocks; i++) {
|
||||
iBlock++;
|
||||
if (tsdbLoadBlockDataColsImpl(pReadh, iBlock, pReadh->pDCols[1], colIds, numOfColsIds, TSDB_BITMODE_DEFAULT) < 0) return -1;
|
||||
if (tsdbLoadBlockDataColsImpl(pReadh, iBlock, pReadh->pDCols[1], colIds, numOfColsIds, TSDB_BITMODE_DEFAULT) < 0)
|
||||
return -1;
|
||||
#ifdef TD_DEBUG_PRINT_TSDB_LOAD_DCOLS
|
||||
printTsdbLoadBlkDataCols(pReadh, pReadh->pDCols[1], iBlock, colIds, numOfColsIds, __func__, __LINE__);
|
||||
#endif
|
||||
// TODO: use the real maxVersion to replace the UINT64_MAX to support Multi-Version
|
||||
if (tdMergeDataCols(pReadh->pDCols[0], pReadh->pDCols[1], pReadh->pDCols[1]->numOfRows, NULL,
|
||||
TD_SUPPORT_UPDATE(update), TD_VER_MAX) < 0)
|
||||
return -1;
|
||||
#ifdef TD_DEBUG_PRINT_TSDB_LOAD_DCOLS
|
||||
printTsdbLoadBlkDataCols(pReadh, pReadh->pDCols[0], NULL, colIds, numOfColsIds, __func__, __LINE__);
|
||||
#endif
|
||||
}
|
||||
// if ((pBlock->numOfSubBlocks == 1) && (iBlock->hasDupKey)) { // TODO: use this line
|
||||
if (pBlock->numOfSubBlocks == 1) {
|
||||
|
@ -329,18 +437,23 @@ int tsdbLoadBlockDataCols(SReadH *pReadh, SBlock *pBlock, SBlockInfo *pBlkInfo,
|
|||
}
|
||||
tsdbSwapDataCols(pReadh->pDCols[0], pReadh->pDCols[1]);
|
||||
ASSERT(pReadh->pDCols[0]->bitmapMode != 0);
|
||||
#ifdef TD_DEBUG_PRINT_TSDB_LOAD_DCOLS
|
||||
printTsdbLoadBlkDataCols(pReadh, pReadh->pDCols[0], NULL, colIds, numOfColsIds,
|
||||
" === update filter === ", __LINE__);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (mergeBitmap && !tdDataColsIsBitmapI(pReadh->pDCols[0])) {
|
||||
for (int i = 0; i < numOfColsIds; ++i) {
|
||||
SDataCol *pDataCol = pReadh->pDCols[0]->cols + i;
|
||||
if (pDataCol->len > 0 && pDataCol->bitmap) {
|
||||
ASSERT(pDataCol->colId != PRIMARYKEY_TIMESTAMP_COL_ID);
|
||||
ASSERT(pDataCol->pBitmap);
|
||||
tdMergeBitmap(pDataCol->pBitmap, pReadh->pDCols[0]->numOfRows, pDataCol->pBitmap);
|
||||
tdDataColsSetBitmapI(pReadh->pDCols[0]);
|
||||
}
|
||||
}
|
||||
#ifdef TD_DEBUG_PRINT_TSDB_LOAD_DCOLS
|
||||
printTsdbLoadBlkDataCols(pReadh, pReadh->pDCols[0], NULL, colIds, numOfColsIds, " === merge bitmap === ", __LINE__);
|
||||
#endif
|
||||
}
|
||||
|
||||
ASSERT(pReadh->pDCols[0]->numOfRows <= pBlock->numOfRows);
|
||||
|
@ -551,9 +664,7 @@ static int tsdbLoadBlockDataImpl(SReadH *pReadh, SBlock *pBlock, SDataCols *pDat
|
|||
|
||||
tdResetDataCols(pDataCols);
|
||||
|
||||
if (tdIsBitmapModeI(bitmapMode)) {
|
||||
tdDataColsSetBitmapI(pDataCols);
|
||||
}
|
||||
pDataCols->bitmapMode = bitmapMode;
|
||||
|
||||
if (tsdbMakeRoom((void **)(&TSDB_READ_BUF(pReadh)), pBlock->len) < 0) return -1;
|
||||
|
||||
|
@ -740,9 +851,7 @@ static int tsdbLoadBlockDataColsImpl(SReadH *pReadh, SBlock *pBlock, SDataCols *
|
|||
|
||||
tdResetDataCols(pDataCols);
|
||||
|
||||
if (tdIsBitmapModeI(bitmapMode)) {
|
||||
tdDataColsSetBitmapI(pDataCols);
|
||||
}
|
||||
pDataCols->bitmapMode = bitmapMode;
|
||||
|
||||
// If only load timestamp column, no need to load SBlockData part
|
||||
if (numOfColIds > 1 && tsdbLoadBlockOffset(pReadh, pBlock) < 0) return -1;
|
||||
|
|
|
@ -85,7 +85,7 @@ static FORCE_INLINE int tsdbCheckRowRange(STsdb *pTsdb, tb_uid_t uid, STSRow *ro
|
|||
return 0;
|
||||
}
|
||||
|
||||
int tsdbScanAndConvertSubmitMsg(STsdb *pTsdb, const SSubmitReq *pMsg) {
|
||||
int tsdbScanAndConvertSubmitMsg(STsdb *pTsdb, SSubmitReq *pMsg) {
|
||||
ASSERT(pMsg != NULL);
|
||||
// STsdbMeta * pMeta = pTsdb->tsdbMeta;
|
||||
SSubmitMsgIter msgIter = {0};
|
||||
|
@ -150,7 +150,6 @@ int tsdbScanAndConvertSubmitMsg(STsdb *pTsdb, const SSubmitReq *pMsg) {
|
|||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (terrno != TSDB_CODE_SUCCESS) return -1;
|
||||
|
|
|
@ -24,26 +24,66 @@ static int vnodeProcessDropTbReq(SVnode *pVnode, int64_t version, void *pReq, in
|
|||
static int vnodeProcessSubmitReq(SVnode *pVnode, int64_t version, void *pReq, int32_t len, SRpcMsg *pRsp);
|
||||
static int vnodeProcessCreateTSmaReq(SVnode *pVnode, int64_t version, void *pReq, int len, SRpcMsg *pRsp);
|
||||
|
||||
int vnodePreprocessWriteReqs(SVnode *pVnode, SArray *pMsgs, int64_t *version) {
|
||||
#if 0
|
||||
SRpcMsg *pMsg;
|
||||
SRpcMsg *pRpc;
|
||||
int32_t vnodePreprocessReq(SVnode *pVnode, SRpcMsg *pMsg) {
|
||||
SDecoder dc = {0};
|
||||
|
||||
*version = pVnode->state.processed;
|
||||
for (int i = 0; i < taosArrayGetSize(pMsgs); i++) {
|
||||
pMsg = *(SRpcMsg **)taosArrayGet(pMsgs, i);
|
||||
pRpc = pMsg;
|
||||
switch (pMsg->msgType) {
|
||||
case TDMT_VND_CREATE_TABLE: {
|
||||
int64_t ctime = taosGetTimestampMs();
|
||||
int32_t nReqs;
|
||||
|
||||
// set request version
|
||||
if (walWrite(pVnode->pWal, pVnode->state.processed++, pRpc->msgType, pRpc->pCont, pRpc->contLen) < 0) {
|
||||
vError("vnode:%d write wal error since %s", TD_VID(pVnode), terrstr());
|
||||
return -1;
|
||||
}
|
||||
tDecoderInit(&dc, (uint8_t *)pMsg->pCont + sizeof(SMsgHead), pMsg->contLen - sizeof(SMsgHead));
|
||||
tStartDecode(&dc);
|
||||
|
||||
tDecodeI32v(&dc, &nReqs);
|
||||
for (int32_t iReq = 0; iReq < nReqs; iReq++) {
|
||||
tb_uid_t uid = tGenIdPI64();
|
||||
tStartDecode(&dc);
|
||||
|
||||
tDecodeI32v(&dc, NULL);
|
||||
*(int64_t *)(dc.data + dc.pos) = uid;
|
||||
*(int64_t *)(dc.data + dc.pos + 8) = ctime;
|
||||
|
||||
tEndDecode(&dc);
|
||||
}
|
||||
|
||||
tEndDecode(&dc);
|
||||
tDecoderClear(&dc);
|
||||
} break;
|
||||
case TDMT_VND_SUBMIT: {
|
||||
SSubmitMsgIter msgIter = {0};
|
||||
SSubmitReq *pSubmitReq = (SSubmitReq *)pMsg->pCont;
|
||||
SSubmitBlk *pBlock = NULL;
|
||||
int64_t ctime = taosGetTimestampMs();
|
||||
tb_uid_t uid;
|
||||
|
||||
tInitSubmitMsgIter(pSubmitReq, &msgIter);
|
||||
|
||||
for (;;) {
|
||||
tGetSubmitMsgNext(&msgIter, &pBlock);
|
||||
if (pBlock == NULL) break;
|
||||
|
||||
if (msgIter.schemaLen > 0) {
|
||||
uid = tGenIdPI64();
|
||||
|
||||
tDecoderInit(&dc, pBlock->data, msgIter.schemaLen);
|
||||
tStartDecode(&dc);
|
||||
|
||||
tDecodeI32v(&dc, NULL);
|
||||
*(int64_t *)(dc.data + dc.pos) = uid;
|
||||
*(int64_t *)(dc.data + dc.pos + 8) = ctime;
|
||||
pBlock->uid = htobe64(uid);
|
||||
|
||||
tEndDecode(&dc);
|
||||
tDecoderClear(&dc);
|
||||
}
|
||||
}
|
||||
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
walFsync(pVnode->pWal, false);
|
||||
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -106,13 +146,6 @@ int vnodeProcessWriteReq(SVnode *pVnode, SRpcMsg *pMsg, int64_t version, SRpcMsg
|
|||
pMsg->contLen - sizeof(SMsgHead)) < 0) {
|
||||
}
|
||||
} break;
|
||||
#if 0
|
||||
case TDMT_VND_TASK_WRITE_EXEC: {
|
||||
if (tqProcessTaskExec(pVnode->pTq, POINTER_SHIFT(pMsg->pCont, sizeof(SMsgHead)), pMsg->contLen - sizeof(SMsgHead),
|
||||
0) < 0) {
|
||||
}
|
||||
} break;
|
||||
#endif
|
||||
case TDMT_VND_ALTER_VNODE:
|
||||
break;
|
||||
default:
|
||||
|
@ -195,17 +228,6 @@ int vnodeProcessFetchMsg(SVnode *pVnode, SRpcMsg *pMsg, SQueueInfo *pInfo) {
|
|||
case TDMT_VND_TASK_RECOVER_RSP:
|
||||
return tqProcessTaskRecoverRsp(pVnode->pTq, pMsg);
|
||||
|
||||
#if 0
|
||||
case TDMT_VND_TASK_PIPE_EXEC:
|
||||
case TDMT_VND_TASK_MERGE_EXEC:
|
||||
return tqProcessTaskExec(pVnode->pTq, msgstr, msgLen, 0);
|
||||
case TDMT_VND_STREAM_TRIGGER:{
|
||||
// refactor, avoid double free
|
||||
int code = tqProcessStreamTrigger(pVnode->pTq, pMsg->pCont, pMsg->contLen, 0);
|
||||
pMsg->pCont = NULL;
|
||||
return code;
|
||||
}
|
||||
#endif
|
||||
case TDMT_VND_QUERY_HEARTBEAT:
|
||||
return qWorkerProcessHbMsg(pVnode, pVnode->pQuery, pMsg);
|
||||
default:
|
||||
|
@ -675,7 +697,7 @@ static int vnodeProcessSubmitReq(SVnode *pVnode, int64_t version, void *pReq, in
|
|||
goto _exit;
|
||||
}
|
||||
|
||||
for (int i = 0;;) {
|
||||
for (;;) {
|
||||
tGetSubmitMsgNext(&msgIter, &pBlock);
|
||||
if (pBlock == NULL) break;
|
||||
|
||||
|
|
|
@ -56,7 +56,13 @@ void vnodeSyncStart(SVnode *pVnode) {
|
|||
|
||||
void vnodeSyncClose(SVnode *pVnode) { syncStop(pVnode->sync); }
|
||||
|
||||
int32_t vnodeSyncEqMsg(const SMsgCb *msgcb, SRpcMsg *pMsg) { return tmsgPutToQueue(msgcb, SYNC_QUEUE, pMsg); }
|
||||
int32_t vnodeSyncEqMsg(const SMsgCb *msgcb, SRpcMsg *pMsg) {
|
||||
int32_t code = tmsgPutToQueue(msgcb, SYNC_QUEUE, pMsg);
|
||||
if (code != 0) {
|
||||
rpcFreeCont(pMsg->pCont);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t vnodeSyncSendMsg(const SEpSet *pEpSet, SRpcMsg *pMsg) { return tmsgSendReq(pEpSet, pMsg); }
|
||||
|
||||
|
@ -141,5 +147,6 @@ SSyncFSM *vnodeSyncMakeFsm(SVnode *pVnode) {
|
|||
pFsm->FpPreCommitCb = vnodeSyncPreCommitMsg;
|
||||
pFsm->FpRollBackCb = vnodeSyncRollBackMsg;
|
||||
pFsm->FpGetSnapshot = vnodeSyncGetSnapshot;
|
||||
pFsm->FpRestoreFinish = NULL;
|
||||
return pFsm;
|
||||
}
|
|
@ -1,279 +0,0 @@
|
|||
#include <gtest/gtest.h>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <queue>
|
||||
|
||||
#include "tqMetaStore.h"
|
||||
|
||||
struct Foo {
|
||||
int32_t a;
|
||||
};
|
||||
|
||||
int FooSerializer(const void* pObj, STqSerializedHead** ppHead) {
|
||||
Foo* foo = (Foo*)pObj;
|
||||
if ((*ppHead) == NULL || (*ppHead)->ssize < sizeof(STqSerializedHead) + sizeof(int32_t)) {
|
||||
*ppHead = (STqSerializedHead*)taosMemoryRealloc(*ppHead, sizeof(STqSerializedHead) + sizeof(int32_t));
|
||||
(*ppHead)->ssize = sizeof(STqSerializedHead) + sizeof(int32_t);
|
||||
}
|
||||
*(int32_t*)(*ppHead)->content = foo->a;
|
||||
return (*ppHead)->ssize;
|
||||
}
|
||||
|
||||
const void* FooDeserializer(const STqSerializedHead* pHead, void** ppObj) {
|
||||
if (*ppObj == NULL) {
|
||||
*ppObj = taosMemoryRealloc(*ppObj, sizeof(int32_t));
|
||||
}
|
||||
Foo* pFoo = *(Foo**)ppObj;
|
||||
pFoo->a = *(int32_t*)pHead->content;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void FooDeleter(void* pObj) { taosMemoryFree(pObj); }
|
||||
|
||||
class TqMetaUpdateAppendTest : public ::testing::Test {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
taosRemoveDir(pathName);
|
||||
pMeta = tqStoreOpen(pathName, FooSerializer, FooDeserializer, FooDeleter, TQ_UPDATE_APPEND);
|
||||
ASSERT(pMeta);
|
||||
}
|
||||
|
||||
void TearDown() override { tqStoreClose(pMeta); }
|
||||
|
||||
STqMetaStore* pMeta;
|
||||
const char* pathName = TD_TMP_DIR_PATH "tq_test";
|
||||
};
|
||||
|
||||
TEST_F(TqMetaUpdateAppendTest, copyPutTest) {
|
||||
Foo foo;
|
||||
foo.a = 3;
|
||||
tqHandleCopyPut(pMeta, 1, &foo, sizeof(Foo));
|
||||
|
||||
Foo* pFoo = (Foo*)tqHandleGet(pMeta, 1);
|
||||
EXPECT_EQ(pFoo == NULL, true);
|
||||
|
||||
tqHandleCommit(pMeta, 1);
|
||||
pFoo = (Foo*)tqHandleGet(pMeta, 1);
|
||||
EXPECT_EQ(pFoo->a, 3);
|
||||
}
|
||||
|
||||
TEST_F(TqMetaUpdateAppendTest, persistTest) {
|
||||
Foo* pFoo = (Foo*)taosMemoryMalloc(sizeof(Foo));
|
||||
pFoo->a = 2;
|
||||
tqHandleMovePut(pMeta, 1, pFoo);
|
||||
Foo* pBar = (Foo*)tqHandleGet(pMeta, 1);
|
||||
EXPECT_EQ(pBar == NULL, true);
|
||||
tqHandleCommit(pMeta, 1);
|
||||
pBar = (Foo*)tqHandleGet(pMeta, 1);
|
||||
EXPECT_EQ(pBar->a, pFoo->a);
|
||||
pBar = (Foo*)tqHandleGet(pMeta, 2);
|
||||
EXPECT_EQ(pBar == NULL, true);
|
||||
|
||||
tqStoreClose(pMeta);
|
||||
pMeta = tqStoreOpen(pathName, FooSerializer, FooDeserializer, FooDeleter, TQ_UPDATE_APPEND);
|
||||
ASSERT(pMeta);
|
||||
|
||||
pBar = (Foo*)tqHandleGet(pMeta, 1);
|
||||
ASSERT_EQ(pBar != NULL, true);
|
||||
EXPECT_EQ(pBar->a, 2);
|
||||
|
||||
pBar = (Foo*)tqHandleGet(pMeta, 2);
|
||||
EXPECT_EQ(pBar == NULL, true);
|
||||
}
|
||||
|
||||
TEST_F(TqMetaUpdateAppendTest, uncommittedTest) {
|
||||
Foo* pFoo = (Foo*)taosMemoryMalloc(sizeof(Foo));
|
||||
pFoo->a = 3;
|
||||
tqHandleMovePut(pMeta, 1, pFoo);
|
||||
|
||||
pFoo = (Foo*)tqHandleGet(pMeta, 1);
|
||||
EXPECT_EQ(pFoo == NULL, true);
|
||||
}
|
||||
|
||||
TEST_F(TqMetaUpdateAppendTest, abortTest) {
|
||||
Foo* pFoo = (Foo*)taosMemoryMalloc(sizeof(Foo));
|
||||
pFoo->a = 3;
|
||||
tqHandleMovePut(pMeta, 1, pFoo);
|
||||
|
||||
pFoo = (Foo*)tqHandleGet(pMeta, 1);
|
||||
EXPECT_EQ(pFoo == NULL, true);
|
||||
|
||||
tqHandleAbort(pMeta, 1);
|
||||
pFoo = (Foo*)tqHandleGet(pMeta, 1);
|
||||
EXPECT_EQ(pFoo == NULL, true);
|
||||
}
|
||||
|
||||
TEST_F(TqMetaUpdateAppendTest, deleteTest) {
|
||||
Foo* pFoo = (Foo*)taosMemoryMalloc(sizeof(Foo));
|
||||
pFoo->a = 3;
|
||||
tqHandleMovePut(pMeta, 1, pFoo);
|
||||
|
||||
pFoo = (Foo*)tqHandleGet(pMeta, 1);
|
||||
EXPECT_EQ(pFoo == NULL, true);
|
||||
|
||||
tqHandleCommit(pMeta, 1);
|
||||
|
||||
pFoo = (Foo*)tqHandleGet(pMeta, 1);
|
||||
ASSERT_EQ(pFoo != NULL, true);
|
||||
EXPECT_EQ(pFoo->a, 3);
|
||||
|
||||
tqHandleDel(pMeta, 1);
|
||||
pFoo = (Foo*)tqHandleGet(pMeta, 1);
|
||||
ASSERT_EQ(pFoo != NULL, true);
|
||||
EXPECT_EQ(pFoo->a, 3);
|
||||
|
||||
tqHandleCommit(pMeta, 1);
|
||||
pFoo = (Foo*)tqHandleGet(pMeta, 1);
|
||||
EXPECT_EQ(pFoo == NULL, true);
|
||||
|
||||
tqStoreClose(pMeta);
|
||||
pMeta = tqStoreOpen(pathName, FooSerializer, FooDeserializer, FooDeleter, TQ_UPDATE_APPEND);
|
||||
ASSERT(pMeta);
|
||||
|
||||
pFoo = (Foo*)tqHandleGet(pMeta, 1);
|
||||
EXPECT_EQ(pFoo == NULL, true);
|
||||
}
|
||||
|
||||
TEST_F(TqMetaUpdateAppendTest, intxnPersist) {
|
||||
Foo* pFoo = (Foo*)taosMemoryMalloc(sizeof(Foo));
|
||||
pFoo->a = 3;
|
||||
tqHandleMovePut(pMeta, 1, pFoo);
|
||||
tqHandleCommit(pMeta, 1);
|
||||
|
||||
Foo* pBar = (Foo*)taosMemoryMalloc(sizeof(Foo));
|
||||
pBar->a = 4;
|
||||
tqHandleMovePut(pMeta, 1, pBar);
|
||||
|
||||
Foo* pFoo1 = (Foo*)tqHandleGet(pMeta, 1);
|
||||
EXPECT_EQ(pFoo1->a, 3);
|
||||
|
||||
tqStoreClose(pMeta);
|
||||
pMeta = tqStoreOpen(pathName, FooSerializer, FooDeserializer, FooDeleter, TQ_UPDATE_APPEND);
|
||||
ASSERT(pMeta);
|
||||
|
||||
pFoo1 = (Foo*)tqHandleGet(pMeta, 1);
|
||||
EXPECT_EQ(pFoo1->a, 3);
|
||||
|
||||
tqHandleCommit(pMeta, 1);
|
||||
|
||||
pFoo1 = (Foo*)tqHandleGet(pMeta, 1);
|
||||
EXPECT_EQ(pFoo1->a, 4);
|
||||
|
||||
tqStoreClose(pMeta);
|
||||
pMeta = tqStoreOpen(pathName, FooSerializer, FooDeserializer, FooDeleter, TQ_UPDATE_APPEND);
|
||||
ASSERT(pMeta);
|
||||
|
||||
pFoo1 = (Foo*)tqHandleGet(pMeta, 1);
|
||||
EXPECT_EQ(pFoo1->a, 4);
|
||||
}
|
||||
|
||||
TEST_F(TqMetaUpdateAppendTest, multiplePage) {
|
||||
taosSeedRand(0);
|
||||
std::vector<int> v;
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
v.push_back(taosRand());
|
||||
Foo foo;
|
||||
foo.a = v[i];
|
||||
tqHandleCopyPut(pMeta, i, &foo, sizeof(Foo));
|
||||
}
|
||||
for (int i = 0; i < 500; i++) {
|
||||
tqHandleCommit(pMeta, i);
|
||||
Foo* pFoo = (Foo*)tqHandleGet(pMeta, i);
|
||||
ASSERT_EQ(pFoo != NULL, true) << " at idx " << i << "\n";
|
||||
EXPECT_EQ(pFoo->a, v[i]);
|
||||
}
|
||||
|
||||
tqStoreClose(pMeta);
|
||||
pMeta = tqStoreOpen(pathName, FooSerializer, FooDeserializer, FooDeleter, TQ_UPDATE_APPEND);
|
||||
ASSERT(pMeta);
|
||||
|
||||
for (int i = 500; i < 1000; i++) {
|
||||
tqHandleCommit(pMeta, i);
|
||||
Foo* pFoo = (Foo*)tqHandleGet(pMeta, i);
|
||||
ASSERT_EQ(pFoo != NULL, true) << " at idx " << i << "\n";
|
||||
EXPECT_EQ(pFoo->a, v[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
Foo* pFoo = (Foo*)tqHandleGet(pMeta, i);
|
||||
ASSERT_EQ(pFoo != NULL, true) << " at idx " << i << "\n";
|
||||
EXPECT_EQ(pFoo->a, v[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TqMetaUpdateAppendTest, multipleRewrite) {
|
||||
taosSeedRand(0);
|
||||
std::vector<int> v;
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
v.push_back(taosRand());
|
||||
Foo foo;
|
||||
foo.a = v[i];
|
||||
tqHandleCopyPut(pMeta, i, &foo, sizeof(Foo));
|
||||
}
|
||||
|
||||
for (int i = 0; i < 500; i++) {
|
||||
tqHandleCommit(pMeta, i);
|
||||
v[i] = taosRand();
|
||||
Foo foo;
|
||||
foo.a = v[i];
|
||||
tqHandleCopyPut(pMeta, i, &foo, sizeof(Foo));
|
||||
}
|
||||
|
||||
for (int i = 500; i < 1000; i++) {
|
||||
v[i] = taosRand();
|
||||
Foo foo;
|
||||
foo.a = v[i];
|
||||
tqHandleCopyPut(pMeta, i, &foo, sizeof(Foo));
|
||||
}
|
||||
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
tqHandleCommit(pMeta, i);
|
||||
}
|
||||
|
||||
tqStoreClose(pMeta);
|
||||
pMeta = tqStoreOpen(pathName, FooSerializer, FooDeserializer, FooDeleter, TQ_UPDATE_APPEND);
|
||||
ASSERT(pMeta);
|
||||
|
||||
for (int i = 500; i < 1000; i++) {
|
||||
v[i] = taosRand();
|
||||
Foo foo;
|
||||
foo.a = v[i];
|
||||
tqHandleCopyPut(pMeta, i, &foo, sizeof(Foo));
|
||||
tqHandleCommit(pMeta, i);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
Foo* pFoo = (Foo*)tqHandleGet(pMeta, i);
|
||||
ASSERT_EQ(pFoo != NULL, true) << " at idx " << i << "\n";
|
||||
EXPECT_EQ(pFoo->a, v[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TqMetaUpdateAppendTest, dupCommit) {
|
||||
taosSeedRand(0);
|
||||
std::vector<int> v;
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
v.push_back(taosRand());
|
||||
Foo foo;
|
||||
foo.a = v[i];
|
||||
tqHandleCopyPut(pMeta, i, &foo, sizeof(Foo));
|
||||
}
|
||||
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
int ret = tqHandleCommit(pMeta, i);
|
||||
EXPECT_EQ(ret, 0);
|
||||
ret = tqHandleCommit(pMeta, i);
|
||||
EXPECT_EQ(ret, -1);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
int ret = tqHandleCommit(pMeta, i);
|
||||
EXPECT_EQ(ret, -1);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
Foo* pFoo = (Foo*)tqHandleGet(pMeta, i);
|
||||
ASSERT_EQ(pFoo != NULL, true) << " at idx " << i << "\n";
|
||||
EXPECT_EQ(pFoo->a, v[i]);
|
||||
}
|
||||
}
|
|
@ -58,6 +58,17 @@ enum {
|
|||
CTG_ACT_MAX
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
CTG_TASK_GET_QNODE = 0,
|
||||
CTG_TASK_GET_DB_VGROUP,
|
||||
CTG_TASK_GET_DB_CFG,
|
||||
CTG_TASK_GET_TB_META,
|
||||
CTG_TASK_GET_TB_HASH,
|
||||
CTG_TASK_GET_INDEX,
|
||||
CTG_TASK_GET_UDF,
|
||||
CTG_TASK_GET_USER,
|
||||
} CTG_TASK_TYPE;
|
||||
|
||||
typedef struct SCtgDebug {
|
||||
bool lockEnable;
|
||||
bool cacheEnable;
|
||||
|
@ -66,6 +77,43 @@ typedef struct SCtgDebug {
|
|||
uint32_t showCachePeriodSec;
|
||||
} SCtgDebug;
|
||||
|
||||
typedef struct SCtgTbCacheInfo {
|
||||
bool inCache;
|
||||
uint64_t dbId;
|
||||
uint64_t suid;
|
||||
int32_t tbType;
|
||||
} SCtgTbCacheInfo;
|
||||
|
||||
typedef struct SCtgTbMetaCtx {
|
||||
SCtgTbCacheInfo tbInfo;
|
||||
SName* pName;
|
||||
int32_t flag;
|
||||
} SCtgTbMetaCtx;
|
||||
|
||||
typedef struct SCtgDbVgCtx {
|
||||
char dbFName[TSDB_DB_FNAME_LEN];
|
||||
} SCtgDbVgCtx;
|
||||
|
||||
typedef struct SCtgDbCfgCtx {
|
||||
char dbFName[TSDB_DB_FNAME_LEN];
|
||||
} SCtgDbCfgCtx;
|
||||
|
||||
typedef struct SCtgTbHashCtx {
|
||||
char dbFName[TSDB_DB_FNAME_LEN];
|
||||
SName* pName;
|
||||
} SCtgTbHashCtx;
|
||||
|
||||
typedef struct SCtgIndexCtx {
|
||||
char indexFName[TSDB_INDEX_FNAME_LEN];
|
||||
} SCtgIndexCtx;
|
||||
|
||||
typedef struct SCtgUdfCtx {
|
||||
char udfName[TSDB_FUNC_NAME_LEN];
|
||||
} SCtgUdfCtx;
|
||||
|
||||
typedef struct SCtgUserCtx {
|
||||
SUserAuthInfo user;
|
||||
} SCtgUserCtx;
|
||||
|
||||
typedef struct SCtgTbMetaCache {
|
||||
SRWLatch stbLock;
|
||||
|
@ -113,6 +161,55 @@ typedef struct SCatalog {
|
|||
SCtgRentMgmt stbRent;
|
||||
} SCatalog;
|
||||
|
||||
typedef struct SCtgJob {
|
||||
int64_t refId;
|
||||
SArray* pTasks;
|
||||
int32_t taskDone;
|
||||
SMetaData jobRes;
|
||||
int32_t rspCode;
|
||||
|
||||
uint64_t queryId;
|
||||
SCatalog* pCtg;
|
||||
void* pTrans;
|
||||
const SEpSet* pMgmtEps;
|
||||
void* userParam;
|
||||
catalogCallback userFp;
|
||||
int32_t tbMetaNum;
|
||||
int32_t tbHashNum;
|
||||
int32_t dbVgNum;
|
||||
int32_t udfNum;
|
||||
int32_t qnodeNum;
|
||||
int32_t dbCfgNum;
|
||||
int32_t indexNum;
|
||||
int32_t userNum;
|
||||
} SCtgJob;
|
||||
|
||||
typedef struct SCtgMsgCtx {
|
||||
int32_t reqType;
|
||||
void* lastOut;
|
||||
void* out;
|
||||
char* target;
|
||||
} SCtgMsgCtx;
|
||||
|
||||
typedef struct SCtgTask {
|
||||
CTG_TASK_TYPE type;
|
||||
int32_t taskId;
|
||||
SCtgJob *pJob;
|
||||
void* taskCtx;
|
||||
SCtgMsgCtx msgCtx;
|
||||
void* res;
|
||||
} SCtgTask;
|
||||
|
||||
typedef int32_t (*ctgLanchTaskFp)(SCtgTask*);
|
||||
typedef int32_t (*ctgHandleTaskMsgRspFp)(SCtgTask*, int32_t, const SDataBuf *, int32_t);
|
||||
typedef int32_t (*ctgDumpTaskResFp)(SCtgTask*);
|
||||
|
||||
typedef struct SCtgAsyncFps {
|
||||
ctgLanchTaskFp launchFp;
|
||||
ctgHandleTaskMsgRspFp handleRspFp;
|
||||
ctgDumpTaskResFp dumpResFp;
|
||||
} SCtgAsyncFps;
|
||||
|
||||
typedef struct SCtgApiStat {
|
||||
|
||||
#ifdef WINDOWS
|
||||
|
@ -214,6 +311,7 @@ typedef struct SCtgQueue {
|
|||
|
||||
typedef struct SCatalogMgmt {
|
||||
bool exit;
|
||||
int32_t jobPool;
|
||||
SRWLatch lock;
|
||||
SCtgQueue queue;
|
||||
TdThread updateThread;
|
||||
|
@ -327,10 +425,80 @@ typedef struct SCtgAction {
|
|||
#define CTG_API_LEAVE(c) do { int32_t __code = c; CTG_UNLOCK(CTG_READ, &gCtgMgmt.lock); CTG_API_DEBUG("CTG API leave %s", __FUNCTION__); CTG_RET(__code); } while (0)
|
||||
#define CTG_API_ENTER() do { CTG_API_DEBUG("CTG API enter %s", __FUNCTION__); CTG_LOCK(CTG_READ, &gCtgMgmt.lock); if (atomic_load_8((int8_t*)&gCtgMgmt.exit)) { CTG_API_LEAVE(TSDB_CODE_CTG_OUT_OF_SERVICE); } } while (0)
|
||||
|
||||
#define CTG_PARAMS SCatalog* pCtg, void *pTrans, const SEpSet* pMgmtEps
|
||||
#define CTG_PARAMS_LIST() pCtg, pTrans, pMgmtEps
|
||||
|
||||
extern void ctgdShowTableMeta(SCatalog* pCtg, const char *tbName, STableMeta* p);
|
||||
extern void ctgdShowClusterCache(SCatalog* pCtg);
|
||||
extern int32_t ctgdShowCacheInfo(void);
|
||||
void ctgdShowTableMeta(SCatalog* pCtg, const char *tbName, STableMeta* p);
|
||||
void ctgdShowClusterCache(SCatalog* pCtg);
|
||||
int32_t ctgdShowCacheInfo(void);
|
||||
|
||||
int32_t ctgRemoveTbMetaFromCache(SCatalog* pCtg, SName* pTableName, bool syncReq);
|
||||
int32_t ctgGetTbMetaFromCache(CTG_PARAMS, SCtgTbMetaCtx* ctx, STableMeta** pTableMeta);
|
||||
|
||||
int32_t ctgActUpdateVg(SCtgMetaAction *action);
|
||||
int32_t ctgActUpdateTb(SCtgMetaAction *action);
|
||||
int32_t ctgActRemoveDB(SCtgMetaAction *action);
|
||||
int32_t ctgActRemoveStb(SCtgMetaAction *action);
|
||||
int32_t ctgActRemoveTb(SCtgMetaAction *action);
|
||||
int32_t ctgActUpdateUser(SCtgMetaAction *action);
|
||||
int32_t ctgAcquireVgInfoFromCache(SCatalog* pCtg, const char *dbFName, SCtgDBCache **pCache);
|
||||
void ctgReleaseDBCache(SCatalog *pCtg, SCtgDBCache *dbCache);
|
||||
void ctgReleaseVgInfo(SCtgDBCache *dbCache);
|
||||
int32_t ctgAcquireVgInfoFromCache(SCatalog* pCtg, const char *dbFName, SCtgDBCache **pCache);
|
||||
int32_t ctgTbMetaExistInCache(SCatalog* pCtg, char *dbFName, char* tbName, int32_t *exist);
|
||||
int32_t ctgReadTbMetaFromCache(SCatalog* pCtg, SCtgTbMetaCtx* ctx, STableMeta** pTableMeta);
|
||||
int32_t ctgReadTbSverFromCache(SCatalog *pCtg, const SName *pTableName, int32_t *sver, int32_t *tbType, uint64_t *suid, char *stbName);
|
||||
int32_t ctgChkAuthFromCache(SCatalog* pCtg, const char* user, const char* dbFName, AUTH_TYPE type, bool *inCache, bool *pass);
|
||||
int32_t ctgPutRmDBToQueue(SCatalog* pCtg, const char *dbFName, int64_t dbId);
|
||||
int32_t ctgPutRmStbToQueue(SCatalog* pCtg, const char *dbFName, int64_t dbId, const char *stbName, uint64_t suid, bool syncReq);
|
||||
int32_t ctgPutRmTbToQueue(SCatalog* pCtg, const char *dbFName, int64_t dbId, const char *tbName, bool syncReq);
|
||||
int32_t ctgPutUpdateVgToQueue(SCatalog* pCtg, const char *dbFName, int64_t dbId, SDBVgInfo* dbInfo, bool syncReq);
|
||||
int32_t ctgPutUpdateTbToQueue(SCatalog* pCtg, STableMetaOutput *output, bool syncReq);
|
||||
int32_t ctgPutUpdateUserToQueue(SCatalog* pCtg, SGetUserAuthRsp *pAuth, bool syncReq);
|
||||
int32_t ctgMetaRentInit(SCtgRentMgmt *mgmt, uint32_t rentSec, int8_t type);
|
||||
int32_t ctgMetaRentAdd(SCtgRentMgmt *mgmt, void *meta, int64_t id, int32_t size);
|
||||
int32_t ctgMetaRentGet(SCtgRentMgmt *mgmt, void **res, uint32_t *num, int32_t size);
|
||||
int32_t ctgUpdateTbMetaToCache(SCatalog* pCtg, STableMetaOutput* pOut, bool syncReq);
|
||||
int32_t ctgStartUpdateThread();
|
||||
int32_t ctgRelaunchGetTbMetaTask(SCtgTask *pTask);
|
||||
|
||||
|
||||
|
||||
int32_t ctgProcessRspMsg(void* out, int32_t reqType, char* msg, int32_t msgSize, int32_t rspCode, char* target);
|
||||
int32_t ctgGetDBVgInfoFromMnode(CTG_PARAMS, SBuildUseDBInput *input, SUseDbOutput *out, SCtgTask* pTask);
|
||||
int32_t ctgGetQnodeListFromMnode(CTG_PARAMS, SArray *out, SCtgTask* pTask);
|
||||
int32_t ctgGetDBCfgFromMnode(CTG_PARAMS, const char *dbFName, SDbCfgInfo *out, SCtgTask* pTask);
|
||||
int32_t ctgGetIndexInfoFromMnode(CTG_PARAMS, const char *indexName, SIndexInfo *out, SCtgTask* pTask);
|
||||
int32_t ctgGetUdfInfoFromMnode(CTG_PARAMS, const char *funcName, SFuncInfo *out, SCtgTask* pTask);
|
||||
int32_t ctgGetUserDbAuthFromMnode(CTG_PARAMS, const char *user, SGetUserAuthRsp *out, SCtgTask* pTask);
|
||||
int32_t ctgGetTbMetaFromMnodeImpl(CTG_PARAMS, char *dbFName, char* tbName, STableMetaOutput* out, SCtgTask* pTask);
|
||||
int32_t ctgGetTbMetaFromMnode(CTG_PARAMS, const SName* pTableName, STableMetaOutput* out, SCtgTask* pTask);
|
||||
int32_t ctgGetTbMetaFromVnode(CTG_PARAMS, const SName* pTableName, SVgroupInfo *vgroupInfo, STableMetaOutput* out, SCtgTask* pTask);
|
||||
|
||||
int32_t ctgInitJob(CTG_PARAMS, SCtgJob** job, uint64_t reqId, const SCatalogReq* pReq, catalogCallback fp, void* param);
|
||||
int32_t ctgLaunchJob(SCtgJob *pJob);
|
||||
int32_t ctgMakeAsyncRes(SCtgJob *pJob);
|
||||
|
||||
int32_t ctgCloneVgInfo(SDBVgInfo *src, SDBVgInfo **dst);
|
||||
int32_t ctgCloneMetaOutput(STableMetaOutput *output, STableMetaOutput **pOutput);
|
||||
int32_t ctgGenerateVgList(SCatalog *pCtg, SHashObj *vgHash, SArray** pList);
|
||||
void ctgFreeJob(void* job);
|
||||
void ctgFreeHandle(SCatalog* pCtg);
|
||||
void ctgFreeVgInfo(SDBVgInfo *vgInfo);
|
||||
int32_t ctgGetVgInfoFromHashValue(SCatalog *pCtg, SDBVgInfo *dbInfo, const SName *pTableName, SVgroupInfo *pVgroup);
|
||||
void ctgResetTbMetaTask(SCtgTask* pTask);
|
||||
void ctgFreeDbCache(SCtgDBCache *dbCache);
|
||||
int32_t ctgStbVersionSortCompare(const void* key1, const void* key2);
|
||||
int32_t ctgDbVgVersionSortCompare(const void* key1, const void* key2);
|
||||
int32_t ctgStbVersionSearchCompare(const void* key1, const void* key2);
|
||||
int32_t ctgDbVgVersionSearchCompare(const void* key1, const void* key2);
|
||||
void ctgFreeSTableMetaOutput(STableMetaOutput* pOutput);
|
||||
int32_t ctgUpdateMsgCtx(SCtgMsgCtx* pCtx, int32_t reqType, void* out, char* target);
|
||||
|
||||
|
||||
extern SCatalogMgmt gCtgMgmt;
|
||||
extern SCtgDebug gCTGDebug;
|
||||
extern SCtgAsyncFps gCtgAsyncFps[];
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -13,23 +13,23 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _INDEX_OPERATOR_H
|
||||
#define _INDEX_OPERATOR_H
|
||||
#ifndef _TD_CATALOG_REMOTE_H_
|
||||
#define _TD_CATALOG_REMOTE_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "nodes.h"
|
||||
#include "tglobal.h"
|
||||
|
||||
typedef enum { SFLT_NOT_INDEX, SFLT_COARSE_INDEX, SFLT_ACCURATE_INDEX } SIdxFltStatus;
|
||||
typedef struct SCtgTaskCallbackParam {
|
||||
uint64_t queryId;
|
||||
int64_t refId;
|
||||
uint64_t taskId;
|
||||
int32_t reqType;
|
||||
} SCtgTaskCallbackParam;
|
||||
|
||||
SIdxFltStatus idxGetFltStatus(SNode *pFilterNode);
|
||||
// construct tag filter operator later
|
||||
int32_t doFilterTag(const SNode *pFilterNode, SArray *result);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*INDEX_OPERATOR_*/
|
||||
#endif /*_TD_CATALOG_REMOTE_H_*/
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,577 @@
|
|||
/*
|
||||
* 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 "trpc.h"
|
||||
#include "query.h"
|
||||
#include "tname.h"
|
||||
#include "catalogInt.h"
|
||||
#include "systable.h"
|
||||
#include "ctgRemote.h"
|
||||
#include "tref.h"
|
||||
|
||||
int32_t ctgProcessRspMsg(void* out, int32_t reqType, char* msg, int32_t msgSize, int32_t rspCode, char* target) {
|
||||
int32_t code = 0;
|
||||
|
||||
switch (reqType) {
|
||||
case TDMT_MND_QNODE_LIST: {
|
||||
if (TSDB_CODE_SUCCESS != rspCode) {
|
||||
qError("error rsp for qnode list, error:%s", tstrerror(rspCode));
|
||||
CTG_ERR_RET(rspCode);
|
||||
}
|
||||
|
||||
code = queryProcessMsgRsp[TMSG_INDEX(reqType)](out, msg, msgSize);
|
||||
if (code) {
|
||||
qError("Process qnode list rsp failed, error:%s", tstrerror(rspCode));
|
||||
CTG_ERR_RET(code);
|
||||
}
|
||||
|
||||
qDebug("Got qnode list from mnode, listNum:%d", (int32_t)taosArrayGetSize(out));
|
||||
break;
|
||||
}
|
||||
case TDMT_MND_USE_DB: {
|
||||
if (TSDB_CODE_SUCCESS != rspCode) {
|
||||
qError("error rsp for use db, error:%s, dbFName:%s", tstrerror(rspCode), target);
|
||||
CTG_ERR_RET(rspCode);
|
||||
}
|
||||
|
||||
code = queryProcessMsgRsp[TMSG_INDEX(reqType)](out, msg, msgSize);
|
||||
if (code) {
|
||||
qError("Process use db rsp failed, error:%s, dbFName:%s", tstrerror(code), target);
|
||||
CTG_ERR_RET(code);
|
||||
}
|
||||
|
||||
qDebug("Got db vgInfo from mnode, dbFName:%s", target);
|
||||
break;
|
||||
}
|
||||
case TDMT_MND_GET_DB_CFG: {
|
||||
if (TSDB_CODE_SUCCESS != rspCode) {
|
||||
qError("error rsp for get db cfg, error:%s, db:%s", tstrerror(rspCode), target);
|
||||
CTG_ERR_RET(rspCode);
|
||||
}
|
||||
|
||||
code = queryProcessMsgRsp[TMSG_INDEX(reqType)](out, msg, msgSize);
|
||||
if (code) {
|
||||
qError("Process get db cfg rsp failed, error:%s, db:%s", tstrerror(code), target);
|
||||
CTG_ERR_RET(code);
|
||||
}
|
||||
|
||||
qDebug("Got db cfg from mnode, dbFName:%s", target);
|
||||
break;
|
||||
}
|
||||
case TDMT_MND_GET_INDEX: {
|
||||
if (TSDB_CODE_SUCCESS != rspCode) {
|
||||
qError("error rsp for get index, error:%s, indexName:%s", tstrerror(rspCode), target);
|
||||
CTG_ERR_RET(rspCode);
|
||||
}
|
||||
|
||||
code = queryProcessMsgRsp[TMSG_INDEX(reqType)](out, msg, msgSize);
|
||||
if (code) {
|
||||
qError("Process get index rsp failed, error:%s, indexName:%s", tstrerror(code), target);
|
||||
CTG_ERR_RET(code);
|
||||
}
|
||||
|
||||
qDebug("Got index from mnode, indexName:%s", target);
|
||||
break;
|
||||
}
|
||||
case TDMT_MND_RETRIEVE_FUNC: {
|
||||
if (TSDB_CODE_SUCCESS != rspCode) {
|
||||
qError("error rsp for get udf, error:%s, funcName:%s", tstrerror(rspCode), target);
|
||||
CTG_ERR_RET(rspCode);
|
||||
}
|
||||
|
||||
code = queryProcessMsgRsp[TMSG_INDEX(reqType)](out, msg, msgSize);
|
||||
if (code) {
|
||||
qError("Process get udf rsp failed, error:%s, funcName:%s", tstrerror(code), target);
|
||||
CTG_ERR_RET(code);
|
||||
}
|
||||
|
||||
qDebug("Got udf from mnode, funcName:%s", target);
|
||||
break;
|
||||
}
|
||||
case TDMT_MND_GET_USER_AUTH: {
|
||||
if (TSDB_CODE_SUCCESS != rspCode) {
|
||||
qError("error rsp for get user auth, error:%s, user:%s", tstrerror(rspCode), target);
|
||||
CTG_ERR_RET(rspCode);
|
||||
}
|
||||
|
||||
code = queryProcessMsgRsp[TMSG_INDEX(reqType)](out, msg, msgSize);
|
||||
if (code) {
|
||||
qError("Process get user auth rsp failed, error:%s, user:%s", tstrerror(code), target);
|
||||
CTG_ERR_RET(code);
|
||||
}
|
||||
|
||||
qDebug("Got user auth from mnode, user:%s", target);
|
||||
break;
|
||||
}
|
||||
case TDMT_MND_TABLE_META: {
|
||||
if (TSDB_CODE_SUCCESS != rspCode) {
|
||||
if (CTG_TABLE_NOT_EXIST(rspCode)) {
|
||||
SET_META_TYPE_NULL(((STableMetaOutput*)out)->metaType);
|
||||
qDebug("stablemeta not exist in mnode, tbFName:%s", target);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
qError("error rsp for stablemeta from mnode, error:%s, tbFName:%s", tstrerror(rspCode), target);
|
||||
CTG_ERR_RET(rspCode);
|
||||
}
|
||||
|
||||
code = queryProcessMsgRsp[TMSG_INDEX(reqType)](out, msg, msgSize);
|
||||
if (code) {
|
||||
qError("Process mnode stablemeta rsp failed, error:%s, tbFName:%s", tstrerror(code), target);
|
||||
CTG_ERR_RET(code);
|
||||
}
|
||||
|
||||
qDebug("Got table meta from mnode, tbFName:%s", target);
|
||||
break;
|
||||
}
|
||||
case TDMT_VND_TABLE_META: {
|
||||
if (TSDB_CODE_SUCCESS != rspCode) {
|
||||
if (CTG_TABLE_NOT_EXIST(rspCode)) {
|
||||
SET_META_TYPE_NULL(((STableMetaOutput*)out)->metaType);
|
||||
qDebug("tablemeta not exist in vnode, tbFName:%s", target);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
qError("error rsp for table meta from vnode, code:%s, tbFName:%s", tstrerror(rspCode), target);
|
||||
CTG_ERR_RET(rspCode);
|
||||
}
|
||||
|
||||
code = queryProcessMsgRsp[TMSG_INDEX(reqType)](out, msg, msgSize);
|
||||
if (code) {
|
||||
qError("Process vnode tablemeta rsp failed, code:%s, tbFName:%s", tstrerror(code), target);
|
||||
CTG_ERR_RET(code);
|
||||
}
|
||||
|
||||
qDebug("Got table meta from vnode, tbFName:%s", target);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int32_t ctgHandleMsgCallback(void *param, const SDataBuf *pMsg, int32_t rspCode) {
|
||||
SCtgTaskCallbackParam* cbParam = (SCtgTaskCallbackParam*)param;
|
||||
int32_t code = 0;
|
||||
|
||||
CTG_API_ENTER();
|
||||
|
||||
SCtgJob* pJob = taosAcquireRef(gCtgMgmt.jobPool, cbParam->refId);
|
||||
if (NULL == pJob) {
|
||||
qDebug("job refId %" PRIx64 " already dropped", cbParam->refId);
|
||||
goto _return;
|
||||
}
|
||||
|
||||
SCtgTask *pTask = taosArrayGet(pJob->pTasks, cbParam->taskId);
|
||||
|
||||
qDebug("QID:%" PRIx64 " task %d start to handle rsp %s", pJob->queryId, pTask->taskId, TMSG_INFO(cbParam->reqType + 1));
|
||||
|
||||
CTG_ERR_JRET((*gCtgAsyncFps[pTask->type].handleRspFp)(pTask, cbParam->reqType, pMsg, rspCode));
|
||||
|
||||
_return:
|
||||
|
||||
if (pJob) {
|
||||
taosReleaseRef(gCtgMgmt.jobPool, cbParam->refId);
|
||||
}
|
||||
|
||||
taosMemoryFree(param);
|
||||
|
||||
CTG_API_LEAVE(code);
|
||||
}
|
||||
|
||||
|
||||
int32_t ctgMakeMsgSendInfo(SCtgTask* pTask, int32_t msgType, SMsgSendInfo **pMsgSendInfo) {
|
||||
int32_t code = 0;
|
||||
SMsgSendInfo *msgSendInfo = taosMemoryCalloc(1, sizeof(SMsgSendInfo));
|
||||
if (NULL == msgSendInfo) {
|
||||
qError("calloc %d failed", (int32_t)sizeof(SMsgSendInfo));
|
||||
CTG_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
SCtgTaskCallbackParam *param = taosMemoryCalloc(1, sizeof(SCtgTaskCallbackParam));
|
||||
if (NULL == param) {
|
||||
qError("calloc %d failed", (int32_t)sizeof(SCtgTaskCallbackParam));
|
||||
CTG_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
param->reqType = msgType;
|
||||
param->queryId = pTask->pJob->queryId;
|
||||
param->refId = pTask->pJob->refId;
|
||||
param->taskId = pTask->taskId;
|
||||
|
||||
msgSendInfo->param = param;
|
||||
msgSendInfo->fp = ctgHandleMsgCallback;
|
||||
|
||||
*pMsgSendInfo = msgSendInfo;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
||||
_return:
|
||||
|
||||
taosMemoryFree(param);
|
||||
taosMemoryFree(msgSendInfo);
|
||||
|
||||
CTG_RET(code);
|
||||
}
|
||||
|
||||
int32_t ctgAsyncSendMsg(CTG_PARAMS, SCtgTask* pTask, int32_t msgType, void *msg, uint32_t msgSize) {
|
||||
int32_t code = 0;
|
||||
SMsgSendInfo *pMsgSendInfo = NULL;
|
||||
CTG_ERR_JRET(ctgMakeMsgSendInfo(pTask, msgType, &pMsgSendInfo));
|
||||
|
||||
pMsgSendInfo->msgInfo.pData = msg;
|
||||
pMsgSendInfo->msgInfo.len = msgSize;
|
||||
pMsgSendInfo->msgInfo.handle = NULL;
|
||||
pMsgSendInfo->msgType = msgType;
|
||||
|
||||
int64_t transporterId = 0;
|
||||
code = asyncSendMsgToServer(pTrans, (SEpSet*)pMgmtEps, &transporterId, pMsgSendInfo);
|
||||
if (code) {
|
||||
ctgError("asyncSendMsgToSever failed, error: %s", tstrerror(code));
|
||||
CTG_ERR_JRET(code);
|
||||
}
|
||||
|
||||
ctgDebug("req msg sent, reqId:%" PRIx64 ", msg type:%d, %s", pTask->pJob->queryId, msgType, TMSG_INFO(msgType));
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
||||
_return:
|
||||
|
||||
if (pMsgSendInfo) {
|
||||
taosMemoryFreeClear(pMsgSendInfo->param);
|
||||
taosMemoryFreeClear(pMsgSendInfo);
|
||||
}
|
||||
|
||||
CTG_RET(code);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int32_t ctgGetQnodeListFromMnode(CTG_PARAMS, SArray *out, SCtgTask* pTask) {
|
||||
char *msg = NULL;
|
||||
int32_t msgLen = 0;
|
||||
int32_t reqType = TDMT_MND_QNODE_LIST;
|
||||
|
||||
ctgDebug("try to get qnode list from mnode, mgmtEpInUse:%d", pMgmtEps->inUse);
|
||||
|
||||
int32_t code = queryBuildMsg[TMSG_INDEX(reqType)](NULL, &msg, 0, &msgLen);
|
||||
if (code) {
|
||||
ctgError("Build qnode list msg failed, error:%s", tstrerror(code));
|
||||
CTG_ERR_RET(code);
|
||||
}
|
||||
|
||||
if (pTask) {
|
||||
void* pOut = taosArrayInit(4, sizeof(struct SQueryNodeAddr));
|
||||
if (NULL == pOut) {
|
||||
CTG_ERR_RET(TSDB_CODE_OUT_OF_MEMORY);
|
||||
}
|
||||
CTG_ERR_RET(ctgUpdateMsgCtx(&pTask->msgCtx, reqType, pOut, NULL));
|
||||
CTG_RET(ctgAsyncSendMsg(CTG_PARAMS_LIST(), pTask, reqType, msg, msgLen));
|
||||
}
|
||||
|
||||
SRpcMsg rpcMsg = {
|
||||
.msgType = reqType,
|
||||
.pCont = msg,
|
||||
.contLen = msgLen,
|
||||
};
|
||||
|
||||
SRpcMsg rpcRsp = {0};
|
||||
rpcSendRecv(pTrans, (SEpSet*)pMgmtEps, &rpcMsg, &rpcRsp);
|
||||
|
||||
CTG_ERR_RET(ctgProcessRspMsg(out, reqType, rpcRsp.pCont, rpcRsp.contLen, rpcRsp.code, NULL));
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int32_t ctgGetDBVgInfoFromMnode(CTG_PARAMS, SBuildUseDBInput *input, SUseDbOutput *out, SCtgTask* pTask) {
|
||||
char *msg = NULL;
|
||||
int32_t msgLen = 0;
|
||||
int32_t reqType = TDMT_MND_USE_DB;
|
||||
|
||||
ctgDebug("try to get db vgInfo from mnode, dbFName:%s", input->db);
|
||||
|
||||
int32_t code = queryBuildMsg[TMSG_INDEX(reqType)](input, &msg, 0, &msgLen);
|
||||
if (code) {
|
||||
ctgError("Build use db msg failed, code:%x, db:%s", code, input->db);
|
||||
CTG_ERR_RET(code);
|
||||
}
|
||||
|
||||
if (pTask) {
|
||||
void* pOut = taosMemoryCalloc(1, sizeof(SUseDbOutput));
|
||||
if (NULL == pOut) {
|
||||
CTG_ERR_RET(TSDB_CODE_OUT_OF_MEMORY);
|
||||
}
|
||||
CTG_ERR_RET(ctgUpdateMsgCtx(&pTask->msgCtx, reqType, pOut, input->db));
|
||||
|
||||
CTG_RET(ctgAsyncSendMsg(CTG_PARAMS_LIST(), pTask, reqType, msg, msgLen));
|
||||
}
|
||||
|
||||
SRpcMsg rpcMsg = {
|
||||
.msgType = reqType,
|
||||
.pCont = msg,
|
||||
.contLen = msgLen,
|
||||
};
|
||||
|
||||
SRpcMsg rpcRsp = {0};
|
||||
rpcSendRecv(pTrans, (SEpSet*)pMgmtEps, &rpcMsg, &rpcRsp);
|
||||
|
||||
CTG_ERR_RET(ctgProcessRspMsg(out, reqType, rpcRsp.pCont, rpcRsp.contLen, rpcRsp.code, input->db));
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t ctgGetDBCfgFromMnode(CTG_PARAMS, const char *dbFName, SDbCfgInfo *out, SCtgTask* pTask) {
|
||||
char *msg = NULL;
|
||||
int32_t msgLen = 0;
|
||||
int32_t reqType = TDMT_MND_GET_DB_CFG;
|
||||
|
||||
ctgDebug("try to get db cfg from mnode, dbFName:%s", dbFName);
|
||||
|
||||
int32_t code = queryBuildMsg[TMSG_INDEX(reqType)]((void *)dbFName, &msg, 0, &msgLen);
|
||||
if (code) {
|
||||
ctgError("Build get db cfg msg failed, code:%x, db:%s", code, dbFName);
|
||||
CTG_ERR_RET(code);
|
||||
}
|
||||
|
||||
if (pTask) {
|
||||
void* pOut = taosMemoryCalloc(1, sizeof(SDbCfgInfo));
|
||||
if (NULL == pOut) {
|
||||
CTG_ERR_RET(TSDB_CODE_OUT_OF_MEMORY);
|
||||
}
|
||||
CTG_ERR_RET(ctgUpdateMsgCtx(&pTask->msgCtx, reqType, pOut, (char*)dbFName));
|
||||
|
||||
CTG_RET(ctgAsyncSendMsg(CTG_PARAMS_LIST(), pTask, reqType, msg, msgLen));
|
||||
}
|
||||
|
||||
SRpcMsg rpcMsg = {
|
||||
.msgType = TDMT_MND_GET_DB_CFG,
|
||||
.pCont = msg,
|
||||
.contLen = msgLen,
|
||||
};
|
||||
|
||||
SRpcMsg rpcRsp = {0};
|
||||
rpcSendRecv(pTrans, (SEpSet*)pMgmtEps, &rpcMsg, &rpcRsp);
|
||||
|
||||
CTG_ERR_RET(ctgProcessRspMsg(out, reqType, rpcRsp.pCont, rpcRsp.contLen, rpcRsp.code, (char*)dbFName));
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t ctgGetIndexInfoFromMnode(CTG_PARAMS, const char *indexName, SIndexInfo *out, SCtgTask* pTask) {
|
||||
char *msg = NULL;
|
||||
int32_t msgLen = 0;
|
||||
int32_t reqType = TDMT_MND_GET_INDEX;
|
||||
|
||||
ctgDebug("try to get index from mnode, indexName:%s", indexName);
|
||||
|
||||
int32_t code = queryBuildMsg[TMSG_INDEX(reqType)]((void *)indexName, &msg, 0, &msgLen);
|
||||
if (code) {
|
||||
ctgError("Build get index msg failed, code:%x, db:%s", code, indexName);
|
||||
CTG_ERR_RET(code);
|
||||
}
|
||||
|
||||
if (pTask) {
|
||||
void* pOut = taosMemoryCalloc(1, sizeof(SIndexInfo));
|
||||
if (NULL == pOut) {
|
||||
CTG_ERR_RET(TSDB_CODE_OUT_OF_MEMORY);
|
||||
}
|
||||
CTG_ERR_RET(ctgUpdateMsgCtx(&pTask->msgCtx, reqType, pOut, (char*)indexName));
|
||||
|
||||
CTG_RET(ctgAsyncSendMsg(CTG_PARAMS_LIST(), pTask, reqType, msg, msgLen));
|
||||
}
|
||||
|
||||
SRpcMsg rpcMsg = {
|
||||
.msgType = reqType,
|
||||
.pCont = msg,
|
||||
.contLen = msgLen,
|
||||
};
|
||||
|
||||
SRpcMsg rpcRsp = {0};
|
||||
rpcSendRecv(pTrans, (SEpSet*)pMgmtEps, &rpcMsg, &rpcRsp);
|
||||
|
||||
CTG_ERR_RET(ctgProcessRspMsg(out, reqType, rpcRsp.pCont, rpcRsp.contLen, rpcRsp.code, (char*)indexName));
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t ctgGetUdfInfoFromMnode(CTG_PARAMS, const char *funcName, SFuncInfo *out, SCtgTask* pTask) {
|
||||
char *msg = NULL;
|
||||
int32_t msgLen = 0;
|
||||
int32_t reqType = TDMT_MND_RETRIEVE_FUNC;
|
||||
|
||||
ctgDebug("try to get udf info from mnode, funcName:%s", funcName);
|
||||
|
||||
int32_t code = queryBuildMsg[TMSG_INDEX(reqType)]((void *)funcName, &msg, 0, &msgLen);
|
||||
if (code) {
|
||||
ctgError("Build get udf msg failed, code:%x, db:%s", code, funcName);
|
||||
CTG_ERR_RET(code);
|
||||
}
|
||||
|
||||
if (pTask) {
|
||||
void* pOut = taosMemoryCalloc(1, sizeof(SFuncInfo));
|
||||
if (NULL == pOut) {
|
||||
CTG_ERR_RET(TSDB_CODE_OUT_OF_MEMORY);
|
||||
}
|
||||
CTG_ERR_RET(ctgUpdateMsgCtx(&pTask->msgCtx, reqType, pOut, (char*)funcName));
|
||||
|
||||
CTG_RET(ctgAsyncSendMsg(CTG_PARAMS_LIST(), pTask, reqType, msg, msgLen));
|
||||
}
|
||||
|
||||
SRpcMsg rpcMsg = {
|
||||
.msgType = reqType,
|
||||
.pCont = msg,
|
||||
.contLen = msgLen,
|
||||
};
|
||||
|
||||
SRpcMsg rpcRsp = {0};
|
||||
rpcSendRecv(pTrans, (SEpSet*)pMgmtEps, &rpcMsg, &rpcRsp);
|
||||
|
||||
CTG_ERR_RET(ctgProcessRspMsg(out, reqType, rpcRsp.pCont, rpcRsp.contLen, rpcRsp.code, (char*)funcName));
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t ctgGetUserDbAuthFromMnode(CTG_PARAMS, const char *user, SGetUserAuthRsp *out, SCtgTask* pTask) {
|
||||
char *msg = NULL;
|
||||
int32_t msgLen = 0;
|
||||
int32_t reqType = TDMT_MND_GET_USER_AUTH;
|
||||
|
||||
ctgDebug("try to get user auth from mnode, user:%s", user);
|
||||
|
||||
int32_t code = queryBuildMsg[TMSG_INDEX(reqType)]((void *)user, &msg, 0, &msgLen);
|
||||
if (code) {
|
||||
ctgError("Build get user auth msg failed, code:%x, db:%s", code, user);
|
||||
CTG_ERR_RET(code);
|
||||
}
|
||||
|
||||
if (pTask) {
|
||||
void* pOut = taosMemoryCalloc(1, sizeof(SGetUserAuthRsp));
|
||||
if (NULL == pOut) {
|
||||
CTG_ERR_RET(TSDB_CODE_OUT_OF_MEMORY);
|
||||
}
|
||||
CTG_ERR_RET(ctgUpdateMsgCtx(&pTask->msgCtx, reqType, pOut, (char*)user));
|
||||
|
||||
CTG_RET(ctgAsyncSendMsg(CTG_PARAMS_LIST(), pTask, reqType, msg, msgLen));
|
||||
}
|
||||
|
||||
SRpcMsg rpcMsg = {
|
||||
.msgType = reqType,
|
||||
.pCont = msg,
|
||||
.contLen = msgLen,
|
||||
};
|
||||
|
||||
SRpcMsg rpcRsp = {0};
|
||||
rpcSendRecv(pTrans, (SEpSet*)pMgmtEps, &rpcMsg, &rpcRsp);
|
||||
|
||||
CTG_ERR_RET(ctgProcessRspMsg(out, reqType, rpcRsp.pCont, rpcRsp.contLen, rpcRsp.code, (char*)user));
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int32_t ctgGetTbMetaFromMnodeImpl(CTG_PARAMS, char *dbFName, char* tbName, STableMetaOutput* out, SCtgTask* pTask) {
|
||||
SBuildTableMetaInput bInput = {.vgId = 0, .dbFName = dbFName, .tbName = tbName};
|
||||
char *msg = NULL;
|
||||
SEpSet *pVnodeEpSet = NULL;
|
||||
int32_t msgLen = 0;
|
||||
int32_t reqType = TDMT_MND_TABLE_META;
|
||||
char tbFName[TSDB_TABLE_FNAME_LEN];
|
||||
sprintf(tbFName, "%s.%s", dbFName, tbName);
|
||||
|
||||
ctgDebug("try to get table meta from mnode, tbFName:%s", tbFName);
|
||||
|
||||
int32_t code = queryBuildMsg[TMSG_INDEX(reqType)](&bInput, &msg, 0, &msgLen);
|
||||
if (code) {
|
||||
ctgError("Build mnode stablemeta msg failed, code:%x", code);
|
||||
CTG_ERR_RET(code);
|
||||
}
|
||||
|
||||
if (pTask) {
|
||||
void* pOut = taosMemoryCalloc(1, sizeof(STableMetaOutput));
|
||||
if (NULL == pOut) {
|
||||
CTG_ERR_RET(TSDB_CODE_OUT_OF_MEMORY);
|
||||
}
|
||||
CTG_ERR_RET(ctgUpdateMsgCtx(&pTask->msgCtx, reqType, pOut, tbFName));
|
||||
|
||||
CTG_RET(ctgAsyncSendMsg(CTG_PARAMS_LIST(), pTask, reqType, msg, msgLen));
|
||||
}
|
||||
|
||||
SRpcMsg rpcMsg = {
|
||||
.msgType = reqType,
|
||||
.pCont = msg,
|
||||
.contLen = msgLen,
|
||||
};
|
||||
|
||||
SRpcMsg rpcRsp = {0};
|
||||
rpcSendRecv(pTrans, (SEpSet*)pMgmtEps, &rpcMsg, &rpcRsp);
|
||||
|
||||
CTG_ERR_RET(ctgProcessRspMsg(out, reqType, rpcRsp.pCont, rpcRsp.contLen, rpcRsp.code, tbFName));
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t ctgGetTbMetaFromMnode(CTG_PARAMS, const SName* pTableName, STableMetaOutput* out, SCtgTask* pTask) {
|
||||
char dbFName[TSDB_DB_FNAME_LEN];
|
||||
tNameGetFullDbName(pTableName, dbFName);
|
||||
|
||||
return ctgGetTbMetaFromMnodeImpl(CTG_PARAMS_LIST(), dbFName, (char *)pTableName->tname, out, pTask);
|
||||
}
|
||||
|
||||
int32_t ctgGetTbMetaFromVnode(CTG_PARAMS, const SName* pTableName, SVgroupInfo *vgroupInfo, STableMetaOutput* out, SCtgTask* pTask) {
|
||||
char dbFName[TSDB_DB_FNAME_LEN];
|
||||
tNameGetFullDbName(pTableName, dbFName);
|
||||
int32_t reqType = TDMT_VND_TABLE_META;
|
||||
char tbFName[TSDB_TABLE_FNAME_LEN];
|
||||
sprintf(tbFName, "%s.%s", dbFName, pTableName->tname);
|
||||
|
||||
ctgDebug("try to get table meta from vnode, vgId:%d, tbFName:%s", vgroupInfo->vgId, tbFName);
|
||||
|
||||
SBuildTableMetaInput bInput = {.vgId = vgroupInfo->vgId, .dbFName = dbFName, .tbName = (char *)tNameGetTableName(pTableName)};
|
||||
char *msg = NULL;
|
||||
int32_t msgLen = 0;
|
||||
|
||||
int32_t code = queryBuildMsg[TMSG_INDEX(reqType)](&bInput, &msg, 0, &msgLen);
|
||||
if (code) {
|
||||
ctgError("Build vnode tablemeta msg failed, code:%x, tbFName:%s", code, tbFName);
|
||||
CTG_ERR_RET(code);
|
||||
}
|
||||
|
||||
if (pTask) {
|
||||
void* pOut = taosMemoryCalloc(1, sizeof(STableMetaOutput));
|
||||
if (NULL == pOut) {
|
||||
CTG_ERR_RET(TSDB_CODE_OUT_OF_MEMORY);
|
||||
}
|
||||
CTG_ERR_RET(ctgUpdateMsgCtx(&pTask->msgCtx, reqType, pOut, tbFName));
|
||||
|
||||
CTG_RET(ctgAsyncSendMsg(CTG_PARAMS_LIST(), pTask, reqType, msg, msgLen));
|
||||
}
|
||||
|
||||
SRpcMsg rpcMsg = {
|
||||
.msgType = reqType,
|
||||
.pCont = msg,
|
||||
.contLen = msgLen,
|
||||
};
|
||||
|
||||
SRpcMsg rpcRsp = {0};
|
||||
rpcSendRecv(pTrans, &vgroupInfo->epSet, &rpcMsg, &rpcRsp);
|
||||
|
||||
CTG_ERR_RET(ctgProcessRspMsg(out, reqType, rpcRsp.pCont, rpcRsp.contLen, rpcRsp.code, tbFName));
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,577 @@
|
|||
/*
|
||||
* 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 "trpc.h"
|
||||
#include "query.h"
|
||||
#include "tname.h"
|
||||
#include "catalogInt.h"
|
||||
#include "systable.h"
|
||||
|
||||
void ctgFreeSMetaData(SMetaData* pData) {
|
||||
taosArrayDestroy(pData->pTableMeta);
|
||||
pData->pTableMeta = NULL;
|
||||
|
||||
for (int32_t i = 0; i < taosArrayGetSize(pData->pDbVgroup); ++i) {
|
||||
SArray** pArray = taosArrayGet(pData->pDbVgroup, i);
|
||||
taosArrayDestroy(*pArray);
|
||||
}
|
||||
taosArrayDestroy(pData->pDbVgroup);
|
||||
pData->pDbVgroup = NULL;
|
||||
|
||||
taosArrayDestroy(pData->pTableHash);
|
||||
pData->pTableHash = NULL;
|
||||
|
||||
taosArrayDestroy(pData->pUdfList);
|
||||
pData->pUdfList = NULL;
|
||||
|
||||
for (int32_t i = 0; i < taosArrayGetSize(pData->pDbCfg); ++i) {
|
||||
SDbCfgInfo* pInfo = taosArrayGet(pData->pDbCfg, i);
|
||||
taosArrayDestroy(pInfo->pRetensions);
|
||||
}
|
||||
taosArrayDestroy(pData->pDbCfg);
|
||||
pData->pDbCfg = NULL;
|
||||
|
||||
taosArrayDestroy(pData->pIndex);
|
||||
pData->pIndex = NULL;
|
||||
|
||||
taosArrayDestroy(pData->pUser);
|
||||
pData->pUser = NULL;
|
||||
|
||||
taosArrayDestroy(pData->pQnodeList);
|
||||
pData->pQnodeList = NULL;
|
||||
}
|
||||
|
||||
void ctgFreeSCtgUserAuth(SCtgUserAuth *userCache) {
|
||||
taosHashCleanup(userCache->createdDbs);
|
||||
taosHashCleanup(userCache->readDbs);
|
||||
taosHashCleanup(userCache->writeDbs);
|
||||
}
|
||||
|
||||
void ctgFreeMetaRent(SCtgRentMgmt *mgmt) {
|
||||
if (NULL == mgmt->slots) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < mgmt->slotNum; ++i) {
|
||||
SCtgRentSlot *slot = &mgmt->slots[i];
|
||||
if (slot->meta) {
|
||||
taosArrayDestroy(slot->meta);
|
||||
slot->meta = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
taosMemoryFreeClear(mgmt->slots);
|
||||
}
|
||||
|
||||
|
||||
void ctgFreeTbMetaCache(SCtgTbMetaCache *cache) {
|
||||
CTG_LOCK(CTG_WRITE, &cache->stbLock);
|
||||
if (cache->stbCache) {
|
||||
int32_t stblNum = taosHashGetSize(cache->stbCache);
|
||||
taosHashCleanup(cache->stbCache);
|
||||
cache->stbCache = NULL;
|
||||
CTG_CACHE_STAT_SUB(stblNum, stblNum);
|
||||
}
|
||||
CTG_UNLOCK(CTG_WRITE, &cache->stbLock);
|
||||
|
||||
CTG_LOCK(CTG_WRITE, &cache->metaLock);
|
||||
if (cache->metaCache) {
|
||||
int32_t tblNum = taosHashGetSize(cache->metaCache);
|
||||
taosHashCleanup(cache->metaCache);
|
||||
cache->metaCache = NULL;
|
||||
CTG_CACHE_STAT_SUB(tblNum, tblNum);
|
||||
}
|
||||
CTG_UNLOCK(CTG_WRITE, &cache->metaLock);
|
||||
}
|
||||
|
||||
void ctgFreeVgInfo(SDBVgInfo *vgInfo) {
|
||||
if (NULL == vgInfo) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (vgInfo->vgHash) {
|
||||
taosHashCleanup(vgInfo->vgHash);
|
||||
vgInfo->vgHash = NULL;
|
||||
}
|
||||
|
||||
taosMemoryFreeClear(vgInfo);
|
||||
}
|
||||
|
||||
void ctgFreeDbCache(SCtgDBCache *dbCache) {
|
||||
if (NULL == dbCache) {
|
||||
return;
|
||||
}
|
||||
|
||||
CTG_LOCK(CTG_WRITE, &dbCache->vgLock);
|
||||
ctgFreeVgInfo (dbCache->vgInfo);
|
||||
CTG_UNLOCK(CTG_WRITE, &dbCache->vgLock);
|
||||
|
||||
ctgFreeTbMetaCache(&dbCache->tbCache);
|
||||
}
|
||||
|
||||
|
||||
void ctgFreeHandle(SCatalog* pCtg) {
|
||||
ctgFreeMetaRent(&pCtg->dbRent);
|
||||
ctgFreeMetaRent(&pCtg->stbRent);
|
||||
|
||||
if (pCtg->dbCache) {
|
||||
int32_t dbNum = taosHashGetSize(pCtg->dbCache);
|
||||
|
||||
void *pIter = taosHashIterate(pCtg->dbCache, NULL);
|
||||
while (pIter) {
|
||||
SCtgDBCache *dbCache = pIter;
|
||||
|
||||
atomic_store_8(&dbCache->deleted, 1);
|
||||
|
||||
ctgFreeDbCache(dbCache);
|
||||
|
||||
pIter = taosHashIterate(pCtg->dbCache, pIter);
|
||||
}
|
||||
|
||||
taosHashCleanup(pCtg->dbCache);
|
||||
|
||||
CTG_CACHE_STAT_SUB(dbNum, dbNum);
|
||||
}
|
||||
|
||||
if (pCtg->userCache) {
|
||||
int32_t userNum = taosHashGetSize(pCtg->userCache);
|
||||
|
||||
void *pIter = taosHashIterate(pCtg->userCache, NULL);
|
||||
while (pIter) {
|
||||
SCtgUserAuth *userCache = pIter;
|
||||
|
||||
ctgFreeSCtgUserAuth(userCache);
|
||||
|
||||
pIter = taosHashIterate(pCtg->userCache, pIter);
|
||||
}
|
||||
|
||||
taosHashCleanup(pCtg->userCache);
|
||||
|
||||
CTG_CACHE_STAT_SUB(userNum, userNum);
|
||||
}
|
||||
|
||||
taosMemoryFree(pCtg);
|
||||
}
|
||||
|
||||
|
||||
void ctgFreeSUseDbOutput(SUseDbOutput* pOutput) {
|
||||
if (NULL == pOutput || NULL == pOutput->dbVgroup) {
|
||||
return;
|
||||
}
|
||||
|
||||
taosHashCleanup(pOutput->dbVgroup->vgHash);
|
||||
taosMemoryFreeClear(pOutput->dbVgroup);
|
||||
taosMemoryFree(pOutput);
|
||||
}
|
||||
|
||||
void ctgFreeMsgCtx(SCtgMsgCtx* pCtx) {
|
||||
taosMemoryFreeClear(pCtx->target);
|
||||
if (NULL == pCtx->out) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (pCtx->reqType) {
|
||||
case TDMT_MND_GET_DB_CFG: {
|
||||
SDbCfgInfo* pOut = (SDbCfgInfo*)pCtx->out;
|
||||
taosArrayDestroy(pOut->pRetensions);
|
||||
taosMemoryFreeClear(pCtx->out);
|
||||
break;
|
||||
}
|
||||
case TDMT_MND_USE_DB:{
|
||||
SUseDbOutput* pOut = (SUseDbOutput*)pCtx->out;
|
||||
ctgFreeSUseDbOutput(pOut);
|
||||
pCtx->out = NULL;
|
||||
break;
|
||||
}
|
||||
case TDMT_MND_GET_INDEX: {
|
||||
SIndexInfo* pOut = (SIndexInfo*)pCtx->out;
|
||||
taosMemoryFreeClear(pCtx->out);
|
||||
break;
|
||||
}
|
||||
case TDMT_MND_QNODE_LIST: {
|
||||
SArray* pOut = (SArray*)pCtx->out;
|
||||
taosArrayDestroy(pOut);
|
||||
pCtx->out = NULL;
|
||||
break;
|
||||
}
|
||||
case TDMT_VND_TABLE_META:
|
||||
case TDMT_MND_TABLE_META: {
|
||||
STableMetaOutput* pOut = (STableMetaOutput*)pCtx->out;
|
||||
taosMemoryFree(pOut->tbMeta);
|
||||
taosMemoryFreeClear(pCtx->out);
|
||||
break;
|
||||
}
|
||||
case TDMT_MND_RETRIEVE_FUNC: {
|
||||
SFuncInfo* pOut = (SFuncInfo*)pCtx->out;
|
||||
taosMemoryFree(pOut->pCode);
|
||||
taosMemoryFree(pOut->pComment);
|
||||
taosMemoryFreeClear(pCtx->out);
|
||||
break;
|
||||
}
|
||||
case TDMT_MND_GET_USER_AUTH: {
|
||||
SGetUserAuthRsp* pOut = (SGetUserAuthRsp*)pCtx->out;
|
||||
taosHashCleanup(pOut->createdDbs);
|
||||
taosHashCleanup(pOut->readDbs);
|
||||
taosHashCleanup(pOut->writeDbs);
|
||||
taosMemoryFreeClear(pCtx->out);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
qError("invalid reqType %d", pCtx->reqType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ctgFreeSTableMetaOutput(STableMetaOutput* pOutput) {
|
||||
if (NULL == pOutput) {
|
||||
return;
|
||||
}
|
||||
|
||||
taosMemoryFree(pOutput->tbMeta);
|
||||
taosMemoryFree(pOutput);
|
||||
}
|
||||
|
||||
|
||||
void ctgResetTbMetaTask(SCtgTask* pTask) {
|
||||
SCtgTbMetaCtx* taskCtx = (SCtgTbMetaCtx*)pTask->taskCtx;
|
||||
memset(&taskCtx->tbInfo, 0, sizeof(taskCtx->tbInfo));
|
||||
taskCtx->flag = CTG_FLAG_UNKNOWN_STB;
|
||||
|
||||
if (pTask->msgCtx.lastOut) {
|
||||
ctgFreeSTableMetaOutput((STableMetaOutput*)pTask->msgCtx.lastOut);
|
||||
pTask->msgCtx.lastOut = NULL;
|
||||
}
|
||||
if (pTask->msgCtx.out) {
|
||||
ctgFreeSTableMetaOutput((STableMetaOutput*)pTask->msgCtx.out);
|
||||
pTask->msgCtx.out = NULL;
|
||||
}
|
||||
taosMemoryFreeClear(pTask->msgCtx.target);
|
||||
taosMemoryFreeClear(pTask->res);
|
||||
}
|
||||
|
||||
void ctgFreeTask(SCtgTask* pTask) {
|
||||
ctgFreeMsgCtx(&pTask->msgCtx);
|
||||
|
||||
switch (pTask->type) {
|
||||
case CTG_TASK_GET_QNODE: {
|
||||
taosArrayDestroy((SArray*)pTask->res);
|
||||
pTask->res = NULL;
|
||||
break;
|
||||
}
|
||||
case CTG_TASK_GET_TB_META: {
|
||||
SCtgTbMetaCtx* taskCtx = (SCtgTbMetaCtx*)pTask->taskCtx;
|
||||
taosMemoryFreeClear(taskCtx->pName);
|
||||
if (pTask->msgCtx.lastOut) {
|
||||
ctgFreeSTableMetaOutput((STableMetaOutput*)pTask->msgCtx.lastOut);
|
||||
pTask->msgCtx.lastOut = NULL;
|
||||
}
|
||||
taosMemoryFreeClear(pTask->res);
|
||||
break;
|
||||
}
|
||||
case CTG_TASK_GET_DB_VGROUP: {
|
||||
taosArrayDestroy((SArray*)pTask->res);
|
||||
pTask->res = NULL;
|
||||
break;
|
||||
}
|
||||
case CTG_TASK_GET_DB_CFG: {
|
||||
if (pTask->res) {
|
||||
taosArrayDestroy(((SDbCfgInfo*)pTask->res)->pRetensions);
|
||||
taosMemoryFreeClear(pTask->res);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CTG_TASK_GET_TB_HASH: {
|
||||
SCtgTbHashCtx* taskCtx = (SCtgTbHashCtx*)pTask->taskCtx;
|
||||
taosMemoryFreeClear(taskCtx->pName);
|
||||
taosMemoryFreeClear(pTask->res);
|
||||
break;
|
||||
}
|
||||
case CTG_TASK_GET_INDEX: {
|
||||
taosMemoryFreeClear(pTask->taskCtx);
|
||||
taosMemoryFreeClear(pTask->res);
|
||||
break;
|
||||
}
|
||||
case CTG_TASK_GET_UDF: {
|
||||
taosMemoryFreeClear(pTask->taskCtx);
|
||||
taosMemoryFreeClear(pTask->res);
|
||||
break;
|
||||
}
|
||||
case CTG_TASK_GET_USER: {
|
||||
taosMemoryFreeClear(pTask->taskCtx);
|
||||
taosMemoryFreeClear(pTask->res);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
qError("invalid task type %d", pTask->type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ctgFreeTasks(SArray* pArray) {
|
||||
if (NULL == pArray) {
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t num = taosArrayGetSize(pArray);
|
||||
for (int32_t i = 0; i < num; ++i) {
|
||||
SCtgTask* pTask = taosArrayGet(pArray, i);
|
||||
ctgFreeTask(pTask);
|
||||
}
|
||||
|
||||
taosArrayDestroy(pArray);
|
||||
}
|
||||
|
||||
void ctgFreeJob(void* job) {
|
||||
if (NULL == job) {
|
||||
return;
|
||||
}
|
||||
|
||||
SCtgJob* pJob = (SCtgJob*)job;
|
||||
|
||||
int64_t rid = pJob->refId;
|
||||
uint64_t qid = pJob->queryId;
|
||||
|
||||
ctgFreeTasks(pJob->pTasks);
|
||||
|
||||
ctgFreeSMetaData(&pJob->jobRes);
|
||||
|
||||
taosMemoryFree(job);
|
||||
|
||||
qDebug("QID:%" PRIx64 ", job %" PRIx64 " freed", qid, rid);
|
||||
}
|
||||
|
||||
int32_t ctgUpdateMsgCtx(SCtgMsgCtx* pCtx, int32_t reqType, void* out, char* target) {
|
||||
ctgFreeMsgCtx(pCtx);
|
||||
|
||||
pCtx->reqType = reqType;
|
||||
pCtx->out = out;
|
||||
if (target) {
|
||||
pCtx->target = strdup(target);
|
||||
if (NULL == pCtx->target) {
|
||||
CTG_ERR_RET(TSDB_CODE_OUT_OF_MEMORY);
|
||||
}
|
||||
} else {
|
||||
pCtx->target = NULL;
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int32_t ctgGetHashFunction(int8_t hashMethod, tableNameHashFp *fp) {
|
||||
switch (hashMethod) {
|
||||
default:
|
||||
*fp = MurmurHash3_32;
|
||||
break;
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t ctgGenerateVgList(SCatalog *pCtg, SHashObj *vgHash, SArray** pList) {
|
||||
SHashObj *vgroupHash = NULL;
|
||||
SVgroupInfo *vgInfo = NULL;
|
||||
SArray *vgList = NULL;
|
||||
int32_t code = 0;
|
||||
int32_t vgNum = taosHashGetSize(vgHash);
|
||||
|
||||
vgList = taosArrayInit(vgNum, sizeof(SVgroupInfo));
|
||||
if (NULL == vgList) {
|
||||
ctgError("taosArrayInit failed, num:%d", vgNum);
|
||||
CTG_ERR_RET(TSDB_CODE_CTG_MEM_ERROR);
|
||||
}
|
||||
|
||||
void *pIter = taosHashIterate(vgHash, NULL);
|
||||
while (pIter) {
|
||||
vgInfo = pIter;
|
||||
|
||||
if (NULL == taosArrayPush(vgList, vgInfo)) {
|
||||
ctgError("taosArrayPush failed, vgId:%d", vgInfo->vgId);
|
||||
taosHashCancelIterate(vgHash, pIter);
|
||||
CTG_ERR_JRET(TSDB_CODE_CTG_MEM_ERROR);
|
||||
}
|
||||
|
||||
pIter = taosHashIterate(vgHash, pIter);
|
||||
vgInfo = NULL;
|
||||
}
|
||||
|
||||
*pList = vgList;
|
||||
|
||||
ctgDebug("Got vgList from cache, vgNum:%d", vgNum);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
||||
_return:
|
||||
|
||||
if (vgList) {
|
||||
taosArrayDestroy(vgList);
|
||||
}
|
||||
|
||||
CTG_RET(code);
|
||||
}
|
||||
|
||||
|
||||
int32_t ctgGetVgInfoFromHashValue(SCatalog *pCtg, SDBVgInfo *dbInfo, const SName *pTableName, SVgroupInfo *pVgroup) {
|
||||
int32_t code = 0;
|
||||
|
||||
int32_t vgNum = taosHashGetSize(dbInfo->vgHash);
|
||||
char db[TSDB_DB_FNAME_LEN] = {0};
|
||||
tNameGetFullDbName(pTableName, db);
|
||||
|
||||
if (vgNum <= 0) {
|
||||
ctgError("db vgroup cache invalid, db:%s, vgroup number:%d", db, vgNum);
|
||||
CTG_ERR_RET(TSDB_CODE_TSC_DB_NOT_SELECTED);
|
||||
}
|
||||
|
||||
tableNameHashFp fp = NULL;
|
||||
SVgroupInfo *vgInfo = NULL;
|
||||
|
||||
CTG_ERR_RET(ctgGetHashFunction(dbInfo->hashMethod, &fp));
|
||||
|
||||
char tbFullName[TSDB_TABLE_FNAME_LEN];
|
||||
tNameExtractFullName(pTableName, tbFullName);
|
||||
|
||||
uint32_t hashValue = (*fp)(tbFullName, (uint32_t)strlen(tbFullName));
|
||||
|
||||
void *pIter = taosHashIterate(dbInfo->vgHash, NULL);
|
||||
while (pIter) {
|
||||
vgInfo = pIter;
|
||||
if (hashValue >= vgInfo->hashBegin && hashValue <= vgInfo->hashEnd) {
|
||||
taosHashCancelIterate(dbInfo->vgHash, pIter);
|
||||
break;
|
||||
}
|
||||
|
||||
pIter = taosHashIterate(dbInfo->vgHash, pIter);
|
||||
vgInfo = NULL;
|
||||
}
|
||||
|
||||
if (NULL == vgInfo) {
|
||||
ctgError("no hash range found for hash value [%u], db:%s, numOfVgId:%d", hashValue, db, taosHashGetSize(dbInfo->vgHash));
|
||||
CTG_ERR_RET(TSDB_CODE_CTG_INTERNAL_ERROR);
|
||||
}
|
||||
|
||||
*pVgroup = *vgInfo;
|
||||
|
||||
CTG_RET(code);
|
||||
}
|
||||
|
||||
int32_t ctgStbVersionSearchCompare(const void* key1, const void* key2) {
|
||||
if (*(uint64_t *)key1 < ((SSTableMetaVersion*)key2)->suid) {
|
||||
return -1;
|
||||
} else if (*(uint64_t *)key1 > ((SSTableMetaVersion*)key2)->suid) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t ctgDbVgVersionSearchCompare(const void* key1, const void* key2) {
|
||||
if (*(int64_t *)key1 < ((SDbVgVersion*)key2)->dbId) {
|
||||
return -1;
|
||||
} else if (*(int64_t *)key1 > ((SDbVgVersion*)key2)->dbId) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t ctgStbVersionSortCompare(const void* key1, const void* key2) {
|
||||
if (((SSTableMetaVersion*)key1)->suid < ((SSTableMetaVersion*)key2)->suid) {
|
||||
return -1;
|
||||
} else if (((SSTableMetaVersion*)key1)->suid > ((SSTableMetaVersion*)key2)->suid) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t ctgDbVgVersionSortCompare(const void* key1, const void* key2) {
|
||||
if (((SDbVgVersion*)key1)->dbId < ((SDbVgVersion*)key2)->dbId) {
|
||||
return -1;
|
||||
} else if (((SDbVgVersion*)key1)->dbId > ((SDbVgVersion*)key2)->dbId) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int32_t ctgCloneVgInfo(SDBVgInfo *src, SDBVgInfo **dst) {
|
||||
*dst = taosMemoryMalloc(sizeof(SDBVgInfo));
|
||||
if (NULL == *dst) {
|
||||
qError("malloc %d failed", (int32_t)sizeof(SDBVgInfo));
|
||||
CTG_ERR_RET(TSDB_CODE_CTG_MEM_ERROR);
|
||||
}
|
||||
|
||||
memcpy(*dst, src, sizeof(SDBVgInfo));
|
||||
|
||||
size_t hashSize = taosHashGetSize(src->vgHash);
|
||||
(*dst)->vgHash = taosHashInit(hashSize, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_ENTRY_LOCK);
|
||||
if (NULL == (*dst)->vgHash) {
|
||||
qError("taosHashInit %d failed", (int32_t)hashSize);
|
||||
taosMemoryFreeClear(*dst);
|
||||
CTG_ERR_RET(TSDB_CODE_CTG_MEM_ERROR);
|
||||
}
|
||||
|
||||
int32_t *vgId = NULL;
|
||||
void *pIter = taosHashIterate(src->vgHash, NULL);
|
||||
while (pIter) {
|
||||
vgId = taosHashGetKey(pIter, NULL);
|
||||
|
||||
if (taosHashPut((*dst)->vgHash, (void *)vgId, sizeof(int32_t), pIter, sizeof(SVgroupInfo))) {
|
||||
qError("taosHashPut failed, hashSize:%d", (int32_t)hashSize);
|
||||
taosHashCancelIterate(src->vgHash, pIter);
|
||||
taosHashCleanup((*dst)->vgHash);
|
||||
taosMemoryFreeClear(*dst);
|
||||
CTG_ERR_RET(TSDB_CODE_CTG_MEM_ERROR);
|
||||
}
|
||||
|
||||
pIter = taosHashIterate(src->vgHash, pIter);
|
||||
}
|
||||
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int32_t ctgCloneMetaOutput(STableMetaOutput *output, STableMetaOutput **pOutput) {
|
||||
*pOutput = taosMemoryMalloc(sizeof(STableMetaOutput));
|
||||
if (NULL == *pOutput) {
|
||||
qError("malloc %d failed", (int32_t)sizeof(STableMetaOutput));
|
||||
CTG_ERR_RET(TSDB_CODE_CTG_MEM_ERROR);
|
||||
}
|
||||
|
||||
memcpy(*pOutput, output, sizeof(STableMetaOutput));
|
||||
|
||||
if (output->tbMeta) {
|
||||
int32_t metaSize = CTG_META_SIZE(output->tbMeta);
|
||||
(*pOutput)->tbMeta = taosMemoryMalloc(metaSize);
|
||||
if (NULL == (*pOutput)->tbMeta) {
|
||||
qError("malloc %d failed", (int32_t)sizeof(STableMetaOutput));
|
||||
taosMemoryFreeClear(*pOutput);
|
||||
CTG_ERR_RET(TSDB_CODE_CTG_MEM_ERROR);
|
||||
}
|
||||
|
||||
memcpy((*pOutput)->tbMeta, output->tbMeta, metaSize);
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -40,10 +40,8 @@
|
|||
|
||||
namespace {
|
||||
|
||||
extern "C" int32_t ctgGetTableMetaFromCache(struct SCatalog *pCatalog, const SName *pTableName, STableMeta **pTableMeta,
|
||||
bool *inCache, int32_t flag, uint64_t *dbId);
|
||||
extern "C" int32_t ctgdGetClusterCacheNum(struct SCatalog* pCatalog, int32_t type);
|
||||
extern "C" int32_t ctgActUpdateTbl(SCtgMetaAction *action);
|
||||
extern "C" int32_t ctgActUpdateTb(SCtgMetaAction *action);
|
||||
extern "C" int32_t ctgdEnableDebug(char *option);
|
||||
extern "C" int32_t ctgdGetStatNum(char *option, void *res);
|
||||
|
||||
|
@ -52,7 +50,7 @@ void ctgTestSetRspCTableMeta();
|
|||
void ctgTestSetRspSTableMeta();
|
||||
void ctgTestSetRspMultiSTableMeta();
|
||||
|
||||
extern "C" SCatalogMgmt gCtgMgmt;
|
||||
//extern "C" SCatalogMgmt gCtgMgmt;
|
||||
|
||||
enum {
|
||||
CTGT_RSP_VGINFO = 1,
|
||||
|
@ -859,8 +857,12 @@ void *ctgTestGetCtableMetaThread(void *param) {
|
|||
strcpy(cn.dbname, "db1");
|
||||
strcpy(cn.tname, ctgTestCTablename);
|
||||
|
||||
SCtgTbMetaCtx ctx = {0};
|
||||
ctx.pName = &cn;
|
||||
ctx.flag = CTG_FLAG_UNKNOWN_STB;
|
||||
|
||||
while (!ctgTestStop) {
|
||||
code = ctgGetTableMetaFromCache(pCtg, &cn, &tbMeta, &inCache, 0, NULL);
|
||||
code = ctgReadTbMetaFromCache(pCtg, &ctx, &tbMeta);
|
||||
if (code || !inCache) {
|
||||
assert(0);
|
||||
}
|
||||
|
@ -899,7 +901,7 @@ void *ctgTestSetCtableMetaThread(void *param) {
|
|||
msg->output = output;
|
||||
action.data = msg;
|
||||
|
||||
code = ctgActUpdateTbl(&action);
|
||||
code = ctgActUpdateTb(&action);
|
||||
if (code) {
|
||||
assert(0);
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ static int32_t getSchemaBytes(const SSchema* pSchema) {
|
|||
case TSDB_DATA_TYPE_BINARY:
|
||||
return (pSchema->bytes - VARSTR_HEADER_SIZE);
|
||||
case TSDB_DATA_TYPE_NCHAR:
|
||||
case TSDB_DATA_TYPE_JSON:
|
||||
return (pSchema->bytes - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE;
|
||||
default:
|
||||
return pSchema->bytes;
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <executorimpl.h>
|
||||
#include "filter.h"
|
||||
#include "function.h"
|
||||
#include "functionMgt.h"
|
||||
|
@ -107,7 +106,7 @@ static void destroyTableQueryInfoImpl(STableQueryInfo* pTableQueryInfo);
|
|||
|
||||
static SColumnInfo* extractColumnFilterInfo(SExprInfo* pExpr, int32_t numOfOutput, int32_t* numOfFilterCols);
|
||||
|
||||
static void releaseQueryBuf(size_t numOfTables);
|
||||
static void releaseQueryBuf(size_t numOfTables);
|
||||
|
||||
static int32_t getNumOfScanTimes(STaskAttr* pQueryAttr);
|
||||
|
||||
|
@ -155,8 +154,9 @@ SOperatorFpSet createOperatorFpSet(__optr_open_fn_t openFn, __optr_fn_t nextFn,
|
|||
|
||||
void operatorDummyCloseFn(void* param, int32_t numOfCols) {}
|
||||
|
||||
static int32_t doCopyToSDataBlock(SExecTaskInfo* taskInfo, SSDataBlock* pBlock, SExprInfo* pExprInfo, SDiskbasedBuf* pBuf, SGroupResInfo* pGroupResInfo,
|
||||
const int32_t* rowCellOffset, SqlFunctionCtx* pCtx, int32_t numOfExprs);
|
||||
static int32_t doCopyToSDataBlock(SExecTaskInfo* taskInfo, SSDataBlock* pBlock, SExprInfo* pExprInfo,
|
||||
SDiskbasedBuf* pBuf, SGroupResInfo* pGroupResInfo, const int32_t* rowCellOffset,
|
||||
SqlFunctionCtx* pCtx, int32_t numOfExprs);
|
||||
|
||||
static void initCtxOutputBuffer(SqlFunctionCtx* pCtx, int32_t size);
|
||||
static void setResultBufSize(STaskAttr* pQueryAttr, SResultInfo* pResultInfo);
|
||||
|
@ -183,10 +183,10 @@ static int compareRowData(const void* a, const void* b, const void* userData) {
|
|||
|
||||
int16_t offset = supporter->dataOffset;
|
||||
return 0;
|
||||
// char* in1 = getPosInResultPage(pRuntimeEnv->pQueryAttr, page1, pRow1->offset, offset);
|
||||
// char* in2 = getPosInResultPage(pRuntimeEnv->pQueryAttr, page2, pRow2->offset, offset);
|
||||
// char* in1 = getPosInResultPage(pRuntimeEnv->pQueryAttr, page1, pRow1->offset, offset);
|
||||
// char* in2 = getPosInResultPage(pRuntimeEnv->pQueryAttr, page2, pRow2->offset, offset);
|
||||
|
||||
// return (in1 != NULL && in2 != NULL) ? supporter->comFunc(in1, in2) : 0;
|
||||
// return (in1 != NULL && in2 != NULL) ? supporter->comFunc(in1, in2) : 0;
|
||||
}
|
||||
|
||||
// setup the output buffer for each operator
|
||||
|
@ -583,8 +583,9 @@ void initExecTimeWindowInfo(SColumnInfoData* pColData, STimeWindow* pQueryWindow
|
|||
colDataAppendInt64(pColData, 4, &pQueryWindow->ekey);
|
||||
}
|
||||
|
||||
void doApplyFunctions(SExecTaskInfo* taskInfo, SqlFunctionCtx* pCtx, STimeWindow* pWin, SColumnInfoData* pTimeWindowData, int32_t offset,
|
||||
int32_t forwardStep, TSKEY* tsCol, int32_t numOfTotal, int32_t numOfOutput, int32_t order) {
|
||||
void doApplyFunctions(SExecTaskInfo* taskInfo, SqlFunctionCtx* pCtx, STimeWindow* pWin,
|
||||
SColumnInfoData* pTimeWindowData, int32_t offset, int32_t forwardStep, TSKEY* tsCol,
|
||||
int32_t numOfTotal, int32_t numOfOutput, int32_t order) {
|
||||
for (int32_t k = 0; k < numOfOutput; ++k) {
|
||||
// keep it temporarily
|
||||
bool hasAgg = pCtx[k].input.colDataAggIsSet;
|
||||
|
@ -666,8 +667,8 @@ static void doSetInputDataBlockInfo(SOperatorInfo* pOperator, SqlFunctionCtx* pC
|
|||
}
|
||||
}
|
||||
|
||||
void setInputDataBlock(SOperatorInfo* pOperator, SqlFunctionCtx* pCtx, SSDataBlock* pBlock, int32_t order, int32_t scanFlag,
|
||||
bool createDummyCol) {
|
||||
void setInputDataBlock(SOperatorInfo* pOperator, SqlFunctionCtx* pCtx, SSDataBlock* pBlock, int32_t order,
|
||||
int32_t scanFlag, bool createDummyCol) {
|
||||
if (pBlock->pBlockAgg != NULL) {
|
||||
doSetInputDataBlockInfo(pOperator, pCtx, pBlock, order);
|
||||
} else {
|
||||
|
@ -718,7 +719,7 @@ static int32_t doCreateConstantValColumnInfo(SInputColumnInfoData* pInput, SFunc
|
|||
}
|
||||
|
||||
static int32_t doSetInputDataBlock(SOperatorInfo* pOperator, SqlFunctionCtx* pCtx, SSDataBlock* pBlock, int32_t order,
|
||||
int32_t scanFlag, bool createDummyCol) {
|
||||
int32_t scanFlag, bool createDummyCol) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
|
||||
for (int32_t i = 0; i < pOperator->numOfExprs; ++i) {
|
||||
|
@ -726,7 +727,7 @@ static int32_t doSetInputDataBlock(SOperatorInfo* pOperator, SqlFunctionCtx* pCt
|
|||
pCtx[i].input.numOfRows = pBlock->info.rows;
|
||||
|
||||
pCtx[i].pSrcBlock = pBlock;
|
||||
pCtx[i].scanFlag = scanFlag;
|
||||
pCtx[i].scanFlag = scanFlag;
|
||||
|
||||
SInputColumnInfoData* pInput = &pCtx[i].input;
|
||||
pInput->uid = pBlock->info.uid;
|
||||
|
@ -835,7 +836,7 @@ int32_t projectApplyFunctions(SExprInfo* pExpr, SSDataBlock* pResult, SSDataBloc
|
|||
SColumnInfoData idata = {.info = pResColData->info, .hasNull = true};
|
||||
|
||||
SScalarParam dest = {.columnData = &idata};
|
||||
int32_t code = scalarCalculate(pExpr[k].pExpr->_optrRoot.pRootNode, pBlockList, &dest);
|
||||
int32_t code = scalarCalculate(pExpr[k].pExpr->_optrRoot.pRootNode, pBlockList, &dest);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
taosArrayDestroy(pBlockList);
|
||||
return code;
|
||||
|
@ -853,7 +854,7 @@ int32_t projectApplyFunctions(SExprInfo* pExpr, SSDataBlock* pResult, SSDataBloc
|
|||
// _rowts/_c0, not tbname column
|
||||
if (fmIsPseudoColumnFunc(pfCtx->functionId) && (!fmIsScanPseudoColumnFunc(pfCtx->functionId))) {
|
||||
// do nothing
|
||||
} else if (fmIsNonstandardSQLFunc(pfCtx->functionId)) {
|
||||
} else if (fmIsIndefiniteRowsFunc(pfCtx->functionId)) {
|
||||
SResultRowEntryInfo* pResInfo = GET_RES_INFO(&pCtx[k]);
|
||||
pfCtx->fpSet.init(&pCtx[k], pResInfo);
|
||||
|
||||
|
@ -951,14 +952,14 @@ static bool functionNeedToExecute(SqlFunctionCtx* pCtx) {
|
|||
return false;
|
||||
}
|
||||
|
||||
// if (functionId == FUNCTION_FIRST_DST || functionId == FUNCTION_FIRST) {
|
||||
// // return QUERY_IS_ASC_QUERY(pQueryAttr);
|
||||
// }
|
||||
//
|
||||
// // denote the order type
|
||||
// if ((functionId == FUNCTION_LAST_DST || functionId == FUNCTION_LAST)) {
|
||||
// // return pCtx->param[0].i == pQueryAttr->order.order;
|
||||
// }
|
||||
// if (functionId == FUNCTION_FIRST_DST || functionId == FUNCTION_FIRST) {
|
||||
// // return QUERY_IS_ASC_QUERY(pQueryAttr);
|
||||
// }
|
||||
//
|
||||
// // denote the order type
|
||||
// if ((functionId == FUNCTION_LAST_DST || functionId == FUNCTION_LAST)) {
|
||||
// // return pCtx->param[0].i == pQueryAttr->order.order;
|
||||
// }
|
||||
|
||||
// in the reverse table scan, only the following functions need to be executed
|
||||
// if (IS_REVERSE_SCAN(pRuntimeEnv) ||
|
||||
|
@ -1073,19 +1074,19 @@ static int32_t setSelectValueColumnInfo(SqlFunctionCtx* pCtx, int32_t numOfOutpu
|
|||
for (int32_t i = 0; i < numOfOutput; ++i) {
|
||||
if (strcmp(pCtx[i].pExpr->pExpr->_function.functionName, "_select_value") == 0) {
|
||||
pValCtx[num++] = &pCtx[i];
|
||||
} else if (fmIsAggFunc(pCtx[i].functionId)) {
|
||||
} else if (fmIsSelectFunc(pCtx[i].functionId)) {
|
||||
p = &pCtx[i];
|
||||
}
|
||||
// if (functionId == FUNCTION_TAG_DUMMY || functionId == FUNCTION_TS_DUMMY) {
|
||||
// tagLen += pCtx[i].resDataInfo.bytes;
|
||||
// pTagCtx[num++] = &pCtx[i];
|
||||
// } else if (functionId == FUNCTION_TS || functionId == FUNCTION_TAG) {
|
||||
// // tag function may be the group by tag column
|
||||
// // ts may be the required primary timestamp column
|
||||
// continue;
|
||||
// } else {
|
||||
// // the column may be the normal column, group by normal_column, the functionId is FUNCTION_PRJ
|
||||
// }
|
||||
// if (functionId == FUNCTION_TAG_DUMMY || functionId == FUNCTION_TS_DUMMY) {
|
||||
// tagLen += pCtx[i].resDataInfo.bytes;
|
||||
// pTagCtx[num++] = &pCtx[i];
|
||||
// } else if (functionId == FUNCTION_TS || functionId == FUNCTION_TAG) {
|
||||
// // tag function may be the group by tag column
|
||||
// // ts may be the required primary timestamp column
|
||||
// continue;
|
||||
// } else {
|
||||
// // the column may be the normal column, group by normal_column, the functionId is FUNCTION_PRJ
|
||||
// }
|
||||
}
|
||||
|
||||
if (p != NULL) {
|
||||
|
@ -1124,7 +1125,7 @@ SqlFunctionCtx* createSqlFunctionCtx(SExprInfo* pExprInfo, int32_t numOfOutput,
|
|||
SFuncExecEnv env = {0};
|
||||
pCtx->functionId = pExpr->pExpr->_function.pFunctNode->funcId;
|
||||
|
||||
if (fmIsAggFunc(pCtx->functionId) || fmIsNonstandardSQLFunc(pCtx->functionId)) {
|
||||
if (fmIsAggFunc(pCtx->functionId) || fmIsIndefiniteRowsFunc(pCtx->functionId)) {
|
||||
bool isUdaf = fmIsUserDefinedFunc(pCtx->functionId);
|
||||
if (!isUdaf) {
|
||||
fmGetFuncExecFuncs(pCtx->functionId, &pCtx->fpSet);
|
||||
|
@ -1883,7 +1884,7 @@ void setResultRowInitCtx(SResultRow* pResult, SqlFunctionCtx* pCtx, int32_t numO
|
|||
}
|
||||
|
||||
static void extractQualifiedTupleByFilterResult(SSDataBlock* pBlock, const int8_t* rowRes, bool keep);
|
||||
void doFilter(const SNode* pFilterNode, SSDataBlock* pBlock, SArray* pColMatchInfo) {
|
||||
void doFilter(const SNode* pFilterNode, SSDataBlock* pBlock, SArray* pColMatchInfo) {
|
||||
if (pFilterNode == NULL) {
|
||||
return;
|
||||
}
|
||||
|
@ -2006,8 +2007,9 @@ static void doUpdateNumOfRows(SResultRow* pRow, int32_t numOfExprs, const int32_
|
|||
}
|
||||
}
|
||||
|
||||
int32_t doCopyToSDataBlock(SExecTaskInfo* pTaskInfo, SSDataBlock* pBlock, SExprInfo* pExprInfo, SDiskbasedBuf* pBuf, SGroupResInfo* pGroupResInfo,
|
||||
const int32_t* rowCellOffset, SqlFunctionCtx* pCtx, int32_t numOfExprs) {
|
||||
int32_t doCopyToSDataBlock(SExecTaskInfo* pTaskInfo, SSDataBlock* pBlock, SExprInfo* pExprInfo, SDiskbasedBuf* pBuf,
|
||||
SGroupResInfo* pGroupResInfo, const int32_t* rowCellOffset, SqlFunctionCtx* pCtx,
|
||||
int32_t numOfExprs) {
|
||||
int32_t numOfRows = getNumOfTotalRes(pGroupResInfo);
|
||||
int32_t start = pGroupResInfo->index;
|
||||
|
||||
|
@ -2056,11 +2058,11 @@ int32_t doCopyToSDataBlock(SExecTaskInfo* pTaskInfo, SSDataBlock* pBlock, SExprI
|
|||
} else {
|
||||
// expand the result into multiple rows. E.g., _wstartts, top(k, 20)
|
||||
// the _wstartts needs to copy to 20 following rows, since the results of top-k expands to 20 different rows.
|
||||
SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, slotId);
|
||||
char* in = GET_ROWCELL_INTERBUF(pCtx[j].resultInfo);
|
||||
for(int32_t k = 0; k < pRow->numOfRows; ++k) {
|
||||
colDataAppend(pColInfoData, pBlock->info.rows + k, in, pCtx[j].resultInfo->isNullRes);
|
||||
}
|
||||
SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, slotId);
|
||||
char* in = GET_ROWCELL_INTERBUF(pCtx[j].resultInfo);
|
||||
for (int32_t k = 0; k < pRow->numOfRows; ++k) {
|
||||
colDataAppend(pColInfoData, pBlock->info.rows + k, in, pCtx[j].resultInfo->isNullRes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2071,14 +2073,16 @@ int32_t doCopyToSDataBlock(SExecTaskInfo* pTaskInfo, SSDataBlock* pBlock, SExprI
|
|||
}
|
||||
}
|
||||
|
||||
qDebug("%s result generated, rows:%d, groupId:%"PRIu64, GET_TASKID(pTaskInfo), pBlock->info.rows, pBlock->info.groupId);
|
||||
qDebug("%s result generated, rows:%d, groupId:%" PRIu64, GET_TASKID(pTaskInfo), pBlock->info.rows,
|
||||
pBlock->info.groupId);
|
||||
blockDataUpdateTsWindow(pBlock, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void doBuildResultDatablock(SOperatorInfo* pOperator, SOptrBasicInfo* pbInfo, SGroupResInfo* pGroupResInfo, SDiskbasedBuf* pBuf) {
|
||||
SExprInfo* pExprInfo = pOperator->pExpr;
|
||||
int32_t numOfExprs = pOperator->numOfExprs;
|
||||
void doBuildResultDatablock(SOperatorInfo* pOperator, SOptrBasicInfo* pbInfo, SGroupResInfo* pGroupResInfo,
|
||||
SDiskbasedBuf* pBuf) {
|
||||
SExprInfo* pExprInfo = pOperator->pExpr;
|
||||
int32_t numOfExprs = pOperator->numOfExprs;
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
|
||||
int32_t* rowCellOffset = pbInfo->rowCellInfoOffset;
|
||||
|
@ -2747,10 +2751,10 @@ int32_t setSDataBlockFromFetchRsp(SSDataBlock* pRes, SLoadRemoteDataInfo* pLoadI
|
|||
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||
SColumnInfoData idata = {0};
|
||||
|
||||
idata.info.type = pSchema[i].type;
|
||||
idata.info.type = pSchema[i].type;
|
||||
idata.info.bytes = pSchema[i].bytes;
|
||||
idata.info.colId = pSchema[i].colId;
|
||||
idata.hasNull = true;
|
||||
idata.hasNull = true;
|
||||
|
||||
taosArrayPush(pBlock->pDataBlock, &idata);
|
||||
if (IS_VAR_DATA_TYPE(idata.info.type)) {
|
||||
|
@ -3100,7 +3104,7 @@ static int32_t initDataSource(int32_t numOfSources, SExchangeInfo* pInfo) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
SOperatorInfo* createExchangeOperatorInfo(void *pTransporter, const SNodeList* pSources, SSDataBlock* pBlock,
|
||||
SOperatorInfo* createExchangeOperatorInfo(void* pTransporter, const SNodeList* pSources, SSDataBlock* pBlock,
|
||||
SExecTaskInfo* pTaskInfo) {
|
||||
SExchangeInfo* pInfo = taosMemoryCalloc(1, sizeof(SExchangeInfo));
|
||||
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
|
||||
|
@ -3213,7 +3217,7 @@ static bool needToMerge(SSDataBlock* pBlock, SArray* groupInfo, char** buf, int3
|
|||
static void doMergeResultImpl(SSortedMergeOperatorInfo* pInfo, SqlFunctionCtx* pCtx, int32_t numOfExpr,
|
||||
int32_t rowIndex) {
|
||||
for (int32_t j = 0; j < numOfExpr; ++j) { // TODO set row index
|
||||
// pCtx[j].startRow = rowIndex;
|
||||
// pCtx[j].startRow = rowIndex;
|
||||
}
|
||||
|
||||
for (int32_t j = 0; j < numOfExpr; ++j) {
|
||||
|
@ -3264,7 +3268,7 @@ static void doMergeImpl(SOperatorInfo* pOperator, int32_t numOfExpr, SSDataBlock
|
|||
|
||||
SqlFunctionCtx* pCtx = pInfo->binfo.pCtx;
|
||||
for (int32_t i = 0; i < pBlock->info.numOfCols; ++i) {
|
||||
// pCtx[i].size = 1;
|
||||
// pCtx[i].size = 1;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < pBlock->info.rows; ++i) {
|
||||
|
@ -3490,10 +3494,11 @@ _error:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
int32_t getTableScanInfo(SOperatorInfo* pOperator, int32_t *order, int32_t* scanFlag) {
|
||||
int32_t getTableScanInfo(SOperatorInfo* pOperator, int32_t* order, int32_t* scanFlag) {
|
||||
// todo add more information about exchange operation
|
||||
int32_t type = pOperator->operatorType;
|
||||
if (type == QUERY_NODE_PHYSICAL_PLAN_EXCHANGE || type == QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN || type == QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN) {
|
||||
if (type == QUERY_NODE_PHYSICAL_PLAN_EXCHANGE || type == QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN ||
|
||||
type == QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN) {
|
||||
*order = TSDB_ORDER_ASC;
|
||||
*scanFlag = MAIN_SCAN;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -3521,7 +3526,7 @@ static int32_t doOpenAggregateOptr(SOperatorInfo* pOperator) {
|
|||
SAggOperatorInfo* pAggInfo = pOperator->info;
|
||||
|
||||
SOptrBasicInfo* pInfo = &pAggInfo->binfo;
|
||||
SOperatorInfo* downstream = pOperator->pDownstream[0];
|
||||
SOperatorInfo* downstream = pOperator->pDownstream[0];
|
||||
|
||||
int32_t order = TSDB_ORDER_ASC;
|
||||
int32_t scanFlag = MAIN_SCAN;
|
||||
|
@ -3860,7 +3865,8 @@ static SSDataBlock* doProjectOperation(SOperatorInfo* pOperator) {
|
|||
setInputDataBlock(pOperator, pInfo->pCtx, pBlock, order, scanFlag, false);
|
||||
blockDataEnsureCapacity(pInfo->pRes, pInfo->pRes->info.rows + pBlock->info.rows);
|
||||
|
||||
code = projectApplyFunctions(pOperator->pExpr, pInfo->pRes, pBlock, pInfo->pCtx, pOperator->numOfExprs, pProjectInfo->pPseudoColInfo);
|
||||
code = projectApplyFunctions(pOperator->pExpr, pInfo->pRes, pBlock, pInfo->pCtx, pOperator->numOfExprs,
|
||||
pProjectInfo->pPseudoColInfo);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
longjmp(pTaskInfo->env, code);
|
||||
}
|
||||
|
@ -4110,7 +4116,7 @@ static STableQueryInfo* initTableQueryInfo(const STableGroupInfo* pTableGroupInf
|
|||
for (int32_t i = 0; i < taosArrayGetSize(pTableGroupInfo->pGroupList); ++i) {
|
||||
SArray* pa = taosArrayGetP(pTableGroupInfo->pGroupList, i);
|
||||
for (int32_t j = 0; j < taosArrayGetSize(pa); ++j) {
|
||||
STableKeyInfo* pk = taosArrayGet(pa, j);
|
||||
STableKeyInfo* pk = taosArrayGet(pa, j);
|
||||
STableQueryInfo* pTQueryInfo = &pTableQueryInfo[index++];
|
||||
pTQueryInfo->lastKey = pk->lastKey;
|
||||
}
|
||||
|
@ -4246,9 +4252,9 @@ SOperatorInfo* createProjectOperatorInfo(SOperatorInfo* downstream, SExprInfo* p
|
|||
goto _error;
|
||||
}
|
||||
|
||||
pInfo->limit = *pLimit;
|
||||
pInfo->slimit = *pSlimit;
|
||||
pInfo->curOffset = pLimit->offset;
|
||||
pInfo->limit = *pLimit;
|
||||
pInfo->slimit = *pSlimit;
|
||||
pInfo->curOffset = pLimit->offset;
|
||||
pInfo->curSOffset = pSlimit->offset;
|
||||
|
||||
pInfo->binfo.pRes = pResBlock;
|
||||
|
@ -4267,15 +4273,15 @@ SOperatorInfo* createProjectOperatorInfo(SOperatorInfo* downstream, SExprInfo* p
|
|||
initAggInfo(&pInfo->binfo, &pInfo->aggSup, pExprInfo, numOfCols, pResBlock, keyBufSize, pTaskInfo->id.str);
|
||||
setFunctionResultOutput(&pInfo->binfo, &pInfo->aggSup, MAIN_SCAN, numOfCols, pTaskInfo);
|
||||
|
||||
pInfo->pPseudoColInfo = setRowTsColumnOutputInfo(pInfo->binfo.pCtx, numOfCols);
|
||||
pOperator->name = "ProjectOperator";
|
||||
pInfo->pPseudoColInfo = setRowTsColumnOutputInfo(pInfo->binfo.pCtx, numOfCols);
|
||||
pOperator->name = "ProjectOperator";
|
||||
pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_PROJECT;
|
||||
pOperator->blocking = false;
|
||||
pOperator->status = OP_NOT_OPENED;
|
||||
pOperator->info = pInfo;
|
||||
pOperator->pExpr = pExprInfo;
|
||||
pOperator->numOfExprs = num;
|
||||
pOperator->pTaskInfo = pTaskInfo;
|
||||
pOperator->blocking = false;
|
||||
pOperator->status = OP_NOT_OPENED;
|
||||
pOperator->info = pInfo;
|
||||
pOperator->pExpr = pExprInfo;
|
||||
pOperator->numOfExprs = num;
|
||||
pOperator->pTaskInfo = pTaskInfo;
|
||||
|
||||
pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doProjectOperation, NULL, NULL,
|
||||
destroyProjectOperatorInfo, NULL, NULL, NULL);
|
||||
|
@ -4394,10 +4400,10 @@ static SColumn* createColumn(int32_t blockId, int32_t slotId, int32_t colId, SDa
|
|||
}
|
||||
|
||||
pCol->slotId = slotId;
|
||||
pCol->colId = colId;
|
||||
pCol->bytes = pType->bytes;
|
||||
pCol->type = pType->type;
|
||||
pCol->scale = pType->scale;
|
||||
pCol->colId = colId;
|
||||
pCol->bytes = pType->bytes;
|
||||
pCol->type = pType->type;
|
||||
pCol->scale = pType->scale;
|
||||
pCol->precision = pType->precision;
|
||||
pCol->dataBlockId = blockId;
|
||||
|
||||
|
@ -4472,10 +4478,10 @@ SExprInfo* createExprInfo(SNodeList* pNodeList, SNodeList* pGroupKeys, int32_t*
|
|||
if (strcmp(pExp->pExpr->_function.functionName, "tbname") == 0) {
|
||||
pFuncNode->pParameterList = nodesMakeList();
|
||||
ASSERT(LIST_LENGTH(pFuncNode->pParameterList) == 0);
|
||||
SValueNode *res = (SValueNode *)nodesMakeNode(QUERY_NODE_VALUE);
|
||||
if (NULL == res) { // todo handle error
|
||||
SValueNode* res = (SValueNode*)nodesMakeNode(QUERY_NODE_VALUE);
|
||||
if (NULL == res) { // todo handle error
|
||||
} else {
|
||||
res->node.resType = (SDataType) {.bytes = sizeof(int64_t), .type = TSDB_DATA_TYPE_BIGINT};
|
||||
res->node.resType = (SDataType){.bytes = sizeof(int64_t), .type = TSDB_DATA_TYPE_BIGINT};
|
||||
nodesListAppend(pFuncNode->pParameterList, res);
|
||||
}
|
||||
}
|
||||
|
@ -4545,7 +4551,7 @@ static SArray* extractColumnInfo(SNodeList* pNodeList);
|
|||
static SArray* createSortInfo(SNodeList* pNodeList);
|
||||
static SArray* extractPartitionColInfo(SNodeList* pNodeList);
|
||||
|
||||
void extractTableSchemaVersion(SReadHandle *pHandle, uint64_t uid, SExecTaskInfo* pTaskInfo) {
|
||||
void extractTableSchemaVersion(SReadHandle* pHandle, uint64_t uid, SExecTaskInfo* pTaskInfo) {
|
||||
SMetaReader mr = {0};
|
||||
metaReaderInit(&mr, pHandle->meta, 0);
|
||||
metaGetTableEntryByUid(&mr, uid);
|
||||
|
@ -4592,7 +4598,7 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
|
|||
SSDataBlock* pResBlock = createResDataBlock(pExchange->node.pOutputDataBlockDesc);
|
||||
return createExchangeOperatorInfo(pHandle->pMsgCb->clientRpc, pExchange->pSrcEndPoints, pResBlock, pTaskInfo);
|
||||
} else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN == type) {
|
||||
SScanPhysiNode* pScanPhyNode = (SScanPhysiNode*)pPhyNode; // simple child table.
|
||||
SScanPhysiNode* pScanPhyNode = (SScanPhysiNode*)pPhyNode; // simple child table.
|
||||
STableScanPhysiNode* pTableScanNode = (STableScanPhysiNode*)pPhyNode;
|
||||
|
||||
int32_t numOfCols = 0;
|
||||
|
@ -4601,8 +4607,7 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
|
|||
if (pHandle->vnode) {
|
||||
pDataReader = doCreateDataReader(pTableScanNode, pHandle, pTableGroupInfo, (uint64_t)queryId, taskId);
|
||||
} else {
|
||||
doCreateTableGroup(pHandle->meta, pScanPhyNode->tableType, pScanPhyNode->uid, pTableGroupInfo,
|
||||
queryId, taskId);
|
||||
doCreateTableGroup(pHandle->meta, pScanPhyNode->tableType, pScanPhyNode->uid, pTableGroupInfo, queryId, taskId);
|
||||
}
|
||||
|
||||
if (pDataReader == NULL && terrno != 0) {
|
||||
|
@ -4613,15 +4618,17 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
|
|||
}
|
||||
|
||||
SDataBlockDescNode* pDescNode = pScanPhyNode->node.pOutputDataBlockDesc;
|
||||
SOperatorInfo* pOperatorDumy = createTableScanOperatorInfo(pTableScanNode, pDataReader, pHandle, pTaskInfo);
|
||||
SOperatorInfo* pOperatorDumy = createTableScanOperatorInfo(pTableScanNode, pDataReader, pHandle, pTaskInfo);
|
||||
|
||||
SArray* tableIdList = extractTableIdList(pTableGroupInfo);
|
||||
|
||||
SSDataBlock* pResBlock = createResDataBlock(pDescNode);
|
||||
SArray* pCols = extractColMatchInfo(pScanPhyNode->pScanCols, pDescNode, &numOfCols, pTaskInfo, COL_MATCH_FROM_COL_ID);
|
||||
SArray* pCols =
|
||||
extractColMatchInfo(pScanPhyNode->pScanCols, pDescNode, &numOfCols, pTaskInfo, COL_MATCH_FROM_COL_ID);
|
||||
|
||||
SOperatorInfo* pOperator = createStreamScanOperatorInfo(pHandle->reader, pDataReader, pHandle, pScanPhyNode->uid, pResBlock, pCols, tableIdList, pTaskInfo,
|
||||
pScanPhyNode->node.pConditions, pOperatorDumy);
|
||||
SOperatorInfo* pOperator =
|
||||
createStreamScanOperatorInfo(pHandle->reader, pDataReader, pHandle, pScanPhyNode->uid, pResBlock, pCols,
|
||||
tableIdList, pTaskInfo, pScanPhyNode->node.pConditions, pOperatorDumy);
|
||||
taosArrayDestroy(tableIdList);
|
||||
return pOperator;
|
||||
} else if (QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN == type) {
|
||||
|
@ -4633,7 +4640,8 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
|
|||
SSDataBlock* pResBlock = createResDataBlock(pDescNode);
|
||||
|
||||
int32_t numOfOutputCols = 0;
|
||||
SArray* colList = extractColMatchInfo(pScanNode->pScanCols, pDescNode, &numOfOutputCols, pTaskInfo, COL_MATCH_FROM_COL_ID);
|
||||
SArray* colList =
|
||||
extractColMatchInfo(pScanNode->pScanCols, pDescNode, &numOfOutputCols, pTaskInfo, COL_MATCH_FROM_COL_ID);
|
||||
SOperatorInfo* pOperator = createSysTableScanOperatorInfo(
|
||||
pHandle, pResBlock, &pScanNode->tableName, pScanNode->node.pConditions, pSysScanPhyNode->mgmtEpSet, colList,
|
||||
pTaskInfo, pSysScanPhyNode->showRewrite, pSysScanPhyNode->accountId);
|
||||
|
@ -4655,8 +4663,8 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
|
|||
SExprInfo* pExprInfo = createExprInfo(pScanPhyNode->pScanPseudoCols, NULL, &num);
|
||||
|
||||
int32_t numOfOutputCols = 0;
|
||||
SArray* colList =
|
||||
extractColMatchInfo(pScanPhyNode->pScanPseudoCols, pDescNode, &numOfOutputCols, pTaskInfo, COL_MATCH_FROM_COL_ID);
|
||||
SArray* colList = extractColMatchInfo(pScanPhyNode->pScanPseudoCols, pDescNode, &numOfOutputCols, pTaskInfo,
|
||||
COL_MATCH_FROM_COL_ID);
|
||||
|
||||
SOperatorInfo* pOperator =
|
||||
createTagScanOperatorInfo(pHandle, pExprInfo, num, pResBlock, colList, pTableGroupInfo, pTaskInfo);
|
||||
|
@ -4738,7 +4746,8 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
|
|||
SExprInfo* pExprInfo = createExprInfo(pSortPhyNode->pExprs, NULL, &numOfCols);
|
||||
|
||||
int32_t numOfOutputCols = 0;
|
||||
SArray* pColList = extractColMatchInfo(pSortPhyNode->pTargets, pDescNode, &numOfOutputCols, pTaskInfo, COL_MATCH_FROM_SLOT_ID);
|
||||
SArray* pColList =
|
||||
extractColMatchInfo(pSortPhyNode->pTargets, pDescNode, &numOfOutputCols, pTaskInfo, COL_MATCH_FROM_SLOT_ID);
|
||||
|
||||
pOptr = createSortOperatorInfo(ops[0], pResBlock, info, pExprInfo, numOfCols, pColList, pTaskInfo);
|
||||
} else if (QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW == type) {
|
||||
|
@ -4770,7 +4779,7 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
|
|||
int32_t tsSlotId = ((SColumnNode*)pStateNode->window.pTspk)->slotId;
|
||||
|
||||
SColumnNode* pColNode = (SColumnNode*)((STargetNode*)pStateNode->pStateKey)->pExpr;
|
||||
SColumn col = extractColumnFromColumnNode(pColNode);
|
||||
SColumn col = extractColumnFromColumnNode(pColNode);
|
||||
pOptr = createStatewindowOperatorInfo(ops[0], pExprInfo, num, pResBlock, &as, tsSlotId, &col, pTaskInfo);
|
||||
} else if (QUERY_NODE_PHYSICAL_PLAN_JOIN == type) {
|
||||
SJoinPhysiNode* pJoinNode = (SJoinPhysiNode*)pPhyNode;
|
||||
|
@ -4838,11 +4847,11 @@ int32_t initQueryTableDataCond(SQueryTableDataCond* pCond, const STableScanPhysi
|
|||
|
||||
SColumn extractColumnFromColumnNode(SColumnNode* pColNode) {
|
||||
SColumn c = {0};
|
||||
c.slotId = pColNode->slotId;
|
||||
c.colId = pColNode->colId;
|
||||
c.type = pColNode->node.resType.type;
|
||||
c.bytes = pColNode->node.resType.bytes;
|
||||
c.scale = pColNode->node.resType.scale;
|
||||
c.slotId = pColNode->slotId;
|
||||
c.colId = pColNode->colId;
|
||||
c.type = pColNode->node.resType.type;
|
||||
c.bytes = pColNode->node.resType.bytes;
|
||||
c.scale = pColNode->node.resType.scale;
|
||||
c.precision = pColNode->node.resType.precision;
|
||||
return c;
|
||||
}
|
||||
|
@ -5239,15 +5248,15 @@ int32_t getOperatorExplainExecInfo(SOperatorInfo* operatorInfo, SExplainExecInfo
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t initCatchSupporter(SCatchSupporter* pCatchSup, size_t rowSize, size_t keyBufSize,
|
||||
const char* pKey, const char* pDir) {
|
||||
int32_t initCatchSupporter(SCatchSupporter* pCatchSup, size_t rowSize, size_t keyBufSize, const char* pKey,
|
||||
const char* pDir) {
|
||||
pCatchSup->keySize = sizeof(int64_t) + sizeof(int64_t) + sizeof(TSKEY);
|
||||
pCatchSup->pKeyBuf = taosMemoryCalloc(1, pCatchSup->keySize);
|
||||
int32_t pageSize = rowSize * 32;
|
||||
int32_t bufSize = pageSize * 4096;
|
||||
createDiskbasedBuf(&pCatchSup->pDataBuf, pageSize, bufSize, pKey, pDir);
|
||||
_hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);
|
||||
pCatchSup->pWindowHashTable = taosHashInit(10000, hashFn, true, HASH_NO_LOCK);;
|
||||
pCatchSup->pWindowHashTable = taosHashInit(10000, hashFn, true, HASH_NO_LOCK);
|
||||
;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -1181,6 +1181,7 @@ SOperatorInfo* createIntervalOperatorInfo(SOperatorInfo* downstream, SExprInfo*
|
|||
|
||||
initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pInfo->win);
|
||||
pInfo->invertible = allInvertible(pInfo->binfo.pCtx, numOfCols);
|
||||
pInfo->invertible = false; // Todo(liuyao): Dependent TSDB API
|
||||
|
||||
// pInfo->pTableQueryInfo = initTableQueryInfo(pTableGroupInfo);
|
||||
if (code != TSDB_CODE_SUCCESS /* || pInfo->pTableQueryInfo == NULL*/) {
|
||||
|
|
|
@ -28,7 +28,7 @@ extern "C" {
|
|||
|
||||
#define FUNC_MGT_AGG_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(0)
|
||||
#define FUNC_MGT_SCALAR_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(1)
|
||||
#define FUNC_MGT_NONSTANDARD_SQL_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(2)
|
||||
#define FUNC_MGT_INDEFINITE_ROWS_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(2)
|
||||
#define FUNC_MGT_STRING_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(3)
|
||||
#define FUNC_MGT_DATETIME_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(4)
|
||||
#define FUNC_MGT_TIMELINE_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(5)
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
*/
|
||||
|
||||
#include "builtins.h"
|
||||
#include "querynodes.h"
|
||||
#include "builtinsimpl.h"
|
||||
#include "querynodes.h"
|
||||
#include "scalar.h"
|
||||
#include "taoserror.h"
|
||||
#include "tdatablock.h"
|
||||
|
@ -185,6 +185,19 @@ static int32_t translateApercentile(SFunctionNode* pFunc, char* pErrBuf, int32_t
|
|||
if (!IS_NUMERIC_TYPE(para1Type) || !IS_INTEGER_TYPE(para2Type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
SNode* pParamNode = nodesListGetNode(pFunc->pParameterList, 1);
|
||||
if (nodeType(pParamNode) != QUERY_NODE_VALUE) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
SValueNode* pValue = (SValueNode*)pParamNode;
|
||||
if (pValue->datum.i < 0 || pValue->datum.i > 100) {
|
||||
return invaildFuncParaValueErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
pValue->notReserved = true;
|
||||
|
||||
if (3 == paraNum) {
|
||||
SNode* pPara3 = nodesListGetNode(pFunc->pParameterList, 2);
|
||||
if (QUERY_NODE_VALUE != nodeType(pPara3) || !validAperventileAlgo((SValueNode*)pPara3)) {
|
||||
|
@ -215,7 +228,7 @@ static int32_t translateTop(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
|||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
SValueNode* pValue = (SValueNode*) pParamNode;
|
||||
SValueNode* pValue = (SValueNode*)pParamNode;
|
||||
if (pValue->node.resType.type != TSDB_DATA_TYPE_BIGINT) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -224,6 +237,8 @@ static int32_t translateTop(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
|||
return invaildFuncParaValueErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
pValue->notReserved = true;
|
||||
|
||||
SDataType* pType = &((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType;
|
||||
pFunc->node.resType = (SDataType){.bytes = pType->bytes, .type = pType->type};
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -336,7 +351,7 @@ static int32_t translateStateCount(SFunctionNode* pFunc, char* pErrBuf, int32_t
|
|||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
pFunc->node.resType = (SDataType) { .bytes = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes, .type = TSDB_DATA_TYPE_BIGINT };
|
||||
pFunc->node.resType = (SDataType){.bytes = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes, .type = TSDB_DATA_TYPE_BIGINT};
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -361,7 +376,7 @@ static int32_t translateStateDuration(SFunctionNode* pFunc, char* pErrBuf, int32
|
|||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
pFunc->node.resType = (SDataType) { .bytes = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes, .type = TSDB_DATA_TYPE_BIGINT };
|
||||
pFunc->node.resType = (SDataType){.bytes = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes, .type = TSDB_DATA_TYPE_BIGINT};
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -392,7 +407,7 @@ static int32_t translateCsum(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
|||
}
|
||||
}
|
||||
|
||||
pFunc->node.resType = (SDataType) { .bytes = tDataTypes[resType].bytes, .type = resType};
|
||||
pFunc->node.resType = (SDataType){.bytes = tDataTypes[resType].bytes, .type = resType};
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -434,7 +449,7 @@ static int32_t translateSample(SFunctionNode* pFunc, char* pErrBuf, int32_t len)
|
|||
}
|
||||
|
||||
SExprNode* pCol = (SExprNode*)nodesListGetNode(pFunc->pParameterList, 0);
|
||||
uint8_t colType = pCol->resType.type;
|
||||
uint8_t colType = pCol->resType.type;
|
||||
if (IS_VAR_DATA_TYPE(colType)) {
|
||||
pFunc->node.resType = (SDataType){.bytes = pCol->resType.bytes, .type = colType};
|
||||
} else {
|
||||
|
@ -463,7 +478,7 @@ static int32_t translateTail(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
|||
}
|
||||
|
||||
SExprNode* pCol = (SExprNode*)nodesListGetNode(pFunc->pParameterList, 0);
|
||||
uint8_t colType = pCol->resType.type;
|
||||
uint8_t colType = pCol->resType.type;
|
||||
if (IS_VAR_DATA_TYPE(colType)) {
|
||||
pFunc->node.resType = (SDataType){.bytes = pCol->resType.bytes, .type = colType};
|
||||
} else {
|
||||
|
@ -500,8 +515,7 @@ static int32_t translateUnique(SFunctionNode* pFunc, char* pErrBuf, int32_t len)
|
|||
|
||||
SNode* pPara = nodesListGetNode(pFunc->pParameterList, 0);
|
||||
if (QUERY_NODE_COLUMN != nodeType(pPara)) {
|
||||
return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR,
|
||||
"The parameters of UNIQUE can only be columns");
|
||||
return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR, "The parameters of UNIQUE can only be columns");
|
||||
}
|
||||
|
||||
pFunc->node.resType = ((SExprNode*)pPara)->resType;
|
||||
|
@ -823,7 +837,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
{
|
||||
.name = "top",
|
||||
.type = FUNCTION_TYPE_TOP,
|
||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC,
|
||||
.classification = FUNC_MGT_SELECT_FUNC | FUNC_MGT_INDEFINITE_ROWS_FUNC,
|
||||
.translateFunc = translateTop,
|
||||
.getEnvFunc = getTopBotFuncEnv,
|
||||
.initFunc = functionSetup,
|
||||
|
@ -833,7 +847,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
{
|
||||
.name = "bottom",
|
||||
.type = FUNCTION_TYPE_BOTTOM,
|
||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC,
|
||||
.classification = FUNC_MGT_SELECT_FUNC | FUNC_MGT_INDEFINITE_ROWS_FUNC,
|
||||
.translateFunc = translateBottom,
|
||||
.getEnvFunc = getTopBotFuncEnv,
|
||||
.initFunc = functionSetup,
|
||||
|
@ -915,7 +929,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
{
|
||||
.name = "diff",
|
||||
.type = FUNCTION_TYPE_DIFF,
|
||||
.classification = FUNC_MGT_NONSTANDARD_SQL_FUNC | FUNC_MGT_TIMELINE_FUNC,
|
||||
.classification = FUNC_MGT_INDEFINITE_ROWS_FUNC | FUNC_MGT_TIMELINE_FUNC,
|
||||
.translateFunc = translateDiff,
|
||||
.getEnvFunc = getDiffFuncEnv,
|
||||
.initFunc = diffFunctionSetup,
|
||||
|
@ -925,7 +939,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
{
|
||||
.name = "state_count",
|
||||
.type = FUNCTION_TYPE_STATE_COUNT,
|
||||
.classification = FUNC_MGT_NONSTANDARD_SQL_FUNC,
|
||||
.classification = FUNC_MGT_INDEFINITE_ROWS_FUNC,
|
||||
.translateFunc = translateStateCount,
|
||||
.getEnvFunc = getStateFuncEnv,
|
||||
.initFunc = functionSetup,
|
||||
|
@ -935,7 +949,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
{
|
||||
.name = "state_duration",
|
||||
.type = FUNCTION_TYPE_STATE_DURATION,
|
||||
.classification = FUNC_MGT_NONSTANDARD_SQL_FUNC | FUNC_MGT_TIMELINE_FUNC,
|
||||
.classification = FUNC_MGT_INDEFINITE_ROWS_FUNC | FUNC_MGT_TIMELINE_FUNC,
|
||||
.translateFunc = translateStateDuration,
|
||||
.getEnvFunc = getStateFuncEnv,
|
||||
.initFunc = functionSetup,
|
||||
|
@ -945,7 +959,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
{
|
||||
.name = "csum",
|
||||
.type = FUNCTION_TYPE_CSUM,
|
||||
.classification = FUNC_MGT_NONSTANDARD_SQL_FUNC | FUNC_MGT_TIMELINE_FUNC,
|
||||
.classification = FUNC_MGT_INDEFINITE_ROWS_FUNC | FUNC_MGT_TIMELINE_FUNC,
|
||||
.translateFunc = translateCsum,
|
||||
.getEnvFunc = getCsumFuncEnv,
|
||||
.initFunc = functionSetup,
|
||||
|
@ -955,7 +969,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
{
|
||||
.name = "mavg",
|
||||
.type = FUNCTION_TYPE_MAVG,
|
||||
.classification = FUNC_MGT_NONSTANDARD_SQL_FUNC | FUNC_MGT_TIMELINE_FUNC,
|
||||
.classification = FUNC_MGT_INDEFINITE_ROWS_FUNC | FUNC_MGT_TIMELINE_FUNC,
|
||||
.translateFunc = translateMavg,
|
||||
.getEnvFunc = getMavgFuncEnv,
|
||||
.initFunc = mavgFunctionSetup,
|
||||
|
@ -965,7 +979,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
{
|
||||
.name = "sample",
|
||||
.type = FUNCTION_TYPE_SAMPLE,
|
||||
.classification = FUNC_MGT_NONSTANDARD_SQL_FUNC | FUNC_MGT_TIMELINE_FUNC,
|
||||
.classification = FUNC_MGT_INDEFINITE_ROWS_FUNC | FUNC_MGT_TIMELINE_FUNC,
|
||||
.translateFunc = translateSample,
|
||||
.getEnvFunc = getSampleFuncEnv,
|
||||
.initFunc = sampleFunctionSetup,
|
||||
|
@ -975,7 +989,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
{
|
||||
.name = "tail",
|
||||
.type = FUNCTION_TYPE_TAIL,
|
||||
.classification = FUNC_MGT_NONSTANDARD_SQL_FUNC | FUNC_MGT_TIMELINE_FUNC,
|
||||
.classification = FUNC_MGT_INDEFINITE_ROWS_FUNC | FUNC_MGT_TIMELINE_FUNC,
|
||||
.translateFunc = translateTail,
|
||||
.getEnvFunc = getTailFuncEnv,
|
||||
.initFunc = tailFunctionSetup,
|
||||
|
@ -985,7 +999,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
{
|
||||
.name = "unique",
|
||||
.type = FUNCTION_TYPE_UNIQUE,
|
||||
.classification = FUNC_MGT_NONSTANDARD_SQL_FUNC | FUNC_MGT_TIMELINE_FUNC,
|
||||
.classification = FUNC_MGT_INDEFINITE_ROWS_FUNC | FUNC_MGT_TIMELINE_FUNC,
|
||||
.translateFunc = translateUnique,
|
||||
.getEnvFunc = getUniqueFuncEnv,
|
||||
.initFunc = uniqueFunctionSetup,
|
||||
|
|
|
@ -66,22 +66,18 @@ static bool isSpecificClassifyFunc(int32_t funcId, uint64_t classification) {
|
|||
}
|
||||
|
||||
static int32_t getUdfInfo(SFmGetFuncInfoParam* pParam, SFunctionNode* pFunc) {
|
||||
SFuncInfo* pInfo = NULL;
|
||||
int32_t code = catalogGetUdfInfo(pParam->pCtg, pParam->pRpc, pParam->pMgmtEps, pFunc->functionName, &pInfo);
|
||||
SFuncInfo funcInfo = {0};
|
||||
int32_t code = catalogGetUdfInfo(pParam->pCtg, pParam->pRpc, pParam->pMgmtEps, pFunc->functionName, &funcInfo);
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
return code;
|
||||
}
|
||||
if (NULL == pInfo) {
|
||||
snprintf(pParam->pErrBuf, pParam->errBufLen, "Invalid function name: %s", pFunc->functionName);
|
||||
return TSDB_CODE_FUNC_INVALID_FUNTION;
|
||||
}
|
||||
|
||||
pFunc->funcType = FUNCTION_TYPE_UDF;
|
||||
pFunc->funcId = TSDB_FUNC_TYPE_AGGREGATE == pInfo->funcType ? FUNC_AGGREGATE_UDF_ID : FUNC_SCALAR_UDF_ID;
|
||||
pFunc->node.resType.type = pInfo->outputType;
|
||||
pFunc->node.resType.bytes = pInfo->outputLen;
|
||||
pFunc->udfBufSize = pInfo->bufSize;
|
||||
tFreeSFuncInfo(pInfo);
|
||||
taosMemoryFree(pInfo);
|
||||
pFunc->funcId = TSDB_FUNC_TYPE_AGGREGATE == funcInfo.funcType ? FUNC_AGGREGATE_UDF_ID : FUNC_SCALAR_UDF_ID;
|
||||
pFunc->node.resType.type = funcInfo.outputType;
|
||||
pFunc->node.resType.bytes = funcInfo.outputLen;
|
||||
pFunc->udfBufSize = funcInfo.bufSize;
|
||||
tFreeSFuncInfo(&funcInfo);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -149,6 +145,8 @@ bool fmIsAggFunc(int32_t funcId) { return isSpecificClassifyFunc(funcId, FUNC_MG
|
|||
|
||||
bool fmIsScalarFunc(int32_t funcId) { return isSpecificClassifyFunc(funcId, FUNC_MGT_SCALAR_FUNC); }
|
||||
|
||||
bool fmIsVectorFunc(int32_t funcId) { return !fmIsScalarFunc(funcId); }
|
||||
|
||||
bool fmIsSelectFunc(int32_t funcId) { return isSpecificClassifyFunc(funcId, FUNC_MGT_SELECT_FUNC); }
|
||||
|
||||
bool fmIsTimelineFunc(int32_t funcId) { return isSpecificClassifyFunc(funcId, FUNC_MGT_TIMELINE_FUNC); }
|
||||
|
@ -161,7 +159,7 @@ bool fmIsWindowPseudoColumnFunc(int32_t funcId) { return isSpecificClassifyFunc(
|
|||
|
||||
bool fmIsWindowClauseFunc(int32_t funcId) { return fmIsAggFunc(funcId) || fmIsWindowPseudoColumnFunc(funcId); }
|
||||
|
||||
bool fmIsNonstandardSQLFunc(int32_t funcId) { return isSpecificClassifyFunc(funcId, FUNC_MGT_NONSTANDARD_SQL_FUNC); }
|
||||
bool fmIsIndefiniteRowsFunc(int32_t funcId) { return isSpecificClassifyFunc(funcId, FUNC_MGT_INDEFINITE_ROWS_FUNC); }
|
||||
|
||||
bool fmIsSpecialDataRequiredFunc(int32_t funcId) {
|
||||
return isSpecificClassifyFunc(funcId, FUNC_MGT_SPECIAL_DATA_REQUIRED);
|
||||
|
|
|
@ -72,12 +72,20 @@ static int32_t udfSpawnUdfd(SUdfdData* pData) {
|
|||
char path[PATH_MAX] = {0};
|
||||
if (tsProcPath == NULL) {
|
||||
path[0] = '.';
|
||||
#ifdef WINDOWS
|
||||
GetModuleFileName(NULL, path, PATH_MAX);
|
||||
taosDirName(path);
|
||||
#endif
|
||||
} else {
|
||||
strncpy(path, tsProcPath, strlen(tsProcPath));
|
||||
taosDirName(path);
|
||||
}
|
||||
#ifdef WINDOWS
|
||||
strcat(path, "udfd.exe");
|
||||
if (strlen(path)==0) {
|
||||
strcat(path, "udfd.exe");
|
||||
} else {
|
||||
strcat(path, "\\udfd.exe");
|
||||
}
|
||||
#else
|
||||
strcat(path, "/udfd");
|
||||
#endif
|
||||
|
|
|
@ -138,6 +138,7 @@ static void udfdCtrlReadCb(uv_stream_t *q, ssize_t nread, const uv_buf_t *buf);
|
|||
static int32_t udfdUvInit();
|
||||
static void udfdCloseWalkCb(uv_handle_t *handle, void *arg);
|
||||
static int32_t udfdRun();
|
||||
static void udfdConnectMnodeThreadFunc(void* args);
|
||||
|
||||
void udfdProcessRequest(uv_work_t *req) {
|
||||
SUvUdfWork *uvUdf = (SUvUdfWork *)(req->data);
|
||||
|
@ -870,6 +871,23 @@ static int32_t udfdRun() {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void udfdConnectMnodeThreadFunc(void* args) {
|
||||
int32_t retryMnodeTimes = 0;
|
||||
int32_t code = 0;
|
||||
while (retryMnodeTimes++ <= TSDB_MAX_REPLICA) {
|
||||
uv_sleep(100 * (1 << retryMnodeTimes));
|
||||
code = udfdConnectToMnode();
|
||||
if (code == 0) {
|
||||
break;
|
||||
}
|
||||
fnError("udfd can not connect to mnode, code: %s. retry", tstrerror(code));
|
||||
}
|
||||
|
||||
if (code != 0) {
|
||||
fnError("udfd can not connect to mnode");
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (!taosCheckSystemIsSmallEnd()) {
|
||||
printf("failed to start since on non-small-end machines\n");
|
||||
|
@ -902,30 +920,18 @@ int main(int argc, char *argv[]) {
|
|||
return -3;
|
||||
}
|
||||
|
||||
int32_t retryMnodeTimes = 0;
|
||||
int32_t code = 0;
|
||||
while (retryMnodeTimes++ <= TSDB_MAX_REPLICA) {
|
||||
uv_sleep(100 * (1 << retryMnodeTimes));
|
||||
code = udfdConnectToMnode();
|
||||
if (code == 0) {
|
||||
break;
|
||||
}
|
||||
fnError("can not connect to mnode, code: %s. retry", tstrerror(code));
|
||||
}
|
||||
|
||||
if (code != 0) {
|
||||
fnError("failed to start since can not connect to mnode");
|
||||
return -4;
|
||||
}
|
||||
|
||||
if (udfdUvInit() != 0) {
|
||||
fnError("uv init failure");
|
||||
return -5;
|
||||
}
|
||||
|
||||
uv_thread_t mnodeConnectThread;
|
||||
uv_thread_create(&mnodeConnectThread, udfdConnectMnodeThreadFunc, NULL);
|
||||
|
||||
udfdRun();
|
||||
|
||||
removeListeningPipe();
|
||||
uv_thread_join(&mnodeConnectThread);
|
||||
udfdCloseClientRpc();
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -12,6 +12,9 @@ target_link_libraries(
|
|||
PUBLIC os
|
||||
PUBLIC util
|
||||
PUBLIC common
|
||||
PUBLIC nodes
|
||||
PUBLIC scalar
|
||||
PUBLIC function
|
||||
)
|
||||
|
||||
if (${BUILD_WITH_LUCENE})
|
||||
|
@ -31,7 +34,7 @@ if (${BUILD_WITH_INVERTEDINDEX})
|
|||
endif(${BUILD_WITH_INVERTEDINDEX})
|
||||
|
||||
|
||||
#if (${BUILD_TEST})
|
||||
# add_subdirectory(test)
|
||||
#endif(${BUILD_TEST})
|
||||
if (${BUILD_TEST})
|
||||
add_subdirectory(test)
|
||||
endif(${BUILD_TEST})
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ typedef struct TFileHeader {
|
|||
} TFileHeader;
|
||||
#pragma pack(pop)
|
||||
|
||||
#define TFILE_HEADER_SIZE (sizeof(TFileHeader))
|
||||
#define TFILE_HEADER_SIZE (sizeof(TFileHeader))
|
||||
#define TFILE_HEADER_NO_FST (TFILE_HEADER_SIZE - sizeof(int32_t))
|
||||
|
||||
typedef struct TFileValue {
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
#include "lucene++/Lucene_c.h"
|
||||
#endif
|
||||
|
||||
#define INDEX_NUM_OF_THREADS 4
|
||||
#define INDEX_NUM_OF_THREADS 1
|
||||
#define INDEX_QUEUE_SIZE 200
|
||||
|
||||
#define INDEX_DATA_BOOL_NULL 0x02
|
||||
|
@ -117,7 +117,6 @@ int indexOpen(SIndexOpts* opts, const char* path, SIndex** index) {
|
|||
sIdx->path = tstrdup(path);
|
||||
taosThreadMutexInit(&sIdx->mtx, NULL);
|
||||
tsem_init(&sIdx->sem, 0, 0);
|
||||
// taosThreadCondInit(&sIdx->finished, NULL);
|
||||
|
||||
sIdx->refId = indexAddRef(sIdx);
|
||||
indexAcquireRef(sIdx->refId);
|
||||
|
@ -143,13 +142,13 @@ void indexDestroy(void* handle) {
|
|||
return;
|
||||
}
|
||||
void indexClose(SIndex* sIdx) {
|
||||
indexReleaseRef(sIdx->refId);
|
||||
bool ref = 0;
|
||||
if (sIdx->colObj != NULL) {
|
||||
void* iter = taosHashIterate(sIdx->colObj, NULL);
|
||||
while (iter) {
|
||||
IndexCache** pCache = iter;
|
||||
indexCacheForceToMerge((void*)(*pCache));
|
||||
indexInfo("%s wait to merge", (*pCache)->colName);
|
||||
indexWait((void*)(sIdx));
|
||||
iter = taosHashIterate(sIdx->colObj, iter);
|
||||
indexCacheUnRef(*pCache);
|
||||
|
@ -157,7 +156,7 @@ void indexClose(SIndex* sIdx) {
|
|||
taosHashCleanup(sIdx->colObj);
|
||||
sIdx->colObj = NULL;
|
||||
}
|
||||
// taosMsleep(1000 * 5);
|
||||
indexReleaseRef(sIdx->refId);
|
||||
indexRemoveRef(sIdx->refId);
|
||||
}
|
||||
int64_t indexAddRef(void* p) {
|
||||
|
@ -554,8 +553,29 @@ void iterateValueDestroy(IterateValue* value, bool destroy) {
|
|||
taosMemoryFree(value->colVal);
|
||||
value->colVal = NULL;
|
||||
}
|
||||
|
||||
static int64_t indexGetAvaialbleVer(SIndex* sIdx, IndexCache* cache) {
|
||||
ICacheKey key = {.suid = cache->suid, .colName = cache->colName, .nColName = strlen(cache->colName)};
|
||||
int64_t ver = CACHE_VERSION(cache);
|
||||
taosThreadMutexLock(&sIdx->mtx);
|
||||
TFileReader* trd = tfileCacheGet(((IndexTFile*)sIdx->tindex)->cache, &key);
|
||||
if (trd != NULL) {
|
||||
if (ver < trd->header.version) {
|
||||
ver = trd->header.version + 1;
|
||||
} else {
|
||||
ver += 1;
|
||||
}
|
||||
indexInfo("header: %d, ver: %" PRId64 "", trd->header.version, ver);
|
||||
tfileReaderUnRef(trd);
|
||||
} else {
|
||||
indexInfo("not found reader base %p", trd);
|
||||
}
|
||||
taosThreadMutexUnlock(&sIdx->mtx);
|
||||
return ver;
|
||||
}
|
||||
static int indexGenTFile(SIndex* sIdx, IndexCache* cache, SArray* batch) {
|
||||
int32_t version = CACHE_VERSION(cache);
|
||||
int64_t version = indexGetAvaialbleVer(sIdx, cache);
|
||||
indexInfo("file name version: %" PRId64 "", version);
|
||||
uint8_t colType = cache->type;
|
||||
|
||||
TFileWriter* tw = tfileWriterOpen(sIdx->path, cache->suid, version, cache->colName, colType);
|
||||
|
@ -575,6 +595,7 @@ static int indexGenTFile(SIndex* sIdx, IndexCache* cache, SArray* batch) {
|
|||
if (reader == NULL) {
|
||||
return -1;
|
||||
}
|
||||
indexInfo("success to create tfile, reopen it, %s", reader->ctx->file.buf);
|
||||
|
||||
TFileHeader* header = &reader->header;
|
||||
ICacheKey key = {.suid = cache->suid, .colName = header->colName, .nColName = strlen(header->colName)};
|
||||
|
|
|
@ -335,6 +335,9 @@ IndexCache* indexCacheCreate(SIndex* idx, uint64_t suid, const char* colName, in
|
|||
taosThreadCondInit(&cache->finished, NULL);
|
||||
|
||||
indexCacheRef(cache);
|
||||
if (idx != NULL) {
|
||||
indexAcquireRef(idx->refId);
|
||||
}
|
||||
return cache;
|
||||
}
|
||||
void indexCacheDebug(IndexCache* cache) {
|
||||
|
@ -426,13 +429,16 @@ void indexCacheDestroy(void* cache) {
|
|||
if (pCache == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
indexMemUnRef(pCache->mem);
|
||||
indexMemUnRef(pCache->imm);
|
||||
taosMemoryFree(pCache->colName);
|
||||
|
||||
taosThreadMutexDestroy(&pCache->mtx);
|
||||
taosThreadCondDestroy(&pCache->finished);
|
||||
|
||||
if (pCache->index != NULL) {
|
||||
indexReleaseRef(((SIndex*)pCache->index)->refId);
|
||||
}
|
||||
taosMemoryFree(pCache);
|
||||
}
|
||||
|
||||
|
|
|
@ -13,10 +13,11 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "indexoperator.h"
|
||||
#include "executorimpl.h"
|
||||
#include "index.h"
|
||||
#include "indexInt.h"
|
||||
#include "nodes.h"
|
||||
#include "querynodes.h"
|
||||
#include "scalar.h"
|
||||
#include "tdatablock.h"
|
||||
|
||||
// clang-format off
|
||||
|
@ -69,9 +70,9 @@ typedef int32_t (*sif_func_t)(SIFParam *left, SIFParam *rigth, SIFParam *output)
|
|||
static sif_func_t sifNullFunc = NULL;
|
||||
// typedef struct SIFWalkParm
|
||||
// construct tag filter operator later
|
||||
static void destroyTagFilterOperatorInfo(void *param) {
|
||||
STagFilterOperatorInfo *pInfo = (STagFilterOperatorInfo *)param;
|
||||
}
|
||||
// static void destroyTagFilterOperatorInfo(void *param) {
|
||||
// STagFilterOperatorInfo *pInfo = (STagFilterOperatorInfo *)param;
|
||||
//}
|
||||
|
||||
static void sifFreeParam(SIFParam *param) {
|
||||
if (param == NULL) return;
|
||||
|
@ -178,13 +179,13 @@ static int32_t sifInitParam(SNode *node, SIFParam *param, SIFCtx *ctx) {
|
|||
case QUERY_NODE_NODE_LIST: {
|
||||
SNodeListNode *nl = (SNodeListNode *)node;
|
||||
if (LIST_LENGTH(nl->pNodeList) <= 0) {
|
||||
qError("invalid length for node:%p, length: %d", node, LIST_LENGTH(nl->pNodeList));
|
||||
indexError("invalid length for node:%p, length: %d", node, LIST_LENGTH(nl->pNodeList));
|
||||
SIF_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
|
||||
}
|
||||
SIF_ERR_RET(scalarGenerateSetFromList((void **)¶m->pFilter, node, nl->dataType.type));
|
||||
if (taosHashPut(ctx->pRes, &node, POINTER_BYTES, param, sizeof(*param))) {
|
||||
taosHashCleanup(param->pFilter);
|
||||
qError("taosHashPut nodeList failed, size:%d", (int32_t)sizeof(*param));
|
||||
indexError("taosHashPut nodeList failed, size:%d", (int32_t)sizeof(*param));
|
||||
SIF_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
break;
|
||||
|
@ -194,7 +195,7 @@ static int32_t sifInitParam(SNode *node, SIFParam *param, SIFCtx *ctx) {
|
|||
case QUERY_NODE_LOGIC_CONDITION: {
|
||||
SIFParam *res = (SIFParam *)taosHashGet(ctx->pRes, &node, POINTER_BYTES);
|
||||
if (NULL == res) {
|
||||
qError("no result for node, type:%d, node:%p", nodeType(node), node);
|
||||
indexError("no result for node, type:%d, node:%p", nodeType(node), node);
|
||||
SIF_ERR_RET(TSDB_CODE_QRY_APP_ERROR);
|
||||
}
|
||||
*param = *res;
|
||||
|
@ -210,7 +211,7 @@ static int32_t sifInitOperParams(SIFParam **params, SOperatorNode *node, SIFCtx
|
|||
int32_t code = 0;
|
||||
int32_t nParam = sifGetOperParamNum(node->opType);
|
||||
if (NULL == node->pLeft || (nParam == 2 && NULL == node->pRight)) {
|
||||
qError("invalid operation node, left: %p, rigth: %p", node->pLeft, node->pRight);
|
||||
indexError("invalid operation node, left: %p, rigth: %p", node->pLeft, node->pRight);
|
||||
SIF_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
|
||||
}
|
||||
SIFParam *paramList = taosMemoryCalloc(nParam, sizeof(SIFParam));
|
||||
|
@ -232,7 +233,7 @@ static int32_t sifInitParamList(SIFParam **params, SNodeList *nodeList, SIFCtx *
|
|||
int32_t code = 0;
|
||||
SIFParam *tParams = taosMemoryCalloc(nodeList->length, sizeof(SIFParam));
|
||||
if (tParams == NULL) {
|
||||
qError("failed to calloc, nodeList: %p", nodeList);
|
||||
indexError("failed to calloc, nodeList: %p", nodeList);
|
||||
SIF_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
|
@ -252,7 +253,7 @@ _return:
|
|||
SIF_RET(code);
|
||||
}
|
||||
static int32_t sifExecFunction(SFunctionNode *node, SIFCtx *ctx, SIFParam *output) {
|
||||
qError("index-filter not support buildin function");
|
||||
indexError("index-filter not support buildin function");
|
||||
return TSDB_CODE_QRY_INVALID_INPUT;
|
||||
}
|
||||
static int32_t sifDoIndex(SIFParam *left, SIFParam *right, int8_t operType, SIFParam *output) {
|
||||
|
@ -390,8 +391,8 @@ _return:
|
|||
|
||||
static int32_t sifExecLogic(SLogicConditionNode *node, SIFCtx *ctx, SIFParam *output) {
|
||||
if (NULL == node->pParameterList || node->pParameterList->length <= 0) {
|
||||
qError("invalid logic parameter list, list:%p, paramNum:%d", node->pParameterList,
|
||||
node->pParameterList ? node->pParameterList->length : 0);
|
||||
indexError("invalid logic parameter list, list:%p, paramNum:%d", node->pParameterList,
|
||||
node->pParameterList ? node->pParameterList->length : 0);
|
||||
return TSDB_CODE_QRY_INVALID_INPUT;
|
||||
}
|
||||
|
||||
|
@ -485,7 +486,7 @@ EDealRes sifCalcWalker(SNode *node, void *context) {
|
|||
return sifWalkOper(node, ctx);
|
||||
}
|
||||
|
||||
qError("invalid node type for index filter calculating, type:%d", nodeType(node));
|
||||
indexError("invalid node type for index filter calculating, type:%d", nodeType(node));
|
||||
ctx->code = TSDB_CODE_QRY_INVALID_INPUT;
|
||||
return DEAL_RES_ERROR;
|
||||
}
|
||||
|
@ -509,7 +510,7 @@ static int32_t sifCalculate(SNode *pNode, SIFParam *pDst) {
|
|||
SIFCtx ctx = {.code = 0, .noExec = false};
|
||||
ctx.pRes = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK);
|
||||
if (NULL == ctx.pRes) {
|
||||
qError("index-filter failed to taosHashInit");
|
||||
indexError("index-filter failed to taosHashInit");
|
||||
return TSDB_CODE_QRY_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
|
@ -519,7 +520,7 @@ static int32_t sifCalculate(SNode *pNode, SIFParam *pDst) {
|
|||
if (pDst) {
|
||||
SIFParam *res = (SIFParam *)taosHashGet(ctx.pRes, (void *)&pNode, POINTER_BYTES);
|
||||
if (res == NULL) {
|
||||
qError("no valid res in hash, node:(%p), type(%d)", (void *)&pNode, nodeType(pNode));
|
||||
indexError("no valid res in hash, node:(%p), type(%d)", (void *)&pNode, nodeType(pNode));
|
||||
SIF_ERR_RET(TSDB_CODE_QRY_APP_ERROR);
|
||||
}
|
||||
taosArrayAddAll(pDst->result, res->result);
|
||||
|
@ -539,7 +540,7 @@ static int32_t sifGetFltHint(SNode *pNode, SIdxFltStatus *status) {
|
|||
SIFCtx ctx = {.code = 0, .noExec = true};
|
||||
ctx.pRes = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK);
|
||||
if (NULL == ctx.pRes) {
|
||||
qError("index-filter failed to taosHashInit");
|
||||
indexError("index-filter failed to taosHashInit");
|
||||
return TSDB_CODE_QRY_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
|
@ -549,7 +550,7 @@ static int32_t sifGetFltHint(SNode *pNode, SIdxFltStatus *status) {
|
|||
|
||||
SIFParam *res = (SIFParam *)taosHashGet(ctx.pRes, (void *)&pNode, POINTER_BYTES);
|
||||
if (res == NULL) {
|
||||
qError("no valid res in hash, node:(%p), type(%d)", (void *)&pNode, nodeType(pNode));
|
||||
indexError("no valid res in hash, node:(%p), type(%d)", (void *)&pNode, nodeType(pNode));
|
||||
SIF_ERR_RET(TSDB_CODE_QRY_APP_ERROR);
|
||||
}
|
||||
*status = res->status;
|
|
@ -97,6 +97,7 @@ WriterCtx* writerCtxCreate(WriterType type, const char* path, bool readOnly, int
|
|||
int64_t file_size;
|
||||
taosStatFile(path, &file_size, NULL);
|
||||
ctx->file.size = (int)file_size;
|
||||
|
||||
} else {
|
||||
// ctx->file.pFile = open(path, O_RDONLY, S_IRWXU | S_IRWXG | S_IRWXO);
|
||||
ctx->file.pFile = taosOpenFile(path, TD_FILE_READ);
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
p *
|
||||
* 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.
|
||||
|
@ -152,10 +151,13 @@ TFileReader* tfileCacheGet(TFileCache* tcache, ICacheKey* key) {
|
|||
char buf[128] = {0};
|
||||
int32_t sz = indexSerialCacheKey(key, buf);
|
||||
assert(sz < sizeof(buf));
|
||||
indexInfo("Try to get key: %s", buf);
|
||||
TFileReader** reader = taosHashGet(tcache->tableCache, buf, sz);
|
||||
if (reader == NULL) {
|
||||
if (reader == NULL || *reader == NULL) {
|
||||
indexInfo("failed to get key: %s", buf);
|
||||
return NULL;
|
||||
}
|
||||
indexInfo("Get key: %s file: %s", buf, (*reader)->ctx->file.buf);
|
||||
tfileReaderRef(*reader);
|
||||
|
||||
return *reader;
|
||||
|
@ -165,9 +167,10 @@ void tfileCachePut(TFileCache* tcache, ICacheKey* key, TFileReader* reader) {
|
|||
int32_t sz = indexSerialCacheKey(key, buf);
|
||||
// remove last version index reader
|
||||
TFileReader** p = taosHashGet(tcache->tableCache, buf, sz);
|
||||
if (p != NULL) {
|
||||
if (p != NULL && *p != NULL) {
|
||||
TFileReader* oldReader = *p;
|
||||
taosHashRemove(tcache->tableCache, buf, sz);
|
||||
indexInfo("found %s, remove file %s", buf, oldReader->ctx->file.buf);
|
||||
oldReader->remove = true;
|
||||
tfileReaderUnRef(oldReader);
|
||||
}
|
||||
|
@ -180,7 +183,6 @@ TFileReader* tfileReaderCreate(WriterCtx* ctx) {
|
|||
if (reader == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
reader->ctx = ctx;
|
||||
|
||||
if (0 != tfileReaderVerify(reader)) {
|
||||
|
@ -202,6 +204,7 @@ TFileReader* tfileReaderCreate(WriterCtx* ctx) {
|
|||
tfileReaderDestroy(reader);
|
||||
return NULL;
|
||||
}
|
||||
reader->remove = false;
|
||||
|
||||
return reader;
|
||||
}
|
||||
|
@ -536,7 +539,7 @@ TFileReader* tfileReaderOpen(char* path, uint64_t suid, int32_t version, const c
|
|||
indexError("failed to open readonly file: %s, reason: %s", fullname, terrstr());
|
||||
return NULL;
|
||||
}
|
||||
indexInfo("open read file name:%s, file size: %d", wc->file.buf, wc->file.size);
|
||||
indexTrace("open read file name:%s, file size: %d", wc->file.buf, wc->file.size);
|
||||
|
||||
TFileReader* reader = tfileReaderCreate(wc);
|
||||
return reader;
|
||||
|
|
|
@ -674,10 +674,13 @@ class IndexObj {
|
|||
// opt
|
||||
numOfWrite = 0;
|
||||
numOfRead = 0;
|
||||
indexInit();
|
||||
// indexInit();
|
||||
}
|
||||
int Init(const std::string& dir) {
|
||||
taosRemoveDir(dir.c_str());
|
||||
int Init(const std::string& dir, bool remove = true) {
|
||||
if (remove) {
|
||||
taosRemoveDir(dir.c_str());
|
||||
taosMkDir(dir.c_str());
|
||||
}
|
||||
taosMkDir(dir.c_str());
|
||||
int ret = indexOpen(&opts, dir.c_str(), &idx);
|
||||
if (ret != 0) {
|
||||
|
@ -838,8 +841,11 @@ class IndexEnv2 : public ::testing::Test {
|
|||
initLog();
|
||||
index = new IndexObj();
|
||||
}
|
||||
virtual void TearDown() { delete index; }
|
||||
IndexObj* index;
|
||||
virtual void TearDown() {
|
||||
// taosMsleep(500);
|
||||
delete index;
|
||||
}
|
||||
IndexObj* index;
|
||||
};
|
||||
TEST_F(IndexEnv2, testIndexOpen) {
|
||||
std::string path = TD_TMP_DIR_PATH "test";
|
||||
|
@ -951,6 +957,8 @@ static void single_write_and_search(IndexObj* idx) {
|
|||
target = idx->SearchOne("tag2", "Test");
|
||||
}
|
||||
static void multi_write_and_search(IndexObj* idx) {
|
||||
idx->PutOne("tag1", "Hello");
|
||||
idx->PutOne("tag2", "Test");
|
||||
int target = idx->SearchOne("tag1", "Hello");
|
||||
target = idx->SearchOne("tag2", "Test");
|
||||
idx->WriteMultiMillonData("tag1", "hello world test", 100 * 100);
|
||||
|
@ -992,16 +1000,16 @@ TEST_F(IndexEnv2, testIndex_MultiWrite_and_MultiRead) {
|
|||
}
|
||||
}
|
||||
|
||||
// TEST_F(IndexEnv2, testIndex_restart) {
|
||||
// std::string path = TD_TMP_DIR_PATH "cache_and_tfile";
|
||||
// if (index->Init(path) != 0) {
|
||||
// }
|
||||
// index->SearchOneTarget("tag1", "Hello", 10);
|
||||
// index->SearchOneTarget("tag2", "Test", 10);
|
||||
//}
|
||||
TEST_F(IndexEnv2, testIndex_restart) {
|
||||
std::string path = TD_TMP_DIR_PATH "cache_and_tfile";
|
||||
if (index->Init(path, false) != 0) {
|
||||
}
|
||||
index->SearchOneTarget("tag1", "Hello", 10);
|
||||
index->SearchOneTarget("tag2", "Test", 10);
|
||||
}
|
||||
// TEST_F(IndexEnv2, testIndex_restart1) {
|
||||
// std::string path = TD_TMP_DIR_PATH "cache_and_tfile";
|
||||
// if (index->Init(path) != 0) {
|
||||
// if (index->Init(path, false) != 0) {
|
||||
// }
|
||||
// index->ReadMultiMillonData("tag1", "coding");
|
||||
// index->SearchOneTarget("tag1", "Hello", 10);
|
||||
|
@ -1018,16 +1026,16 @@ TEST_F(IndexEnv2, testIndex_MultiWrite_and_MultiRead) {
|
|||
// std::cout << "reader sz: " << index->SearchOne("tag1", "Hello") << std::endl;
|
||||
// assert(3 == index->SearchOne("tag1", "Hello"));
|
||||
//}
|
||||
// TEST_F(IndexEnv2, testIndexMultiTag) {
|
||||
// std::string path = TD_TMP_DIR_PATH "multi_tag";
|
||||
// if (index->Init(path) != 0) {
|
||||
// }
|
||||
// int64_t st = taosGetTimestampUs();
|
||||
// int32_t num = 1000 * 10000;
|
||||
// index->WriteMultiMillonData("tag1", "xxxxxxxxxxxxxxx", num);
|
||||
// std::cout << "numOfRow: " << num << "\ttime cost:" << taosGetTimestampUs() - st << std::endl;
|
||||
// // index->WriteMultiMillonData("tag2", "xxxxxxxxxxxxxxxxxxxxxxxxx", 100 * 10000);
|
||||
//}
|
||||
TEST_F(IndexEnv2, testIndexMultiTag) {
|
||||
std::string path = TD_TMP_DIR_PATH "multi_tag";
|
||||
if (index->Init(path) != 0) {
|
||||
}
|
||||
int64_t st = taosGetTimestampUs();
|
||||
int32_t num = 100 * 100;
|
||||
index->WriteMultiMillonData("tag1", "xxxxxxxxxxxxxxx", num);
|
||||
std::cout << "numOfRow: " << num << "\ttime cost:" << taosGetTimestampUs() - st << std::endl;
|
||||
// index->WriteMultiMillonData("tag2", "xxxxxxxxxxxxxxxxxxxxxxxxx", 100 * 10000);
|
||||
}
|
||||
TEST_F(IndexEnv2, testLongComVal1) {
|
||||
std::string path = TD_TMP_DIR_PATH "long_colVal";
|
||||
if (index->Init(path) != 0) {
|
||||
|
|
|
@ -19,6 +19,21 @@
|
|||
#include "taos.h"
|
||||
#include "taoserror.h"
|
||||
|
||||
#define COPY_SCALAR_FIELD(fldname) \
|
||||
do { \
|
||||
(pDst)->fldname = (pSrc)->fldname; \
|
||||
} while (0)
|
||||
|
||||
#define COPY_CHAR_ARRAY_FIELD(fldname) \
|
||||
do { \
|
||||
strcpy((pDst)->fldname, (pSrc)->fldname); \
|
||||
} while (0)
|
||||
|
||||
#define COPY_OBJECT_FIELD(fldname, size) \
|
||||
do { \
|
||||
memcpy(&((pDst)->fldname), &((pSrc)->fldname), size); \
|
||||
} while (0)
|
||||
|
||||
#define COPY_CHAR_POINT_FIELD(fldname) \
|
||||
do { \
|
||||
if (NULL == (pSrc)->fldname) { \
|
||||
|
@ -70,27 +85,61 @@
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
static void dataTypeCopy(const SDataType* pSrc, SDataType* pDst) {}
|
||||
|
||||
static SNode* exprNodeCopy(const SExprNode* pSrc, SExprNode* pDst) {
|
||||
dataTypeCopy(&pSrc->resType, &pDst->resType);
|
||||
pDst->pAssociation = NULL;
|
||||
COPY_OBJECT_FIELD(resType, sizeof(SDataType));
|
||||
COPY_CHAR_ARRAY_FIELD(aliasName);
|
||||
COPY_CHAR_ARRAY_FIELD(userAlias);
|
||||
return (SNode*)pDst;
|
||||
}
|
||||
|
||||
static SNode* columnNodeCopy(const SColumnNode* pSrc, SColumnNode* pDst) {
|
||||
COPY_BASE_OBJECT_FIELD(node, exprNodeCopy);
|
||||
pDst->pProjectRef = NULL;
|
||||
COPY_SCALAR_FIELD(tableId);
|
||||
COPY_SCALAR_FIELD(tableType);
|
||||
COPY_SCALAR_FIELD(colId);
|
||||
COPY_SCALAR_FIELD(colType);
|
||||
COPY_CHAR_ARRAY_FIELD(dbName);
|
||||
COPY_CHAR_ARRAY_FIELD(tableName);
|
||||
COPY_CHAR_ARRAY_FIELD(tableAlias);
|
||||
COPY_CHAR_ARRAY_FIELD(colName);
|
||||
COPY_SCALAR_FIELD(dataBlockId);
|
||||
COPY_SCALAR_FIELD(slotId);
|
||||
return (SNode*)pDst;
|
||||
}
|
||||
|
||||
static SNode* valueNodeCopy(const SValueNode* pSrc, SValueNode* pDst) {
|
||||
COPY_BASE_OBJECT_FIELD(node, exprNodeCopy);
|
||||
COPY_CHAR_POINT_FIELD(literal);
|
||||
COPY_SCALAR_FIELD(isDuration);
|
||||
COPY_SCALAR_FIELD(translate);
|
||||
COPY_SCALAR_FIELD(notReserved);
|
||||
COPY_SCALAR_FIELD(placeholderNo);
|
||||
COPY_SCALAR_FIELD(typeData);
|
||||
COPY_SCALAR_FIELD(unit);
|
||||
if (!pSrc->translate) {
|
||||
return (SNode*)pDst;
|
||||
}
|
||||
switch (pSrc->node.resType.type) {
|
||||
case TSDB_DATA_TYPE_BOOL:
|
||||
COPY_SCALAR_FIELD(datum.b);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_TINYINT:
|
||||
case TSDB_DATA_TYPE_SMALLINT:
|
||||
case TSDB_DATA_TYPE_INT:
|
||||
case TSDB_DATA_TYPE_BIGINT:
|
||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||
COPY_SCALAR_FIELD(datum.i);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_FLOAT:
|
||||
case TSDB_DATA_TYPE_DOUBLE:
|
||||
COPY_SCALAR_FIELD(datum.d);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_UTINYINT:
|
||||
case TSDB_DATA_TYPE_USMALLINT:
|
||||
case TSDB_DATA_TYPE_UINT:
|
||||
case TSDB_DATA_TYPE_UBIGINT:
|
||||
COPY_SCALAR_FIELD(datum.u);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_NCHAR:
|
||||
case TSDB_DATA_TYPE_VARCHAR:
|
||||
case TSDB_DATA_TYPE_VARBINARY:
|
||||
|
@ -104,7 +153,7 @@ static SNode* valueNodeCopy(const SValueNode* pSrc, SValueNode* pDst) {
|
|||
case TSDB_DATA_TYPE_JSON:
|
||||
case TSDB_DATA_TYPE_DECIMAL:
|
||||
case TSDB_DATA_TYPE_BLOB:
|
||||
// todo
|
||||
case TSDB_DATA_TYPE_MEDIUMBLOB:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -113,6 +162,7 @@ static SNode* valueNodeCopy(const SValueNode* pSrc, SValueNode* pDst) {
|
|||
|
||||
static SNode* operatorNodeCopy(const SOperatorNode* pSrc, SOperatorNode* pDst) {
|
||||
COPY_BASE_OBJECT_FIELD(node, exprNodeCopy);
|
||||
COPY_SCALAR_FIELD(opType);
|
||||
CLONE_NODE_FIELD(pLeft);
|
||||
CLONE_NODE_FIELD(pRight);
|
||||
return (SNode*)pDst;
|
||||
|
@ -120,18 +170,27 @@ static SNode* operatorNodeCopy(const SOperatorNode* pSrc, SOperatorNode* pDst) {
|
|||
|
||||
static SNode* logicConditionNodeCopy(const SLogicConditionNode* pSrc, SLogicConditionNode* pDst) {
|
||||
COPY_BASE_OBJECT_FIELD(node, exprNodeCopy);
|
||||
COPY_SCALAR_FIELD(condType);
|
||||
CLONE_NODE_LIST_FIELD(pParameterList);
|
||||
return (SNode*)pDst;
|
||||
}
|
||||
|
||||
static SNode* functionNodeCopy(const SFunctionNode* pSrc, SFunctionNode* pDst) {
|
||||
COPY_BASE_OBJECT_FIELD(node, exprNodeCopy);
|
||||
COPY_CHAR_ARRAY_FIELD(functionName);
|
||||
COPY_SCALAR_FIELD(funcId);
|
||||
COPY_SCALAR_FIELD(funcType);
|
||||
CLONE_NODE_LIST_FIELD(pParameterList);
|
||||
COPY_SCALAR_FIELD(udfBufSize);
|
||||
return (SNode*)pDst;
|
||||
}
|
||||
|
||||
static SNode* tableNodeCopy(const STableNode* pSrc, STableNode* pDst) {
|
||||
COPY_BASE_OBJECT_FIELD(node, exprNodeCopy);
|
||||
COPY_CHAR_ARRAY_FIELD(dbName);
|
||||
COPY_CHAR_ARRAY_FIELD(tableName);
|
||||
COPY_CHAR_ARRAY_FIELD(tableAlias);
|
||||
COPY_SCALAR_FIELD(precision);
|
||||
return (SNode*)pDst;
|
||||
}
|
||||
|
||||
|
@ -159,6 +218,8 @@ static SNode* realTableNodeCopy(const SRealTableNode* pSrc, SRealTableNode* pDst
|
|||
COPY_BASE_OBJECT_FIELD(table, tableNodeCopy);
|
||||
CLONE_OBJECT_FIELD(pMeta, tableMetaClone);
|
||||
CLONE_OBJECT_FIELD(pVgroupList, vgroupsInfoClone);
|
||||
COPY_CHAR_ARRAY_FIELD(qualDbName);
|
||||
COPY_SCALAR_FIELD(ratio);
|
||||
return (SNode*)pDst;
|
||||
}
|
||||
|
||||
|
@ -170,6 +231,7 @@ static SNode* tempTableNodeCopy(const STempTableNode* pSrc, STempTableNode* pDst
|
|||
|
||||
static SNode* joinTableNodeCopy(const SJoinTableNode* pSrc, SJoinTableNode* pDst) {
|
||||
COPY_BASE_OBJECT_FIELD(table, tableNodeCopy);
|
||||
COPY_SCALAR_FIELD(joinType);
|
||||
CLONE_NODE_FIELD(pLeft);
|
||||
CLONE_NODE_FIELD(pRight);
|
||||
CLONE_NODE_FIELD(pOnCond);
|
||||
|
@ -177,21 +239,30 @@ static SNode* joinTableNodeCopy(const SJoinTableNode* pSrc, SJoinTableNode* pDst
|
|||
}
|
||||
|
||||
static SNode* targetNodeCopy(const STargetNode* pSrc, STargetNode* pDst) {
|
||||
COPY_SCALAR_FIELD(dataBlockId);
|
||||
COPY_SCALAR_FIELD(slotId);
|
||||
CLONE_NODE_FIELD(pExpr);
|
||||
return (SNode*)pDst;
|
||||
}
|
||||
|
||||
static SNode* groupingSetNodeCopy(const SGroupingSetNode* pSrc, SGroupingSetNode* pDst) {
|
||||
COPY_SCALAR_FIELD(groupingSetType);
|
||||
CLONE_NODE_LIST_FIELD(pParameterList);
|
||||
return (SNode*)pDst;
|
||||
}
|
||||
|
||||
static SNode* orderByExprNodeCopy(const SOrderByExprNode* pSrc, SOrderByExprNode* pDst) {
|
||||
CLONE_NODE_FIELD(pExpr);
|
||||
COPY_SCALAR_FIELD(order);
|
||||
COPY_SCALAR_FIELD(nullOrder);
|
||||
return (SNode*)pDst;
|
||||
}
|
||||
|
||||
static SNode* limitNodeCopy(const SLimitNode* pSrc, SLimitNode* pDst) { return (SNode*)pDst; }
|
||||
static SNode* limitNodeCopy(const SLimitNode* pSrc, SLimitNode* pDst) {
|
||||
COPY_SCALAR_FIELD(limit);
|
||||
COPY_SCALAR_FIELD(offset);
|
||||
return (SNode*)pDst;
|
||||
}
|
||||
|
||||
static SNode* stateWindowNodeCopy(const SStateWindowNode* pSrc, SStateWindowNode* pDst) {
|
||||
CLONE_NODE_FIELD(pCol);
|
||||
|
@ -215,13 +286,16 @@ static SNode* intervalWindowNodeCopy(const SIntervalWindowNode* pSrc, SIntervalW
|
|||
}
|
||||
|
||||
static SNode* nodeListNodeCopy(const SNodeListNode* pSrc, SNodeListNode* pDst) {
|
||||
COPY_OBJECT_FIELD(dataType, sizeof(SDataType));
|
||||
CLONE_NODE_LIST_FIELD(pNodeList);
|
||||
return (SNode*)pDst;
|
||||
}
|
||||
|
||||
static SNode* fillNodeCopy(const SFillNode* pSrc, SFillNode* pDst) {
|
||||
COPY_SCALAR_FIELD(mode);
|
||||
CLONE_NODE_FIELD(pValues);
|
||||
CLONE_NODE_FIELD(pWStartTs);
|
||||
COPY_OBJECT_FIELD(timeRange, sizeof(STimeWindow));
|
||||
return (SNode*)pDst;
|
||||
}
|
||||
|
||||
|
@ -229,7 +303,7 @@ static SNode* logicNodeCopy(const SLogicNode* pSrc, SLogicNode* pDst) {
|
|||
CLONE_NODE_LIST_FIELD(pTargets);
|
||||
CLONE_NODE_FIELD(pConditions);
|
||||
CLONE_NODE_LIST_FIELD(pChildren);
|
||||
pDst->pParent = NULL;
|
||||
COPY_SCALAR_FIELD(optimizedFlag);
|
||||
return (SNode*)pDst;
|
||||
}
|
||||
|
||||
|
@ -239,12 +313,25 @@ static SNode* logicScanCopy(const SScanLogicNode* pSrc, SScanLogicNode* pDst) {
|
|||
CLONE_NODE_LIST_FIELD(pScanPseudoCols);
|
||||
CLONE_OBJECT_FIELD(pMeta, tableMetaClone);
|
||||
CLONE_OBJECT_FIELD(pVgroupList, vgroupsInfoClone);
|
||||
COPY_SCALAR_FIELD(scanType);
|
||||
COPY_OBJECT_FIELD(scanSeq[0], sizeof(uint8_t) * 2);
|
||||
COPY_OBJECT_FIELD(scanRange, sizeof(STimeWindow));
|
||||
COPY_OBJECT_FIELD(tableName, sizeof(SName));
|
||||
COPY_SCALAR_FIELD(showRewrite);
|
||||
COPY_SCALAR_FIELD(ratio);
|
||||
CLONE_NODE_LIST_FIELD(pDynamicScanFuncs);
|
||||
COPY_SCALAR_FIELD(dataRequired);
|
||||
COPY_SCALAR_FIELD(interval);
|
||||
COPY_SCALAR_FIELD(offset);
|
||||
COPY_SCALAR_FIELD(sliding);
|
||||
COPY_SCALAR_FIELD(intervalUnit);
|
||||
COPY_SCALAR_FIELD(slidingUnit);
|
||||
return (SNode*)pDst;
|
||||
}
|
||||
|
||||
static SNode* logicJoinCopy(const SJoinLogicNode* pSrc, SJoinLogicNode* pDst) {
|
||||
COPY_BASE_OBJECT_FIELD(node, logicNodeCopy);
|
||||
COPY_SCALAR_FIELD(joinType);
|
||||
CLONE_NODE_FIELD(pOnConditions);
|
||||
return (SNode*)pDst;
|
||||
}
|
||||
|
@ -259,32 +346,50 @@ static SNode* logicAggCopy(const SAggLogicNode* pSrc, SAggLogicNode* pDst) {
|
|||
static SNode* logicProjectCopy(const SProjectLogicNode* pSrc, SProjectLogicNode* pDst) {
|
||||
COPY_BASE_OBJECT_FIELD(node, logicNodeCopy);
|
||||
CLONE_NODE_LIST_FIELD(pProjections);
|
||||
COPY_CHAR_ARRAY_FIELD(stmtName);
|
||||
COPY_SCALAR_FIELD(limit);
|
||||
COPY_SCALAR_FIELD(offset);
|
||||
COPY_SCALAR_FIELD(slimit);
|
||||
COPY_SCALAR_FIELD(soffset);
|
||||
return (SNode*)pDst;
|
||||
}
|
||||
|
||||
static SNode* logicVnodeModifCopy(const SVnodeModifLogicNode* pSrc, SVnodeModifLogicNode* pDst) {
|
||||
COPY_BASE_OBJECT_FIELD(node, logicNodeCopy);
|
||||
pDst->pDataBlocks = NULL;
|
||||
pDst->pVgDataBlocks = NULL;
|
||||
COPY_SCALAR_FIELD(msgType);
|
||||
return (SNode*)pDst;
|
||||
}
|
||||
|
||||
static SNode* logicExchangeCopy(const SExchangeLogicNode* pSrc, SExchangeLogicNode* pDst) {
|
||||
COPY_BASE_OBJECT_FIELD(node, logicNodeCopy);
|
||||
COPY_SCALAR_FIELD(srcGroupId);
|
||||
COPY_SCALAR_FIELD(precision);
|
||||
return (SNode*)pDst;
|
||||
}
|
||||
|
||||
static SNode* logicWindowCopy(const SWindowLogicNode* pSrc, SWindowLogicNode* pDst) {
|
||||
COPY_BASE_OBJECT_FIELD(node, logicNodeCopy);
|
||||
COPY_SCALAR_FIELD(winType);
|
||||
CLONE_NODE_LIST_FIELD(pFuncs);
|
||||
COPY_SCALAR_FIELD(interval);
|
||||
COPY_SCALAR_FIELD(offset);
|
||||
COPY_SCALAR_FIELD(sliding);
|
||||
COPY_SCALAR_FIELD(intervalUnit);
|
||||
COPY_SCALAR_FIELD(slidingUnit);
|
||||
COPY_SCALAR_FIELD(sessionGap);
|
||||
CLONE_NODE_FIELD(pTspk);
|
||||
CLONE_NODE_FIELD(pStateExpr);
|
||||
COPY_SCALAR_FIELD(triggerType);
|
||||
COPY_SCALAR_FIELD(watermark);
|
||||
return (SNode*)pDst;
|
||||
}
|
||||
|
||||
static SNode* logicFillCopy(const SFillLogicNode* pSrc, SFillLogicNode* pDst) {
|
||||
COPY_BASE_OBJECT_FIELD(node, logicNodeCopy);
|
||||
COPY_SCALAR_FIELD(mode);
|
||||
CLONE_NODE_FIELD(pWStartTs);
|
||||
CLONE_NODE_FIELD(pValues);
|
||||
COPY_OBJECT_FIELD(timeRange, sizeof(STimeWindow));
|
||||
return (SNode*)pDst;
|
||||
}
|
||||
|
||||
|
@ -301,28 +406,41 @@ static SNode* logicPartitionCopy(const SPartitionLogicNode* pSrc, SPartitionLogi
|
|||
}
|
||||
|
||||
static SNode* logicSubplanCopy(const SLogicSubplan* pSrc, SLogicSubplan* pDst) {
|
||||
COPY_OBJECT_FIELD(id, sizeof(SSubplanId));
|
||||
CLONE_NODE_FIELD(pNode);
|
||||
pDst->pChildren = NULL;
|
||||
pDst->pParents = NULL;
|
||||
pDst->pVgroupList = NULL;
|
||||
COPY_SCALAR_FIELD(subplanType);
|
||||
COPY_SCALAR_FIELD(level);
|
||||
COPY_SCALAR_FIELD(splitFlag);
|
||||
return (SNode*)pDst;
|
||||
}
|
||||
|
||||
static SNode* dataBlockDescCopy(const SDataBlockDescNode* pSrc, SDataBlockDescNode* pDst) {
|
||||
COPY_SCALAR_FIELD(dataBlockId);
|
||||
CLONE_NODE_LIST_FIELD(pSlots);
|
||||
COPY_SCALAR_FIELD(totalRowSize);
|
||||
COPY_SCALAR_FIELD(outputRowSize);
|
||||
COPY_SCALAR_FIELD(precision);
|
||||
return (SNode*)pDst;
|
||||
}
|
||||
|
||||
static SNode* slotDescCopy(const SSlotDescNode* pSrc, SSlotDescNode* pDst) {
|
||||
dataTypeCopy(&pSrc->dataType, &pDst->dataType);
|
||||
COPY_SCALAR_FIELD(slotId);
|
||||
COPY_OBJECT_FIELD(dataType, sizeof(SDataType));
|
||||
COPY_SCALAR_FIELD(reserve);
|
||||
COPY_SCALAR_FIELD(output);
|
||||
COPY_SCALAR_FIELD(tag);
|
||||
return (SNode*)pDst;
|
||||
}
|
||||
|
||||
static SNode* downstreamSourceCopy(const SDownstreamSourceNode* pSrc, SDownstreamSourceNode* pDst) {
|
||||
COPY_OBJECT_FIELD(addr, sizeof(SQueryNodeAddr));
|
||||
COPY_SCALAR_FIELD(taskId);
|
||||
COPY_SCALAR_FIELD(schedId);
|
||||
return (SNode*)pDst;
|
||||
}
|
||||
|
||||
static SNode* selectStmtCopy(const SSelectStmt* pSrc, SSelectStmt* pDst) {
|
||||
COPY_SCALAR_FIELD(isDistinct);
|
||||
CLONE_NODE_LIST_FIELD(pProjectionList);
|
||||
CLONE_NODE_FIELD(pFromTable);
|
||||
CLONE_NODE_FIELD(pWhere);
|
||||
|
@ -333,6 +451,12 @@ static SNode* selectStmtCopy(const SSelectStmt* pSrc, SSelectStmt* pDst) {
|
|||
CLONE_NODE_LIST_FIELD(pOrderByList);
|
||||
CLONE_NODE_FIELD(pLimit);
|
||||
CLONE_NODE_FIELD(pLimit);
|
||||
COPY_CHAR_ARRAY_FIELD(stmtName);
|
||||
COPY_SCALAR_FIELD(precision);
|
||||
COPY_SCALAR_FIELD(isEmptyResult);
|
||||
COPY_SCALAR_FIELD(isTimeOrderQuery);
|
||||
COPY_SCALAR_FIELD(hasAggFuncs);
|
||||
COPY_SCALAR_FIELD(hasRepeatScanFuncs);
|
||||
return (SNode*)pDst;
|
||||
}
|
||||
|
||||
|
@ -345,7 +469,6 @@ SNodeptr nodesCloneNode(const SNodeptr pNode) {
|
|||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return NULL;
|
||||
}
|
||||
memcpy(pDst, pNode, nodesNodeSize(nodeType(pNode)));
|
||||
switch (nodeType(pNode)) {
|
||||
case QUERY_NODE_COLUMN:
|
||||
return columnNodeCopy((const SColumnNode*)pNode, (SColumnNode*)pDst);
|
||||
|
@ -387,6 +510,8 @@ SNodeptr nodesCloneNode(const SNodeptr pNode) {
|
|||
return slotDescCopy((const SSlotDescNode*)pNode, (SSlotDescNode*)pDst);
|
||||
case QUERY_NODE_DOWNSTREAM_SOURCE:
|
||||
return downstreamSourceCopy((const SDownstreamSourceNode*)pNode, (SDownstreamSourceNode*)pDst);
|
||||
case QUERY_NODE_LEFT_VALUE:
|
||||
return pDst;
|
||||
case QUERY_NODE_SELECT_STMT:
|
||||
return selectStmtCopy((const SSelectStmt*)pNode, (SSelectStmt*)pDst);
|
||||
case QUERY_NODE_LOGIC_PLAN_SCAN:
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue