refactor: merge from 3.0
This commit is contained in:
commit
d3d4ac9b3f
81
Jenkinsfile2
81
Jenkinsfile2
|
@ -47,36 +47,67 @@ def pre_test(){
|
|||
script {
|
||||
if (env.CHANGE_TARGET == 'master') {
|
||||
sh '''
|
||||
cd ${WK}
|
||||
git checkout master
|
||||
cd ${WKC}
|
||||
git checkout master
|
||||
'''
|
||||
} else if(env.CHANGE_TARGET == '2.0') {
|
||||
sh '''
|
||||
cd ${WK}
|
||||
git checkout 2.0
|
||||
cd ${WKC}
|
||||
git checkout 2.0
|
||||
'''
|
||||
} else if(env.CHANGE_TARGET == '3.0') {
|
||||
sh '''
|
||||
cd ${WK}
|
||||
git checkout 3.0
|
||||
cd ${WKC}
|
||||
git checkout 3.0
|
||||
[ -d contrib/bdb ] && cd contrib/bdb && git clean -fxd && cd ../..
|
||||
'''
|
||||
} else {
|
||||
sh '''
|
||||
cd ${WK}
|
||||
git checkout develop
|
||||
cd ${WKC}
|
||||
git checkout develop
|
||||
'''
|
||||
}
|
||||
}
|
||||
if (env.CHANGE_URL =~ /\/TDengine\//) {
|
||||
sh '''
|
||||
cd ${WKC}
|
||||
git pull >/dev/null
|
||||
git fetch origin +refs/pull/${CHANGE_ID}/merge
|
||||
git checkout -qf FETCH_HEAD
|
||||
git log|head -n20
|
||||
cd ${WK}
|
||||
git pull >/dev/null
|
||||
git log|head -n20
|
||||
'''
|
||||
} else if (env.CHANGE_URL =~ /\/TDinternal\//) {
|
||||
sh '''
|
||||
cd ${WK}
|
||||
git pull >/dev/null
|
||||
git fetch origin +refs/pull/${CHANGE_ID}/merge
|
||||
git checkout -qf FETCH_HEAD
|
||||
git log|head -n20
|
||||
cd ${WKC}
|
||||
git pull >/dev/null
|
||||
git log|head -n20
|
||||
'''
|
||||
} else {
|
||||
sh '''
|
||||
echo "unmatched reposiotry ${CHANGE_URL}"
|
||||
'''
|
||||
}
|
||||
sh '''
|
||||
cd ${WKC}
|
||||
git pull >/dev/null
|
||||
git fetch origin +refs/pull/${CHANGE_ID}/merge
|
||||
git checkout -qf FETCH_HEAD
|
||||
git submodule update --init --recursive
|
||||
'''
|
||||
sh '''
|
||||
cd ${WKC}
|
||||
cd ${WK}
|
||||
export TZ=Asia/Harbin
|
||||
date
|
||||
rm -rf debug
|
||||
|
@ -162,8 +193,8 @@ pipeline {
|
|||
options { skipDefaultCheckout() }
|
||||
environment{
|
||||
WK = '/var/lib/jenkins/workspace/TDinternal'
|
||||
WKC= '/var/lib/jenkins/workspace/TDengine'
|
||||
WKPY= '/var/lib/jenkins/workspace/taos-connector-python'
|
||||
WKC = '/var/lib/jenkins/workspace/TDinternal/community'
|
||||
WKPY = '/var/lib/jenkins/workspace/taos-connector-python'
|
||||
}
|
||||
stages {
|
||||
stage('run test') {
|
||||
|
@ -177,15 +208,33 @@ pipeline {
|
|||
steps {
|
||||
timeout(time: 45, unit: 'MINUTES'){
|
||||
pre_test()
|
||||
sh '''
|
||||
cd ${WKC}/debug
|
||||
ctest -VV
|
||||
'''
|
||||
sh '''
|
||||
export LD_LIBRARY_PATH=${WKC}/debug/build/lib
|
||||
cd ${WKC}/tests/system-test
|
||||
./fulltest.sh
|
||||
'''
|
||||
script {
|
||||
if (env.CHANGE_URL =~ /\/TDengine\//) {
|
||||
sh '''
|
||||
cd ${WK}/debug
|
||||
ctest -VV
|
||||
'''
|
||||
sh '''
|
||||
export LD_LIBRARY_PATH=${WK}/debug/build/lib
|
||||
cd ${WKC}/tests/system-test
|
||||
./fulltest.sh
|
||||
'''
|
||||
} else if (env.CHANGE_URL =~ /\/TDinternal\//) {
|
||||
sh '''
|
||||
cd ${WKC}/debug
|
||||
ctest -VV
|
||||
'''
|
||||
sh '''
|
||||
export LD_LIBRARY_PATH=${WKC}/debug/build/lib
|
||||
cd ${WKC}/tests/system-test
|
||||
./fulltest.sh
|
||||
'''
|
||||
} else {
|
||||
sh '''
|
||||
echo "unmatched reposiotry ${CHANGE_URL}"
|
||||
'''
|
||||
}
|
||||
}
|
||||
sh '''
|
||||
cd ${WKC}/tests
|
||||
./test-all.sh b1fq
|
||||
|
|
|
@ -32,6 +32,11 @@ static void msg_process(TAOS_RES* msg) {
|
|||
int32_t numOfFields = taos_field_count(msg);
|
||||
taos_print_row(buf, row, fields, numOfFields);
|
||||
printf("%s\n", buf);
|
||||
|
||||
const char* tbName = tmq_get_table_name(msg);
|
||||
if (tbName) {
|
||||
printf("from tb: %s\n", tbName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,8 +106,8 @@ int32_t create_topic() {
|
|||
}
|
||||
taos_free_result(pRes);
|
||||
|
||||
pRes = taos_query(pConn, "create topic topic_ctb_column as abc1");
|
||||
/*pRes = taos_query(pConn, "create topic topic_ctb_column as select ts, c1, c2, c3 from ct1");*/
|
||||
/*pRes = taos_query(pConn, "create topic topic_ctb_column as abc1");*/
|
||||
pRes = taos_query(pConn, "create topic topic_ctb_column as select ts, c1, c2, c3 from st1");
|
||||
if (taos_errno(pRes) != 0) {
|
||||
printf("failed to create topic topic_ctb_column, reason:%s\n", taos_errstr(pRes));
|
||||
return -1;
|
||||
|
@ -161,6 +166,7 @@ tmq_t* build_consumer() {
|
|||
tmq_conf_set(conf, "td.connect.user", "root");
|
||||
tmq_conf_set(conf, "td.connect.pass", "taosdata");
|
||||
/*tmq_conf_set(conf, "td.connect.db", "abc1");*/
|
||||
tmq_conf_set(conf, "msg.with.table.name", "true");
|
||||
tmq_conf_set_offset_commit_cb(conf, tmq_commit_cb_print, NULL);
|
||||
tmq_t* tmq = tmq_consumer_new(conf, NULL, 0);
|
||||
assert(tmq);
|
||||
|
|
|
@ -257,10 +257,7 @@ DLL_EXPORT void tmq_conf_set_offset_commit_cb(tmq_conf_t *conf, tmq_co
|
|||
|
||||
DLL_EXPORT const char *tmq_get_topic_name(TAOS_RES *res);
|
||||
DLL_EXPORT int32_t tmq_get_vgroup_id(TAOS_RES *res);
|
||||
// TODO
|
||||
#if 0
|
||||
DLL_EXPORT char *tmq_get_table_name(TAOS_RES *res);
|
||||
#endif
|
||||
DLL_EXPORT const char *tmq_get_table_name(TAOS_RES *res);
|
||||
|
||||
#if 0
|
||||
DLL_EXPORT int64_t tmq_get_request_offset(tmq_message_t *message);
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include "os.h"
|
||||
#include "talgo.h"
|
||||
#include "tencode.h"
|
||||
#include "ttypes.h"
|
||||
#include "tutil.h"
|
||||
|
||||
|
@ -25,6 +26,73 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct SSchema SSchema;
|
||||
typedef struct STColumn STColumn;
|
||||
typedef struct STSchema STSchema;
|
||||
typedef struct STSRow2 STSRow2;
|
||||
typedef struct STSRowBuilder STSRowBuilder;
|
||||
typedef struct SKVIdx SKVIdx;
|
||||
|
||||
// STSchema
|
||||
|
||||
// STSRow2
|
||||
int32_t tEncodeTSRow(SEncoder *pEncoder, const STSRow2 *pRow);
|
||||
int32_t tDecodeTSRow(SDecoder *pDecoder, STSRow2 *pRow);
|
||||
|
||||
// STSchema
|
||||
int32_t tTSchemaCreate(int32_t sver, SSchema *pSchema, int32_t nCols, STSchema **ppTSchema);
|
||||
void tTSchemaDestroy(STSchema *pTSchema);
|
||||
|
||||
// STSRowBuilder
|
||||
int32_t tTSRowBuilderInit(STSRowBuilder *pBuilder, int32_t sver, SSchema *pSchema, int32_t nCols);
|
||||
void tTSRowBuilderClear(STSRowBuilder *pBuilder);
|
||||
void tTSRowBuilderReset(STSRowBuilder *pBuilder);
|
||||
int32_t tTSRowBuilderPut(STSRowBuilder *pBuilder, int32_t cid, const uint8_t *pData, uint32_t nData);
|
||||
int32_t tTSRowBuilderGetRow(STSRowBuilder *pBuilder, const STSRow2 **ppRow);
|
||||
|
||||
// STRUCT =================
|
||||
struct STColumn {
|
||||
col_id_t colId;
|
||||
int8_t type;
|
||||
int8_t flags;
|
||||
int32_t bytes;
|
||||
int32_t offset;
|
||||
};
|
||||
|
||||
struct STSchema {
|
||||
int32_t numOfCols;
|
||||
int32_t version;
|
||||
int32_t flen;
|
||||
int32_t vlen;
|
||||
int32_t tlen;
|
||||
STColumn columns[];
|
||||
};
|
||||
|
||||
struct STSRow2 {
|
||||
TSKEY ts;
|
||||
uint32_t flags;
|
||||
union {
|
||||
int32_t sver;
|
||||
int32_t ncols;
|
||||
};
|
||||
uint32_t nData;
|
||||
const uint8_t *pData;
|
||||
};
|
||||
|
||||
struct STSRowBuilder {
|
||||
STColumn *pTColumn;
|
||||
STSchema *pTSchema;
|
||||
int32_t szKVBuf;
|
||||
uint8_t *pKVBuf;
|
||||
int32_t szTPBuf;
|
||||
uint8_t *pTPBuf;
|
||||
int32_t nCols;
|
||||
int32_t kvVLen;
|
||||
int32_t tpVLen;
|
||||
STSRow2 row;
|
||||
};
|
||||
|
||||
#if 1 //====================================
|
||||
// Imported since 3.0 and use bitmap to demonstrate None/Null/Norm, while use Null/Norm below 3.0 without of bitmap.
|
||||
#define TD_SUPPORT_BITMAP
|
||||
#define TD_SUPPORT_READ2
|
||||
|
@ -59,15 +127,6 @@ extern "C" {
|
|||
} while (0);
|
||||
|
||||
// ----------------- TSDB COLUMN DEFINITION
|
||||
#pragma pack(push, 1)
|
||||
typedef struct {
|
||||
col_id_t colId; // column ID(start from PRIMARYKEY_TIMESTAMP_COL_ID(1))
|
||||
int8_t type; // column type
|
||||
int8_t flags; // flags: 0 no index, 1 SCHEMA_SMA_ON, 2 SCHEMA_IDX_ON
|
||||
int32_t bytes; // column bytes (0~16M)
|
||||
int32_t offset; // point offset in STpRow after the header part.
|
||||
} STColumn;
|
||||
#pragma pack(pop)
|
||||
|
||||
#define colType(col) ((col)->type)
|
||||
#define colFlags(col) ((col)->flags)
|
||||
|
@ -82,15 +141,6 @@ typedef struct {
|
|||
#define colSetOffset(col, o) (colOffset(col) = (o))
|
||||
|
||||
// ----------------- TSDB SCHEMA DEFINITION
|
||||
typedef struct {
|
||||
int32_t numOfCols; // Number of columns appended
|
||||
schema_ver_t version; // schema version
|
||||
uint16_t flen; // First part length in a STpRow after the header part
|
||||
int32_t vlen; // pure value part length, excluded the overhead (bytes only)
|
||||
int32_t tlen; // maximum length of a STpRow without the header part
|
||||
// (sizeof(VarDataOffsetT) + sizeof(VarDataLenT) + (bytes))
|
||||
STColumn columns[];
|
||||
} STSchema;
|
||||
|
||||
#define schemaNCols(s) ((s)->numOfCols)
|
||||
#define schemaVersion(s) ((s)->version)
|
||||
|
@ -334,7 +384,7 @@ static FORCE_INLINE int32_t comparTagId(const void *key1, const void *key2) {
|
|||
}
|
||||
}
|
||||
|
||||
static FORCE_INLINE void *tdGetKVRowValOfCol(SKVRow row, int16_t colId) {
|
||||
static FORCE_INLINE void *tdGetKVRowValOfCol(const SKVRow row, int16_t colId) {
|
||||
void *ret = taosbsearch(&colId, kvRowColIdx(row), kvRowNCols(row), sizeof(SColIdx), comparTagId, TD_EQ);
|
||||
if (ret == NULL) return NULL;
|
||||
return kvRowColVal(row, (SColIdx *)ret);
|
||||
|
@ -386,6 +436,7 @@ static FORCE_INLINE int32_t tdAddColToKVRow(SKVRowBuilder *pBuilder, col_id_t co
|
|||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ extern int32_t tsMaxNumOfDistinctResults;
|
|||
extern int32_t tsCompatibleModel;
|
||||
extern bool tsEnableSlaveQuery;
|
||||
extern bool tsPrintAuth;
|
||||
extern int64_t tsTickPerDay[3];
|
||||
extern int64_t tsTickPerMin[3];
|
||||
|
||||
// multi-process
|
||||
extern bool tsMultiProcess;
|
||||
|
@ -122,7 +122,7 @@ extern int32_t tsDiskCfgNum;
|
|||
extern SDiskCfg tsDiskCfg[];
|
||||
|
||||
// udf
|
||||
extern bool tsStartUdfd;
|
||||
extern bool tsStartUdfd;
|
||||
|
||||
// internal
|
||||
extern int32_t tsTransPullupInterval;
|
||||
|
|
|
@ -252,23 +252,32 @@ STSRow* tGetSubmitBlkNext(SSubmitBlkIter* pIter);
|
|||
int32_t tPrintFixedSchemaSubmitReq(const SSubmitReq* pReq, STSchema* pSchema);
|
||||
|
||||
typedef struct {
|
||||
int32_t index; // index of failed block in submit blocks
|
||||
int32_t vnode; // vnode index of failed block
|
||||
int32_t sid; // table index of failed block
|
||||
int32_t code; // errorcode while write data to vnode, such as not created, dropped, no space, invalid table
|
||||
} SSubmitRspBlock;
|
||||
int32_t code;
|
||||
int8_t hashMeta;
|
||||
int64_t uid;
|
||||
char* tblFName;
|
||||
int32_t numOfRows;
|
||||
int32_t affectedRows;
|
||||
} SSubmitBlkRsp;
|
||||
|
||||
typedef struct {
|
||||
int32_t code; // 0-success, > 0 error code
|
||||
int32_t numOfRows; // number of records the client is trying to write
|
||||
int32_t affectedRows; // number of records actually written
|
||||
int32_t failedRows; // number of failed records (exclude duplicate records)
|
||||
int32_t numOfFailedBlocks;
|
||||
SSubmitRspBlock failedBlocks[];
|
||||
int32_t numOfRows;
|
||||
int32_t affectedRows;
|
||||
int32_t nBlocks;
|
||||
union {
|
||||
SArray* pArray;
|
||||
SSubmitBlkRsp* pBlocks;
|
||||
};
|
||||
} SSubmitRsp;
|
||||
|
||||
#define SCHEMA_SMA_ON 0x1
|
||||
#define SCHEMA_IDX_ON 0x2
|
||||
int32_t tEncodeSSubmitRsp(SEncoder* pEncoder, const SSubmitRsp* pRsp);
|
||||
int32_t tDecodeSSubmitRsp(SDecoder* pDecoder, SSubmitRsp* pRsp);
|
||||
void tFreeSSubmitRsp(SSubmitRsp* pRsp);
|
||||
|
||||
#define COL_SMA_ON ((int8_t)0x1)
|
||||
#define COL_IDX_ON ((int8_t)0x2)
|
||||
#define COL_VAL_SET ((int8_t)0x4)
|
||||
|
||||
typedef struct SSchema {
|
||||
int8_t type;
|
||||
int8_t flags;
|
||||
|
@ -277,7 +286,7 @@ typedef struct SSchema {
|
|||
char name[TSDB_COL_NAME_LEN];
|
||||
} SSchema;
|
||||
|
||||
#define IS_BSMA_ON(s) (((s)->flags & 0x01) == SCHEMA_SMA_ON)
|
||||
#define IS_BSMA_ON(s) (((s)->flags & 0x01) == COL_SMA_ON)
|
||||
|
||||
#define SSCHMEA_TYPE(s) ((s)->type)
|
||||
#define SSCHMEA_FLAGS(s) ((s)->flags)
|
||||
|
@ -291,6 +300,109 @@ typedef struct {
|
|||
SSchema* pSchema;
|
||||
} SSchemaWrapper;
|
||||
|
||||
static FORCE_INLINE SSchemaWrapper* tCloneSSchemaWrapper(const SSchemaWrapper* pSchemaWrapper) {
|
||||
SSchemaWrapper* pSW = (SSchemaWrapper*)taosMemoryMalloc(sizeof(SSchemaWrapper));
|
||||
if (pSW == NULL) return pSW;
|
||||
pSW->nCols = pSchemaWrapper->nCols;
|
||||
pSW->sver = pSchemaWrapper->sver;
|
||||
pSW->pSchema = (SSchema*)taosMemoryCalloc(pSW->nCols, sizeof(SSchema));
|
||||
if (pSW->pSchema == NULL) {
|
||||
taosMemoryFree(pSW);
|
||||
return NULL;
|
||||
}
|
||||
memcpy(pSW->pSchema, pSchemaWrapper->pSchema, pSW->nCols * sizeof(SSchema));
|
||||
return pSW;
|
||||
}
|
||||
|
||||
static FORCE_INLINE void tDeleteSSchemaWrapper(SSchemaWrapper* pSchemaWrapper) {
|
||||
taosMemoryFree(pSchemaWrapper->pSchema);
|
||||
taosMemoryFree(pSchemaWrapper);
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t taosEncodeSSchema(void** buf, const SSchema* pSchema) {
|
||||
int32_t tlen = 0;
|
||||
tlen += taosEncodeFixedI8(buf, pSchema->type);
|
||||
tlen += taosEncodeFixedI8(buf, pSchema->flags);
|
||||
tlen += taosEncodeFixedI32(buf, pSchema->bytes);
|
||||
tlen += taosEncodeFixedI16(buf, pSchema->colId);
|
||||
tlen += taosEncodeString(buf, pSchema->name);
|
||||
return tlen;
|
||||
}
|
||||
|
||||
static FORCE_INLINE void* taosDecodeSSchema(const void* buf, SSchema* pSchema) {
|
||||
buf = taosDecodeFixedI8(buf, &pSchema->type);
|
||||
buf = taosDecodeFixedI8(buf, &pSchema->flags);
|
||||
buf = taosDecodeFixedI32(buf, &pSchema->bytes);
|
||||
buf = taosDecodeFixedI16(buf, &pSchema->colId);
|
||||
buf = taosDecodeStringTo(buf, pSchema->name);
|
||||
return (void*)buf;
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tEncodeSSchema(SEncoder* pEncoder, const SSchema* pSchema) {
|
||||
if (tEncodeI8(pEncoder, pSchema->type) < 0) return -1;
|
||||
if (tEncodeI8(pEncoder, pSchema->flags) < 0) return -1;
|
||||
if (tEncodeI32v(pEncoder, pSchema->bytes) < 0) return -1;
|
||||
if (tEncodeI16v(pEncoder, pSchema->colId) < 0) return -1;
|
||||
if (tEncodeCStr(pEncoder, pSchema->name) < 0) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tDecodeSSchema(SDecoder* pDecoder, SSchema* pSchema) {
|
||||
if (tDecodeI8(pDecoder, &pSchema->type) < 0) return -1;
|
||||
if (tDecodeI8(pDecoder, &pSchema->flags) < 0) return -1;
|
||||
if (tDecodeI32v(pDecoder, &pSchema->bytes) < 0) return -1;
|
||||
if (tDecodeI16v(pDecoder, &pSchema->colId) < 0) return -1;
|
||||
if (tDecodeCStrTo(pDecoder, pSchema->name) < 0) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t taosEncodeSSchemaWrapper(void** buf, const SSchemaWrapper* pSW) {
|
||||
int32_t tlen = 0;
|
||||
tlen += taosEncodeVariantI32(buf, pSW->nCols);
|
||||
tlen += taosEncodeVariantI32(buf, pSW->sver);
|
||||
for (int32_t i = 0; i < pSW->nCols; i++) {
|
||||
tlen += taosEncodeSSchema(buf, &pSW->pSchema[i]);
|
||||
}
|
||||
return tlen;
|
||||
}
|
||||
|
||||
static FORCE_INLINE void* taosDecodeSSchemaWrapper(const void* buf, SSchemaWrapper* pSW) {
|
||||
buf = taosDecodeVariantI32(buf, &pSW->nCols);
|
||||
buf = taosDecodeVariantI32(buf, &pSW->sver);
|
||||
pSW->pSchema = (SSchema*)taosMemoryCalloc(pSW->nCols, sizeof(SSchema));
|
||||
if (pSW->pSchema == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < pSW->nCols; i++) {
|
||||
buf = taosDecodeSSchema(buf, &pSW->pSchema[i]);
|
||||
}
|
||||
return (void*)buf;
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tEncodeSSchemaWrapper(SEncoder* pEncoder, const SSchemaWrapper* pSW) {
|
||||
if (tEncodeI32v(pEncoder, pSW->nCols) < 0) return -1;
|
||||
if (tEncodeI32v(pEncoder, pSW->sver) < 0) return -1;
|
||||
for (int32_t i = 0; i < pSW->nCols; i++) {
|
||||
if (tEncodeSSchema(pEncoder, &pSW->pSchema[i]) < 0) return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tDecodeSSchemaWrapper(SDecoder* pDecoder, SSchemaWrapper* pSW) {
|
||||
if (tDecodeI32v(pDecoder, &pSW->nCols) < 0) return -1;
|
||||
if (tDecodeI32v(pDecoder, &pSW->sver) < 0) return -1;
|
||||
|
||||
pSW->pSchema = (SSchema*)taosMemoryCalloc(pSW->nCols, sizeof(SSchema));
|
||||
if (pSW->pSchema == NULL) return -1;
|
||||
for (int32_t i = 0; i < pSW->nCols; i++) {
|
||||
if (tDecodeSSchema(pDecoder, &pSW->pSchema[i]) < 0) return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
STSchema* tdGetSTSChemaFromSSChema(SSchema** pSchema, int32_t nCols);
|
||||
|
||||
typedef struct {
|
||||
|
@ -372,6 +484,7 @@ typedef struct {
|
|||
int32_t acctId;
|
||||
int64_t clusterId;
|
||||
uint32_t connId;
|
||||
int32_t dnodeNum;
|
||||
int8_t superUser;
|
||||
int8_t connType;
|
||||
SEpSet epSet;
|
||||
|
@ -1873,7 +1986,7 @@ typedef struct SMqHbTopicInfo {
|
|||
int32_t epoch;
|
||||
int64_t topicUid;
|
||||
char name[TSDB_TOPIC_FNAME_LEN];
|
||||
SArray* pVgInfo;
|
||||
SArray* pVgInfo; // SArray<SMqHbVgInfo>
|
||||
} SMqHbTopicInfo;
|
||||
|
||||
static FORCE_INLINE int32_t taosEncodeSMqHbTopicInfoMsg(void** buf, const SMqHbTopicInfo* pTopicInfo) {
|
||||
|
@ -1992,49 +2105,6 @@ static FORCE_INLINE void* tDecodeSMqRebVgReq(const void* buf, SMqRebVgReq* pReq)
|
|||
return (void*)buf;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
int8_t reserved;
|
||||
} SMqRebVgRsp;
|
||||
|
||||
typedef struct {
|
||||
int64_t leftForVer;
|
||||
int32_t vgId;
|
||||
int32_t epoch;
|
||||
int64_t consumerId;
|
||||
char topicName[TSDB_TOPIC_FNAME_LEN];
|
||||
char cgroup[TSDB_CGROUP_LEN];
|
||||
char* sql;
|
||||
char* physicalPlan;
|
||||
char* qmsg;
|
||||
} SMqSetCVgReq;
|
||||
|
||||
static FORCE_INLINE int32_t tEncodeSMqSetCVgReq(void** buf, const SMqSetCVgReq* pReq) {
|
||||
int32_t tlen = 0;
|
||||
tlen += taosEncodeFixedI64(buf, pReq->leftForVer);
|
||||
tlen += taosEncodeFixedI32(buf, pReq->vgId);
|
||||
tlen += taosEncodeFixedI32(buf, pReq->epoch);
|
||||
tlen += taosEncodeFixedI64(buf, pReq->consumerId);
|
||||
tlen += taosEncodeString(buf, pReq->topicName);
|
||||
tlen += taosEncodeString(buf, pReq->cgroup);
|
||||
tlen += taosEncodeString(buf, pReq->sql);
|
||||
tlen += taosEncodeString(buf, pReq->physicalPlan);
|
||||
tlen += taosEncodeString(buf, pReq->qmsg);
|
||||
return tlen;
|
||||
}
|
||||
|
||||
static FORCE_INLINE void* tDecodeSMqSetCVgReq(void* buf, SMqSetCVgReq* pReq) {
|
||||
buf = taosDecodeFixedI64(buf, &pReq->leftForVer);
|
||||
buf = taosDecodeFixedI32(buf, &pReq->vgId);
|
||||
buf = taosDecodeFixedI32(buf, &pReq->epoch);
|
||||
buf = taosDecodeFixedI64(buf, &pReq->consumerId);
|
||||
buf = taosDecodeStringTo(buf, pReq->topicName);
|
||||
buf = taosDecodeStringTo(buf, pReq->cgroup);
|
||||
buf = taosDecodeString(buf, &pReq->sql);
|
||||
buf = taosDecodeString(buf, &pReq->physicalPlan);
|
||||
buf = taosDecodeString(buf, &pReq->qmsg);
|
||||
return buf;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
int32_t vgId;
|
||||
int64_t offset;
|
||||
|
@ -2056,109 +2126,6 @@ int32_t tDecodeSMqOffset(SDecoder* decoder, SMqOffset* pOffset);
|
|||
int32_t tEncodeSMqCMCommitOffsetReq(SEncoder* encoder, const SMqCMCommitOffsetReq* pReq);
|
||||
int32_t tDecodeSMqCMCommitOffsetReq(SDecoder* decoder, SMqCMCommitOffsetReq* pReq);
|
||||
|
||||
static FORCE_INLINE SSchemaWrapper* tCloneSSchemaWrapper(const SSchemaWrapper* pSchemaWrapper) {
|
||||
SSchemaWrapper* pSW = (SSchemaWrapper*)taosMemoryMalloc(sizeof(SSchemaWrapper));
|
||||
if (pSW == NULL) return pSW;
|
||||
pSW->nCols = pSchemaWrapper->nCols;
|
||||
pSW->sver = pSchemaWrapper->sver;
|
||||
pSW->pSchema = (SSchema*)taosMemoryCalloc(pSW->nCols, sizeof(SSchema));
|
||||
if (pSW->pSchema == NULL) {
|
||||
taosMemoryFree(pSW);
|
||||
return NULL;
|
||||
}
|
||||
memcpy(pSW->pSchema, pSchemaWrapper->pSchema, pSW->nCols * sizeof(SSchema));
|
||||
return pSW;
|
||||
}
|
||||
|
||||
static FORCE_INLINE void tDeleteSSchemaWrapper(SSchemaWrapper* pSchemaWrapper) {
|
||||
taosMemoryFree(pSchemaWrapper->pSchema);
|
||||
taosMemoryFree(pSchemaWrapper);
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t taosEncodeSSchema(void** buf, const SSchema* pSchema) {
|
||||
int32_t tlen = 0;
|
||||
tlen += taosEncodeFixedI8(buf, pSchema->type);
|
||||
tlen += taosEncodeFixedI8(buf, pSchema->flags);
|
||||
tlen += taosEncodeFixedI32(buf, pSchema->bytes);
|
||||
tlen += taosEncodeFixedI16(buf, pSchema->colId);
|
||||
tlen += taosEncodeString(buf, pSchema->name);
|
||||
return tlen;
|
||||
}
|
||||
|
||||
static FORCE_INLINE void* taosDecodeSSchema(const void* buf, SSchema* pSchema) {
|
||||
buf = taosDecodeFixedI8(buf, &pSchema->type);
|
||||
buf = taosDecodeFixedI8(buf, &pSchema->flags);
|
||||
buf = taosDecodeFixedI32(buf, &pSchema->bytes);
|
||||
buf = taosDecodeFixedI16(buf, &pSchema->colId);
|
||||
buf = taosDecodeStringTo(buf, pSchema->name);
|
||||
return (void*)buf;
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tEncodeSSchema(SEncoder* pEncoder, const SSchema* pSchema) {
|
||||
if (tEncodeI8(pEncoder, pSchema->type) < 0) return -1;
|
||||
if (tEncodeI8(pEncoder, pSchema->flags) < 0) return -1;
|
||||
if (tEncodeI32v(pEncoder, pSchema->bytes) < 0) return -1;
|
||||
if (tEncodeI16v(pEncoder, pSchema->colId) < 0) return -1;
|
||||
if (tEncodeCStr(pEncoder, pSchema->name) < 0) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tDecodeSSchema(SDecoder* pDecoder, SSchema* pSchema) {
|
||||
if (tDecodeI8(pDecoder, &pSchema->type) < 0) return -1;
|
||||
if (tDecodeI8(pDecoder, &pSchema->flags) < 0) return -1;
|
||||
if (tDecodeI32v(pDecoder, &pSchema->bytes) < 0) return -1;
|
||||
if (tDecodeI16v(pDecoder, &pSchema->colId) < 0) return -1;
|
||||
if (tDecodeCStrTo(pDecoder, pSchema->name) < 0) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t taosEncodeSSchemaWrapper(void** buf, const SSchemaWrapper* pSW) {
|
||||
int32_t tlen = 0;
|
||||
tlen += taosEncodeVariantI32(buf, pSW->nCols);
|
||||
tlen += taosEncodeVariantI32(buf, pSW->sver);
|
||||
for (int32_t i = 0; i < pSW->nCols; i++) {
|
||||
tlen += taosEncodeSSchema(buf, &pSW->pSchema[i]);
|
||||
}
|
||||
return tlen;
|
||||
}
|
||||
|
||||
static FORCE_INLINE void* taosDecodeSSchemaWrapper(const void* buf, SSchemaWrapper* pSW) {
|
||||
buf = taosDecodeVariantI32(buf, &pSW->nCols);
|
||||
buf = taosDecodeVariantI32(buf, &pSW->sver);
|
||||
pSW->pSchema = (SSchema*)taosMemoryCalloc(pSW->nCols, sizeof(SSchema));
|
||||
if (pSW->pSchema == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < pSW->nCols; i++) {
|
||||
buf = taosDecodeSSchema(buf, &pSW->pSchema[i]);
|
||||
}
|
||||
return (void*)buf;
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tEncodeSSchemaWrapper(SEncoder* pEncoder, const SSchemaWrapper* pSW) {
|
||||
if (tEncodeI32v(pEncoder, pSW->nCols) < 0) return -1;
|
||||
if (tEncodeI32v(pEncoder, pSW->sver) < 0) return -1;
|
||||
for (int32_t i = 0; i < pSW->nCols; i++) {
|
||||
if (tEncodeSSchema(pEncoder, &pSW->pSchema[i]) < 0) return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tDecodeSSchemaWrapper(SDecoder* pDecoder, SSchemaWrapper* pSW) {
|
||||
if (tDecodeI32v(pDecoder, &pSW->nCols) < 0) return -1;
|
||||
if (tDecodeI32v(pDecoder, &pSW->sver) < 0) return -1;
|
||||
|
||||
pSW->pSchema = (SSchema*)taosMemoryCalloc(pSW->nCols, sizeof(SSchema));
|
||||
if (pSW->pSchema == NULL) return -1;
|
||||
for (int32_t i = 0; i < pSW->nCols; i++) {
|
||||
if (tDecodeSSchema(pDecoder, &pSW->pSchema[i]) < 0) return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
char name[TSDB_TABLE_FNAME_LEN];
|
||||
char stb[TSDB_TABLE_FNAME_LEN];
|
||||
|
@ -2414,6 +2381,7 @@ typedef struct {
|
|||
typedef struct {
|
||||
SMsgHead head;
|
||||
char subKey[TSDB_SUBSCRIBE_KEY_LEN];
|
||||
int8_t withTbName;
|
||||
int32_t epoch;
|
||||
uint64_t reqId;
|
||||
int64_t consumerId;
|
||||
|
@ -2427,6 +2395,21 @@ typedef struct {
|
|||
SEpSet epSet;
|
||||
} SMqSubVgEp;
|
||||
|
||||
static FORCE_INLINE int32_t tEncodeSMqSubVgEp(void** buf, const SMqSubVgEp* pVgEp) {
|
||||
int32_t tlen = 0;
|
||||
tlen += taosEncodeFixedI32(buf, pVgEp->vgId);
|
||||
tlen += taosEncodeFixedI64(buf, pVgEp->offset);
|
||||
tlen += taosEncodeSEpSet(buf, &pVgEp->epSet);
|
||||
return tlen;
|
||||
}
|
||||
|
||||
static FORCE_INLINE void* tDecodeSMqSubVgEp(void* buf, SMqSubVgEp* pVgEp) {
|
||||
buf = taosDecodeFixedI32(buf, &pVgEp->vgId);
|
||||
buf = taosDecodeFixedI64(buf, &pVgEp->offset);
|
||||
buf = taosDecodeSEpSet(buf, &pVgEp->epSet);
|
||||
return buf;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
char topic[TSDB_TOPIC_FNAME_LEN];
|
||||
int8_t isSchemaAdaptive;
|
||||
|
@ -2434,6 +2417,43 @@ typedef struct {
|
|||
SSchemaWrapper schema;
|
||||
} SMqSubTopicEp;
|
||||
|
||||
static FORCE_INLINE int32_t tEncodeSMqSubTopicEp(void** buf, const SMqSubTopicEp* pTopicEp) {
|
||||
int32_t tlen = 0;
|
||||
tlen += taosEncodeString(buf, pTopicEp->topic);
|
||||
tlen += taosEncodeFixedI8(buf, pTopicEp->isSchemaAdaptive);
|
||||
int32_t sz = taosArrayGetSize(pTopicEp->vgs);
|
||||
tlen += taosEncodeFixedI32(buf, sz);
|
||||
for (int32_t i = 0; i < sz; i++) {
|
||||
SMqSubVgEp* pVgEp = (SMqSubVgEp*)taosArrayGet(pTopicEp->vgs, i);
|
||||
tlen += tEncodeSMqSubVgEp(buf, pVgEp);
|
||||
}
|
||||
tlen += taosEncodeSSchemaWrapper(buf, &pTopicEp->schema);
|
||||
return tlen;
|
||||
}
|
||||
|
||||
static FORCE_INLINE void* tDecodeSMqSubTopicEp(void* buf, SMqSubTopicEp* pTopicEp) {
|
||||
buf = taosDecodeStringTo(buf, pTopicEp->topic);
|
||||
buf = taosDecodeFixedI8(buf, &pTopicEp->isSchemaAdaptive);
|
||||
int32_t sz;
|
||||
buf = taosDecodeFixedI32(buf, &sz);
|
||||
pTopicEp->vgs = taosArrayInit(sz, sizeof(SMqSubVgEp));
|
||||
if (pTopicEp->vgs == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
for (int32_t i = 0; i < sz; i++) {
|
||||
SMqSubVgEp vgEp;
|
||||
buf = tDecodeSMqSubVgEp(buf, &vgEp);
|
||||
taosArrayPush(pTopicEp->vgs, &vgEp);
|
||||
}
|
||||
buf = taosDecodeSSchemaWrapper(buf, &pTopicEp->schema);
|
||||
return buf;
|
||||
}
|
||||
|
||||
static FORCE_INLINE void tDeleteSMqSubTopicEp(SMqSubTopicEp* pSubTopicEp) {
|
||||
// taosMemoryFree(pSubTopicEp->schema.pSchema);
|
||||
taosArrayDestroy(pSubTopicEp->vgs);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
SMqRspHead head;
|
||||
int64_t reqOffset;
|
||||
|
@ -2471,6 +2491,10 @@ static FORCE_INLINE int32_t tEncodeSMqDataBlkRsp(void** buf, const SMqDataBlkRsp
|
|||
SSchemaWrapper* pSW = (SSchemaWrapper*)taosArrayGetP(pRsp->blockSchema, i);
|
||||
tlen += taosEncodeSSchemaWrapper(buf, pSW);
|
||||
}
|
||||
if (pRsp->withTbName) {
|
||||
char* tbName = (char*)taosArrayGetP(pRsp->blockTbName, i);
|
||||
tlen += taosEncodeString(buf, tbName);
|
||||
}
|
||||
}
|
||||
}
|
||||
return tlen;
|
||||
|
@ -2483,6 +2507,7 @@ static FORCE_INLINE void* tDecodeSMqDataBlkRsp(const void* buf, SMqDataBlkRsp* p
|
|||
buf = taosDecodeFixedI32(buf, &pRsp->blockNum);
|
||||
pRsp->blockData = taosArrayInit(pRsp->blockNum, sizeof(void*));
|
||||
pRsp->blockDataLen = taosArrayInit(pRsp->blockNum, sizeof(void*));
|
||||
pRsp->blockTbName = taosArrayInit(pRsp->blockNum, sizeof(void*));
|
||||
pRsp->blockSchema = taosArrayInit(pRsp->blockNum, sizeof(void*));
|
||||
if (pRsp->blockNum != 0) {
|
||||
buf = taosDecodeFixedI8(buf, &pRsp->withTbName);
|
||||
|
@ -2501,6 +2526,11 @@ static FORCE_INLINE void* tDecodeSMqDataBlkRsp(const void* buf, SMqDataBlkRsp* p
|
|||
buf = taosDecodeSSchemaWrapper(buf, pSW);
|
||||
taosArrayPush(pRsp->blockSchema, &pSW);
|
||||
}
|
||||
if (pRsp->withTbName) {
|
||||
char* name = NULL;
|
||||
buf = taosDecodeString(buf, &name);
|
||||
taosArrayPush(pRsp->blockTbName, &name);
|
||||
}
|
||||
}
|
||||
}
|
||||
return (void*)buf;
|
||||
|
@ -2512,58 +2542,6 @@ typedef struct {
|
|||
SArray* topics; // SArray<SMqSubTopicEp>
|
||||
} SMqAskEpRsp;
|
||||
|
||||
static FORCE_INLINE void tDeleteSMqSubTopicEp(SMqSubTopicEp* pSubTopicEp) {
|
||||
// taosMemoryFree(pSubTopicEp->schema.pSchema);
|
||||
taosArrayDestroy(pSubTopicEp->vgs);
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tEncodeSMqSubVgEp(void** buf, const SMqSubVgEp* pVgEp) {
|
||||
int32_t tlen = 0;
|
||||
tlen += taosEncodeFixedI32(buf, pVgEp->vgId);
|
||||
tlen += taosEncodeFixedI64(buf, pVgEp->offset);
|
||||
tlen += taosEncodeSEpSet(buf, &pVgEp->epSet);
|
||||
return tlen;
|
||||
}
|
||||
|
||||
static FORCE_INLINE void* tDecodeSMqSubVgEp(void* buf, SMqSubVgEp* pVgEp) {
|
||||
buf = taosDecodeFixedI32(buf, &pVgEp->vgId);
|
||||
buf = taosDecodeFixedI64(buf, &pVgEp->offset);
|
||||
buf = taosDecodeSEpSet(buf, &pVgEp->epSet);
|
||||
return buf;
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tEncodeSMqSubTopicEp(void** buf, const SMqSubTopicEp* pTopicEp) {
|
||||
int32_t tlen = 0;
|
||||
tlen += taosEncodeString(buf, pTopicEp->topic);
|
||||
tlen += taosEncodeFixedI8(buf, pTopicEp->isSchemaAdaptive);
|
||||
int32_t sz = taosArrayGetSize(pTopicEp->vgs);
|
||||
tlen += taosEncodeFixedI32(buf, sz);
|
||||
for (int32_t i = 0; i < sz; i++) {
|
||||
SMqSubVgEp* pVgEp = (SMqSubVgEp*)taosArrayGet(pTopicEp->vgs, i);
|
||||
tlen += tEncodeSMqSubVgEp(buf, pVgEp);
|
||||
}
|
||||
tlen += taosEncodeSSchemaWrapper(buf, &pTopicEp->schema);
|
||||
return tlen;
|
||||
}
|
||||
|
||||
static FORCE_INLINE void* tDecodeSMqSubTopicEp(void* buf, SMqSubTopicEp* pTopicEp) {
|
||||
buf = taosDecodeStringTo(buf, pTopicEp->topic);
|
||||
buf = taosDecodeFixedI8(buf, &pTopicEp->isSchemaAdaptive);
|
||||
int32_t sz;
|
||||
buf = taosDecodeFixedI32(buf, &sz);
|
||||
pTopicEp->vgs = taosArrayInit(sz, sizeof(SMqSubVgEp));
|
||||
if (pTopicEp->vgs == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
for (int32_t i = 0; i < sz; i++) {
|
||||
SMqSubVgEp vgEp;
|
||||
buf = tDecodeSMqSubVgEp(buf, &vgEp);
|
||||
taosArrayPush(pTopicEp->vgs, &vgEp);
|
||||
}
|
||||
buf = taosDecodeSSchemaWrapper(buf, &pTopicEp->schema);
|
||||
return buf;
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tEncodeSMqAskEpRsp(void** buf, const SMqAskEpRsp* pRsp) {
|
||||
int32_t tlen = 0;
|
||||
// tlen += taosEncodeString(buf, pRsp->cgroup);
|
||||
|
|
|
@ -217,6 +217,7 @@ enum {
|
|||
TD_DEF_MSG_TYPE(TDMT_VND_SYNC_UNKNOWN, "vnode-sync-unknown", NULL, NULL)
|
||||
TD_DEF_MSG_TYPE(TDMT_VND_SYNC_COMMON_RESPONSE, "vnode-sync-common-response", NULL, NULL)
|
||||
TD_DEF_MSG_TYPE(TDMT_VND_SYNC_APPLY_MSG, "vnode-sync-apply-msg", NULL, NULL)
|
||||
TD_DEF_MSG_TYPE(TDMT_VND_SYNC_CONFIG_CHANGE, "vnode-sync-config-change", NULL, NULL)
|
||||
|
||||
TD_DEF_MSG_TYPE(TDMT_VND_SYNC_VNODE, "vnode-sync-vnode", NULL, NULL)
|
||||
TD_DEF_MSG_TYPE(TDMT_VND_ALTER_VNODE, "vnode-alter-vnode", NULL, NULL)
|
||||
|
|
|
@ -50,6 +50,7 @@ typedef struct {
|
|||
#define varDataLenByData(v) (*(VarDataLenT *)(((char *)(v)) - VARSTR_HEADER_SIZE))
|
||||
#define varDataSetLen(v, _len) (((VarDataLenT *)(v))[0] = (VarDataLenT)(_len))
|
||||
#define IS_VAR_DATA_TYPE(t) (((t) == TSDB_DATA_TYPE_VARCHAR) || ((t) == TSDB_DATA_TYPE_NCHAR) || ((t) == TSDB_DATA_TYPE_JSON))
|
||||
#define IS_STR_DATA_TYPE(t) (((t) == TSDB_DATA_TYPE_VARCHAR) || ((t) == TSDB_DATA_TYPE_NCHAR))
|
||||
|
||||
#define varDataNetLen(v) (htons(((VarDataLenT *)(v))[0]))
|
||||
#define varDataNetTLen(v) (sizeof(VarDataLenT) + varDataNetLen(v))
|
||||
|
|
|
@ -36,12 +36,11 @@ typedef struct SVariant {
|
|||
};
|
||||
} SVariant;
|
||||
|
||||
int32_t toInteger(const char *z, int32_t n, int32_t base, int64_t *value, bool *issigned);
|
||||
int32_t toInteger(const char *z, int32_t n, int32_t base, int64_t *value);
|
||||
int32_t toUInteger(const char *z, int32_t n, int32_t base, uint64_t *value);
|
||||
|
||||
bool taosVariantIsValid(SVariant *pVar);
|
||||
|
||||
void taosVariantCreate(SVariant *pVar, const char *z, int32_t n, int32_t type);
|
||||
|
||||
void taosVariantCreateFromBinary(SVariant *pVar, const char *pz, size_t len, uint32_t type);
|
||||
|
||||
void taosVariantDestroy(SVariant *pV);
|
||||
|
@ -59,10 +58,10 @@ int32_t taosVariantDumpEx(SVariant *pVariant, char *payload, int16_t type, bool
|
|||
#endif
|
||||
|
||||
int32_t taosVariantTypeSetType(SVariant *pVariant, char type);
|
||||
char * taosVariantGet(SVariant *pVar, int32_t type);
|
||||
char *taosVariantGet(SVariant *pVar, int32_t type);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_TD_COMMON_VARIANT_H_*/
|
||||
#endif /*_TD_COMMON_VARIANT_H_*/
|
||||
|
|
|
@ -39,15 +39,6 @@ extern "C" {
|
|||
//======================================================================================
|
||||
//begin API to taosd and qworker
|
||||
|
||||
enum {
|
||||
UDFC_CODE_STOPPING = -1,
|
||||
UDFC_CODE_PIPE_READ_ERR = -2,
|
||||
UDFC_CODE_CONNECT_PIPE_ERR = -3,
|
||||
UDFC_CODE_LOAD_UDF_FAILURE = -4,
|
||||
UDFC_CODE_INVALID_STATE = -5,
|
||||
UDFC_CODE_NO_PIPE = -6,
|
||||
};
|
||||
|
||||
typedef void *UdfcFuncHandle;
|
||||
|
||||
/**
|
||||
|
@ -89,6 +80,7 @@ typedef struct SUdfColumnData {
|
|||
|
||||
typedef struct SUdfColumn {
|
||||
SUdfColumnMeta colMeta;
|
||||
bool hasNull;
|
||||
SUdfColumnData colData;
|
||||
} SUdfColumn;
|
||||
|
||||
|
@ -232,6 +224,7 @@ static FORCE_INLINE void udfColDataSetNull(SUdfColumn* pColumn, int32_t row) {
|
|||
} else {
|
||||
udfColDataSetNull_f(pColumn, row);
|
||||
}
|
||||
pColumn->hasNull = true;
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t udfColDataSet(SUdfColumn* pColumn, uint32_t currentRow, const char* pData, bool isNull) {
|
||||
|
|
|
@ -232,9 +232,9 @@ typedef struct SSelectStmt {
|
|||
char stmtName[TSDB_TABLE_NAME_LEN];
|
||||
uint8_t precision;
|
||||
bool isEmptyResult;
|
||||
bool isTimeOrderQuery;
|
||||
bool hasAggFuncs;
|
||||
bool hasRepeatScanFuncs;
|
||||
bool isTimeOrderQuery;
|
||||
} SSelectStmt;
|
||||
|
||||
typedef enum ESetOperatorType { SET_OP_TYPE_UNION_ALL = 1, SET_OP_TYPE_UNION } ESetOperatorType;
|
||||
|
@ -324,6 +324,7 @@ typedef struct SQuery {
|
|||
SArray* pTableList;
|
||||
bool showRewrite;
|
||||
int32_t placeholderNum;
|
||||
SArray* pPlaceholderValues;
|
||||
} SQuery;
|
||||
|
||||
void nodesWalkSelectStmt(SSelectStmt* pSelect, ESqlClause clause, FNodeWalker walker, void* pContext);
|
||||
|
|
|
@ -26,8 +26,7 @@ extern "C" {
|
|||
typedef struct SStmtCallback {
|
||||
TAOS_STMT* pStmt;
|
||||
int32_t (*getTbNameFn)(TAOS_STMT*, char**);
|
||||
int32_t (*setBindInfoFn)(TAOS_STMT*, STableMeta*, void*);
|
||||
int32_t (*setExecInfoFn)(TAOS_STMT*, SHashObj*, SHashObj*);
|
||||
int32_t (*setInfoFn)(TAOS_STMT*, STableMeta*, void*, char*, bool, SHashObj*, SHashObj*);
|
||||
int32_t (*getExecInfoFn)(TAOS_STMT*, SHashObj**, SHashObj**);
|
||||
} SStmtCallback;
|
||||
|
||||
|
@ -48,20 +47,23 @@ typedef struct SParseContext {
|
|||
bool isSuperUser;
|
||||
} SParseContext;
|
||||
|
||||
int32_t qParseQuerySql(SParseContext* pCxt, SQuery** pQuery);
|
||||
int32_t qParseSql(SParseContext* pCxt, SQuery** pQuery);
|
||||
bool isInsertSql(const char* pStr, size_t length);
|
||||
|
||||
void qDestroyQuery(SQuery* pQueryNode);
|
||||
|
||||
int32_t qExtractResultSchema(const SNode* pRoot, int32_t* numOfCols, SSchema** pSchema);
|
||||
|
||||
int32_t qBuildStmtOutput(SQuery* pQuery, SHashObj* pVgHash, SHashObj* pBlockHash);
|
||||
int32_t qResetStmtDataBlock(void* block, bool keepBuf);
|
||||
int32_t qCloneStmtDataBlock(void** pDst, void* pSrc);
|
||||
void qFreeStmtDataBlock(void* pDataBlock);
|
||||
int32_t qRebuildStmtDataBlock(void** pDst, void* pSrc);
|
||||
void qDestroyStmtDataBlock(void* pBlock);
|
||||
int32_t qBuildStmtOutput(SQuery* pQuery, SHashObj* pVgHash, SHashObj* pBlockHash);
|
||||
int32_t qResetStmtDataBlock(void* block, bool keepBuf);
|
||||
int32_t qCloneStmtDataBlock(void** pDst, void* pSrc);
|
||||
void qFreeStmtDataBlock(void* pDataBlock);
|
||||
int32_t qRebuildStmtDataBlock(void** pDst, void* pSrc, uint64_t uid, int32_t vgId);
|
||||
void qDestroyStmtDataBlock(void* pBlock);
|
||||
STableMeta* qGetTableMetaInDataBlock(void* pDataBlock);
|
||||
|
||||
int32_t qStmtBindParams(SQuery* pQuery, TAOS_MULTI_BIND* pParams, int32_t colIdx, uint64_t queryId);
|
||||
int32_t qStmtParseQuerySql(SParseContext* pCxt, SQuery* pQuery);
|
||||
int32_t qBindStmtColsValue(void* pBlock, TAOS_MULTI_BIND* bind, char* msgBuf, int32_t msgBufLen);
|
||||
int32_t qBindStmtSingleColValue(void* pBlock, TAOS_MULTI_BIND* bind, char* msgBuf, int32_t msgBufLen, int32_t colIdx,
|
||||
int32_t rowNum);
|
||||
|
|
|
@ -48,7 +48,8 @@ int32_t qCreateQueryPlan(SPlanContext* pCxt, SQueryPlan** pPlan, SArray* pExecNo
|
|||
// @pSource one execution location of this group of datasource subplans
|
||||
int32_t qSetSubplanExecutionNode(SSubplan* pSubplan, int32_t groupId, SDownstreamSourceNode* pSource);
|
||||
|
||||
int32_t qStmtBindParam(SQueryPlan* pPlan, TAOS_MULTI_BIND* pParams, int32_t colIdx, uint64_t queryId);
|
||||
int32_t qStmtBindParam(SQueryPlan* pPlan, TAOS_MULTI_BIND* pParams, int32_t colIdx, uint64_t queryId,
|
||||
bool* pEmptyResult);
|
||||
|
||||
// Convert to subplan to string for the scheduler to send to the executor
|
||||
int32_t qSubPlanToString(const SSubplan* pSubplan, char** pStr, int32_t* pLen);
|
||||
|
|
|
@ -56,6 +56,7 @@ typedef struct SQueryResult {
|
|||
uint64_t numOfRows;
|
||||
int32_t msgSize;
|
||||
char *msg;
|
||||
void *res;
|
||||
} SQueryResult;
|
||||
|
||||
typedef struct STaskInfo {
|
||||
|
@ -71,7 +72,7 @@ int32_t schedulerInit(SSchedulerCfg *cfg);
|
|||
* @param nodeList Qnode/Vnode address list, element is SQueryNodeAddr
|
||||
* @return
|
||||
*/
|
||||
int32_t schedulerExecJob(void *transport, SArray *nodeList, SQueryPlan *pDag, int64_t *pJob, const char *sql, int64_t startTs, SQueryResult *pRes);
|
||||
int32_t schedulerExecJob(void *transport, SArray *nodeList, SQueryPlan *pDag, int64_t *pJob, const char *sql, int64_t startTs, bool needRes, SQueryResult *pRes);
|
||||
|
||||
/**
|
||||
* Process the query job, generated according to the query physical plan.
|
||||
|
|
|
@ -208,6 +208,7 @@ int32_t walReadWithFp(SWal *, FWalWrite writeFp, int64_t verStart, int32_t readN
|
|||
int64_t walGetFirstVer(SWal *);
|
||||
int64_t walGetSnapshotVer(SWal *);
|
||||
int64_t walGetLastVer(SWal *);
|
||||
int64_t walGetCommittedVer(SWal *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -634,6 +634,7 @@ int32_t* taosGetErrno();
|
|||
#define TSDB_CODE_PAR_INVALID_TAGS_NUM TAOS_DEF_ERROR_CODE(0, 0x2643)
|
||||
#define TSDB_CODE_PAR_PERMISSION_DENIED TAOS_DEF_ERROR_CODE(0, 0x2644)
|
||||
#define TSDB_CODE_PAR_INVALID_STREAM_QUERY TAOS_DEF_ERROR_CODE(0, 0x2645)
|
||||
#define TSDB_CODE_PAR_INVALID_INTERNAL_PK TAOS_DEF_ERROR_CODE(0, 0x2646)
|
||||
|
||||
//planner
|
||||
#define TSDB_CODE_PLAN_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x2700)
|
||||
|
@ -645,7 +646,16 @@ int32_t* taosGetErrno();
|
|||
#define TSDB_CODE_FUNC_FUNTION_PARA_NUM TAOS_DEF_ERROR_CODE(0, 0x2801)
|
||||
#define TSDB_CODE_FUNC_FUNTION_PARA_TYPE TAOS_DEF_ERROR_CODE(0, 0x2802)
|
||||
#define TSDB_CODE_FUNC_FUNTION_PARA_VALUE TAOS_DEF_ERROR_CODE(0, 0x2803)
|
||||
#define TSDB_CODE_FUNC_INVALID_FUNTION TAOS_DEF_ERROR_CODE(0, 0x2604)
|
||||
#define TSDB_CODE_FUNC_INVALID_FUNTION TAOS_DEF_ERROR_CODE(0, 0x2804)
|
||||
|
||||
//udf
|
||||
#define TSDB_CODE_UDF_STOPPING TAOS_DEF_ERROR_CODE(0, 0x2901)
|
||||
#define TSDB_CODE_UDF_PIPE_READ_ERR TAOS_DEF_ERROR_CODE(0, 0x2902)
|
||||
#define TSDB_CODE_UDF_PIPE_CONNECT_ERR TAOS_DEF_ERROR_CODE(0, 0x2903)
|
||||
#define TSDB_CODE_UDF_PIPE_NO_PIPE TAOS_DEF_ERROR_CODE(0, 0x2904)
|
||||
#define TSDB_CODE_UDF_LOAD_UDF_FAILURE TAOS_DEF_ERROR_CODE(0, 0x2905)
|
||||
#define TSDB_CODE_UDF_INVALID_STATE TAOS_DEF_ERROR_CODE(0, 0x2906)
|
||||
#define TSDB_CODE_UDF_INVALID_INPUT TAOS_DEF_ERROR_CODE(0, 0x2907)
|
||||
|
||||
#define TSDB_CODE_SML_INVALID_PROTOCOL_TYPE TAOS_DEF_ERROR_CODE(0, 0x3000)
|
||||
#define TSDB_CODE_SML_INVALID_PRECISION_TYPE TAOS_DEF_ERROR_CODE(0, 0x3001)
|
||||
|
|
|
@ -59,6 +59,21 @@ static FORCE_INLINE void *taosDecodeFixedI8(const void *buf, int8_t *value) {
|
|||
|
||||
static FORCE_INLINE void *taosSkipFixedLen(const void *buf, size_t len) { return POINTER_SHIFT(buf, len); }
|
||||
|
||||
// --- Bool
|
||||
|
||||
static FORCE_INLINE int32_t taosEncodeFixedBool(void **buf, bool value) {
|
||||
if (buf != NULL) {
|
||||
((int8_t *)(*buf))[0] = value ? 1 : 0;
|
||||
*buf = POINTER_SHIFT(*buf, sizeof(int8_t));
|
||||
}
|
||||
return (int32_t)sizeof(int8_t);
|
||||
}
|
||||
|
||||
static FORCE_INLINE void *taosDecodeFixedBool(const void *buf, bool *value) {
|
||||
*value = ((int8_t *)buf)[0] == 0 ? false : true;
|
||||
return POINTER_SHIFT(buf, sizeof(int8_t));
|
||||
}
|
||||
|
||||
// ---- Fixed U16
|
||||
static FORCE_INLINE int32_t taosEncodeFixedU16(void **buf, uint16_t value) {
|
||||
if (buf != NULL) {
|
||||
|
|
|
@ -457,6 +457,55 @@ static FORCE_INLINE void* tDecoderMalloc(SDecoder* pCoder, int32_t size) {
|
|||
return p;
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tPutBinary(uint8_t* p, const uint8_t* pData, uint32_t nData) {
|
||||
int n = 0;
|
||||
uint32_t v = nData;
|
||||
|
||||
for (;;) {
|
||||
if (v <= 0x7f) {
|
||||
if (p) p[n] = v;
|
||||
n++;
|
||||
break;
|
||||
}
|
||||
|
||||
if (p) p[n] = (v & 0x7f) | 0x80;
|
||||
n++;
|
||||
v >>= 7;
|
||||
}
|
||||
|
||||
if (p) {
|
||||
memcpy(p + n, pData, nData);
|
||||
}
|
||||
n += nData;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tGetBinary(const uint8_t* p, const uint8_t** ppData, uint32_t* nData) {
|
||||
int32_t n = 0;
|
||||
uint32_t tv = 0;
|
||||
uint32_t t;
|
||||
|
||||
for (;;) {
|
||||
if (p[n] <= 0x7f) {
|
||||
t = p[n];
|
||||
tv |= (t << (7 * n));
|
||||
n++;
|
||||
break;
|
||||
}
|
||||
|
||||
t = p[n] & 0x7f;
|
||||
tv |= (t << (7 * n));
|
||||
n++;
|
||||
}
|
||||
|
||||
if (nData) *nData = n;
|
||||
if (ppData) *ppData = p + n;
|
||||
|
||||
n += tv;
|
||||
return n;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -307,9 +307,9 @@ int hbAddConnInfo(SAppHbMgr* pAppHbMgr, SClientHbKey connKey, void* key, void* v
|
|||
// --- mq
|
||||
void hbMgrInitMqHbRspHandle();
|
||||
|
||||
SRequestObj* launchQueryImpl(SRequestObj* pRequest, SQuery* pQuery, int32_t code, bool keepQuery);
|
||||
SRequestObj* launchQueryImpl(SRequestObj* pRequest, SQuery* pQuery, int32_t code, bool keepQuery, void** res);
|
||||
int32_t getQueryPlan(SRequestObj* pRequest, SQuery* pQuery, SArray** pNodeList);
|
||||
int32_t scheduleQuery(SRequestObj* pRequest, SQueryPlan* pDag, SArray* pNodeList);
|
||||
int32_t scheduleQuery(SRequestObj* pRequest, SQueryPlan* pDag, SArray* pNodeList, void** res);
|
||||
int32_t refreshMeta(STscObj* pTscObj, SRequestObj* pRequest);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -55,6 +55,7 @@ typedef struct SStmtQueryResInfo {
|
|||
|
||||
typedef struct SStmtBindInfo {
|
||||
bool needParse;
|
||||
bool inExecCache;
|
||||
uint64_t tbUid;
|
||||
uint64_t tbSuid;
|
||||
int32_t sBindRowNum;
|
||||
|
@ -62,21 +63,24 @@ typedef struct SStmtBindInfo {
|
|||
int8_t tbType;
|
||||
bool tagsCached;
|
||||
void* boundTags;
|
||||
char* tbName;
|
||||
char tbName[TSDB_TABLE_FNAME_LEN];;
|
||||
char tbFName[TSDB_TABLE_FNAME_LEN];
|
||||
char stbFName[TSDB_TABLE_FNAME_LEN];
|
||||
SName sname;
|
||||
} SStmtBindInfo;
|
||||
|
||||
typedef struct SStmtExecInfo {
|
||||
int32_t affectedRows;
|
||||
bool emptyRes;
|
||||
SRequestObj* pRequest;
|
||||
SHashObj* pVgHash;
|
||||
SHashObj* pBlockHash;
|
||||
bool autoCreateTbl;
|
||||
} SStmtExecInfo;
|
||||
|
||||
typedef struct SStmtSQLInfo {
|
||||
STMT_TYPE type;
|
||||
STMT_STATUS status;
|
||||
bool autoCreate;
|
||||
uint64_t runTimes;
|
||||
SHashObj* pTableCache; //SHash<SStmtTableCache>
|
||||
SQuery* pQuery;
|
||||
|
@ -85,6 +89,7 @@ typedef struct SStmtSQLInfo {
|
|||
SArray* nodeList;
|
||||
SQueryPlan* pQueryPlan;
|
||||
SStmtQueryResInfo queryRes;
|
||||
bool autoCreateTbl;
|
||||
} SStmtSQLInfo;
|
||||
|
||||
typedef struct STscStmt {
|
||||
|
|
|
@ -180,7 +180,7 @@ int32_t parseSql(SRequestObj* pRequest, bool topicQuery, SQuery** pQuery, SStmtC
|
|||
return code;
|
||||
}
|
||||
|
||||
code = qParseQuerySql(&cxt, pQuery);
|
||||
code = qParseSql(&cxt, pQuery);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
if ((*pQuery)->haveResultSet) {
|
||||
setResSchemaInfo(&pRequest->body.resInfo, (*pQuery)->pResSchema, (*pQuery)->numOfResCols);
|
||||
|
@ -286,12 +286,12 @@ void setResPrecision(SReqResultInfo* pResInfo, int32_t precision) {
|
|||
pResInfo->precision = precision;
|
||||
}
|
||||
|
||||
int32_t scheduleQuery(SRequestObj* pRequest, SQueryPlan* pDag, SArray* pNodeList) {
|
||||
int32_t scheduleQuery(SRequestObj* pRequest, SQueryPlan* pDag, SArray* pNodeList, void** pRes) {
|
||||
void* pTransporter = pRequest->pTscObj->pAppInfo->pTransporter;
|
||||
|
||||
SQueryResult res = {.code = 0, .numOfRows = 0, .msgSize = ERROR_MSG_BUF_DEFAULT_SIZE, .msg = pRequest->msgBuf};
|
||||
int32_t code = schedulerExecJob(pTransporter, pNodeList, pDag, &pRequest->body.queryJob, pRequest->sqlstr,
|
||||
pRequest->metric.start, &res);
|
||||
pRequest->metric.start, NULL != pRes, &res);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
if (pRequest->body.queryJob != 0) {
|
||||
schedulerFreeJob(pRequest->body.queryJob);
|
||||
|
@ -310,6 +310,10 @@ int32_t scheduleQuery(SRequestObj* pRequest, SQueryPlan* pDag, SArray* pNodeList
|
|||
}
|
||||
}
|
||||
|
||||
if (pRes) {
|
||||
*pRes = res.res;
|
||||
}
|
||||
|
||||
pRequest->code = res.code;
|
||||
terrno = res.code;
|
||||
return pRequest->code;
|
||||
|
@ -320,7 +324,7 @@ int32_t getQueryPlan(SRequestObj* pRequest, SQuery* pQuery, SArray** pNodeList)
|
|||
return getPlan(pRequest, pQuery, &pRequest->body.pDag, *pNodeList);
|
||||
}
|
||||
|
||||
SRequestObj* launchQueryImpl(SRequestObj* pRequest, SQuery* pQuery, int32_t code, bool keepQuery) {
|
||||
SRequestObj* launchQueryImpl(SRequestObj* pRequest, SQuery* pQuery, int32_t code, bool keepQuery, void** res) {
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
switch (pQuery->execMode) {
|
||||
case QUERY_EXEC_MODE_LOCAL:
|
||||
|
@ -333,7 +337,7 @@ SRequestObj* launchQueryImpl(SRequestObj* pRequest, SQuery* pQuery, int32_t code
|
|||
SArray* pNodeList = taosArrayInit(4, sizeof(struct SQueryNodeAddr));
|
||||
code = getPlan(pRequest, pQuery, &pRequest->body.pDag, pNodeList);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = scheduleQuery(pRequest, pRequest->body.pDag, pNodeList);
|
||||
code = scheduleQuery(pRequest, pRequest->body.pDag, pNodeList, res);
|
||||
}
|
||||
taosArrayDestroy(pNodeList);
|
||||
break;
|
||||
|
@ -373,7 +377,7 @@ SRequestObj* launchQuery(STscObj* pTscObj, const char* sql, int sqlLen) {
|
|||
return pRequest;
|
||||
}
|
||||
|
||||
return launchQueryImpl(pRequest, pQuery, code, false);
|
||||
return launchQueryImpl(pRequest, pQuery, code, false, NULL);
|
||||
}
|
||||
|
||||
int32_t refreshMeta(STscObj* pTscObj, SRequestObj* pRequest) {
|
||||
|
@ -550,8 +554,8 @@ static SMsgSendInfo* buildConnectMsg(SRequestObj* pRequest) {
|
|||
}
|
||||
taosMemoryFreeClear(db);
|
||||
|
||||
connectReq.connType = pObj->connType;
|
||||
connectReq.pid = htonl(appInfo.pid);
|
||||
connectReq.connType = pObj->connType;
|
||||
connectReq.pid = htonl(appInfo.pid);
|
||||
connectReq.startTime = htobe64(appInfo.startTime);
|
||||
|
||||
tstrncpy(connectReq.app, appInfo.appName, sizeof(connectReq.app));
|
||||
|
|
|
@ -58,7 +58,7 @@ int32_t processConnectRsp(void* param, const SDataBuf* pMsg, int32_t code) {
|
|||
return code;
|
||||
}
|
||||
|
||||
if (!isEpsetEqual(&pTscObj->pAppInfo->mgmtEp.epSet, &connectRsp.epSet)) {
|
||||
if (connectRsp.dnodeNum > 1 && !isEpsetEqual(&pTscObj->pAppInfo->mgmtEp.epSet, &connectRsp.epSet)) {
|
||||
updateEpSet_s(&pTscObj->pAppInfo->mgmtEp, &connectRsp.epSet);
|
||||
}
|
||||
|
||||
|
|
|
@ -427,7 +427,7 @@ static int32_t smlModifyDBSchemas(SSmlHandle* info) {
|
|||
code = catalogGetSTableMeta(info->pCatalog, info->taos->pAppInfo->pTransporter, &ep, &pName, &pTableMeta);
|
||||
|
||||
if (code == TSDB_CODE_PAR_TABLE_NOT_EXIST || code == TSDB_CODE_MND_INVALID_STB) {
|
||||
SSchemaAction schemaAction = {.action = SCHEMA_ACTION_CREATE_STABLE};
|
||||
SSchemaAction schemaAction = { SCHEMA_ACTION_CREATE_STABLE, 0};
|
||||
memcpy(schemaAction.createSTable.sTableName, superTable, superTableLen);
|
||||
schemaAction.createSTable.tags = sTableData->tags;
|
||||
schemaAction.createSTable.fields = sTableData->cols;
|
||||
|
@ -1987,6 +1987,7 @@ static int32_t smlParseInfluxLine(SSmlHandle* info, const char* sql) {
|
|||
(*oneTable)->sTableNameLen = elements.measureLen;
|
||||
RandTableName rName = {.tags=(*oneTable)->tags, .sTableName=(*oneTable)->sTableName, .sTableNameLen=(uint8_t)(*oneTable)->sTableNameLen,
|
||||
.childTableName=(*oneTable)->childTableName};
|
||||
|
||||
buildChildTableName(&rName);
|
||||
(*oneTable)->uid = rName.uid;
|
||||
}
|
||||
|
@ -2157,7 +2158,7 @@ static int32_t smlInsertData(SSmlHandle* info) {
|
|||
}
|
||||
info->cost.insertRpcTime = taosGetTimestampUs();
|
||||
|
||||
launchQueryImpl(info->pRequest, info->pQuery, TSDB_CODE_SUCCESS, true);
|
||||
launchQueryImpl(info->pRequest, info->pQuery, TSDB_CODE_SUCCESS, true, NULL);
|
||||
|
||||
info->affectedRows = taos_affected_rows(info->pRequest);
|
||||
return info->pRequest->code;
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
|
||||
#include "clientInt.h"
|
||||
#include "clientLog.h"
|
||||
#include "clientStmt.h"
|
||||
#include "tdef.h"
|
||||
|
||||
#include "clientStmt.h"
|
||||
|
||||
int32_t stmtSwitchStatus(STscStmt* pStmt, STMT_STATUS newStatus) {
|
||||
int32_t code = 0;
|
||||
|
||||
|
||||
switch (newStatus) {
|
||||
case STMT_PREPARE:
|
||||
break;
|
||||
|
@ -29,11 +30,11 @@ int32_t stmtSwitchStatus(STscStmt* pStmt, STMT_STATUS newStatus) {
|
|||
if (STMT_STATUS_EQ(INIT) || STMT_STATUS_EQ(BIND_COL)) {
|
||||
code = TSDB_CODE_TSC_STMT_API_ERROR;
|
||||
}
|
||||
/*
|
||||
if ((pStmt->sql.type == STMT_TYPE_MULTI_INSERT) && ()) {
|
||||
code = TSDB_CODE_TSC_STMT_API_ERROR;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
if ((pStmt->sql.type == STMT_TYPE_MULTI_INSERT) && ()) {
|
||||
code = TSDB_CODE_TSC_STMT_API_ERROR;
|
||||
}
|
||||
*/
|
||||
break;
|
||||
case STMT_BIND_COL:
|
||||
if (STMT_STATUS_EQ(INIT) || STMT_STATUS_EQ(BIND)) {
|
||||
|
@ -62,13 +63,12 @@ int32_t stmtSwitchStatus(STscStmt* pStmt, STMT_STATUS newStatus) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int32_t stmtGetTbName(TAOS_STMT *stmt, char **tbName) {
|
||||
int32_t stmtGetTbName(TAOS_STMT* stmt, char** tbName) {
|
||||
STscStmt* pStmt = (STscStmt*)stmt;
|
||||
|
||||
pStmt->sql.type = STMT_TYPE_MULTI_INSERT;
|
||||
|
||||
if (NULL == pStmt->bInfo.tbName) {
|
||||
if ('\0' == pStmt->bInfo.tbName[0]) {
|
||||
tscError("no table name set");
|
||||
STMT_ERR_RET(TSDB_CODE_TSC_STMT_TBNAME_ERROR);
|
||||
}
|
||||
|
@ -79,10 +79,10 @@ int32_t stmtGetTbName(TAOS_STMT *stmt, char **tbName) {
|
|||
}
|
||||
|
||||
int32_t stmtBackupQueryFields(STscStmt* pStmt) {
|
||||
SStmtQueryResInfo *pRes = &pStmt->sql.queryRes;
|
||||
SStmtQueryResInfo* pRes = &pStmt->sql.queryRes;
|
||||
pRes->numOfCols = pStmt->exec.pRequest->body.resInfo.numOfCols;
|
||||
pRes->precision = pStmt->exec.pRequest->body.resInfo.precision;
|
||||
|
||||
|
||||
int32_t size = pRes->numOfCols * sizeof(TAOS_FIELD);
|
||||
pRes->fields = taosMemoryMalloc(size);
|
||||
pRes->userFields = taosMemoryMalloc(size);
|
||||
|
@ -96,9 +96,9 @@ int32_t stmtBackupQueryFields(STscStmt* pStmt) {
|
|||
}
|
||||
|
||||
int32_t stmtRestoreQueryFields(STscStmt* pStmt) {
|
||||
SStmtQueryResInfo *pRes = &pStmt->sql.queryRes;
|
||||
int32_t size = pRes->numOfCols * sizeof(TAOS_FIELD);
|
||||
|
||||
SStmtQueryResInfo* pRes = &pStmt->sql.queryRes;
|
||||
int32_t size = pRes->numOfCols * sizeof(TAOS_FIELD);
|
||||
|
||||
pStmt->exec.pRequest->body.resInfo.numOfCols = pRes->numOfCols;
|
||||
pStmt->exec.pRequest->body.resInfo.precision = pRes->precision;
|
||||
|
||||
|
@ -121,9 +121,12 @@ int32_t stmtRestoreQueryFields(STscStmt* pStmt) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t stmtSetBindInfo(TAOS_STMT* stmt, STableMeta* pTableMeta, void* tags) {
|
||||
int32_t stmtUpdateBindInfo(TAOS_STMT* stmt, STableMeta* pTableMeta, void* tags, char* tbFName) {
|
||||
STscStmt* pStmt = (STscStmt*)stmt;
|
||||
|
||||
strncpy(pStmt->bInfo.tbFName, tbFName, sizeof(pStmt->bInfo.tbFName) - 1);
|
||||
pStmt->bInfo.tbFName[sizeof(pStmt->bInfo.tbFName) - 1] = 0;
|
||||
|
||||
pStmt->bInfo.tbUid = pTableMeta->uid;
|
||||
pStmt->bInfo.tbSuid = pTableMeta->suid;
|
||||
pStmt->bInfo.tbType = pTableMeta->tableType;
|
||||
|
@ -133,15 +136,28 @@ int32_t stmtSetBindInfo(TAOS_STMT* stmt, STableMeta* pTableMeta, void* tags) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t stmtSetExecInfo(TAOS_STMT* stmt, SHashObj* pVgHash, SHashObj* pBlockHash) {
|
||||
int32_t stmtUpdateExecInfo(TAOS_STMT* stmt, SHashObj* pVgHash, SHashObj* pBlockHash, bool autoCreateTbl) {
|
||||
STscStmt* pStmt = (STscStmt*)stmt;
|
||||
|
||||
pStmt->exec.pVgHash = pVgHash;
|
||||
pStmt->exec.pBlockHash = pBlockHash;
|
||||
pStmt->exec.autoCreateTbl = autoCreateTbl;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t stmtUpdateInfo(TAOS_STMT* stmt, STableMeta* pTableMeta, void* tags, char* tbFName, bool autoCreateTbl, SHashObj* pVgHash, SHashObj* pBlockHash) {
|
||||
STscStmt* pStmt = (STscStmt*)stmt;
|
||||
|
||||
STMT_ERR_RET(stmtUpdateBindInfo(stmt, pTableMeta, tags, tbFName));
|
||||
STMT_ERR_RET(stmtUpdateExecInfo(stmt, pVgHash, pBlockHash, autoCreateTbl));
|
||||
|
||||
pStmt->sql.autoCreateTbl = autoCreateTbl;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int32_t stmtGetExecInfo(TAOS_STMT* stmt, SHashObj** pVgHash, SHashObj** pBlockHash) {
|
||||
STscStmt* pStmt = (STscStmt*)stmt;
|
||||
|
||||
|
@ -151,34 +167,38 @@ int32_t stmtGetExecInfo(TAOS_STMT* stmt, SHashObj** pVgHash, SHashObj** pBlockHa
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t stmtCacheBlock(STscStmt *pStmt) {
|
||||
int32_t stmtCacheBlock(STscStmt* pStmt) {
|
||||
if (pStmt->sql.type != STMT_TYPE_MULTI_INSERT) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
uint64_t uid = pStmt->bInfo.tbUid;
|
||||
uint64_t tuid = (TSDB_CHILD_TABLE == pStmt->bInfo.tbType) ? pStmt->bInfo.tbSuid : uid;
|
||||
uint64_t cacheUid = (TSDB_CHILD_TABLE == pStmt->bInfo.tbType) ? pStmt->bInfo.tbSuid : uid;
|
||||
|
||||
if (taosHashGet(pStmt->sql.pTableCache, &tuid, sizeof(tuid))) {
|
||||
if (taosHashGet(pStmt->sql.pTableCache, &cacheUid, sizeof(cacheUid))) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
STableDataBlocks** pSrc = taosHashGet(pStmt->exec.pBlockHash, &uid, sizeof(uid));
|
||||
STableDataBlocks** pSrc = taosHashGet(pStmt->exec.pBlockHash, pStmt->bInfo.tbFName, strlen(pStmt->bInfo.tbFName));
|
||||
STableDataBlocks* pDst = NULL;
|
||||
|
||||
STMT_ERR_RET(qCloneStmtDataBlock(&pDst, *pSrc));
|
||||
|
||||
SStmtTableCache cache = {
|
||||
.pDataBlock = pDst,
|
||||
.boundTags = pStmt->bInfo.boundTags,
|
||||
.pDataBlock = pDst,
|
||||
.boundTags = pStmt->bInfo.boundTags,
|
||||
};
|
||||
|
||||
if (taosHashPut(pStmt->sql.pTableCache, &tuid, sizeof(tuid), &cache, sizeof(cache))) {
|
||||
if (taosHashPut(pStmt->sql.pTableCache, &cacheUid, sizeof(cacheUid), &cache, sizeof(cache))) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
pStmt->bInfo.boundTags = NULL;
|
||||
|
||||
if (pStmt->sql.autoCreateTbl) {
|
||||
pStmt->bInfo.tagsCached = true;
|
||||
} else {
|
||||
pStmt->bInfo.boundTags = NULL;
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -186,19 +206,18 @@ int32_t stmtParseSql(STscStmt* pStmt) {
|
|||
SStmtCallback stmtCb = {
|
||||
.pStmt = pStmt,
|
||||
.getTbNameFn = stmtGetTbName,
|
||||
.setBindInfoFn = stmtSetBindInfo,
|
||||
.setExecInfoFn = stmtSetExecInfo,
|
||||
.setInfoFn = stmtUpdateInfo,
|
||||
.getExecInfoFn = stmtGetExecInfo,
|
||||
};
|
||||
|
||||
if (NULL == pStmt->exec.pRequest) {
|
||||
STMT_ERR_RET(buildRequest(pStmt->taos, pStmt->sql.sqlStr, pStmt->sql.sqlLen, &pStmt->exec.pRequest));
|
||||
}
|
||||
|
||||
|
||||
STMT_ERR_RET(parseSql(pStmt->exec.pRequest, false, &pStmt->sql.pQuery, &stmtCb));
|
||||
|
||||
pStmt->bInfo.needParse = false;
|
||||
|
||||
|
||||
switch (nodeType(pStmt->sql.pQuery->pRoot)) {
|
||||
case QUERY_NODE_VNODE_MODIF_STMT:
|
||||
if (0 == pStmt->sql.type) {
|
||||
|
@ -221,8 +240,10 @@ int32_t stmtCleanBindInfo(STscStmt* pStmt) {
|
|||
pStmt->bInfo.tbSuid = 0;
|
||||
pStmt->bInfo.tbType = 0;
|
||||
pStmt->bInfo.needParse = true;
|
||||
pStmt->bInfo.inExecCache = false;
|
||||
|
||||
taosMemoryFreeClear(pStmt->bInfo.tbName);
|
||||
pStmt->bInfo.tbName[0] = 0;
|
||||
pStmt->bInfo.tbFName[0] = 0;
|
||||
if (!pStmt->bInfo.tagsCached) {
|
||||
destroyBoundColumnInfo(pStmt->bInfo.boundTags);
|
||||
taosMemoryFreeClear(pStmt->bInfo.boundTags);
|
||||
|
@ -237,24 +258,29 @@ int32_t stmtCleanExecInfo(STscStmt* pStmt, bool keepTable, bool freeRequest) {
|
|||
pStmt->exec.pRequest = NULL;
|
||||
}
|
||||
|
||||
size_t keyLen = 0;
|
||||
void *pIter = taosHashIterate(pStmt->exec.pBlockHash, NULL);
|
||||
while (pIter) {
|
||||
STableDataBlocks* pBlocks = *(STableDataBlocks**)pIter;
|
||||
uint64_t *key = taosHashGetKey(pIter, NULL);
|
||||
char *key = taosHashGetKey(pIter, &keyLen);
|
||||
STableMeta* pMeta = qGetTableMetaInDataBlock(pBlocks);
|
||||
|
||||
if (keepTable && (*key == pStmt->bInfo.tbUid)) {
|
||||
if (keepTable && (strlen(pStmt->bInfo.tbFName) == keyLen) && strncmp(pStmt->bInfo.tbFName, key, keyLen) == 0) {
|
||||
STMT_ERR_RET(qResetStmtDataBlock(pBlocks, true));
|
||||
|
||||
|
||||
pIter = taosHashIterate(pStmt->exec.pBlockHash, pIter);
|
||||
continue;
|
||||
}
|
||||
|
||||
qFreeStmtDataBlock(pBlocks);
|
||||
taosHashRemove(pStmt->exec.pBlockHash, key, sizeof(*key));
|
||||
taosHashRemove(pStmt->exec.pBlockHash, key, keyLen);
|
||||
|
||||
pIter = taosHashIterate(pStmt->exec.pBlockHash, pIter);
|
||||
}
|
||||
|
||||
pStmt->exec.autoCreateTbl = false;
|
||||
pStmt->exec.emptyRes = false;
|
||||
|
||||
if (keepTable) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
@ -274,15 +300,15 @@ int32_t stmtCleanSQLInfo(STscStmt* pStmt) {
|
|||
qDestroyQuery(pStmt->sql.pQuery);
|
||||
qDestroyQueryPlan(pStmt->sql.pQueryPlan);
|
||||
taosArrayDestroy(pStmt->sql.nodeList);
|
||||
|
||||
void *pIter = taosHashIterate(pStmt->sql.pTableCache, NULL);
|
||||
|
||||
void* pIter = taosHashIterate(pStmt->sql.pTableCache, NULL);
|
||||
while (pIter) {
|
||||
SStmtTableCache* pCache = (SStmtTableCache*)pIter;
|
||||
SStmtTableCache* pCache = (SStmtTableCache*)pIter;
|
||||
|
||||
qDestroyStmtDataBlock(pCache->pDataBlock);
|
||||
destroyBoundColumnInfo(pCache->boundTags);
|
||||
taosMemoryFreeClear(pCache->boundTags);
|
||||
|
||||
|
||||
pIter = taosHashIterate(pStmt->sql.pTableCache, pIter);
|
||||
}
|
||||
taosHashCleanup(pStmt->sql.pTableCache);
|
||||
|
@ -296,10 +322,39 @@ int32_t stmtCleanSQLInfo(STscStmt* pStmt) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t stmtRebuildDataBlock(STscStmt* pStmt, STableDataBlocks *pDataBlock, STableDataBlocks **newBlock, uint64_t uid) {
|
||||
SEpSet ep = getEpSet_s(&pStmt->taos->pAppInfo->mgmtEp);
|
||||
SVgroupInfo vgInfo = {0};
|
||||
|
||||
STMT_ERR_RET(catalogGetTableHashVgroup(pStmt->pCatalog, pStmt->taos->pAppInfo->pTransporter, &ep, &pStmt->bInfo.sname, &vgInfo));
|
||||
STMT_ERR_RET(taosHashPut(pStmt->exec.pVgHash, (const char*)&vgInfo.vgId, sizeof(vgInfo.vgId), (char*)&vgInfo, sizeof(vgInfo)));
|
||||
|
||||
STMT_ERR_RET(qRebuildStmtDataBlock(newBlock, pDataBlock, uid, vgInfo.vgId));
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t stmtGetFromCache(STscStmt* pStmt) {
|
||||
pStmt->bInfo.needParse = true;
|
||||
pStmt->bInfo.inExecCache = false;
|
||||
|
||||
STableDataBlocks *pBlockInExec = taosHashGet(pStmt->exec.pBlockHash, pStmt->bInfo.tbFName, strlen(pStmt->bInfo.tbFName));
|
||||
if (pBlockInExec) {
|
||||
pStmt->bInfo.needParse = false;
|
||||
pStmt->bInfo.inExecCache = true;
|
||||
|
||||
if (pStmt->sql.autoCreateTbl) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL == pStmt->sql.pTableCache || taosHashGetSize(pStmt->sql.pTableCache) <= 0) {
|
||||
if (pStmt->bInfo.inExecCache) {
|
||||
ASSERT(taosHashGetSize(pStmt->exec.pBlockHash) == 1);
|
||||
pStmt->bInfo.needParse = false;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -307,21 +362,44 @@ int32_t stmtGetFromCache(STscStmt* pStmt) {
|
|||
STMT_ERR_RET(catalogGetHandle(pStmt->taos->pAppInfo->clusterId, &pStmt->pCatalog));
|
||||
}
|
||||
|
||||
if (pStmt->sql.autoCreateTbl) {
|
||||
SStmtTableCache* pCache = taosHashGet(pStmt->sql.pTableCache, &pStmt->bInfo.tbSuid, sizeof(pStmt->bInfo.tbSuid));
|
||||
if (pCache) {
|
||||
pStmt->bInfo.needParse = false;
|
||||
pStmt->exec.autoCreateTbl = true;
|
||||
|
||||
pStmt->bInfo.tbUid = 0;
|
||||
|
||||
STableDataBlocks* pNewBlock = NULL;
|
||||
STMT_ERR_RET(stmtRebuildDataBlock(pStmt, pCache->pDataBlock, &pNewBlock, 0));
|
||||
|
||||
if (taosHashPut(pStmt->exec.pBlockHash, pStmt->bInfo.tbFName, strlen(pStmt->bInfo.tbFName), &pNewBlock, POINTER_BYTES)) {
|
||||
STMT_ERR_RET(TSDB_CODE_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
STMT_RET(stmtCleanBindInfo(pStmt));
|
||||
}
|
||||
|
||||
|
||||
STableMeta *pTableMeta = NULL;
|
||||
SEpSet ep = getEpSet_s(&pStmt->taos->pAppInfo->mgmtEp);
|
||||
int32_t code = catalogGetTableMeta(pStmt->pCatalog, pStmt->taos->pAppInfo->pTransporter, &ep, &pStmt->bInfo.sname, &pTableMeta);
|
||||
if (TSDB_CODE_PAR_TABLE_NOT_EXIST == code) {
|
||||
STMT_ERR_RET(stmtCleanBindInfo(pStmt));
|
||||
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
STMT_ERR_RET(code);
|
||||
|
||||
|
||||
uint64_t uid = pTableMeta->uid;
|
||||
uint64_t suid = pTableMeta->suid;
|
||||
int8_t tableType = pTableMeta->tableType;
|
||||
int8_t tableType = pTableMeta->tableType;
|
||||
taosMemoryFree(pTableMeta);
|
||||
uint64_t cacheUid = (TSDB_CHILD_TABLE == tableType) ? suid : uid;
|
||||
|
||||
if (uid == pStmt->bInfo.tbUid) {
|
||||
pStmt->bInfo.needParse = false;
|
||||
|
@ -329,16 +407,16 @@ int32_t stmtGetFromCache(STscStmt* pStmt) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
if (taosHashGet(pStmt->exec.pBlockHash, &uid, sizeof(uid))) {
|
||||
SStmtTableCache* pCache = taosHashGet(pStmt->sql.pTableCache, &uid, sizeof(uid));
|
||||
if (pStmt->bInfo.inExecCache) {
|
||||
SStmtTableCache* pCache = taosHashGet(pStmt->sql.pTableCache, &cacheUid, sizeof(cacheUid));
|
||||
if (NULL == pCache) {
|
||||
tscError("table uid %" PRIx64 "found in exec blockHash, but not in sql blockHash", uid);
|
||||
tscError("table [%s, %" PRIx64 ", %" PRIx64 "] found in exec blockHash, but not in sql blockHash", pStmt->bInfo.tbFName, uid, cacheUid);
|
||||
|
||||
STMT_ERR_RET(TSDB_CODE_TSC_APP_ERROR);
|
||||
}
|
||||
|
||||
|
||||
pStmt->bInfo.needParse = false;
|
||||
|
||||
|
||||
pStmt->bInfo.tbUid = uid;
|
||||
pStmt->bInfo.tbSuid = suid;
|
||||
pStmt->bInfo.tbType = tableType;
|
||||
|
@ -348,7 +426,7 @@ int32_t stmtGetFromCache(STscStmt* pStmt) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
SStmtTableCache* pCache = taosHashGet(pStmt->sql.pTableCache, &uid, sizeof(uid));
|
||||
SStmtTableCache* pCache = taosHashGet(pStmt->sql.pTableCache, &cacheUid, sizeof(cacheUid));
|
||||
if (pCache) {
|
||||
pStmt->bInfo.needParse = false;
|
||||
|
||||
|
@ -359,12 +437,12 @@ int32_t stmtGetFromCache(STscStmt* pStmt) {
|
|||
pStmt->bInfo.tagsCached = true;
|
||||
|
||||
STableDataBlocks* pNewBlock = NULL;
|
||||
STMT_ERR_RET(qRebuildStmtDataBlock(&pNewBlock, pCache->pDataBlock));
|
||||
STMT_ERR_RET(stmtRebuildDataBlock(pStmt, pCache->pDataBlock, &pNewBlock, uid));
|
||||
|
||||
if (taosHashPut(pStmt->exec.pBlockHash, &pStmt->bInfo.tbUid, sizeof(pStmt->bInfo.tbUid), &pNewBlock, POINTER_BYTES)) {
|
||||
if (taosHashPut(pStmt->exec.pBlockHash, pStmt->bInfo.tbFName, strlen(pStmt->bInfo.tbFName), &pNewBlock, POINTER_BYTES)) {
|
||||
STMT_ERR_RET(TSDB_CODE_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -387,9 +465,8 @@ int32_t stmtResetStmt(STscStmt* pStmt) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
TAOS_STMT *stmtInit(TAOS *taos) {
|
||||
STscObj* pObj = (STscObj*)taos;
|
||||
TAOS_STMT* stmtInit(TAOS* taos) {
|
||||
STscObj* pObj = (STscObj*)taos;
|
||||
STscStmt* pStmt = NULL;
|
||||
|
||||
pStmt = taosMemoryCalloc(1, sizeof(STscStmt));
|
||||
|
@ -408,11 +485,11 @@ TAOS_STMT *stmtInit(TAOS *taos) {
|
|||
pStmt->taos = pObj;
|
||||
pStmt->bInfo.needParse = true;
|
||||
pStmt->sql.status = STMT_INIT;
|
||||
|
||||
|
||||
return pStmt;
|
||||
}
|
||||
|
||||
int stmtPrepare(TAOS_STMT *stmt, const char *sql, unsigned long length) {
|
||||
int stmtPrepare(TAOS_STMT* stmt, const char* sql, unsigned long length) {
|
||||
STscStmt* pStmt = (STscStmt*)stmt;
|
||||
|
||||
if (pStmt->sql.status >= STMT_PREPARE) {
|
||||
|
@ -424,15 +501,14 @@ int stmtPrepare(TAOS_STMT *stmt, const char *sql, unsigned long length) {
|
|||
if (length <= 0) {
|
||||
length = strlen(sql);
|
||||
}
|
||||
|
||||
|
||||
pStmt->sql.sqlStr = strndup(sql, length);
|
||||
pStmt->sql.sqlLen = length;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int stmtSetTbName(TAOS_STMT *stmt, const char *tbName) {
|
||||
int stmtSetTbName(TAOS_STMT* stmt, const char* tbName) {
|
||||
STscStmt* pStmt = (STscStmt*)stmt;
|
||||
|
||||
STMT_ERR_RET(stmtSwitchStatus(pStmt, STMT_SETTBNAME));
|
||||
|
@ -449,49 +525,52 @@ int stmtSetTbName(TAOS_STMT *stmt, const char *tbName) {
|
|||
}
|
||||
|
||||
STMT_ERR_RET(qCreateSName(&pStmt->bInfo.sname, tbName, pStmt->taos->acctId, pStmt->exec.pRequest->pDb, pStmt->exec.pRequest->msgBuf, pStmt->exec.pRequest->msgBufLen));
|
||||
|
||||
tNameExtractFullName(&pStmt->bInfo.sname, pStmt->bInfo.tbFName);
|
||||
|
||||
STMT_ERR_RET(stmtGetFromCache(pStmt));
|
||||
|
||||
if (pStmt->bInfo.needParse) {
|
||||
taosMemoryFree(pStmt->bInfo.tbName);
|
||||
pStmt->bInfo.tbName = strdup(tbName);
|
||||
strncpy(pStmt->bInfo.tbName, tbName, sizeof(pStmt->bInfo.tbName) - 1);
|
||||
pStmt->bInfo.tbName[sizeof(pStmt->bInfo.tbName) - 1] = 0;
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int stmtSetTbTags(TAOS_STMT *stmt, TAOS_MULTI_BIND *tags) {
|
||||
int stmtSetTbTags(TAOS_STMT* stmt, TAOS_MULTI_BIND* tags) {
|
||||
STscStmt* pStmt = (STscStmt*)stmt;
|
||||
|
||||
STMT_ERR_RET(stmtSwitchStatus(pStmt, STMT_SETTAGS));
|
||||
|
||||
if (!pStmt->bInfo.needParse) {
|
||||
if (pStmt->bInfo.needParse) {
|
||||
STMT_ERR_RET(stmtParseSql(pStmt));
|
||||
}
|
||||
|
||||
if (pStmt->bInfo.inExecCache) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
STMT_ERR_RET(stmtParseSql(pStmt));
|
||||
|
||||
STableDataBlocks **pDataBlock = (STableDataBlocks**)taosHashGet(pStmt->exec.pBlockHash, (const char*)&pStmt->bInfo.tbUid, sizeof(pStmt->bInfo.tbUid));
|
||||
STableDataBlocks **pDataBlock = (STableDataBlocks**)taosHashGet(pStmt->exec.pBlockHash, pStmt->bInfo.tbFName, strlen(pStmt->bInfo.tbFName));
|
||||
if (NULL == pDataBlock) {
|
||||
tscError("table uid %" PRIx64 "not found in exec blockHash", pStmt->bInfo.tbUid);
|
||||
tscError("table %s not found in exec blockHash", pStmt->bInfo.tbFName);
|
||||
STMT_ERR_RET(TSDB_CODE_QRY_APP_ERROR);
|
||||
}
|
||||
|
||||
STMT_ERR_RET(qBindStmtTagsValue(*pDataBlock, pStmt->bInfo.boundTags, pStmt->bInfo.tbSuid, pStmt->bInfo.sname.tname, tags, pStmt->exec.pRequest->msgBuf, pStmt->exec.pRequest->msgBufLen));
|
||||
|
||||
STMT_ERR_RET(qBindStmtTagsValue(*pDataBlock, pStmt->bInfo.boundTags, pStmt->bInfo.tbSuid, pStmt->bInfo.sname.tname,
|
||||
tags, pStmt->exec.pRequest->msgBuf, pStmt->exec.pRequest->msgBufLen));
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int32_t stmtFetchTagFields(STscStmt* pStmt, int32_t *fieldNum, TAOS_FIELD** fields) {
|
||||
int32_t stmtFetchTagFields(STscStmt* pStmt, int32_t* fieldNum, TAOS_FIELD** fields) {
|
||||
if (STMT_TYPE_QUERY == pStmt->sql.type) {
|
||||
tscError("invalid operation to get query tag fileds");
|
||||
STMT_ERR_RET(TSDB_CODE_TSC_STMT_API_ERROR);
|
||||
}
|
||||
|
||||
STableDataBlocks **pDataBlock = (STableDataBlocks**)taosHashGet(pStmt->exec.pBlockHash, (const char*)&pStmt->bInfo.tbUid, sizeof(pStmt->bInfo.tbUid));
|
||||
STableDataBlocks **pDataBlock = (STableDataBlocks**)taosHashGet(pStmt->exec.pBlockHash, pStmt->bInfo.tbFName, strlen(pStmt->bInfo.tbFName));
|
||||
if (NULL == pDataBlock) {
|
||||
tscError("table uid %" PRIx64 "not found in exec blockHash", pStmt->bInfo.tbUid);
|
||||
tscError("table %s not found in exec blockHash", pStmt->bInfo.tbFName);
|
||||
STMT_ERR_RET(TSDB_CODE_QRY_APP_ERROR);
|
||||
}
|
||||
|
||||
|
@ -500,27 +579,28 @@ int32_t stmtFetchTagFields(STscStmt* pStmt, int32_t *fieldNum, TAOS_FIELD** fiel
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t stmtFetchColFields(STscStmt* pStmt, int32_t *fieldNum, TAOS_FIELD** fields) {
|
||||
int32_t stmtFetchColFields(STscStmt* pStmt, int32_t* fieldNum, TAOS_FIELD** fields) {
|
||||
if (STMT_TYPE_QUERY == pStmt->sql.type) {
|
||||
tscError("invalid operation to get query column fileds");
|
||||
STMT_ERR_RET(TSDB_CODE_TSC_STMT_API_ERROR);
|
||||
}
|
||||
|
||||
STableDataBlocks **pDataBlock = (STableDataBlocks**)taosHashGet(pStmt->exec.pBlockHash, (const char*)&pStmt->bInfo.tbUid, sizeof(pStmt->bInfo.tbUid));
|
||||
STableDataBlocks **pDataBlock = (STableDataBlocks**)taosHashGet(pStmt->exec.pBlockHash, pStmt->bInfo.tbFName, strlen(pStmt->bInfo.tbFName));
|
||||
if (NULL == pDataBlock) {
|
||||
tscError("table uid %" PRIx64 "not found in exec blockHash", pStmt->bInfo.tbUid);
|
||||
tscError("table %s not found in exec blockHash", pStmt->bInfo.tbFName);
|
||||
STMT_ERR_RET(TSDB_CODE_QRY_APP_ERROR);
|
||||
}
|
||||
|
||||
STMT_ERR_RET(qBuildStmtColFields(*pDataBlock, fieldNum, fields));
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int stmtBindBatch(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind, int32_t colIdx) {
|
||||
int stmtBindBatch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind, int32_t colIdx) {
|
||||
STscStmt* pStmt = (STscStmt*)stmt;
|
||||
|
||||
if (pStmt->bInfo.needParse && pStmt->sql.runTimes && pStmt->sql.type > 0 && STMT_TYPE_MULTI_INSERT != pStmt->sql.type) {
|
||||
if (pStmt->bInfo.needParse && pStmt->sql.runTimes && pStmt->sql.type > 0 &&
|
||||
STMT_TYPE_MULTI_INSERT != pStmt->sql.type) {
|
||||
pStmt->bInfo.needParse = false;
|
||||
}
|
||||
|
||||
|
@ -528,7 +608,7 @@ int stmtBindBatch(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind, int32_t colIdx) {
|
|||
taos_free_result(pStmt->exec.pRequest);
|
||||
pStmt->exec.pRequest = NULL;
|
||||
}
|
||||
|
||||
|
||||
if (NULL == pStmt->exec.pRequest) {
|
||||
STMT_ERR_RET(buildRequest(pStmt->taos, pStmt->sql.sqlStr, pStmt->sql.sqlLen, &pStmt->exec.pRequest));
|
||||
}
|
||||
|
@ -548,13 +628,13 @@ int stmtBindBatch(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind, int32_t colIdx) {
|
|||
} else {
|
||||
STMT_ERR_RET(stmtRestoreQueryFields(pStmt));
|
||||
}
|
||||
|
||||
STMT_RET(qStmtBindParam(pStmt->sql.pQueryPlan, bind, colIdx, pStmt->exec.pRequest->requestId));
|
||||
|
||||
STMT_RET(qStmtBindParam(pStmt->sql.pQueryPlan, bind, colIdx, pStmt->exec.pRequest->requestId, &pStmt->exec.emptyRes));
|
||||
}
|
||||
|
||||
STableDataBlocks **pDataBlock = (STableDataBlocks**)taosHashGet(pStmt->exec.pBlockHash, (const char*)&pStmt->bInfo.tbUid, sizeof(pStmt->bInfo.tbUid));
|
||||
STableDataBlocks **pDataBlock = (STableDataBlocks**)taosHashGet(pStmt->exec.pBlockHash, pStmt->bInfo.tbFName, strlen(pStmt->bInfo.tbFName));
|
||||
if (NULL == pDataBlock) {
|
||||
tscError("table uid %" PRIx64 "not found in exec blockHash", pStmt->bInfo.tbUid);
|
||||
tscError("table %s not found in exec blockHash", pStmt->bInfo.tbFName);
|
||||
STMT_ERR_RET(TSDB_CODE_QRY_APP_ERROR);
|
||||
}
|
||||
|
||||
|
@ -571,39 +651,99 @@ int stmtBindBatch(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind, int32_t colIdx) {
|
|||
}
|
||||
|
||||
pStmt->bInfo.sBindLastIdx = colIdx;
|
||||
|
||||
|
||||
if (0 == colIdx) {
|
||||
pStmt->bInfo.sBindRowNum = bind->num;
|
||||
}
|
||||
|
||||
qBindStmtSingleColValue(*pDataBlock, bind, pStmt->exec.pRequest->msgBuf, pStmt->exec.pRequest->msgBufLen, colIdx, pStmt->bInfo.sBindRowNum);
|
||||
|
||||
qBindStmtSingleColValue(*pDataBlock, bind, pStmt->exec.pRequest->msgBuf, pStmt->exec.pRequest->msgBufLen, colIdx,
|
||||
pStmt->bInfo.sBindRowNum);
|
||||
}
|
||||
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int stmtAddBatch(TAOS_STMT *stmt) {
|
||||
int stmtAddBatch(TAOS_STMT* stmt) {
|
||||
STscStmt* pStmt = (STscStmt*)stmt;
|
||||
|
||||
STMT_ERR_RET(stmtSwitchStatus(pStmt, STMT_ADD_BATCH));
|
||||
|
||||
STMT_ERR_RET(stmtCacheBlock(pStmt));
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int stmtUpdateTableUid(STscStmt* pStmt, SSubmitRsp *pRsp) {
|
||||
if (pRsp->nBlocks <= 0) {
|
||||
tscError("invalid submit resp block number %d", pRsp->nBlocks);
|
||||
STMT_ERR_RET(TSDB_CODE_TSC_APP_ERROR);
|
||||
}
|
||||
|
||||
size_t keyLen = 0;
|
||||
STableDataBlocks **pIter = taosHashIterate(pStmt->exec.pBlockHash, NULL);
|
||||
while (pIter) {
|
||||
STableDataBlocks *pBlock = *pIter;
|
||||
char *key = taosHashGetKey(pIter, &keyLen);
|
||||
|
||||
STableMeta *pMeta = qGetTableMetaInDataBlock(pBlock);
|
||||
if (pMeta->uid != pStmt->bInfo.tbUid) {
|
||||
tscError("table uid %" PRIx64 " mis-match with current table uid %" PRIx64, pMeta->uid, pStmt->bInfo.tbUid);
|
||||
STMT_ERR_RET(TSDB_CODE_TSC_APP_ERROR);
|
||||
}
|
||||
|
||||
if (pMeta->uid) {
|
||||
pIter = taosHashIterate(pStmt->exec.pBlockHash, pIter);
|
||||
continue;
|
||||
}
|
||||
|
||||
SSubmitBlkRsp *blkRsp = NULL;
|
||||
int32_t i = 0;
|
||||
for (; i < pRsp->nBlocks; ++i) {
|
||||
blkRsp = pRsp->pBlocks + i;
|
||||
if (strlen(blkRsp->tblFName) != keyLen) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strncmp(blkRsp->tblFName, key, keyLen)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (i < pRsp->nBlocks) {
|
||||
tscDebug("auto created table %s uid updated from %" PRIx64 " to %" PRIx64, blkRsp->tblFName, pMeta->uid, blkRsp->uid);
|
||||
|
||||
pMeta->uid = blkRsp->uid;
|
||||
pStmt->bInfo.tbUid = blkRsp->uid;
|
||||
} else {
|
||||
tscError("table %s not found in submit rsp", pStmt->bInfo.tbFName);
|
||||
STMT_ERR_RET(TSDB_CODE_TSC_APP_ERROR);
|
||||
}
|
||||
|
||||
pIter = taosHashIterate(pStmt->exec.pBlockHash, pIter);
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int stmtExec(TAOS_STMT *stmt) {
|
||||
STscStmt* pStmt = (STscStmt*)stmt;
|
||||
int32_t code = 0;
|
||||
SSubmitRsp *pRsp = NULL;
|
||||
bool autoCreateTbl = pStmt->exec.autoCreateTbl;
|
||||
|
||||
STMT_ERR_RET(stmtSwitchStatus(pStmt, STMT_EXECUTE));
|
||||
|
||||
if (STMT_TYPE_QUERY == pStmt->sql.type) {
|
||||
scheduleQuery(pStmt->exec.pRequest, pStmt->sql.pQueryPlan, pStmt->sql.nodeList);
|
||||
if (pStmt->exec.emptyRes) {
|
||||
pStmt->exec.pRequest->type = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
|
||||
} else {
|
||||
scheduleQuery(pStmt->exec.pRequest, pStmt->sql.pQueryPlan, pStmt->sql.nodeList, NULL);
|
||||
}
|
||||
} else {
|
||||
STMT_ERR_RET(qBuildStmtOutput(pStmt->sql.pQuery, pStmt->exec.pVgHash, pStmt->exec.pBlockHash));
|
||||
launchQueryImpl(pStmt->exec.pRequest, pStmt->sql.pQuery, TSDB_CODE_SUCCESS, true);
|
||||
launchQueryImpl(pStmt->exec.pRequest, pStmt->sql.pQuery, TSDB_CODE_SUCCESS, true, (autoCreateTbl ? (void**)&pRsp : NULL));
|
||||
}
|
||||
|
||||
if (pStmt->exec.pRequest->code && NEED_CLIENT_HANDLE_ERROR(pStmt->exec.pRequest->code)) {
|
||||
|
@ -615,7 +755,7 @@ int stmtExec(TAOS_STMT *stmt) {
|
|||
STMT_ERR_RET(TSDB_CODE_NEED_RETRY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
STMT_ERR_JRET(pStmt->exec.pRequest->code);
|
||||
|
||||
pStmt->exec.affectedRows = taos_affected_rows(pStmt->exec.pRequest);
|
||||
|
@ -624,14 +764,22 @@ int stmtExec(TAOS_STMT *stmt) {
|
|||
_return:
|
||||
|
||||
stmtCleanExecInfo(pStmt, (code ? false : true), false);
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code && autoCreateTbl) {
|
||||
if (NULL == pRsp) {
|
||||
tscError("no submit resp got for auto create table");
|
||||
STMT_ERR_RET(TSDB_CODE_TSC_APP_ERROR);
|
||||
}
|
||||
|
||||
STMT_ERR_RET(stmtUpdateTableUid(pStmt, pRsp));
|
||||
}
|
||||
|
||||
++pStmt->sql.runTimes;
|
||||
|
||||
|
||||
STMT_RET(code);
|
||||
}
|
||||
|
||||
|
||||
int stmtClose(TAOS_STMT *stmt) {
|
||||
int stmtClose(TAOS_STMT* stmt) {
|
||||
STscStmt* pStmt = (STscStmt*)stmt;
|
||||
|
||||
STMT_RET(stmtCleanSQLInfo(pStmt));
|
||||
|
@ -639,11 +787,11 @@ int stmtClose(TAOS_STMT *stmt) {
|
|||
taosMemoryFree(stmt);
|
||||
}
|
||||
|
||||
const char *stmtErrstr(TAOS_STMT *stmt) {
|
||||
const char* stmtErrstr(TAOS_STMT* stmt) {
|
||||
STscStmt* pStmt = (STscStmt*)stmt;
|
||||
|
||||
if (stmt == NULL || NULL == pStmt->exec.pRequest) {
|
||||
return (char*) tstrerror(terrno);
|
||||
return (char*)tstrerror(terrno);
|
||||
}
|
||||
|
||||
pStmt->exec.pRequest->code = terrno;
|
||||
|
@ -651,15 +799,11 @@ const char *stmtErrstr(TAOS_STMT *stmt) {
|
|||
return taos_errstr(pStmt->exec.pRequest);
|
||||
}
|
||||
|
||||
int stmtAffectedRows(TAOS_STMT *stmt) {
|
||||
return ((STscStmt*)stmt)->affectedRows;
|
||||
}
|
||||
int stmtAffectedRows(TAOS_STMT* stmt) { return ((STscStmt*)stmt)->affectedRows; }
|
||||
|
||||
int stmtAffectedRowsOnce(TAOS_STMT *stmt) {
|
||||
return ((STscStmt*)stmt)->exec.affectedRows;
|
||||
}
|
||||
int stmtAffectedRowsOnce(TAOS_STMT* stmt) { return ((STscStmt*)stmt)->exec.affectedRows; }
|
||||
|
||||
int stmtIsInsert(TAOS_STMT *stmt, int *insert) {
|
||||
int stmtIsInsert(TAOS_STMT* stmt, int* insert) {
|
||||
STscStmt* pStmt = (STscStmt*)stmt;
|
||||
|
||||
if (pStmt->sql.type) {
|
||||
|
@ -667,16 +811,17 @@ int stmtIsInsert(TAOS_STMT *stmt, int *insert) {
|
|||
} else {
|
||||
*insert = isInsertSql(pStmt->sql.sqlStr, 0);
|
||||
}
|
||||
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int stmtGetParamNum(TAOS_STMT *stmt, int *nums) {
|
||||
int stmtGetParamNum(TAOS_STMT* stmt, int* nums) {
|
||||
STscStmt* pStmt = (STscStmt*)stmt;
|
||||
|
||||
STMT_ERR_RET(stmtSwitchStatus(pStmt, STMT_FETCH_FIELDS));
|
||||
|
||||
if (pStmt->bInfo.needParse && pStmt->sql.runTimes && pStmt->sql.type > 0 && STMT_TYPE_MULTI_INSERT != pStmt->sql.type) {
|
||||
if (pStmt->bInfo.needParse && pStmt->sql.runTimes && pStmt->sql.type > 0 &&
|
||||
STMT_TYPE_MULTI_INSERT != pStmt->sql.type) {
|
||||
pStmt->bInfo.needParse = false;
|
||||
}
|
||||
|
||||
|
@ -684,7 +829,7 @@ int stmtGetParamNum(TAOS_STMT *stmt, int *nums) {
|
|||
taos_free_result(pStmt->exec.pRequest);
|
||||
pStmt->exec.pRequest = NULL;
|
||||
}
|
||||
|
||||
|
||||
if (NULL == pStmt->exec.pRequest) {
|
||||
STMT_ERR_RET(buildRequest(pStmt->taos, pStmt->sql.sqlStr, pStmt->sql.sqlLen, &pStmt->exec.pRequest));
|
||||
}
|
||||
|
@ -702,16 +847,16 @@ int stmtGetParamNum(TAOS_STMT *stmt, int *nums) {
|
|||
} else {
|
||||
STMT_ERR_RET(stmtRestoreQueryFields(pStmt));
|
||||
}
|
||||
|
||||
|
||||
*nums = taosArrayGetSize(pStmt->sql.pQueryPlan->pPlaceholderValues);
|
||||
} else {
|
||||
STMT_ERR_RET(stmtFetchColFields(stmt, nums, NULL));
|
||||
}
|
||||
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
TAOS_RES *stmtUseResult(TAOS_STMT *stmt) {
|
||||
TAOS_RES* stmtUseResult(TAOS_STMT* stmt) {
|
||||
STscStmt* pStmt = (STscStmt*)stmt;
|
||||
|
||||
if (STMT_TYPE_QUERY != pStmt->sql.type) {
|
||||
|
@ -721,6 +866,3 @@ TAOS_RES *stmtUseResult(TAOS_STMT *stmt) {
|
|||
|
||||
return pStmt->exec.pRequest;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -57,16 +57,17 @@ struct tmq_topic_vgroup_list_t {
|
|||
};
|
||||
|
||||
struct tmq_conf_t {
|
||||
char clientId[256];
|
||||
char groupId[TSDB_CGROUP_LEN];
|
||||
int8_t autoCommit;
|
||||
int8_t resetOffset;
|
||||
uint16_t port;
|
||||
int32_t autoCommitInterval;
|
||||
char* ip;
|
||||
char* user;
|
||||
char* pass;
|
||||
char* db;
|
||||
char clientId[256];
|
||||
char groupId[TSDB_CGROUP_LEN];
|
||||
int8_t autoCommit;
|
||||
int8_t resetOffset;
|
||||
int8_t withTbName;
|
||||
uint16_t port;
|
||||
int32_t autoCommitInterval;
|
||||
char* ip;
|
||||
char* user;
|
||||
char* pass;
|
||||
/*char* db;*/
|
||||
tmq_commit_cb* commitCb;
|
||||
void* commitCbUserParam;
|
||||
};
|
||||
|
@ -75,6 +76,7 @@ struct tmq_t {
|
|||
// conf
|
||||
char groupId[TSDB_CGROUP_LEN];
|
||||
char clientId[256];
|
||||
int8_t withTbName;
|
||||
int8_t autoCommit;
|
||||
int32_t autoCommitInterval;
|
||||
int32_t resetOffsetCfg;
|
||||
|
@ -187,6 +189,7 @@ typedef struct {
|
|||
|
||||
tmq_conf_t* tmq_conf_new() {
|
||||
tmq_conf_t* conf = taosMemoryCalloc(1, sizeof(tmq_conf_t));
|
||||
conf->withTbName = -1;
|
||||
conf->autoCommit = true;
|
||||
conf->autoCommitInterval = 5000;
|
||||
conf->resetOffset = TMQ_CONF__RESET_OFFSET__EARLIEAST;
|
||||
|
@ -240,6 +243,18 @@ tmq_conf_res_t tmq_conf_set(tmq_conf_t* conf, const char* key, const char* value
|
|||
}
|
||||
}
|
||||
|
||||
if (strcmp(key, "msg.with.table.name") == 0) {
|
||||
if (strcmp(value, "true") == 0) {
|
||||
conf->withTbName = 1;
|
||||
} else if (strcmp(value, "false") == 0) {
|
||||
conf->withTbName = 0;
|
||||
} else if (strcmp(value, "none") == 0) {
|
||||
conf->withTbName = -1;
|
||||
} else {
|
||||
return TMQ_CONF_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
if (strcmp(key, "td.connect.ip") == 0) {
|
||||
conf->ip = strdup(value);
|
||||
return TMQ_CONF_OK;
|
||||
|
@ -257,7 +272,7 @@ tmq_conf_res_t tmq_conf_set(tmq_conf_t* conf, const char* key, const char* value
|
|||
return TMQ_CONF_OK;
|
||||
}
|
||||
if (strcmp(key, "td.connect.db") == 0) {
|
||||
conf->db = strdup(value);
|
||||
/*conf->db = strdup(value);*/
|
||||
return TMQ_CONF_OK;
|
||||
}
|
||||
|
||||
|
@ -485,6 +500,7 @@ tmq_t* tmq_consumer_new(tmq_conf_t* conf, char* errstr, int32_t errstrLen) {
|
|||
// set conf
|
||||
strcpy(pTmq->clientId, conf->clientId);
|
||||
strcpy(pTmq->groupId, conf->groupId);
|
||||
pTmq->withTbName = conf->withTbName;
|
||||
pTmq->autoCommit = conf->autoCommit;
|
||||
pTmq->autoCommitInterval = conf->autoCommitInterval;
|
||||
pTmq->commitCb = conf->commitCb;
|
||||
|
@ -1104,6 +1120,7 @@ SMqPollReq* tmqBuildConsumeReqImpl(tmq_t* tmq, int64_t waitTime, SMqClientTopic*
|
|||
pReq->subKey[tlen] = TMQ_SEPARATOR;
|
||||
strcpy(pReq->subKey + tlen + 1, pTopic->topicName);
|
||||
|
||||
pReq->withTbName = tmq->withTbName;
|
||||
pReq->waitTime = waitTime;
|
||||
pReq->consumerId = tmq->consumerId;
|
||||
pReq->epoch = tmq->epoch;
|
||||
|
@ -1346,3 +1363,16 @@ int32_t tmq_get_vgroup_id(TAOS_RES* res) {
|
|||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
const char* tmq_get_table_name(TAOS_RES* res) {
|
||||
if (TD_RES_TMQ(res)) {
|
||||
SMqRspObj* pRspObj = (SMqRspObj*)res;
|
||||
if (!pRspObj->rsp.withTbName || pRspObj->rsp.blockTbName == NULL || pRspObj->resIter < 0 ||
|
||||
pRspObj->resIter >= pRspObj->rsp.blockNum) {
|
||||
return NULL;
|
||||
}
|
||||
const char* name = taosArrayGetP(pRspObj->rsp.blockTbName, pRspObj->resIter);
|
||||
return name;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -1311,6 +1311,7 @@ int32_t tEncodeDataBlock(void** buf, const SSDataBlock* pBlock) {
|
|||
tlen += taosEncodeFixedI16(buf, pColData->info.colId);
|
||||
tlen += taosEncodeFixedI16(buf, pColData->info.type);
|
||||
tlen += taosEncodeFixedI32(buf, pColData->info.bytes);
|
||||
tlen += taosEncodeFixedBool(buf, pColData->hasNull);
|
||||
|
||||
if (IS_VAR_DATA_TYPE(pColData->info.type)) {
|
||||
tlen += taosEncodeBinary(buf, pColData->varmeta.offset, sizeof(int32_t) * rows);
|
||||
|
@ -1340,6 +1341,7 @@ void* tDecodeDataBlock(const void* buf, SSDataBlock* pBlock) {
|
|||
buf = taosDecodeFixedI16(buf, &data.info.colId);
|
||||
buf = taosDecodeFixedI16(buf, &data.info.type);
|
||||
buf = taosDecodeFixedI32(buf, &data.info.bytes);
|
||||
buf = taosDecodeFixedBool(buf, &data.hasNull);
|
||||
|
||||
if (IS_VAR_DATA_TYPE(data.info.type)) {
|
||||
buf = taosDecodeBinary(buf, (void**)&data.varmeta.offset, pBlock->info.rows * sizeof(int32_t));
|
||||
|
|
|
@ -19,12 +19,238 @@
|
|||
#include "tdatablock.h"
|
||||
#include "tlog.h"
|
||||
|
||||
#define TD_KV_ROW 0x1U
|
||||
|
||||
struct SKVIdx {
|
||||
int32_t cid;
|
||||
int32_t offset;
|
||||
};
|
||||
|
||||
int32_t tEncodeTSRow(SEncoder *pEncoder, const STSRow2 *pRow) {
|
||||
if (tEncodeI64(pEncoder, pRow->ts) < 0) return -1;
|
||||
if (tEncodeU32v(pEncoder, pRow->flags) < 0) return -1;
|
||||
if (pRow->flags & TD_KV_ROW) {
|
||||
if (tEncodeI32v(pEncoder, pRow->ncols) < 0) return -1;
|
||||
} else {
|
||||
if (tEncodeI32v(pEncoder, pRow->sver) < 0) return -1;
|
||||
}
|
||||
if (tEncodeBinary(pEncoder, pRow->pData, pRow->nData) < 0) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tDecodeTSRow(SDecoder *pDecoder, STSRow2 *pRow) {
|
||||
if (tDecodeI64(pDecoder, &pRow->ts) < 0) return -1;
|
||||
if (tDecodeU32v(pDecoder, &pRow->flags) < 0) return -1;
|
||||
if (pRow->flags & TD_KV_ROW) {
|
||||
if (tDecodeI32v(pDecoder, &pRow->ncols) < 0) return -1;
|
||||
} else {
|
||||
if (tDecodeI32v(pDecoder, &pRow->sver) < 0) return -1;
|
||||
}
|
||||
if (tDecodeBinary(pDecoder, &pRow->pData, &pRow->nData) < 0) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tTSchemaCreate(int32_t sver, SSchema *pSchema, int32_t ncols, STSchema **ppTSchema) {
|
||||
*ppTSchema = (STSchema *)taosMemoryMalloc(sizeof(STSchema) + sizeof(STColumn) * ncols);
|
||||
if (*ppTSchema == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
|
||||
(*ppTSchema)->numOfCols = ncols;
|
||||
(*ppTSchema)->version = sver;
|
||||
(*ppTSchema)->flen = 0;
|
||||
(*ppTSchema)->vlen = 0;
|
||||
(*ppTSchema)->tlen = 0;
|
||||
|
||||
for (int32_t iCol = 0; iCol < ncols; iCol++) {
|
||||
SSchema *pColumn = &pSchema[iCol];
|
||||
STColumn *pTColumn = &((*ppTSchema)->columns[iCol]);
|
||||
|
||||
pTColumn->colId = pColumn->colId;
|
||||
pTColumn->type = pColumn->type;
|
||||
pTColumn->flags = pColumn->flags;
|
||||
pTColumn->bytes = pColumn->bytes;
|
||||
pTColumn->offset = (*ppTSchema)->flen;
|
||||
|
||||
// skip first column
|
||||
if (iCol) {
|
||||
(*ppTSchema)->flen += TYPE_BYTES[pColumn->type];
|
||||
if (IS_VAR_DATA_TYPE(pColumn->type)) {
|
||||
(*ppTSchema)->vlen += (pColumn->bytes + 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void tTSchemaDestroy(STSchema *pTSchema) { taosMemoryFree(pTSchema); }
|
||||
|
||||
int32_t tTSRowBuilderInit(STSRowBuilder *pBuilder, int32_t sver, SSchema *pSchema, int32_t nCols) {
|
||||
int32_t kvBufLen;
|
||||
int32_t tpBufLen;
|
||||
uint8_t *p;
|
||||
|
||||
if (tTSchemaCreate(sver, pSchema, nCols, &pBuilder->pTSchema) < 0) return -1;
|
||||
|
||||
kvBufLen = sizeof(SKVIdx) * nCols + pBuilder->pTSchema->flen + pBuilder->pTSchema->vlen;
|
||||
tpBufLen = pBuilder->pTSchema->flen + pBuilder->pTSchema->vlen;
|
||||
|
||||
if (pBuilder->szKVBuf < kvBufLen) {
|
||||
p = taosMemoryRealloc(pBuilder->pKVBuf, kvBufLen);
|
||||
if (p == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
pBuilder->pKVBuf = p;
|
||||
pBuilder->szKVBuf = kvBufLen;
|
||||
}
|
||||
|
||||
if (pBuilder->szTPBuf < tpBufLen) {
|
||||
p = taosMemoryRealloc(pBuilder->pTPBuf, tpBufLen);
|
||||
if (p == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
pBuilder->pTPBuf = p;
|
||||
pBuilder->szTPBuf = tpBufLen;
|
||||
}
|
||||
|
||||
tTSRowBuilderReset(pBuilder);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void tTSRowBuilderClear(STSRowBuilder *pBuilder) {
|
||||
taosMemoryFree(pBuilder->pKVBuf);
|
||||
taosMemoryFree(pBuilder->pTPBuf);
|
||||
}
|
||||
|
||||
void tTSRowBuilderReset(STSRowBuilder *pBuilder) {
|
||||
for (int32_t iCol = pBuilder->pTSchema->numOfCols - 1; iCol >= 0; iCol--) {
|
||||
pBuilder->pTColumn = &pBuilder->pTSchema->columns[iCol];
|
||||
|
||||
pBuilder->pTColumn->flags &= (~COL_VAL_SET);
|
||||
}
|
||||
|
||||
pBuilder->nCols = 0;
|
||||
pBuilder->kvVLen = 0;
|
||||
pBuilder->tpVLen = 0;
|
||||
pBuilder->row.flags = 0;
|
||||
}
|
||||
|
||||
int32_t tTSRowBuilderPut(STSRowBuilder *pBuilder, int32_t cid, const uint8_t *pData, uint32_t nData) {
|
||||
int32_t iCol;
|
||||
uint8_t *p;
|
||||
|
||||
// search column
|
||||
if (pBuilder->pTColumn->colId < cid) {
|
||||
iCol = (pBuilder->pTColumn - pBuilder->pTSchema->columns) / sizeof(STColumn) + 1;
|
||||
for (; iCol < pBuilder->pTSchema->numOfCols; iCol++) {
|
||||
pBuilder->pTColumn = &pBuilder->pTSchema->columns[iCol];
|
||||
if (pBuilder->pTColumn->colId == cid) break;
|
||||
}
|
||||
} else if (pBuilder->pTColumn->colId > cid) {
|
||||
iCol = (pBuilder->pTColumn - pBuilder->pTSchema->columns) / sizeof(STColumn) - 1;
|
||||
for (; iCol >= 0; iCol--) {
|
||||
pBuilder->pTColumn = &pBuilder->pTSchema->columns[iCol];
|
||||
if (pBuilder->pTColumn->colId == cid) break;
|
||||
}
|
||||
}
|
||||
|
||||
// check
|
||||
if (pBuilder->pTColumn->colId != cid || pBuilder->pTColumn->flags & COL_VAL_SET) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// set value
|
||||
if (cid == 0) {
|
||||
ASSERT(pData && nData == sizeof(TSKEY));
|
||||
pBuilder->row.ts = *(TSKEY *)pData;
|
||||
} else {
|
||||
if (pData) {
|
||||
// ASSERT(!IS_NULL(pData));
|
||||
|
||||
// set tuple data
|
||||
p = pBuilder->pTPBuf + pBuilder->pTColumn->offset;
|
||||
if (IS_VAR_DATA_TYPE(pBuilder->pTColumn->type)) {
|
||||
*(int32_t *)p = pBuilder->tpVLen;
|
||||
|
||||
// encode the variant-length data
|
||||
p = pBuilder->pTPBuf + pBuilder->pTSchema->flen + pBuilder->tpVLen;
|
||||
pBuilder->tpVLen += tPutBinary(p, pData, nData);
|
||||
} else {
|
||||
memcpy(p, pData, nData);
|
||||
}
|
||||
|
||||
// set kv data
|
||||
p = pBuilder->pKVBuf + sizeof(SKVIdx) * pBuilder->nCols;
|
||||
((SKVIdx *)p)->cid = cid;
|
||||
((SKVIdx *)p)->offset = pBuilder->kvVLen;
|
||||
|
||||
p = pBuilder->pKVBuf + sizeof(SKVIdx) * pBuilder->pTSchema->numOfCols + pBuilder->kvVLen;
|
||||
if (IS_VAR_DATA_TYPE(pBuilder->pTColumn->type)) {
|
||||
pBuilder->kvVLen += tPutBinary(p, pData, nData);
|
||||
} else {
|
||||
memcpy(p, pData, nData);
|
||||
pBuilder->kvVLen += nData;
|
||||
}
|
||||
} else {
|
||||
// set NULL val
|
||||
}
|
||||
}
|
||||
|
||||
pBuilder->pTColumn->flags |= COL_VAL_SET;
|
||||
pBuilder->nCols++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tTSRowBuilderGetRow(STSRowBuilder *pBuilder, const STSRow2 **ppRow) {
|
||||
if ((pBuilder->pTSchema->columns[0].flags & COL_VAL_SET) == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pBuilder->nCols * sizeof(SKVIdx) + pBuilder->kvVLen < pBuilder->pTSchema->flen + pBuilder->tpVLen) {
|
||||
// encode as TD_KV_ROW
|
||||
pBuilder->row.flags |= TD_KV_ROW;
|
||||
pBuilder->row.ncols = pBuilder->nCols;
|
||||
pBuilder->row.nData = pBuilder->nCols * sizeof(SKVIdx) + pBuilder->kvVLen;
|
||||
pBuilder->row.pData = pBuilder->pKVBuf;
|
||||
|
||||
if (pBuilder->nCols < pBuilder->pTSchema->numOfCols) {
|
||||
memmove(pBuilder->pKVBuf + sizeof(SKVIdx) * pBuilder->nCols,
|
||||
pBuilder->pKVBuf + sizeof(SKVIdx) * pBuilder->pTSchema->numOfCols, pBuilder->kvVLen);
|
||||
}
|
||||
} else {
|
||||
// encode as TD_TUPLE_ROW
|
||||
pBuilder->row.flags &= (~TD_KV_ROW);
|
||||
pBuilder->row.sver = pBuilder->pTSchema->version;
|
||||
pBuilder->row.nData = pBuilder->pTSchema->flen + pBuilder->tpVLen;
|
||||
pBuilder->row.pData = pBuilder->pTPBuf;
|
||||
|
||||
if (pBuilder->nCols < pBuilder->pTSchema->numOfCols) {
|
||||
// set non-set cols as None
|
||||
for (int32_t iCol = 1; iCol < pBuilder->pTSchema->numOfCols; iCol++) {
|
||||
pBuilder->pTColumn = &pBuilder->pTSchema->columns[iCol];
|
||||
if (pBuilder->pTColumn->flags & COL_VAL_SET) continue;
|
||||
|
||||
{
|
||||
// set None (todo)
|
||||
}
|
||||
|
||||
pBuilder->pTColumn->flags |= COL_VAL_SET;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*ppRow = &pBuilder->row;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 1 // ====================
|
||||
static void dataColSetNEleNull(SDataCol *pCol, int nEle);
|
||||
#if 0
|
||||
static void tdMergeTwoDataCols(SDataCols *target, SDataCols *src1, int *iter1, int limit1, SDataCols *src2, int *iter2,
|
||||
int limit2, int tRows, bool forceSetNull);
|
||||
#endif
|
||||
int tdAllocMemForCol(SDataCol *pCol, int maxPoints) {
|
||||
int tdAllocMemForCol(SDataCol *pCol, int maxPoints) {
|
||||
int spaceNeeded = pCol->bytes * maxPoints;
|
||||
if (IS_VAR_DATA_TYPE(pCol->type)) {
|
||||
spaceNeeded += sizeof(VarDataOffsetT) * maxPoints;
|
||||
|
@ -504,3 +730,4 @@ SKVRow tdGetKVRowFromBuilder(SKVRowBuilder *pBuilder) {
|
|||
|
||||
return row;
|
||||
}
|
||||
#endif
|
|
@ -153,11 +153,11 @@ bool tsStreamSchedV = true;
|
|||
|
||||
/*
|
||||
* minimum scale for whole system, millisecond by default
|
||||
* for TSDB_TIME_PRECISION_MILLI: 86400000L
|
||||
* TSDB_TIME_PRECISION_MICRO: 86400000000L
|
||||
* TSDB_TIME_PRECISION_NANO: 86400000000000L
|
||||
* for TSDB_TIME_PRECISION_MILLI: 60000L
|
||||
* TSDB_TIME_PRECISION_MICRO: 60000000L
|
||||
* TSDB_TIME_PRECISION_NANO: 60000000000L
|
||||
*/
|
||||
int64_t tsTickPerDay[] = {86400000L, 86400000000L, 86400000000000L};
|
||||
int64_t tsTickPerMin[] = {60000L, 60000000L, 60000000000L};
|
||||
|
||||
// lossy compress 6
|
||||
char tsLossyColumns[32] = ""; // "float|double" means all float and double columns can be lossy compressed. set empty
|
||||
|
@ -170,7 +170,7 @@ uint32_t tsCurRange = 100; // range
|
|||
char tsCompressor[32] = "ZSTD_COMPRESSOR"; // ZSTD_COMPRESSOR or GZIP_COMPRESSOR
|
||||
|
||||
// udf
|
||||
bool tsStartUdfd = true;
|
||||
bool tsStartUdfd = true;
|
||||
|
||||
// internal
|
||||
int32_t tsTransPullupInterval = 6;
|
||||
|
@ -444,7 +444,7 @@ static int32_t taosAddServerCfg(SConfig *pCfg) {
|
|||
if (cfgAddInt32(pCfg, "transPullupInterval", tsTransPullupInterval, 1, 10000, 1) != 0) return -1;
|
||||
if (cfgAddInt32(pCfg, "mqRebalanceInterval", tsMqRebalanceInterval, 1, 10000, 1) != 0) return -1;
|
||||
|
||||
if (cfgAddBool(pCfg, "startUdfd", tsStartUdfd, 0) != 0) return -1;
|
||||
if (cfgAddBool(pCfg, "udf", tsStartUdfd, 0) != 0) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -585,7 +585,7 @@ static int32_t taosSetServerCfg(SConfig *pCfg) {
|
|||
tsTransPullupInterval = cfgGetItem(pCfg, "transPullupInterval")->i32;
|
||||
tsMqRebalanceInterval = cfgGetItem(pCfg, "mqRebalanceInterval")->i32;
|
||||
|
||||
tsStartUdfd = cfgGetItem(pCfg, "startUdfd")->bval;
|
||||
tsStartUdfd = cfgGetItem(pCfg, "udf")->bval;
|
||||
|
||||
if (tsQueryBufferSize >= 0) {
|
||||
tsQueryBufferSizeBytes = tsQueryBufferSize * 1048576UL;
|
||||
|
|
|
@ -2764,6 +2764,7 @@ int32_t tSerializeSConnectRsp(void *buf, int32_t bufLen, SConnectRsp *pRsp) {
|
|||
if (tEncodeI32(&encoder, pRsp->acctId) < 0) return -1;
|
||||
if (tEncodeI64(&encoder, pRsp->clusterId) < 0) return -1;
|
||||
if (tEncodeU32(&encoder, pRsp->connId) < 0) return -1;
|
||||
if (tEncodeI32(&encoder, pRsp->dnodeNum) < 0) return -1;
|
||||
if (tEncodeI8(&encoder, pRsp->superUser) < 0) return -1;
|
||||
if (tEncodeI8(&encoder, pRsp->connType) < 0) return -1;
|
||||
if (tEncodeSEpSet(&encoder, &pRsp->epSet) < 0) return -1;
|
||||
|
@ -2783,6 +2784,7 @@ int32_t tDeserializeSConnectRsp(void *buf, int32_t bufLen, SConnectRsp *pRsp) {
|
|||
if (tDecodeI32(&decoder, &pRsp->acctId) < 0) return -1;
|
||||
if (tDecodeI64(&decoder, &pRsp->clusterId) < 0) return -1;
|
||||
if (tDecodeU32(&decoder, &pRsp->connId) < 0) return -1;
|
||||
if (tDecodeI32(&decoder, &pRsp->dnodeNum) < 0) return -1;
|
||||
if (tDecodeI8(&decoder, &pRsp->superUser) < 0) return -1;
|
||||
if (tDecodeI8(&decoder, &pRsp->connType) < 0) return -1;
|
||||
if (tDecodeSEpSet(&decoder, &pRsp->epSet) < 0) return -1;
|
||||
|
@ -4026,3 +4028,85 @@ int32_t tDecodeSVSubmitReq(SDecoder *pCoder, SVSubmitReq *pReq) {
|
|||
tEndDecode(pCoder);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t tEncodeSSubmitBlkRsp(SEncoder *pEncoder, const SSubmitBlkRsp *pBlock) {
|
||||
if (tStartEncode(pEncoder) < 0) return -1;
|
||||
|
||||
if (tEncodeI32(pEncoder, pBlock->code) < 0) return -1;
|
||||
if (tEncodeI8(pEncoder, pBlock->hashMeta) < 0) return -1;
|
||||
if (pBlock->hashMeta) {
|
||||
if (tEncodeI64(pEncoder, pBlock->uid) < 0) return -1;
|
||||
if (tEncodeCStr(pEncoder, pBlock->tblFName) < 0) return -1;
|
||||
}
|
||||
if (tEncodeI32v(pEncoder, pBlock->numOfRows) < 0) return -1;
|
||||
if (tEncodeI32v(pEncoder, pBlock->affectedRows) < 0) return -1;
|
||||
|
||||
tEndEncode(pEncoder);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t tDecodeSSubmitBlkRsp(SDecoder *pDecoder, SSubmitBlkRsp *pBlock) {
|
||||
if (tStartDecode(pDecoder) < 0) return -1;
|
||||
|
||||
if (tDecodeI32(pDecoder, &pBlock->code) < 0) return -1;
|
||||
if (tDecodeI8(pDecoder, &pBlock->hashMeta) < 0) return -1;
|
||||
if (pBlock->hashMeta) {
|
||||
if (tDecodeI64(pDecoder, &pBlock->uid) < 0) return -1;
|
||||
pBlock->tblFName = taosMemoryCalloc(TSDB_TABLE_FNAME_LEN, 1);
|
||||
if (NULL == pBlock->tblFName) return -1;
|
||||
if (tDecodeCStrTo(pDecoder, pBlock->tblFName) < 0) return -1;
|
||||
}
|
||||
if (tDecodeI32v(pDecoder, &pBlock->numOfRows) < 0) return -1;
|
||||
if (tDecodeI32v(pDecoder, &pBlock->affectedRows) < 0) return -1;
|
||||
|
||||
tEndDecode(pDecoder);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tEncodeSSubmitRsp(SEncoder *pEncoder, const SSubmitRsp *pRsp) {
|
||||
int32_t nBlocks = taosArrayGetSize(pRsp->pArray);
|
||||
|
||||
if (tStartEncode(pEncoder) < 0) return -1;
|
||||
|
||||
if (tEncodeI32v(pEncoder, pRsp->numOfRows) < 0) return -1;
|
||||
if (tEncodeI32v(pEncoder, pRsp->affectedRows) < 0) return -1;
|
||||
if (tEncodeI32v(pEncoder, nBlocks) < 0) return -1;
|
||||
for (int32_t iBlock = 0; iBlock < nBlocks; iBlock++) {
|
||||
if (tEncodeSSubmitBlkRsp(pEncoder, (SSubmitBlkRsp *)taosArrayGet(pRsp->pArray, iBlock)) < 0) return -1;
|
||||
}
|
||||
|
||||
tEndEncode(pEncoder);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tDecodeSSubmitRsp(SDecoder *pDecoder, SSubmitRsp *pRsp) {
|
||||
if (tStartDecode(pDecoder) < 0) return -1;
|
||||
|
||||
if (tDecodeI32v(pDecoder, &pRsp->numOfRows) < 0) return -1;
|
||||
if (tDecodeI32v(pDecoder, &pRsp->affectedRows) < 0) return -1;
|
||||
if (tDecodeI32v(pDecoder, &pRsp->nBlocks) < 0) return -1;
|
||||
pRsp->pBlocks = taosMemoryCalloc(pRsp->nBlocks, sizeof(*pRsp->pBlocks));
|
||||
if (pRsp->pBlocks == NULL) return -1;
|
||||
for (int32_t iBlock = 0; iBlock < pRsp->nBlocks; iBlock++) {
|
||||
if (tDecodeSSubmitBlkRsp(pDecoder, pRsp->pBlocks + iBlock) < 0) return -1;
|
||||
}
|
||||
|
||||
tEndDecode(pDecoder);
|
||||
tDecoderClear(pDecoder);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void tFreeSSubmitRsp(SSubmitRsp *pRsp) {
|
||||
if (NULL == pRsp) return;
|
||||
|
||||
if (pRsp->pBlocks) {
|
||||
for (int32_t i = 0; i < pRsp->nBlocks; ++i) {
|
||||
SSubmitBlkRsp *sRsp = pRsp->pBlocks + i;
|
||||
taosMemoryFree(sRsp->tblFName);
|
||||
}
|
||||
|
||||
taosMemoryFree(pRsp->pBlocks);
|
||||
}
|
||||
|
||||
taosMemoryFree(pRsp);
|
||||
}
|
||||
|
|
|
@ -1159,7 +1159,7 @@ bool tdGetKvRowValOfColEx(STSRowIter *pIter, col_id_t colId, col_type_t colType,
|
|||
|
||||
#ifdef TD_SUPPORT_BITMAP
|
||||
int16_t colIdx = -1;
|
||||
if (pKvIdx) colIdx = POINTER_DISTANCE(TD_ROW_COL_IDX(pRow), pKvIdx) / sizeof(SKvRowIdx);
|
||||
if (pKvIdx) colIdx = POINTER_DISTANCE(pKvIdx, TD_ROW_COL_IDX(pRow)) / sizeof(SKvRowIdx);
|
||||
if (tdGetBitmapValType(pIter->pBitmap, colIdx, &pVal->valType, 0) != TSDB_CODE_SUCCESS) {
|
||||
pVal->valType = TD_VTYPE_NONE;
|
||||
}
|
||||
|
@ -1226,7 +1226,7 @@ bool tdSTSRowGetVal(STSRowIter *pIter, col_id_t colId, col_type_t colType, SCell
|
|||
compareKvRowColId, TD_EQ);
|
||||
#ifdef TD_SUPPORT_BITMAP
|
||||
if (pIdx) {
|
||||
colIdx = POINTER_DISTANCE(TD_ROW_COL_IDX(pRow), pIdx) / sizeof(SKvRowIdx);
|
||||
colIdx = POINTER_DISTANCE(pIdx, TD_ROW_COL_IDX(pRow)) / sizeof(SKvRowIdx);
|
||||
}
|
||||
#endif
|
||||
tdGetKvRowValOfCol(pVal, pRow, pIter->pBitmap, pIdx ? pIdx->offset : -1, colIdx);
|
||||
|
|
|
@ -35,104 +35,36 @@
|
|||
assert(0); \
|
||||
} while (0)
|
||||
|
||||
int32_t toInteger(const char *z, int32_t n, int32_t base, int64_t *value, bool *isSigned) {
|
||||
int32_t toInteger(const char *z, int32_t n, int32_t base, int64_t *value) {
|
||||
errno = 0;
|
||||
char *endPtr = NULL;
|
||||
|
||||
int32_t index = 0;
|
||||
|
||||
bool specifiedSign = (z[0] == '+' || z[0] == '-');
|
||||
if (specifiedSign) {
|
||||
*isSigned = true;
|
||||
index = 1;
|
||||
}
|
||||
|
||||
uint64_t val = strtoull(&z[index], &endPtr, base);
|
||||
if (errno == ERANGE || errno == EINVAL) {
|
||||
*value = strtoll(z, &endPtr, base);
|
||||
if (errno == ERANGE || errno == EINVAL || endPtr - z != n) {
|
||||
errno = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (specifiedSign && val > INT64_MAX) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (endPtr - &z[index] != n - index) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*isSigned = specifiedSign || (val <= INT64_MAX);
|
||||
if (*isSigned) {
|
||||
*value = (z[0] == '-') ? -val : val;
|
||||
} else {
|
||||
*(uint64_t *)value = val;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void taosVariantCreate(SVariant *pVar, const char *z, int32_t n, int32_t type) {
|
||||
int32_t ret = 0;
|
||||
memset(pVar, 0, sizeof(SVariant));
|
||||
int32_t toUInteger(const char *z, int32_t n, int32_t base, uint64_t *value) {
|
||||
errno = 0;
|
||||
char *endPtr = NULL;
|
||||
|
||||
switch (type) {
|
||||
case TSDB_DATA_TYPE_BOOL: {
|
||||
if (strncasecmp(z, "true", 4) == 0) {
|
||||
pVar->i = TSDB_TRUE;
|
||||
} else if (strncasecmp(z, "false", 5) == 0) {
|
||||
pVar->i = TSDB_FALSE;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDB_DATA_TYPE_TINYINT:
|
||||
case TSDB_DATA_TYPE_SMALLINT:
|
||||
case TSDB_DATA_TYPE_BIGINT:
|
||||
case TSDB_DATA_TYPE_INT: {
|
||||
bool sign = true;
|
||||
|
||||
int32_t base = 10;
|
||||
if (type == TK_NK_HEX) {
|
||||
base = 16;
|
||||
} else if (type == TK_NK_OCT) {
|
||||
base = 8;
|
||||
} else if (type == TK_NK_BIN) {
|
||||
base = 2;
|
||||
}
|
||||
|
||||
ret = toInteger(z, n, base, &pVar->i, &sign);
|
||||
if (ret != 0) {
|
||||
pVar->nType = -1; // -1 means error type
|
||||
return;
|
||||
}
|
||||
|
||||
pVar->nType = (sign) ? TSDB_DATA_TYPE_BIGINT : TSDB_DATA_TYPE_UBIGINT;
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_DOUBLE:
|
||||
case TSDB_DATA_TYPE_FLOAT: {
|
||||
pVar->d = strtod(z, NULL);
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_BINARY: {
|
||||
pVar->pz = strndup(z, n);
|
||||
//pVar->nLen = strRmquote(pVar->pz, n);
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_TIMESTAMP: {
|
||||
assert(0);
|
||||
pVar->i = taosGetTimestamp(TSDB_TIME_PRECISION_NANO);
|
||||
break;
|
||||
}
|
||||
|
||||
default: { // nType == 0 means the null value
|
||||
type = TSDB_DATA_TYPE_NULL;
|
||||
}
|
||||
const char *p = z;
|
||||
while (*p != 0 && *p == ' ') p++;
|
||||
if (*p != 0 && *p == '-') {
|
||||
return -1;
|
||||
}
|
||||
|
||||
pVar->nType = type;
|
||||
*value = strtoull(z, &endPtr, base);
|
||||
if (errno == ERANGE || errno == EINVAL || endPtr - z != n) {
|
||||
errno = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -461,7 +393,7 @@ static int32_t toNchar(SVariant *pVariant, char **pDest, int32_t *pDestSize) {
|
|||
|
||||
if (*pDest == pVariant->pz) {
|
||||
TdUcs4 *pWStr = taosMemoryCalloc(1, (nLen + 1) * TSDB_NCHAR_SIZE);
|
||||
bool ret = taosMbsToUcs4(pDst, nLen, pWStr, (nLen + 1) * TSDB_NCHAR_SIZE, NULL);
|
||||
bool ret = taosMbsToUcs4(pDst, nLen, pWStr, (nLen + 1) * TSDB_NCHAR_SIZE, NULL);
|
||||
if (!ret) {
|
||||
taosMemoryFreeClear(pWStr);
|
||||
return -1;
|
||||
|
@ -483,7 +415,7 @@ static int32_t toNchar(SVariant *pVariant, char **pDest, int32_t *pDestSize) {
|
|||
} else {
|
||||
int32_t output = 0;
|
||||
|
||||
bool ret = taosMbsToUcs4(pDst, nLen, (TdUcs4*)*pDest, (nLen + 1) * TSDB_NCHAR_SIZE, &output);
|
||||
bool ret = taosMbsToUcs4(pDst, nLen, (TdUcs4 *)*pDest, (nLen + 1) * TSDB_NCHAR_SIZE, &output);
|
||||
if (!ret) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -518,9 +450,9 @@ static FORCE_INLINE int32_t convertToInteger(SVariant *pVariant, int64_t *result
|
|||
} else if (IS_UNSIGNED_NUMERIC_TYPE(pVariant->nType)) {
|
||||
*result = pVariant->u;
|
||||
} else if (IS_FLOAT_TYPE(pVariant->nType)) {
|
||||
*result = (int64_t) pVariant->d;
|
||||
*result = (int64_t)pVariant->d;
|
||||
} else {
|
||||
//TODO: handling var types
|
||||
// TODO: handling var types
|
||||
}
|
||||
#if 0
|
||||
errno = 0;
|
||||
|
@ -909,7 +841,7 @@ int32_t tVariantDumpEx(SVariant *pVariant, char *payload, int16_t type, bool inc
|
|||
return -1;
|
||||
}
|
||||
} else {
|
||||
tasoUcs4Copy((TdUcs4*)payload, pVariant->ucs4, pVariant->nLen);
|
||||
tasoUcs4Copy((TdUcs4 *)payload, pVariant->ucs4, pVariant->nLen);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -1026,7 +958,7 @@ int32_t taosVariantTypeSetType(SVariant *pVariant, char type) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
char * taosVariantGet(SVariant *pVar, int32_t type) {
|
||||
char *taosVariantGet(SVariant *pVar, int32_t type) {
|
||||
switch (type) {
|
||||
case TSDB_DATA_TYPE_BOOL:
|
||||
case TSDB_DATA_TYPE_TINYINT:
|
||||
|
|
|
@ -8,12 +8,11 @@
|
|||
#pragma GCC diagnostic ignored "-Wsign-compare"
|
||||
#include "os.h"
|
||||
|
||||
#include "taos.h"
|
||||
#include "tcommon.h"
|
||||
#include "tdatablock.h"
|
||||
#include "tcommon.h"
|
||||
#include "taos.h"
|
||||
#include "tvariant.h"
|
||||
#include "tdef.h"
|
||||
#include "tvariant.h"
|
||||
|
||||
namespace {
|
||||
//
|
||||
|
@ -29,72 +28,62 @@ TEST(testCase, toInteger_test) {
|
|||
uint32_t type = 0;
|
||||
|
||||
int64_t val = 0;
|
||||
bool sign = true;
|
||||
|
||||
int32_t ret = toInteger(s, strlen(s), 10, &val, &sign);
|
||||
int32_t ret = toInteger(s, strlen(s), 10, &val);
|
||||
ASSERT_EQ(ret, 0);
|
||||
ASSERT_EQ(val, 123);
|
||||
ASSERT_EQ(sign, true);
|
||||
|
||||
s = "9223372036854775807";
|
||||
ret = toInteger(s, strlen(s), 10, &val, &sign);
|
||||
ret = toInteger(s, strlen(s), 10, &val);
|
||||
ASSERT_EQ(ret, 0);
|
||||
ASSERT_EQ(val, 9223372036854775807);
|
||||
ASSERT_EQ(sign, true);
|
||||
|
||||
s = "9323372036854775807";
|
||||
ret = toInteger(s, strlen(s), 10, &val, &sign);
|
||||
ret = toInteger(s, strlen(s), 10, &val);
|
||||
ASSERT_EQ(ret, 0);
|
||||
ASSERT_EQ(val, 9323372036854775807u);
|
||||
ASSERT_EQ(sign, false);
|
||||
|
||||
s = "-9323372036854775807";
|
||||
ret = toInteger(s, strlen(s), 10, &val, &sign);
|
||||
ret = toInteger(s, strlen(s), 10, &val);
|
||||
ASSERT_EQ(ret, -1);
|
||||
|
||||
s = "-1";
|
||||
ret = toInteger(s, strlen(s), 10, &val, &sign);
|
||||
ret = toInteger(s, strlen(s), 10, &val);
|
||||
ASSERT_EQ(ret, 0);
|
||||
ASSERT_EQ(val, -1);
|
||||
ASSERT_EQ(sign, true);
|
||||
|
||||
s = "-9223372036854775807";
|
||||
ret = toInteger(s, strlen(s), 10, &val, &sign);
|
||||
ret = toInteger(s, strlen(s), 10, &val);
|
||||
ASSERT_EQ(ret, 0);
|
||||
ASSERT_EQ(val, -9223372036854775807);
|
||||
ASSERT_EQ(sign, true);
|
||||
|
||||
s = "1000u";
|
||||
ret = toInteger(s, strlen(s), 10, &val, &sign);
|
||||
ret = toInteger(s, strlen(s), 10, &val);
|
||||
ASSERT_EQ(ret, -1);
|
||||
|
||||
s = "0x10";
|
||||
ret = toInteger(s, strlen(s), 16, &val, &sign);
|
||||
ret = toInteger(s, strlen(s), 16, &val);
|
||||
ASSERT_EQ(ret, 0);
|
||||
ASSERT_EQ(val, 16);
|
||||
ASSERT_EQ(sign, true);
|
||||
|
||||
s = "110";
|
||||
ret = toInteger(s, strlen(s), 2, &val, &sign);
|
||||
ret = toInteger(s, strlen(s), 2, &val);
|
||||
ASSERT_EQ(ret, 0);
|
||||
ASSERT_EQ(val, 6);
|
||||
ASSERT_EQ(sign, true);
|
||||
|
||||
s = "110";
|
||||
ret = toInteger(s, strlen(s), 8, &val, &sign);
|
||||
ret = toInteger(s, strlen(s), 8, &val);
|
||||
ASSERT_EQ(ret, 0);
|
||||
ASSERT_EQ(val, 72);
|
||||
ASSERT_EQ(sign, true);
|
||||
|
||||
//18446744073709551615 UINT64_MAX
|
||||
// 18446744073709551615 UINT64_MAX
|
||||
s = "18446744073709551615";
|
||||
ret = toInteger(s, strlen(s), 10, &val, &sign);
|
||||
ret = toInteger(s, strlen(s), 10, &val);
|
||||
ASSERT_EQ(ret, 0);
|
||||
ASSERT_EQ(val, 18446744073709551615u);
|
||||
ASSERT_EQ(sign, false);
|
||||
|
||||
s = "18446744073709551616";
|
||||
ret = toInteger(s, strlen(s), 10, &val, &sign);
|
||||
ret = toInteger(s, strlen(s), 10, &val);
|
||||
ASSERT_EQ(ret, -1);
|
||||
}
|
||||
|
||||
|
@ -108,8 +97,8 @@ TEST(testCase, Datablock_test) {
|
|||
infoData.info.type = TSDB_DATA_TYPE_INT;
|
||||
infoData.info.colId = 1;
|
||||
|
||||
infoData.pData = (char*) taosMemoryCalloc(40, infoData.info.bytes);
|
||||
infoData.nullbitmap = (char*) taosMemoryCalloc(1, sizeof(char) * (40/8));
|
||||
infoData.pData = (char*)taosMemoryCalloc(40, infoData.info.bytes);
|
||||
infoData.nullbitmap = (char*)taosMemoryCalloc(1, sizeof(char) * (40 / 8));
|
||||
taosArrayPush(b->pDataBlock, &infoData);
|
||||
|
||||
SColumnInfoData infoData1 = {0};
|
||||
|
@ -117,36 +106,36 @@ TEST(testCase, Datablock_test) {
|
|||
infoData1.info.type = TSDB_DATA_TYPE_BINARY;
|
||||
infoData1.info.colId = 2;
|
||||
|
||||
infoData1.varmeta.offset = (int32_t*) taosMemoryCalloc(40, sizeof(uint32_t));
|
||||
infoData1.varmeta.offset = (int32_t*)taosMemoryCalloc(40, sizeof(uint32_t));
|
||||
taosArrayPush(b->pDataBlock, &infoData1);
|
||||
|
||||
char* str = "the value of: %d";
|
||||
char buf[128] = {0};
|
||||
char varbuf[128] = {0};
|
||||
char buf[128] = {0};
|
||||
char varbuf[128] = {0};
|
||||
|
||||
for(int32_t i = 0; i < 40; ++i) {
|
||||
SColumnInfoData* p0 = (SColumnInfoData *) taosArrayGet(b->pDataBlock, 0);
|
||||
SColumnInfoData* p1 = (SColumnInfoData *) taosArrayGet(b->pDataBlock, 1);
|
||||
for (int32_t i = 0; i < 40; ++i) {
|
||||
SColumnInfoData* p0 = (SColumnInfoData*)taosArrayGet(b->pDataBlock, 0);
|
||||
SColumnInfoData* p1 = (SColumnInfoData*)taosArrayGet(b->pDataBlock, 1);
|
||||
|
||||
if (i&0x01) {
|
||||
if (i & 0x01) {
|
||||
int32_t len = sprintf(buf, str, i);
|
||||
STR_TO_VARSTR(varbuf, buf)
|
||||
colDataAppend(p0, i, (const char*) &i, false);
|
||||
colDataAppend(p1, i, (const char*) varbuf, false);
|
||||
colDataAppend(p0, i, (const char*)&i, false);
|
||||
colDataAppend(p1, i, (const char*)varbuf, false);
|
||||
|
||||
memset(varbuf, 0, sizeof(varbuf));
|
||||
memset(buf, 0, sizeof(buf));
|
||||
} else {
|
||||
colDataAppend(p0, i, (const char*) &i, true);
|
||||
colDataAppend(p1, i, (const char*) varbuf, true);
|
||||
colDataAppend(p0, i, (const char*)&i, true);
|
||||
colDataAppend(p1, i, (const char*)varbuf, true);
|
||||
}
|
||||
|
||||
b->info.rows++;
|
||||
}
|
||||
|
||||
SColumnInfoData* p0 = (SColumnInfoData *) taosArrayGet(b->pDataBlock, 0);
|
||||
SColumnInfoData* p1 = (SColumnInfoData *) taosArrayGet(b->pDataBlock, 1);
|
||||
for(int32_t i = 0; i < 40; ++i) {
|
||||
SColumnInfoData* p0 = (SColumnInfoData*)taosArrayGet(b->pDataBlock, 0);
|
||||
SColumnInfoData* p1 = (SColumnInfoData*)taosArrayGet(b->pDataBlock, 1);
|
||||
for (int32_t i = 0; i < 40; ++i) {
|
||||
if (i & 0x01) {
|
||||
ASSERT_EQ(colDataIsNull_f(p0->nullbitmap, i), false);
|
||||
ASSERT_EQ(colDataIsNull(p1, b->info.rows, i, nullptr), false);
|
||||
|
@ -158,7 +147,7 @@ TEST(testCase, Datablock_test) {
|
|||
}
|
||||
}
|
||||
|
||||
printf("binary column length:%d\n", *(int32_t*) p1->pData);
|
||||
printf("binary column length:%d\n", *(int32_t*)p1->pData);
|
||||
|
||||
ASSERT_EQ(blockDataGetNumOfCols(b), 2);
|
||||
ASSERT_EQ(blockDataGetNumOfRows(b), 40);
|
||||
|
@ -166,8 +155,8 @@ TEST(testCase, Datablock_test) {
|
|||
char* pData = colDataGetData(p1, 3);
|
||||
printf("the second row of binary:%s, length:%d\n", (char*)varDataVal(pData), varDataLen(pData));
|
||||
|
||||
SArray* pOrderInfo = taosArrayInit(3, sizeof(SBlockOrderInfo));
|
||||
SBlockOrderInfo order = { true, TSDB_ORDER_ASC, 0, NULL };
|
||||
SArray* pOrderInfo = taosArrayInit(3, sizeof(SBlockOrderInfo));
|
||||
SBlockOrderInfo order = {true, TSDB_ORDER_ASC, 0, NULL};
|
||||
taosArrayPush(pOrderInfo, &order);
|
||||
|
||||
blockDataSort(b, pOrderInfo);
|
||||
|
@ -244,8 +233,8 @@ TEST(testCase, var_dataBlock_split_test) {
|
|||
infoData.info.type = TSDB_DATA_TYPE_INT;
|
||||
infoData.info.colId = 1;
|
||||
|
||||
infoData.pData = (char*) taosMemoryCalloc(numOfRows, infoData.info.bytes);
|
||||
infoData.nullbitmap = (char*) taosMemoryCalloc(1, sizeof(char) * (numOfRows/8));
|
||||
infoData.pData = (char*)taosMemoryCalloc(numOfRows, infoData.info.bytes);
|
||||
infoData.nullbitmap = (char*)taosMemoryCalloc(1, sizeof(char) * (numOfRows / 8));
|
||||
taosArrayPush(b->pDataBlock, &infoData);
|
||||
|
||||
SColumnInfoData infoData1 = {0};
|
||||
|
@ -253,13 +242,13 @@ TEST(testCase, var_dataBlock_split_test) {
|
|||
infoData1.info.type = TSDB_DATA_TYPE_BINARY;
|
||||
infoData1.info.colId = 2;
|
||||
|
||||
infoData1.varmeta.offset = (int32_t*) taosMemoryCalloc(numOfRows, sizeof(uint32_t));
|
||||
infoData1.varmeta.offset = (int32_t*)taosMemoryCalloc(numOfRows, sizeof(uint32_t));
|
||||
taosArrayPush(b->pDataBlock, &infoData1);
|
||||
|
||||
char buf[41] = {0};
|
||||
char buf1[100] = {0};
|
||||
|
||||
for(int32_t i = 0; i < numOfRows; ++i) {
|
||||
for (int32_t i = 0; i < numOfRows; ++i) {
|
||||
SColumnInfoData* p0 = (SColumnInfoData*)taosArrayGet(b->pDataBlock, 0);
|
||||
SColumnInfoData* p1 = (SColumnInfoData*)taosArrayGet(b->pDataBlock, 1);
|
||||
|
||||
|
@ -278,10 +267,10 @@ TEST(testCase, var_dataBlock_split_test) {
|
|||
|
||||
int32_t pageSize = 64 * 1024;
|
||||
|
||||
int32_t startIndex= 0;
|
||||
int32_t startIndex = 0;
|
||||
int32_t stopIndex = 0;
|
||||
int32_t count = 1;
|
||||
while(1) {
|
||||
while (1) {
|
||||
blockDataSplitRows(b, true, startIndex, &stopIndex, pageSize);
|
||||
printf("the %d split, from: %d to %d\n", count++, startIndex, stopIndex);
|
||||
|
||||
|
|
|
@ -140,11 +140,18 @@ static void vmGenerateVnodeCfg(SCreateVnodeReq *pCreate, SVnodeCfg *pCfg) {
|
|||
pCfg->vgId = pCreate->vgId;
|
||||
tstrncpy(pCfg->dbname, pCreate->db, sizeof(pCfg->dbname));
|
||||
pCfg->dbId = pCreate->dbUid;
|
||||
pCfg->szPage = pCreate->pageSize * 1024;
|
||||
pCfg->szCache = pCreate->pages;
|
||||
pCfg->szBuf = pCreate->buffer * 1024 * 1024;
|
||||
pCfg->isWeak = true;
|
||||
pCfg->tsdbCfg.days = 10;
|
||||
pCfg->tsdbCfg.keep0 = 3650;
|
||||
pCfg->tsdbCfg.keep1 = 3650;
|
||||
pCfg->tsdbCfg.keep2 = 3650;
|
||||
pCfg->tsdbCfg.compression = pCreate->compression;
|
||||
pCfg->tsdbCfg.precision = pCreate->precision;
|
||||
pCfg->tsdbCfg.days = pCreate->daysPerFile;
|
||||
pCfg->tsdbCfg.keep0 = pCreate->daysToKeep0;
|
||||
pCfg->tsdbCfg.keep1 = pCreate->daysToKeep1;
|
||||
pCfg->tsdbCfg.keep2 = pCreate->daysToKeep2;
|
||||
pCfg->tsdbCfg.minRows = pCreate->minRows;
|
||||
pCfg->tsdbCfg.maxRows = pCreate->maxRows;
|
||||
for (size_t i = 0; i < taosArrayGetSize(pCreate->pRetensions); ++i) {
|
||||
memcpy(&pCfg->tsdbCfg.retentions[i], taosArrayGet(pCreate->pRetensions, i), sizeof(SRetention));
|
||||
}
|
||||
|
|
|
@ -452,6 +452,7 @@ typedef struct {
|
|||
int8_t withSchema;
|
||||
int8_t withTag;
|
||||
SRWLatch lock;
|
||||
int32_t consumerCnt;
|
||||
int32_t sqlLen;
|
||||
int32_t astLen;
|
||||
char* sql;
|
||||
|
|
|
@ -412,8 +412,8 @@ static void mndSetDefaultDbCfg(SDbCfg *pCfg) {
|
|||
if (pCfg->numOfVgroups < 0) pCfg->numOfVgroups = TSDB_DEFAULT_VN_PER_DB;
|
||||
if (pCfg->numOfStables < 0) pCfg->numOfStables = TSDB_DEFAULT_DB_SINGLE_STABLE;
|
||||
if (pCfg->buffer < 0) pCfg->buffer = TSDB_DEFAULT_BUFFER_PER_VNODE;
|
||||
if (pCfg->pageSize < 0) pCfg->pageSize = TSDB_DEFAULT_PAGES_PER_VNODE;
|
||||
if (pCfg->pages < 0) pCfg->pages = TSDB_MAX_PAGESIZE_PER_VNODE;
|
||||
if (pCfg->pageSize < 0) pCfg->pageSize = TSDB_DEFAULT_PAGESIZE_PER_VNODE;
|
||||
if (pCfg->pages < 0) pCfg->pages = TSDB_DEFAULT_PAGES_PER_VNODE;
|
||||
if (pCfg->daysPerFile < 0) pCfg->daysPerFile = TSDB_DEFAULT_DURATION_PER_FILE;
|
||||
if (pCfg->daysToKeep0 < 0) pCfg->daysToKeep0 = TSDB_DEFAULT_KEEP;
|
||||
if (pCfg->daysToKeep1 < 0) pCfg->daysToKeep1 = pCfg->daysToKeep0;
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "mndShow.h"
|
||||
#include "mndStb.h"
|
||||
#include "mndUser.h"
|
||||
#include "mndDnode.h"
|
||||
#include "tglobal.h"
|
||||
#include "version.h"
|
||||
|
||||
|
@ -227,6 +228,7 @@ static int32_t mndProcessConnectReq(SNodeMsg *pReq) {
|
|||
connectRsp.clusterId = pMnode->clusterId;
|
||||
connectRsp.connId = pConn->id;
|
||||
connectRsp.connType = connReq.connType;
|
||||
connectRsp.dnodeNum = mndGetDnodeSize(pMnode);
|
||||
|
||||
snprintf(connectRsp.sVersion, sizeof(connectRsp.sVersion), "ver:%s\nbuild:%s\ngitinfo:%s", version, buildinfo,
|
||||
gitinfo);
|
||||
|
|
|
@ -318,6 +318,7 @@ static int32_t mndStbActionUpdate(SSdb *pSdb, SStbObj *pOld, SStbObj *pNew) {
|
|||
pOld->updateTime = pNew->updateTime;
|
||||
pOld->version = pNew->version;
|
||||
pOld->nextColId = pNew->nextColId;
|
||||
pOld->ttl = pNew->ttl;
|
||||
pOld->numOfColumns = pNew->numOfColumns;
|
||||
pOld->numOfTags = pNew->numOfTags;
|
||||
memcpy(pOld->pColumns, pNew->pColumns, pOld->numOfColumns * sizeof(SSchema));
|
||||
|
@ -832,7 +833,7 @@ static int32_t mndProcessVCreateStbRsp(SNodeMsg *pRsp) {
|
|||
}
|
||||
|
||||
static int32_t mndCheckAlterStbReq(SMAlterStbReq *pAlter) {
|
||||
if (pAlter->commentLen != 0) return 0;
|
||||
if (pAlter->commentLen != 0 || pAlter->ttl != 0) return 0;
|
||||
|
||||
if (pAlter->numOfFields < 1 || pAlter->numOfFields != (int32_t)taosArrayGetSize(pAlter->pFields)) {
|
||||
terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
|
||||
|
@ -883,7 +884,8 @@ static int32_t mndAllocStbSchemas(const SStbObj *pOld, SStbObj *pNew) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mndUpdateStbComment(const SStbObj *pOld, SStbObj *pNew, char *pComment, int32_t commentLen) {
|
||||
static int32_t mndUpdateStbCommentAndTTL(const SStbObj *pOld, SStbObj *pNew, char *pComment, int32_t commentLen,
|
||||
int32_t ttl) {
|
||||
if (commentLen > 0) {
|
||||
pNew->commentLen = commentLen;
|
||||
pNew->comment = taosMemoryCalloc(1, commentLen);
|
||||
|
@ -893,6 +895,9 @@ static int32_t mndUpdateStbComment(const SStbObj *pOld, SStbObj *pNew, char *pCo
|
|||
}
|
||||
memcpy(pNew->comment, pComment, commentLen);
|
||||
}
|
||||
if (ttl >= 0) {
|
||||
pNew->ttl = ttl;
|
||||
}
|
||||
|
||||
if (mndAllocStbSchemas(pOld, pNew) != 0) {
|
||||
return -1;
|
||||
|
@ -1232,7 +1237,7 @@ static int32_t mndAlterStb(SMnode *pMnode, SNodeMsg *pReq, const SMAlterStbReq *
|
|||
code = mndAlterStbColumnBytes(pOld, &stbObj, pField0);
|
||||
break;
|
||||
case TSDB_ALTER_TABLE_UPDATE_OPTIONS:
|
||||
code = mndUpdateStbComment(pOld, &stbObj, pAlter->comment, pAlter->commentLen);
|
||||
code = mndUpdateStbCommentAndTTL(pOld, &stbObj, pAlter->comment, pAlter->commentLen, pAlter->ttl);
|
||||
break;
|
||||
default:
|
||||
terrno = TSDB_CODE_OPS_NOT_SUPPORT;
|
||||
|
@ -1723,7 +1728,7 @@ static int32_t mndRetrieveStb(SNodeMsg *pReq, SShowObj *pShow, SSDataBlock *pBlo
|
|||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataAppend(pColInfo, numOfRows, (const char *)&pStb->updateTime, false); // number of tables
|
||||
|
||||
char *p = taosMemoryMalloc(pStb->commentLen + VARSTR_HEADER_SIZE); // check malloc failures
|
||||
char *p = taosMemoryCalloc(1, pStb->commentLen + 1 + VARSTR_HEADER_SIZE); // check malloc failures
|
||||
if (p != NULL) {
|
||||
if (pStb->commentLen != 0) {
|
||||
STR_TO_VARSTR(p, pStb->comment);
|
||||
|
|
|
@ -787,6 +787,8 @@ static int32_t mndRetrieveSubscribe(SNodeMsg *pReq, SShowObj *pShow, SSDataBlock
|
|||
}
|
||||
}
|
||||
|
||||
// do not show for cleared subscription
|
||||
#if 0
|
||||
int32_t sz = taosArrayGetSize(pSub->unassignedVgs);
|
||||
for (int32_t i = 0; i < sz; i++) {
|
||||
SMqVgEp *pVgEp = taosArrayGetP(pSub->unassignedVgs, i);
|
||||
|
@ -829,6 +831,7 @@ static int32_t mndRetrieveSubscribe(SNodeMsg *pReq, SShowObj *pShow, SSDataBlock
|
|||
numOfRows++;
|
||||
}
|
||||
|
||||
#endif
|
||||
taosRUnLockLatch(&pSub->lock);
|
||||
sdbRelease(pSdb, pSub);
|
||||
}
|
||||
|
|
|
@ -89,6 +89,8 @@ SSdbRaw *mndTopicActionEncode(SMqTopicObj *pTopic) {
|
|||
SDB_SET_INT8(pRaw, dataPos, pTopic->withTbName, TOPIC_ENCODE_OVER);
|
||||
SDB_SET_INT8(pRaw, dataPos, pTopic->withSchema, TOPIC_ENCODE_OVER);
|
||||
SDB_SET_INT8(pRaw, dataPos, pTopic->withTag, TOPIC_ENCODE_OVER);
|
||||
|
||||
SDB_SET_INT32(pRaw, dataPos, pTopic->consumerCnt, TOPIC_ENCODE_OVER);
|
||||
SDB_SET_INT32(pRaw, dataPos, pTopic->sqlLen, TOPIC_ENCODE_OVER);
|
||||
SDB_SET_BINARY(pRaw, dataPos, pTopic->sql, pTopic->sqlLen, TOPIC_ENCODE_OVER);
|
||||
SDB_SET_INT32(pRaw, dataPos, pTopic->astLen, TOPIC_ENCODE_OVER);
|
||||
|
@ -152,6 +154,8 @@ SSdbRow *mndTopicActionDecode(SSdbRaw *pRaw) {
|
|||
SDB_GET_INT8(pRaw, dataPos, &pTopic->withSchema, TOPIC_DECODE_OVER);
|
||||
SDB_GET_INT8(pRaw, dataPos, &pTopic->withTag, TOPIC_DECODE_OVER);
|
||||
|
||||
SDB_GET_INT32(pRaw, dataPos, &pTopic->consumerCnt, TOPIC_DECODE_OVER);
|
||||
|
||||
SDB_GET_INT32(pRaw, dataPos, &pTopic->sqlLen, TOPIC_DECODE_OVER);
|
||||
pTopic->sql = taosMemoryCalloc(pTopic->sqlLen, sizeof(char));
|
||||
if (pTopic->sql == NULL) {
|
||||
|
@ -293,8 +297,8 @@ static int32_t mndCreateTopic(SMnode *pMnode, SNodeMsg *pReq, SCMCreateTopicReq
|
|||
topicObj.ast = strdup(pCreate->ast);
|
||||
topicObj.astLen = strlen(pCreate->ast) + 1;
|
||||
topicObj.subType = TOPIC_SUB_TYPE__TABLE;
|
||||
topicObj.withTbName = 0;
|
||||
topicObj.withSchema = 0;
|
||||
topicObj.withTbName = pCreate->withTbName;
|
||||
topicObj.withSchema = pCreate->withSchema;
|
||||
|
||||
SNode *pAst = NULL;
|
||||
if (nodesStringToNode(pCreate->ast, &pAst) != 0) {
|
||||
|
@ -481,8 +485,10 @@ static int32_t mndProcessDropTopicReq(SNodeMsg *pReq) {
|
|||
return -1;
|
||||
}
|
||||
}
|
||||
// TODO: check ref
|
||||
|
||||
int32_t code = mndDropTopic(pMnode, pReq, pTopic);
|
||||
// TODO: iterate and drop related subscriptions and offsets
|
||||
mndReleaseTopic(pMnode, pTopic);
|
||||
|
||||
if (code != 0) {
|
||||
|
|
|
@ -72,10 +72,11 @@ typedef struct SMeta SMeta; // todo: remove
|
|||
typedef struct SMetaReader SMetaReader;
|
||||
typedef struct SMetaEntry SMetaEntry;
|
||||
|
||||
void metaReaderInit(SMetaReader *pReader, SMeta *pMeta, int32_t flags);
|
||||
void metaReaderClear(SMetaReader *pReader);
|
||||
int metaGetTableEntryByUid(SMetaReader *pReader, tb_uid_t uid);
|
||||
int metaReadNext(SMetaReader *pReader);
|
||||
void metaReaderInit(SMetaReader *pReader, SMeta *pMeta, int32_t flags);
|
||||
void metaReaderClear(SMetaReader *pReader);
|
||||
int metaGetTableEntryByUid(SMetaReader *pReader, tb_uid_t uid);
|
||||
int metaReadNext(SMetaReader *pReader);
|
||||
const void *metaGetTableTagVal(SMetaEntry *pEntry, int16_t cid);
|
||||
|
||||
#if 1 // refact APIs below (TODO)
|
||||
typedef SVCreateTbReq STbCfg;
|
||||
|
|
|
@ -37,6 +37,9 @@ typedef struct SMSmaCursor SMSmaCursor;
|
|||
// clang-format on
|
||||
|
||||
// metaOpen ==================
|
||||
int32_t metaRLock(SMeta* pMeta);
|
||||
int32_t metaWLock(SMeta* pMeta);
|
||||
int32_t metaULock(SMeta* pMeta);
|
||||
|
||||
// metaEntry ==================
|
||||
int metaEncodeEntry(SEncoder* pCoder, const SMetaEntry* pME);
|
||||
|
@ -57,6 +60,8 @@ int metaRemoveTableFromIdx(SMeta* pMeta, tb_uid_t uid);
|
|||
static FORCE_INLINE tb_uid_t metaGenerateUid(SMeta* pMeta) { return tGenIdPI64(); }
|
||||
|
||||
struct SMeta {
|
||||
TdThreadRwlock lock;
|
||||
|
||||
char* path;
|
||||
SVnode* pVnode;
|
||||
TENV* pEnv;
|
||||
|
@ -111,10 +116,10 @@ int64_t metaSmaCursorNext(SMSmaCursor* pSmaCur);
|
|||
// SMetaDB
|
||||
int metaOpenDB(SMeta* pMeta);
|
||||
void metaCloseDB(SMeta* pMeta);
|
||||
int metaSaveTableToDB(SMeta* pMeta, STbCfg* pTbCfg, STbDdlH* pHandle);
|
||||
int metaRemoveTableFromDb(SMeta* pMeta, tb_uid_t uid);
|
||||
int metaSaveSmaToDB(SMeta* pMeta, STSma* pTbCfg);
|
||||
int metaRemoveSmaFromDb(SMeta* pMeta, int64_t indexUid);
|
||||
// int metaSaveTableToDB(SMeta* pMeta, STbCfg* pTbCfg, STbDdlH* pHandle);
|
||||
int metaRemoveTableFromDb(SMeta* pMeta, tb_uid_t uid);
|
||||
int metaSaveSmaToDB(SMeta* pMeta, STSma* pTbCfg);
|
||||
int metaRemoveSmaFromDb(SMeta* pMeta, int64_t indexUid);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -123,4 +128,4 @@ int metaRemoveSmaFromDb(SMeta* pMeta, int64_t indexUid);
|
|||
}
|
||||
#endif
|
||||
|
||||
#endif /*_TD_VNODE_META_H_*/
|
||||
#endif /*_TD_VNODE_META_H_*/
|
||||
|
|
|
@ -518,9 +518,9 @@ void tsdbGetRtnSnap(STsdb *pRepo, SRtn *pRtn);
|
|||
|
||||
static FORCE_INLINE int TSDB_KEY_FID(TSKEY key, int32_t days, int8_t precision) {
|
||||
if (key < 0) {
|
||||
return (int)((key + 1) / tsTickPerDay[precision] / days - 1);
|
||||
return (int)((key + 1) / tsTickPerMin[precision] / days - 1);
|
||||
} else {
|
||||
return (int)((key / tsTickPerDay[precision] / days));
|
||||
return (int)((key / tsTickPerMin[precision] / days));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -770,8 +770,8 @@ static FORCE_INLINE int tsdbCopyDFileSet(SDFileSet *pSrc, SDFileSet *pDest) {
|
|||
}
|
||||
|
||||
static FORCE_INLINE void tsdbGetFidKeyRange(int days, int8_t precision, int fid, TSKEY *minKey, TSKEY *maxKey) {
|
||||
*minKey = fid * days * tsTickPerDay[precision];
|
||||
*maxKey = *minKey + days * tsTickPerDay[precision] - 1;
|
||||
*minKey = fid * days * tsTickPerMin[precision];
|
||||
*maxKey = *minKey + days * tsTickPerMin[precision] - 1;
|
||||
}
|
||||
|
||||
static FORCE_INLINE bool tsdbFSetIsOk(SDFileSet *pSet) {
|
||||
|
|
|
@ -102,7 +102,7 @@ int32_t tsdbUpdateSmaWindow(STsdb* pTsdb, SSubmitReq* pMsg, int64_t version
|
|||
int32_t tsdbCreateTSma(STsdb* pTsdb, char* pMsg);
|
||||
int32_t tsdbInsertTSmaData(STsdb* pTsdb, int64_t indexUid, const char* msg);
|
||||
int tsdbInsertData(STsdb* pTsdb, int64_t version, SSubmitReq* pMsg, SSubmitRsp* pRsp);
|
||||
int tsdbInsertTableData(STsdb* pTsdb, SSubmitMsgIter* pMsgIter, SSubmitBlk* pBlock, int32_t* pAffectedRows);
|
||||
int tsdbInsertTableData(STsdb* pTsdb, SSubmitMsgIter* pMsgIter, SSubmitBlk* pBlock, SSubmitBlkRsp* pRsp);
|
||||
tsdbReaderT* tsdbQueryTables(SVnode* pVnode, SQueryTableDataCond* pCond, STableGroupInfo* groupList, uint64_t qId,
|
||||
uint64_t taskId);
|
||||
tsdbReaderT tsdbQueryCacheLastT(STsdb* tsdb, SQueryTableDataCond* pCond, STableGroupInfo* groupList, uint64_t qId,
|
||||
|
|
|
@ -22,6 +22,9 @@ static int tagIdxKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kL
|
|||
static int ttlIdxKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2);
|
||||
static int uidIdxKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2);
|
||||
|
||||
static int32_t metaInitLock(SMeta *pMeta) { return taosThreadRwlockInit(&pMeta->lock, NULL); }
|
||||
static int32_t metaDestroyLock(SMeta *pMeta) { return taosThreadRwlockDestroy(&pMeta->lock); }
|
||||
|
||||
int metaOpen(SVnode *pVnode, SMeta **ppMeta) {
|
||||
SMeta *pMeta = NULL;
|
||||
int ret;
|
||||
|
@ -36,6 +39,7 @@ int metaOpen(SVnode *pVnode, SMeta **ppMeta) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
metaInitLock(pMeta);
|
||||
pMeta->path = (char *)&pMeta[1];
|
||||
sprintf(pMeta->path, "%s%s%s%s%s", tfsGetPrimaryPath(pVnode->pTfs), TD_DIRSEP, pVnode->path, TD_DIRSEP,
|
||||
VNODE_META_DIR);
|
||||
|
@ -121,6 +125,7 @@ _err:
|
|||
if (pMeta->pSkmDb) tdbDbClose(pMeta->pSkmDb);
|
||||
if (pMeta->pTbDb) tdbDbClose(pMeta->pTbDb);
|
||||
if (pMeta->pEnv) tdbEnvClose(pMeta->pEnv);
|
||||
metaDestroyLock(pMeta);
|
||||
taosMemoryFree(pMeta);
|
||||
return -1;
|
||||
}
|
||||
|
@ -136,12 +141,19 @@ int metaClose(SMeta *pMeta) {
|
|||
if (pMeta->pSkmDb) tdbDbClose(pMeta->pSkmDb);
|
||||
if (pMeta->pTbDb) tdbDbClose(pMeta->pTbDb);
|
||||
if (pMeta->pEnv) tdbEnvClose(pMeta->pEnv);
|
||||
metaDestroyLock(pMeta);
|
||||
taosMemoryFree(pMeta);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t metaRLock(SMeta *pMeta) { return taosThreadRwlockRdlock(&pMeta->lock); }
|
||||
|
||||
int32_t metaWLock(SMeta *pMeta) { return taosThreadRwlockWrlock(&pMeta->lock); }
|
||||
|
||||
int32_t metaULock(SMeta *pMeta) { return taosThreadRwlockUnlock(&pMeta->lock); }
|
||||
|
||||
static int tbDbKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2) {
|
||||
STbDbKey *pTbDbKey1 = (STbDbKey *)pKey1;
|
||||
STbDbKey *pTbDbKey2 = (STbDbKey *)pKey2;
|
||||
|
|
|
@ -19,9 +19,13 @@ void metaReaderInit(SMetaReader *pReader, SMeta *pMeta, int32_t flags) {
|
|||
memset(pReader, 0, sizeof(*pReader));
|
||||
pReader->flags = flags;
|
||||
pReader->pMeta = pMeta;
|
||||
metaRLock(pMeta);
|
||||
}
|
||||
|
||||
void metaReaderClear(SMetaReader *pReader) {
|
||||
if (pReader->pMeta) {
|
||||
metaULock(pReader->pMeta);
|
||||
}
|
||||
tDecoderClear(&pReader->coder);
|
||||
tdbFree(pReader->pBuf);
|
||||
}
|
||||
|
@ -154,7 +158,9 @@ SSchemaWrapper *metaGetTableSchema(SMeta *pMeta, tb_uid_t uid, int32_t sver, boo
|
|||
skmDbKey.sver = sver;
|
||||
pKey = &skmDbKey;
|
||||
kLen = sizeof(skmDbKey);
|
||||
metaRLock(pMeta);
|
||||
ret = tdbDbGet(pMeta->pSkmDb, pKey, kLen, &pVal, &vLen);
|
||||
metaULock(pMeta);
|
||||
if (ret < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -177,6 +183,7 @@ SSchemaWrapper *metaGetTableSchema(SMeta *pMeta, tb_uid_t uid, int32_t sver, boo
|
|||
}
|
||||
|
||||
struct SMCtbCursor {
|
||||
SMeta *pMeta;
|
||||
TDBC *pCur;
|
||||
tb_uid_t suid;
|
||||
void *pKey;
|
||||
|
@ -196,9 +203,13 @@ SMCtbCursor *metaOpenCtbCursor(SMeta *pMeta, tb_uid_t uid) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
pCtbCur->pMeta = pMeta;
|
||||
pCtbCur->suid = uid;
|
||||
metaRLock(pMeta);
|
||||
|
||||
ret = tdbDbcOpen(pMeta->pCtbIdx, &pCtbCur->pCur, NULL);
|
||||
if (ret < 0) {
|
||||
metaULock(pMeta);
|
||||
taosMemoryFree(pCtbCur);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -216,6 +227,7 @@ SMCtbCursor *metaOpenCtbCursor(SMeta *pMeta, tb_uid_t uid) {
|
|||
|
||||
void metaCloseCtbCurosr(SMCtbCursor *pCtbCur) {
|
||||
if (pCtbCur) {
|
||||
if (pCtbCur->pMeta) metaULock(pCtbCur->pMeta);
|
||||
if (pCtbCur->pCur) {
|
||||
tdbDbcClose(pCtbCur->pCur);
|
||||
|
||||
|
@ -264,6 +276,8 @@ STSchema *metaGetTbTSchema(SMeta *pMeta, tb_uid_t uid, int32_t sver) {
|
|||
metaReaderClear(&mr);
|
||||
|
||||
pSW = metaGetTableSchema(pMeta, quid, sver, 0);
|
||||
if (!pSW) return NULL;
|
||||
|
||||
tdInitTSchemaBuilder(&sb, 0);
|
||||
for (int i = 0; i < pSW->nCols; i++) {
|
||||
pSchema = pSW->pSchema + i;
|
||||
|
@ -452,3 +466,8 @@ void *metaGetSmaInfoByIndex(SMeta *pMeta, int64_t indexUid, bool isDecode) {
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
const void *metaGetTableTagVal(SMetaEntry *pEntry, int16_t cid) {
|
||||
ASSERT(pEntry->type == TSDB_CHILD_TABLE);
|
||||
return tdGetKVRowValOfCol((const SKVRow)pEntry->ctbEntry.pTags, cid);
|
||||
}
|
|
@ -439,29 +439,36 @@ _exit:
|
|||
}
|
||||
|
||||
static int metaHandleEntry(SMeta *pMeta, const SMetaEntry *pME) {
|
||||
metaWLock(pMeta);
|
||||
|
||||
// save to table.db
|
||||
if (metaSaveToTbDb(pMeta, pME) < 0) return -1;
|
||||
if (metaSaveToTbDb(pMeta, pME) < 0) goto _err;
|
||||
|
||||
// update uid.idx
|
||||
if (metaUpdateUidIdx(pMeta, pME) < 0) return -1;
|
||||
if (metaUpdateUidIdx(pMeta, pME) < 0) goto _err;
|
||||
|
||||
// update name.idx
|
||||
if (metaUpdateNameIdx(pMeta, pME) < 0) return -1;
|
||||
if (metaUpdateNameIdx(pMeta, pME) < 0) goto _err;
|
||||
|
||||
if (pME->type == TSDB_CHILD_TABLE) {
|
||||
// update ctb.idx
|
||||
if (metaUpdateCtbIdx(pMeta, pME) < 0) return -1;
|
||||
if (metaUpdateCtbIdx(pMeta, pME) < 0) goto _err;
|
||||
|
||||
// update tag.idx
|
||||
if (metaUpdateTagIdx(pMeta, pME) < 0) return -1;
|
||||
if (metaUpdateTagIdx(pMeta, pME) < 0) goto _err;
|
||||
} else {
|
||||
// update schema.db
|
||||
if (metaSaveToSkmDb(pMeta, pME) < 0) return -1;
|
||||
if (metaSaveToSkmDb(pMeta, pME) < 0) goto _err;
|
||||
}
|
||||
|
||||
if (pME->type != TSDB_SUPER_TABLE) {
|
||||
if (metaUpdateTtlIdx(pMeta, pME) < 0) return -1;
|
||||
if (metaUpdateTtlIdx(pMeta, pME) < 0) goto _err;
|
||||
}
|
||||
|
||||
metaULock(pMeta);
|
||||
return 0;
|
||||
|
||||
_err:
|
||||
metaULock(pMeta);
|
||||
return -1;
|
||||
}
|
|
@ -66,9 +66,9 @@ static void tdSRowDemo() {
|
|||
SRowBuilder rb = {0};
|
||||
|
||||
SSchema schema[DEMO_N_COLS] = {
|
||||
{.type = TSDB_DATA_TYPE_TIMESTAMP, .colId = 1, .name = "ts", .bytes = 8, .flags = SCHEMA_SMA_ON},
|
||||
{.type = TSDB_DATA_TYPE_INT, .colId = 2, .name = "c1", .bytes = 4, .flags = SCHEMA_SMA_ON},
|
||||
{.type = TSDB_DATA_TYPE_INT, .colId = 3, .name = "c2", .bytes = 4, .flags = SCHEMA_SMA_ON}};
|
||||
{.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);
|
||||
|
@ -401,7 +401,7 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg, int32_t workerId) {
|
|||
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);
|
||||
fetchOffset = walGetCommittedVer(pTq->pWal);
|
||||
} else {
|
||||
fetchOffset = pReq->currentOffset + 1;
|
||||
}
|
||||
|
@ -427,9 +427,17 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg, int32_t workerId) {
|
|||
SMqDataBlkRsp rsp = {0};
|
||||
rsp.reqOffset = pReq->currentOffset;
|
||||
rsp.withSchema = pExec->withSchema;
|
||||
|
||||
rsp.blockData = taosArrayInit(0, sizeof(void*));
|
||||
rsp.blockDataLen = taosArrayInit(0, sizeof(int32_t));
|
||||
rsp.blockSchema = taosArrayInit(0, sizeof(void*));
|
||||
rsp.blockTbName = taosArrayInit(0, sizeof(void*));
|
||||
|
||||
int8_t withTbName = pExec->withTbName;
|
||||
if (pReq->withTbName != -1) {
|
||||
withTbName = pReq->withTbName;
|
||||
}
|
||||
rsp.withTbName = withTbName;
|
||||
|
||||
while (1) {
|
||||
consumerEpoch = atomic_load_32(&pExec->epoch);
|
||||
|
@ -535,6 +543,18 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg, int32_t workerId) {
|
|||
taosArrayPush(rsp.blockSchema, &pSW);
|
||||
}
|
||||
|
||||
if (withTbName) {
|
||||
SMetaReader mr = {0};
|
||||
metaReaderInit(&mr, pTq->pVnode->pMeta, 0);
|
||||
int64_t uid = pExec->pExecReader[workerId]->msgIter.uid;
|
||||
if (metaGetTableEntryByUid(&mr, uid) < 0) {
|
||||
ASSERT(0);
|
||||
}
|
||||
char* tbName = strdup(mr.me.name);
|
||||
taosArrayPush(rsp.blockTbName, &tbName);
|
||||
metaReaderClear(&mr);
|
||||
}
|
||||
|
||||
rsp.blockNum++;
|
||||
}
|
||||
// db subscribe
|
||||
|
@ -563,6 +583,16 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg, int32_t workerId) {
|
|||
ASSERT(actualLen <= dataStrLen);
|
||||
taosArrayPush(rsp.blockDataLen, &actualLen);
|
||||
taosArrayPush(rsp.blockData, &buf);
|
||||
if (withTbName) {
|
||||
SMetaReader mr = {0};
|
||||
metaReaderInit(&mr, pTq->pVnode->pMeta, 0);
|
||||
if (metaGetTableEntryByUid(&mr, block.info.uid) < 0) {
|
||||
ASSERT(0);
|
||||
}
|
||||
char* tbName = strdup(mr.me.name);
|
||||
taosArrayPush(rsp.blockTbName, &tbName);
|
||||
metaReaderClear(&mr);
|
||||
}
|
||||
|
||||
SSchemaWrapper* pSW = tCloneSSchemaWrapper(pExec->pExecReader[workerId]->pSchemaWrapper);
|
||||
taosArrayPush(rsp.blockSchema, &pSW);
|
||||
|
@ -614,6 +644,7 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg, int32_t workerId) {
|
|||
taosArrayDestroy(rsp.blockData);
|
||||
taosArrayDestroy(rsp.blockDataLen);
|
||||
taosArrayDestroyP(rsp.blockSchema, (FDelete)tDeleteSSchemaWrapper);
|
||||
taosArrayDestroyP(rsp.blockTbName, (FDelete)taosMemoryFree);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -70,6 +70,7 @@ static int tsdbCommitToFile(SCommitH *pCommith, SDFileSet *pSet, int fid);
|
|||
static void tsdbResetCommitFile(SCommitH *pCommith);
|
||||
static int tsdbSetAndOpenCommitFile(SCommitH *pCommith, SDFileSet *pSet, int fid);
|
||||
static int tsdbCommitToTable(SCommitH *pCommith, int tid);
|
||||
static bool tsdbCommitIsSameFile(SCommitH *pCommith, int bidx);
|
||||
static int tsdbMoveBlkIdx(SCommitH *pCommith, SBlockIdx *pIdx);
|
||||
static int tsdbSetCommitTable(SCommitH *pCommith, STable *pTable);
|
||||
static int tsdbComparKeyBlock(const void *arg1, const void *arg2);
|
||||
|
@ -215,9 +216,9 @@ void tsdbGetRtnSnap(STsdb *pRepo, SRtn *pRtn) {
|
|||
TSKEY minKey, midKey, maxKey, now;
|
||||
|
||||
now = taosGetTimestamp(pCfg->precision);
|
||||
minKey = now - pCfg->keep2 * tsTickPerDay[pCfg->precision];
|
||||
midKey = now - pCfg->keep1 * tsTickPerDay[pCfg->precision];
|
||||
maxKey = now - pCfg->keep0 * tsTickPerDay[pCfg->precision];
|
||||
minKey = now - pCfg->keep2 * tsTickPerMin[pCfg->precision];
|
||||
midKey = now - pCfg->keep1 * tsTickPerMin[pCfg->precision];
|
||||
maxKey = now - pCfg->keep0 * tsTickPerMin[pCfg->precision];
|
||||
|
||||
pRtn->minKey = minKey;
|
||||
pRtn->minFid = (int)(TSDB_KEY_FID(minKey, pCfg->days, pCfg->precision));
|
||||
|
@ -382,6 +383,7 @@ static int tsdbCommitToFile(SCommitH *pCommith, SDFileSet *pSet, int fid) {
|
|||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
if (pIter && pIter->pTable && (!pIdx || (pIter->pTable->uid <= pIdx->uid))) {
|
||||
if (tsdbCommitToTable(pCommith, mIter) < 0) {
|
||||
tsdbCloseCommitFile(pCommith, true);
|
||||
|
@ -394,6 +396,9 @@ static int tsdbCommitToFile(SCommitH *pCommith, SDFileSet *pSet, int fid) {
|
|||
++fIter;
|
||||
}
|
||||
++mIter;
|
||||
} else if (pIter && !pIter->pTable) {
|
||||
// When table already dropped during commit, pIter is not NULL but pIter->pTable is NULL.
|
||||
++mIter; // skip the table and do nothing
|
||||
} else if (pIdx) {
|
||||
if (tsdbMoveBlkIdx(pCommith, pIdx) < 0) {
|
||||
tsdbCloseCommitFile(pCommith, true);
|
||||
|
@ -439,6 +444,7 @@ static int tsdbCreateCommitIters(SCommitH *pCommith) {
|
|||
SCommitIter *pCommitIter;
|
||||
SSkipListNode *pNode;
|
||||
STbData *pTbData;
|
||||
STSchema *pTSchema = NULL;
|
||||
|
||||
pCommith->niters = SL_SIZE(pMem->pSlIdx);
|
||||
pCommith->iters = (SCommitIter *)taosMemoryCalloc(pCommith->niters, sizeof(SCommitIter));
|
||||
|
@ -459,13 +465,17 @@ static int tsdbCreateCommitIters(SCommitH *pCommith) {
|
|||
pTbData = (STbData *)pNode->pData;
|
||||
|
||||
pCommitIter = pCommith->iters + i;
|
||||
pCommitIter->pIter = tSkipListCreateIter(pTbData->pData);
|
||||
tSkipListIterNext(pCommitIter->pIter);
|
||||
pTSchema = metaGetTbTSchema(REPO_META(pRepo), pTbData->uid, 0); // TODO: schema version
|
||||
|
||||
pCommitIter->pTable = (STable *)taosMemoryMalloc(sizeof(STable));
|
||||
pCommitIter->pTable->uid = pTbData->uid;
|
||||
pCommitIter->pTable->tid = pTbData->uid;
|
||||
pCommitIter->pTable->pSchema = metaGetTbTSchema(REPO_META(pRepo), pTbData->uid, 0);
|
||||
if (pTSchema) {
|
||||
pCommitIter->pIter = tSkipListCreateIter(pTbData->pData);
|
||||
tSkipListIterNext(pCommitIter->pIter);
|
||||
|
||||
pCommitIter->pTable = (STable *)taosMemoryMalloc(sizeof(STable));
|
||||
pCommitIter->pTable->uid = pTbData->uid;
|
||||
pCommitIter->pTable->tid = pTbData->uid;
|
||||
pCommitIter->pTable->pSchema = pTSchema; // metaGetTbTSchema(REPO_META(pRepo), pTbData->uid, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -476,8 +486,10 @@ static void tsdbDestroyCommitIters(SCommitH *pCommith) {
|
|||
|
||||
for (int i = 1; i < pCommith->niters; i++) {
|
||||
tSkipListDestroyIter(pCommith->iters[i].pIter);
|
||||
tdFreeSchema(pCommith->iters[i].pTable->pSchema);
|
||||
taosMemoryFree(pCommith->iters[i].pTable);
|
||||
if (pCommith->iters[i].pTable) {
|
||||
tdFreeSchema(pCommith->iters[i].pTable->pSchema);
|
||||
taosMemoryFreeClear(pCommith->iters[i].pTable);
|
||||
}
|
||||
}
|
||||
|
||||
taosMemoryFree(pCommith->iters);
|
||||
|
@ -880,9 +892,11 @@ static int tsdbCommitToTable(SCommitH *pCommith, int tid) {
|
|||
}
|
||||
|
||||
static int tsdbMoveBlkIdx(SCommitH *pCommith, SBlockIdx *pIdx) {
|
||||
SReadH *pReadh = &pCommith->readh;
|
||||
int nBlocks = pIdx->numOfBlocks;
|
||||
int bidx = 0;
|
||||
SReadH *pReadh = &pCommith->readh;
|
||||
STsdb *pTsdb = TSDB_READ_REPO(pReadh);
|
||||
STSchema *pTSchema = NULL;
|
||||
int nBlocks = pIdx->numOfBlocks;
|
||||
int bidx = 0;
|
||||
|
||||
tsdbResetCommitTable(pCommith);
|
||||
|
||||
|
@ -892,24 +906,42 @@ static int tsdbMoveBlkIdx(SCommitH *pCommith, SBlockIdx *pIdx) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
STable table = {.tid = pIdx->uid, .uid = pIdx->uid, .pSchema = NULL};
|
||||
pCommith->pTable = &table;
|
||||
|
||||
while (bidx < nBlocks) {
|
||||
if (!pTSchema && !tsdbCommitIsSameFile(pCommith, bidx)) {
|
||||
// Set commit table
|
||||
pTSchema = metaGetTbTSchema(REPO_META(pTsdb), pIdx->uid, 0); // TODO: schema version
|
||||
if (!pTSchema) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
table.pSchema = pTSchema;
|
||||
if (tsdbSetCommitTable(pCommith, &table) < 0) {
|
||||
taosMemoryFreeClear(pTSchema);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (tsdbMoveBlock(pCommith, bidx) < 0) {
|
||||
tsdbError("vgId:%d failed to move block into file %s since %s", TSDB_COMMIT_REPO_ID(pCommith),
|
||||
TSDB_FILE_FULL_NAME(TSDB_COMMIT_HEAD_FILE(pCommith)), tstrerror(terrno));
|
||||
taosMemoryFreeClear(pTSchema);
|
||||
return -1;
|
||||
}
|
||||
|
||||
++bidx;
|
||||
}
|
||||
|
||||
STable table = {.tid = pIdx->uid, .uid = pIdx->uid, .pSchema = NULL};
|
||||
TSDB_COMMIT_TABLE(pCommith) = &table;
|
||||
|
||||
if (tsdbWriteBlockInfo(pCommith) < 0) {
|
||||
tsdbError("vgId:%d failed to write SBlockInfo part into file %s since %s", TSDB_COMMIT_REPO_ID(pCommith),
|
||||
TSDB_FILE_FULL_NAME(TSDB_COMMIT_HEAD_FILE(pCommith)), tstrerror(terrno));
|
||||
taosMemoryFreeClear(pTSchema);
|
||||
return -1;
|
||||
}
|
||||
|
||||
taosMemoryFreeClear(pTSchema);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1312,6 +1344,14 @@ static int tsdbMergeMemData(SCommitH *pCommith, SCommitIter *pIter, int bidx) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool tsdbCommitIsSameFile(SCommitH *pCommith, int bidx) {
|
||||
SBlock *pBlock = pCommith->readh.pBlkInfo->blocks + bidx;
|
||||
if (pBlock->last) {
|
||||
return pCommith->isLFileSame;
|
||||
}
|
||||
return pCommith->isDFileSame;
|
||||
}
|
||||
|
||||
static int tsdbMoveBlock(SCommitH *pCommith, int bidx) {
|
||||
SBlock *pBlock = pCommith->readh.pBlkInfo->blocks + bidx;
|
||||
SDFile *pDFile;
|
||||
|
|
|
@ -62,6 +62,16 @@ int tsdbMemTableCreate(STsdb *pTsdb, STsdbMemTable **ppMemTable) {
|
|||
void tsdbMemTableDestroy(STsdb *pTsdb, STsdbMemTable *pMemTable) {
|
||||
if (pMemTable) {
|
||||
taosHashCleanup(pMemTable->pHashIdx);
|
||||
SSkipListIterator *pIter = tSkipListCreateIter(pMemTable->pSlIdx);
|
||||
SSkipListNode *pNode = NULL;
|
||||
STbData *pTbData = NULL;
|
||||
for (;;) {
|
||||
if (!tSkipListIterNext(pIter)) break;
|
||||
pNode = tSkipListIterGet(pIter);
|
||||
pTbData = (STbData *)pNode->pData;
|
||||
tsdbFreeTbData(pTbData);
|
||||
}
|
||||
tSkipListDestroyIter(pIter);
|
||||
tSkipListDestroy(pMemTable->pSlIdx);
|
||||
taosMemoryFree(pMemTable);
|
||||
}
|
||||
|
@ -290,7 +300,7 @@ int tsdbLoadDataFromCache(STable *pTable, SSkipListIterator *pIter, TSKEY maxKey
|
|||
return 0;
|
||||
}
|
||||
|
||||
int tsdbInsertTableData(STsdb *pTsdb, SSubmitMsgIter *pMsgIter, SSubmitBlk *pBlock, int32_t *pAffectedRows) {
|
||||
int tsdbInsertTableData(STsdb *pTsdb, SSubmitMsgIter *pMsgIter, SSubmitBlk *pBlock, SSubmitBlkRsp *pRsp) {
|
||||
SSubmitBlkIter blkIter = {0};
|
||||
STsdbMemTable *pMemTable = pTsdb->mem;
|
||||
void *tptr;
|
||||
|
@ -300,6 +310,17 @@ int tsdbInsertTableData(STsdb *pTsdb, SSubmitMsgIter *pMsgIter, SSubmitBlk *pBlo
|
|||
TSKEY keyMax;
|
||||
SSubmitBlk *pBlkCopy;
|
||||
|
||||
// check if table exists
|
||||
SMetaReader mr = {0};
|
||||
SMetaEntry me = {0};
|
||||
metaReaderInit(&mr, pTsdb->pVnode->pMeta, 0);
|
||||
if (metaGetTableEntryByUid(&mr, pMsgIter->uid) < 0) {
|
||||
metaReaderClear(&mr);
|
||||
terrno = TSDB_CODE_PAR_TABLE_NOT_EXIST;
|
||||
return -1;
|
||||
}
|
||||
metaReaderClear(&mr);
|
||||
|
||||
// create container is nedd
|
||||
tptr = taosHashGet(pMemTable->pHashIdx, &(pMsgIter->uid), sizeof(pMsgIter->uid));
|
||||
if (tptr == NULL) {
|
||||
|
@ -344,7 +365,8 @@ int tsdbInsertTableData(STsdb *pTsdb, SSubmitMsgIter *pMsgIter, SSubmitBlk *pBlo
|
|||
if (pMemTable->keyMin > keyMin) pMemTable->keyMin = keyMin;
|
||||
if (pMemTable->keyMax < keyMax) pMemTable->keyMax = keyMax;
|
||||
|
||||
(*pAffectedRows) = pMsgIter->numOfRows;
|
||||
pRsp->numOfRows = pMsgIter->numOfRows;
|
||||
pRsp->affectedRows = pMsgIter->numOfRows;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ struct SMemTable {
|
|||
|
||||
struct SMemSkipListNode {
|
||||
int8_t level;
|
||||
SMemSkipListNode *forwards[];
|
||||
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[];
|
||||
SMemSkipListNode pHead[1]; // Windows does not allow 0
|
||||
};
|
||||
|
||||
struct SMemData {
|
||||
|
|
|
@ -323,7 +323,7 @@ static int64_t getEarliestValidTimestamp(STsdb* pTsdb) {
|
|||
STsdbKeepCfg* pCfg = REPO_KEEP_CFG(pTsdb);
|
||||
|
||||
int64_t now = taosGetTimestamp(pCfg->precision);
|
||||
return now - (tsTickPerDay[pCfg->precision] * pCfg->keep2) + 1; // needs to add one tick
|
||||
return now - (tsTickPerMin[pCfg->precision] * pCfg->keep2) + 1; // needs to add one tick
|
||||
}
|
||||
|
||||
static void setQueryTimewindow(STsdbReadHandle* pTsdbReadHandle, SQueryTableDataCond* pCond) {
|
||||
|
@ -1047,10 +1047,10 @@ static int32_t getFileIdFromKey(TSKEY key, int32_t daysPerFile, int32_t precisio
|
|||
}
|
||||
|
||||
if (key < 0) {
|
||||
key -= (daysPerFile * tsTickPerDay[precision]);
|
||||
key -= (daysPerFile * tsTickPerMin[precision]);
|
||||
}
|
||||
|
||||
int64_t fid = (int64_t)(key / (daysPerFile * tsTickPerDay[precision])); // set the starting fileId
|
||||
int64_t fid = (int64_t)(key / (daysPerFile * tsTickPerMin[precision])); // set the starting fileId
|
||||
if (fid < 0L && llabs(fid) > INT32_MAX) { // data value overflow for INT32
|
||||
fid = INT32_MIN;
|
||||
}
|
||||
|
@ -3870,6 +3870,7 @@ int32_t tsdbQuerySTableByTagCond(void* pMeta, uint64_t uid, TSKEY skey, const ch
|
|||
|
||||
if (metaGetTableEntryByUid(&mr, uid) < 0) {
|
||||
tsdbError("%p failed to get stable, uid:%" PRIu64 ", TID:0x%" PRIx64 " QID:0x%" PRIx64, pMeta, uid, taskId, reqId);
|
||||
metaReaderClear(&mr);
|
||||
terrno = TSDB_CODE_PAR_TABLE_NOT_EXIST;
|
||||
goto _error;
|
||||
} else {
|
||||
|
@ -3880,6 +3881,7 @@ int32_t tsdbQuerySTableByTagCond(void* pMeta, uint64_t uid, TSKEY skey, const ch
|
|||
tsdbError("%p query normal tag not allowed, uid:%" PRIu64 ", TID:0x%" PRIx64 " QID:0x%" PRIx64, pMeta, uid, taskId,
|
||||
reqId);
|
||||
terrno = TSDB_CODE_OPS_NOT_SUPPORT; // basically, this error is caused by invalid sql issued by client
|
||||
metaReaderClear(&mr);
|
||||
goto _error;
|
||||
}
|
||||
|
||||
|
|
|
@ -1017,7 +1017,7 @@ static int32_t tsdbGetTSmaDays(STsdb *pTsdb, int64_t interval, int32_t storageLe
|
|||
int32_t daysPerFile = pCfg->days;
|
||||
|
||||
if (storageLevel == SMA_STORAGE_LEVEL_TSDB) {
|
||||
int32_t days = SMA_STORAGE_TSDB_TIMES * (interval / tsTickPerDay[pCfg->precision]);
|
||||
int32_t days = SMA_STORAGE_TSDB_TIMES * (interval / tsTickPerMin[pCfg->precision]);
|
||||
daysPerFile = days > SMA_STORAGE_TSDB_DAYS ? days : SMA_STORAGE_TSDB_DAYS;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,9 +36,10 @@ int tsdbInsertData(STsdb *pTsdb, int64_t version, SSubmitReq *pMsg, SSubmitRsp *
|
|||
// loop to insert
|
||||
tInitSubmitMsgIter(pMsg, &msgIter);
|
||||
while (true) {
|
||||
SSubmitBlkRsp r = {0};
|
||||
tGetSubmitMsgNext(&msgIter, &pBlock);
|
||||
if (pBlock == NULL) break;
|
||||
if (tsdbInsertTableData(pTsdb, &msgIter, pBlock, &affectedrows) < 0) {
|
||||
if (tsdbInsertTableData(pTsdb, &msgIter, pBlock, &r) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -46,8 +47,8 @@ int tsdbInsertData(STsdb *pTsdb, int64_t version, SSubmitReq *pMsg, SSubmitRsp *
|
|||
}
|
||||
|
||||
if (pRsp != NULL) {
|
||||
pRsp->affectedRows = affectedrows;
|
||||
pRsp->numOfRows = numOfRows;
|
||||
// pRsp->affectedRows = affectedrows;
|
||||
// pRsp->numOfRows = numOfRows;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -62,8 +63,8 @@ static int tsdbScanAndConvertSubmitMsg(STsdb *pTsdb, SSubmitReq *pMsg) {
|
|||
STSRow *row = NULL;
|
||||
STsdbKeepCfg *pCfg = REPO_KEEP_CFG(pTsdb);
|
||||
TSKEY now = taosGetTimestamp(pCfg->precision);
|
||||
TSKEY minKey = now - tsTickPerDay[pCfg->precision] * pCfg->keep2;
|
||||
TSKEY maxKey = now + tsTickPerDay[pCfg->precision] * pCfg->days;
|
||||
TSKEY minKey = now - tsTickPerMin[pCfg->precision] * pCfg->keep2;
|
||||
TSKEY maxKey = now + tsTickPerMin[pCfg->precision] * pCfg->days;
|
||||
|
||||
terrno = TSDB_CODE_SUCCESS;
|
||||
// pMsg->length = htonl(pMsg->length);
|
||||
|
|
|
@ -119,7 +119,7 @@ _exit:
|
|||
taosMemoryFree(metaRsp.pSchemas);
|
||||
metaReaderClear(&mer2);
|
||||
metaReaderClear(&mer1);
|
||||
return code;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t vnodeGetLoad(SVnode *pVnode, SVnodeLoad *pLoad) {
|
||||
|
|
|
@ -392,7 +392,7 @@ static int vnodeProcessCreateTbReq(SVnode *pVnode, int64_t version, void *pReq,
|
|||
tEncoderClear(&encoder);
|
||||
|
||||
_exit:
|
||||
taosArrayClear(rsp.pArray);
|
||||
taosArrayDestroy(rsp.pArray);
|
||||
tDecoderClear(&decoder);
|
||||
tEncoderClear(&encoder);
|
||||
return rcode;
|
||||
|
@ -454,6 +454,7 @@ static int vnodeProcessDropTbReq(SVnode *pVnode, int64_t version, void *pReq, in
|
|||
SVDropTbBatchReq req = {0};
|
||||
SVDropTbBatchRsp rsp = {0};
|
||||
SDecoder decoder = {0};
|
||||
SEncoder encoder = {0};
|
||||
int ret;
|
||||
|
||||
pRsp->msgType = TDMT_VND_DROP_TABLE_RSP;
|
||||
|
@ -471,7 +472,7 @@ static int vnodeProcessDropTbReq(SVnode *pVnode, int64_t version, void *pReq, in
|
|||
}
|
||||
|
||||
// process req
|
||||
rsp.pArray = taosArrayInit(sizeof(SVDropTbRsp), req.nReqs);
|
||||
rsp.pArray = taosArrayInit(req.nReqs, sizeof(SVDropTbRsp));
|
||||
for (int iReq = 0; iReq < req.nReqs; iReq++) {
|
||||
SVDropTbReq *pDropTbReq = req.pReqs + iReq;
|
||||
SVDropTbRsp dropTbRsp = {0};
|
||||
|
@ -493,59 +494,75 @@ static int vnodeProcessDropTbReq(SVnode *pVnode, int64_t version, void *pReq, in
|
|||
|
||||
_exit:
|
||||
tDecoderClear(&decoder);
|
||||
// encode rsp (TODO)
|
||||
tEncodeSize(tEncodeSVDropTbBatchRsp, &rsp, pRsp->contLen, ret);
|
||||
pRsp->pCont = rpcMallocCont(pRsp->contLen);
|
||||
tEncoderInit(&encoder, pRsp->pCont, pRsp->contLen);
|
||||
tEncodeSVDropTbBatchRsp(&encoder, &rsp);
|
||||
tEncoderClear(&encoder);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vnodeDebugPrintSubmitMsg(SVnode *pVnode, SSubmitReq *pMsg, const char* tags) {
|
||||
static int vnodeDebugPrintSingleSubmitMsg(SMeta *pMeta, SSubmitBlk *pBlock, SSubmitMsgIter *msgIter, const char *tags) {
|
||||
SSubmitBlkIter blkIter = {0};
|
||||
STSchema *pSchema = NULL;
|
||||
tb_uid_t suid = 0;
|
||||
STSRow *row = NULL;
|
||||
|
||||
tInitSubmitBlkIter(msgIter, pBlock, &blkIter);
|
||||
if (blkIter.row == NULL) return 0;
|
||||
if (!pSchema || (suid != msgIter->suid)) {
|
||||
if (pSchema) {
|
||||
taosMemoryFreeClear(pSchema);
|
||||
}
|
||||
pSchema = metaGetTbTSchema(pMeta, msgIter->suid, 0); // TODO: use the real schema
|
||||
if (pSchema) {
|
||||
suid = msgIter->suid;
|
||||
}
|
||||
}
|
||||
if (!pSchema) {
|
||||
printf("%s:%d no valid schema\n", tags, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
char __tags[128] = {0};
|
||||
snprintf(__tags, 128, "%s: uid %" PRIi64 " ", tags, msgIter->uid);
|
||||
while ((row = tGetSubmitBlkNext(&blkIter))) {
|
||||
tdSRowPrint(row, pSchema, __tags);
|
||||
}
|
||||
|
||||
taosMemoryFreeClear(pSchema);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int vnodeDebugPrintSubmitMsg(SVnode *pVnode, SSubmitReq *pMsg, const char *tags) {
|
||||
ASSERT(pMsg != NULL);
|
||||
SSubmitMsgIter msgIter = {0};
|
||||
SMeta *pMeta = pVnode->pMeta;
|
||||
SSubmitBlk *pBlock = NULL;
|
||||
SSubmitBlkIter blkIter = {0};
|
||||
STSRow *row = NULL;
|
||||
STSchema *pSchema = NULL;
|
||||
tb_uid_t suid = 0;
|
||||
|
||||
if (tInitSubmitMsgIter(pMsg, &msgIter) < 0) return -1;
|
||||
while (true) {
|
||||
if (tGetSubmitMsgNext(&msgIter, &pBlock) < 0) return -1;
|
||||
if (pBlock == NULL) break;
|
||||
tInitSubmitBlkIter(&msgIter, pBlock, &blkIter);
|
||||
if (blkIter.row == NULL) continue;
|
||||
if (!pSchema || (suid != msgIter.suid)) {
|
||||
if (pSchema) {
|
||||
taosMemoryFreeClear(pSchema);
|
||||
}
|
||||
pSchema = metaGetTbTSchema(pMeta, msgIter.suid, 0); // TODO: use the real schema
|
||||
if(pSchema) {
|
||||
suid = msgIter.suid;
|
||||
}
|
||||
}
|
||||
if(!pSchema) {
|
||||
printf("%s:%d no valid schema\n", tags, __LINE__);
|
||||
continue;
|
||||
}
|
||||
char __tags[128] = {0};
|
||||
snprintf(__tags, 128, "%s: uid %" PRIi64 " ", tags, msgIter.uid);
|
||||
while ((row = tGetSubmitBlkNext(&blkIter))) {
|
||||
tdSRowPrint(row, pSchema, __tags);
|
||||
}
|
||||
}
|
||||
|
||||
taosMemoryFreeClear(pSchema);
|
||||
vnodeDebugPrintSingleSubmitMsg(pMeta, pBlock, &msgIter, tags);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vnodeProcessSubmitReq(SVnode *pVnode, int64_t version, void *pReq, int32_t len, SRpcMsg *pRsp) {
|
||||
SSubmitReq *pSubmitReq = (SSubmitReq *)pReq;
|
||||
SSubmitRsp submitRsp = {0};
|
||||
SSubmitMsgIter msgIter = {0};
|
||||
SSubmitBlk *pBlock;
|
||||
SSubmitRsp rsp = {0};
|
||||
SVCreateTbReq createTbReq = {0};
|
||||
SDecoder decoder = {0};
|
||||
int32_t nRows;
|
||||
int32_t tsize, ret;
|
||||
SEncoder encoder = {0};
|
||||
terrno = TSDB_CODE_SUCCESS;
|
||||
|
||||
pRsp->code = 0;
|
||||
|
||||
|
@ -559,12 +576,22 @@ static int vnodeProcessSubmitReq(SVnode *pVnode, int64_t version, void *pReq, in
|
|||
goto _exit;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
submitRsp.pArray = taosArrayInit(pSubmitReq->numOfBlocks, sizeof(SSubmitBlkRsp));
|
||||
if (!submitRsp.pArray) {
|
||||
pRsp->code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
for (int i = 0;;) {
|
||||
tGetSubmitMsgNext(&msgIter, &pBlock);
|
||||
if (pBlock == NULL) break;
|
||||
|
||||
SSubmitBlkRsp submitBlkRsp = {0};
|
||||
|
||||
// create table for auto create table mode
|
||||
if (msgIter.schemaLen > 0) {
|
||||
submitBlkRsp.hashMeta = 1;
|
||||
|
||||
tDecoderInit(&decoder, pBlock->data, msgIter.schemaLen);
|
||||
if (tDecodeSVCreateTbReq(&decoder, &createTbReq) < 0) {
|
||||
pRsp->code = TSDB_CODE_INVALID_MSG;
|
||||
|
@ -574,12 +601,16 @@ static int vnodeProcessSubmitReq(SVnode *pVnode, int64_t version, void *pReq, in
|
|||
|
||||
if (metaCreateTable(pVnode->pMeta, version, &createTbReq) < 0) {
|
||||
if (terrno != TSDB_CODE_TDB_TABLE_ALREADY_EXIST) {
|
||||
pRsp->code = terrno;
|
||||
submitBlkRsp.code = terrno;
|
||||
tDecoderClear(&decoder);
|
||||
goto _exit;
|
||||
}
|
||||
}
|
||||
|
||||
submitBlkRsp.uid = createTbReq.uid;
|
||||
submitBlkRsp.tblFName = taosMemoryMalloc(strlen(pVnode->config.dbname) + strlen(createTbReq.name) + 2);
|
||||
sprintf(submitBlkRsp.tblFName, "%s.%s", pVnode->config.dbname, createTbReq.name);
|
||||
|
||||
msgIter.uid = createTbReq.uid;
|
||||
if (createTbReq.type == TSDB_CHILD_TABLE) {
|
||||
msgIter.suid = createTbReq.ctb.suid;
|
||||
|
@ -587,25 +618,39 @@ static int vnodeProcessSubmitReq(SVnode *pVnode, int64_t version, void *pReq, in
|
|||
msgIter.suid = 0;
|
||||
}
|
||||
|
||||
vnodeDebugPrintSingleSubmitMsg(pVnode->pMeta, pBlock, &msgIter, "real uid");
|
||||
tDecoderClear(&decoder);
|
||||
}
|
||||
|
||||
if (tsdbInsertTableData(pVnode->pTsdb, &msgIter, pBlock, &nRows) < 0) {
|
||||
pRsp->code = terrno;
|
||||
goto _exit;
|
||||
if (tsdbInsertTableData(pVnode->pTsdb, &msgIter, pBlock, &submitBlkRsp) < 0) {
|
||||
submitBlkRsp.code = terrno;
|
||||
}
|
||||
|
||||
rsp.affectedRows += nRows;
|
||||
|
||||
submitRsp.numOfRows += submitBlkRsp.numOfRows;
|
||||
submitRsp.affectedRows += submitBlkRsp.affectedRows;
|
||||
taosArrayPush(submitRsp.pArray, &submitBlkRsp);
|
||||
}
|
||||
|
||||
_exit:
|
||||
// encode the response (TODO)
|
||||
pRsp->pCont = rpcMallocCont(sizeof(SSubmitRsp));
|
||||
memcpy(pRsp->pCont, &rsp, sizeof(rsp));
|
||||
pRsp->contLen = sizeof(SSubmitRsp);
|
||||
tEncodeSize(tEncodeSSubmitRsp, &submitRsp, tsize, ret);
|
||||
pRsp->pCont = rpcMallocCont(tsize);
|
||||
pRsp->contLen = tsize;
|
||||
tEncoderInit(&encoder, pRsp->pCont, tsize);
|
||||
tEncodeSSubmitRsp(&encoder, &submitRsp);
|
||||
tEncoderClear(&encoder);
|
||||
|
||||
tsdbTriggerRSma(pVnode->pTsdb, pReq, STREAM_DATA_TYPE_SUBMIT_BLOCK);
|
||||
for (int32_t i = 0; i < taosArrayGetSize(submitRsp.pArray); i++) {
|
||||
taosMemoryFree(((SSubmitBlkRsp *)taosArrayGet(submitRsp.pArray, i))[0].tblFName);
|
||||
}
|
||||
|
||||
taosArrayDestroy(submitRsp.pArray);
|
||||
|
||||
// TODO: the partial success scenario and the error case
|
||||
// TODO: refactor
|
||||
if ((terrno == TSDB_CODE_SUCCESS || terrno == TSDB_CODE_TDB_TABLE_ALREADY_EXIST) &&
|
||||
(pRsp->code == TSDB_CODE_SUCCESS)) {
|
||||
tsdbTriggerRSma(pVnode->pTsdb, pReq, STREAM_DATA_TYPE_SUBMIT_BLOCK);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -72,6 +72,7 @@ int32_t vnodeSendMsg(void *rpcHandle, const SEpSet *pEpSet, SRpcMsg *pMsg) {
|
|||
int32_t ret = 0;
|
||||
SMsgCb *pMsgCb = rpcHandle;
|
||||
if (pMsgCb->queueFps[SYNC_QUEUE] != NULL) {
|
||||
pMsg->noResp = 1;
|
||||
tmsgSendReq(rpcHandle, pEpSet, pMsg);
|
||||
} else {
|
||||
vError("vnodeSendMsg queue is NULL, SYNC_QUEUE:%d", SYNC_QUEUE);
|
||||
|
|
|
@ -616,10 +616,10 @@ int32_t appendDownstream(SOperatorInfo* p, SOperatorInfo** pDownstream, int32_t
|
|||
int32_t initAggInfo(SOptrBasicInfo* pBasicInfo, SAggSupporter* pAggSup, SExprInfo* pExprInfo, int32_t numOfCols,
|
||||
SSDataBlock* pResultBlock, size_t keyBufSize, const char* pkey);
|
||||
void initResultSizeInfo(SOperatorInfo* pOperator, int32_t numOfRows);
|
||||
void doBuildResultDatablock(SOptrBasicInfo *pbInfo, SGroupResInfo* pGroupResInfo, SExprInfo* pExprInfo, SDiskbasedBuf* pBuf);
|
||||
void doBuildResultDatablock(SExecTaskInfo *taskInfo, SOptrBasicInfo *pbInfo, SGroupResInfo* pGroupResInfo, SExprInfo* pExprInfo, SDiskbasedBuf* pBuf);
|
||||
|
||||
void finalizeMultiTupleQueryResult(int32_t numOfOutput, SDiskbasedBuf* pBuf, SResultRowInfo* pResultRowInfo, int32_t* rowCellInfoOffset);
|
||||
void doApplyFunctions(SqlFunctionCtx* pCtx, STimeWindow* pWin, SColumnInfoData* pTimeWindowData, int32_t offset,
|
||||
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);
|
||||
int32_t setGroupResultOutputBuf(SOptrBasicInfo* binfo, int32_t numOfCols, char* pData, int16_t type, int16_t bytes,
|
||||
int32_t groupId, SDiskbasedBuf* pBuf, SExecTaskInfo* pTaskInfo, SAggSupporter* pAggSup);
|
||||
|
|
|
@ -13,11 +13,23 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "filter.h"
|
||||
#ifndef _INDEX_OPERATOR_H
|
||||
#define _INDEX_OPERATOR_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "nodes.h"
|
||||
#include "tglobal.h"
|
||||
|
||||
typedef enum { SFLT_NOT_INDEX, SFLT_COARSE_INDEX, SFLT_ACCURATE_INDEX } SIdxFltStatus;
|
||||
|
||||
SIdxFltStatus idxGetFltStatus(SNode *pFilterNode);
|
||||
// construct tag filter operator later
|
||||
int32_t doFilterTag(const SNode *pFilterNode, SArray *resutl);
|
||||
int32_t doFilterTag(const SNode *pFilterNode, SArray *result);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*INDEX_OPERATOR_*/
|
||||
|
|
|
@ -155,7 +155,7 @@ SOperatorFpSet createOperatorFpSet(__optr_open_fn_t openFn, __optr_fn_t nextFn,
|
|||
|
||||
void operatorDummyCloseFn(void* param, int32_t numOfCols) {}
|
||||
|
||||
static int32_t doCopyToSDataBlock(SSDataBlock* pBlock, SExprInfo* pExprInfo, SDiskbasedBuf* pBuf,
|
||||
static int32_t doCopyToSDataBlock(SExecTaskInfo *taskInfo, SSDataBlock* pBlock, SExprInfo* pExprInfo, SDiskbasedBuf* pBuf,
|
||||
SGroupResInfo* pGroupResInfo, int32_t orderType, int32_t* rowCellOffset,
|
||||
SqlFunctionCtx* pCtx);
|
||||
|
||||
|
@ -579,7 +579,7 @@ void initExecTimeWindowInfo(SColumnInfoData* pColData, STimeWindow* pQueryWindow
|
|||
colDataAppendInt64(pColData, 4, &pQueryWindow->ekey);
|
||||
}
|
||||
|
||||
void doApplyFunctions(SqlFunctionCtx* pCtx, STimeWindow* pWin, SColumnInfoData* pTimeWindowData, int32_t offset,
|
||||
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) {
|
||||
pCtx[k].startTs = pWin->skey;
|
||||
|
@ -618,9 +618,14 @@ void doApplyFunctions(SqlFunctionCtx* pCtx, STimeWindow* pWin, SColumnInfoData*
|
|||
pEntryInfo->numOfRes = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
if (functionNeedToExecute(&pCtx[k]) && pCtx[k].fpSet.process != NULL) {
|
||||
pCtx[k].fpSet.process(&pCtx[k]);
|
||||
code = pCtx[k].fpSet.process(&pCtx[k]);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
qError("%s apply functions error, code: %s", GET_TASKID(taskInfo), tstrerror(code));
|
||||
taskInfo->code = code;
|
||||
longjmp(taskInfo->env, code);
|
||||
}
|
||||
}
|
||||
|
||||
// restore it
|
||||
|
@ -806,7 +811,13 @@ static void doAggregateImpl(SOperatorInfo* pOperator, TSKEY startTs, SqlFunction
|
|||
// this can be set during create the struct
|
||||
// todo add a dummy funtion to avoid process check
|
||||
if (pCtx[k].fpSet.process != NULL) {
|
||||
pCtx[k].fpSet.process(&pCtx[k]);
|
||||
int32_t code = pCtx[k].fpSet.process(&pCtx[k]);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
qError("%s call aggregate function error happens, code : %s",
|
||||
GET_TASKID(pOperator->pTaskInfo), tstrerror(code));
|
||||
pOperator->pTaskInfo->code = code;
|
||||
longjmp(pOperator->pTaskInfo->env, code);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2176,7 +2187,7 @@ void setExecutionContext(int32_t numOfOutput, uint64_t groupId, SExecTaskInfo* p
|
|||
* @param pQInfo
|
||||
* @param result
|
||||
*/
|
||||
int32_t doCopyToSDataBlock(SSDataBlock* pBlock, SExprInfo* pExprInfo, SDiskbasedBuf* pBuf, SGroupResInfo* pGroupResInfo,
|
||||
int32_t doCopyToSDataBlock(SExecTaskInfo* taskInfo, SSDataBlock* pBlock, SExprInfo* pExprInfo, SDiskbasedBuf* pBuf, SGroupResInfo* pGroupResInfo,
|
||||
int32_t orderType, int32_t* rowCellOffset, SqlFunctionCtx* pCtx) {
|
||||
int32_t numOfRows = getNumOfTotalRes(pGroupResInfo);
|
||||
int32_t numOfResult = pBlock->info.rows; // there are already exists result rows
|
||||
|
@ -2215,8 +2226,14 @@ int32_t doCopyToSDataBlock(SSDataBlock* pBlock, SExprInfo* pExprInfo, SDiskbased
|
|||
int32_t slotId = pExprInfo[j].base.resSchema.slotId;
|
||||
|
||||
pCtx[j].resultInfo = getResultCell(pRow, j, rowCellOffset);
|
||||
if (pCtx[j].fpSet.process) {
|
||||
pCtx[j].fpSet.finalize(&pCtx[j], pBlock);
|
||||
if (pCtx[j].fpSet.finalize) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
code = pCtx[j].fpSet.finalize(&pCtx[j], pBlock);
|
||||
if (TAOS_FAILED(code)) {
|
||||
qError("%s build result data block error, code %s", GET_TASKID(taskInfo), tstrerror(code));
|
||||
taskInfo->code = code;
|
||||
longjmp(taskInfo->env, code);
|
||||
}
|
||||
} else if (strcmp(pCtx[j].pExpr->pExpr->_function.functionName, "_select_value") == 0) {
|
||||
// do nothing, todo refactor
|
||||
} else {
|
||||
|
@ -2243,7 +2260,7 @@ int32_t doCopyToSDataBlock(SSDataBlock* pBlock, SExprInfo* pExprInfo, SDiskbased
|
|||
return 0;
|
||||
}
|
||||
|
||||
void doBuildResultDatablock(SOptrBasicInfo* pbInfo, SGroupResInfo* pGroupResInfo, SExprInfo* pExprInfo,
|
||||
void doBuildResultDatablock(SExecTaskInfo *taskInfo, SOptrBasicInfo* pbInfo, SGroupResInfo* pGroupResInfo, SExprInfo* pExprInfo,
|
||||
SDiskbasedBuf* pBuf) {
|
||||
assert(pGroupResInfo->currentGroup <= pGroupResInfo->totalGroup);
|
||||
|
||||
|
@ -2257,7 +2274,7 @@ void doBuildResultDatablock(SOptrBasicInfo* pbInfo, SGroupResInfo* pGroupResInfo
|
|||
}
|
||||
|
||||
int32_t orderType = TSDB_ORDER_ASC;
|
||||
doCopyToSDataBlock(pBlock, pExprInfo, pBuf, pGroupResInfo, orderType, rowCellOffset, pCtx);
|
||||
doCopyToSDataBlock(taskInfo, pBlock, pExprInfo, pBuf, pGroupResInfo, orderType, rowCellOffset, pCtx);
|
||||
|
||||
// add condition (pBlock->info.rows >= 1) just to runtime happy
|
||||
blockDataUpdateTsWindow(pBlock);
|
||||
|
@ -3749,7 +3766,7 @@ static SSDataBlock* getAggregateResult(SOperatorInfo* pOperator) {
|
|||
}
|
||||
|
||||
blockDataEnsureCapacity(pInfo->pRes, pOperator->resultInfo.capacity);
|
||||
doBuildResultDatablock(pInfo, &pAggInfo->groupResInfo, pOperator->pExpr, pAggInfo->aggSup.pResultBuf);
|
||||
doBuildResultDatablock(pTaskInfo, pInfo, &pAggInfo->groupResInfo, pOperator->pExpr, pAggInfo->aggSup.pResultBuf);
|
||||
if (pInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pAggInfo->groupResInfo)) {
|
||||
doSetOperatorCompleted(pOperator);
|
||||
}
|
||||
|
|
|
@ -234,7 +234,7 @@ static void doHashGroupbyAgg(SOperatorInfo* pOperator, SSDataBlock* pBlock) {
|
|||
}
|
||||
|
||||
int32_t rowIndex = j - num;
|
||||
doApplyFunctions(pCtx, &w, NULL, rowIndex, num, NULL, pBlock->info.rows, pOperator->numOfExprs, TSDB_ORDER_ASC);
|
||||
doApplyFunctions(pTaskInfo, pCtx, &w, NULL, rowIndex, num, NULL, pBlock->info.rows, pOperator->numOfExprs, TSDB_ORDER_ASC);
|
||||
|
||||
// assign the group keys or user input constant values if required
|
||||
doAssignGroupKeys(pCtx, pOperator->numOfExprs, pBlock->info.rows, rowIndex);
|
||||
|
@ -252,7 +252,7 @@ static void doHashGroupbyAgg(SOperatorInfo* pOperator, SSDataBlock* pBlock) {
|
|||
}
|
||||
|
||||
int32_t rowIndex = pBlock->info.rows - num;
|
||||
doApplyFunctions(pCtx, &w, NULL, rowIndex, num, NULL, pBlock->info.rows, pOperator->numOfExprs, TSDB_ORDER_ASC);
|
||||
doApplyFunctions(pTaskInfo, pCtx, &w, NULL, rowIndex, num, NULL, pBlock->info.rows, pOperator->numOfExprs, TSDB_ORDER_ASC);
|
||||
doAssignGroupKeys(pCtx, pOperator->numOfExprs, pBlock->info.rows, rowIndex);
|
||||
}
|
||||
}
|
||||
|
@ -268,7 +268,7 @@ static SSDataBlock* hashGroupbyAggregate(SOperatorInfo* pOperator) {
|
|||
SSDataBlock* pRes = pInfo->binfo.pRes;
|
||||
|
||||
if (pOperator->status == OP_RES_TO_RETURN) {
|
||||
doBuildResultDatablock(&pInfo->binfo, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf);
|
||||
doBuildResultDatablock(pTaskInfo, &pInfo->binfo, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf);
|
||||
if (pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) {
|
||||
pOperator->status = OP_EXEC_DONE;
|
||||
}
|
||||
|
@ -317,7 +317,7 @@ static SSDataBlock* hashGroupbyAggregate(SOperatorInfo* pOperator) {
|
|||
initGroupedResultInfo(&pInfo->groupResInfo, pInfo->aggSup.pResultRowHashTable, false);
|
||||
|
||||
while(1) {
|
||||
doBuildResultDatablock(&pInfo->binfo, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf);
|
||||
doBuildResultDatablock(pTaskInfo, &pInfo->binfo, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf);
|
||||
doFilter(pInfo->pCondition, pRes);
|
||||
|
||||
bool hasRemain = hasRemainDataInCurrentGroup(&pInfo->groupResInfo);
|
||||
|
|
|
@ -21,7 +21,9 @@
|
|||
|
||||
typedef struct SIFCtx {
|
||||
int32_t code;
|
||||
SHashObj *pRes; /* element is SScalarParam */
|
||||
SHashObj *pRes; /* element is SScalarParam */
|
||||
bool noExec; // true: just iterate condition tree, and add hint to executor plan
|
||||
// SIdxFltStatus st;
|
||||
} SIFCtx;
|
||||
|
||||
#define SIF_ERR_RET(c) \
|
||||
|
@ -55,11 +57,12 @@ typedef struct SIFParam {
|
|||
SArray *result;
|
||||
char * condValue;
|
||||
|
||||
uint8_t colValType;
|
||||
col_id_t colId;
|
||||
int64_t suid; // add later
|
||||
char dbName[TSDB_DB_NAME_LEN];
|
||||
char colName[TSDB_COL_NAME_LEN];
|
||||
SIdxFltStatus status;
|
||||
uint8_t colValType;
|
||||
col_id_t colId;
|
||||
int64_t suid; // add later
|
||||
char dbName[TSDB_DB_NAME_LEN];
|
||||
char colName[TSDB_COL_NAME_LEN];
|
||||
} SIFParam;
|
||||
|
||||
static int32_t sifGetFuncFromSql(EOperatorType src, EIndexQueryType *dst) {
|
||||
|
@ -82,6 +85,9 @@ static int32_t sifGetFuncFromSql(EOperatorType src, EIndexQueryType *dst) {
|
|||
}
|
||||
|
||||
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;
|
||||
|
@ -114,6 +120,24 @@ static int32_t sifValidateColumn(SColumnNode *cn) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static SIdxFltStatus sifMergeCond(ELogicConditionType type, SIdxFltStatus ls, SIdxFltStatus rs) {
|
||||
// enh rule later
|
||||
if (type == LOGIC_COND_TYPE_AND) {
|
||||
if (ls == SFLT_NOT_INDEX || rs == SFLT_NOT_INDEX) {
|
||||
if (ls == SFLT_NOT_INDEX)
|
||||
return rs;
|
||||
else
|
||||
return ls;
|
||||
}
|
||||
return SFLT_COARSE_INDEX;
|
||||
} else if (type == LOGIC_COND_TYPE_OR) {
|
||||
return SFLT_COARSE_INDEX;
|
||||
} else if (type == LOGIC_COND_TYPE_NOT) {
|
||||
return SFLT_NOT_INDEX;
|
||||
}
|
||||
return SFLT_NOT_INDEX;
|
||||
}
|
||||
|
||||
static int32_t sifGetValueFromNode(SNode *node, char **value) {
|
||||
// covert data From snode;
|
||||
SValueNode *vn = (SValueNode *)node;
|
||||
|
@ -257,11 +281,11 @@ static int32_t sifDoIndex(SIFParam *left, SIFParam *right, int8_t operType, SIFP
|
|||
if (tm == NULL) {
|
||||
return TSDB_CODE_QRY_OUT_OF_MEMORY;
|
||||
}
|
||||
SIndexMultiTermQuery *mtm = indexMultiTermQueryCreate(MUST);
|
||||
|
||||
EIndexQueryType qtype = 0;
|
||||
SIF_ERR_RET(sifGetFuncFromSql(operType, &qtype));
|
||||
|
||||
SIndexMultiTermQuery *mtm = indexMultiTermQueryCreate(MUST);
|
||||
indexMultiTermQueryAdd(mtm, tm, qtype);
|
||||
int ret = indexSearch(NULL, mtm, output->result);
|
||||
indexMultiTermQueryDestroy(mtm);
|
||||
|
@ -319,6 +343,7 @@ static int32_t sifNotMatchFunc(SIFParam *left, SIFParam *right, SIFParam *output
|
|||
int id = OP_TYPE_NMATCH;
|
||||
return sifDoIndex(left, right, id, output);
|
||||
}
|
||||
|
||||
static int32_t sifDefaultFunc(SIFParam *left, SIFParam *right, SIFParam *output) {
|
||||
// add more except
|
||||
return TSDB_CODE_QRY_INVALID_INPUT;
|
||||
|
@ -352,9 +377,9 @@ static sif_func_t sifGetOperFn(int32_t funcId) {
|
|||
case OP_TYPE_NMATCH:
|
||||
return sifNotMatchFunc;
|
||||
default:
|
||||
return sifDefaultFunc;
|
||||
return sifNullFunc;
|
||||
}
|
||||
return sifDefaultFunc;
|
||||
return sifNullFunc;
|
||||
}
|
||||
static int32_t sifExecOper(SOperatorNode *node, SIFCtx *ctx, SIFParam *output) {
|
||||
int32_t code = 0;
|
||||
|
@ -367,6 +392,11 @@ static int32_t sifExecOper(SOperatorNode *node, SIFCtx *ctx, SIFParam *output) {
|
|||
SIF_ERR_RET(sifInitOperParams(¶ms, node, ctx));
|
||||
|
||||
sif_func_t operFn = sifGetOperFn(node->opType);
|
||||
if (ctx->noExec && operFn == NULL) {
|
||||
output->status = SFLT_NOT_INDEX;
|
||||
} else {
|
||||
output->status = SFLT_ACCURATE_INDEX;
|
||||
}
|
||||
|
||||
return operFn(¶ms[0], nParam > 1 ? ¶ms[1] : NULL, output);
|
||||
_return:
|
||||
|
@ -385,14 +415,20 @@ static int32_t sifExecLogic(SLogicConditionNode *node, SIFCtx *ctx, SIFParam *ou
|
|||
SIFParam *params = NULL;
|
||||
SIF_ERR_RET(sifInitParamList(¶ms, node->pParameterList, ctx));
|
||||
|
||||
for (int32_t m = 0; m < node->pParameterList->length; m++) {
|
||||
// add impl later
|
||||
if (node->condType == LOGIC_COND_TYPE_AND) {
|
||||
taosArrayAddAll(output->result, params[m].result);
|
||||
} else if (node->condType == LOGIC_COND_TYPE_OR) {
|
||||
taosArrayAddAll(output->result, params[m].result);
|
||||
} else if (node->condType == LOGIC_COND_TYPE_NOT) {
|
||||
taosArrayAddAll(output->result, params[m].result);
|
||||
if (ctx->noExec == false) {
|
||||
for (int32_t m = 0; m < node->pParameterList->length; m++) {
|
||||
// add impl later
|
||||
if (node->condType == LOGIC_COND_TYPE_AND) {
|
||||
taosArrayAddAll(output->result, params[m].result);
|
||||
} else if (node->condType == LOGIC_COND_TYPE_OR) {
|
||||
taosArrayAddAll(output->result, params[m].result);
|
||||
} else if (node->condType == LOGIC_COND_TYPE_NOT) {
|
||||
taosArrayAddAll(output->result, params[m].result);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int32_t m = 0; m < node->pParameterList->length; m++) {
|
||||
output->status = sifMergeCond(node->condType, output->status, params[m].status);
|
||||
}
|
||||
}
|
||||
_return:
|
||||
|
@ -486,7 +522,7 @@ static int32_t sifCalculate(SNode *pNode, SIFParam *pDst) {
|
|||
return TSDB_CODE_QRY_INVALID_INPUT;
|
||||
}
|
||||
int32_t code = 0;
|
||||
SIFCtx ctx = {.code = 0};
|
||||
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");
|
||||
|
@ -510,6 +546,36 @@ static int32_t sifCalculate(SNode *pNode, SIFParam *pDst) {
|
|||
SIF_RET(code);
|
||||
}
|
||||
|
||||
static int32_t sifGetFltHint(SNode *pNode, SIdxFltStatus *status) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
if (pNode == NULL) {
|
||||
return TSDB_CODE_QRY_INVALID_INPUT;
|
||||
}
|
||||
|
||||
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");
|
||||
return TSDB_CODE_QRY_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
nodesWalkExprPostOrder(pNode, sifCalcWalker, &ctx);
|
||||
|
||||
SIF_ERR_RET(ctx.code);
|
||||
|
||||
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));
|
||||
SIF_ERR_RET(TSDB_CODE_QRY_APP_ERROR);
|
||||
}
|
||||
*status = res->status;
|
||||
|
||||
sifFreeParam(res);
|
||||
taosHashRemove(ctx.pRes, (void *)&pNode, POINTER_BYTES);
|
||||
|
||||
SIF_RET(code);
|
||||
}
|
||||
|
||||
int32_t doFilterTag(const SNode *pFilterNode, SArray *result) {
|
||||
if (pFilterNode == NULL) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -517,7 +583,7 @@ int32_t doFilterTag(const SNode *pFilterNode, SArray *result) {
|
|||
|
||||
SFilterInfo *filter = NULL;
|
||||
// todo move to the initialization function
|
||||
SIF_ERR_RET(filterInitFromNode((SNode *)pFilterNode, &filter, 0));
|
||||
// SIF_ERR_RET(filterInitFromNode((SNode *)pFilterNode, &filter, 0));
|
||||
|
||||
SIFParam param = {0};
|
||||
SIF_ERR_RET(sifCalculate((SNode *)pFilterNode, ¶m));
|
||||
|
@ -528,10 +594,14 @@ int32_t doFilterTag(const SNode *pFilterNode, SArray *result) {
|
|||
}
|
||||
|
||||
SIdxFltStatus idxGetFltStatus(SNode *pFilterNode) {
|
||||
SIdxFltStatus st = SFLT_NOT_INDEX;
|
||||
if (pFilterNode == NULL) {
|
||||
return SFLT_NOT_INDEX;
|
||||
}
|
||||
// SFilterInfo *filter = NULL;
|
||||
// todo move to the initialization function
|
||||
// SIF_ERR_RET(filterInitFromNode((SNode *)pFilterNode, &filter, 0));
|
||||
|
||||
// impl later
|
||||
return SFLT_ACCURATE_INDEX;
|
||||
SIF_ERR_RET(sifGetFltHint((SNode *)pFilterNode, &st));
|
||||
return st;
|
||||
}
|
||||
|
|
|
@ -703,7 +703,7 @@ static SArray* hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pRe
|
|||
pInfo->order, false);
|
||||
|
||||
updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &win, true);
|
||||
doApplyFunctions(pInfo->binfo.pCtx, &win, &pInfo->twAggSup.timeWindowData, startPos, forwardStep, tsCols,
|
||||
doApplyFunctions(pTaskInfo, pInfo->binfo.pCtx, &win, &pInfo->twAggSup.timeWindowData, startPos, forwardStep, tsCols,
|
||||
pSDataBlock->info.rows, numOfOutput, TSDB_ORDER_ASC);
|
||||
|
||||
STimeWindow nextWin = win;
|
||||
|
@ -740,7 +740,7 @@ static SArray* hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pRe
|
|||
pInfo->order, false);
|
||||
|
||||
updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &nextWin, true);
|
||||
doApplyFunctions(pInfo->binfo.pCtx, &nextWin, &pInfo->twAggSup.timeWindowData, startPos, forwardStep, tsCols,
|
||||
doApplyFunctions(pTaskInfo, pInfo->binfo.pCtx, &nextWin, &pInfo->twAggSup.timeWindowData, startPos, forwardStep, tsCols,
|
||||
pSDataBlock->info.rows, numOfOutput, TSDB_ORDER_ASC);
|
||||
}
|
||||
|
||||
|
@ -855,7 +855,7 @@ static void doStateWindowAggImpl(SOperatorInfo* pOperator, SStateWindowOperatorI
|
|||
}
|
||||
|
||||
updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &window, false);
|
||||
doApplyFunctions(pInfo->binfo.pCtx, &window, &pInfo->twAggSup.timeWindowData, pRowSup->startRowIndex,
|
||||
doApplyFunctions(pTaskInfo, pInfo->binfo.pCtx, &window, &pInfo->twAggSup.timeWindowData, pRowSup->startRowIndex,
|
||||
pRowSup->numOfRows, NULL, pBlock->info.rows, numOfOutput, TSDB_ORDER_ASC);
|
||||
|
||||
// here we start a new session window
|
||||
|
@ -874,7 +874,7 @@ static void doStateWindowAggImpl(SOperatorInfo* pOperator, SStateWindowOperatorI
|
|||
}
|
||||
|
||||
updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pRowSup->win, false);
|
||||
doApplyFunctions(pInfo->binfo.pCtx, &pRowSup->win, &pInfo->twAggSup.timeWindowData, pRowSup->startRowIndex,
|
||||
doApplyFunctions(pTaskInfo, pInfo->binfo.pCtx, &pRowSup->win, &pInfo->twAggSup.timeWindowData, pRowSup->startRowIndex,
|
||||
pRowSup->numOfRows, NULL, pBlock->info.rows, numOfOutput, TSDB_ORDER_ASC);
|
||||
}
|
||||
|
||||
|
@ -888,7 +888,7 @@ static SSDataBlock* doStateWindowAgg(SOperatorInfo* pOperator) {
|
|||
SOptrBasicInfo* pBInfo = &pInfo->binfo;
|
||||
|
||||
if (pOperator->status == OP_RES_TO_RETURN) {
|
||||
doBuildResultDatablock(pBInfo, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf);
|
||||
doBuildResultDatablock(pTaskInfo, pBInfo, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf);
|
||||
if (pBInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) {
|
||||
doSetOperatorCompleted(pOperator);
|
||||
return NULL;
|
||||
|
@ -921,7 +921,7 @@ static SSDataBlock* doStateWindowAgg(SOperatorInfo* pOperator) {
|
|||
|
||||
initGroupedResultInfo(&pInfo->groupResInfo, pInfo->aggSup.pResultRowHashTable, true);
|
||||
blockDataEnsureCapacity(pBInfo->pRes, pOperator->resultInfo.capacity);
|
||||
doBuildResultDatablock(pBInfo, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf);
|
||||
doBuildResultDatablock(pTaskInfo, pBInfo, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf);
|
||||
if (pBInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) {
|
||||
doSetOperatorCompleted(pOperator);
|
||||
}
|
||||
|
@ -948,7 +948,7 @@ static SSDataBlock* doBuildIntervalResult(SOperatorInfo* pOperator) {
|
|||
}
|
||||
|
||||
blockDataEnsureCapacity(pBlock, pOperator->resultInfo.capacity);
|
||||
doBuildResultDatablock(&pInfo->binfo, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf);
|
||||
doBuildResultDatablock(pTaskInfo, &pInfo->binfo, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf);
|
||||
|
||||
if (pBlock->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) {
|
||||
doSetOperatorCompleted(pOperator);
|
||||
|
@ -998,7 +998,7 @@ static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) {
|
|||
}
|
||||
|
||||
if (pOperator->status == OP_RES_TO_RETURN) {
|
||||
doBuildResultDatablock(&pInfo->binfo, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf);
|
||||
doBuildResultDatablock(pOperator->pTaskInfo, &pInfo->binfo, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf);
|
||||
if (pInfo->binfo.pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) {
|
||||
pOperator->status = OP_EXEC_DONE;
|
||||
}
|
||||
|
@ -1035,7 +1035,7 @@ static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) {
|
|||
|
||||
initMultiResInfoFromArrayList(&pInfo->groupResInfo, pUpdated);
|
||||
blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity);
|
||||
doBuildResultDatablock(&pInfo->binfo, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf);
|
||||
doBuildResultDatablock(pOperator->pTaskInfo, &pInfo->binfo, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf);
|
||||
|
||||
// TODO: remove for stream
|
||||
/*ASSERT(pInfo->binfo.pRes->info.rows > 0);*/
|
||||
|
@ -1233,7 +1233,7 @@ static void doSessionWindowAggImpl(SOperatorInfo* pOperator, SSessionAggOperator
|
|||
|
||||
// pInfo->numOfRows data belong to the current session window
|
||||
updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &window, false);
|
||||
doApplyFunctions(pInfo->binfo.pCtx, &window, &pInfo->twAggSup.timeWindowData, pRowSup->startRowIndex,
|
||||
doApplyFunctions(pTaskInfo, pInfo->binfo.pCtx, &window, &pInfo->twAggSup.timeWindowData, pRowSup->startRowIndex,
|
||||
pRowSup->numOfRows, NULL, pBlock->info.rows, numOfOutput, TSDB_ORDER_ASC);
|
||||
|
||||
// here we start a new session window
|
||||
|
@ -1252,7 +1252,7 @@ static void doSessionWindowAggImpl(SOperatorInfo* pOperator, SSessionAggOperator
|
|||
}
|
||||
|
||||
updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pRowSup->win, false);
|
||||
doApplyFunctions(pInfo->binfo.pCtx, &pRowSup->win, &pInfo->twAggSup.timeWindowData, pRowSup->startRowIndex,
|
||||
doApplyFunctions(pTaskInfo, pInfo->binfo.pCtx, &pRowSup->win, &pInfo->twAggSup.timeWindowData, pRowSup->startRowIndex,
|
||||
pRowSup->numOfRows, NULL, pBlock->info.rows, numOfOutput, TSDB_ORDER_ASC);
|
||||
}
|
||||
|
||||
|
@ -1265,7 +1265,7 @@ static SSDataBlock* doSessionWindowAgg(SOperatorInfo* pOperator) {
|
|||
SOptrBasicInfo* pBInfo = &pInfo->binfo;
|
||||
|
||||
if (pOperator->status == OP_RES_TO_RETURN) {
|
||||
doBuildResultDatablock(pBInfo, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf);
|
||||
doBuildResultDatablock(pOperator->pTaskInfo, pBInfo, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf);
|
||||
if (pBInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) {
|
||||
doSetOperatorCompleted(pOperator);
|
||||
return NULL;
|
||||
|
@ -1298,7 +1298,7 @@ static SSDataBlock* doSessionWindowAgg(SOperatorInfo* pOperator) {
|
|||
|
||||
initGroupedResultInfo(&pInfo->groupResInfo, pInfo->aggSup.pResultRowHashTable, true);
|
||||
blockDataEnsureCapacity(pBInfo->pRes, pOperator->resultInfo.capacity);
|
||||
doBuildResultDatablock(pBInfo, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf);
|
||||
doBuildResultDatablock(pOperator->pTaskInfo, pBInfo, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf);
|
||||
if (pBInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) {
|
||||
doSetOperatorCompleted(pOperator);
|
||||
}
|
||||
|
|
|
@ -948,10 +948,6 @@ TEST(testCase, build_executor_tree_Test) {
|
|||
code = qCreateExecTask(&handle, 2, 1, plan, (void**)&pTaskInfo, &sinkHandle, OPTR_EXEC_MODEL_BATCH);
|
||||
ASSERT_EQ(code, 0);
|
||||
}
|
||||
TEST(testCase, index_plan_test) {
|
||||
// add later
|
||||
EXPECT_EQ(0, 0);
|
||||
}
|
||||
#if 0
|
||||
|
||||
TEST(testCase, inMem_sort_Test) {
|
||||
|
|
|
@ -0,0 +1,253 @@
|
|||
/*
|
||||
* 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 <gtest/gtest.h>
|
||||
#include <tglobal.h>
|
||||
#include <tsort.h>
|
||||
#include <iostream>
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wwrite-strings"
|
||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||
#pragma GCC diagnostic ignored "-Wunused-variable"
|
||||
#pragma GCC diagnostic ignored "-Wsign-compare"
|
||||
|
||||
#include "executor.h"
|
||||
#include "executorimpl.h"
|
||||
#include "indexoperator.h"
|
||||
#include "os.h"
|
||||
|
||||
#include "stub.h"
|
||||
#include "taos.h"
|
||||
#include "tcompare.h"
|
||||
#include "tdatablock.h"
|
||||
#include "tdef.h"
|
||||
#include "trpc.h"
|
||||
#include "tvariant.h"
|
||||
|
||||
namespace {
|
||||
SColumnInfo createColumnInfo(int32_t colId, int32_t type, int32_t bytes) {
|
||||
SColumnInfo info = {0};
|
||||
info.colId = colId;
|
||||
info.type = type;
|
||||
info.bytes = bytes;
|
||||
return info;
|
||||
}
|
||||
|
||||
int64_t sifLeftV = 21, sifRightV = 10;
|
||||
double sifLeftVd = 21.0, sifRightVd = 10.0;
|
||||
|
||||
void sifFreeDataBlock(void *block) { blockDataDestroy(*(SSDataBlock **)block); }
|
||||
|
||||
void sifInitLogFile() {
|
||||
const char * defaultLogFileNamePrefix = "taoslog";
|
||||
const int32_t maxLogFileNum = 10;
|
||||
|
||||
tsAsyncLog = 0;
|
||||
qDebugFlag = 159;
|
||||
strcpy(tsLogDir, "/tmp/sif");
|
||||
taosRemoveDir(tsLogDir);
|
||||
taosMkDir(tsLogDir);
|
||||
|
||||
if (taosInitLog(defaultLogFileNamePrefix, maxLogFileNum) < 0) {
|
||||
printf("failed to open log file in directory:%s\n", tsLogDir);
|
||||
}
|
||||
}
|
||||
|
||||
void sifAppendReservedSlot(SArray *pBlockList, int16_t *dataBlockId, int16_t *slotId, bool newBlock, int32_t rows,
|
||||
SColumnInfo *colInfo) {
|
||||
if (newBlock) {
|
||||
SSDataBlock *res = (SSDataBlock *)taosMemoryCalloc(1, sizeof(SSDataBlock));
|
||||
res->info.numOfCols = 1;
|
||||
res->info.rows = rows;
|
||||
res->pDataBlock = taosArrayInit(1, sizeof(SColumnInfoData));
|
||||
SColumnInfoData idata = {0};
|
||||
idata.info = *colInfo;
|
||||
|
||||
taosArrayPush(res->pDataBlock, &idata);
|
||||
taosArrayPush(pBlockList, &res);
|
||||
|
||||
blockDataEnsureCapacity(res, rows);
|
||||
|
||||
*dataBlockId = taosArrayGetSize(pBlockList) - 1;
|
||||
res->info.blockId = *dataBlockId;
|
||||
*slotId = 0;
|
||||
} else {
|
||||
SSDataBlock *res = *(SSDataBlock **)taosArrayGetLast(pBlockList);
|
||||
res->info.numOfCols++;
|
||||
SColumnInfoData idata = {0};
|
||||
idata.info = *colInfo;
|
||||
|
||||
colInfoDataEnsureCapacity(&idata, 0, rows);
|
||||
|
||||
taosArrayPush(res->pDataBlock, &idata);
|
||||
|
||||
*dataBlockId = taosArrayGetSize(pBlockList) - 1;
|
||||
*slotId = taosArrayGetSize(res->pDataBlock) - 1;
|
||||
}
|
||||
}
|
||||
|
||||
void sifMakeValueNode(SNode **pNode, int32_t dataType, void *value) {
|
||||
SNode * node = (SNode *)nodesMakeNode(QUERY_NODE_VALUE);
|
||||
SValueNode *vnode = (SValueNode *)node;
|
||||
vnode->node.resType.type = dataType;
|
||||
|
||||
if (IS_VAR_DATA_TYPE(dataType)) {
|
||||
vnode->datum.p = (char *)taosMemoryMalloc(varDataTLen(value));
|
||||
varDataCopy(vnode->datum.p, value);
|
||||
vnode->node.resType.bytes = varDataTLen(value);
|
||||
} else {
|
||||
vnode->node.resType.bytes = tDataTypes[dataType].bytes;
|
||||
assignVal((char *)nodesGetValueFromNode(vnode), (const char *)value, 0, dataType);
|
||||
}
|
||||
|
||||
*pNode = (SNode *)vnode;
|
||||
}
|
||||
|
||||
void sifMakeColumnNode(SNode **pNode, const char *db, const char *colName, EColumnType colType, uint8_t colValType) {
|
||||
SNode * node = (SNode *)nodesMakeNode(QUERY_NODE_COLUMN);
|
||||
SColumnNode *rnode = (SColumnNode *)node;
|
||||
memcpy(rnode->dbName, db, strlen(db));
|
||||
memcpy(rnode->colName, colName, strlen(colName));
|
||||
|
||||
rnode->colType = colType;
|
||||
rnode->node.resType.type = colValType;
|
||||
|
||||
*pNode = (SNode *)rnode;
|
||||
}
|
||||
|
||||
void sifMakeOpNode(SNode **pNode, EOperatorType opType, int32_t resType, SNode *pLeft, SNode *pRight) {
|
||||
SNode * node = (SNode *)nodesMakeNode(QUERY_NODE_OPERATOR);
|
||||
SOperatorNode *onode = (SOperatorNode *)node;
|
||||
onode->node.resType.type = resType;
|
||||
onode->node.resType.bytes = tDataTypes[resType].bytes;
|
||||
|
||||
onode->opType = opType;
|
||||
onode->pLeft = pLeft;
|
||||
onode->pRight = pRight;
|
||||
|
||||
*pNode = (SNode *)onode;
|
||||
}
|
||||
|
||||
void sifMakeListNode(SNode **pNode, SNodeList *list, int32_t resType) {
|
||||
SNode * node = (SNode *)nodesMakeNode(QUERY_NODE_NODE_LIST);
|
||||
SNodeListNode *lnode = (SNodeListNode *)node;
|
||||
lnode->dataType.type = resType;
|
||||
lnode->pNodeList = list;
|
||||
|
||||
*pNode = (SNode *)lnode;
|
||||
}
|
||||
|
||||
void sifMakeLogicNode(SNode **pNode, ELogicConditionType opType, SNode **nodeList, int32_t nodeNum) {
|
||||
SNode * node = (SNode *)nodesMakeNode(QUERY_NODE_LOGIC_CONDITION);
|
||||
SLogicConditionNode *onode = (SLogicConditionNode *)node;
|
||||
onode->condType = opType;
|
||||
onode->node.resType.type = TSDB_DATA_TYPE_BOOL;
|
||||
onode->node.resType.bytes = sizeof(bool);
|
||||
|
||||
onode->pParameterList = nodesMakeList();
|
||||
for (int32_t i = 0; i < nodeNum; ++i) {
|
||||
nodesListAppend(onode->pParameterList, nodeList[i]);
|
||||
}
|
||||
|
||||
*pNode = (SNode *)onode;
|
||||
}
|
||||
|
||||
void sifMakeTargetNode(SNode **pNode, int16_t dataBlockId, int16_t slotId, SNode *snode) {
|
||||
SNode * node = (SNode *)nodesMakeNode(QUERY_NODE_TARGET);
|
||||
STargetNode *onode = (STargetNode *)node;
|
||||
onode->pExpr = snode;
|
||||
onode->dataBlockId = dataBlockId;
|
||||
onode->slotId = slotId;
|
||||
|
||||
*pNode = (SNode *)onode;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#if 1
|
||||
TEST(testCase, index_filter) {
|
||||
{
|
||||
SNode *pLeft = NULL, *pRight = NULL, *opNode = NULL, *res = NULL;
|
||||
sifMakeColumnNode(&pLeft, "test", "col", COLUMN_TYPE_TAG, TSDB_DATA_TYPE_INT);
|
||||
sifMakeValueNode(&pRight, TSDB_DATA_TYPE_INT, &sifRightV);
|
||||
sifMakeOpNode(&opNode, OP_TYPE_LOWER_THAN, TSDB_DATA_TYPE_INT, pLeft, pRight);
|
||||
SArray *result = taosArrayInit(4, sizeof(uint64_t));
|
||||
doFilterTag(opNode, result);
|
||||
EXPECT_EQ(1, taosArrayGetSize(result));
|
||||
taosArrayDestroy(result);
|
||||
nodesDestroyNode(res);
|
||||
}
|
||||
{
|
||||
SNode *pLeft = NULL, *pRight = NULL, *opNode = NULL, *res = NULL;
|
||||
sifMakeColumnNode(&pLeft, "test", "col", COLUMN_TYPE_TAG, TSDB_DATA_TYPE_INT);
|
||||
sifMakeValueNode(&pRight, TSDB_DATA_TYPE_INT, &sifRightV);
|
||||
sifMakeOpNode(&opNode, OP_TYPE_LOWER_THAN, TSDB_DATA_TYPE_DOUBLE, pLeft, pRight);
|
||||
|
||||
SArray *result = taosArrayInit(4, sizeof(uint64_t));
|
||||
doFilterTag(opNode, result);
|
||||
EXPECT_EQ(1, taosArrayGetSize(result));
|
||||
|
||||
taosArrayDestroy(result);
|
||||
nodesDestroyNode(res);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(testCase, index_filter_varify) {
|
||||
{
|
||||
SNode *pLeft = NULL, *pRight = NULL, *opNode = NULL, *res = NULL;
|
||||
sifMakeColumnNode(&pLeft, "test", "col", COLUMN_TYPE_TAG, TSDB_DATA_TYPE_INT);
|
||||
sifMakeValueNode(&pRight, TSDB_DATA_TYPE_INT, &sifRightV);
|
||||
sifMakeOpNode(&opNode, OP_TYPE_LOWER_THAN, TSDB_DATA_TYPE_INT, pLeft, pRight);
|
||||
nodesDestroyNode(res);
|
||||
|
||||
SIdxFltStatus st = idxGetFltStatus(opNode);
|
||||
EXPECT_EQ(st, SFLT_ACCURATE_INDEX);
|
||||
}
|
||||
{
|
||||
SNode *pLeft = NULL, *pRight = NULL, *opNode = NULL, *res = NULL;
|
||||
sifMakeColumnNode(&pLeft, "test", "col", COLUMN_TYPE_TAG, TSDB_DATA_TYPE_INT);
|
||||
sifMakeValueNode(&pRight, TSDB_DATA_TYPE_INT, &sifRightV);
|
||||
sifMakeOpNode(&opNode, OP_TYPE_LOWER_THAN, TSDB_DATA_TYPE_DOUBLE, pLeft, pRight);
|
||||
|
||||
SIdxFltStatus st = idxGetFltStatus(opNode);
|
||||
EXPECT_EQ(st, SFLT_COARSE_INDEX);
|
||||
nodesDestroyNode(res);
|
||||
}
|
||||
{
|
||||
SNode *pLeft = NULL, *pRight = NULL, *opNode = NULL, *res = NULL;
|
||||
sifMakeColumnNode(&pLeft, "test", "col", COLUMN_TYPE_TAG, TSDB_DATA_TYPE_INT);
|
||||
sifMakeValueNode(&pRight, TSDB_DATA_TYPE_INT, &sifRightV);
|
||||
sifMakeOpNode(&opNode, OP_TYPE_GREATER_THAN, TSDB_DATA_TYPE_INT, pLeft, pRight);
|
||||
nodesDestroyNode(res);
|
||||
|
||||
SIdxFltStatus st = idxGetFltStatus(opNode);
|
||||
EXPECT_EQ(st, SFLT_ACCURATE_INDEX);
|
||||
}
|
||||
{
|
||||
SNode *pLeft = NULL, *pRight = NULL, *opNode = NULL, *res = NULL;
|
||||
sifMakeColumnNode(&pLeft, "test", "col", COLUMN_TYPE_TAG, TSDB_DATA_TYPE_INT);
|
||||
sifMakeValueNode(&pRight, TSDB_DATA_TYPE_INT, &sifRightV);
|
||||
sifMakeOpNode(&opNode, OP_TYPE_GREATER_THAN, TSDB_DATA_TYPE_DOUBLE, pLeft, pRight);
|
||||
|
||||
SIdxFltStatus st = idxGetFltStatus(opNode);
|
||||
EXPECT_EQ(st, SFLT_COARSE_INDEX);
|
||||
nodesDestroyNode(res);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#pragma GCC diagnostic pop
|
|
@ -93,6 +93,10 @@ int32_t histogramFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock);
|
|||
bool getStateFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
|
||||
bool stateFunctionSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo);
|
||||
int32_t stateCountFunction(SqlFunctionCtx* pCtx);
|
||||
int32_t stateDurationFunction(SqlFunctionCtx* pCtx);
|
||||
|
||||
bool getCsumFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
|
||||
int32_t csumFunction(SqlFunctionCtx* pCtx);
|
||||
|
||||
bool getSelectivityFuncEnv(SFunctionNode* pFunc, SFuncExecEnv* pEnv);
|
||||
|
||||
|
|
|
@ -239,7 +239,7 @@ static int32_t translateLeastSQR(SFunctionNode* pFunc, char* pErrBuf, int32_t le
|
|||
}
|
||||
}
|
||||
|
||||
pFunc->node.resType = (SDataType) { .bytes = 64, .type = TSDB_DATA_TYPE_BINARY };
|
||||
pFunc->node.resType = (SDataType){.bytes = 64, .type = TSDB_DATA_TYPE_BINARY};
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -263,7 +263,7 @@ static int32_t translateHistogram(SFunctionNode* pFunc, char* pErrBuf, int32_t l
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t translateState(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||
static int32_t translateStateCount(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||
if (3 != LIST_LENGTH(pFunc->pParameterList)) {
|
||||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -283,6 +283,62 @@ static int32_t translateState(SFunctionNode* pFunc, char* pErrBuf, int32_t len)
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t translateStateDuration(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||
int32_t paraNum = LIST_LENGTH(pFunc->pParameterList);
|
||||
if (3 != paraNum && 4 != paraNum) {
|
||||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t colType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
if (!IS_NUMERIC_TYPE(colType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
if (((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type != TSDB_DATA_TYPE_BINARY ||
|
||||
(((SExprNode*)nodesListGetNode(pFunc->pParameterList, 2))->resType.type != TSDB_DATA_TYPE_BIGINT &&
|
||||
((SExprNode*)nodesListGetNode(pFunc->pParameterList, 2))->resType.type != TSDB_DATA_TYPE_DOUBLE)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
if (paraNum == 4 && ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 3))->resType.type != TSDB_DATA_TYPE_BIGINT) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
pFunc->node.resType = (SDataType) { .bytes = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes, .type = TSDB_DATA_TYPE_BIGINT };
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t translateCsum(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||
if (1 != LIST_LENGTH(pFunc->pParameterList)) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
SNode* pPara = nodesListGetNode(pFunc->pParameterList, 0);
|
||||
if (QUERY_NODE_COLUMN != nodeType(pPara)) {
|
||||
return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR,
|
||||
"The input parameter of CSUM function can only be column");
|
||||
}
|
||||
|
||||
uint8_t colType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t resType;
|
||||
if (!IS_NUMERIC_TYPE(colType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
} else {
|
||||
if (IS_SIGNED_NUMERIC_TYPE(colType)) {
|
||||
resType = TSDB_DATA_TYPE_BIGINT;
|
||||
} else if (IS_UNSIGNED_NUMERIC_TYPE(colType)) {
|
||||
resType = TSDB_DATA_TYPE_UBIGINT;
|
||||
} else if (IS_FLOAT_TYPE(colType)) {
|
||||
resType = TSDB_DATA_TYPE_DOUBLE;
|
||||
} else {
|
||||
ASSERT(0);
|
||||
}
|
||||
}
|
||||
|
||||
pFunc->node.resType = (SDataType) { .bytes = tDataTypes[resType].bytes, .type = resType};
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t translateLastRow(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||
// todo
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -701,12 +757,32 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.name = "state_count",
|
||||
.type = FUNCTION_TYPE_STATE_COUNT,
|
||||
.classification = FUNC_MGT_NONSTANDARD_SQL_FUNC,
|
||||
.translateFunc = translateState,
|
||||
.translateFunc = translateStateCount,
|
||||
.getEnvFunc = getStateFuncEnv,
|
||||
.initFunc = functionSetup,
|
||||
.processFunc = stateCountFunction,
|
||||
.finalizeFunc = NULL
|
||||
},
|
||||
{
|
||||
.name = "state_duration",
|
||||
.type = FUNCTION_TYPE_STATE_DURATION,
|
||||
.classification = FUNC_MGT_NONSTANDARD_SQL_FUNC | FUNC_MGT_TIMELINE_FUNC,
|
||||
.translateFunc = translateStateDuration,
|
||||
.getEnvFunc = getStateFuncEnv,
|
||||
.initFunc = functionSetup,
|
||||
.processFunc = stateDurationFunction,
|
||||
.finalizeFunc = NULL
|
||||
},
|
||||
{
|
||||
.name = "csum",
|
||||
.type = FUNCTION_TYPE_CSUM,
|
||||
.classification = FUNC_MGT_NONSTANDARD_SQL_FUNC | FUNC_MGT_TIMELINE_FUNC,
|
||||
.translateFunc = translateCsum,
|
||||
.getEnvFunc = getCsumFuncEnv,
|
||||
.initFunc = functionSetup,
|
||||
.processFunc = csumFunction,
|
||||
.finalizeFunc = NULL
|
||||
},
|
||||
{
|
||||
.name = "abs",
|
||||
.type = FUNCTION_TYPE_ABS,
|
||||
|
@ -1007,26 +1083,6 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.sprocessFunc = timezoneFunction,
|
||||
.finalizeFunc = NULL
|
||||
},
|
||||
{
|
||||
.name = "_rowts",
|
||||
.type = FUNCTION_TYPE_ROWTS,
|
||||
.classification = FUNC_MGT_PSEUDO_COLUMN_FUNC,
|
||||
.translateFunc = translateTimePseudoColumn,
|
||||
.getEnvFunc = getTimePseudoFuncEnv,
|
||||
.initFunc = NULL,
|
||||
.sprocessFunc = NULL,
|
||||
.finalizeFunc = NULL
|
||||
},
|
||||
{
|
||||
.name = "_c0",
|
||||
.type = FUNCTION_TYPE_ROWTS,
|
||||
.classification = FUNC_MGT_PSEUDO_COLUMN_FUNC,
|
||||
.translateFunc = translateTimePseudoColumn,
|
||||
.getEnvFunc = getTimePseudoFuncEnv,
|
||||
.initFunc = NULL,
|
||||
.sprocessFunc = NULL,
|
||||
.finalizeFunc = NULL
|
||||
},
|
||||
{
|
||||
.name = "tbname",
|
||||
.type = FUNCTION_TYPE_TBNAME,
|
||||
|
|
|
@ -125,7 +125,10 @@ typedef enum {
|
|||
} EHistoBinType;
|
||||
|
||||
typedef struct SStateInfo {
|
||||
int64_t count;
|
||||
union {
|
||||
int64_t count;
|
||||
int64_t durationStart;
|
||||
};
|
||||
} SStateInfo;
|
||||
|
||||
typedef enum {
|
||||
|
@ -2815,7 +2818,6 @@ int32_t stateCountFunction(SqlFunctionCtx* pCtx) {
|
|||
SInputColumnInfoData* pInput = &pCtx->input;
|
||||
|
||||
SColumnInfoData* pInputCol = pInput->pData[0];
|
||||
SColumnInfoData* pTsOutput = pCtx->pTsOutput;
|
||||
|
||||
int32_t numOfElems = 0;
|
||||
SColumnInfoData* pOutput = (SColumnInfoData*)pCtx->pOutput;
|
||||
|
@ -2844,3 +2846,106 @@ int32_t stateCountFunction(SqlFunctionCtx* pCtx) {
|
|||
|
||||
return numOfElems;
|
||||
}
|
||||
|
||||
int32_t stateDurationFunction(SqlFunctionCtx* pCtx) {
|
||||
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
|
||||
SStateInfo* pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||
|
||||
SInputColumnInfoData* pInput = &pCtx->input;
|
||||
TSKEY* tsList = (int64_t*)pInput->pPTS->pData;
|
||||
|
||||
SColumnInfoData* pInputCol = pInput->pData[0];
|
||||
|
||||
int32_t numOfElems = 0;
|
||||
SColumnInfoData* pOutput = (SColumnInfoData*)pCtx->pOutput;
|
||||
|
||||
//TODO: process timeUnit for different db precisions
|
||||
int32_t timeUnit = 1000;
|
||||
if (pCtx->numOfParams == 5) { //TODO: param number incorrect
|
||||
timeUnit = pCtx->param[3].param.i;
|
||||
}
|
||||
|
||||
int8_t op = getStateOpType(varDataVal(pCtx->param[1].param.pz));
|
||||
if (STATE_OPER_INVALID == op) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (int32_t i = pInput->startRowIndex; i < pInput->numOfRows + pInput->startRowIndex; i += 1) {
|
||||
numOfElems++;
|
||||
if (colDataIsNull_f(pInputCol->nullbitmap, i)) {
|
||||
colDataAppendNULL(pOutput, i);
|
||||
continue;
|
||||
}
|
||||
|
||||
bool ret = checkStateOp(op, pInputCol, i, pCtx->param[2].param);
|
||||
int64_t output = -1;
|
||||
if (ret) {
|
||||
if (pInfo->durationStart == 0) {
|
||||
output = 0;
|
||||
pInfo->durationStart = tsList[i];
|
||||
} else {
|
||||
output = (tsList[i] - pInfo->durationStart) / timeUnit;
|
||||
}
|
||||
} else {
|
||||
pInfo->durationStart = 0;
|
||||
}
|
||||
colDataAppend(pOutput, i, (char *)&output, false);
|
||||
}
|
||||
|
||||
return numOfElems;
|
||||
}
|
||||
|
||||
bool getCsumFuncEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv) {
|
||||
pEnv->calcMemSize = sizeof(SSumRes);
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t csumFunction(SqlFunctionCtx* pCtx) {
|
||||
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
|
||||
SSumRes* pSumRes = GET_ROWCELL_INTERBUF(pResInfo);
|
||||
|
||||
SInputColumnInfoData* pInput = &pCtx->input;
|
||||
TSKEY* tsList = (int64_t*)pInput->pPTS->pData;
|
||||
|
||||
SColumnInfoData* pInputCol = pInput->pData[0];
|
||||
SColumnInfoData* pTsOutput = pCtx->pTsOutput;
|
||||
SColumnInfoData* pOutput = (SColumnInfoData*)pCtx->pOutput;
|
||||
|
||||
int32_t numOfElems = 0;
|
||||
int32_t type = pInputCol->info.type;
|
||||
int32_t startOffset = pCtx->offset;
|
||||
for (int32_t i = pInput->startRowIndex; i < pInput->numOfRows + pInput->startRowIndex; i += 1) {
|
||||
int32_t pos = startOffset + numOfElems;
|
||||
if (colDataIsNull_f(pInputCol->nullbitmap, i)) {
|
||||
//colDataAppendNULL(pOutput, i);
|
||||
continue;
|
||||
}
|
||||
|
||||
char* data = colDataGetData(pInputCol, i);
|
||||
if (IS_SIGNED_NUMERIC_TYPE(type)) {
|
||||
int64_t v;
|
||||
GET_TYPED_DATA(v, int64_t, type, data);
|
||||
pSumRes->isum += v;
|
||||
colDataAppend(pOutput, pos, (char *)&pSumRes->isum, false);
|
||||
} else if (IS_UNSIGNED_NUMERIC_TYPE(type)) {
|
||||
uint64_t v;
|
||||
GET_TYPED_DATA(v, uint64_t, type, data);
|
||||
pSumRes->usum += v;
|
||||
colDataAppend(pOutput, pos, (char *)&pSumRes->usum, false);
|
||||
} else if (IS_FLOAT_TYPE(type)) {
|
||||
double v;
|
||||
GET_TYPED_DATA(v, double, type, data);
|
||||
pSumRes->dsum += v;
|
||||
colDataAppend(pOutput, pos, (char *)&pSumRes->dsum, false);
|
||||
}
|
||||
|
||||
//TODO: remove this after pTsOutput is handled
|
||||
if (pTsOutput != NULL) {
|
||||
colDataAppendInt64(pTsOutput, pos, &tsList[i]);
|
||||
}
|
||||
|
||||
numOfElems++;
|
||||
}
|
||||
|
||||
return numOfElems;
|
||||
}
|
||||
|
|
|
@ -695,6 +695,7 @@ int32_t convertDataBlockToUdfDataBlock(SSDataBlock *block, SUdfDataBlock *udfBlo
|
|||
udfCol->colMeta.scale = col->info.scale;
|
||||
udfCol->colMeta.precision = col->info.precision;
|
||||
udfCol->colData.numOfRows = udfBlock->numOfRows;
|
||||
udfCol->hasNull = col->hasNull;
|
||||
if (IS_VAR_DATA_TYPE(udfCol->colMeta.type)) {
|
||||
udfCol->colData.varLenCol.varOffsetsLen = sizeof(int32_t) * udfBlock->numOfRows;
|
||||
udfCol->colData.varLenCol.varOffsets = taosMemoryMalloc(udfCol->colData.varLenCol.varOffsetsLen);
|
||||
|
@ -731,6 +732,7 @@ int32_t convertUdfColumnToDataBlock(SUdfColumn *udfCol, SSDataBlock *block) {
|
|||
col->info.bytes = meta->bytes;
|
||||
col->info.scale = meta->scale;
|
||||
col->info.type = meta->type;
|
||||
col->hasNull = udfCol->hasNull;
|
||||
SUdfColumnData *data = &udfCol->colData;
|
||||
|
||||
if (!IS_VAR_DATA_TYPE(meta->type)) {
|
||||
|
@ -929,7 +931,7 @@ void udfcUvHandleError(SClientUvConn *conn) {
|
|||
while (!QUEUE_EMPTY(&conn->taskQueue)) {
|
||||
QUEUE* h = QUEUE_HEAD(&conn->taskQueue);
|
||||
SClientUvTaskNode *task = QUEUE_DATA(h, SClientUvTaskNode, connTaskQueue);
|
||||
task->errCode = UDFC_CODE_PIPE_READ_ERR;
|
||||
task->errCode = TSDB_CODE_UDF_PIPE_READ_ERR;
|
||||
QUEUE_REMOVE(&task->connTaskQueue);
|
||||
QUEUE_REMOVE(&task->procTaskQueue);
|
||||
uv_sem_post(&task->taskSem);
|
||||
|
@ -1117,7 +1119,7 @@ void cleanUpUvTasks(SUdfdProxy *udfc) {
|
|||
QUEUE_REMOVE(h);
|
||||
SClientUvTaskNode *task = QUEUE_DATA(h, SClientUvTaskNode, recvTaskQueue);
|
||||
if (udfc->gUdfcState == UDFC_STATE_STOPPING) {
|
||||
task->errCode = UDFC_CODE_STOPPING;
|
||||
task->errCode = TSDB_CODE_UDF_STOPPING;
|
||||
}
|
||||
uv_sem_post(&task->taskSem);
|
||||
}
|
||||
|
@ -1127,7 +1129,7 @@ void cleanUpUvTasks(SUdfdProxy *udfc) {
|
|||
QUEUE_REMOVE(h);
|
||||
SClientUvTaskNode *task = QUEUE_DATA(h, SClientUvTaskNode, procTaskQueue);
|
||||
if (udfc->gUdfcState == UDFC_STATE_STOPPING) {
|
||||
task->errCode = UDFC_CODE_STOPPING;
|
||||
task->errCode = TSDB_CODE_UDF_STOPPING;
|
||||
}
|
||||
uv_sem_post(&task->taskSem);
|
||||
}
|
||||
|
@ -1211,7 +1213,7 @@ int32_t udfcRunUdfUvTask(SClientUdfTask *task, int8_t uvTaskType) {
|
|||
int32_t setupUdf(char udfName[], UdfcFuncHandle *funcHandle) {
|
||||
fnInfo("udfc setup udf. udfName: %s", udfName);
|
||||
if (gUdfdProxy.gUdfcState != UDFC_STATE_READY) {
|
||||
return UDFC_CODE_INVALID_STATE;
|
||||
return TSDB_CODE_UDF_INVALID_STATE;
|
||||
}
|
||||
SClientUdfTask *task = taosMemoryCalloc(1,sizeof(SClientUdfTask));
|
||||
task->errCode = 0;
|
||||
|
@ -1225,7 +1227,7 @@ int32_t setupUdf(char udfName[], UdfcFuncHandle *funcHandle) {
|
|||
int32_t errCode = udfcRunUdfUvTask(task, UV_TASK_CONNECT);
|
||||
if (errCode != 0) {
|
||||
fnError("failed to connect to pipe. udfName: %s, pipe: %s", udfName, (&gUdfdProxy)->udfdPipeName);
|
||||
return UDFC_CODE_CONNECT_PIPE_ERR;
|
||||
return TSDB_CODE_UDF_PIPE_CONNECT_ERR;
|
||||
}
|
||||
|
||||
udfcRunUdfUvTask(task, UV_TASK_REQ_RSP);
|
||||
|
@ -1252,7 +1254,7 @@ int32_t callUdf(UdfcFuncHandle handle, int8_t callType, SSDataBlock *input, SUdf
|
|||
SClientUdfUvSession *session = (SClientUdfUvSession *) handle;
|
||||
if (session->udfUvPipe == NULL) {
|
||||
fnError("No pipe to udfd");
|
||||
return UDFC_CODE_NO_PIPE;
|
||||
return TSDB_CODE_UDF_PIPE_NO_PIPE;
|
||||
}
|
||||
SClientUdfTask *task = taosMemoryCalloc(1, sizeof(SClientUdfTask));
|
||||
task->errCode = 0;
|
||||
|
@ -1372,7 +1374,7 @@ int32_t teardownUdf(UdfcFuncHandle handle) {
|
|||
SClientUdfUvSession *session = (SClientUdfUvSession *) handle;
|
||||
if (session->udfUvPipe == NULL) {
|
||||
fnError("pipe to udfd does not exist");
|
||||
return UDFC_CODE_NO_PIPE;
|
||||
return TSDB_CODE_UDF_PIPE_NO_PIPE;
|
||||
}
|
||||
|
||||
SClientUdfTask *task = taosMemoryCalloc(1, sizeof(SClientUdfTask));
|
||||
|
@ -1495,7 +1497,7 @@ int32_t udfAggProcess(struct SqlFunctionCtx *pCtx) {
|
|||
taosArrayDestroy(tempBlock.pDataBlock);
|
||||
|
||||
taosMemoryFree(newState.buf);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
return udfCode;
|
||||
}
|
||||
|
||||
int32_t udfAggFinalize(struct SqlFunctionCtx *pCtx, SSDataBlock* pBlock) {
|
||||
|
|
|
@ -102,7 +102,7 @@ int32_t udfdLoadUdf(char *udfName, SUdf *udf) {
|
|||
int err = uv_dlopen(udf->path, &udf->lib);
|
||||
if (err != 0) {
|
||||
fnError("can not load library %s. error: %s", udf->path, uv_strerror(err));
|
||||
return UDFC_CODE_LOAD_UDF_FAILURE;
|
||||
return TSDB_CODE_UDF_LOAD_UDF_FAILURE;
|
||||
}
|
||||
|
||||
char initFuncName[TSDB_FUNC_NAME_LEN+5] = {0};
|
||||
|
@ -140,6 +140,182 @@ int32_t udfdLoadUdf(char *udfName, SUdf *udf) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void udfdProcessSetupRequest(SUvUdfWork* uvUdf, SUdfRequest* request) {
|
||||
// TODO: tracable id from client. connect, setup, call, teardown
|
||||
fnInfo("%" PRId64 " setup request. udf name: %s", request->seqNum, request->setup.udfName);
|
||||
SUdfSetupRequest *setup = &request->setup;
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
SUdf *udf = NULL;
|
||||
uv_mutex_lock(&global.udfsMutex);
|
||||
SUdf **udfInHash = taosHashGet(global.udfsHash, request->setup.udfName, strlen(request->setup.udfName));
|
||||
if (udfInHash) {
|
||||
++(*udfInHash)->refCount;
|
||||
udf = *udfInHash;
|
||||
uv_mutex_unlock(&global.udfsMutex);
|
||||
} else {
|
||||
SUdf *udfNew = taosMemoryCalloc(1, sizeof(SUdf));
|
||||
udfNew->refCount = 1;
|
||||
udfNew->state = UDF_STATE_INIT;
|
||||
|
||||
uv_mutex_init(&udfNew->lock);
|
||||
uv_cond_init(&udfNew->condReady);
|
||||
udf = udfNew;
|
||||
taosHashPut(global.udfsHash, request->setup.udfName, strlen(request->setup.udfName), &udfNew, sizeof(&udfNew));
|
||||
uv_mutex_unlock(&global.udfsMutex);
|
||||
}
|
||||
|
||||
uv_mutex_lock(&udf->lock);
|
||||
if (udf->state == UDF_STATE_INIT) {
|
||||
udf->state = UDF_STATE_LOADING;
|
||||
code = udfdLoadUdf(setup->udfName, udf);
|
||||
if (udf->initFunc) {
|
||||
udf->initFunc();
|
||||
}
|
||||
udf->state = UDF_STATE_READY;
|
||||
uv_cond_broadcast(&udf->condReady);
|
||||
uv_mutex_unlock(&udf->lock);
|
||||
} else {
|
||||
while (udf->state != UDF_STATE_READY) {
|
||||
uv_cond_wait(&udf->condReady, &udf->lock);
|
||||
}
|
||||
uv_mutex_unlock(&udf->lock);
|
||||
}
|
||||
SUdfcFuncHandle *handle = taosMemoryMalloc(sizeof(SUdfcFuncHandle));
|
||||
handle->udf = udf;
|
||||
|
||||
SUdfResponse rsp;
|
||||
rsp.seqNum = request->seqNum;
|
||||
rsp.type = request->type;
|
||||
rsp.code = code;
|
||||
rsp.setupRsp.udfHandle = (int64_t)(handle);
|
||||
rsp.setupRsp.outputType = udf->outputType;
|
||||
rsp.setupRsp.outputLen = udf->outputLen;
|
||||
rsp.setupRsp.bufSize = udf->bufSize;
|
||||
|
||||
int32_t len = encodeUdfResponse(NULL, &rsp);
|
||||
rsp.msgLen = len;
|
||||
void *bufBegin = taosMemoryMalloc(len);
|
||||
void *buf = bufBegin;
|
||||
encodeUdfResponse(&buf, &rsp);
|
||||
|
||||
uvUdf->output = uv_buf_init(bufBegin, len);
|
||||
|
||||
taosMemoryFree(uvUdf->input.base);
|
||||
return;
|
||||
}
|
||||
|
||||
void udfdProcessCallRequest(SUvUdfWork *uvUdf, SUdfRequest *request) {
|
||||
SUdfCallRequest *call = &request->call;
|
||||
fnDebug("%" PRId64 "call request. call type %d, handle: %" PRIx64, request->seqNum, call->callType,
|
||||
call->udfHandle);
|
||||
SUdfcFuncHandle *handle = (SUdfcFuncHandle *)(call->udfHandle);
|
||||
SUdf *udf = handle->udf;
|
||||
SUdfResponse response = {0};
|
||||
SUdfResponse *rsp = &response;
|
||||
SUdfCallResponse *subRsp = &rsp->callRsp;
|
||||
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
switch(call->callType) {
|
||||
case TSDB_UDF_CALL_SCALA_PROC: {
|
||||
SUdfColumn output = {0};
|
||||
|
||||
SUdfDataBlock input = {0};
|
||||
convertDataBlockToUdfDataBlock(&call->block, &input);
|
||||
code = udf->scalarProcFunc(&input, &output);
|
||||
|
||||
convertUdfColumnToDataBlock(&output, &response.callRsp.resultData);
|
||||
freeUdfColumn(&output);
|
||||
break;
|
||||
}
|
||||
case TSDB_UDF_CALL_AGG_INIT: {
|
||||
SUdfInterBuf outBuf = {.buf = taosMemoryMalloc(udf->bufSize),
|
||||
.bufLen= udf->bufSize,
|
||||
.numOfResult = 0};
|
||||
udf->aggStartFunc(&outBuf);
|
||||
subRsp->resultBuf = outBuf;
|
||||
break;
|
||||
}
|
||||
case TSDB_UDF_CALL_AGG_PROC: {
|
||||
SUdfDataBlock input = {0};
|
||||
convertDataBlockToUdfDataBlock(&call->block, &input);
|
||||
SUdfInterBuf outBuf = {.buf = taosMemoryMalloc(udf->bufSize),
|
||||
.bufLen= udf->bufSize,
|
||||
.numOfResult = 0};
|
||||
code = udf->aggProcFunc(&input, &call->interBuf, &outBuf);
|
||||
subRsp->resultBuf = outBuf;
|
||||
|
||||
break;
|
||||
}
|
||||
case TSDB_UDF_CALL_AGG_FIN: {
|
||||
SUdfInterBuf outBuf = {.buf = taosMemoryMalloc(udf->bufSize),
|
||||
.bufLen= udf->bufSize,
|
||||
.numOfResult = 0};
|
||||
code = udf->aggFinishFunc(&call->interBuf, &outBuf);
|
||||
subRsp->resultBuf = outBuf;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
rsp->seqNum = request->seqNum;
|
||||
rsp->type = request->type;
|
||||
rsp->code = code;
|
||||
subRsp->callType = call->callType;
|
||||
|
||||
int32_t len = encodeUdfResponse(NULL, rsp);
|
||||
rsp->msgLen = len;
|
||||
void *bufBegin = taosMemoryMalloc(len);
|
||||
void *buf = bufBegin;
|
||||
encodeUdfResponse(&buf, rsp);
|
||||
uvUdf->output = uv_buf_init(bufBegin, len);
|
||||
|
||||
taosMemoryFree(uvUdf->input.base);
|
||||
return;
|
||||
}
|
||||
|
||||
void udfdProcessTeardownRequest(SUvUdfWork* uvUdf, SUdfRequest* request) {
|
||||
SUdfTeardownRequest *teardown = &request->teardown;
|
||||
fnInfo("teardown. %" PRId64 "handle:%" PRIx64, request->seqNum, teardown->udfHandle);
|
||||
SUdfcFuncHandle *handle = (SUdfcFuncHandle *)(teardown->udfHandle);
|
||||
SUdf *udf = handle->udf;
|
||||
bool unloadUdf = false;
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
|
||||
uv_mutex_lock(&global.udfsMutex);
|
||||
udf->refCount--;
|
||||
if (udf->refCount == 0) {
|
||||
unloadUdf = true;
|
||||
taosHashRemove(global.udfsHash, udf->name, strlen(udf->name));
|
||||
}
|
||||
uv_mutex_unlock(&global.udfsMutex);
|
||||
if (unloadUdf) {
|
||||
uv_cond_destroy(&udf->condReady);
|
||||
uv_mutex_destroy(&udf->lock);
|
||||
if (udf->destroyFunc) {
|
||||
(udf->destroyFunc)();
|
||||
}
|
||||
uv_dlclose(&udf->lib);
|
||||
taosMemoryFree(udf);
|
||||
}
|
||||
taosMemoryFree(handle);
|
||||
|
||||
SUdfResponse response;
|
||||
SUdfResponse *rsp = &response;
|
||||
rsp->seqNum = request->seqNum;
|
||||
rsp->type = request->type;
|
||||
rsp->code = code;
|
||||
int32_t len = encodeUdfResponse(NULL, rsp);
|
||||
rsp->msgLen = len;
|
||||
void *bufBegin = taosMemoryMalloc(len);
|
||||
void *buf = bufBegin;
|
||||
encodeUdfResponse(&buf, rsp);
|
||||
uvUdf->output = uv_buf_init(bufBegin, len);
|
||||
|
||||
taosMemoryFree(uvUdf->input.base);
|
||||
return;
|
||||
}
|
||||
|
||||
void udfdProcessRequest(uv_work_t *req) {
|
||||
SUvUdfWork *uvUdf = (SUvUdfWork *)(req->data);
|
||||
SUdfRequest request = {0};
|
||||
|
@ -147,172 +323,16 @@ void udfdProcessRequest(uv_work_t *req) {
|
|||
|
||||
switch (request.type) {
|
||||
case UDF_TASK_SETUP: {
|
||||
// TODO: tracable id from client. connect, setup, call, teardown
|
||||
fnInfo("%" PRId64 " setup request. udf name: %s", request.seqNum, request.setup.udfName);
|
||||
SUdfSetupRequest *setup = &request.setup;
|
||||
|
||||
SUdf *udf = NULL;
|
||||
uv_mutex_lock(&global.udfsMutex);
|
||||
SUdf **udfInHash = taosHashGet(global.udfsHash, request.setup.udfName, strlen(request.setup.udfName));
|
||||
if (udfInHash) {
|
||||
++(*udfInHash)->refCount;
|
||||
udf = *udfInHash;
|
||||
uv_mutex_unlock(&global.udfsMutex);
|
||||
} else {
|
||||
SUdf *udfNew = taosMemoryCalloc(1, sizeof(SUdf));
|
||||
udfNew->refCount = 1;
|
||||
udfNew->state = UDF_STATE_INIT;
|
||||
|
||||
uv_mutex_init(&udfNew->lock);
|
||||
uv_cond_init(&udfNew->condReady);
|
||||
udf = udfNew;
|
||||
taosHashPut(global.udfsHash, request.setup.udfName, strlen(request.setup.udfName), &udfNew, sizeof(&udfNew));
|
||||
uv_mutex_unlock(&global.udfsMutex);
|
||||
}
|
||||
|
||||
uv_mutex_lock(&udf->lock);
|
||||
if (udf->state == UDF_STATE_INIT) {
|
||||
udf->state = UDF_STATE_LOADING;
|
||||
udfdLoadUdf(setup->udfName, udf);
|
||||
if (udf->initFunc) {
|
||||
udf->initFunc();
|
||||
}
|
||||
udf->state = UDF_STATE_READY;
|
||||
uv_cond_broadcast(&udf->condReady);
|
||||
uv_mutex_unlock(&udf->lock);
|
||||
} else {
|
||||
while (udf->state != UDF_STATE_READY) {
|
||||
uv_cond_wait(&udf->condReady, &udf->lock);
|
||||
}
|
||||
uv_mutex_unlock(&udf->lock);
|
||||
}
|
||||
SUdfcFuncHandle *handle = taosMemoryMalloc(sizeof(SUdfcFuncHandle));
|
||||
handle->udf = udf;
|
||||
SUdfResponse rsp;
|
||||
rsp.seqNum = request.seqNum;
|
||||
rsp.type = request.type;
|
||||
rsp.code = 0;
|
||||
rsp.setupRsp.udfHandle = (int64_t)(handle);
|
||||
rsp.setupRsp.outputType = udf->outputType;
|
||||
rsp.setupRsp.outputLen = udf->outputLen;
|
||||
rsp.setupRsp.bufSize = udf->bufSize;
|
||||
int32_t len = encodeUdfResponse(NULL, &rsp);
|
||||
rsp.msgLen = len;
|
||||
void *bufBegin = taosMemoryMalloc(len);
|
||||
void *buf = bufBegin;
|
||||
encodeUdfResponse(&buf, &rsp);
|
||||
|
||||
uvUdf->output = uv_buf_init(bufBegin, len);
|
||||
|
||||
taosMemoryFree(uvUdf->input.base);
|
||||
udfdProcessSetupRequest(uvUdf, &request);
|
||||
break;
|
||||
}
|
||||
|
||||
case UDF_TASK_CALL: {
|
||||
SUdfCallRequest *call = &request.call;
|
||||
fnDebug("%" PRId64 "call request. call type %d, handle: %" PRIx64, request.seqNum, call->callType,
|
||||
call->udfHandle);
|
||||
SUdfcFuncHandle *handle = (SUdfcFuncHandle *)(call->udfHandle);
|
||||
SUdf *udf = handle->udf;
|
||||
SUdfResponse response = {0};
|
||||
SUdfResponse *rsp = &response;
|
||||
SUdfCallResponse *subRsp = &rsp->callRsp;
|
||||
|
||||
switch(call->callType) {
|
||||
case TSDB_UDF_CALL_SCALA_PROC: {
|
||||
SUdfColumn output = {0};
|
||||
|
||||
SUdfDataBlock input = {0};
|
||||
convertDataBlockToUdfDataBlock(&call->block, &input);
|
||||
udf->scalarProcFunc(&input, &output);
|
||||
|
||||
convertUdfColumnToDataBlock(&output, &response.callRsp.resultData);
|
||||
freeUdfColumn(&output);
|
||||
break;
|
||||
}
|
||||
case TSDB_UDF_CALL_AGG_INIT: {
|
||||
SUdfInterBuf outBuf = {.buf = taosMemoryMalloc(udf->bufSize),
|
||||
.bufLen= udf->bufSize,
|
||||
.numOfResult = 0};
|
||||
udf->aggStartFunc(&outBuf);
|
||||
subRsp->resultBuf = outBuf;
|
||||
break;
|
||||
}
|
||||
case TSDB_UDF_CALL_AGG_PROC: {
|
||||
SUdfDataBlock input = {0};
|
||||
convertDataBlockToUdfDataBlock(&call->block, &input);
|
||||
SUdfInterBuf outBuf = {.buf = taosMemoryMalloc(udf->bufSize),
|
||||
.bufLen= udf->bufSize,
|
||||
.numOfResult = 0};
|
||||
udf->aggProcFunc(&input, &call->interBuf, &outBuf);
|
||||
subRsp->resultBuf = outBuf;
|
||||
|
||||
break;
|
||||
}
|
||||
case TSDB_UDF_CALL_AGG_FIN: {
|
||||
SUdfInterBuf outBuf = {.buf = taosMemoryMalloc(udf->bufSize),
|
||||
.bufLen= udf->bufSize,
|
||||
.numOfResult = 0};
|
||||
udf->aggFinishFunc(&call->interBuf, &outBuf);
|
||||
subRsp->resultBuf = outBuf;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
rsp->seqNum = request.seqNum;
|
||||
rsp->type = request.type;
|
||||
rsp->code = 0;
|
||||
subRsp->callType = call->callType;
|
||||
|
||||
int32_t len = encodeUdfResponse(NULL, rsp);
|
||||
rsp->msgLen = len;
|
||||
void *bufBegin = taosMemoryMalloc(len);
|
||||
void *buf = bufBegin;
|
||||
encodeUdfResponse(&buf, rsp);
|
||||
uvUdf->output = uv_buf_init(bufBegin, len);
|
||||
|
||||
taosMemoryFree(uvUdf->input.base);
|
||||
udfdProcessCallRequest(uvUdf, &request);
|
||||
break;
|
||||
}
|
||||
case UDF_TASK_TEARDOWN: {
|
||||
SUdfTeardownRequest *teardown = &request.teardown;
|
||||
fnInfo("teardown. %" PRId64 "handle:%" PRIx64, request.seqNum, teardown->udfHandle) SUdfcFuncHandle *handle =
|
||||
(SUdfcFuncHandle *)(teardown->udfHandle);
|
||||
SUdf *udf = handle->udf;
|
||||
bool unloadUdf = false;
|
||||
uv_mutex_lock(&global.udfsMutex);
|
||||
udf->refCount--;
|
||||
if (udf->refCount == 0) {
|
||||
unloadUdf = true;
|
||||
taosHashRemove(global.udfsHash, udf->name, strlen(udf->name));
|
||||
}
|
||||
uv_mutex_unlock(&global.udfsMutex);
|
||||
if (unloadUdf) {
|
||||
uv_cond_destroy(&udf->condReady);
|
||||
uv_mutex_destroy(&udf->lock);
|
||||
if (udf->destroyFunc) {
|
||||
(udf->destroyFunc)();
|
||||
}
|
||||
uv_dlclose(&udf->lib);
|
||||
taosMemoryFree(udf);
|
||||
}
|
||||
taosMemoryFree(handle);
|
||||
|
||||
SUdfResponse response;
|
||||
SUdfResponse *rsp = &response;
|
||||
rsp->seqNum = request.seqNum;
|
||||
rsp->type = request.type;
|
||||
rsp->code = 0;
|
||||
int32_t len = encodeUdfResponse(NULL, rsp);
|
||||
rsp->msgLen = len;
|
||||
void *bufBegin = taosMemoryMalloc(len);
|
||||
void *buf = bufBegin;
|
||||
encodeUdfResponse(&buf, rsp);
|
||||
uvUdf->output = uv_buf_init(bufBegin, len);
|
||||
|
||||
taosMemoryFree(uvUdf->input.base);
|
||||
udfdProcessTeardownRequest(uvUdf, &request);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
|
|
|
@ -27,6 +27,12 @@ int32_t udf2_start(SUdfInterBuf *buf) {
|
|||
int32_t udf2(SUdfDataBlock* block, SUdfInterBuf *interBuf, SUdfInterBuf *newInterBuf) {
|
||||
int64_t sumSquares = *(int64_t*)interBuf->buf;
|
||||
int8_t numOutput = 0;
|
||||
for (int32_t i = 0; i < block->numOfCols; ++i) {
|
||||
SUdfColumn* col = block->udfCols[i];
|
||||
if (col->colMeta.type != TSDB_DATA_TYPE_INT) {
|
||||
return TSDB_CODE_UDF_INVALID_INPUT;
|
||||
}
|
||||
}
|
||||
for (int32_t i = 0; i < block->numOfCols; ++i) {
|
||||
for (int32_t j = 0; j < block->numOfRows; ++j) {
|
||||
SUdfColumn* col = block->udfCols[i];
|
||||
|
|
|
@ -32,6 +32,7 @@ typedef struct SAstCreateContext {
|
|||
bool notSupport;
|
||||
SNode* pRootNode;
|
||||
int16_t placeholderNo;
|
||||
SArray* pPlaceholderValues;
|
||||
int32_t errCode;
|
||||
} SAstCreateContext;
|
||||
|
||||
|
|
|
@ -137,7 +137,7 @@ void destroyBlockArrayList(SArray* pDataBlockList);
|
|||
void destroyBlockHashmap(SHashObj* pDataBlockHash);
|
||||
int initRowBuilder(SRowBuilder *pBuilder, int16_t schemaVer, SParsedDataColInfo *pColInfo);
|
||||
int32_t allocateMemIfNeed(STableDataBlocks *pDataBlock, int32_t rowSize, int32_t * numOfRows);
|
||||
int32_t getDataBlockFromList(SHashObj* pHashList, int64_t id, int32_t size, int32_t startOffset, int32_t rowSize,
|
||||
int32_t getDataBlockFromList(SHashObj* pHashList, void* id, int32_t idLen, int32_t size, int32_t startOffset, int32_t rowSize,
|
||||
STableMeta* pTableMeta, STableDataBlocks** dataBlocks, SArray* pBlockList, SVCreateTbReq* pCreateTbReq);
|
||||
int32_t mergeTableDataBlocks(SHashObj* pHashObj, uint8_t payloadType, SArray** pVgDataBlocks);
|
||||
int32_t buildCreateTbMsg(STableDataBlocks* pBlocks, SVCreateTbReq* pCreateTbReq);
|
||||
|
|
|
@ -46,6 +46,7 @@ SSchema* getTableTagSchema(const STableMeta* pTableMeta);
|
|||
int32_t getNumOfColumns(const STableMeta* pTableMeta);
|
||||
int32_t getNumOfTags(const STableMeta* pTableMeta);
|
||||
STableComInfo getTableInfo(const STableMeta* pTableMeta);
|
||||
STableMeta* tableMetaDup(const STableMeta* pTableMeta);
|
||||
int parseJsontoTagData(const char* json, SKVRowBuilder* kvRowBuilder, SMsgBuf* errMsg, int16_t startColId);
|
||||
|
||||
int32_t trimString(const char* src, int32_t len, char* dst, int32_t dlen);
|
||||
|
|
|
@ -44,6 +44,7 @@ void initAstCreateContext(SParseContext* pParseCxt, SAstCreateContext* pCxt) {
|
|||
pCxt->notSupport = false;
|
||||
pCxt->pRootNode = NULL;
|
||||
pCxt->placeholderNo = 0;
|
||||
pCxt->pPlaceholderValues = NULL;
|
||||
pCxt->errCode = TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -78,7 +79,7 @@ static bool checkUserName(SAstCreateContext* pCxt, SToken* pUserName) {
|
|||
static bool checkPassword(SAstCreateContext* pCxt, const SToken* pPasswordToken, char* pPassword) {
|
||||
if (NULL == pPasswordToken) {
|
||||
pCxt->errCode = TSDB_CODE_PAR_SYNTAX_ERROR;
|
||||
} else if (pPasswordToken->n >= (TSDB_USET_PASSWORD_LEN - 2)) {
|
||||
} else if (pPasswordToken->n >= (TSDB_USET_PASSWORD_LEN + 2)) {
|
||||
pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG);
|
||||
} else {
|
||||
strncpy(pPassword, pPasswordToken->z, pPasswordToken->n);
|
||||
|
@ -299,6 +300,14 @@ SNode* createPlaceholderValueNode(SAstCreateContext* pCxt, const SToken* pLitera
|
|||
val->literal = strndup(pLiteral->z, pLiteral->n);
|
||||
CHECK_OUT_OF_MEM(val->literal);
|
||||
val->placeholderNo = ++pCxt->placeholderNo;
|
||||
if (NULL == pCxt->pPlaceholderValues) {
|
||||
pCxt->pPlaceholderValues = taosArrayInit(TARRAY_MIN_SIZE, POINTER_BYTES);
|
||||
if (NULL == pCxt->pPlaceholderValues) {
|
||||
nodesDestroyNode(val);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
taosArrayPush(pCxt->pPlaceholderValues, &val);
|
||||
return (SNode*)val;
|
||||
}
|
||||
|
||||
|
@ -350,7 +359,18 @@ SNode* createNotBetweenAnd(SAstCreateContext* pCxt, SNode* pExpr, SNode* pLeft,
|
|||
createOperatorNode(pCxt, OP_TYPE_GREATER_THAN, nodesCloneNode(pExpr), pRight));
|
||||
}
|
||||
|
||||
static SNode* createPrimaryKeyCol(SAstCreateContext* pCxt) {
|
||||
SColumnNode* pCol = nodesMakeNode(QUERY_NODE_COLUMN);
|
||||
CHECK_OUT_OF_MEM(pCol);
|
||||
pCol->colId = PRIMARYKEY_TIMESTAMP_COL_ID;
|
||||
strcpy(pCol->colName, PK_TS_COL_INTERNAL_NAME);
|
||||
return (SNode*)pCol;
|
||||
}
|
||||
|
||||
SNode* createFunctionNode(SAstCreateContext* pCxt, const SToken* pFuncName, SNodeList* pParameterList) {
|
||||
if (0 == strncasecmp("_rowts", pFuncName->z, pFuncName->n) || 0 == strncasecmp("_c0", pFuncName->z, pFuncName->n)) {
|
||||
return createPrimaryKeyCol(pCxt);
|
||||
}
|
||||
SFunctionNode* func = (SFunctionNode*)nodesMakeNode(QUERY_NODE_FUNCTION);
|
||||
CHECK_OUT_OF_MEM(func);
|
||||
strncpy(func->functionName, pFuncName->z, pFuncName->n);
|
||||
|
@ -467,13 +487,11 @@ SNode* createSessionWindowNode(SAstCreateContext* pCxt, SNode* pCol, SNode* pGap
|
|||
SNode* createStateWindowNode(SAstCreateContext* pCxt, SNode* pExpr) {
|
||||
SStateWindowNode* state = (SStateWindowNode*)nodesMakeNode(QUERY_NODE_STATE_WINDOW);
|
||||
CHECK_OUT_OF_MEM(state);
|
||||
state->pCol = nodesMakeNode(QUERY_NODE_COLUMN);
|
||||
state->pCol = createPrimaryKeyCol(pCxt);
|
||||
if (NULL == state->pCol) {
|
||||
nodesDestroyNode(state);
|
||||
CHECK_OUT_OF_MEM(state->pCol);
|
||||
}
|
||||
((SColumnNode*)state->pCol)->colId = PRIMARYKEY_TIMESTAMP_COL_ID;
|
||||
strcpy(((SColumnNode*)state->pCol)->colName, PK_TS_COL_INTERNAL_NAME);
|
||||
state->pExpr = pExpr;
|
||||
return (SNode*)state;
|
||||
}
|
||||
|
@ -482,13 +500,11 @@ SNode* createIntervalWindowNode(SAstCreateContext* pCxt, SNode* pInterval, SNode
|
|||
SNode* pFill) {
|
||||
SIntervalWindowNode* interval = (SIntervalWindowNode*)nodesMakeNode(QUERY_NODE_INTERVAL_WINDOW);
|
||||
CHECK_OUT_OF_MEM(interval);
|
||||
interval->pCol = nodesMakeNode(QUERY_NODE_COLUMN);
|
||||
interval->pCol = createPrimaryKeyCol(pCxt);
|
||||
if (NULL == interval->pCol) {
|
||||
nodesDestroyNode(interval);
|
||||
CHECK_OUT_OF_MEM(interval->pCol);
|
||||
}
|
||||
((SColumnNode*)interval->pCol)->colId = PRIMARYKEY_TIMESTAMP_COL_ID;
|
||||
strcpy(((SColumnNode*)interval->pCol)->colName, PK_TS_COL_INTERNAL_NAME);
|
||||
interval->pInterval = pInterval;
|
||||
interval->pOffset = pOffset;
|
||||
interval->pSliding = pSliding;
|
||||
|
@ -667,7 +683,7 @@ SNode* setDatabaseOption(SAstCreateContext* pCxt, SNode* pOptions, EDatabaseOpti
|
|||
case DB_OPTION_DAYS: {
|
||||
SToken* pToken = pVal;
|
||||
if (TK_NK_INTEGER == pToken->type) {
|
||||
((SDatabaseOptions*)pOptions)->daysPerFile = strtol(pToken->z, NULL, 10);
|
||||
((SDatabaseOptions*)pOptions)->daysPerFile = strtol(pToken->z, NULL, 10) * 1440;
|
||||
} else {
|
||||
((SDatabaseOptions*)pOptions)->pDaysPerFile = (SValueNode*)createDurationValueNode(pCxt, pToken);
|
||||
}
|
||||
|
|
|
@ -81,6 +81,8 @@ abort_parse:
|
|||
}
|
||||
(*pQuery)->pRoot = cxt.pRootNode;
|
||||
(*pQuery)->placeholderNum = cxt.placeholderNo;
|
||||
TSWAP((*pQuery)->pPlaceholderValues, cxt.pPlaceholderValues);
|
||||
}
|
||||
taosArrayDestroy(cxt.pPlaceholderValues);
|
||||
return cxt.errCode;
|
||||
}
|
||||
|
|
|
@ -53,6 +53,7 @@ typedef struct SInsertParseContext {
|
|||
SHashObj* pTableBlockHashObj; // global
|
||||
SHashObj* pSubTableHashObj; // global
|
||||
SArray* pVgDataBlocks; // global
|
||||
SHashObj* pTableNameHashObj; // global
|
||||
int32_t totalNum;
|
||||
SVnodeModifOpStmt* pOutput;
|
||||
SStmtCallback* pStmtCb;
|
||||
|
@ -237,36 +238,37 @@ static int32_t createSName(SName* pName, SToken* pTableName, int32_t acctId, con
|
|||
return code;
|
||||
}
|
||||
|
||||
static int32_t getTableMetaImpl(SInsertParseContext* pCxt, SToken* pTname, bool isStb) {
|
||||
static int32_t getTableMetaImpl(SInsertParseContext* pCxt, SName* name, char* dbFname, bool isStb) {
|
||||
SParseContext* pBasicCtx = pCxt->pComCxt;
|
||||
SName name = {0};
|
||||
createSName(&name, pTname, pBasicCtx->acctId, pBasicCtx->db, &pCxt->msg);
|
||||
|
||||
char dbFname[TSDB_DB_FNAME_LEN] = {0};
|
||||
tNameGetFullDbName(&name, dbFname);
|
||||
|
||||
bool pass = false;
|
||||
CHECK_CODE(catalogChkAuth(pBasicCtx->pCatalog, pBasicCtx->pTransporter, &pBasicCtx->mgmtEpSet, pBasicCtx->pUser, dbFname, AUTH_TYPE_WRITE, &pass));
|
||||
CHECK_CODE(catalogChkAuth(pBasicCtx->pCatalog, pBasicCtx->pTransporter, &pBasicCtx->mgmtEpSet, pBasicCtx->pUser,
|
||||
dbFname, AUTH_TYPE_WRITE, &pass));
|
||||
if (!pass) {
|
||||
return TSDB_CODE_PAR_PERMISSION_DENIED;
|
||||
}
|
||||
if (isStb) {
|
||||
CHECK_CODE(catalogGetSTableMeta(pBasicCtx->pCatalog, pBasicCtx->pTransporter, &pBasicCtx->mgmtEpSet, &name,
|
||||
CHECK_CODE(catalogGetSTableMeta(pBasicCtx->pCatalog, pBasicCtx->pTransporter, &pBasicCtx->mgmtEpSet, name,
|
||||
&pCxt->pTableMeta));
|
||||
} else {
|
||||
CHECK_CODE(catalogGetTableMeta(pBasicCtx->pCatalog, pBasicCtx->pTransporter, &pBasicCtx->mgmtEpSet, &name,
|
||||
CHECK_CODE(catalogGetTableMeta(pBasicCtx->pCatalog, pBasicCtx->pTransporter, &pBasicCtx->mgmtEpSet, name,
|
||||
&pCxt->pTableMeta));
|
||||
ASSERT(pCxt->pTableMeta->tableInfo.rowSize > 0);
|
||||
SVgroupInfo vg;
|
||||
CHECK_CODE(
|
||||
catalogGetTableHashVgroup(pBasicCtx->pCatalog, pBasicCtx->pTransporter, &pBasicCtx->mgmtEpSet, &name, &vg));
|
||||
catalogGetTableHashVgroup(pBasicCtx->pCatalog, pBasicCtx->pTransporter, &pBasicCtx->mgmtEpSet, name, &vg));
|
||||
CHECK_CODE(taosHashPut(pCxt->pVgroupsHashObj, (const char*)&vg.vgId, sizeof(vg.vgId), (char*)&vg, sizeof(vg)));
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t getTableMeta(SInsertParseContext* pCxt, SToken* pTname) { return getTableMetaImpl(pCxt, pTname, false); }
|
||||
static int32_t getTableMeta(SInsertParseContext* pCxt, SName* name, char* dbFname) {
|
||||
return getTableMetaImpl(pCxt, name, dbFname, false);
|
||||
}
|
||||
|
||||
static int32_t getSTableMeta(SInsertParseContext* pCxt, SToken* pTname) { return getTableMetaImpl(pCxt, pTname, true); }
|
||||
static int32_t getSTableMeta(SInsertParseContext* pCxt, SName* name, char* dbFname) {
|
||||
return getTableMetaImpl(pCxt, name, dbFname, true);
|
||||
}
|
||||
|
||||
static int32_t findCol(SToken* pColname, int32_t start, int32_t end, SSchema* pSchema) {
|
||||
while (start < end) {
|
||||
|
@ -349,8 +351,7 @@ static int parseTime(char** end, SToken* pToken, int16_t timePrec, int64_t* time
|
|||
} else if (pToken->type == TK_TODAY) {
|
||||
ts = taosGetTimestampToday(timePrec);
|
||||
} else if (pToken->type == TK_NK_INTEGER) {
|
||||
bool isSigned = false;
|
||||
toInteger(pToken->z, pToken->n, 10, &ts, &isSigned);
|
||||
toInteger(pToken->z, pToken->n, 10, &ts);
|
||||
} else { // parse the RFC-3339/ISO-8601 timestamp format string
|
||||
if (taosParseTime(pToken->z, time, pToken->n, timePrec, tsDaylight) != TSDB_CODE_SUCCESS) {
|
||||
return buildSyntaxErrMsg(pMsgBuf, "invalid timestamp format", pToken->z);
|
||||
|
@ -453,9 +454,9 @@ static FORCE_INLINE int32_t toDouble(SToken* pToken, double* value, char** endPt
|
|||
|
||||
static int32_t parseValueToken(char** end, SToken* pToken, SSchema* pSchema, int16_t timePrec, char* tmpTokenBuf,
|
||||
_row_append_fn_t func, void* param, SMsgBuf* pMsgBuf) {
|
||||
int64_t iv;
|
||||
char* endptr = NULL;
|
||||
bool isSigned = false;
|
||||
int64_t iv;
|
||||
uint64_t uv;
|
||||
char* endptr = NULL;
|
||||
|
||||
int32_t code = checkAndTrimValue(pToken, pSchema->type, tmpTokenBuf, pMsgBuf);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
|
@ -490,7 +491,7 @@ static int32_t parseValueToken(char** end, SToken* pToken, SSchema* pSchema, int
|
|||
}
|
||||
|
||||
case TSDB_DATA_TYPE_TINYINT: {
|
||||
if (TSDB_CODE_SUCCESS != toInteger(pToken->z, pToken->n, 10, &iv, &isSigned)) {
|
||||
if (TSDB_CODE_SUCCESS != toInteger(pToken->z, pToken->n, 10, &iv)) {
|
||||
return buildSyntaxErrMsg(pMsgBuf, "invalid tinyint data", pToken->z);
|
||||
} else if (!IS_VALID_TINYINT(iv)) {
|
||||
return buildSyntaxErrMsg(pMsgBuf, "tinyint data overflow", pToken->z);
|
||||
|
@ -501,17 +502,17 @@ static int32_t parseValueToken(char** end, SToken* pToken, SSchema* pSchema, int
|
|||
}
|
||||
|
||||
case TSDB_DATA_TYPE_UTINYINT: {
|
||||
if (TSDB_CODE_SUCCESS != toInteger(pToken->z, pToken->n, 10, &iv, &isSigned)) {
|
||||
if (TSDB_CODE_SUCCESS != toUInteger(pToken->z, pToken->n, 10, &uv)) {
|
||||
return buildSyntaxErrMsg(pMsgBuf, "invalid unsigned tinyint data", pToken->z);
|
||||
} else if (!IS_VALID_UTINYINT(iv)) {
|
||||
} else if (!IS_VALID_UTINYINT(uv)) {
|
||||
return buildSyntaxErrMsg(pMsgBuf, "unsigned tinyint data overflow", pToken->z);
|
||||
}
|
||||
uint8_t tmpVal = (uint8_t)iv;
|
||||
uint8_t tmpVal = (uint8_t)uv;
|
||||
return func(pMsgBuf, &tmpVal, pSchema->bytes, param);
|
||||
}
|
||||
|
||||
case TSDB_DATA_TYPE_SMALLINT: {
|
||||
if (TSDB_CODE_SUCCESS != toInteger(pToken->z, pToken->n, 10, &iv, &isSigned)) {
|
||||
if (TSDB_CODE_SUCCESS != toInteger(pToken->z, pToken->n, 10, &iv)) {
|
||||
return buildSyntaxErrMsg(pMsgBuf, "invalid smallint data", pToken->z);
|
||||
} else if (!IS_VALID_SMALLINT(iv)) {
|
||||
return buildSyntaxErrMsg(pMsgBuf, "smallint data overflow", pToken->z);
|
||||
|
@ -521,17 +522,17 @@ static int32_t parseValueToken(char** end, SToken* pToken, SSchema* pSchema, int
|
|||
}
|
||||
|
||||
case TSDB_DATA_TYPE_USMALLINT: {
|
||||
if (TSDB_CODE_SUCCESS != toInteger(pToken->z, pToken->n, 10, &iv, &isSigned)) {
|
||||
if (TSDB_CODE_SUCCESS != toUInteger(pToken->z, pToken->n, 10, &uv)) {
|
||||
return buildSyntaxErrMsg(pMsgBuf, "invalid unsigned smallint data", pToken->z);
|
||||
} else if (!IS_VALID_USMALLINT(iv)) {
|
||||
} else if (!IS_VALID_USMALLINT(uv)) {
|
||||
return buildSyntaxErrMsg(pMsgBuf, "unsigned smallint data overflow", pToken->z);
|
||||
}
|
||||
uint16_t tmpVal = (uint16_t)iv;
|
||||
uint16_t tmpVal = (uint16_t)uv;
|
||||
return func(pMsgBuf, &tmpVal, pSchema->bytes, param);
|
||||
}
|
||||
|
||||
case TSDB_DATA_TYPE_INT: {
|
||||
if (TSDB_CODE_SUCCESS != toInteger(pToken->z, pToken->n, 10, &iv, &isSigned)) {
|
||||
if (TSDB_CODE_SUCCESS != toInteger(pToken->z, pToken->n, 10, &iv)) {
|
||||
return buildSyntaxErrMsg(pMsgBuf, "invalid int data", pToken->z);
|
||||
} else if (!IS_VALID_INT(iv)) {
|
||||
return buildSyntaxErrMsg(pMsgBuf, "int data overflow", pToken->z);
|
||||
|
@ -541,17 +542,17 @@ static int32_t parseValueToken(char** end, SToken* pToken, SSchema* pSchema, int
|
|||
}
|
||||
|
||||
case TSDB_DATA_TYPE_UINT: {
|
||||
if (TSDB_CODE_SUCCESS != toInteger(pToken->z, pToken->n, 10, &iv, &isSigned)) {
|
||||
if (TSDB_CODE_SUCCESS != toUInteger(pToken->z, pToken->n, 10, &uv)) {
|
||||
return buildSyntaxErrMsg(pMsgBuf, "invalid unsigned int data", pToken->z);
|
||||
} else if (!IS_VALID_UINT(iv)) {
|
||||
} else if (!IS_VALID_UINT(uv)) {
|
||||
return buildSyntaxErrMsg(pMsgBuf, "unsigned int data overflow", pToken->z);
|
||||
}
|
||||
uint32_t tmpVal = (uint32_t)iv;
|
||||
uint32_t tmpVal = (uint32_t)uv;
|
||||
return func(pMsgBuf, &tmpVal, pSchema->bytes, param);
|
||||
}
|
||||
|
||||
case TSDB_DATA_TYPE_BIGINT: {
|
||||
if (TSDB_CODE_SUCCESS != toInteger(pToken->z, pToken->n, 10, &iv, &isSigned)) {
|
||||
if (TSDB_CODE_SUCCESS != toInteger(pToken->z, pToken->n, 10, &iv)) {
|
||||
return buildSyntaxErrMsg(pMsgBuf, "invalid bigint data", pToken->z);
|
||||
} else if (!IS_VALID_BIGINT(iv)) {
|
||||
return buildSyntaxErrMsg(pMsgBuf, "bigint data overflow", pToken->z);
|
||||
|
@ -560,13 +561,12 @@ static int32_t parseValueToken(char** end, SToken* pToken, SSchema* pSchema, int
|
|||
}
|
||||
|
||||
case TSDB_DATA_TYPE_UBIGINT: {
|
||||
if (TSDB_CODE_SUCCESS != toInteger(pToken->z, pToken->n, 10, &iv, &isSigned)) {
|
||||
if (TSDB_CODE_SUCCESS != toUInteger(pToken->z, pToken->n, 10, &uv)) {
|
||||
return buildSyntaxErrMsg(pMsgBuf, "invalid unsigned bigint data", pToken->z);
|
||||
} else if (!IS_VALID_UBIGINT((uint64_t)iv)) {
|
||||
} else if (!IS_VALID_UBIGINT(uv)) {
|
||||
return buildSyntaxErrMsg(pMsgBuf, "unsigned bigint data overflow", pToken->z);
|
||||
}
|
||||
uint64_t tmpVal = (uint64_t)iv;
|
||||
return func(pMsgBuf, &tmpVal, pSchema->bytes, param);
|
||||
return func(pMsgBuf, &uv, pSchema->bytes, param);
|
||||
}
|
||||
|
||||
case TSDB_DATA_TYPE_FLOAT: {
|
||||
|
@ -771,7 +771,7 @@ static int32_t KvRowAppend(SMsgBuf* pMsgBuf, const void* value, int32_t len, voi
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t buildCreateTbReq(SVCreateTbReq *pTbReq, const char* tname, SKVRow row, int64_t suid) {
|
||||
static int32_t buildCreateTbReq(SVCreateTbReq* pTbReq, const char* tname, SKVRow row, int64_t suid) {
|
||||
pTbReq->type = TD_CHILD_TABLE;
|
||||
pTbReq->name = strdup(tname);
|
||||
pTbReq->ctb.suid = suid;
|
||||
|
@ -842,8 +842,9 @@ static int32_t storeTableMeta(SInsertParseContext* pCxt, SHashObj* pHash, SName*
|
|||
catalogGetTableHashVgroup(pBasicCtx->pCatalog, pBasicCtx->pTransporter, &pBasicCtx->mgmtEpSet, pTableName, &vg));
|
||||
CHECK_CODE(taosHashPut(pCxt->pVgroupsHashObj, (const char*)&vg.vgId, sizeof(vg.vgId), (char*)&vg, sizeof(vg)));
|
||||
|
||||
pMeta->uid = tGenIdPI64();
|
||||
pMeta->uid = 0;
|
||||
pMeta->vgId = vg.vgId;
|
||||
pMeta->tableType = TSDB_CHILD_TABLE;
|
||||
|
||||
STableMeta* pBackup = NULL;
|
||||
if (TSDB_CODE_SUCCESS != cloneTableMeta(pMeta, &pBackup)) {
|
||||
|
@ -853,11 +854,7 @@ static int32_t storeTableMeta(SInsertParseContext* pCxt, SHashObj* pHash, SName*
|
|||
}
|
||||
|
||||
// pSql -> stb_name [(tag1_name, ...)] TAGS (tag1_value, ...)
|
||||
static int32_t parseUsingClause(SInsertParseContext* pCxt, SToken* pTbnameToken) {
|
||||
SName name;
|
||||
createSName(&name, pTbnameToken, pCxt->pComCxt->acctId, pCxt->pComCxt->db, &pCxt->msg);
|
||||
char tbFName[TSDB_TABLE_FNAME_LEN];
|
||||
tNameExtractFullName(&name, tbFName);
|
||||
static int32_t parseUsingClause(SInsertParseContext* pCxt, SName* name, char* tbFName) {
|
||||
int32_t len = strlen(tbFName);
|
||||
STableMeta** pMeta = taosHashGet(pCxt->pSubTableHashObj, tbFName, len);
|
||||
if (NULL != pMeta) {
|
||||
|
@ -867,11 +864,17 @@ static int32_t parseUsingClause(SInsertParseContext* pCxt, SToken* pTbnameToken)
|
|||
SToken sToken;
|
||||
// pSql -> stb_name [(tag1_name, ...)] TAGS (tag1_value, ...)
|
||||
NEXT_TOKEN(pCxt->pSql, sToken);
|
||||
CHECK_CODE(getSTableMeta(pCxt, &sToken));
|
||||
|
||||
SName sname;
|
||||
createSName(&sname, &sToken, pCxt->pComCxt->acctId, pCxt->pComCxt->db, &pCxt->msg);
|
||||
char stbFName[TSDB_TABLE_FNAME_LEN];
|
||||
tNameExtractFullName(&sname, stbFName);
|
||||
|
||||
CHECK_CODE(getSTableMeta(pCxt, &sname, stbFName));
|
||||
if (TSDB_SUPER_TABLE != pCxt->pTableMeta->tableType) {
|
||||
return buildInvalidOperationMsg(&pCxt->msg, "create table only from super table is allowed");
|
||||
}
|
||||
CHECK_CODE(storeTableMeta(pCxt, pCxt->pSubTableHashObj, &name, tbFName, len, pCxt->pTableMeta));
|
||||
CHECK_CODE(storeTableMeta(pCxt, pCxt->pSubTableHashObj, name, tbFName, len, pCxt->pTableMeta));
|
||||
|
||||
SSchema* pTagsSchema = getTableTagSchema(pCxt->pTableMeta);
|
||||
setBoundColumnInfo(&pCxt->tags, pTagsSchema, getNumOfTags(pCxt->pTableMeta));
|
||||
|
@ -891,7 +894,7 @@ static int32_t parseUsingClause(SInsertParseContext* pCxt, SToken* pTbnameToken)
|
|||
if (TK_NK_LP != sToken.type) {
|
||||
return buildSyntaxErrMsg(&pCxt->msg, "( is expected", sToken.z);
|
||||
}
|
||||
CHECK_CODE(parseTagsClause(pCxt, pCxt->pTableMeta->schema, getTableInfo(pCxt->pTableMeta).precision, name.tname));
|
||||
CHECK_CODE(parseTagsClause(pCxt, pCxt->pTableMeta->schema, getTableInfo(pCxt->pTableMeta).precision, name->tname));
|
||||
NEXT_TOKEN(pCxt->pSql, sToken);
|
||||
if (TK_NK_RP != sToken.type) {
|
||||
return buildSyntaxErrMsg(&pCxt->msg, ") is expected", sToken.z);
|
||||
|
@ -1066,6 +1069,9 @@ static void destroyInsertParseContext(SInsertParseContext* pCxt) {
|
|||
// [...];
|
||||
static int32_t parseInsertBody(SInsertParseContext* pCxt) {
|
||||
int32_t tbNum = 0;
|
||||
char tbFName[TSDB_TABLE_FNAME_LEN];
|
||||
bool autoCreateTbl = false;
|
||||
STableMeta *pMeta = NULL;
|
||||
|
||||
// for each table
|
||||
while (1) {
|
||||
|
@ -1103,22 +1109,31 @@ static int32_t parseInsertBody(SInsertParseContext* pCxt) {
|
|||
SToken tbnameToken = sToken;
|
||||
NEXT_TOKEN(pCxt->pSql, sToken);
|
||||
|
||||
SName name;
|
||||
createSName(&name, &tbnameToken, pCxt->pComCxt->acctId, pCxt->pComCxt->db, &pCxt->msg);
|
||||
tNameExtractFullName(&name, tbFName);
|
||||
|
||||
CHECK_CODE(taosHashPut(pCxt->pTableNameHashObj, tbFName, strlen(tbFName), &name, sizeof(SName)));
|
||||
|
||||
// USING cluase
|
||||
if (TK_USING == sToken.type) {
|
||||
CHECK_CODE(parseUsingClause(pCxt, &tbnameToken));
|
||||
CHECK_CODE(parseUsingClause(pCxt, &name, tbFName));
|
||||
NEXT_TOKEN(pCxt->pSql, sToken);
|
||||
autoCreateTbl = true;
|
||||
} else {
|
||||
CHECK_CODE(getTableMeta(pCxt, &tbnameToken));
|
||||
CHECK_CODE(getTableMeta(pCxt, &name, tbFName));
|
||||
}
|
||||
|
||||
STableDataBlocks* dataBuf = NULL;
|
||||
CHECK_CODE(getDataBlockFromList(pCxt->pTableBlockHashObj, pCxt->pTableMeta->uid, TSDB_DEFAULT_PAYLOAD_SIZE,
|
||||
CHECK_CODE(getDataBlockFromList(pCxt->pTableBlockHashObj, tbFName, strlen(tbFName), TSDB_DEFAULT_PAYLOAD_SIZE,
|
||||
sizeof(SSubmitBlk), getTableInfo(pCxt->pTableMeta).rowSize, pCxt->pTableMeta,
|
||||
&dataBuf, NULL, &pCxt->createTblReq));
|
||||
|
||||
pMeta = pCxt->pTableMeta;
|
||||
pCxt->pTableMeta = NULL;
|
||||
|
||||
if (TK_NK_LP == sToken.type) {
|
||||
// pSql -> field1_name, ...)
|
||||
CHECK_CODE(parseBoundColumns(pCxt, &dataBuf->boundColumnInfo, getTableColumnSchema(pCxt->pTableMeta)));
|
||||
CHECK_CODE(parseBoundColumns(pCxt, &dataBuf->boundColumnInfo, getTableColumnSchema(pMeta)));
|
||||
NEXT_TOKEN(pCxt->pSql, sToken);
|
||||
}
|
||||
|
||||
|
@ -1154,10 +1169,9 @@ static int32_t parseInsertBody(SInsertParseContext* pCxt) {
|
|||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
memcpy(tags, &pCxt->tags, sizeof(pCxt->tags));
|
||||
(*pCxt->pStmtCb->setBindInfoFn)(pCxt->pStmtCb->pStmt, pCxt->pTableMeta, tags);
|
||||
memset(&pCxt->tags, 0, sizeof(pCxt->tags));
|
||||
(*pCxt->pStmtCb->setInfoFn)(pCxt->pStmtCb->pStmt, pMeta, tags, tbFName, autoCreateTbl, pCxt->pVgroupsHashObj, pCxt->pTableBlockHashObj);
|
||||
|
||||
(*pCxt->pStmtCb->setExecInfoFn)(pCxt->pStmtCb->pStmt, pCxt->pVgroupsHashObj, pCxt->pTableBlockHashObj);
|
||||
memset(&pCxt->tags, 0, sizeof(pCxt->tags));
|
||||
pCxt->pVgroupsHashObj = NULL;
|
||||
pCxt->pTableBlockHashObj = NULL;
|
||||
pCxt->pTableMeta = NULL;
|
||||
|
@ -1184,7 +1198,8 @@ int32_t parseInsertSql(SParseContext* pContext, SQuery** pQuery) {
|
|||
.pSql = (char*)pContext->pSql,
|
||||
.msg = {.buf = pContext->pMsg, .len = pContext->msgLen},
|
||||
.pTableMeta = NULL,
|
||||
.pSubTableHashObj = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), true, false),
|
||||
.pSubTableHashObj = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), true, HASH_NO_LOCK),
|
||||
.pTableNameHashObj = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), true, HASH_NO_LOCK),
|
||||
.totalNum = 0,
|
||||
.pOutput = (SVnodeModifOpStmt*)nodesMakeNode(QUERY_NODE_VNODE_MODIF_STMT),
|
||||
.pStmtCb = pContext->pStmtCb};
|
||||
|
@ -1193,12 +1208,13 @@ int32_t parseInsertSql(SParseContext* pContext, SQuery** pQuery) {
|
|||
(*pContext->pStmtCb->getExecInfoFn)(pContext->pStmtCb->pStmt, &context.pVgroupsHashObj,
|
||||
&context.pTableBlockHashObj);
|
||||
} else {
|
||||
context.pVgroupsHashObj = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, false);
|
||||
context.pTableBlockHashObj = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
||||
context.pVgroupsHashObj = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_NO_LOCK);
|
||||
context.pTableBlockHashObj =
|
||||
taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK);
|
||||
}
|
||||
|
||||
if (NULL == context.pVgroupsHashObj || NULL == context.pTableBlockHashObj || NULL == context.pSubTableHashObj ||
|
||||
NULL == context.pOutput) {
|
||||
NULL == context.pTableNameHashObj || NULL == context.pOutput) {
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
|
@ -1211,6 +1227,10 @@ int32_t parseInsertSql(SParseContext* pContext, SQuery** pQuery) {
|
|||
if (NULL == *pQuery) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
(*pQuery)->pTableList = taosArrayInit(taosHashGetSize(context.pTableNameHashObj), sizeof(SName));
|
||||
if (NULL == (*pQuery)->pTableList) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
(*pQuery)->execMode = QUERY_EXEC_MODE_SCHEDULE;
|
||||
(*pQuery)->haveResultSet = false;
|
||||
(*pQuery)->msgType = TDMT_VND_SUBMIT;
|
||||
|
@ -1223,6 +1243,13 @@ int32_t parseInsertSql(SParseContext* pContext, SQuery** pQuery) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = parseInsertBody(&context);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
SName* pTable = taosHashIterate(context.pTableNameHashObj, NULL);
|
||||
while (NULL != pTable) {
|
||||
taosArrayPush((*pQuery)->pTableList, pTable);
|
||||
pTable = taosHashIterate(context.pTableNameHashObj, pTable);
|
||||
}
|
||||
}
|
||||
destroyInsertParseContext(&context);
|
||||
return code;
|
||||
}
|
||||
|
@ -1273,9 +1300,10 @@ int32_t qBuildStmtOutput(SQuery* pQuery, SHashObj* pVgHash, SHashObj* pBlockHash
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t qBindStmtTagsValue(void *pBlock, void *boundTags, int64_t suid, char *tName, TAOS_MULTI_BIND *bind, char *msgBuf, int32_t msgBufLen){
|
||||
STableDataBlocks *pDataBlock = (STableDataBlocks *)pBlock;
|
||||
SMsgBuf pBuf = {.buf = msgBuf, .len = msgBufLen};
|
||||
int32_t qBindStmtTagsValue(void* pBlock, void* boundTags, int64_t suid, char* tName, TAOS_MULTI_BIND* bind,
|
||||
char* msgBuf, int32_t msgBufLen) {
|
||||
STableDataBlocks* pDataBlock = (STableDataBlocks*)pBlock;
|
||||
SMsgBuf pBuf = {.buf = msgBuf, .len = msgBufLen};
|
||||
SParsedDataColInfo* tags = (SParsedDataColInfo*)boundTags;
|
||||
if (NULL == tags) {
|
||||
return TSDB_CODE_QRY_APP_ERROR;
|
||||
|
@ -1389,7 +1417,6 @@ int32_t qBindStmtColsValue(void* pBlock, TAOS_MULTI_BIND* bind, char* msgBuf, in
|
|||
tdSRowPrint(row, pSTSchema, __func__);
|
||||
taosMemoryFree(pSTSchema);
|
||||
#endif
|
||||
|
||||
pDataBlock->size += extendedRowSize;
|
||||
}
|
||||
|
||||
|
@ -1550,16 +1577,16 @@ int32_t qBuildStmtColFields(void* pBlock, int32_t* fieldNum, TAOS_FIELD** fields
|
|||
// schemaless logic start
|
||||
|
||||
typedef struct SmlExecHandle {
|
||||
SHashObj* pBlockHash;
|
||||
SHashObj* pBlockHash;
|
||||
|
||||
SParsedDataColInfo tags; // each table
|
||||
SKVRowBuilder tagsBuilder; // each table
|
||||
SVCreateTbReq createTblReq; // each table
|
||||
SParsedDataColInfo tags; // each table
|
||||
SKVRowBuilder tagsBuilder; // each table
|
||||
SVCreateTbReq createTblReq; // each table
|
||||
|
||||
SQuery* pQuery;
|
||||
} SSmlExecHandle;
|
||||
|
||||
static int32_t smlBoundColumnData(SArray *cols, SParsedDataColInfo* pColList, SSchema* pSchema) {
|
||||
static int32_t smlBoundColumnData(SArray* cols, SParsedDataColInfo* pColList, SSchema* pSchema) {
|
||||
col_id_t nCols = pColList->numOfCols;
|
||||
|
||||
pColList->numOfBound = 0;
|
||||
|
@ -1572,8 +1599,8 @@ static int32_t smlBoundColumnData(SArray *cols, SParsedDataColInfo* pColList, SS
|
|||
bool isOrdered = true;
|
||||
col_id_t lastColIdx = -1; // last column found
|
||||
for (int i = 0; i < taosArrayGetSize(cols); ++i) {
|
||||
SSmlKv *kv = taosArrayGetP(cols, i);
|
||||
SToken sToken = {.n=kv->keyLen, .z=(char*)kv->key};
|
||||
SSmlKv* kv = taosArrayGetP(cols, i);
|
||||
SToken sToken = {.n = kv->keyLen, .z = (char*)kv->key};
|
||||
col_id_t t = lastColIdx + 1;
|
||||
col_id_t index = findCol(&sToken, t, nCols, pSchema);
|
||||
if (index < 0 && t > 0) {
|
||||
|
@ -1622,7 +1649,7 @@ static int32_t smlBoundColumnData(SArray *cols, SParsedDataColInfo* pColList, SS
|
|||
qsort(pColIdx, pColList->numOfBound, sizeof(SBoundIdxInfo), boundIdxCompar);
|
||||
}
|
||||
|
||||
if(pColList->numOfCols > pColList->numOfBound){
|
||||
if (pColList->numOfCols > pColList->numOfBound) {
|
||||
memset(&pColList->boundColumns[pColList->numOfBound], 0,
|
||||
sizeof(col_id_t) * (pColList->numOfCols - pColList->numOfBound));
|
||||
}
|
||||
|
@ -1630,22 +1657,22 @@ static int32_t smlBoundColumnData(SArray *cols, SParsedDataColInfo* pColList, SS
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t smlBuildTagRow(SArray *cols, SKVRowBuilder *tagsBuilder, SParsedDataColInfo* tags, SSchema* pSchema, SKVRow *row, SMsgBuf *msg) {
|
||||
static int32_t smlBuildTagRow(SArray* cols, SKVRowBuilder* tagsBuilder, SParsedDataColInfo* tags, SSchema* pSchema,
|
||||
SKVRow* row, SMsgBuf* msg) {
|
||||
if (tdInitKVRowBuilder(tagsBuilder) < 0) {
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
SKvParam param = {.builder = tagsBuilder};
|
||||
for (int i = 0; i < tags->numOfBound; ++i) {
|
||||
SSchema* pTagSchema = &pSchema[tags->boundColumns[i] - 1]; // colId starts with 1
|
||||
SSchema* pTagSchema = &pSchema[tags->boundColumns[i] - 1]; // colId starts with 1
|
||||
param.schema = pTagSchema;
|
||||
SSmlKv *kv = taosArrayGetP(cols, i);
|
||||
KvRowAppend(msg, kv->value, kv->valueLen, ¶m) ;
|
||||
SSmlKv* kv = taosArrayGetP(cols, i);
|
||||
KvRowAppend(msg, kv->value, kv->valueLen, ¶m);
|
||||
}
|
||||
|
||||
|
||||
*row = tdGetKVRowFromBuilder(tagsBuilder);
|
||||
if(*row == NULL){
|
||||
if (*row == NULL) {
|
||||
return TSDB_CODE_SML_INVALID_DATA;
|
||||
}
|
||||
tdSortKVRowByColIdx(*row);
|
||||
|
@ -1656,27 +1683,27 @@ int32_t smlBindData(void *handle, SArray *tags, SArray *colsSchema, SArray *cols
|
|||
STableMeta *pTableMeta, char *tableName, char *msgBuf, int16_t msgBufLen) {
|
||||
SMsgBuf pBuf = {.buf = msgBuf, .len = msgBufLen};
|
||||
|
||||
SSmlExecHandle *smlHandle = (SSmlExecHandle *)handle;
|
||||
SSchema* pTagsSchema = getTableTagSchema(pTableMeta);
|
||||
SSmlExecHandle* smlHandle = (SSmlExecHandle*)handle;
|
||||
SSchema* pTagsSchema = getTableTagSchema(pTableMeta);
|
||||
setBoundColumnInfo(&smlHandle->tags, pTagsSchema, getNumOfTags(pTableMeta));
|
||||
int ret = smlBoundColumnData(tags, &smlHandle->tags, pTagsSchema);
|
||||
if(ret != TSDB_CODE_SUCCESS){
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
buildInvalidOperationMsg(&pBuf, "bound tags error");
|
||||
return ret;
|
||||
}
|
||||
SKVRow row = NULL;
|
||||
ret = smlBuildTagRow(tags, &smlHandle->tagsBuilder, &smlHandle->tags, pTagsSchema, &row, &pBuf);
|
||||
if(ret != TSDB_CODE_SUCCESS){
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
buildCreateTbReq(&smlHandle->createTblReq, tableName, row, pTableMeta->suid);
|
||||
|
||||
STableDataBlocks* pDataBlock = NULL;
|
||||
ret = getDataBlockFromList(smlHandle->pBlockHash, pTableMeta->uid, TSDB_DEFAULT_PAYLOAD_SIZE,
|
||||
sizeof(SSubmitBlk), getTableInfo(pTableMeta).rowSize, pTableMeta,
|
||||
&pDataBlock, NULL, &smlHandle->createTblReq);
|
||||
if(ret != TSDB_CODE_SUCCESS){
|
||||
ret = getDataBlockFromList(smlHandle->pBlockHash, &pTableMeta->uid, sizeof(pTableMeta->uid),
|
||||
TSDB_DEFAULT_PAYLOAD_SIZE, sizeof(SSubmitBlk), getTableInfo(pTableMeta).rowSize,
|
||||
pTableMeta, &pDataBlock, NULL, &smlHandle->createTblReq);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
buildInvalidOperationMsg(&pBuf, "create data block error");
|
||||
return ret;
|
||||
}
|
||||
|
@ -1684,14 +1711,14 @@ int32_t smlBindData(void *handle, SArray *tags, SArray *colsSchema, SArray *cols
|
|||
SSchema* pSchema = getTableColumnSchema(pTableMeta);
|
||||
|
||||
ret = smlBoundColumnData(colsSchema, &pDataBlock->boundColumnInfo, pSchema);
|
||||
if(ret != TSDB_CODE_SUCCESS){
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
buildInvalidOperationMsg(&pBuf, "bound cols error");
|
||||
return ret;
|
||||
}
|
||||
int32_t extendedRowSize = getExtendedRowSize(pDataBlock);
|
||||
int32_t extendedRowSize = getExtendedRowSize(pDataBlock);
|
||||
SParsedDataColInfo* spd = &pDataBlock->boundColumnInfo;
|
||||
SRowBuilder* pBuilder = &pDataBlock->rowBuilder;
|
||||
SMemParam param = {.rb = pBuilder};
|
||||
SMemParam param = {.rb = pBuilder};
|
||||
|
||||
initRowBuilder(&pDataBlock->rowBuilder, pDataBlock->pTableMeta->sversion, &pDataBlock->boundColumnInfo);
|
||||
|
||||
|
@ -1700,7 +1727,7 @@ int32_t smlBindData(void *handle, SArray *tags, SArray *colsSchema, SArray *cols
|
|||
return buildInvalidOperationMsg(&pBuf, "cols size <= 0");
|
||||
}
|
||||
ret = allocateMemForSize(pDataBlock, extendedRowSize * rowNum);
|
||||
if(ret != TSDB_CODE_SUCCESS){
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
buildInvalidOperationMsg(&pBuf, "allocate memory error");
|
||||
return ret;
|
||||
}
|
||||
|
@ -1720,19 +1747,20 @@ int32_t smlBindData(void *handle, SArray *tags, SArray *colsSchema, SArray *cols
|
|||
param.schema = pColSchema;
|
||||
getSTSRowAppendInfo(pBuilder->rowType, spd, c, ¶m.toffset, ¶m.colIdx);
|
||||
|
||||
SSmlKv *kv = NULL;
|
||||
if(format){
|
||||
if(j < rowDataSize){
|
||||
SSmlKv* kv = NULL;
|
||||
if (format) {
|
||||
if (j < rowDataSize) {
|
||||
kv = taosArrayGetP(rowData, j);
|
||||
if (rowDataSize != spd->numOfBound && (kv->keyLen != strlen(pColSchema->name) || strncmp(kv->key, pColSchema->name, kv->keyLen) != 0)){
|
||||
if (rowDataSize != spd->numOfBound &&
|
||||
(kv->keyLen != strlen(pColSchema->name) || strncmp(kv->key, pColSchema->name, kv->keyLen) != 0)) {
|
||||
kv = NULL;
|
||||
}else{
|
||||
} else {
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
void **p =taosHashGet(rowData, pColSchema->name, strlen(pColSchema->name));
|
||||
if(p) kv = *p;
|
||||
} else {
|
||||
void** p = taosHashGet(rowData, pColSchema->name, strlen(pColSchema->name));
|
||||
if (p) kv = *p;
|
||||
}
|
||||
|
||||
if (!kv || kv->length == 0) {
|
||||
|
@ -1741,7 +1769,7 @@ int32_t smlBindData(void *handle, SArray *tags, SArray *colsSchema, SArray *cols
|
|||
int32_t colLen = pColSchema->bytes;
|
||||
if (IS_VAR_DATA_TYPE(pColSchema->type)) {
|
||||
colLen = kv->length;
|
||||
} else if(pColSchema->type == TSDB_DATA_TYPE_TIMESTAMP){
|
||||
} else if (pColSchema->type == TSDB_DATA_TYPE_TIMESTAMP) {
|
||||
kv->i = convertTimePrecision(kv->i, TSDB_TIME_PRECISION_NANO, pTableMeta->tableInfo.precision);
|
||||
}
|
||||
|
||||
|
@ -1750,7 +1778,7 @@ int32_t smlBindData(void *handle, SArray *tags, SArray *colsSchema, SArray *cols
|
|||
|
||||
if (PRIMARYKEY_TIMESTAMP_COL_ID == pColSchema->colId) {
|
||||
TSKEY tsKey = TD_ROW_KEY(row);
|
||||
checkTimestamp(pDataBlock, (const char *)&tsKey);
|
||||
checkTimestamp(pDataBlock, (const char*)&tsKey);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1767,7 +1795,7 @@ int32_t smlBindData(void *handle, SArray *tags, SArray *colsSchema, SArray *cols
|
|||
pDataBlock->size += extendedRowSize;
|
||||
}
|
||||
|
||||
SSubmitBlk *pBlocks = (SSubmitBlk *)(pDataBlock->pData);
|
||||
SSubmitBlk* pBlocks = (SSubmitBlk*)(pDataBlock->pData);
|
||||
if (TSDB_CODE_SUCCESS != setBlockInfo(pBlocks, pDataBlock, rowNum)) {
|
||||
return buildInvalidOperationMsg(&pBuf, "too many rows in sql, total number of rows should be less than 32767");
|
||||
}
|
||||
|
@ -1775,25 +1803,24 @@ int32_t smlBindData(void *handle, SArray *tags, SArray *colsSchema, SArray *cols
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
void* smlInitHandle(SQuery *pQuery){
|
||||
SSmlExecHandle *handle = taosMemoryCalloc(1, sizeof(SSmlExecHandle));
|
||||
if(!handle) return NULL;
|
||||
void* smlInitHandle(SQuery* pQuery) {
|
||||
SSmlExecHandle* handle = taosMemoryCalloc(1, sizeof(SSmlExecHandle));
|
||||
if (!handle) return NULL;
|
||||
handle->pBlockHash = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
||||
handle->pQuery = pQuery;
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void smlDestroyHandle(void *pHandle){
|
||||
if(!pHandle) return;
|
||||
SSmlExecHandle *handle = (SSmlExecHandle *)pHandle;
|
||||
void smlDestroyHandle(void* pHandle) {
|
||||
if (!pHandle) return;
|
||||
SSmlExecHandle* handle = (SSmlExecHandle*)pHandle;
|
||||
destroyBlockHashmap(handle->pBlockHash);
|
||||
taosMemoryFree(handle);
|
||||
}
|
||||
|
||||
int32_t smlBuildOutput(void* handle, SHashObj* pVgHash) {
|
||||
SSmlExecHandle *smlHandle = (SSmlExecHandle *)handle;
|
||||
SSmlExecHandle* smlHandle = (SSmlExecHandle*)handle;
|
||||
return qBuildStmtOutput(smlHandle->pQuery, pVgHash, smlHandle->pBlockHash);
|
||||
}
|
||||
// schemaless logic end
|
||||
|
||||
|
|
|
@ -137,7 +137,7 @@ static int32_t createDataBlock(size_t defaultSize, int32_t rowSize, int32_t star
|
|||
}
|
||||
memset(dataBuf->pData, 0, sizeof(SSubmitBlk));
|
||||
|
||||
dataBuf->pTableMeta = pTableMeta;
|
||||
dataBuf->pTableMeta = tableMetaDup(pTableMeta);
|
||||
|
||||
SParsedDataColInfo* pColInfo = &dataBuf->boundColumnInfo;
|
||||
SSchema* pSchema = getTableColumnSchema(dataBuf->pTableMeta);
|
||||
|
@ -185,11 +185,11 @@ int32_t buildCreateTbMsg(STableDataBlocks* pBlocks, SVCreateTbReq* pCreateTbReq)
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t getDataBlockFromList(SHashObj* pHashList, int64_t id, int32_t size, int32_t startOffset, int32_t rowSize,
|
||||
int32_t getDataBlockFromList(SHashObj* pHashList, void* id, int32_t idLen, int32_t size, int32_t startOffset, int32_t rowSize,
|
||||
STableMeta* pTableMeta, STableDataBlocks** dataBlocks, SArray* pBlockList,
|
||||
SVCreateTbReq* pCreateTbReq) {
|
||||
*dataBlocks = NULL;
|
||||
STableDataBlocks** t1 = (STableDataBlocks**)taosHashGet(pHashList, (const char*)&id, sizeof(id));
|
||||
STableDataBlocks** t1 = (STableDataBlocks**)taosHashGet(pHashList, (const char*)id, idLen);
|
||||
if (t1 != NULL) {
|
||||
*dataBlocks = *t1;
|
||||
}
|
||||
|
@ -207,7 +207,7 @@ int32_t getDataBlockFromList(SHashObj* pHashList, int64_t id, int32_t size, int3
|
|||
}
|
||||
}
|
||||
|
||||
taosHashPut(pHashList, (const char*)&id, sizeof(int64_t), (char*)dataBlocks, POINTER_BYTES);
|
||||
taosHashPut(pHashList, (const char*)id, idLen, (char*)dataBlocks, POINTER_BYTES);
|
||||
if (pBlockList) {
|
||||
taosArrayPush(pBlockList, dataBlocks);
|
||||
}
|
||||
|
@ -445,7 +445,7 @@ int32_t mergeTableDataBlocks(SHashObj* pHashObj, uint8_t payloadType, SArray** p
|
|||
const int INSERT_HEAD_SIZE = sizeof(SSubmitReq);
|
||||
int code = 0;
|
||||
bool isRawPayload = IS_RAW_PAYLOAD(payloadType);
|
||||
SHashObj* pVnodeDataBlockHashList = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
||||
SHashObj* pVnodeDataBlockHashList = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, false);
|
||||
SArray* pVnodeDataBlockList = taosArrayInit(8, POINTER_BYTES);
|
||||
|
||||
STableDataBlocks** p = taosHashIterate(pHashObj, NULL);
|
||||
|
@ -457,7 +457,7 @@ int32_t mergeTableDataBlocks(SHashObj* pHashObj, uint8_t payloadType, SArray** p
|
|||
STableDataBlocks* dataBuf = NULL;
|
||||
pOneTableBlock->pTableMeta->vgId = pOneTableBlock->vgId; // for schemaless, restore origin vgId
|
||||
int32_t ret =
|
||||
getDataBlockFromList(pVnodeDataBlockHashList, pOneTableBlock->vgId, TSDB_PAYLOAD_SIZE, INSERT_HEAD_SIZE, 0,
|
||||
getDataBlockFromList(pVnodeDataBlockHashList, &pOneTableBlock->vgId, sizeof(pOneTableBlock->vgId), TSDB_PAYLOAD_SIZE, INSERT_HEAD_SIZE, 0,
|
||||
pOneTableBlock->pTableMeta, &dataBuf, pVnodeDataBlockList, NULL);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
taosHashCleanup(pVnodeDataBlockHashList);
|
||||
|
@ -465,7 +465,7 @@ int32_t mergeTableDataBlocks(SHashObj* pHashObj, uint8_t payloadType, SArray** p
|
|||
taosMemoryFreeClear(blkKeyInfo.pKeyTuple);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ASSERT(pOneTableBlock->pTableMeta->tableInfo.rowSize > 0);
|
||||
// the maximum expanded size in byte when a row-wise data is converted to SDataRow format
|
||||
int32_t expandSize = isRawPayload ? getRowExpandSize(pOneTableBlock->pTableMeta) : 0;
|
||||
int64_t destSize = dataBuf->size + pOneTableBlock->size + pBlocks->numOfRows * expandSize +
|
||||
|
@ -620,7 +620,7 @@ int32_t qCloneStmtDataBlock(void** pDst, void* pSrc) {
|
|||
return qResetStmtDataBlock(*pDst, false);
|
||||
}
|
||||
|
||||
int32_t qRebuildStmtDataBlock(void** pDst, void* pSrc) {
|
||||
int32_t qRebuildStmtDataBlock(void** pDst, void* pSrc, uint64_t uid, int32_t vgId) {
|
||||
int32_t code = qCloneStmtDataBlock(pDst, pSrc);
|
||||
if (code) {
|
||||
return code;
|
||||
|
@ -633,11 +633,22 @@ int32_t qRebuildStmtDataBlock(void** pDst, void* pSrc) {
|
|||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
pBlock->vgId = vgId;
|
||||
|
||||
if (pBlock->pTableMeta) {
|
||||
pBlock->pTableMeta->uid = uid;
|
||||
pBlock->pTableMeta->vgId = vgId;
|
||||
}
|
||||
|
||||
memset(pBlock->pData, 0, sizeof(SSubmitBlk));
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
STableMeta *qGetTableMetaInDataBlock(void* pDataBlock) {
|
||||
return ((STableDataBlocks*)pDataBlock)->pTableMeta;
|
||||
}
|
||||
|
||||
void qFreeStmtDataBlock(void* pDataBlock) {
|
||||
if (pDataBlock == NULL) {
|
||||
return;
|
||||
|
|
|
@ -368,11 +368,15 @@ static int32_t createColumnsByTable(STranslateContext* pCxt, const STableNode* p
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static bool isInternalPrimaryKey(const SColumnNode* pCol) {
|
||||
return PRIMARYKEY_TIMESTAMP_COL_ID == pCol->colId && 0 == strcmp(pCol->colName, PK_TS_COL_INTERNAL_NAME);
|
||||
}
|
||||
|
||||
static bool findAndSetColumn(SColumnNode* pCol, const STableNode* pTable) {
|
||||
bool found = false;
|
||||
if (QUERY_NODE_REAL_TABLE == nodeType(pTable)) {
|
||||
const STableMeta* pMeta = ((SRealTableNode*)pTable)->pMeta;
|
||||
if (PRIMARYKEY_TIMESTAMP_COL_ID == pCol->colId && 0 == strcmp(pCol->colName, PK_TS_COL_INTERNAL_NAME)) {
|
||||
if (isInternalPrimaryKey(pCol)) {
|
||||
setColumnInfoBySchema((SRealTableNode*)pTable, pMeta->schema, false, pCol);
|
||||
return true;
|
||||
}
|
||||
|
@ -389,7 +393,9 @@ static bool findAndSetColumn(SColumnNode* pCol, const STableNode* pTable) {
|
|||
SNode* pNode;
|
||||
FOREACH(pNode, pProjectList) {
|
||||
SExprNode* pExpr = (SExprNode*)pNode;
|
||||
if (0 == strcmp(pCol->colName, pExpr->aliasName)) {
|
||||
if (0 == strcmp(pCol->colName, pExpr->aliasName) ||
|
||||
((QUERY_NODE_COLUMN == nodeType(pExpr) && PRIMARYKEY_TIMESTAMP_COL_ID == ((SColumnNode*)pExpr)->colId) &&
|
||||
isInternalPrimaryKey(pCol))) {
|
||||
setColumnInfoByExpr(pTable, pExpr, pCol);
|
||||
found = true;
|
||||
break;
|
||||
|
@ -433,7 +439,11 @@ static EDealRes translateColumnWithoutPrefix(STranslateContext* pCxt, SColumnNod
|
|||
}
|
||||
}
|
||||
if (!found) {
|
||||
return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_INVALID_COLUMN, pCol->colName);
|
||||
if (isInternalPrimaryKey(pCol)) {
|
||||
return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_INVALID_INTERNAL_PK);
|
||||
} else {
|
||||
return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_INVALID_COLUMN, pCol->colName);
|
||||
}
|
||||
}
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
@ -1886,6 +1896,9 @@ static int32_t checkDbKeepOption(STranslateContext* pCxt, SDatabaseOptions* pOpt
|
|||
TIME_UNIT_DAY != pVal->unit) {
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_KEEP_UNIT, pVal->unit);
|
||||
}
|
||||
if (!pVal->isDuration) {
|
||||
pVal->datum.i = pVal->datum.i * 1440;
|
||||
}
|
||||
}
|
||||
|
||||
pOptions->keep[0] = getBigintFromValueNode((SValueNode*)nodesListGetNode(pOptions->pKeep, 0));
|
||||
|
@ -2138,7 +2151,7 @@ static int32_t columnDefNodeToField(SNodeList* pList, SArray** pArray) {
|
|||
SField field = {.type = pCol->dataType.type, .bytes = calcTypeBytes(pCol->dataType)};
|
||||
strcpy(field.name, pCol->colName);
|
||||
if (pCol->sma) {
|
||||
field.flags |= SCHEMA_SMA_ON;
|
||||
field.flags |= COL_SMA_ON;
|
||||
}
|
||||
taosArrayPush(*pArray, &field);
|
||||
}
|
||||
|
@ -2321,7 +2334,7 @@ static int32_t checkCreateTable(STranslateContext* pCxt, SCreateTableStmt* pStmt
|
|||
static void toSchema(const SColumnDefNode* pCol, col_id_t colId, SSchema* pSchema) {
|
||||
int8_t flags = 0;
|
||||
if (pCol->sma) {
|
||||
flags |= SCHEMA_SMA_ON;
|
||||
flags |= COL_SMA_ON;
|
||||
}
|
||||
pSchema->colId = colId;
|
||||
pSchema->type = pCol->dataType.type;
|
||||
|
@ -3652,6 +3665,9 @@ static int32_t buildNormalTableBatchReq(int32_t acctId, const SCreateTableStmt*
|
|||
destroyCreateTbReq(&req);
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
if (pStmt->ignoreExists) {
|
||||
req.flags |= TD_CREATE_IF_NOT_EXISTS;
|
||||
}
|
||||
SNode* pCol;
|
||||
col_id_t index = 0;
|
||||
FOREACH(pCol, pStmt->pCols) {
|
||||
|
@ -3782,24 +3798,27 @@ static int32_t rewriteCreateTable(STranslateContext* pCxt, SQuery* pQuery) {
|
|||
return code;
|
||||
}
|
||||
|
||||
static void addCreateTbReqIntoVgroup(int32_t acctId, SHashObj* pVgroupHashmap, const char* pDbName,
|
||||
const char* pTableName, SKVRow row, uint64_t suid, SVgroupInfo* pVgInfo) {
|
||||
static void addCreateTbReqIntoVgroup(int32_t acctId, SHashObj* pVgroupHashmap, SCreateSubTableClause* pStmt, SKVRow row,
|
||||
uint64_t suid, SVgroupInfo* pVgInfo) {
|
||||
char dbFName[TSDB_DB_FNAME_LEN] = {0};
|
||||
SName name = {.type = TSDB_DB_NAME_T, .acctId = acctId};
|
||||
strcpy(name.dbname, pDbName);
|
||||
strcpy(name.dbname, pStmt->dbName);
|
||||
tNameGetFullDbName(&name, dbFName);
|
||||
|
||||
struct SVCreateTbReq req = {0};
|
||||
req.type = TD_CHILD_TABLE;
|
||||
req.name = strdup(pTableName);
|
||||
req.name = strdup(pStmt->tableName);
|
||||
req.ctb.suid = suid;
|
||||
req.ctb.pTag = row;
|
||||
if (pStmt->ignoreExists) {
|
||||
req.flags |= TD_CREATE_IF_NOT_EXISTS;
|
||||
}
|
||||
|
||||
SVgroupCreateTableBatch* pTableBatch = taosHashGet(pVgroupHashmap, &pVgInfo->vgId, sizeof(pVgInfo->vgId));
|
||||
if (pTableBatch == NULL) {
|
||||
SVgroupCreateTableBatch tBatch = {0};
|
||||
tBatch.info = *pVgInfo;
|
||||
strcpy(tBatch.dbName, pDbName);
|
||||
strcpy(tBatch.dbName, pStmt->dbName);
|
||||
|
||||
tBatch.req.pArray = taosArrayInit(4, sizeof(struct SVCreateTbReq));
|
||||
taosArrayPush(tBatch.req.pArray, &req);
|
||||
|
@ -3961,8 +3980,7 @@ static int32_t rewriteCreateSubTable(STranslateContext* pCxt, SCreateSubTableCla
|
|||
code = getTableHashVgroup(pCxt, pStmt->dbName, pStmt->tableName, &info);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
addCreateTbReqIntoVgroup(pCxt->pParseCxt->acctId, pVgroupHashmap, pStmt->dbName, pStmt->tableName, row,
|
||||
pSuperTableMeta->uid, &info);
|
||||
addCreateTbReqIntoVgroup(pCxt->pParseCxt->acctId, pVgroupHashmap, pStmt, row, pSuperTableMeta->uid, &info);
|
||||
}
|
||||
|
||||
taosMemoryFreeClear(pSuperTableMeta);
|
||||
|
|
|
@ -146,6 +146,8 @@ static char* getSyntaxErrFormat(int32_t errCode) {
|
|||
return "Invalid binary/nchar column length";
|
||||
case TSDB_CODE_PAR_INVALID_TAGS_NUM:
|
||||
return "Invalid number of tag columns";
|
||||
case TSDB_CODE_PAR_INVALID_INTERNAL_PK:
|
||||
return "Invalid _c0 or _rowts expression";
|
||||
case TSDB_CODE_OUT_OF_MEMORY:
|
||||
return "Out of memory";
|
||||
default:
|
||||
|
@ -191,7 +193,7 @@ int32_t buildSyntaxErrMsg(SMsgBuf* pBuf, const char* additionalInfo, const char*
|
|||
return TSDB_CODE_TSC_SQL_SYNTAX_ERROR;
|
||||
}
|
||||
|
||||
SSchema *getTableColumnSchema(const STableMeta *pTableMeta) {
|
||||
SSchema* getTableColumnSchema(const STableMeta* pTableMeta) {
|
||||
assert(pTableMeta != NULL);
|
||||
return (SSchema*)pTableMeta->schema;
|
||||
}
|
||||
|
@ -226,6 +228,23 @@ STableComInfo getTableInfo(const STableMeta* pTableMeta) {
|
|||
return pTableMeta->tableInfo;
|
||||
}
|
||||
|
||||
static uint32_t getTableMetaSize(const STableMeta* pTableMeta) {
|
||||
int32_t totalCols = 0;
|
||||
if (pTableMeta->tableInfo.numOfColumns >= 0) {
|
||||
totalCols = pTableMeta->tableInfo.numOfColumns + pTableMeta->tableInfo.numOfTags;
|
||||
}
|
||||
|
||||
return sizeof(STableMeta) + totalCols * sizeof(SSchema);
|
||||
}
|
||||
|
||||
STableMeta* tableMetaDup(const STableMeta* pTableMeta) {
|
||||
size_t size = getTableMetaSize(pTableMeta);
|
||||
|
||||
STableMeta* p = taosMemoryMalloc(size);
|
||||
memcpy(p, pTableMeta, size);
|
||||
return p;
|
||||
}
|
||||
|
||||
int32_t trimString(const char* src, int32_t len, char* dst, int32_t dlen) {
|
||||
if (len <= 0 || dlen <= 0) return 0;
|
||||
|
||||
|
|
|
@ -39,16 +39,99 @@ static int32_t parseSqlIntoAst(SParseContext* pCxt, SQuery** pQuery) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = authenticate(pCxt, *pQuery);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
if (TSDB_CODE_SUCCESS == code && 0 == (*pQuery)->placeholderNum) {
|
||||
code = translate(pCxt, *pQuery);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
if (TSDB_CODE_SUCCESS == code && 0 == (*pQuery)->placeholderNum) {
|
||||
code = calculateConstant(pCxt, *pQuery);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t qParseQuerySql(SParseContext* pCxt, SQuery** pQuery) {
|
||||
static int32_t setValueByBindParam(SValueNode* pVal, TAOS_MULTI_BIND* pParam) {
|
||||
if (pParam->is_null && 1 == *(pParam->is_null)) {
|
||||
pVal->node.resType.type = TSDB_DATA_TYPE_NULL;
|
||||
pVal->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_NULL].bytes;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
int32_t inputSize = (NULL != pParam->length ? *(pParam->length) : tDataTypes[pParam->buffer_type].bytes);
|
||||
pVal->node.resType.type = pParam->buffer_type;
|
||||
pVal->node.resType.bytes = inputSize;
|
||||
switch (pParam->buffer_type) {
|
||||
case TSDB_DATA_TYPE_BOOL:
|
||||
pVal->datum.b = *((bool*)pParam->buffer);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_TINYINT:
|
||||
pVal->datum.i = *((int8_t*)pParam->buffer);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_SMALLINT:
|
||||
pVal->datum.i = *((int16_t*)pParam->buffer);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_INT:
|
||||
pVal->datum.i = *((int32_t*)pParam->buffer);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_BIGINT:
|
||||
pVal->datum.i = *((int64_t*)pParam->buffer);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_FLOAT:
|
||||
pVal->datum.d = *((float*)pParam->buffer);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_DOUBLE:
|
||||
pVal->datum.d = *((double*)pParam->buffer);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_VARCHAR:
|
||||
case TSDB_DATA_TYPE_VARBINARY:
|
||||
pVal->datum.p = taosMemoryCalloc(1, pVal->node.resType.bytes + VARSTR_HEADER_SIZE + 1);
|
||||
if (NULL == pVal->datum.p) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
varDataSetLen(pVal->datum.p, pVal->node.resType.bytes);
|
||||
strncpy(varDataVal(pVal->datum.p), (const char*)pParam->buffer, pVal->node.resType.bytes);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_NCHAR: {
|
||||
pVal->node.resType.bytes *= TSDB_NCHAR_SIZE;
|
||||
pVal->datum.p = taosMemoryCalloc(1, pVal->node.resType.bytes + VARSTR_HEADER_SIZE + 1);
|
||||
if (NULL == pVal->datum.p) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
int32_t output = 0;
|
||||
if (!taosMbsToUcs4(pParam->buffer, inputSize, (TdUcs4*)varDataVal(pVal->datum.p), pVal->node.resType.bytes,
|
||||
&output)) {
|
||||
return errno;
|
||||
}
|
||||
varDataSetLen(pVal->datum.p, output);
|
||||
pVal->node.resType.bytes = output;
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||
pVal->datum.i = *((int64_t*)pParam->buffer);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_UTINYINT:
|
||||
pVal->datum.u = *((uint8_t*)pParam->buffer);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_USMALLINT:
|
||||
pVal->datum.u = *((uint16_t*)pParam->buffer);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_UINT:
|
||||
pVal->datum.u = *((uint32_t*)pParam->buffer);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_UBIGINT:
|
||||
pVal->datum.u = *((uint64_t*)pParam->buffer);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_JSON:
|
||||
case TSDB_DATA_TYPE_DECIMAL:
|
||||
case TSDB_DATA_TYPE_BLOB:
|
||||
case TSDB_DATA_TYPE_MEDIUMBLOB:
|
||||
// todo
|
||||
default:
|
||||
break;
|
||||
}
|
||||
pVal->translate = true;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t qParseSql(SParseContext* pCxt, SQuery** pQuery) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
if (isInsertSql(pCxt->pSql, pCxt->sqlLen)) {
|
||||
code = parseInsertSql(pCxt, pQuery);
|
||||
|
@ -77,3 +160,29 @@ void qDestroyQuery(SQuery* pQueryNode) {
|
|||
int32_t qExtractResultSchema(const SNode* pRoot, int32_t* numOfCols, SSchema** pSchema) {
|
||||
return extractResultSchema(pRoot, numOfCols, pSchema);
|
||||
}
|
||||
|
||||
int32_t qStmtBindParams(SQuery* pQuery, TAOS_MULTI_BIND* pParams, int32_t colIdx, uint64_t queryId) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
|
||||
if (colIdx < 0) {
|
||||
int32_t size = taosArrayGetSize(pQuery->pPlaceholderValues);
|
||||
for (int32_t i = 0; i < size; ++i) {
|
||||
code = setValueByBindParam((SValueNode*)taosArrayGetP(pQuery->pPlaceholderValues, i), pParams + i);
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
return code;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
code = setValueByBindParam((SValueNode*)taosArrayGetP(pQuery->pPlaceholderValues, colIdx), pParams);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t qStmtParseQuerySql(SParseContext* pCxt, SQuery* pQuery) {
|
||||
int32_t code = translate(pCxt, pQuery);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = calculateConstant(pCxt, pQuery);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* 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.
|
||||
* 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
|
||||
|
@ -14,6 +14,7 @@
|
|||
*/
|
||||
|
||||
#include "parTestUtil.h"
|
||||
#include "ttime.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -26,72 +27,226 @@ class ParserInitialCTest : public ParserDdlTest {};
|
|||
TEST_F(ParserInitialCTest, createAccount) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("create account ac_wxy pass '123456'", TSDB_CODE_PAR_EXPRIE_STATEMENT);
|
||||
run("CREATE ACCOUNT ac_wxy PASS '123456'", TSDB_CODE_PAR_EXPRIE_STATEMENT);
|
||||
}
|
||||
|
||||
TEST_F(ParserInitialCTest, createBnode) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("create bnode on dnode 1");
|
||||
run("CREATE BNODE ON DNODE 1");
|
||||
}
|
||||
|
||||
/*
|
||||
* CREATE DATABASE [IF NOT EXISTS] db_name [database_options]
|
||||
*
|
||||
* database_options:
|
||||
* database_option ...
|
||||
*
|
||||
* database_option: {
|
||||
* BUFFER value
|
||||
* | CACHELAST value
|
||||
* | COMP {0 | 1 | 2}
|
||||
* | DAYS value
|
||||
* | FSYNC value
|
||||
* | MAXROWS value
|
||||
* | MINROWS value
|
||||
* | KEEP value
|
||||
* | PAGES value
|
||||
* | PAGESIZE value
|
||||
* | PRECISION {'ms' | 'us' | 'ns'}
|
||||
* | REPLICA value
|
||||
* | RETENTIONS ingestion_duration:keep_duration ...
|
||||
* | STRICT value
|
||||
* | WAL value
|
||||
* | VGROUPS value
|
||||
* | SINGLE_STABLE {0 | 1}
|
||||
* }
|
||||
*/
|
||||
TEST_F(ParserInitialCTest, createDatabase) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("create database wxy_db");
|
||||
SCreateDbReq expect = {0};
|
||||
|
||||
run("create database if not exists wxy_db "
|
||||
"cachelast 2 "
|
||||
"comp 1 "
|
||||
"days 100 "
|
||||
"fsync 100 "
|
||||
"maxrows 1000 "
|
||||
"minrows 100 "
|
||||
"keep 1440 "
|
||||
"precision 'ms' "
|
||||
"replica 3 "
|
||||
"wal 2 "
|
||||
"vgroups 100 "
|
||||
"single_stable 0 "
|
||||
"retentions 15s:7d,1m:21d,15m:5y");
|
||||
auto setCreateDbReqFunc = [&](const char* pDbname, int8_t igExists = 0) {
|
||||
memset(&expect, 0, sizeof(SCreateDbReq));
|
||||
int32_t len = snprintf(expect.db, sizeof(expect.db), "0.%s", pDbname);
|
||||
expect.db[len] = '\0';
|
||||
expect.ignoreExist = igExists;
|
||||
expect.buffer = TSDB_DEFAULT_BUFFER_PER_VNODE;
|
||||
expect.cacheLastRow = TSDB_DEFAULT_CACHE_LAST_ROW;
|
||||
expect.compression = TSDB_DEFAULT_COMP_LEVEL;
|
||||
expect.daysPerFile = TSDB_DEFAULT_DAYS_PER_FILE;
|
||||
expect.fsyncPeriod = TSDB_DEFAULT_FSYNC_PERIOD;
|
||||
expect.maxRows = TSDB_DEFAULT_MAXROWS_FBLOCK;
|
||||
expect.minRows = TSDB_DEFAULT_MINROWS_FBLOCK;
|
||||
expect.daysToKeep0 = TSDB_DEFAULT_KEEP;
|
||||
expect.daysToKeep1 = TSDB_DEFAULT_KEEP;
|
||||
expect.daysToKeep2 = TSDB_DEFAULT_KEEP;
|
||||
expect.pages = TSDB_DEFAULT_PAGES_PER_VNODE;
|
||||
expect.pageSize = TSDB_DEFAULT_PAGESIZE_PER_VNODE;
|
||||
expect.precision = TSDB_DEFAULT_PRECISION;
|
||||
expect.replications = TSDB_DEFAULT_DB_REPLICA;
|
||||
expect.strict = TSDB_DEFAULT_DB_STRICT;
|
||||
expect.walLevel = TSDB_DEFAULT_WAL_LEVEL;
|
||||
expect.numOfVgroups = TSDB_DEFAULT_VN_PER_DB;
|
||||
expect.numOfStables = TSDB_DEFAULT_DB_SINGLE_STABLE;
|
||||
};
|
||||
|
||||
run("create database if not exists wxy_db "
|
||||
"days 100m "
|
||||
"keep 1440m,300h,400d ");
|
||||
auto setDbBufferFunc = [&](int32_t buffer) { expect.buffer = buffer; };
|
||||
auto setDbCachelastFunc = [&](int8_t CACHELAST) { expect.cacheLastRow = CACHELAST; };
|
||||
auto setDbCompressionFunc = [&](int8_t compressionLevel) { expect.compression = compressionLevel; };
|
||||
auto setDbDaysFunc = [&](int32_t daysPerFile) { expect.daysPerFile = daysPerFile; };
|
||||
auto setDbFsyncFunc = [&](int32_t fsyncPeriod) { expect.fsyncPeriod = fsyncPeriod; };
|
||||
auto setDbMaxRowsFunc = [&](int32_t maxRowsPerBlock) { expect.maxRows = maxRowsPerBlock; };
|
||||
auto setDbMinRowsFunc = [&](int32_t minRowsPerBlock) { expect.minRows = minRowsPerBlock; };
|
||||
auto setDbKeepFunc = [&](int32_t keep0, int32_t keep1 = 0, int32_t keep2 = 0) {
|
||||
expect.daysToKeep0 = keep0;
|
||||
expect.daysToKeep1 = 0 == keep1 ? expect.daysToKeep0 : keep1;
|
||||
expect.daysToKeep2 = 0 == keep2 ? expect.daysToKeep1 : keep2;
|
||||
};
|
||||
auto setDbPagesFunc = [&](int32_t pages) { expect.pages = pages; };
|
||||
auto setDbPageSizeFunc = [&](int32_t pagesize) { expect.pageSize = pagesize; };
|
||||
auto setDbPrecisionFunc = [&](int8_t precision) { expect.precision = precision; };
|
||||
auto setDbReplicaFunc = [&](int8_t replica) { expect.replications = replica; };
|
||||
auto setDbStrictaFunc = [&](int8_t strict) { expect.strict = strict; };
|
||||
auto setDbWalLevelFunc = [&](int8_t walLevel) { expect.walLevel = walLevel; };
|
||||
auto setDbVgroupsFunc = [&](int32_t numOfVgroups) { expect.numOfVgroups = numOfVgroups; };
|
||||
auto setDbSingleStableFunc = [&](int8_t singleStable) { expect.numOfStables = singleStable; };
|
||||
auto addDbRetentionFunc = [&](int64_t freq, int64_t keep, int8_t freqUnit, int8_t keepUnit) {
|
||||
SRetention retention = {0};
|
||||
retention.freq = freq;
|
||||
retention.keep = keep;
|
||||
retention.freqUnit = freqUnit;
|
||||
retention.keepUnit = keepUnit;
|
||||
if (NULL == expect.pRetensions) {
|
||||
expect.pRetensions = taosArrayInit(TARRAY_MIN_SIZE, sizeof(SRetention));
|
||||
}
|
||||
taosArrayPush(expect.pRetensions, &retention);
|
||||
++expect.numOfRetensions;
|
||||
};
|
||||
|
||||
setCheckDdlFunc([&](const SQuery* pQuery, ParserStage stage) {
|
||||
ASSERT_EQ(nodeType(pQuery->pRoot), QUERY_NODE_CREATE_DATABASE_STMT);
|
||||
SCreateDbReq req = {0};
|
||||
ASSERT_TRUE(TSDB_CODE_SUCCESS == tDeserializeSCreateDbReq(pQuery->pCmdMsg->pMsg, pQuery->pCmdMsg->msgLen, &req));
|
||||
|
||||
ASSERT_EQ(std::string(req.db), std::string(expect.db));
|
||||
ASSERT_EQ(req.numOfVgroups, expect.numOfVgroups);
|
||||
ASSERT_EQ(req.numOfStables, expect.numOfStables);
|
||||
ASSERT_EQ(req.buffer, expect.buffer);
|
||||
ASSERT_EQ(req.pageSize, expect.pageSize);
|
||||
ASSERT_EQ(req.pages, expect.pages);
|
||||
ASSERT_EQ(req.daysPerFile, expect.daysPerFile);
|
||||
ASSERT_EQ(req.daysToKeep0, expect.daysToKeep0);
|
||||
ASSERT_EQ(req.daysToKeep1, expect.daysToKeep1);
|
||||
ASSERT_EQ(req.daysToKeep2, expect.daysToKeep2);
|
||||
ASSERT_EQ(req.minRows, expect.minRows);
|
||||
ASSERT_EQ(req.maxRows, expect.maxRows);
|
||||
ASSERT_EQ(req.fsyncPeriod, expect.fsyncPeriod);
|
||||
ASSERT_EQ(req.walLevel, expect.walLevel);
|
||||
ASSERT_EQ(req.precision, expect.precision);
|
||||
ASSERT_EQ(req.compression, expect.compression);
|
||||
ASSERT_EQ(req.replications, expect.replications);
|
||||
ASSERT_EQ(req.strict, expect.strict);
|
||||
ASSERT_EQ(req.cacheLastRow, expect.cacheLastRow);
|
||||
ASSERT_EQ(req.ignoreExist, expect.ignoreExist);
|
||||
ASSERT_EQ(req.numOfRetensions, expect.numOfRetensions);
|
||||
if (expect.numOfRetensions > 0) {
|
||||
ASSERT_EQ(taosArrayGetSize(req.pRetensions), expect.numOfRetensions);
|
||||
ASSERT_EQ(taosArrayGetSize(req.pRetensions), taosArrayGetSize(expect.pRetensions));
|
||||
for (int32_t i = 0; i < expect.numOfRetensions; ++i) {
|
||||
SRetention* pReten = (SRetention*)taosArrayGet(req.pRetensions, i);
|
||||
SRetention* pExpectReten = (SRetention*)taosArrayGet(expect.pRetensions, i);
|
||||
ASSERT_EQ(pReten->freq, pExpectReten->freq);
|
||||
ASSERT_EQ(pReten->keep, pExpectReten->keep);
|
||||
ASSERT_EQ(pReten->freqUnit, pExpectReten->freqUnit);
|
||||
ASSERT_EQ(pReten->keepUnit, pExpectReten->keepUnit);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
setCreateDbReqFunc("wxy_db");
|
||||
run("CREATE DATABASE wxy_db");
|
||||
|
||||
setCreateDbReqFunc("wxy_db", 1);
|
||||
setDbBufferFunc(64);
|
||||
setDbCachelastFunc(2);
|
||||
setDbCompressionFunc(1);
|
||||
setDbDaysFunc(100 * 1440);
|
||||
setDbFsyncFunc(100);
|
||||
setDbMaxRowsFunc(1000);
|
||||
setDbMinRowsFunc(100);
|
||||
setDbKeepFunc(1440 * 1440);
|
||||
setDbPagesFunc(96);
|
||||
setDbPageSizeFunc(8);
|
||||
setDbPrecisionFunc(TSDB_TIME_PRECISION_NANO);
|
||||
setDbReplicaFunc(3);
|
||||
addDbRetentionFunc(15 * MILLISECOND_PER_SECOND, 7 * MILLISECOND_PER_DAY, TIME_UNIT_SECOND, TIME_UNIT_DAY);
|
||||
addDbRetentionFunc(1 * MILLISECOND_PER_MINUTE, 21 * MILLISECOND_PER_DAY, TIME_UNIT_MINUTE, TIME_UNIT_DAY);
|
||||
addDbRetentionFunc(15 * MILLISECOND_PER_MINUTE, 5, TIME_UNIT_MINUTE, TIME_UNIT_YEAR);
|
||||
setDbStrictaFunc(1);
|
||||
setDbWalLevelFunc(2);
|
||||
setDbVgroupsFunc(100);
|
||||
setDbSingleStableFunc(1);
|
||||
run("CREATE DATABASE IF NOT EXISTS wxy_db "
|
||||
"BUFFER 64 "
|
||||
"CACHELAST 2 "
|
||||
"COMP 1 "
|
||||
"DAYS 100 "
|
||||
"FSYNC 100 "
|
||||
"MAXROWS 1000 "
|
||||
"MINROWS 100 "
|
||||
"KEEP 1440 "
|
||||
"PAGES 96 "
|
||||
"PAGESIZE 8 "
|
||||
"PRECISION 'ns' "
|
||||
"REPLICA 3 "
|
||||
"RETENTIONS 15s:7d,1m:21d,15m:5y "
|
||||
"STRICT 1 "
|
||||
"WAL 2 "
|
||||
"VGROUPS 100 "
|
||||
"SINGLE_STABLE 1 ");
|
||||
|
||||
setCreateDbReqFunc("wxy_db", 1);
|
||||
setDbDaysFunc(100);
|
||||
setDbKeepFunc(1440, 300 * 60, 400 * 1440);
|
||||
run("CREATE DATABASE IF NOT EXISTS wxy_db "
|
||||
"DAYS 100m "
|
||||
"KEEP 1440m,300h,400d ");
|
||||
}
|
||||
|
||||
TEST_F(ParserInitialCTest, createDnode) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("create dnode abc1 port 7000");
|
||||
run("CREATE DNODE abc1 PORT 7000");
|
||||
|
||||
run("create dnode 1.1.1.1 port 9000");
|
||||
run("CREATE DNODE 1.1.1.1 PORT 9000");
|
||||
}
|
||||
|
||||
// todo create function
|
||||
// todo CREATE FUNCTION
|
||||
|
||||
TEST_F(ParserInitialCTest, createIndexSma) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("create sma index index1 on t1 function(max(c1), min(c3 + 10), sum(c4)) INTERVAL(10s)");
|
||||
run("CREATE SMA INDEX index1 ON t1 FUNCTION(MAX(c1), MIN(c3 + 10), SUM(c4)) INTERVAL(10s)");
|
||||
}
|
||||
|
||||
TEST_F(ParserInitialCTest, createMnode) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("create mnode on dnode 1");
|
||||
run("CREATE MNODE ON DNODE 1");
|
||||
}
|
||||
|
||||
TEST_F(ParserInitialCTest, createQnode) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("create qnode on dnode 1");
|
||||
run("CREATE QNODE ON DNODE 1");
|
||||
}
|
||||
|
||||
TEST_F(ParserInitialCTest, createSnode) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("create snode on dnode 1");
|
||||
run("CREATE SNODE ON DNODE 1");
|
||||
}
|
||||
|
||||
TEST_F(ParserInitialCTest, createStable) {
|
||||
|
@ -117,7 +272,7 @@ TEST_F(ParserInitialCTest, createStable) {
|
|||
};
|
||||
|
||||
auto addFieldToCreateStbReqFunc = [&](bool col, const char* pFieldName, uint8_t type, int32_t bytes = 0,
|
||||
int8_t flags = SCHEMA_SMA_ON) {
|
||||
int8_t flags = COL_SMA_ON) {
|
||||
SField field = {0};
|
||||
strcpy(field.name, pFieldName);
|
||||
field.type = type;
|
||||
|
@ -194,7 +349,7 @@ TEST_F(ParserInitialCTest, createStable) {
|
|||
addFieldToCreateStbReqFunc(true, "ts", TSDB_DATA_TYPE_TIMESTAMP);
|
||||
addFieldToCreateStbReqFunc(true, "c1", TSDB_DATA_TYPE_INT);
|
||||
addFieldToCreateStbReqFunc(false, "id", TSDB_DATA_TYPE_INT);
|
||||
run("create stable t1(ts timestamp, c1 int) TAGS(id int)");
|
||||
run("CREATE STABLE t1(ts TIMESTAMP, c1 INT) TAGS(id INT)");
|
||||
|
||||
setCreateStbReqFunc("t1", 1, 0.1, 2, 100, "test create table");
|
||||
addFieldToCreateStbReqFunc(true, "ts", TSDB_DATA_TYPE_TIMESTAMP, 0, 0);
|
||||
|
@ -227,80 +382,72 @@ TEST_F(ParserInitialCTest, createStable) {
|
|||
addFieldToCreateStbReqFunc(false, "a13", TSDB_DATA_TYPE_BOOL);
|
||||
addFieldToCreateStbReqFunc(false, "a14", TSDB_DATA_TYPE_NCHAR, 30 * TSDB_NCHAR_SIZE + VARSTR_HEADER_SIZE);
|
||||
addFieldToCreateStbReqFunc(false, "a15", TSDB_DATA_TYPE_VARCHAR, 50 + VARSTR_HEADER_SIZE);
|
||||
run("create stable if not exists test.t1("
|
||||
run("CREATE STABLE IF NOT EXISTS test.t1("
|
||||
"ts TIMESTAMP, c1 INT, c2 INT UNSIGNED, c3 BIGINT, c4 BIGINT UNSIGNED, c5 FLOAT, c6 DOUBLE, c7 BINARY(20), "
|
||||
"c8 SMALLINT, c9 SMALLINT UNSIGNED COMMENT 'test column comment', c10 TINYINT, c11 TINYINT UNSIGNED, c12 BOOL, "
|
||||
"c13 NCHAR(30), c14 VARCHAR(50)) "
|
||||
"TAGS (a1 TIMESTAMP, a2 INT, a3 INT UNSIGNED, a4 BIGINT, a5 BIGINT UNSIGNED, a6 FLOAT, a7 DOUBLE, "
|
||||
"a8 BINARY(20), a9 SMALLINT, a10 SMALLINT UNSIGNED COMMENT 'test column comment', a11 TINYINT, "
|
||||
"a12 TINYINT UNSIGNED, a13 BOOL, a14 NCHAR(30), a15 VARCHAR(50)) "
|
||||
"TTL 100 COMMENT 'test create table' SMA(c1, c2, c3) ROLLUP (min) FILE_FACTOR 0.1 DELAY 2");
|
||||
"TTL 100 COMMENT 'test create table' SMA(c1, c2, c3) ROLLUP (MIN) FILE_FACTOR 0.1 DELAY 2");
|
||||
}
|
||||
|
||||
TEST_F(ParserInitialCTest, createStream) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("create stream s1 as select * from t1");
|
||||
run("CREATE STREAM s1 AS SELECT * FROM t1");
|
||||
|
||||
run("create stream if not exists s1 as select * from t1");
|
||||
run("CREATE STREAM IF NOT EXISTS s1 AS SELECT * FROM t1");
|
||||
|
||||
run("create stream s1 into st1 as select * from t1");
|
||||
run("CREATE STREAM s1 INTO st1 AS SELECT * FROM t1");
|
||||
|
||||
run("create stream if not exists s1 trigger window_close watermark 10s into st1 as select * from t1");
|
||||
run("CREATE STREAM IF NOT EXISTS s1 TRIGGER WINDOW_CLOSE WATERMARK 10s INTO st1 AS SELECT * FROM t1");
|
||||
}
|
||||
|
||||
TEST_F(ParserInitialCTest, createTable) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("create table t1(ts timestamp, c1 int)");
|
||||
run("CREATE TABLE t1(ts TIMESTAMP, c1 INT)");
|
||||
|
||||
run("create table if not exists test.t1("
|
||||
"ts TIMESTAMP, c1 INT, c2 INT UNSIGNED, c3 BIGINT, c4 BIGINT UNSIGNED, c5 FLOAT, c6 DOUBLE, c7 BINARY(20), c8 "
|
||||
"SMALLINT, "
|
||||
"c9 SMALLINT UNSIGNED COMMENT 'test column comment', c10 TINYINT, c11 TINYINT UNSIGNED, c12 BOOL, c13 "
|
||||
"NCHAR(30), "
|
||||
"c15 VARCHAR(50)) "
|
||||
run("CREATE TABLE IF NOT EXISTS test.t1("
|
||||
"ts TIMESTAMP, c1 INT, c2 INT UNSIGNED, c3 BIGINT, c4 BIGINT UNSIGNED, c5 FLOAT, c6 DOUBLE, c7 BINARY(20), "
|
||||
"c8 SMALLINT, c9 SMALLINT UNSIGNED COMMENT 'test column comment', c10 TINYINT, c11 TINYINT UNSIGNED, c12 BOOL, "
|
||||
"c13 NCHAR(30), c15 VARCHAR(50)) "
|
||||
"TTL 100 COMMENT 'test create table' SMA(c1, c2, c3)");
|
||||
|
||||
run("create table if not exists test.t1("
|
||||
"ts TIMESTAMP, c1 INT, c2 INT UNSIGNED, c3 BIGINT, c4 BIGINT UNSIGNED, c5 FLOAT, c6 DOUBLE, c7 BINARY(20), c8 "
|
||||
"SMALLINT, "
|
||||
"c9 SMALLINT UNSIGNED COMMENT 'test column comment', c10 TINYINT, c11 TINYINT UNSIGNED, c12 BOOL, c13 "
|
||||
"NCHAR(30), "
|
||||
"c15 VARCHAR(50)) "
|
||||
"TAGS (tsa TIMESTAMP, a1 INT, a2 INT UNSIGNED, a3 BIGINT, a4 BIGINT UNSIGNED, "
|
||||
"a5 FLOAT, a6 DOUBLE, a7 "
|
||||
"BINARY(20), a8 SMALLINT, "
|
||||
"a9 SMALLINT UNSIGNED COMMENT 'test column comment', a10 "
|
||||
"TINYINT, a11 TINYINT UNSIGNED, a12 BOOL, a13 NCHAR(30), "
|
||||
"a15 VARCHAR(50)) "
|
||||
"TTL 100 COMMENT 'test create "
|
||||
"table' SMA(c1, c2, c3) ROLLUP (min) FILE_FACTOR 0.1 DELAY 2");
|
||||
run("CREATE TABLE IF NOT EXISTS test.t1("
|
||||
"ts TIMESTAMP, c1 INT, c2 INT UNSIGNED, c3 BIGINT, c4 BIGINT UNSIGNED, c5 FLOAT, c6 DOUBLE, c7 BINARY(20), "
|
||||
"c8 SMALLINT, c9 SMALLINT UNSIGNED COMMENT 'test column comment', c10 TINYINT, c11 TINYINT UNSIGNED, c12 BOOL, "
|
||||
"c13 NCHAR(30), c14 VARCHAR(50)) "
|
||||
"TAGS (a1 TIMESTAMP, a2 INT, a3 INT UNSIGNED, a4 BIGINT, a5 BIGINT UNSIGNED, a6 FLOAT, a7 DOUBLE, a8 BINARY(20), "
|
||||
"a9 SMALLINT, a10 SMALLINT UNSIGNED COMMENT 'test column comment', a11 TINYINT, a12 TINYINT UNSIGNED, a13 BOOL, "
|
||||
"a14 NCHAR(30), a15 VARCHAR(50)) "
|
||||
"TTL 100 COMMENT 'test create table' SMA(c1, c2, c3) ROLLUP (MIN) FILE_FACTOR 0.1 DELAY 2");
|
||||
|
||||
run("create table if not exists t1 using st1 tags(1, 'wxy')");
|
||||
run("CREATE TABLE IF NOT EXISTS t1 USING st1 TAGS(1, 'wxy')");
|
||||
|
||||
run("create table "
|
||||
"if not exists test.t1 using test.st1 (tag1, tag2) tags(1, 'abc') "
|
||||
"if not exists test.t2 using test.st1 (tag1, tag2) tags(2, 'abc') "
|
||||
"if not exists test.t3 using test.st1 (tag1, tag2) tags(3, 'abc') ");
|
||||
run("CREATE TABLE "
|
||||
"IF NOT EXISTS test.t1 USING test.st1 (tag1, tag2) TAGS(1, 'abc') "
|
||||
"IF NOT EXISTS test.t2 USING test.st1 (tag1, tag2) TAGS(2, 'abc') "
|
||||
"IF NOT EXISTS test.t3 USING test.st1 (tag1, tag2) TAGS(3, 'abc') ");
|
||||
}
|
||||
|
||||
TEST_F(ParserInitialCTest, createTopic) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("create topic tp1 as select * from t1");
|
||||
run("CREATE TOPIC tp1 AS SELECT * FROM t1");
|
||||
|
||||
run("create topic if not exists tp1 as select * from t1");
|
||||
run("CREATE TOPIC IF NOT EXISTS tp1 AS SELECT * FROM t1");
|
||||
|
||||
run("create topic tp1 as test");
|
||||
run("CREATE TOPIC tp1 AS test");
|
||||
|
||||
run("create topic if not exists tp1 as test");
|
||||
run("CREATE TOPIC IF NOT EXISTS tp1 AS test");
|
||||
}
|
||||
|
||||
TEST_F(ParserInitialCTest, createUser) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("create user wxy pass '123456'");
|
||||
run("CREATE USER wxy PASS '123456'");
|
||||
}
|
||||
|
||||
} // namespace ParserTest
|
||||
|
|
|
@ -151,20 +151,32 @@ static bool needOptimizeDynamicScan(const SFunctionNode* pFunc) {
|
|||
|
||||
static int32_t osdGetRelatedFuncs(SScanLogicNode* pScan, SNodeList** pSdrFuncs, SNodeList** pDsoFuncs) {
|
||||
SNodeList* pAllFuncs = osdGetAllFuncs(pScan->node.pParent);
|
||||
SNodeList* pTmpSdrFuncs = NULL;
|
||||
SNodeList* pTmpDsoFuncs = NULL;
|
||||
SNode* pFunc = NULL;
|
||||
bool otherFunc = false;
|
||||
FOREACH(pFunc, pAllFuncs) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
if (needOptimizeDataRequire((SFunctionNode*)pFunc)) {
|
||||
code = nodesListMakeStrictAppend(pSdrFuncs, nodesCloneNode(pFunc));
|
||||
code = nodesListMakeStrictAppend(&pTmpSdrFuncs, nodesCloneNode(pFunc));
|
||||
} else if (needOptimizeDynamicScan((SFunctionNode*)pFunc)) {
|
||||
code = nodesListMakeStrictAppend(pDsoFuncs, nodesCloneNode(pFunc));
|
||||
code = nodesListMakeStrictAppend(&pTmpDsoFuncs, nodesCloneNode(pFunc));
|
||||
} else {
|
||||
otherFunc = true;
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
nodesDestroyList(*pSdrFuncs);
|
||||
nodesDestroyList(*pDsoFuncs);
|
||||
nodesDestroyList(pTmpSdrFuncs);
|
||||
nodesDestroyList(pTmpDsoFuncs);
|
||||
return code;
|
||||
}
|
||||
}
|
||||
if (otherFunc) {
|
||||
nodesDestroyList(pTmpSdrFuncs);
|
||||
nodesDestroyList(pTmpDsoFuncs);
|
||||
} else {
|
||||
*pSdrFuncs = pTmpSdrFuncs;
|
||||
*pDsoFuncs = pTmpDsoFuncs;
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
static char* getUsageErrFormat(int32_t errCode) {
|
||||
switch (errCode) {
|
||||
case TSDB_CODE_PLAN_EXPECTED_TS_EQUAL:
|
||||
return "l.ts = r.ts is expected in join expression";
|
||||
return "left.ts = right.ts is expected in join expression";
|
||||
case TSDB_CODE_PLAN_NOT_SUPPORT_CROSS_JOIN:
|
||||
return "not support cross join";
|
||||
default:
|
||||
|
|
|
@ -16,9 +16,10 @@
|
|||
#include "planner.h"
|
||||
|
||||
#include "planInt.h"
|
||||
#include "scalar.h"
|
||||
|
||||
typedef struct SCollectPlaceholderValuesCxt {
|
||||
int32_t errCode;
|
||||
int32_t errCode;
|
||||
SArray* pValues;
|
||||
} SCollectPlaceholderValuesCxt;
|
||||
|
||||
|
@ -144,9 +145,10 @@ static int32_t setValueByBindParam(SValueNode* pVal, TAOS_MULTI_BIND* pParam) {
|
|||
if (NULL == pVal->datum.p) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
|
||||
int32_t output = 0;
|
||||
if (!taosMbsToUcs4(pParam->buffer, inputSize, (TdUcs4*)varDataVal(pVal->datum.p), pVal->node.resType.bytes, &output)) {
|
||||
if (!taosMbsToUcs4(pParam->buffer, inputSize, (TdUcs4*)varDataVal(pVal->datum.p), pVal->node.resType.bytes,
|
||||
&output)) {
|
||||
return errno;
|
||||
}
|
||||
varDataSetLen(pVal->datum.p, output);
|
||||
|
@ -181,8 +183,8 @@ static int32_t setValueByBindParam(SValueNode* pVal, TAOS_MULTI_BIND* pParam) {
|
|||
}
|
||||
|
||||
static EDealRes updatePlanQueryId(SNode* pNode, void* pContext) {
|
||||
int64_t queryId = *(uint64_t *)pContext;
|
||||
|
||||
int64_t queryId = *(uint64_t*)pContext;
|
||||
|
||||
if (QUERY_NODE_PHYSICAL_PLAN == nodeType(pNode)) {
|
||||
SQueryPlan* planNode = (SQueryPlan*)pNode;
|
||||
planNode->queryId = queryId;
|
||||
|
@ -194,10 +196,130 @@ static EDealRes updatePlanQueryId(SNode* pNode, void* pContext) {
|
|||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
int32_t qStmtBindParam(SQueryPlan* pPlan, TAOS_MULTI_BIND* pParams, int32_t colIdx, uint64_t queryId) {
|
||||
static int32_t calcConstNode(SNode** pNode) {
|
||||
if (NULL == *pNode) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
SNode* pNew = NULL;
|
||||
int32_t code = scalarCalculateConstants(*pNode, &pNew);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
*pNode = pNew;
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t calcConstList(SNodeList* pList) {
|
||||
SNode* pNode = NULL;
|
||||
FOREACH(pNode, pList) {
|
||||
SNode* pNew = NULL;
|
||||
int32_t code = scalarCalculateConstants(pNode, &pNew);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
REPLACE_NODE(pNew);
|
||||
} else {
|
||||
return code;
|
||||
}
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static bool isEmptyResultCond(SNode** pCond) {
|
||||
if (NULL == *pCond || QUERY_NODE_VALUE != nodeType(*pCond)) {
|
||||
return false;
|
||||
}
|
||||
if (((SValueNode*)*pCond)->datum.b) {
|
||||
nodesDestroyNode(*pCond);
|
||||
*pCond = NULL;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static int32_t calcConstSpecificPhysiNode(SPhysiNode* pPhyNode) {
|
||||
switch (nodeType(pPhyNode)) {
|
||||
case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_TABLE_SEQ_SCAN:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_EXCHANGE:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_FILL:
|
||||
return TSDB_CODE_SUCCESS;
|
||||
case QUERY_NODE_PHYSICAL_PLAN_PROJECT:
|
||||
return calcConstList(((SProjectPhysiNode*)pPhyNode)->pProjections);
|
||||
case QUERY_NODE_PHYSICAL_PLAN_JOIN:
|
||||
return calcConstNode(&(((SJoinPhysiNode*)pPhyNode)->pOnConditions));
|
||||
case QUERY_NODE_PHYSICAL_PLAN_AGG:
|
||||
return calcConstList(((SAggPhysiNode*)pPhyNode)->pExprs);
|
||||
case QUERY_NODE_PHYSICAL_PLAN_SORT:
|
||||
return calcConstList(((SSortPhysiNode*)pPhyNode)->pExprs);
|
||||
case QUERY_NODE_PHYSICAL_PLAN_INTERVAL:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STATE_WINDOW:
|
||||
return calcConstList(((SWinodwPhysiNode*)pPhyNode)->pExprs);
|
||||
case QUERY_NODE_PHYSICAL_PLAN_PARTITION:
|
||||
return calcConstList(((SPartitionPhysiNode*)pPhyNode)->pExprs);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t calcConstSubplan(SPhysiNode* pPhyNode, bool* pEmptyResult) {
|
||||
int32_t code = calcConstNode(&pPhyNode->pConditions);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = calcConstSpecificPhysiNode(pPhyNode);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
return code;
|
||||
}
|
||||
|
||||
*pEmptyResult = isEmptyResultCond(&pPhyNode->pConditions);
|
||||
if (*pEmptyResult) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
*pEmptyResult = true;
|
||||
|
||||
bool subEmptyResult = false;
|
||||
SNode* pChild = NULL;
|
||||
FOREACH(pChild, pPhyNode->pChildren) {
|
||||
code = calcConstSubplan((SPhysiNode*)pChild, &subEmptyResult);
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
return code;
|
||||
}
|
||||
if (!subEmptyResult) {
|
||||
*pEmptyResult = false;
|
||||
}
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t calcConstPhysiPlan(SQueryPlan* pPlan, bool* pEmptyResult) {
|
||||
*pEmptyResult = true;
|
||||
|
||||
bool subEmptyResult = false;
|
||||
SNodeListNode* pNode = nodesListGetNode(pPlan->pSubplans, 0);
|
||||
SNode* pSubplan = NULL;
|
||||
FOREACH(pSubplan, pNode->pNodeList) {
|
||||
int32_t code = calcConstSubplan(((SSubplan*)pSubplan)->pNode, pEmptyResult);
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
return code;
|
||||
}
|
||||
if (!subEmptyResult) {
|
||||
*pEmptyResult = false;
|
||||
}
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t qStmtBindParam(SQueryPlan* pPlan, TAOS_MULTI_BIND* pParams, int32_t colIdx, uint64_t queryId,
|
||||
bool* pEmptyResult) {
|
||||
int32_t size = taosArrayGetSize(pPlan->pPlaceholderValues);
|
||||
int32_t code = 0;
|
||||
|
||||
|
||||
if (colIdx < 0) {
|
||||
for (int32_t i = 0; i < size; ++i) {
|
||||
code = setValueByBindParam((SValueNode*)taosArrayGetP(pPlan->pPlaceholderValues, i), pParams + i);
|
||||
|
@ -214,9 +336,10 @@ int32_t qStmtBindParam(SQueryPlan* pPlan, TAOS_MULTI_BIND* pParams, int32_t colI
|
|||
|
||||
if (colIdx < 0 || ((colIdx + 1) == size)) {
|
||||
nodesWalkPhysiPlan((SNode*)pPlan, updatePlanQueryId, &queryId);
|
||||
code = calcConstPhysiPlan(pPlan, pEmptyResult);
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t qSubPlanToString(const SSubplan* pSubplan, char** pStr, int32_t* pLen) {
|
||||
|
|
|
@ -28,6 +28,8 @@ TEST_F(PlanOptimizeTest, optimizeScanData) {
|
|||
run("SELECT COUNT(c1) FROM t1");
|
||||
|
||||
run("SELECT COUNT(CAST(c1 AS BIGINT)) FROM t1");
|
||||
|
||||
run("SELECT PERCENTILE(c1, 40), COUNT(*) FROM t1");
|
||||
}
|
||||
|
||||
TEST_F(PlanOptimizeTest, orderByPrimaryKey) {
|
||||
|
|
|
@ -50,5 +50,5 @@ class PlanStmtTest : public PlannerTestBase {
|
|||
TEST_F(PlanStmtTest, stmt) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("select * from t1 where c1 = ?");
|
||||
// run("select * from t1 where c1 = ?");
|
||||
}
|
||||
|
|
|
@ -198,7 +198,7 @@ class PlannerTestBaseImpl {
|
|||
cxt.pMsg = stmtEnv_.msgBuf_.data();
|
||||
cxt.msgLen = stmtEnv_.msgBuf_.max_size();
|
||||
|
||||
DO_WITH_THROW(qParseQuerySql, &cxt, pQuery);
|
||||
DO_WITH_THROW(qParseSql, &cxt, pQuery);
|
||||
res_.ast_ = toString((*pQuery)->pRoot);
|
||||
}
|
||||
|
||||
|
|
|
@ -153,11 +153,6 @@ int32_t asyncSendMsgToServerExt(void* pTransporter, SEpSet* epSet, int64_t* pTra
|
|||
.handle = pInfo->msgInfo.handle,
|
||||
.persistHandle = persistHandle,
|
||||
.code = 0};
|
||||
if (pInfo->msgType == TDMT_VND_QUERY || pInfo->msgType == TDMT_VND_FETCH ||
|
||||
pInfo->msgType == TDMT_VND_QUERY_CONTINUE) {
|
||||
rpcMsg.persistHandle = 1;
|
||||
}
|
||||
|
||||
assert(pInfo->fp != NULL);
|
||||
|
||||
rpcSendRequestWithCtx(pTransporter, epSet, &rpcMsg, pTransporterId, rpcCtx);
|
||||
|
@ -168,7 +163,7 @@ int32_t asyncSendMsgToServer(void* pTransporter, SEpSet* epSet, int64_t* pTransp
|
|||
return asyncSendMsgToServerExt(pTransporter, epSet, pTransporterId, pInfo, false, NULL);
|
||||
}
|
||||
|
||||
char *jobTaskStatusStr(int32_t status) {
|
||||
char* jobTaskStatusStr(int32_t status) {
|
||||
switch (status) {
|
||||
case JOB_TASK_STATUS_NULL:
|
||||
return "NULL";
|
||||
|
@ -197,13 +192,10 @@ char *jobTaskStatusStr(int32_t status) {
|
|||
|
||||
SSchema createSchema(int8_t type, int32_t bytes, col_id_t colId, const char* name) {
|
||||
SSchema s = {0};
|
||||
s.type = type;
|
||||
s.type = type;
|
||||
s.bytes = bytes;
|
||||
s.colId = colId;
|
||||
|
||||
tstrncpy(s.name, name, tListLen(s.name));
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -49,6 +49,7 @@ typedef struct SScalarCtx {
|
|||
|
||||
int32_t doConvertDataType(SValueNode* pValueNode, SScalarParam* out);
|
||||
SColumnInfoData* createColumnInfoData(SDataType* pType, int32_t numOfRows);
|
||||
void sclConvertToTsValueNode(int8_t precision, SValueNode* valueNode);
|
||||
|
||||
#define GET_PARAM_TYPE(_c) ((_c)->columnData->info.type)
|
||||
#define GET_PARAM_BYTES(_c) ((_c)->columnData->info.bytes)
|
||||
|
|
|
@ -260,7 +260,7 @@ int8_t filterGetCompFuncIdx(int32_t type, int32_t optr) {
|
|||
comparFn = 20;
|
||||
} else if (optr == OP_TYPE_LIKE) {
|
||||
comparFn = 9;
|
||||
} else if (optr == OP_TYPE_LIKE) {
|
||||
} else if (optr == OP_TYPE_NOT_LIKE) {
|
||||
comparFn = 27;
|
||||
} else if (optr == OP_TYPE_IN) {
|
||||
comparFn = 8;
|
||||
|
@ -3505,18 +3505,6 @@ int32_t fltAddValueNodeToConverList(SFltTreeStat *stat, SValueNode* pNode) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
void fltConvertToTsValueNode(SFltTreeStat *stat, SValueNode* valueNode) {
|
||||
char *timeStr = valueNode->datum.p;
|
||||
if (convertStringToTimestamp(valueNode->node.resType.type, valueNode->datum.p, stat->precision, &valueNode->datum.i) !=
|
||||
TSDB_CODE_SUCCESS) {
|
||||
valueNode->datum.i = 0;
|
||||
}
|
||||
taosMemoryFree(timeStr);
|
||||
|
||||
valueNode->node.resType.type = TSDB_DATA_TYPE_TIMESTAMP;
|
||||
valueNode->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_TIMESTAMP].bytes;
|
||||
}
|
||||
|
||||
EDealRes fltReviseRewriter(SNode** pNode, void* pContext) {
|
||||
SFltTreeStat *stat = (SFltTreeStat *)pContext;
|
||||
|
||||
|
@ -3565,7 +3553,7 @@ EDealRes fltReviseRewriter(SNode** pNode, void* pContext) {
|
|||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
fltConvertToTsValueNode(stat, valueNode);
|
||||
sclConvertToTsValueNode(stat->precision, valueNode);
|
||||
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
@ -3613,6 +3601,11 @@ EDealRes fltReviseRewriter(SNode** pNode, void* pContext) {
|
|||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
if (FILTER_GET_FLAG(stat->info->options, FLT_OPTION_TIMESTAMP) && node->opType >= OP_TYPE_NOT_EQUAL) {
|
||||
stat->scalarMode = true;
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
if (NULL == node->pRight) {
|
||||
if (scalarGetOperatorParamNum(node->opType) > 1) {
|
||||
fltError("invalid operator, pRight:%p, nodeType:%d, opType:%d", node->pRight, nodeType(node), node->opType);
|
||||
|
@ -3694,7 +3687,7 @@ int32_t fltReviseNodes(SFilterInfo *pInfo, SNode** pNode, SFltTreeStat *pStat) {
|
|||
for (int32_t i = 0; i < nodeNum; ++i) {
|
||||
SValueNode *valueNode = *(SValueNode **)taosArrayGet(pStat->nodeList, i);
|
||||
|
||||
fltConvertToTsValueNode(pStat, valueNode);
|
||||
sclConvertToTsValueNode(pStat->precision, valueNode);
|
||||
}
|
||||
|
||||
_return:
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "tdatablock.h"
|
||||
#include "scalar.h"
|
||||
#include "tudf.h"
|
||||
#include "ttime.h"
|
||||
|
||||
int32_t scalarGetOperatorParamNum(EOperatorType type) {
|
||||
if (OP_TYPE_IS_NULL == type || OP_TYPE_IS_NOT_NULL == type || OP_TYPE_IS_TRUE == type || OP_TYPE_IS_NOT_TRUE == type
|
||||
|
@ -19,6 +20,19 @@ int32_t scalarGetOperatorParamNum(EOperatorType type) {
|
|||
return 2;
|
||||
}
|
||||
|
||||
void sclConvertToTsValueNode(int8_t precision, SValueNode* valueNode) {
|
||||
char *timeStr = valueNode->datum.p;
|
||||
if (convertStringToTimestamp(valueNode->node.resType.type, valueNode->datum.p, precision, &valueNode->datum.i) !=
|
||||
TSDB_CODE_SUCCESS) {
|
||||
valueNode->datum.i = 0;
|
||||
}
|
||||
taosMemoryFree(timeStr);
|
||||
|
||||
valueNode->node.resType.type = TSDB_DATA_TYPE_TIMESTAMP;
|
||||
valueNode->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_TIMESTAMP].bytes;
|
||||
}
|
||||
|
||||
|
||||
SColumnInfoData* createColumnInfoData(SDataType* pType, int32_t numOfRows) {
|
||||
SColumnInfoData* pColumnData = taosMemoryCalloc(1, sizeof(SColumnInfoData));
|
||||
if (pColumnData == NULL) {
|
||||
|
@ -92,8 +106,9 @@ int32_t scalarGenerateSetFromList(void **data, void *pNode, uint32_t type) {
|
|||
}
|
||||
|
||||
if (IS_VAR_DATA_TYPE(type)) {
|
||||
len = varDataLen(out.columnData->pData);
|
||||
buf = varDataVal(out.columnData->pData);
|
||||
char* data = colDataGetVarData(out.columnData, 0);
|
||||
len = varDataLen(data);
|
||||
buf = varDataVal(data);
|
||||
} else {
|
||||
len = tDataTypes[type].bytes;
|
||||
buf = out.columnData->pData;
|
||||
|
@ -109,7 +124,7 @@ int32_t scalarGenerateSetFromList(void **data, void *pNode, uint32_t type) {
|
|||
}
|
||||
|
||||
if (taosHashPut(pObj, buf, (size_t)len, NULL, 0)) {
|
||||
sclError("taosHashPut failed");
|
||||
sclError("taosHashPut to set failed");
|
||||
SCL_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
|
@ -534,7 +549,7 @@ EDealRes sclRewriteBasedOnOptr(SNode** pNode, SScalarCtx *ctx, EOperatorType opT
|
|||
}
|
||||
|
||||
|
||||
EDealRes sclRewriteOperatorForNullValue(SNode** pNode, SScalarCtx *ctx) {
|
||||
EDealRes sclRewriteNonConstOperator(SNode** pNode, SScalarCtx *ctx) {
|
||||
SOperatorNode *node = (SOperatorNode *)*pNode;
|
||||
|
||||
if (node->pLeft && (QUERY_NODE_VALUE == nodeType(node->pLeft))) {
|
||||
|
@ -542,6 +557,11 @@ EDealRes sclRewriteOperatorForNullValue(SNode** pNode, SScalarCtx *ctx) {
|
|||
if (SCL_IS_NULL_VALUE_NODE(valueNode) && (node->opType != OP_TYPE_IS_NULL && node->opType != OP_TYPE_IS_NOT_NULL)) {
|
||||
return sclRewriteBasedOnOptr(pNode, ctx, node->opType);
|
||||
}
|
||||
|
||||
if (IS_STR_DATA_TYPE(valueNode->node.resType.type) && node->pRight && nodesIsExprNode(node->pRight)
|
||||
&& ((SExprNode*)node->pRight)->resType.type == TSDB_DATA_TYPE_TIMESTAMP) {
|
||||
sclConvertToTsValueNode(((SExprNode*)node->pRight)->resType.precision, valueNode);
|
||||
}
|
||||
}
|
||||
|
||||
if (node->pRight && (QUERY_NODE_VALUE == nodeType(node->pRight))) {
|
||||
|
@ -549,6 +569,11 @@ EDealRes sclRewriteOperatorForNullValue(SNode** pNode, SScalarCtx *ctx) {
|
|||
if (SCL_IS_NULL_VALUE_NODE(valueNode) && (node->opType != OP_TYPE_IS_NULL && node->opType != OP_TYPE_IS_NOT_NULL)) {
|
||||
return sclRewriteBasedOnOptr(pNode, ctx, node->opType);
|
||||
}
|
||||
|
||||
if (IS_STR_DATA_TYPE(valueNode->node.resType.type) && node->pLeft && nodesIsExprNode(node->pLeft)
|
||||
&& ((SExprNode*)node->pLeft)->resType.type == TSDB_DATA_TYPE_TIMESTAMP) {
|
||||
sclConvertToTsValueNode(((SExprNode*)node->pLeft)->resType.precision, valueNode);
|
||||
}
|
||||
}
|
||||
|
||||
if (node->pRight && (QUERY_NODE_NODE_LIST == nodeType(node->pRight))) {
|
||||
|
@ -671,7 +696,7 @@ EDealRes sclRewriteOperator(SNode** pNode, SScalarCtx *ctx) {
|
|||
SOperatorNode *node = (SOperatorNode *)*pNode;
|
||||
|
||||
if ((!SCL_IS_CONST_NODE(node->pLeft)) || (!SCL_IS_CONST_NODE(node->pRight))) {
|
||||
return sclRewriteOperatorForNullValue(pNode, ctx);
|
||||
return sclRewriteNonConstOperator(pNode, ctx);
|
||||
}
|
||||
|
||||
SScalarParam output = {.columnData = taosMemoryCalloc(1, sizeof(SColumnInfoData))};
|
||||
|
|
|
@ -328,9 +328,10 @@ static FORCE_INLINE void varToBool(char *buf, SScalarParam* pOut, int32_t rowInd
|
|||
static FORCE_INLINE void varToNchar(char* buf, SScalarParam* pOut, int32_t rowIndex) {
|
||||
int32_t len = 0;
|
||||
int32_t inputLen = varDataLen(buf);
|
||||
int32_t outputMaxLen = (inputLen + 1) * TSDB_NCHAR_SIZE + VARSTR_HEADER_SIZE;
|
||||
|
||||
char* t = taosMemoryCalloc(1,(inputLen + 1) * TSDB_NCHAR_SIZE + VARSTR_HEADER_SIZE);
|
||||
/*int32_t resLen = */taosMbsToUcs4(varDataVal(buf), inputLen, (TdUcs4*) varDataVal(t), pOut->columnData->info.bytes, &len);
|
||||
char* t = taosMemoryCalloc(1, outputMaxLen);
|
||||
/*int32_t resLen = */taosMbsToUcs4(varDataVal(buf), inputLen, (TdUcs4*) varDataVal(t), outputMaxLen, &len);
|
||||
varDataSetLen(t, len);
|
||||
|
||||
colDataAppend(pOut->columnData, rowIndex, t, false);
|
||||
|
@ -512,7 +513,7 @@ int32_t vectorConvertToVarData(const SScalarParam* pIn, SScalarParam* pOut, int1
|
|||
if (outType == TSDB_DATA_TYPE_NCHAR) {
|
||||
varToNchar(tmp, pOut, i);
|
||||
} else {
|
||||
colDataAppend(pOutputCol, i, (char *)&value, false);
|
||||
colDataAppend(pOutputCol, i, (char *)tmp, false);
|
||||
}
|
||||
}
|
||||
} else if (IS_UNSIGNED_NUMERIC_TYPE(inType)) {
|
||||
|
@ -529,7 +530,7 @@ int32_t vectorConvertToVarData(const SScalarParam* pIn, SScalarParam* pOut, int1
|
|||
if (outType == TSDB_DATA_TYPE_NCHAR) {
|
||||
varToNchar(tmp, pOut, i);
|
||||
} else {
|
||||
colDataAppend(pOutputCol, i, (char *)&value, false);
|
||||
colDataAppend(pOutputCol, i, (char *)tmp, false);
|
||||
}
|
||||
}
|
||||
} else if (IS_FLOAT_TYPE(inType)) {
|
||||
|
@ -546,7 +547,7 @@ int32_t vectorConvertToVarData(const SScalarParam* pIn, SScalarParam* pOut, int1
|
|||
if (outType == TSDB_DATA_TYPE_NCHAR) {
|
||||
varToNchar(tmp, pOut, i);
|
||||
} else {
|
||||
colDataAppend(pOutputCol, i, (char *)&value, false);
|
||||
colDataAppend(pOutputCol, i, (char *)tmp, false);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -159,6 +159,7 @@ typedef struct SSchTask {
|
|||
|
||||
typedef struct SSchJobAttr {
|
||||
EExplainMode explainMode;
|
||||
bool needRes;
|
||||
bool syncSchedule;
|
||||
bool queryJob;
|
||||
bool needFlowCtrl;
|
||||
|
@ -190,6 +191,7 @@ typedef struct SSchJob {
|
|||
SSchTask *fetchTask;
|
||||
int32_t errCode;
|
||||
SArray *errList; // SArray<SQueryErrorInfo>
|
||||
SRWLatch resLock;
|
||||
void *resData; //TODO free it or not
|
||||
int32_t resNumOfRows;
|
||||
const char *sql;
|
||||
|
|
|
@ -70,7 +70,7 @@ int32_t schInitTask(SSchJob *pJob, SSchTask *pTask, SSubplan *pPlan, SSchLevel *
|
|||
}
|
||||
|
||||
int32_t schInitJob(SSchJob **pSchJob, SQueryPlan *pDag, void *transport, SArray *pNodeList, const char *sql,
|
||||
int64_t startTs, bool syncSchedule) {
|
||||
int64_t startTs, bool needRes, bool syncSchedule) {
|
||||
int32_t code = 0;
|
||||
int64_t refId = -1;
|
||||
SSchJob *pJob = taosMemoryCalloc(1, sizeof(SSchJob));
|
||||
|
@ -81,6 +81,7 @@ int32_t schInitJob(SSchJob **pSchJob, SQueryPlan *pDag, void *transport, SArray
|
|||
|
||||
pJob->attr.explainMode = pDag->explainInfo.mode;
|
||||
pJob->attr.syncSchedule = syncSchedule;
|
||||
pJob->attr.needRes = needRes;
|
||||
pJob->transport = transport;
|
||||
pJob->sql = sql;
|
||||
|
||||
|
@ -1091,11 +1092,10 @@ int32_t schHandleResponseMsg(SSchJob *pJob, SSchTask *pTask, int32_t msgType, ch
|
|||
if (TSDB_CODE_SUCCESS == code && batchRsp.nRsps > 0) {
|
||||
for (int32_t i = 0; i < batchRsp.nRsps; ++i) {
|
||||
SVCreateTbRsp *rsp = batchRsp.pRsps + i;
|
||||
if (NEED_CLIENT_HANDLE_ERROR(rsp->code)) {
|
||||
tDecoderClear(&coder);
|
||||
SCH_ERR_JRET(rsp->code);
|
||||
} else if (TSDB_CODE_SUCCESS != rsp->code) {
|
||||
if (TSDB_CODE_SUCCESS != rsp->code) {
|
||||
code = rsp->code;
|
||||
tDecoderClear(&coder);
|
||||
SCH_ERR_JRET(code);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1116,11 +1116,10 @@ int32_t schHandleResponseMsg(SSchJob *pJob, SSchTask *pTask, int32_t msgType, ch
|
|||
if (TSDB_CODE_SUCCESS == code && batchRsp.nRsps > 0) {
|
||||
for (int32_t i = 0; i < batchRsp.nRsps; ++i) {
|
||||
SVDropTbRsp *rsp = batchRsp.pRsps + i;
|
||||
if (NEED_CLIENT_HANDLE_ERROR(rsp->code)) {
|
||||
tDecoderClear(&coder);
|
||||
SCH_ERR_JRET(rsp->code);
|
||||
} else if (TSDB_CODE_SUCCESS != rsp->code) {
|
||||
if (TSDB_CODE_SUCCESS != rsp->code) {
|
||||
code = rsp->code;
|
||||
tDecoderClear(&coder);
|
||||
SCH_ERR_JRET(code);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1133,16 +1132,50 @@ int32_t schHandleResponseMsg(SSchJob *pJob, SSchTask *pTask, int32_t msgType, ch
|
|||
break;
|
||||
}
|
||||
case TDMT_VND_SUBMIT_RSP: {
|
||||
if (msg) {
|
||||
SSubmitRsp *rsp = (SSubmitRsp *)msg;
|
||||
SCH_ERR_JRET(rsp->code);
|
||||
}
|
||||
|
||||
SCH_ERR_JRET(rspCode);
|
||||
|
||||
SSubmitRsp *rsp = (SSubmitRsp *)msg;
|
||||
if (rsp) {
|
||||
pJob->resNumOfRows += rsp->affectedRows;
|
||||
if (msg) {
|
||||
SDecoder coder = {0};
|
||||
SSubmitRsp *rsp = taosMemoryMalloc(sizeof(*rsp));
|
||||
tDecoderInit(&coder, msg, msgSize);
|
||||
code = tDecodeSSubmitRsp(&coder, rsp);
|
||||
if (code) {
|
||||
SCH_TASK_ELOG("decode submitRsp failed, code:%d", code);
|
||||
tFreeSSubmitRsp(rsp);
|
||||
SCH_ERR_JRET(code);
|
||||
}
|
||||
|
||||
if (rsp->nBlocks > 0) {
|
||||
for (int32_t i = 0; i < rsp->nBlocks; ++i) {
|
||||
SSubmitBlkRsp *blk = rsp->pBlocks + i;
|
||||
if (TSDB_CODE_SUCCESS != blk->code) {
|
||||
code = blk->code;
|
||||
tFreeSSubmitRsp(rsp);
|
||||
SCH_ERR_JRET(code);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
atomic_add_fetch_32(&pJob->resNumOfRows, rsp->affectedRows);
|
||||
SCH_TASK_DLOG("submit succeed, affectedRows:%d", rsp->affectedRows);
|
||||
|
||||
if (pJob->attr.needRes) {
|
||||
SCH_LOCK(SCH_WRITE, &pJob->resLock);
|
||||
if (pJob->resData) {
|
||||
SSubmitRsp *sum = pJob->resData;
|
||||
sum->affectedRows += rsp->affectedRows;
|
||||
sum->nBlocks += rsp->nBlocks;
|
||||
sum->pBlocks = taosMemoryRealloc(sum->pBlocks, sum->nBlocks * sizeof(*sum->pBlocks));
|
||||
memcpy(sum->pBlocks + sum->nBlocks - rsp->nBlocks, rsp->pBlocks, rsp->nBlocks * sizeof(*sum->pBlocks));
|
||||
taosMemoryFree(rsp->pBlocks);
|
||||
taosMemoryFree(rsp);
|
||||
} else {
|
||||
pJob->resData = rsp;
|
||||
}
|
||||
SCH_UNLOCK(SCH_WRITE, &pJob->resLock);
|
||||
} else {
|
||||
tFreeSSubmitRsp(rsp);
|
||||
}
|
||||
}
|
||||
|
||||
SCH_ERR_RET(schProcessOnTaskSuccess(pJob, pTask));
|
||||
|
@ -2350,7 +2383,7 @@ void schFreeJobImpl(void *job) {
|
|||
}
|
||||
|
||||
static int32_t schExecJobImpl(void *transport, SArray *pNodeList, SQueryPlan *pDag, int64_t *job, const char *sql,
|
||||
int64_t startTs, bool syncSchedule) {
|
||||
int64_t startTs, bool needRes, bool syncSchedule) {
|
||||
qDebug("QID:0x%" PRIx64 " job started", pDag->queryId);
|
||||
|
||||
if (pNodeList == NULL || taosArrayGetSize(pNodeList) <= 0) {
|
||||
|
@ -2359,7 +2392,7 @@ static int32_t schExecJobImpl(void *transport, SArray *pNodeList, SQueryPlan *pD
|
|||
|
||||
int32_t code = 0;
|
||||
SSchJob *pJob = NULL;
|
||||
SCH_ERR_JRET(schInitJob(&pJob, pDag, transport, pNodeList, sql, startTs, syncSchedule));
|
||||
SCH_ERR_JRET(schInitJob(&pJob, pDag, transport, pNodeList, sql, startTs, needRes, syncSchedule));
|
||||
|
||||
SCH_ERR_JRET(schLaunchJob(pJob));
|
||||
|
||||
|
@ -2473,7 +2506,7 @@ int32_t schedulerInit(SSchedulerCfg *cfg) {
|
|||
}
|
||||
|
||||
int32_t schedulerExecJob(void *transport, SArray *nodeList, SQueryPlan *pDag, int64_t *pJob, const char *sql,
|
||||
int64_t startTs, SQueryResult *pRes) {
|
||||
int64_t startTs, bool needRes, SQueryResult *pRes) {
|
||||
if (NULL == transport || NULL == pDag || NULL == pDag->pSubplans || NULL == pJob || NULL == pRes) {
|
||||
SCH_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
|
||||
}
|
||||
|
@ -2481,13 +2514,17 @@ int32_t schedulerExecJob(void *transport, SArray *nodeList, SQueryPlan *pDag, in
|
|||
if (EXPLAIN_MODE_STATIC == pDag->explainInfo.mode) {
|
||||
SCH_ERR_RET(schExecStaticExplain(transport, nodeList, pDag, pJob, sql, true));
|
||||
} else {
|
||||
SCH_ERR_RET(schExecJobImpl(transport, nodeList, pDag, pJob, sql, startTs, true));
|
||||
SCH_ERR_RET(schExecJobImpl(transport, nodeList, pDag, pJob, sql, startTs, needRes, true));
|
||||
}
|
||||
|
||||
SSchJob *job = schAcquireJob(*pJob);
|
||||
|
||||
pRes->code = atomic_load_32(&job->errCode);
|
||||
pRes->numOfRows = job->resNumOfRows;
|
||||
if (needRes) {
|
||||
pRes->res = job->resData;
|
||||
job->resData = NULL;
|
||||
}
|
||||
|
||||
schReleaseJob(*pJob);
|
||||
|
||||
|
@ -2502,7 +2539,7 @@ int32_t schedulerAsyncExecJob(void *transport, SArray *pNodeList, SQueryPlan *pD
|
|||
if (EXPLAIN_MODE_STATIC == pDag->explainInfo.mode) {
|
||||
SCH_ERR_RET(schExecStaticExplain(transport, pNodeList, pDag, pJob, sql, false));
|
||||
} else {
|
||||
SCH_ERR_RET(schExecJobImpl(transport, pNodeList, pDag, pJob, sql, 0, false));
|
||||
SCH_ERR_RET(schExecJobImpl(transport, pNodeList, pDag, pJob, sql, 0, false, false));
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
|
|
@ -985,7 +985,7 @@ TEST(insertTest, normalCase) {
|
|||
taosThreadCreate(&(thread1), &thattr, schtSendRsp, &insertJobRefId);
|
||||
|
||||
SQueryResult res = {0};
|
||||
code = schedulerExecJob(mockPointer, qnodeList, &dag, &insertJobRefId, "insert into tb values(now,1)", 0, &res);
|
||||
code = schedulerExecJob(mockPointer, qnodeList, &dag, &insertJobRefId, "insert into tb values(now,1)", 0, false, &res);
|
||||
ASSERT_EQ(code, 0);
|
||||
ASSERT_EQ(res.numOfRows, 20);
|
||||
|
||||
|
|
|
@ -271,6 +271,7 @@ int32_t syncNodeSendMsgByInfo(const SNodeInfo* nodeInfo, SSyncNode* pSyncNode, S
|
|||
cJSON* syncNode2Json(const SSyncNode* pSyncNode);
|
||||
char* syncNode2Str(const SSyncNode* pSyncNode);
|
||||
char* syncNode2SimpleStr(const SSyncNode* pSyncNode);
|
||||
void syncNodeUpdateConfig(SSyncNode* pSyncNode, SSyncCfg *newConfig);
|
||||
|
||||
SSyncNode* syncNodeAcquire(int64_t rid);
|
||||
void syncNodeRelease(SSyncNode* pNode);
|
||||
|
|
|
@ -57,6 +57,11 @@ SyncIndex syncUtilMinIndex(SyncIndex a, SyncIndex b);
|
|||
SyncIndex syncUtilMaxIndex(SyncIndex a, SyncIndex b);
|
||||
void syncUtilMsgHtoN(void* msg);
|
||||
void syncUtilMsgNtoH(void* msg);
|
||||
bool syncUtilIsData(tmsg_t msgType);
|
||||
bool syncUtilUserPreCommit(tmsg_t msgType);
|
||||
bool syncUtilUserCommit(tmsg_t msgType);
|
||||
bool syncUtilUserRollback(tmsg_t msgType);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "syncRaftStore.h"
|
||||
#include "syncUtil.h"
|
||||
#include "syncVoteMgr.h"
|
||||
#include "syncRaftCfg.h"
|
||||
|
||||
// TLA+ Spec
|
||||
// HandleAppendEntriesRequest(i, j, m) ==
|
||||
|
@ -199,7 +200,8 @@ int32_t syncNodeOnAppendEntriesCb(SSyncNode* ths, SyncAppendEntries* pMsg) {
|
|||
SSyncRaftEntry* pRollBackEntry = logStoreGetEntry(ths->pLogStore, index);
|
||||
assert(pRollBackEntry != NULL);
|
||||
|
||||
if (pRollBackEntry->msgType != TDMT_VND_SYNC_NOOP) {
|
||||
//if (pRollBackEntry->msgType != TDMT_VND_SYNC_NOOP) {
|
||||
if (syncUtilUserRollback(pRollBackEntry->msgType)) {
|
||||
SRpcMsg rpcMsg;
|
||||
syncEntry2OriginalRpc(pRollBackEntry, &rpcMsg);
|
||||
|
||||
|
@ -227,7 +229,8 @@ int32_t syncNodeOnAppendEntriesCb(SSyncNode* ths, SyncAppendEntries* pMsg) {
|
|||
SRpcMsg rpcMsg;
|
||||
syncEntry2OriginalRpc(pAppendEntry, &rpcMsg);
|
||||
if (ths->pFsm != NULL) {
|
||||
if (ths->pFsm->FpPreCommitCb != NULL && pAppendEntry->originalRpcType != TDMT_VND_SYNC_NOOP) {
|
||||
//if (ths->pFsm->FpPreCommitCb != NULL && pAppendEntry->originalRpcType != TDMT_VND_SYNC_NOOP) {
|
||||
if (ths->pFsm->FpPreCommitCb != NULL && syncUtilUserPreCommit(pAppendEntry->originalRpcType)) {
|
||||
SFsmCbMeta cbMeta;
|
||||
cbMeta.index = pAppendEntry->index;
|
||||
cbMeta.isWeak = pAppendEntry->isWeak;
|
||||
|
@ -258,7 +261,8 @@ int32_t syncNodeOnAppendEntriesCb(SSyncNode* ths, SyncAppendEntries* pMsg) {
|
|||
SRpcMsg rpcMsg;
|
||||
syncEntry2OriginalRpc(pAppendEntry, &rpcMsg);
|
||||
if (ths->pFsm != NULL) {
|
||||
if (ths->pFsm->FpPreCommitCb != NULL && pAppendEntry->originalRpcType != TDMT_VND_SYNC_NOOP) {
|
||||
//if (ths->pFsm->FpPreCommitCb != NULL && pAppendEntry->originalRpcType != TDMT_VND_SYNC_NOOP) {
|
||||
if (ths->pFsm->FpPreCommitCb != NULL && syncUtilUserPreCommit(pAppendEntry->originalRpcType)) {
|
||||
SFsmCbMeta cbMeta;
|
||||
cbMeta.index = pAppendEntry->index;
|
||||
cbMeta.isWeak = pAppendEntry->isWeak;
|
||||
|
@ -320,7 +324,8 @@ int32_t syncNodeOnAppendEntriesCb(SSyncNode* ths, SyncAppendEntries* pMsg) {
|
|||
SRpcMsg rpcMsg;
|
||||
syncEntry2OriginalRpc(pEntry, &rpcMsg);
|
||||
|
||||
if (ths->pFsm->FpCommitCb != NULL && pEntry->originalRpcType != TDMT_VND_SYNC_NOOP) {
|
||||
//if (ths->pFsm->FpCommitCb != NULL && pEntry->originalRpcType != TDMT_VND_SYNC_NOOP) {
|
||||
if (ths->pFsm->FpCommitCb != NULL && syncUtilUserCommit(pEntry->originalRpcType)) {
|
||||
SFsmCbMeta cbMeta;
|
||||
cbMeta.index = pEntry->index;
|
||||
cbMeta.isWeak = pEntry->isWeak;
|
||||
|
@ -330,6 +335,15 @@ int32_t syncNodeOnAppendEntriesCb(SSyncNode* ths, SyncAppendEntries* pMsg) {
|
|||
ths->pFsm->FpCommitCb(ths->pFsm, &rpcMsg, cbMeta);
|
||||
}
|
||||
|
||||
// config change
|
||||
if (pEntry->originalRpcType == TDMT_VND_SYNC_CONFIG_CHANGE) {
|
||||
SSyncCfg newSyncCfg;
|
||||
int32_t ret = syncCfgFromStr(rpcMsg.pCont, &newSyncCfg);
|
||||
ASSERT(ret == 0);
|
||||
|
||||
syncNodeUpdateConfig(ths, &newSyncCfg);
|
||||
}
|
||||
|
||||
rpcFreeCont(rpcMsg.pCont);
|
||||
syncEntryDestory(pEntry);
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "syncRaftLog.h"
|
||||
#include "syncRaftStore.h"
|
||||
#include "syncUtil.h"
|
||||
#include "syncRaftCfg.h"
|
||||
|
||||
// \* Leader i advances its commitIndex.
|
||||
// \* This is done as a separate step from handling AppendEntries responses,
|
||||
|
@ -101,7 +102,8 @@ void syncMaybeAdvanceCommitIndex(SSyncNode* pSyncNode) {
|
|||
SRpcMsg rpcMsg;
|
||||
syncEntry2OriginalRpc(pEntry, &rpcMsg);
|
||||
|
||||
if (pSyncNode->pFsm->FpCommitCb != NULL && pEntry->originalRpcType != TDMT_VND_SYNC_NOOP) {
|
||||
//if (pSyncNode->pFsm->FpCommitCb != NULL && pEntry->originalRpcType != TDMT_VND_SYNC_NOOP) {
|
||||
if (pSyncNode->pFsm->FpCommitCb != NULL && syncUtilUserCommit(pEntry->originalRpcType)) {
|
||||
SFsmCbMeta cbMeta;
|
||||
cbMeta.index = pEntry->index;
|
||||
cbMeta.isWeak = pEntry->isWeak;
|
||||
|
@ -111,6 +113,15 @@ void syncMaybeAdvanceCommitIndex(SSyncNode* pSyncNode) {
|
|||
pSyncNode->pFsm->FpCommitCb(pSyncNode->pFsm, &rpcMsg, cbMeta);
|
||||
}
|
||||
|
||||
// config change
|
||||
if (pEntry->originalRpcType == TDMT_VND_SYNC_CONFIG_CHANGE) {
|
||||
SSyncCfg newSyncCfg;
|
||||
int32_t ret = syncCfgFromStr(rpcMsg.pCont, &newSyncCfg);
|
||||
ASSERT(ret == 0);
|
||||
|
||||
syncNodeUpdateConfig(pSyncNode, &newSyncCfg);
|
||||
}
|
||||
|
||||
rpcFreeCont(rpcMsg.pCont);
|
||||
syncEntryDestory(pEntry);
|
||||
}
|
||||
|
|
|
@ -116,6 +116,15 @@ void syncStop(int64_t rid) {
|
|||
|
||||
int32_t syncReconfig(int64_t rid, const SSyncCfg* pSyncCfg) {
|
||||
int32_t ret = 0;
|
||||
char *configChange = syncCfg2Str((SSyncCfg*)pSyncCfg);
|
||||
SRpcMsg rpcMsg = {0};
|
||||
rpcMsg.msgType = TDMT_VND_SYNC_CONFIG_CHANGE;
|
||||
rpcMsg.noResp = 1;
|
||||
rpcMsg.contLen = strlen(configChange) + 1;
|
||||
rpcMsg.pCont = rpcMallocCont(rpcMsg.contLen);
|
||||
snprintf(rpcMsg.pCont, rpcMsg.contLen, "%s", configChange);
|
||||
taosMemoryFree(configChange);
|
||||
ret = syncPropose(rid, &rpcMsg, false);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -849,6 +858,35 @@ char* syncNode2SimpleStr(const SSyncNode* pSyncNode) {
|
|||
return s;
|
||||
}
|
||||
|
||||
void syncNodeUpdateConfig(SSyncNode* pSyncNode, SSyncCfg *newConfig) {
|
||||
pSyncNode->pRaftCfg->cfg = *newConfig;
|
||||
int32_t ret = raftCfgPersist(pSyncNode->pRaftCfg);
|
||||
ASSERT(ret == 0);
|
||||
|
||||
// init internal
|
||||
pSyncNode->myNodeInfo = pSyncNode->pRaftCfg->cfg.nodeInfo[pSyncNode->pRaftCfg->cfg.myIndex];
|
||||
syncUtilnodeInfo2raftId(&pSyncNode->myNodeInfo, pSyncNode->vgId, &pSyncNode->myRaftId);
|
||||
|
||||
// init peersNum, peers, peersId
|
||||
pSyncNode->peersNum = pSyncNode->pRaftCfg->cfg.replicaNum - 1;
|
||||
int j = 0;
|
||||
for (int i = 0; i < pSyncNode->pRaftCfg->cfg.replicaNum; ++i) {
|
||||
if (i != pSyncNode->pRaftCfg->cfg.myIndex) {
|
||||
pSyncNode->peersNodeInfo[j] = pSyncNode->pRaftCfg->cfg.nodeInfo[i];
|
||||
j++;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < pSyncNode->peersNum; ++i) {
|
||||
syncUtilnodeInfo2raftId(&pSyncNode->peersNodeInfo[i], pSyncNode->vgId, &pSyncNode->peersId[i]);
|
||||
}
|
||||
|
||||
// init replicaNum, replicasId
|
||||
pSyncNode->replicaNum = pSyncNode->pRaftCfg->cfg.replicaNum;
|
||||
for (int i = 0; i < pSyncNode->pRaftCfg->cfg.replicaNum; ++i) {
|
||||
syncUtilnodeInfo2raftId(&pSyncNode->pRaftCfg->cfg.nodeInfo[i], pSyncNode->vgId, &pSyncNode->replicasId[i]);
|
||||
}
|
||||
}
|
||||
|
||||
SSyncNode* syncNodeAcquire(int64_t rid) {
|
||||
SSyncNode* pNode = taosAcquireRef(tsNodeRefId, rid);
|
||||
if (pNode == NULL) {
|
||||
|
@ -1207,7 +1245,8 @@ int32_t syncNodeOnClientRequestCb(SSyncNode* ths, SyncClientRequest* pMsg) {
|
|||
syncEntry2OriginalRpc(pEntry, &rpcMsg);
|
||||
|
||||
if (ths->pFsm != NULL) {
|
||||
if (ths->pFsm->FpPreCommitCb != NULL && pEntry->originalRpcType != TDMT_VND_SYNC_NOOP) {
|
||||
//if (ths->pFsm->FpPreCommitCb != NULL && pEntry->originalRpcType != TDMT_VND_SYNC_NOOP) {
|
||||
if (ths->pFsm->FpPreCommitCb != NULL && syncUtilUserPreCommit(pEntry->originalRpcType)) {
|
||||
SFsmCbMeta cbMeta;
|
||||
cbMeta.index = pEntry->index;
|
||||
cbMeta.isWeak = pEntry->isWeak;
|
||||
|
@ -1228,7 +1267,8 @@ int32_t syncNodeOnClientRequestCb(SSyncNode* ths, SyncClientRequest* pMsg) {
|
|||
syncEntry2OriginalRpc(pEntry, &rpcMsg);
|
||||
|
||||
if (ths->pFsm != NULL) {
|
||||
if (ths->pFsm->FpPreCommitCb != NULL && pEntry->originalRpcType != TDMT_VND_SYNC_NOOP) {
|
||||
//if (ths->pFsm->FpPreCommitCb != NULL && pEntry->originalRpcType != TDMT_VND_SYNC_NOOP) {
|
||||
if (ths->pFsm->FpPreCommitCb != NULL && syncUtilUserPreCommit(pEntry->originalRpcType)) {
|
||||
SFsmCbMeta cbMeta;
|
||||
cbMeta.index = pEntry->index;
|
||||
cbMeta.isWeak = pEntry->isWeak;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue