Merge from master
This commit is contained in:
commit
e99a35a5b0
|
@ -5,7 +5,6 @@ node {
|
||||||
git url: 'https://github.com/taosdata/TDengine.git'
|
git url: 'https://github.com/taosdata/TDengine.git'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def skipbuild=0
|
def skipbuild=0
|
||||||
|
|
||||||
def abortPreviousBuilds() {
|
def abortPreviousBuilds() {
|
||||||
|
@ -107,19 +106,17 @@ def pre_test(){
|
||||||
make > /dev/null
|
make > /dev/null
|
||||||
make install > /dev/null
|
make install > /dev/null
|
||||||
cd ${WKC}/tests
|
cd ${WKC}/tests
|
||||||
pip3 install ${WKC}/src/connector/python
|
pip3 install ${WKC}/src/connector/python/
|
||||||
'''
|
'''
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
pipeline {
|
pipeline {
|
||||||
agent none
|
agent none
|
||||||
|
|
||||||
environment{
|
environment{
|
||||||
WK = '/var/lib/jenkins/workspace/TDinternal'
|
WK = '/var/lib/jenkins/workspace/TDinternal'
|
||||||
WKC= '/var/lib/jenkins/workspace/TDinternal/community'
|
WKC= '/var/lib/jenkins/workspace/TDinternal/community'
|
||||||
}
|
}
|
||||||
|
|
||||||
stages {
|
stages {
|
||||||
stage('pre_build'){
|
stage('pre_build'){
|
||||||
agent{label 'master'}
|
agent{label 'master'}
|
||||||
|
@ -159,7 +156,6 @@ pipeline {
|
||||||
git checkout -qf FETCH_HEAD
|
git checkout -qf FETCH_HEAD
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
script{
|
script{
|
||||||
skipbuild='2'
|
skipbuild='2'
|
||||||
skipbuild=sh(script: "git log -2 --pretty=%B | fgrep -ie '[skip ci]' -e '[ci skip]' && echo 1 || echo 2", returnStdout:true)
|
skipbuild=sh(script: "git log -2 --pretty=%B | fgrep -ie '[skip ci]' -e '[ci skip]' && echo 1 || echo 2", returnStdout:true)
|
||||||
|
@ -171,7 +167,6 @@ pipeline {
|
||||||
'''
|
'''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stage('Parallel test stage') {
|
stage('Parallel test stage') {
|
||||||
//only build pr
|
//only build pr
|
||||||
when {
|
when {
|
||||||
|
@ -237,7 +232,6 @@ pipeline {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stage('test_crash_gen_s3') {
|
stage('test_crash_gen_s3') {
|
||||||
agent{label " slave3 || slave13 "}
|
agent{label " slave3 || slave13 "}
|
||||||
|
|
||||||
|
@ -273,10 +267,8 @@ pipeline {
|
||||||
date
|
date
|
||||||
'''
|
'''
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stage('test_valgrind_s4') {
|
stage('test_valgrind_s4') {
|
||||||
agent{label " slave4 || slave14 "}
|
agent{label " slave4 || slave14 "}
|
||||||
|
|
||||||
|
@ -442,5 +434,4 @@ pipeline {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -84,9 +84,14 @@ typedef struct SParamInfo {
|
||||||
} SParamInfo;
|
} SParamInfo;
|
||||||
|
|
||||||
typedef struct SBoundColumn {
|
typedef struct SBoundColumn {
|
||||||
bool hasVal; // denote if current column has bound or not
|
|
||||||
int32_t offset; // all column offset value
|
int32_t offset; // all column offset value
|
||||||
|
int32_t toffset; // first part offset for SDataRow TODO: get offset from STSchema on future
|
||||||
|
uint8_t valStat; // denote if current column bound or not(0 means has val, 1 means no val)
|
||||||
} SBoundColumn;
|
} SBoundColumn;
|
||||||
|
typedef enum {
|
||||||
|
VAL_STAT_HAS = 0x0, // 0 means has val
|
||||||
|
VAL_STAT_NONE = 0x01, // 1 means no val
|
||||||
|
} EValStat;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint16_t schemaColIdx;
|
uint16_t schemaColIdx;
|
||||||
|
@ -99,32 +104,106 @@ typedef enum _COL_ORDER_STATUS {
|
||||||
ORDER_STATUS_ORDERED = 1,
|
ORDER_STATUS_ORDERED = 1,
|
||||||
ORDER_STATUS_DISORDERED = 2,
|
ORDER_STATUS_DISORDERED = 2,
|
||||||
} EOrderStatus;
|
} EOrderStatus;
|
||||||
|
|
||||||
typedef struct SParsedDataColInfo {
|
typedef struct SParsedDataColInfo {
|
||||||
int16_t numOfCols;
|
int16_t numOfCols;
|
||||||
int16_t numOfBound;
|
int16_t numOfBound;
|
||||||
int32_t * boundedColumns; // bounded column idx according to schema
|
uint16_t flen; // TODO: get from STSchema
|
||||||
|
uint16_t allNullLen; // TODO: get from STSchema
|
||||||
|
uint16_t extendedVarLen;
|
||||||
|
int32_t * boundedColumns; // bound column idx according to schema
|
||||||
SBoundColumn * cols;
|
SBoundColumn * cols;
|
||||||
SBoundIdxInfo *colIdxInfo;
|
SBoundIdxInfo *colIdxInfo;
|
||||||
int8_t orderStatus; // bounded columns:
|
int8_t orderStatus; // bound columns
|
||||||
} SParsedDataColInfo;
|
} SParsedDataColInfo;
|
||||||
|
|
||||||
#define IS_DATA_COL_ORDERED(s) ((s) == (int8_t)ORDER_STATUS_ORDERED)
|
#define IS_DATA_COL_ORDERED(spd) ((spd->orderStatus) == (int8_t)ORDER_STATUS_ORDERED)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
SSchema * pSchema;
|
int32_t dataLen; // len of SDataRow
|
||||||
int16_t sversion;
|
int32_t kvLen; // len of SKVRow
|
||||||
int32_t flen;
|
} SMemRowInfo;
|
||||||
uint16_t nCols;
|
typedef struct {
|
||||||
void * buf;
|
uint8_t memRowType;
|
||||||
void * pDataBlock;
|
uint8_t compareStat; // 0 unknown, 1 need compare, 2 no need
|
||||||
SSubmitBlk *pSubmitBlk;
|
TDRowTLenT dataRowInitLen;
|
||||||
|
TDRowTLenT kvRowInitLen;
|
||||||
|
SMemRowInfo *rowInfo;
|
||||||
} SMemRowBuilder;
|
} SMemRowBuilder;
|
||||||
|
|
||||||
typedef struct {
|
typedef enum {
|
||||||
TDRowLenT allNullLen;
|
ROW_COMPARE_UNKNOWN = 0,
|
||||||
} SMemRowHelper;
|
ROW_COMPARE_NEED = 1,
|
||||||
|
ROW_COMPARE_NO_NEED = 2,
|
||||||
|
} ERowCompareStat;
|
||||||
|
|
||||||
|
int tsParseTime(SStrToken *pToken, int64_t *time, char **next, char *error, int16_t timePrec);
|
||||||
|
|
||||||
|
int initMemRowBuilder(SMemRowBuilder *pBuilder, uint32_t nRows, uint32_t nCols, uint32_t nBoundCols,
|
||||||
|
int32_t allNullLen);
|
||||||
|
void destroyMemRowBuilder(SMemRowBuilder *pBuilder);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
* @param memRowType
|
||||||
|
* @param spd
|
||||||
|
* @param idx the absolute bound index of columns
|
||||||
|
* @return FORCE_INLINE
|
||||||
|
*/
|
||||||
|
static FORCE_INLINE void tscGetMemRowAppendInfo(SSchema *pSchema, uint8_t memRowType, SParsedDataColInfo *spd,
|
||||||
|
int32_t idx, int32_t *toffset, int16_t *colId) {
|
||||||
|
int32_t schemaIdx = 0;
|
||||||
|
if (IS_DATA_COL_ORDERED(spd)) {
|
||||||
|
schemaIdx = spd->boundedColumns[idx];
|
||||||
|
if (isDataRowT(memRowType)) {
|
||||||
|
*toffset = (spd->cols + schemaIdx)->toffset; // the offset of firstPart
|
||||||
|
} else {
|
||||||
|
*toffset = idx * sizeof(SColIdx); // the offset of SColIdx
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ASSERT(idx == (spd->colIdxInfo + idx)->boundIdx);
|
||||||
|
schemaIdx = (spd->colIdxInfo + idx)->schemaColIdx;
|
||||||
|
if (isDataRowT(memRowType)) {
|
||||||
|
*toffset = (spd->cols + schemaIdx)->toffset;
|
||||||
|
} else {
|
||||||
|
*toffset = ((spd->colIdxInfo + idx)->finalIdx) * sizeof(SColIdx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*colId = pSchema[schemaIdx].colId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Applicable to consume by multi-columns
|
||||||
|
*
|
||||||
|
* @param row
|
||||||
|
* @param value
|
||||||
|
* @param isCopyVarData In some scenario, the varVal is copied to row directly before calling tdAppend***ColVal()
|
||||||
|
* @param colId
|
||||||
|
* @param colType
|
||||||
|
* @param idx index in SSchema
|
||||||
|
* @param pBuilder
|
||||||
|
* @param spd
|
||||||
|
* @return FORCE_INLINE
|
||||||
|
*/
|
||||||
|
static FORCE_INLINE void tscAppendMemRowColVal(SMemRow row, const void *value, bool isCopyVarData, int16_t colId,
|
||||||
|
int8_t colType, int32_t toffset, SMemRowBuilder *pBuilder,
|
||||||
|
int32_t rowNum) {
|
||||||
|
tdAppendMemRowColVal(row, value, isCopyVarData, colId, colType, toffset);
|
||||||
|
if (pBuilder->compareStat == ROW_COMPARE_NEED) {
|
||||||
|
SMemRowInfo *pRowInfo = pBuilder->rowInfo + rowNum;
|
||||||
|
tdGetColAppendDeltaLen(value, colType, &pRowInfo->dataLen, &pRowInfo->kvLen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Applicable to consume by one row
|
||||||
|
static FORCE_INLINE void tscAppendMemRowColValEx(SMemRow row, const void *value, bool isCopyVarData, int16_t colId,
|
||||||
|
int8_t colType, int32_t toffset, int32_t *dataLen, int32_t *kvLen,
|
||||||
|
uint8_t compareStat) {
|
||||||
|
tdAppendMemRowColVal(row, value, isCopyVarData, colId, colType, toffset);
|
||||||
|
if (compareStat == ROW_COMPARE_NEED) {
|
||||||
|
tdGetColAppendDeltaLen(value, colType, dataLen, kvLen);
|
||||||
|
}
|
||||||
|
}
|
||||||
typedef struct STableDataBlocks {
|
typedef struct STableDataBlocks {
|
||||||
SName tableName;
|
SName tableName;
|
||||||
int8_t tsSource; // where does the UNIX timestamp come from, server or client
|
int8_t tsSource; // where does the UNIX timestamp come from, server or client
|
||||||
|
@ -146,7 +225,7 @@ typedef struct STableDataBlocks {
|
||||||
uint32_t numOfAllocedParams;
|
uint32_t numOfAllocedParams;
|
||||||
uint32_t numOfParams;
|
uint32_t numOfParams;
|
||||||
SParamInfo * params;
|
SParamInfo * params;
|
||||||
SMemRowHelper rowHelper;
|
SMemRowBuilder rowBuilder;
|
||||||
} STableDataBlocks;
|
} STableDataBlocks;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -435,8 +514,398 @@ int16_t getNewResColId(SSqlCmd* pCmd);
|
||||||
|
|
||||||
int32_t schemaIdxCompar(const void *lhs, const void *rhs);
|
int32_t schemaIdxCompar(const void *lhs, const void *rhs);
|
||||||
int32_t boundIdxCompar(const void *lhs, const void *rhs);
|
int32_t boundIdxCompar(const void *lhs, const void *rhs);
|
||||||
int initSMemRowHelper(SMemRowHelper *pHelper, SSchema *pSSchema, uint16_t nCols, uint16_t allNullColsLen);
|
static FORCE_INLINE int32_t getExtendedRowSize(STableDataBlocks *pBlock) {
|
||||||
int32_t getExtendedRowSize(STableComInfo *tinfo);
|
ASSERT(pBlock->rowSize == pBlock->pTableMeta->tableInfo.rowSize);
|
||||||
|
return pBlock->rowSize + TD_MEM_ROW_DATA_HEAD_SIZE + pBlock->boundColumnInfo.extendedVarLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
static FORCE_INLINE void checkAndConvertMemRow(SMemRow row, int32_t dataLen, int32_t kvLen) {
|
||||||
|
if (isDataRow(row)) {
|
||||||
|
if (kvLen < (dataLen * KVRatioConvert)) {
|
||||||
|
memRowSetConvert(row);
|
||||||
|
}
|
||||||
|
} else if (kvLen > dataLen) {
|
||||||
|
memRowSetConvert(row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static FORCE_INLINE void initSMemRow(SMemRow row, uint8_t memRowType, STableDataBlocks *pBlock, int16_t nBoundCols) {
|
||||||
|
memRowSetType(row, memRowType);
|
||||||
|
if (isDataRowT(memRowType)) {
|
||||||
|
dataRowSetVersion(memRowDataBody(row), pBlock->pTableMeta->sversion);
|
||||||
|
dataRowSetLen(memRowDataBody(row), (TDRowLenT)(TD_DATA_ROW_HEAD_SIZE + pBlock->boundColumnInfo.flen));
|
||||||
|
} else {
|
||||||
|
ASSERT(nBoundCols > 0);
|
||||||
|
memRowSetKvVersion(row, pBlock->pTableMeta->sversion);
|
||||||
|
kvRowSetNCols(memRowKvBody(row), nBoundCols);
|
||||||
|
kvRowSetLen(memRowKvBody(row), (TDRowLenT)(TD_KV_ROW_HEAD_SIZE + sizeof(SColIdx) * nBoundCols));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* TODO: Move to tdataformat.h and refactor when STSchema available.
|
||||||
|
* - fetch flen and toffset from STSChema and remove param spd
|
||||||
|
*/
|
||||||
|
static FORCE_INLINE void convertToSDataRow(SMemRow dest, SMemRow src, SSchema *pSchema, int nCols,
|
||||||
|
SParsedDataColInfo *spd) {
|
||||||
|
ASSERT(isKvRow(src));
|
||||||
|
SKVRow kvRow = memRowKvBody(src);
|
||||||
|
SDataRow dataRow = memRowDataBody(dest);
|
||||||
|
|
||||||
|
memRowSetType(dest, SMEM_ROW_DATA);
|
||||||
|
dataRowSetVersion(dataRow, memRowKvVersion(src));
|
||||||
|
dataRowSetLen(dataRow, (TDRowLenT)(TD_DATA_ROW_HEAD_SIZE + spd->flen));
|
||||||
|
|
||||||
|
int32_t kvIdx = 0;
|
||||||
|
for (int i = 0; i < nCols; ++i) {
|
||||||
|
SSchema *schema = pSchema + i;
|
||||||
|
void * val = tdGetKVRowValOfColEx(kvRow, schema->colId, &kvIdx);
|
||||||
|
tdAppendDataColVal(dataRow, val != NULL ? val : getNullValue(schema->type), true, schema->type,
|
||||||
|
(spd->cols + i)->toffset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Move to tdataformat.h and refactor when STSchema available.
|
||||||
|
static FORCE_INLINE void convertToSKVRow(SMemRow dest, SMemRow src, SSchema *pSchema, int nCols, int nBoundCols,
|
||||||
|
SParsedDataColInfo *spd) {
|
||||||
|
ASSERT(isDataRow(src));
|
||||||
|
|
||||||
|
SDataRow dataRow = memRowDataBody(src);
|
||||||
|
SKVRow kvRow = memRowKvBody(dest);
|
||||||
|
|
||||||
|
memRowSetType(dest, SMEM_ROW_KV);
|
||||||
|
memRowSetKvVersion(kvRow, dataRowVersion(dataRow));
|
||||||
|
kvRowSetNCols(kvRow, nBoundCols);
|
||||||
|
kvRowSetLen(kvRow, (TDRowLenT)(TD_KV_ROW_HEAD_SIZE + sizeof(SColIdx) * nBoundCols));
|
||||||
|
|
||||||
|
int32_t toffset = 0, kvOffset = 0;
|
||||||
|
for (int i = 0; i < nCols; ++i) {
|
||||||
|
if ((spd->cols + i)->valStat == VAL_STAT_HAS) {
|
||||||
|
SSchema *schema = pSchema + i;
|
||||||
|
toffset = (spd->cols + i)->toffset;
|
||||||
|
void *val = tdGetRowDataOfCol(dataRow, schema->type, toffset + TD_DATA_ROW_HEAD_SIZE);
|
||||||
|
tdAppendKvColVal(kvRow, val, true, schema->colId, schema->type, kvOffset);
|
||||||
|
kvOffset += sizeof(SColIdx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Move to tdataformat.h and refactor when STSchema available.
|
||||||
|
static FORCE_INLINE void convertSMemRow(SMemRow dest, SMemRow src, STableDataBlocks *pBlock) {
|
||||||
|
STableMeta * pTableMeta = pBlock->pTableMeta;
|
||||||
|
STableComInfo tinfo = tscGetTableInfo(pTableMeta);
|
||||||
|
SSchema * pSchema = tscGetTableSchema(pTableMeta);
|
||||||
|
SParsedDataColInfo *spd = &pBlock->boundColumnInfo;
|
||||||
|
|
||||||
|
ASSERT(dest != src);
|
||||||
|
|
||||||
|
if (isDataRow(src)) {
|
||||||
|
// TODO: Can we use pBlock -> numOfParam directly?
|
||||||
|
ASSERT(spd->numOfBound > 0);
|
||||||
|
convertToSKVRow(dest, src, pSchema, tinfo.numOfColumns, spd->numOfBound, spd);
|
||||||
|
} else {
|
||||||
|
convertToSDataRow(dest, src, pSchema, tinfo.numOfColumns, spd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isNullStr(SStrToken *pToken) {
|
||||||
|
return (pToken->type == TK_NULL) || ((pToken->type == TK_STRING) && (pToken->n != 0) &&
|
||||||
|
(strncasecmp(TSDB_DATA_NULL_STR_L, pToken->z, pToken->n) == 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
static FORCE_INLINE int32_t tscToDouble(SStrToken *pToken, double *value, char **endPtr) {
|
||||||
|
errno = 0;
|
||||||
|
*value = strtold(pToken->z, endPtr);
|
||||||
|
|
||||||
|
// not a valid integer number, return error
|
||||||
|
if ((*endPtr - pToken->z) != pToken->n) {
|
||||||
|
return TK_ILLEGAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pToken->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t TRUE_VALUE = (uint8_t)TSDB_TRUE;
|
||||||
|
static uint8_t FALSE_VALUE = (uint8_t)TSDB_FALSE;
|
||||||
|
|
||||||
|
static FORCE_INLINE int32_t tsParseOneColumnKV(SSchema *pSchema, SStrToken *pToken, SMemRow row, char *msg, char **str,
|
||||||
|
bool primaryKey, int16_t timePrec, int32_t toffset, int16_t colId,
|
||||||
|
int32_t *dataLen, int32_t *kvLen, uint8_t compareStat) {
|
||||||
|
int64_t iv;
|
||||||
|
int32_t ret;
|
||||||
|
char * endptr = NULL;
|
||||||
|
|
||||||
|
if (IS_NUMERIC_TYPE(pSchema->type) && pToken->n == 0) {
|
||||||
|
return tscInvalidOperationMsg(msg, "invalid numeric data", pToken->z);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (pSchema->type) {
|
||||||
|
case TSDB_DATA_TYPE_BOOL: { // bool
|
||||||
|
if (isNullStr(pToken)) {
|
||||||
|
tscAppendMemRowColValEx(row, getNullValue(pSchema->type), true, colId, pSchema->type, toffset, dataLen, kvLen,
|
||||||
|
compareStat);
|
||||||
|
} else {
|
||||||
|
if ((pToken->type == TK_BOOL || pToken->type == TK_STRING) && (pToken->n != 0)) {
|
||||||
|
if (strncmp(pToken->z, "true", pToken->n) == 0) {
|
||||||
|
tscAppendMemRowColValEx(row, &TRUE_VALUE, true, colId, pSchema->type, toffset, dataLen, kvLen, compareStat);
|
||||||
|
} else if (strncmp(pToken->z, "false", pToken->n) == 0) {
|
||||||
|
tscAppendMemRowColValEx(row, &FALSE_VALUE, true, colId, pSchema->type, toffset, dataLen, kvLen,
|
||||||
|
compareStat);
|
||||||
|
} else {
|
||||||
|
return tscSQLSyntaxErrMsg(msg, "invalid bool data", pToken->z);
|
||||||
|
}
|
||||||
|
} else if (pToken->type == TK_INTEGER) {
|
||||||
|
iv = strtoll(pToken->z, NULL, 10);
|
||||||
|
tscAppendMemRowColValEx(row, ((iv == 0) ? &FALSE_VALUE : &TRUE_VALUE), true, colId, pSchema->type, toffset,
|
||||||
|
dataLen, kvLen, compareStat);
|
||||||
|
} else if (pToken->type == TK_FLOAT) {
|
||||||
|
double dv = strtod(pToken->z, NULL);
|
||||||
|
tscAppendMemRowColValEx(row, ((dv == 0) ? &FALSE_VALUE : &TRUE_VALUE), true, colId, pSchema->type, toffset,
|
||||||
|
dataLen, kvLen, compareStat);
|
||||||
|
} else {
|
||||||
|
return tscInvalidOperationMsg(msg, "invalid bool data", pToken->z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TSDB_DATA_TYPE_TINYINT:
|
||||||
|
if (isNullStr(pToken)) {
|
||||||
|
tscAppendMemRowColValEx(row, getNullValue(pSchema->type), true, colId, pSchema->type, toffset, dataLen, kvLen,
|
||||||
|
compareStat);
|
||||||
|
} else {
|
||||||
|
ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, true);
|
||||||
|
if (ret != TSDB_CODE_SUCCESS) {
|
||||||
|
return tscInvalidOperationMsg(msg, "invalid tinyint data", pToken->z);
|
||||||
|
} else if (!IS_VALID_TINYINT(iv)) {
|
||||||
|
return tscInvalidOperationMsg(msg, "data overflow", pToken->z);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t tmpVal = (uint8_t)iv;
|
||||||
|
tscAppendMemRowColValEx(row, &tmpVal, true, colId, pSchema->type, toffset, dataLen, kvLen, compareStat);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TSDB_DATA_TYPE_UTINYINT:
|
||||||
|
if (isNullStr(pToken)) {
|
||||||
|
tscAppendMemRowColValEx(row, getNullValue(pSchema->type), true, colId, pSchema->type, toffset, dataLen, kvLen,
|
||||||
|
compareStat);
|
||||||
|
} else {
|
||||||
|
ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, false);
|
||||||
|
if (ret != TSDB_CODE_SUCCESS) {
|
||||||
|
return tscInvalidOperationMsg(msg, "invalid unsigned tinyint data", pToken->z);
|
||||||
|
} else if (!IS_VALID_UTINYINT(iv)) {
|
||||||
|
return tscInvalidOperationMsg(msg, "unsigned tinyint data overflow", pToken->z);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t tmpVal = (uint8_t)iv;
|
||||||
|
tscAppendMemRowColValEx(row, &tmpVal, true, colId, pSchema->type, toffset, dataLen, kvLen, compareStat);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TSDB_DATA_TYPE_SMALLINT:
|
||||||
|
if (isNullStr(pToken)) {
|
||||||
|
tscAppendMemRowColValEx(row, getNullValue(pSchema->type), true, colId, pSchema->type, toffset, dataLen, kvLen,
|
||||||
|
compareStat);
|
||||||
|
} else {
|
||||||
|
ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, true);
|
||||||
|
if (ret != TSDB_CODE_SUCCESS) {
|
||||||
|
return tscInvalidOperationMsg(msg, "invalid smallint data", pToken->z);
|
||||||
|
} else if (!IS_VALID_SMALLINT(iv)) {
|
||||||
|
return tscInvalidOperationMsg(msg, "smallint data overflow", pToken->z);
|
||||||
|
}
|
||||||
|
|
||||||
|
int16_t tmpVal = (int16_t)iv;
|
||||||
|
tscAppendMemRowColValEx(row, &tmpVal, true, colId, pSchema->type, toffset, dataLen, kvLen, compareStat);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TSDB_DATA_TYPE_USMALLINT:
|
||||||
|
if (isNullStr(pToken)) {
|
||||||
|
tscAppendMemRowColValEx(row, getNullValue(pSchema->type), true, colId, pSchema->type, toffset, dataLen, kvLen,
|
||||||
|
compareStat);
|
||||||
|
} else {
|
||||||
|
ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, false);
|
||||||
|
if (ret != TSDB_CODE_SUCCESS) {
|
||||||
|
return tscInvalidOperationMsg(msg, "invalid unsigned smallint data", pToken->z);
|
||||||
|
} else if (!IS_VALID_USMALLINT(iv)) {
|
||||||
|
return tscInvalidOperationMsg(msg, "unsigned smallint data overflow", pToken->z);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t tmpVal = (uint16_t)iv;
|
||||||
|
tscAppendMemRowColValEx(row, &tmpVal, true, colId, pSchema->type, toffset, dataLen, kvLen, compareStat);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TSDB_DATA_TYPE_INT:
|
||||||
|
if (isNullStr(pToken)) {
|
||||||
|
tscAppendMemRowColValEx(row, getNullValue(pSchema->type), true, colId, pSchema->type, toffset, dataLen, kvLen,
|
||||||
|
compareStat);
|
||||||
|
} else {
|
||||||
|
ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, true);
|
||||||
|
if (ret != TSDB_CODE_SUCCESS) {
|
||||||
|
return tscInvalidOperationMsg(msg, "invalid int data", pToken->z);
|
||||||
|
} else if (!IS_VALID_INT(iv)) {
|
||||||
|
return tscInvalidOperationMsg(msg, "int data overflow", pToken->z);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t tmpVal = (int32_t)iv;
|
||||||
|
tscAppendMemRowColValEx(row, &tmpVal, true, colId, pSchema->type, toffset, dataLen, kvLen, compareStat);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TSDB_DATA_TYPE_UINT:
|
||||||
|
if (isNullStr(pToken)) {
|
||||||
|
tscAppendMemRowColValEx(row, getNullValue(pSchema->type), true, colId, pSchema->type, toffset, dataLen, kvLen,
|
||||||
|
compareStat);
|
||||||
|
} else {
|
||||||
|
ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, false);
|
||||||
|
if (ret != TSDB_CODE_SUCCESS) {
|
||||||
|
return tscInvalidOperationMsg(msg, "invalid unsigned int data", pToken->z);
|
||||||
|
} else if (!IS_VALID_UINT(iv)) {
|
||||||
|
return tscInvalidOperationMsg(msg, "unsigned int data overflow", pToken->z);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t tmpVal = (uint32_t)iv;
|
||||||
|
tscAppendMemRowColValEx(row, &tmpVal, true, colId, pSchema->type, toffset, dataLen, kvLen, compareStat);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TSDB_DATA_TYPE_BIGINT:
|
||||||
|
if (isNullStr(pToken)) {
|
||||||
|
tscAppendMemRowColValEx(row, getNullValue(pSchema->type), true, colId, pSchema->type, toffset, dataLen, kvLen,
|
||||||
|
compareStat);
|
||||||
|
} else {
|
||||||
|
ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, true);
|
||||||
|
if (ret != TSDB_CODE_SUCCESS) {
|
||||||
|
return tscInvalidOperationMsg(msg, "invalid bigint data", pToken->z);
|
||||||
|
} else if (!IS_VALID_BIGINT(iv)) {
|
||||||
|
return tscInvalidOperationMsg(msg, "bigint data overflow", pToken->z);
|
||||||
|
}
|
||||||
|
|
||||||
|
tscAppendMemRowColValEx(row, &iv, true, colId, pSchema->type, toffset, dataLen, kvLen, compareStat);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TSDB_DATA_TYPE_UBIGINT:
|
||||||
|
if (isNullStr(pToken)) {
|
||||||
|
tscAppendMemRowColValEx(row, getNullValue(pSchema->type), true, colId, pSchema->type, toffset, dataLen, kvLen,
|
||||||
|
compareStat);
|
||||||
|
} else {
|
||||||
|
ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, false);
|
||||||
|
if (ret != TSDB_CODE_SUCCESS) {
|
||||||
|
return tscInvalidOperationMsg(msg, "invalid unsigned bigint data", pToken->z);
|
||||||
|
} else if (!IS_VALID_UBIGINT((uint64_t)iv)) {
|
||||||
|
return tscInvalidOperationMsg(msg, "unsigned bigint data overflow", pToken->z);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t tmpVal = (uint64_t)iv;
|
||||||
|
tscAppendMemRowColValEx(row, &tmpVal, true, colId, pSchema->type, toffset, dataLen, kvLen, compareStat);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TSDB_DATA_TYPE_FLOAT:
|
||||||
|
if (isNullStr(pToken)) {
|
||||||
|
tscAppendMemRowColValEx(row, getNullValue(pSchema->type), true, colId, pSchema->type, toffset, dataLen, kvLen,
|
||||||
|
compareStat);
|
||||||
|
} else {
|
||||||
|
double dv;
|
||||||
|
if (TK_ILLEGAL == tscToDouble(pToken, &dv, &endptr)) {
|
||||||
|
return tscInvalidOperationMsg(msg, "illegal float data", pToken->z);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (((dv == HUGE_VAL || dv == -HUGE_VAL) && errno == ERANGE) || dv > FLT_MAX || dv < -FLT_MAX || isinf(dv) ||
|
||||||
|
isnan(dv)) {
|
||||||
|
return tscInvalidOperationMsg(msg, "illegal float data", pToken->z);
|
||||||
|
}
|
||||||
|
|
||||||
|
float tmpVal = (float)dv;
|
||||||
|
tscAppendMemRowColValEx(row, &tmpVal, true, colId, pSchema->type, toffset, dataLen, kvLen, compareStat);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TSDB_DATA_TYPE_DOUBLE:
|
||||||
|
if (isNullStr(pToken)) {
|
||||||
|
tscAppendMemRowColValEx(row, getNullValue(pSchema->type), true, colId, pSchema->type, toffset, dataLen, kvLen,
|
||||||
|
compareStat);
|
||||||
|
} else {
|
||||||
|
double dv;
|
||||||
|
if (TK_ILLEGAL == tscToDouble(pToken, &dv, &endptr)) {
|
||||||
|
return tscInvalidOperationMsg(msg, "illegal double data", pToken->z);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (((dv == HUGE_VAL || dv == -HUGE_VAL) && errno == ERANGE) || isinf(dv) || isnan(dv)) {
|
||||||
|
return tscInvalidOperationMsg(msg, "illegal double data", pToken->z);
|
||||||
|
}
|
||||||
|
|
||||||
|
tscAppendMemRowColValEx(row, &dv, true, colId, pSchema->type, toffset, dataLen, kvLen, compareStat);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TSDB_DATA_TYPE_BINARY:
|
||||||
|
// binary data cannot be null-terminated char string, otherwise the last char of the string is lost
|
||||||
|
if (pToken->type == TK_NULL) {
|
||||||
|
tscAppendMemRowColValEx(row, getNullValue(pSchema->type), true, colId, pSchema->type, toffset, dataLen, kvLen,
|
||||||
|
compareStat);
|
||||||
|
} else { // too long values will return invalid sql, not be truncated automatically
|
||||||
|
if (pToken->n + VARSTR_HEADER_SIZE > pSchema->bytes) { // todo refactor
|
||||||
|
return tscInvalidOperationMsg(msg, "string data overflow", pToken->z);
|
||||||
|
}
|
||||||
|
// STR_WITH_SIZE_TO_VARSTR(payload, pToken->z, pToken->n);
|
||||||
|
char *rowEnd = memRowEnd(row);
|
||||||
|
STR_WITH_SIZE_TO_VARSTR(rowEnd, pToken->z, pToken->n);
|
||||||
|
tscAppendMemRowColValEx(row, rowEnd, false, colId, pSchema->type, toffset, dataLen, kvLen, compareStat);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TSDB_DATA_TYPE_NCHAR:
|
||||||
|
if (pToken->type == TK_NULL) {
|
||||||
|
tscAppendMemRowColValEx(row, getNullValue(pSchema->type), true, colId, pSchema->type, toffset, dataLen, kvLen,
|
||||||
|
compareStat);
|
||||||
|
} else {
|
||||||
|
// if the converted output len is over than pColumnModel->bytes, return error: 'Argument list too long'
|
||||||
|
int32_t output = 0;
|
||||||
|
char * rowEnd = memRowEnd(row);
|
||||||
|
if (!taosMbsToUcs4(pToken->z, pToken->n, (char *)varDataVal(rowEnd), pSchema->bytes - VARSTR_HEADER_SIZE,
|
||||||
|
&output)) {
|
||||||
|
char buf[512] = {0};
|
||||||
|
snprintf(buf, tListLen(buf), "%s", strerror(errno));
|
||||||
|
return tscInvalidOperationMsg(msg, buf, pToken->z);
|
||||||
|
}
|
||||||
|
varDataSetLen(rowEnd, output);
|
||||||
|
tscAppendMemRowColValEx(row, rowEnd, false, colId, pSchema->type, toffset, dataLen, kvLen, compareStat);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TSDB_DATA_TYPE_TIMESTAMP: {
|
||||||
|
if (pToken->type == TK_NULL) {
|
||||||
|
if (primaryKey) {
|
||||||
|
// When building SKVRow primaryKey, we should not skip even with NULL value.
|
||||||
|
int64_t tmpVal = 0;
|
||||||
|
tscAppendMemRowColValEx(row, &tmpVal, true, colId, pSchema->type, toffset, dataLen, kvLen, compareStat);
|
||||||
|
} else {
|
||||||
|
tscAppendMemRowColValEx(row, getNullValue(pSchema->type), true, colId, pSchema->type, toffset, dataLen, kvLen,
|
||||||
|
compareStat);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int64_t tmpVal;
|
||||||
|
if (tsParseTime(pToken, &tmpVal, str, msg, timePrec) != TSDB_CODE_SUCCESS) {
|
||||||
|
return tscInvalidOperationMsg(msg, "invalid timestamp", pToken->z);
|
||||||
|
}
|
||||||
|
tscAppendMemRowColValEx(row, &tmpVal, true, colId, pSchema->type, toffset, dataLen, kvLen, compareStat);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,43 +38,60 @@ enum {
|
||||||
TSDB_USE_CLI_TS = 1,
|
TSDB_USE_CLI_TS = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
static uint8_t TRUE_VALUE = (uint8_t)TSDB_TRUE;
|
|
||||||
static uint8_t FALSE_VALUE = (uint8_t)TSDB_FALSE;
|
|
||||||
|
|
||||||
static int32_t tscAllocateMemIfNeed(STableDataBlocks *pDataBlock, int32_t rowSize, int32_t *numOfRows);
|
static int32_t tscAllocateMemIfNeed(STableDataBlocks *pDataBlock, int32_t rowSize, int32_t *numOfRows);
|
||||||
static int32_t parseBoundColumns(SInsertStatementParam *pInsertParam, SParsedDataColInfo *pColInfo, SSchema *pSchema,
|
static int32_t parseBoundColumns(SInsertStatementParam *pInsertParam, SParsedDataColInfo *pColInfo, SSchema *pSchema,
|
||||||
char *str, char **end);
|
char *str, char **end);
|
||||||
|
int initMemRowBuilder(SMemRowBuilder *pBuilder, uint32_t nRows, uint32_t nCols, uint32_t nBoundCols,
|
||||||
int32_t getExtendedRowSize(STableComInfo *tinfo) {
|
int32_t allNullLen) {
|
||||||
return tinfo->rowSize + PAYLOAD_HEADER_LEN + PAYLOAD_COL_HEAD_LEN * tinfo->numOfColumns;
|
ASSERT(nRows >= 0 && nCols > 0 && (nBoundCols <= nCols));
|
||||||
|
if (nRows > 0) {
|
||||||
|
// already init(bind multiple rows by single column)
|
||||||
|
if (pBuilder->compareStat == ROW_COMPARE_NEED && (pBuilder->rowInfo != NULL)) {
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
int initSMemRowHelper(SMemRowHelper *pHelper, SSchema *pSSchema, uint16_t nCols, uint16_t allNullColsLen) {
|
|
||||||
pHelper->allNullLen = allNullColsLen; // TODO: get allNullColsLen when creating or altering table meta
|
|
||||||
if (pHelper->allNullLen == 0) {
|
|
||||||
for (uint16_t i = 0; i < nCols; ++i) {
|
|
||||||
uint8_t type = pSSchema[i].type;
|
|
||||||
int32_t typeLen = TYPE_BYTES[type];
|
|
||||||
pHelper->allNullLen += typeLen;
|
|
||||||
if (TSDB_DATA_TYPE_BINARY == type) {
|
|
||||||
pHelper->allNullLen += (VARSTR_HEADER_SIZE + CHAR_BYTES);
|
|
||||||
} else if (TSDB_DATA_TYPE_NCHAR == type) {
|
|
||||||
int len = VARSTR_HEADER_SIZE + TSDB_NCHAR_SIZE;
|
|
||||||
pHelper->allNullLen += len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
static int32_t tscToDouble(SStrToken *pToken, double *value, char **endPtr) {
|
|
||||||
errno = 0;
|
|
||||||
*value = strtold(pToken->z, endPtr);
|
|
||||||
|
|
||||||
// not a valid integer number, return error
|
|
||||||
if ((*endPtr - pToken->z) != pToken->n) {
|
|
||||||
return TK_ILLEGAL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return pToken->type;
|
if (nBoundCols == 0) { // file input
|
||||||
|
pBuilder->memRowType = SMEM_ROW_DATA;
|
||||||
|
pBuilder->compareStat = ROW_COMPARE_NO_NEED;
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
} else {
|
||||||
|
float boundRatio = ((float)nBoundCols / (float)nCols);
|
||||||
|
|
||||||
|
if (boundRatio < KVRatioKV) {
|
||||||
|
pBuilder->memRowType = SMEM_ROW_KV;
|
||||||
|
pBuilder->compareStat = ROW_COMPARE_NO_NEED;
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
} else if (boundRatio > KVRatioData) {
|
||||||
|
pBuilder->memRowType = SMEM_ROW_DATA;
|
||||||
|
pBuilder->compareStat = ROW_COMPARE_NO_NEED;
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
pBuilder->compareStat = ROW_COMPARE_NEED;
|
||||||
|
|
||||||
|
if (boundRatio < KVRatioPredict) {
|
||||||
|
pBuilder->memRowType = SMEM_ROW_KV;
|
||||||
|
} else {
|
||||||
|
pBuilder->memRowType = SMEM_ROW_DATA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pBuilder->dataRowInitLen = TD_MEM_ROW_DATA_HEAD_SIZE + allNullLen;
|
||||||
|
pBuilder->kvRowInitLen = TD_MEM_ROW_KV_HEAD_SIZE + nBoundCols * sizeof(SColIdx);
|
||||||
|
|
||||||
|
if (nRows > 0) {
|
||||||
|
pBuilder->rowInfo = tcalloc(nRows, sizeof(SMemRowInfo));
|
||||||
|
if (pBuilder->rowInfo == NULL) {
|
||||||
|
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < nRows; ++i) {
|
||||||
|
(pBuilder->rowInfo + i)->dataLen = pBuilder->dataRowInitLen;
|
||||||
|
(pBuilder->rowInfo + i)->kvLen = pBuilder->kvRowInitLen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tsParseTime(SStrToken *pToken, int64_t *time, char **next, char *error, int16_t timePrec) {
|
int tsParseTime(SStrToken *pToken, int64_t *time, char **next, char *error, int16_t timePrec) {
|
||||||
|
@ -146,10 +163,6 @@ int tsParseTime(SStrToken *pToken, int64_t *time, char **next, char *error, int1
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isNullStr(SStrToken* pToken) {
|
|
||||||
return (pToken->type == TK_NULL) || ((pToken->type == TK_STRING) && (pToken->n != 0) &&
|
|
||||||
(strncasecmp(TSDB_DATA_NULL_STR_L, pToken->z, pToken->n) == 0));
|
|
||||||
}
|
|
||||||
int32_t tsParseOneColumn(SSchema *pSchema, SStrToken *pToken, char *payload, char *msg, char **str, bool primaryKey,
|
int32_t tsParseOneColumn(SSchema *pSchema, SStrToken *pToken, char *payload, char *msg, char **str, bool primaryKey,
|
||||||
int16_t timePrec) {
|
int16_t timePrec) {
|
||||||
int64_t iv;
|
int64_t iv;
|
||||||
|
@ -400,342 +413,6 @@ int32_t tsParseOneColumn(SSchema *pSchema, SStrToken *pToken, char *payload, cha
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FORCE_INLINE TDRowLenT tsSetPayloadColValue(char *payloadStart, char *payload, int16_t columnId,
|
|
||||||
uint8_t columnType, const void *value, uint16_t valueLen, TDRowTLenT tOffset) {
|
|
||||||
payloadColSetId(payload, columnId);
|
|
||||||
payloadColSetType(payload, columnType);
|
|
||||||
memcpy(POINTER_SHIFT(payloadStart,tOffset), value, valueLen);
|
|
||||||
return valueLen;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t tsParseOneColumnKV(SSchema *pSchema, SStrToken *pToken, char *payloadStart, char *primaryKeyStart,
|
|
||||||
char *payload, char *msg, char **str, bool primaryKey, int16_t timePrec,
|
|
||||||
TDRowTLenT tOffset, TDRowLenT *sizeAppend, TDRowLenT *dataRowColDeltaLen,
|
|
||||||
TDRowLenT *kvRowColLen) {
|
|
||||||
int64_t iv;
|
|
||||||
int32_t ret;
|
|
||||||
char * endptr = NULL;
|
|
||||||
|
|
||||||
if (IS_NUMERIC_TYPE(pSchema->type) && pToken->n == 0) {
|
|
||||||
return tscInvalidOperationMsg(msg, "invalid numeric data", pToken->z);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (pSchema->type) {
|
|
||||||
case TSDB_DATA_TYPE_BOOL: { // bool
|
|
||||||
if (isNullStr(pToken)) {
|
|
||||||
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type,
|
|
||||||
getNullValue(TSDB_DATA_TYPE_BOOL), TYPE_BYTES[TSDB_DATA_TYPE_BOOL], tOffset);
|
|
||||||
} else {
|
|
||||||
if ((pToken->type == TK_BOOL || pToken->type == TK_STRING) && (pToken->n != 0)) {
|
|
||||||
if (strncmp(pToken->z, "true", pToken->n) == 0) {
|
|
||||||
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type, &TRUE_VALUE,
|
|
||||||
TYPE_BYTES[TSDB_DATA_TYPE_BOOL], tOffset);
|
|
||||||
*kvRowColLen += (TDRowLenT)(sizeof(SColIdx) + TYPE_BYTES[TSDB_DATA_TYPE_BOOL]);
|
|
||||||
} else if (strncmp(pToken->z, "false", pToken->n) == 0) {
|
|
||||||
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type, &FALSE_VALUE,
|
|
||||||
TYPE_BYTES[TSDB_DATA_TYPE_BOOL], tOffset);
|
|
||||||
*kvRowColLen += (TDRowLenT)(sizeof(SColIdx) + TYPE_BYTES[TSDB_DATA_TYPE_BOOL]);
|
|
||||||
} else {
|
|
||||||
return tscSQLSyntaxErrMsg(msg, "invalid bool data", pToken->z);
|
|
||||||
}
|
|
||||||
} else if (pToken->type == TK_INTEGER) {
|
|
||||||
iv = strtoll(pToken->z, NULL, 10);
|
|
||||||
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type,
|
|
||||||
((iv == 0) ? &FALSE_VALUE : &TRUE_VALUE), TYPE_BYTES[TSDB_DATA_TYPE_BOOL], tOffset);
|
|
||||||
*kvRowColLen += (TDRowLenT)(sizeof(SColIdx) + TYPE_BYTES[TSDB_DATA_TYPE_BOOL]);
|
|
||||||
} else if (pToken->type == TK_FLOAT) {
|
|
||||||
double dv = strtod(pToken->z, NULL);
|
|
||||||
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type,
|
|
||||||
((dv == 0) ? &FALSE_VALUE : &TRUE_VALUE), TYPE_BYTES[TSDB_DATA_TYPE_BOOL], tOffset);
|
|
||||||
*kvRowColLen += (TDRowLenT)(sizeof(SColIdx) + TYPE_BYTES[TSDB_DATA_TYPE_BOOL]);
|
|
||||||
} else {
|
|
||||||
return tscInvalidOperationMsg(msg, "invalid bool data", pToken->z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case TSDB_DATA_TYPE_TINYINT:
|
|
||||||
if (isNullStr(pToken)) {
|
|
||||||
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type,
|
|
||||||
getNullValue(TSDB_DATA_TYPE_TINYINT), TYPE_BYTES[TSDB_DATA_TYPE_TINYINT], tOffset);
|
|
||||||
} else {
|
|
||||||
ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, true);
|
|
||||||
if (ret != TSDB_CODE_SUCCESS) {
|
|
||||||
return tscInvalidOperationMsg(msg, "invalid tinyint data", pToken->z);
|
|
||||||
} else if (!IS_VALID_TINYINT(iv)) {
|
|
||||||
return tscInvalidOperationMsg(msg, "data overflow", pToken->z);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t tmpVal = (uint8_t)iv;
|
|
||||||
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type, &tmpVal,
|
|
||||||
TYPE_BYTES[TSDB_DATA_TYPE_TINYINT], tOffset);
|
|
||||||
*kvRowColLen += (TDRowLenT)(sizeof(SColIdx) + TYPE_BYTES[TSDB_DATA_TYPE_TINYINT]);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TSDB_DATA_TYPE_UTINYINT:
|
|
||||||
if (isNullStr(pToken)) {
|
|
||||||
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type,
|
|
||||||
getNullValue(TSDB_DATA_TYPE_UTINYINT), TYPE_BYTES[TSDB_DATA_TYPE_UTINYINT], tOffset);
|
|
||||||
} else {
|
|
||||||
ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, false);
|
|
||||||
if (ret != TSDB_CODE_SUCCESS) {
|
|
||||||
return tscInvalidOperationMsg(msg, "invalid unsigned tinyint data", pToken->z);
|
|
||||||
} else if (!IS_VALID_UTINYINT(iv)) {
|
|
||||||
return tscInvalidOperationMsg(msg, "unsigned tinyint data overflow", pToken->z);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t tmpVal = (uint8_t)iv;
|
|
||||||
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type, &tmpVal,
|
|
||||||
TYPE_BYTES[TSDB_DATA_TYPE_UTINYINT], tOffset);
|
|
||||||
*kvRowColLen += (TDRowLenT)(sizeof(SColIdx) + TYPE_BYTES[TSDB_DATA_TYPE_UTINYINT]);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TSDB_DATA_TYPE_SMALLINT:
|
|
||||||
if (isNullStr(pToken)) {
|
|
||||||
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type,
|
|
||||||
getNullValue(TSDB_DATA_TYPE_SMALLINT), TYPE_BYTES[TSDB_DATA_TYPE_SMALLINT], tOffset);
|
|
||||||
} else {
|
|
||||||
ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, true);
|
|
||||||
if (ret != TSDB_CODE_SUCCESS) {
|
|
||||||
return tscInvalidOperationMsg(msg, "invalid smallint data", pToken->z);
|
|
||||||
} else if (!IS_VALID_SMALLINT(iv)) {
|
|
||||||
return tscInvalidOperationMsg(msg, "smallint data overflow", pToken->z);
|
|
||||||
}
|
|
||||||
|
|
||||||
int16_t tmpVal = (int16_t)iv;
|
|
||||||
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type, &tmpVal,
|
|
||||||
TYPE_BYTES[TSDB_DATA_TYPE_SMALLINT], tOffset);
|
|
||||||
*kvRowColLen += (TDRowLenT)(sizeof(SColIdx) + TYPE_BYTES[TSDB_DATA_TYPE_SMALLINT]);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TSDB_DATA_TYPE_USMALLINT:
|
|
||||||
if (isNullStr(pToken)) {
|
|
||||||
*sizeAppend =
|
|
||||||
tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type,
|
|
||||||
getNullValue(TSDB_DATA_TYPE_USMALLINT), TYPE_BYTES[TSDB_DATA_TYPE_USMALLINT], tOffset);
|
|
||||||
} else {
|
|
||||||
ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, false);
|
|
||||||
if (ret != TSDB_CODE_SUCCESS) {
|
|
||||||
return tscInvalidOperationMsg(msg, "invalid unsigned smallint data", pToken->z);
|
|
||||||
} else if (!IS_VALID_USMALLINT(iv)) {
|
|
||||||
return tscInvalidOperationMsg(msg, "unsigned smallint data overflow", pToken->z);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t tmpVal = (uint16_t)iv;
|
|
||||||
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type, &tmpVal,
|
|
||||||
TYPE_BYTES[TSDB_DATA_TYPE_USMALLINT], tOffset);
|
|
||||||
*kvRowColLen += (TDRowLenT)(sizeof(SColIdx) + TYPE_BYTES[TSDB_DATA_TYPE_USMALLINT]);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TSDB_DATA_TYPE_INT:
|
|
||||||
if (isNullStr(pToken)) {
|
|
||||||
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type,
|
|
||||||
getNullValue(TSDB_DATA_TYPE_INT), TYPE_BYTES[TSDB_DATA_TYPE_INT], tOffset);
|
|
||||||
} else {
|
|
||||||
ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, true);
|
|
||||||
if (ret != TSDB_CODE_SUCCESS) {
|
|
||||||
return tscInvalidOperationMsg(msg, "invalid int data", pToken->z);
|
|
||||||
} else if (!IS_VALID_INT(iv)) {
|
|
||||||
return tscInvalidOperationMsg(msg, "int data overflow", pToken->z);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t tmpVal = (int32_t)iv;
|
|
||||||
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type, &tmpVal,
|
|
||||||
TYPE_BYTES[TSDB_DATA_TYPE_INT], tOffset);
|
|
||||||
*kvRowColLen += (TDRowLenT)(sizeof(SColIdx) + TYPE_BYTES[TSDB_DATA_TYPE_INT]);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TSDB_DATA_TYPE_UINT:
|
|
||||||
if (isNullStr(pToken)) {
|
|
||||||
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type,
|
|
||||||
getNullValue(TSDB_DATA_TYPE_UINT), TYPE_BYTES[TSDB_DATA_TYPE_UINT], tOffset);
|
|
||||||
} else {
|
|
||||||
ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, false);
|
|
||||||
if (ret != TSDB_CODE_SUCCESS) {
|
|
||||||
return tscInvalidOperationMsg(msg, "invalid unsigned int data", pToken->z);
|
|
||||||
} else if (!IS_VALID_UINT(iv)) {
|
|
||||||
return tscInvalidOperationMsg(msg, "unsigned int data overflow", pToken->z);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t tmpVal = (uint32_t)iv;
|
|
||||||
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type, &tmpVal,
|
|
||||||
TYPE_BYTES[TSDB_DATA_TYPE_UINT], tOffset);
|
|
||||||
*kvRowColLen += (TDRowLenT)(sizeof(SColIdx) + TYPE_BYTES[TSDB_DATA_TYPE_UINT]);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TSDB_DATA_TYPE_BIGINT:
|
|
||||||
if (isNullStr(pToken)) {
|
|
||||||
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type,
|
|
||||||
getNullValue(TSDB_DATA_TYPE_BIGINT), TYPE_BYTES[TSDB_DATA_TYPE_BIGINT], tOffset);
|
|
||||||
} else {
|
|
||||||
ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, true);
|
|
||||||
if (ret != TSDB_CODE_SUCCESS) {
|
|
||||||
return tscInvalidOperationMsg(msg, "invalid bigint data", pToken->z);
|
|
||||||
} else if (!IS_VALID_BIGINT(iv)) {
|
|
||||||
return tscInvalidOperationMsg(msg, "bigint data overflow", pToken->z);
|
|
||||||
}
|
|
||||||
|
|
||||||
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type, &iv,
|
|
||||||
TYPE_BYTES[TSDB_DATA_TYPE_BIGINT], tOffset);
|
|
||||||
*kvRowColLen += (TDRowLenT)(sizeof(SColIdx) + TYPE_BYTES[TSDB_DATA_TYPE_BIGINT]);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TSDB_DATA_TYPE_UBIGINT:
|
|
||||||
if (isNullStr(pToken)) {
|
|
||||||
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type,
|
|
||||||
getNullValue(TSDB_DATA_TYPE_UBIGINT), TYPE_BYTES[TSDB_DATA_TYPE_UBIGINT], tOffset);
|
|
||||||
} else {
|
|
||||||
ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, false);
|
|
||||||
if (ret != TSDB_CODE_SUCCESS) {
|
|
||||||
return tscInvalidOperationMsg(msg, "invalid unsigned bigint data", pToken->z);
|
|
||||||
} else if (!IS_VALID_UBIGINT((uint64_t)iv)) {
|
|
||||||
return tscInvalidOperationMsg(msg, "unsigned bigint data overflow", pToken->z);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t tmpVal = (uint64_t)iv;
|
|
||||||
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type, &tmpVal,
|
|
||||||
TYPE_BYTES[TSDB_DATA_TYPE_UBIGINT], tOffset);
|
|
||||||
*kvRowColLen += (TDRowLenT)(sizeof(SColIdx) + TYPE_BYTES[TSDB_DATA_TYPE_UBIGINT]);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TSDB_DATA_TYPE_FLOAT:
|
|
||||||
if (isNullStr(pToken)) {
|
|
||||||
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type,
|
|
||||||
getNullValue(TSDB_DATA_TYPE_FLOAT), TYPE_BYTES[TSDB_DATA_TYPE_FLOAT], tOffset);
|
|
||||||
} else {
|
|
||||||
double dv;
|
|
||||||
if (TK_ILLEGAL == tscToDouble(pToken, &dv, &endptr)) {
|
|
||||||
return tscInvalidOperationMsg(msg, "illegal float data", pToken->z);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (((dv == HUGE_VAL || dv == -HUGE_VAL) && errno == ERANGE) || dv > FLT_MAX || dv < -FLT_MAX || isinf(dv) ||
|
|
||||||
isnan(dv)) {
|
|
||||||
return tscInvalidOperationMsg(msg, "illegal float data", pToken->z);
|
|
||||||
}
|
|
||||||
|
|
||||||
float tmpVal = (float)dv;
|
|
||||||
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type, &tmpVal,
|
|
||||||
TYPE_BYTES[TSDB_DATA_TYPE_FLOAT], tOffset);
|
|
||||||
*kvRowColLen += (TDRowLenT)(sizeof(SColIdx) + TYPE_BYTES[TSDB_DATA_TYPE_FLOAT]);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TSDB_DATA_TYPE_DOUBLE:
|
|
||||||
if (isNullStr(pToken)) {
|
|
||||||
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type,
|
|
||||||
getNullValue(TSDB_DATA_TYPE_DOUBLE), TYPE_BYTES[TSDB_DATA_TYPE_DOUBLE], tOffset);
|
|
||||||
} else {
|
|
||||||
double dv;
|
|
||||||
if (TK_ILLEGAL == tscToDouble(pToken, &dv, &endptr)) {
|
|
||||||
return tscInvalidOperationMsg(msg, "illegal double data", pToken->z);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (((dv == HUGE_VAL || dv == -HUGE_VAL) && errno == ERANGE) || isinf(dv) || isnan(dv)) {
|
|
||||||
return tscInvalidOperationMsg(msg, "illegal double data", pToken->z);
|
|
||||||
}
|
|
||||||
|
|
||||||
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type, &dv,
|
|
||||||
TYPE_BYTES[TSDB_DATA_TYPE_DOUBLE], tOffset);
|
|
||||||
*kvRowColLen += (TDRowLenT)(sizeof(SColIdx) + TYPE_BYTES[TSDB_DATA_TYPE_DOUBLE]);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TSDB_DATA_TYPE_BINARY:
|
|
||||||
// binary data cannot be null-terminated char string, otherwise the last char of the string is lost
|
|
||||||
if (pToken->type == TK_NULL) {
|
|
||||||
payloadColSetId(payload, pSchema->colId);
|
|
||||||
payloadColSetType(payload, pSchema->type);
|
|
||||||
memcpy(POINTER_SHIFT(payloadStart, tOffset), getNullValue(TSDB_DATA_TYPE_BINARY), VARSTR_HEADER_SIZE + CHAR_BYTES);
|
|
||||||
*sizeAppend = (TDRowLenT)(VARSTR_HEADER_SIZE + CHAR_BYTES);
|
|
||||||
} else { // too long values will return invalid sql, not be truncated automatically
|
|
||||||
if (pToken->n + VARSTR_HEADER_SIZE > pSchema->bytes) { // todo refactor
|
|
||||||
return tscInvalidOperationMsg(msg, "string data overflow", pToken->z);
|
|
||||||
}
|
|
||||||
// STR_WITH_SIZE_TO_VARSTR(payload, pToken->z, pToken->n);
|
|
||||||
|
|
||||||
payloadColSetId(payload, pSchema->colId);
|
|
||||||
payloadColSetType(payload, pSchema->type);
|
|
||||||
varDataSetLen(POINTER_SHIFT(payloadStart,tOffset), pToken->n);
|
|
||||||
memcpy(varDataVal(POINTER_SHIFT(payloadStart,tOffset)), pToken->z, pToken->n);
|
|
||||||
*sizeAppend = (TDRowLenT)(VARSTR_HEADER_SIZE + pToken->n);
|
|
||||||
*dataRowColDeltaLen += (TDRowLenT)(pToken->n - CHAR_BYTES);
|
|
||||||
*kvRowColLen += (TDRowLenT)(sizeof(SColIdx) + VARSTR_HEADER_SIZE + pToken->n);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TSDB_DATA_TYPE_NCHAR:
|
|
||||||
if (pToken->type == TK_NULL) {
|
|
||||||
payloadColSetId(payload, pSchema->colId);
|
|
||||||
payloadColSetType(payload, pSchema->type);
|
|
||||||
memcpy(POINTER_SHIFT(payloadStart,tOffset), getNullValue(TSDB_DATA_TYPE_NCHAR), VARSTR_HEADER_SIZE + TSDB_NCHAR_SIZE);
|
|
||||||
*sizeAppend = (TDRowLenT)(VARSTR_HEADER_SIZE + TSDB_NCHAR_SIZE);
|
|
||||||
} else {
|
|
||||||
// if the converted output len is over than pColumnModel->bytes, return error: 'Argument list too long'
|
|
||||||
int32_t output = 0;
|
|
||||||
payloadColSetId(payload, pSchema->colId);
|
|
||||||
payloadColSetType(payload, pSchema->type);
|
|
||||||
if (!taosMbsToUcs4(pToken->z, pToken->n, varDataVal(POINTER_SHIFT(payloadStart,tOffset)),
|
|
||||||
pSchema->bytes - VARSTR_HEADER_SIZE, &output)) {
|
|
||||||
char buf[512] = {0};
|
|
||||||
snprintf(buf, tListLen(buf), "%s", strerror(errno));
|
|
||||||
return tscInvalidOperationMsg(msg, buf, pToken->z);
|
|
||||||
}
|
|
||||||
|
|
||||||
varDataSetLen(POINTER_SHIFT(payloadStart,tOffset), output);
|
|
||||||
|
|
||||||
*sizeAppend = (TDRowLenT)(VARSTR_HEADER_SIZE + output);
|
|
||||||
*dataRowColDeltaLen += (TDRowLenT)(output - sizeof(uint32_t));
|
|
||||||
*kvRowColLen += (TDRowLenT)(sizeof(SColIdx) + VARSTR_HEADER_SIZE + output);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TSDB_DATA_TYPE_TIMESTAMP: {
|
|
||||||
if (pToken->type == TK_NULL) {
|
|
||||||
if (primaryKey) {
|
|
||||||
// When building SKVRow primaryKey, we should not skip even with NULL value.
|
|
||||||
int64_t tmpVal = 0;
|
|
||||||
*sizeAppend = tsSetPayloadColValue(payloadStart, primaryKeyStart, pSchema->colId, pSchema->type, &tmpVal,
|
|
||||||
TYPE_BYTES[TSDB_DATA_TYPE_TIMESTAMP], tOffset);
|
|
||||||
*kvRowColLen += (TDRowLenT)(sizeof(SColIdx) + TYPE_BYTES[TSDB_DATA_TYPE_TIMESTAMP]);
|
|
||||||
} else {
|
|
||||||
*sizeAppend = tsSetPayloadColValue(payloadStart, payload, pSchema->colId, pSchema->type,
|
|
||||||
getNullValue(TSDB_DATA_TYPE_TIMESTAMP),
|
|
||||||
TYPE_BYTES[TSDB_DATA_TYPE_TIMESTAMP], tOffset);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
int64_t tmpVal;
|
|
||||||
if (tsParseTime(pToken, &tmpVal, str, msg, timePrec) != TSDB_CODE_SUCCESS) {
|
|
||||||
return tscInvalidOperationMsg(msg, "invalid timestamp", pToken->z);
|
|
||||||
}
|
|
||||||
|
|
||||||
*sizeAppend = tsSetPayloadColValue(payloadStart, primaryKey ? primaryKeyStart : payload, pSchema->colId,
|
|
||||||
pSchema->type, &tmpVal, TYPE_BYTES[TSDB_DATA_TYPE_TIMESTAMP], tOffset);
|
|
||||||
*kvRowColLen += (TDRowLenT)(sizeof(SColIdx) + TYPE_BYTES[TSDB_DATA_TYPE_TIMESTAMP]);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The server time/client time should not be mixed up in one sql string
|
* The server time/client time should not be mixed up in one sql string
|
||||||
* Do not employ sort operation is not involved if server time is used.
|
* Do not employ sort operation is not involved if server time is used.
|
||||||
|
@ -777,31 +454,24 @@ int tsParseOneRow(char **str, STableDataBlocks *pDataBlocks, int16_t timePrec, i
|
||||||
int32_t index = 0;
|
int32_t index = 0;
|
||||||
SStrToken sToken = {0};
|
SStrToken sToken = {0};
|
||||||
|
|
||||||
SMemRowHelper *pHelper = &pDataBlocks->rowHelper;
|
char *row = pDataBlocks->pData + pDataBlocks->size; // skip the SSubmitBlk header
|
||||||
char * payload = pDataBlocks->pData + pDataBlocks->size;
|
|
||||||
|
|
||||||
SParsedDataColInfo *spd = &pDataBlocks->boundColumnInfo;
|
SParsedDataColInfo *spd = &pDataBlocks->boundColumnInfo;
|
||||||
SSchema * schema = tscGetTableSchema(pDataBlocks->pTableMeta);
|
STableMeta * pTableMeta = pDataBlocks->pTableMeta;
|
||||||
|
SSchema * schema = tscGetTableSchema(pTableMeta);
|
||||||
|
SMemRowBuilder * pBuilder = &pDataBlocks->rowBuilder;
|
||||||
|
int32_t dataLen = pBuilder->dataRowInitLen;
|
||||||
|
int32_t kvLen = pBuilder->kvRowInitLen;
|
||||||
|
bool isParseBindParam = false;
|
||||||
|
|
||||||
TDRowTLenT dataRowLen = pHelper->allNullLen;
|
initSMemRow(row, pBuilder->memRowType, pDataBlocks, spd->numOfBound);
|
||||||
TDRowTLenT kvRowLen = TD_MEM_ROW_KV_VER_SIZE;
|
|
||||||
TDRowTLenT payloadValOffset = 0;
|
|
||||||
TDRowLenT colValOffset = 0;
|
|
||||||
ASSERT(dataRowLen > 0);
|
|
||||||
|
|
||||||
payloadSetNCols(payload, spd->numOfBound);
|
|
||||||
payloadValOffset = payloadValuesOffset(payload); // rely on payloadNCols
|
|
||||||
// payloadSetTLen(payload, payloadValOffset);
|
|
||||||
|
|
||||||
char *kvPrimaryKeyStart = payload + PAYLOAD_HEADER_LEN; // primaryKey in 1st column tuple
|
|
||||||
char *kvStart = kvPrimaryKeyStart + PAYLOAD_COL_HEAD_LEN; // the column tuple behind the primaryKey
|
|
||||||
|
|
||||||
// 1. set the parsed value from sql string
|
// 1. set the parsed value from sql string
|
||||||
for (int i = 0; i < spd->numOfBound; ++i) {
|
for (int i = 0; i < spd->numOfBound; ++i) {
|
||||||
// the start position in data block buffer of current value in sql
|
// the start position in data block buffer of current value in sql
|
||||||
int32_t colIndex = spd->boundedColumns[i];
|
int32_t colIndex = spd->boundedColumns[i];
|
||||||
|
|
||||||
char *start = payload + spd->cols[colIndex].offset;
|
char *start = row + spd->cols[colIndex].offset;
|
||||||
|
|
||||||
SSchema *pSchema = &schema[colIndex]; // get colId here
|
SSchema *pSchema = &schema[colIndex]; // get colId here
|
||||||
|
|
||||||
|
@ -810,6 +480,9 @@ int tsParseOneRow(char **str, STableDataBlocks *pDataBlocks, int16_t timePrec, i
|
||||||
*str += index;
|
*str += index;
|
||||||
|
|
||||||
if (sToken.type == TK_QUESTION) {
|
if (sToken.type == TK_QUESTION) {
|
||||||
|
if (!isParseBindParam) {
|
||||||
|
isParseBindParam = true;
|
||||||
|
}
|
||||||
if (pInsertParam->insertType != TSDB_QUERY_TYPE_STMT_INSERT) {
|
if (pInsertParam->insertType != TSDB_QUERY_TYPE_STMT_INSERT) {
|
||||||
return tscSQLSyntaxErrMsg(pInsertParam->msg, "? only allowed in binding insertion", *str);
|
return tscSQLSyntaxErrMsg(pInsertParam->msg, "? only allowed in binding insertion", *str);
|
||||||
}
|
}
|
||||||
|
@ -861,52 +534,43 @@ int tsParseOneRow(char **str, STableDataBlocks *pDataBlocks, int16_t timePrec, i
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isPrimaryKey = (colIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX);
|
bool isPrimaryKey = (colIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX);
|
||||||
TDRowLenT dataRowDeltaColLen = 0; // When combine the data as SDataRow, the delta len between all NULL columns.
|
int32_t toffset = -1;
|
||||||
TDRowLenT kvRowColLen = 0;
|
int16_t colId = -1;
|
||||||
TDRowLenT colValAppended = 0;
|
tscGetMemRowAppendInfo(schema, pBuilder->memRowType, spd, i, &toffset, &colId);
|
||||||
|
|
||||||
if (!IS_DATA_COL_ORDERED(spd->orderStatus)) {
|
int32_t ret = tsParseOneColumnKV(pSchema, &sToken, row, pInsertParam->msg, str, isPrimaryKey, timePrec, toffset,
|
||||||
ASSERT(spd->colIdxInfo != NULL);
|
colId, &dataLen, &kvLen, pBuilder->compareStat);
|
||||||
if(!isPrimaryKey) {
|
|
||||||
kvStart = POINTER_SHIFT(kvPrimaryKeyStart, spd->colIdxInfo[i].finalIdx * PAYLOAD_COL_HEAD_LEN);
|
|
||||||
} else {
|
|
||||||
ASSERT(spd->colIdxInfo[i].finalIdx == 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// the primary key locates in 1st column
|
|
||||||
int32_t ret = tsParseOneColumnKV(pSchema, &sToken, payload, kvPrimaryKeyStart, kvStart, pInsertParam->msg, str,
|
|
||||||
isPrimaryKey, timePrec, payloadValOffset + colValOffset, &colValAppended,
|
|
||||||
&dataRowDeltaColLen, &kvRowColLen);
|
|
||||||
if (ret != TSDB_CODE_SUCCESS) {
|
if (ret != TSDB_CODE_SUCCESS) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isPrimaryKey) {
|
if (isPrimaryKey) {
|
||||||
if (tsCheckTimestamp(pDataBlocks, payloadValues(payload)) != TSDB_CODE_SUCCESS) {
|
TSKEY tsKey = memRowKey(row);
|
||||||
|
if (tsCheckTimestamp(pDataBlocks, (const char *)&tsKey) != TSDB_CODE_SUCCESS) {
|
||||||
tscInvalidOperationMsg(pInsertParam->msg, "client time/server time can not be mixed up", sToken.z);
|
tscInvalidOperationMsg(pInsertParam->msg, "client time/server time can not be mixed up", sToken.z);
|
||||||
return TSDB_CODE_TSC_INVALID_TIME_STAMP;
|
return TSDB_CODE_TSC_INVALID_TIME_STAMP;
|
||||||
}
|
}
|
||||||
payloadColSetOffset(kvPrimaryKeyStart, colValOffset);
|
|
||||||
} else {
|
|
||||||
payloadColSetOffset(kvStart, colValOffset);
|
|
||||||
if (IS_DATA_COL_ORDERED(spd->orderStatus)) {
|
|
||||||
kvStart += PAYLOAD_COL_HEAD_LEN; // move to next column
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
colValOffset += colValAppended;
|
if (!isParseBindParam) {
|
||||||
kvRowLen += kvRowColLen;
|
// 2. check and set convert flag
|
||||||
dataRowLen += dataRowDeltaColLen;
|
if (pBuilder->compareStat == ROW_COMPARE_NEED) {
|
||||||
|
checkAndConvertMemRow(row, dataLen, kvLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kvRowLen < dataRowLen) {
|
// 3. set the null value for the columns that do not assign values
|
||||||
payloadSetType(payload, SMEM_ROW_KV);
|
if ((spd->numOfBound < spd->numOfCols) && isDataRow(row) && !isNeedConvertRow(row)) {
|
||||||
} else {
|
SDataRow dataRow = memRowDataBody(row);
|
||||||
payloadSetType(payload, SMEM_ROW_DATA);
|
for (int32_t i = 0; i < spd->numOfCols; ++i) {
|
||||||
|
if (spd->cols[i].valStat == VAL_STAT_NONE) {
|
||||||
|
tdAppendDataColVal(dataRow, getNullValue(schema[i].type), true, schema[i].type, spd->cols[i].toffset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*len = (int32_t)(payloadValOffset + colValOffset);
|
*len = getExtendedRowSize(pDataBlocks);
|
||||||
payloadSetTLen(payload, *len);
|
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -957,11 +621,13 @@ int32_t tsParseValues(char **str, STableDataBlocks *pDataBlock, int maxRows, SIn
|
||||||
|
|
||||||
int32_t precision = tinfo.precision;
|
int32_t precision = tinfo.precision;
|
||||||
|
|
||||||
int32_t extendedRowSize = getExtendedRowSize(&tinfo);
|
int32_t extendedRowSize = getExtendedRowSize(pDataBlock);
|
||||||
|
|
||||||
initSMemRowHelper(&pDataBlock->rowHelper, tscGetTableSchema(pDataBlock->pTableMeta),
|
|
||||||
tscGetNumOfColumns(pDataBlock->pTableMeta), 0);
|
|
||||||
|
|
||||||
|
if (TSDB_CODE_SUCCESS !=
|
||||||
|
(code = initMemRowBuilder(&pDataBlock->rowBuilder, 0, tinfo.numOfColumns, pDataBlock->boundColumnInfo.numOfBound,
|
||||||
|
pDataBlock->boundColumnInfo.allNullLen))) {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
while (1) {
|
while (1) {
|
||||||
index = 0;
|
index = 0;
|
||||||
sToken = tStrGetToken(*str, &index, false);
|
sToken = tStrGetToken(*str, &index, false);
|
||||||
|
@ -1010,19 +676,37 @@ int32_t tsParseValues(char **str, STableDataBlocks *pDataBlock, int maxRows, SIn
|
||||||
void tscSetBoundColumnInfo(SParsedDataColInfo *pColInfo, SSchema *pSchema, int32_t numOfCols) {
|
void tscSetBoundColumnInfo(SParsedDataColInfo *pColInfo, SSchema *pSchema, int32_t numOfCols) {
|
||||||
pColInfo->numOfCols = numOfCols;
|
pColInfo->numOfCols = numOfCols;
|
||||||
pColInfo->numOfBound = numOfCols;
|
pColInfo->numOfBound = numOfCols;
|
||||||
pColInfo->orderStatus = ORDER_STATUS_ORDERED;
|
pColInfo->orderStatus = ORDER_STATUS_ORDERED; // default is ORDERED for non-bound mode
|
||||||
pColInfo->boundedColumns = calloc(pColInfo->numOfCols, sizeof(int32_t));
|
pColInfo->boundedColumns = calloc(pColInfo->numOfCols, sizeof(int32_t));
|
||||||
pColInfo->cols = calloc(pColInfo->numOfCols, sizeof(SBoundColumn));
|
pColInfo->cols = calloc(pColInfo->numOfCols, sizeof(SBoundColumn));
|
||||||
pColInfo->colIdxInfo = NULL;
|
pColInfo->colIdxInfo = NULL;
|
||||||
|
pColInfo->flen = 0;
|
||||||
|
pColInfo->allNullLen = 0;
|
||||||
|
|
||||||
|
int32_t nVar = 0;
|
||||||
for (int32_t i = 0; i < pColInfo->numOfCols; ++i) {
|
for (int32_t i = 0; i < pColInfo->numOfCols; ++i) {
|
||||||
|
uint8_t type = pSchema[i].type;
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
pColInfo->cols[i].offset = pSchema[i - 1].bytes + pColInfo->cols[i - 1].offset;
|
pColInfo->cols[i].offset = pSchema[i - 1].bytes + pColInfo->cols[i - 1].offset;
|
||||||
|
pColInfo->cols[i].toffset = pColInfo->flen;
|
||||||
|
}
|
||||||
|
pColInfo->flen += TYPE_BYTES[type];
|
||||||
|
switch (type) {
|
||||||
|
case TSDB_DATA_TYPE_BINARY:
|
||||||
|
pColInfo->allNullLen += (VARSTR_HEADER_SIZE + CHAR_BYTES);
|
||||||
|
++nVar;
|
||||||
|
break;
|
||||||
|
case TSDB_DATA_TYPE_NCHAR:
|
||||||
|
pColInfo->allNullLen += (VARSTR_HEADER_SIZE + TSDB_NCHAR_SIZE);
|
||||||
|
++nVar;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
pColInfo->cols[i].hasVal = true;
|
|
||||||
pColInfo->boundedColumns[i] = i;
|
pColInfo->boundedColumns[i] = i;
|
||||||
}
|
}
|
||||||
|
pColInfo->allNullLen += pColInfo->flen;
|
||||||
|
pColInfo->extendedVarLen = (uint16_t)(nVar * sizeof(VarDataOffsetT));
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tscAllocateMemIfNeed(STableDataBlocks *pDataBlock, int32_t rowSize, int32_t * numOfRows) {
|
int32_t tscAllocateMemIfNeed(STableDataBlocks *pDataBlock, int32_t rowSize, int32_t * numOfRows) {
|
||||||
|
@ -1135,22 +819,16 @@ int tscSortRemoveDataBlockDupRows(STableDataBlocks *dataBuf, SBlockKeyInfo *pBlk
|
||||||
}
|
}
|
||||||
memset(pBlkKeyInfo->pKeyTuple, 0, nAlloc);
|
memset(pBlkKeyInfo->pKeyTuple, 0, nAlloc);
|
||||||
|
|
||||||
|
int32_t extendedRowSize = getExtendedRowSize(dataBuf);
|
||||||
SBlockKeyTuple *pBlkKeyTuple = pBlkKeyInfo->pKeyTuple;
|
SBlockKeyTuple *pBlkKeyTuple = pBlkKeyInfo->pKeyTuple;
|
||||||
char * pBlockData = pBlocks->data;
|
char * pBlockData = pBlocks->data;
|
||||||
TDRowTLenT totolPayloadTLen = 0;
|
|
||||||
TDRowTLenT payloadTLen = 0;
|
|
||||||
int n = 0;
|
int n = 0;
|
||||||
while (n < nRows) {
|
while (n < nRows) {
|
||||||
pBlkKeyTuple->skey = payloadTSKey(pBlockData);
|
pBlkKeyTuple->skey = memRowKey(pBlockData);
|
||||||
pBlkKeyTuple->payloadAddr = pBlockData;
|
pBlkKeyTuple->payloadAddr = pBlockData;
|
||||||
payloadTLen = payloadTLen(pBlockData);
|
|
||||||
#if 0
|
|
||||||
ASSERT(payloadNCols(pBlockData) <= 4096);
|
|
||||||
ASSERT(payloadTLen(pBlockData) < 65536);
|
|
||||||
#endif
|
|
||||||
totolPayloadTLen += payloadTLen;
|
|
||||||
// next loop
|
// next loop
|
||||||
pBlockData += payloadTLen;
|
pBlockData += extendedRowSize;
|
||||||
++pBlkKeyTuple;
|
++pBlkKeyTuple;
|
||||||
++n;
|
++n;
|
||||||
}
|
}
|
||||||
|
@ -1167,7 +845,6 @@ int tscSortRemoveDataBlockDupRows(STableDataBlocks *dataBuf, SBlockKeyInfo *pBlk
|
||||||
TSKEY tj = (pBlkKeyTuple + j)->skey;
|
TSKEY tj = (pBlkKeyTuple + j)->skey;
|
||||||
|
|
||||||
if (ti == tj) {
|
if (ti == tj) {
|
||||||
totolPayloadTLen -= payloadTLen(pBlkKeyTuple + j);
|
|
||||||
++j;
|
++j;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1183,17 +860,15 @@ int tscSortRemoveDataBlockDupRows(STableDataBlocks *dataBuf, SBlockKeyInfo *pBlk
|
||||||
pBlocks->numOfRows = i + 1;
|
pBlocks->numOfRows = i + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
dataBuf->size = sizeof(SSubmitBlk) + totolPayloadTLen;
|
dataBuf->size = sizeof(SSubmitBlk) + pBlocks->numOfRows * extendedRowSize;
|
||||||
dataBuf->prevTS = INT64_MIN;
|
dataBuf->prevTS = INT64_MIN;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t doParseInsertStatement(SInsertStatementParam *pInsertParam, char **str, STableDataBlocks* dataBuf, int32_t *totalNum) {
|
static int32_t doParseInsertStatement(SInsertStatementParam *pInsertParam, char **str, STableDataBlocks* dataBuf, int32_t *totalNum) {
|
||||||
STableComInfo tinfo = tscGetTableInfo(dataBuf->pTableMeta);
|
|
||||||
|
|
||||||
int32_t maxNumOfRows;
|
int32_t maxNumOfRows;
|
||||||
int32_t code = tscAllocateMemIfNeed(dataBuf, getExtendedRowSize(&tinfo), &maxNumOfRows);
|
int32_t code = tscAllocateMemIfNeed(dataBuf, getExtendedRowSize(dataBuf), &maxNumOfRows);
|
||||||
if (TSDB_CODE_SUCCESS != code) {
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
@ -1531,7 +1206,7 @@ static int32_t parseBoundColumns(SInsertStatementParam *pInsertParam, SParsedDat
|
||||||
pColInfo->numOfBound = 0;
|
pColInfo->numOfBound = 0;
|
||||||
memset(pColInfo->boundedColumns, 0, sizeof(int32_t) * nCols);
|
memset(pColInfo->boundedColumns, 0, sizeof(int32_t) * nCols);
|
||||||
for (int32_t i = 0; i < nCols; ++i) {
|
for (int32_t i = 0; i < nCols; ++i) {
|
||||||
pColInfo->cols[i].hasVal = false;
|
pColInfo->cols[i].valStat = VAL_STAT_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
@ -1570,12 +1245,12 @@ static int32_t parseBoundColumns(SInsertStatementParam *pInsertParam, SParsedDat
|
||||||
int32_t nScanned = 0, t = lastColIdx + 1;
|
int32_t nScanned = 0, t = lastColIdx + 1;
|
||||||
while (t < nCols) {
|
while (t < nCols) {
|
||||||
if (strncmp(sToken.z, pSchema[t].name, sToken.n) == 0 && strlen(pSchema[t].name) == sToken.n) {
|
if (strncmp(sToken.z, pSchema[t].name, sToken.n) == 0 && strlen(pSchema[t].name) == sToken.n) {
|
||||||
if (pColInfo->cols[t].hasVal == true) {
|
if (pColInfo->cols[t].valStat == VAL_STAT_HAS) {
|
||||||
code = tscInvalidOperationMsg(pInsertParam->msg, "duplicated column name", sToken.z);
|
code = tscInvalidOperationMsg(pInsertParam->msg, "duplicated column name", sToken.z);
|
||||||
goto _clean;
|
goto _clean;
|
||||||
}
|
}
|
||||||
|
|
||||||
pColInfo->cols[t].hasVal = true;
|
pColInfo->cols[t].valStat = VAL_STAT_HAS;
|
||||||
pColInfo->boundedColumns[pColInfo->numOfBound] = t;
|
pColInfo->boundedColumns[pColInfo->numOfBound] = t;
|
||||||
++pColInfo->numOfBound;
|
++pColInfo->numOfBound;
|
||||||
findColumnIndex = true;
|
findColumnIndex = true;
|
||||||
|
@ -1593,12 +1268,12 @@ static int32_t parseBoundColumns(SInsertStatementParam *pInsertParam, SParsedDat
|
||||||
int32_t nRemain = nCols - nScanned;
|
int32_t nRemain = nCols - nScanned;
|
||||||
while (t < nRemain) {
|
while (t < nRemain) {
|
||||||
if (strncmp(sToken.z, pSchema[t].name, sToken.n) == 0 && strlen(pSchema[t].name) == sToken.n) {
|
if (strncmp(sToken.z, pSchema[t].name, sToken.n) == 0 && strlen(pSchema[t].name) == sToken.n) {
|
||||||
if (pColInfo->cols[t].hasVal == true) {
|
if (pColInfo->cols[t].valStat == VAL_STAT_HAS) {
|
||||||
code = tscInvalidOperationMsg(pInsertParam->msg, "duplicated column name", sToken.z);
|
code = tscInvalidOperationMsg(pInsertParam->msg, "duplicated column name", sToken.z);
|
||||||
goto _clean;
|
goto _clean;
|
||||||
}
|
}
|
||||||
|
|
||||||
pColInfo->cols[t].hasVal = true;
|
pColInfo->cols[t].valStat = VAL_STAT_HAS;
|
||||||
pColInfo->boundedColumns[pColInfo->numOfBound] = t;
|
pColInfo->boundedColumns[pColInfo->numOfBound] = t;
|
||||||
++pColInfo->numOfBound;
|
++pColInfo->numOfBound;
|
||||||
findColumnIndex = true;
|
findColumnIndex = true;
|
||||||
|
@ -1833,7 +1508,7 @@ int tsParseInsertSql(SSqlObj *pSql) {
|
||||||
goto _clean;
|
goto _clean;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dataBuf->boundColumnInfo.cols[0].hasVal == false) {
|
if (dataBuf->boundColumnInfo.cols[0].valStat == VAL_STAT_NONE) {
|
||||||
code = tscInvalidOperationMsg(pInsertParam->msg, "primary timestamp column can not be null", NULL);
|
code = tscInvalidOperationMsg(pInsertParam->msg, "primary timestamp column can not be null", NULL);
|
||||||
goto _clean;
|
goto _clean;
|
||||||
}
|
}
|
||||||
|
@ -2044,15 +1719,18 @@ static void parseFileSendDataBlock(void *param, TAOS_RES *tres, int32_t numOfRow
|
||||||
goto _error;
|
goto _error;
|
||||||
}
|
}
|
||||||
|
|
||||||
tscAllocateMemIfNeed(pTableDataBlock, getExtendedRowSize(&tinfo), &maxRows);
|
tscAllocateMemIfNeed(pTableDataBlock, getExtendedRowSize(pTableDataBlock), &maxRows);
|
||||||
tokenBuf = calloc(1, TSDB_MAX_BYTES_PER_ROW);
|
tokenBuf = calloc(1, TSDB_MAX_BYTES_PER_ROW);
|
||||||
if (tokenBuf == NULL) {
|
if (tokenBuf == NULL) {
|
||||||
code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
goto _error;
|
goto _error;
|
||||||
}
|
}
|
||||||
|
|
||||||
initSMemRowHelper(&pTableDataBlock->rowHelper, tscGetTableSchema(pTableDataBlock->pTableMeta),
|
if (TSDB_CODE_SUCCESS !=
|
||||||
tscGetNumOfColumns(pTableDataBlock->pTableMeta), 0);
|
(ret = initMemRowBuilder(&pTableDataBlock->rowBuilder, 0, tinfo.numOfColumns, pTableDataBlock->numOfParams,
|
||||||
|
pTableDataBlock->boundColumnInfo.allNullLen))) {
|
||||||
|
goto _error;
|
||||||
|
}
|
||||||
|
|
||||||
while ((readLen = tgetline(&line, &n, fp)) != -1) {
|
while ((readLen = tgetline(&line, &n, fp)) != -1) {
|
||||||
if (('\r' == line[readLen - 1]) || ('\n' == line[readLen - 1])) {
|
if (('\r' == line[readLen - 1]) || ('\n' == line[readLen - 1])) {
|
||||||
|
|
|
@ -299,7 +299,7 @@ static int fillColumnsNull(STableDataBlocks* pBlock, int32_t rowNum) {
|
||||||
SSchema *schema = (SSchema*)pBlock->pTableMeta->schema;
|
SSchema *schema = (SSchema*)pBlock->pTableMeta->schema;
|
||||||
|
|
||||||
for (int32_t i = 0; i < spd->numOfCols; ++i) {
|
for (int32_t i = 0; i < spd->numOfCols; ++i) {
|
||||||
if (!spd->cols[i].hasVal) { // current column do not have any value to insert, set it to null
|
if (spd->cols[i].valStat == VAL_STAT_NONE) { // current column do not have any value to insert, set it to null
|
||||||
for (int32_t n = 0; n < rowNum; ++n) {
|
for (int32_t n = 0; n < rowNum; ++n) {
|
||||||
char *ptr = pBlock->pData + sizeof(SSubmitBlk) + pBlock->rowSize * n + offset;
|
char *ptr = pBlock->pData + sizeof(SSubmitBlk) + pBlock->rowSize * n + offset;
|
||||||
|
|
||||||
|
|
|
@ -4258,6 +4258,10 @@ static bool isValidExpr(tSqlExpr* pLeft, tSqlExpr* pRight, int32_t optr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pLeft->tokenId >= TK_BOOL && pLeft->tokenId <= TK_BINARY && (optr == TK_NOTNULL || optr == TK_ISNULL)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2395,8 +2395,8 @@ int32_t tscHandleFirstRoundStableQuery(SSqlObj *pSql) {
|
||||||
SColumn* x = taosArrayGetP(pNewQueryInfo->colList, index1);
|
SColumn* x = taosArrayGetP(pNewQueryInfo->colList, index1);
|
||||||
tscColumnCopy(x, pCol);
|
tscColumnCopy(x, pCol);
|
||||||
} else {
|
} else {
|
||||||
SColumn *p = tscColumnClone(pCol);
|
SSchema ss = {.type = (uint8_t)pCol->info.type, .bytes = pCol->info.bytes, .colId = (int16_t)pCol->columnIndex};
|
||||||
taosArrayPush(pNewQueryInfo->colList, &p);
|
tscColumnListInsert(pNewQueryInfo->colList, pCol->columnIndex, pCol->tableUid, &ss);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1776,101 +1776,6 @@ int32_t tscGetDataBlockFromList(SHashObj* pHashList, int64_t id, int32_t size, i
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SMemRow tdGenMemRowFromBuilder(SMemRowBuilder* pBuilder) {
|
|
||||||
SSchema* pSchema = pBuilder->pSchema;
|
|
||||||
char* p = (char*)pBuilder->buf;
|
|
||||||
int toffset = 0;
|
|
||||||
uint16_t nCols = pBuilder->nCols;
|
|
||||||
|
|
||||||
uint8_t memRowType = payloadType(p);
|
|
||||||
uint16_t nColsBound = payloadNCols(p);
|
|
||||||
if (pBuilder->nCols <= 0 || nColsBound <= 0) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
char* pVals = POINTER_SHIFT(p, payloadValuesOffset(p));
|
|
||||||
SMemRow* memRow = (SMemRow)pBuilder->pDataBlock;
|
|
||||||
memRowSetType(memRow, memRowType);
|
|
||||||
|
|
||||||
// ----------------- Raw payload structure for row:
|
|
||||||
/* |<------------ Head ------------->|<----------- body of column data tuple ------------------->|
|
|
||||||
* | |<----------------- flen ------------->|<--- value part --->|
|
|
||||||
* |SMemRowType| dataTLen | nCols | colId | colType | offset | ... | value |...|...|... |
|
|
||||||
* +-----------+----------+----------+--------------------------------------|--------------------|
|
|
||||||
* | uint8_t | uint32_t | uint16_t | int16_t | uint8_t | uint16_t | ... |.......|...|...|... |
|
|
||||||
* +-----------+----------+----------+--------------------------------------+--------------------|
|
|
||||||
* 1. offset in column data tuple starts from the value part in case of uint16_t overflow.
|
|
||||||
* 2. dataTLen: total length including the header and body.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (memRowType == SMEM_ROW_DATA) {
|
|
||||||
SDataRow trow = (SDataRow)memRowDataBody(memRow);
|
|
||||||
dataRowSetLen(trow, (TDRowLenT)(TD_DATA_ROW_HEAD_SIZE + pBuilder->flen));
|
|
||||||
dataRowSetVersion(trow, pBuilder->sversion);
|
|
||||||
|
|
||||||
p = (char*)payloadBody(pBuilder->buf);
|
|
||||||
uint16_t i = 0, j = 0;
|
|
||||||
while (j < nCols) {
|
|
||||||
if (i >= nColsBound) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
int16_t colId = payloadColId(p);
|
|
||||||
if (colId == pSchema[j].colId) {
|
|
||||||
// ASSERT(payloadColType(p) == pSchema[j].type);
|
|
||||||
tdAppendColVal(trow, POINTER_SHIFT(pVals, payloadColOffset(p)), pSchema[j].type, toffset);
|
|
||||||
toffset += TYPE_BYTES[pSchema[j].type];
|
|
||||||
p = payloadNextCol(p);
|
|
||||||
++i;
|
|
||||||
++j;
|
|
||||||
} else if (colId < pSchema[j].colId) {
|
|
||||||
p = payloadNextCol(p);
|
|
||||||
++i;
|
|
||||||
} else {
|
|
||||||
tdAppendColVal(trow, getNullValue(pSchema[j].type), pSchema[j].type, toffset);
|
|
||||||
toffset += TYPE_BYTES[pSchema[j].type];
|
|
||||||
++j;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while (j < nCols) {
|
|
||||||
tdAppendColVal(trow, getNullValue(pSchema[j].type), pSchema[j].type, toffset);
|
|
||||||
toffset += TYPE_BYTES[pSchema[j].type];
|
|
||||||
++j;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0 // no need anymore
|
|
||||||
while (i < nColsBound) {
|
|
||||||
p = payloadNextCol(p);
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} else if (memRowType == SMEM_ROW_KV) {
|
|
||||||
SKVRow kvRow = (SKVRow)memRowKvBody(memRow);
|
|
||||||
kvRowSetLen(kvRow, (TDRowLenT)(TD_KV_ROW_HEAD_SIZE + sizeof(SColIdx) * nColsBound));
|
|
||||||
kvRowSetNCols(kvRow, nColsBound);
|
|
||||||
memRowSetKvVersion(memRow, pBuilder->sversion);
|
|
||||||
|
|
||||||
p = (char*)payloadBody(pBuilder->buf);
|
|
||||||
int i = 0;
|
|
||||||
while (i < nColsBound) {
|
|
||||||
int16_t colId = payloadColId(p);
|
|
||||||
uint8_t colType = payloadColType(p);
|
|
||||||
tdAppendKvColVal(kvRow, POINTER_SHIFT(pVals,payloadColOffset(p)), colId, colType, &toffset);
|
|
||||||
//toffset += sizeof(SColIdx);
|
|
||||||
p = payloadNextCol(p);
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
ASSERT(0);
|
|
||||||
}
|
|
||||||
int32_t rowTLen = memRowTLen(memRow);
|
|
||||||
pBuilder->pDataBlock = (char*)pBuilder->pDataBlock + rowTLen; // next row
|
|
||||||
pBuilder->pSubmitBlk->dataLen += rowTLen;
|
|
||||||
|
|
||||||
return memRow;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Erase the empty space reserved for binary data
|
// Erase the empty space reserved for binary data
|
||||||
static int trimDataBlock(void* pDataBlock, STableDataBlocks* pTableDataBlock, SInsertStatementParam* insertParam,
|
static int trimDataBlock(void* pDataBlock, STableDataBlocks* pTableDataBlock, SInsertStatementParam* insertParam,
|
||||||
SBlockKeyTuple* blkKeyTuple) {
|
SBlockKeyTuple* blkKeyTuple) {
|
||||||
|
@ -1902,10 +1807,11 @@ static int trimDataBlock(void* pDataBlock, STableDataBlocks* pTableDataBlock, SI
|
||||||
int32_t schemaSize = sizeof(STColumn) * numOfCols;
|
int32_t schemaSize = sizeof(STColumn) * numOfCols;
|
||||||
pBlock->schemaLen = schemaSize;
|
pBlock->schemaLen = schemaSize;
|
||||||
} else {
|
} else {
|
||||||
|
if (IS_RAW_PAYLOAD(insertParam->payloadType)) {
|
||||||
for (int32_t j = 0; j < tinfo.numOfColumns; ++j) {
|
for (int32_t j = 0; j < tinfo.numOfColumns; ++j) {
|
||||||
flen += TYPE_BYTES[pSchema[j].type];
|
flen += TYPE_BYTES[pSchema[j].type];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
pBlock->schemaLen = 0;
|
pBlock->schemaLen = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1932,18 +1838,19 @@ static int trimDataBlock(void* pDataBlock, STableDataBlocks* pTableDataBlock, SI
|
||||||
pBlock->dataLen += memRowTLen(memRow);
|
pBlock->dataLen += memRowTLen(memRow);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SMemRowBuilder rowBuilder;
|
|
||||||
rowBuilder.pSchema = pSchema;
|
|
||||||
rowBuilder.sversion = pTableMeta->sversion;
|
|
||||||
rowBuilder.flen = flen;
|
|
||||||
rowBuilder.nCols = tinfo.numOfColumns;
|
|
||||||
rowBuilder.pDataBlock = pDataBlock;
|
|
||||||
rowBuilder.pSubmitBlk = pBlock;
|
|
||||||
rowBuilder.buf = p;
|
|
||||||
|
|
||||||
for (int32_t i = 0; i < numOfRows; ++i) {
|
for (int32_t i = 0; i < numOfRows; ++i) {
|
||||||
rowBuilder.buf = (blkKeyTuple + i)->payloadAddr;
|
char* payload = (blkKeyTuple + i)->payloadAddr;
|
||||||
tdGenMemRowFromBuilder(&rowBuilder);
|
if (isNeedConvertRow(payload)) {
|
||||||
|
convertSMemRow(pDataBlock, payload, pTableDataBlock);
|
||||||
|
TDRowTLenT rowTLen = memRowTLen(pDataBlock);
|
||||||
|
pDataBlock = POINTER_SHIFT(pDataBlock, rowTLen);
|
||||||
|
pBlock->dataLen += rowTLen;
|
||||||
|
} else {
|
||||||
|
TDRowTLenT rowTLen = memRowTLen(payload);
|
||||||
|
memcpy(pDataBlock, payload, rowTLen);
|
||||||
|
pDataBlock = POINTER_SHIFT(pDataBlock, rowTLen);
|
||||||
|
pBlock->dataLen += rowTLen;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2004,7 +1911,7 @@ int32_t tscMergeTableDataBlocks(SInsertStatementParam *pInsertParam, bool freeBl
|
||||||
SSubmitBlk* pBlocks = (SSubmitBlk*) pOneTableBlock->pData;
|
SSubmitBlk* pBlocks = (SSubmitBlk*) pOneTableBlock->pData;
|
||||||
if (pBlocks->numOfRows > 0) {
|
if (pBlocks->numOfRows > 0) {
|
||||||
// the maximum expanded size in byte when a row-wise data is converted to SDataRow format
|
// the maximum expanded size in byte when a row-wise data is converted to SDataRow format
|
||||||
int32_t expandSize = getRowExpandSize(pOneTableBlock->pTableMeta);
|
int32_t expandSize = isRawPayload ? getRowExpandSize(pOneTableBlock->pTableMeta) : 0;
|
||||||
STableDataBlocks* dataBuf = NULL;
|
STableDataBlocks* dataBuf = NULL;
|
||||||
|
|
||||||
int32_t ret = tscGetDataBlockFromList(pVnodeDataBlockHashList, pOneTableBlock->vgId, TSDB_PAYLOAD_SIZE,
|
int32_t ret = tscGetDataBlockFromList(pVnodeDataBlockHashList, pOneTableBlock->vgId, TSDB_PAYLOAD_SIZE,
|
||||||
|
@ -2017,7 +1924,8 @@ int32_t tscMergeTableDataBlocks(SInsertStatementParam *pInsertParam, bool freeBl
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t destSize = dataBuf->size + pOneTableBlock->size + pBlocks->numOfRows * expandSize + sizeof(STColumn) * tscGetNumOfColumns(pOneTableBlock->pTableMeta);
|
int64_t destSize = dataBuf->size + pOneTableBlock->size + pBlocks->numOfRows * expandSize +
|
||||||
|
sizeof(STColumn) * tscGetNumOfColumns(pOneTableBlock->pTableMeta);
|
||||||
|
|
||||||
if (dataBuf->nAllocSize < destSize) {
|
if (dataBuf->nAllocSize < destSize) {
|
||||||
dataBuf->nAllocSize = (uint32_t)(destSize * 1.5);
|
dataBuf->nAllocSize = (uint32_t)(destSize * 1.5);
|
||||||
|
@ -2061,7 +1969,9 @@ int32_t tscMergeTableDataBlocks(SInsertStatementParam *pInsertParam, bool freeBl
|
||||||
pBlocks->numOfRows, pBlocks->sversion, blkKeyInfo.pKeyTuple->skey, pLastKeyTuple->skey);
|
pBlocks->numOfRows, pBlocks->sversion, blkKeyInfo.pKeyTuple->skey, pLastKeyTuple->skey);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t len = pBlocks->numOfRows * (pOneTableBlock->rowSize + expandSize) + sizeof(STColumn) * tscGetNumOfColumns(pOneTableBlock->pTableMeta);
|
int32_t len = pBlocks->numOfRows *
|
||||||
|
(isRawPayload ? (pOneTableBlock->rowSize + expandSize) : getExtendedRowSize(pOneTableBlock)) +
|
||||||
|
sizeof(STColumn) * tscGetNumOfColumns(pOneTableBlock->pTableMeta);
|
||||||
|
|
||||||
pBlocks->tid = htonl(pBlocks->tid);
|
pBlocks->tid = htonl(pBlocks->tid);
|
||||||
pBlocks->uid = htobe64(pBlocks->uid);
|
pBlocks->uid = htobe64(pBlocks->uid);
|
||||||
|
|
|
@ -186,6 +186,7 @@ typedef void *SDataRow;
|
||||||
#define TD_DATA_ROW_HEAD_SIZE (sizeof(uint16_t) + sizeof(int16_t))
|
#define TD_DATA_ROW_HEAD_SIZE (sizeof(uint16_t) + sizeof(int16_t))
|
||||||
|
|
||||||
#define dataRowLen(r) (*(TDRowLenT *)(r)) // 0~65535
|
#define dataRowLen(r) (*(TDRowLenT *)(r)) // 0~65535
|
||||||
|
#define dataRowEnd(r) POINTER_SHIFT(r, dataRowLen(r))
|
||||||
#define dataRowVersion(r) (*(int16_t *)POINTER_SHIFT(r, sizeof(int16_t)))
|
#define dataRowVersion(r) (*(int16_t *)POINTER_SHIFT(r, sizeof(int16_t)))
|
||||||
#define dataRowTuple(r) POINTER_SHIFT(r, TD_DATA_ROW_HEAD_SIZE)
|
#define dataRowTuple(r) POINTER_SHIFT(r, TD_DATA_ROW_HEAD_SIZE)
|
||||||
#define dataRowTKey(r) (*(TKEY *)(dataRowTuple(r)))
|
#define dataRowTKey(r) (*(TKEY *)(dataRowTuple(r)))
|
||||||
|
@ -201,14 +202,18 @@ void tdFreeDataRow(SDataRow row);
|
||||||
void tdInitDataRow(SDataRow row, STSchema *pSchema);
|
void tdInitDataRow(SDataRow row, STSchema *pSchema);
|
||||||
SDataRow tdDataRowDup(SDataRow row);
|
SDataRow tdDataRowDup(SDataRow row);
|
||||||
|
|
||||||
|
|
||||||
// offset here not include dataRow header length
|
// offset here not include dataRow header length
|
||||||
static FORCE_INLINE int tdAppendColVal(SDataRow row, const void *value, int8_t type, int32_t offset) {
|
static FORCE_INLINE int tdAppendDataColVal(SDataRow row, const void *value, bool isCopyVarData, int8_t type,
|
||||||
|
int32_t offset) {
|
||||||
ASSERT(value != NULL);
|
ASSERT(value != NULL);
|
||||||
int32_t toffset = offset + TD_DATA_ROW_HEAD_SIZE;
|
int32_t toffset = offset + TD_DATA_ROW_HEAD_SIZE;
|
||||||
|
|
||||||
if (IS_VAR_DATA_TYPE(type)) {
|
if (IS_VAR_DATA_TYPE(type)) {
|
||||||
*(VarDataOffsetT *)POINTER_SHIFT(row, toffset) = dataRowLen(row);
|
*(VarDataOffsetT *)POINTER_SHIFT(row, toffset) = dataRowLen(row);
|
||||||
|
if (isCopyVarData) {
|
||||||
memcpy(POINTER_SHIFT(row, dataRowLen(row)), value, varDataTLen(value));
|
memcpy(POINTER_SHIFT(row, dataRowLen(row)), value, varDataTLen(value));
|
||||||
|
}
|
||||||
dataRowLen(row) += varDataTLen(value);
|
dataRowLen(row) += varDataTLen(value);
|
||||||
} else {
|
} else {
|
||||||
if (offset == 0) {
|
if (offset == 0) {
|
||||||
|
@ -223,6 +228,12 @@ static FORCE_INLINE int tdAppendColVal(SDataRow row, const void *value, int8_t t
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// offset here not include dataRow header length
|
||||||
|
static FORCE_INLINE int tdAppendColVal(SDataRow row, const void *value, int8_t type, int32_t offset) {
|
||||||
|
return tdAppendDataColVal(row, value, true, type, offset);
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE: offset here including the header size
|
// NOTE: offset here including the header size
|
||||||
static FORCE_INLINE void *tdGetRowDataOfCol(SDataRow row, int8_t type, int32_t offset) {
|
static FORCE_INLINE void *tdGetRowDataOfCol(SDataRow row, int8_t type, int32_t offset) {
|
||||||
if (IS_VAR_DATA_TYPE(type)) {
|
if (IS_VAR_DATA_TYPE(type)) {
|
||||||
|
@ -328,11 +339,10 @@ static FORCE_INLINE void dataColReset(SDataCol *pDataCol) { pDataCol->len = 0; }
|
||||||
int tdAllocMemForCol(SDataCol *pCol, int maxPoints);
|
int tdAllocMemForCol(SDataCol *pCol, int maxPoints);
|
||||||
|
|
||||||
void dataColInit(SDataCol *pDataCol, STColumn *pCol, int maxPoints);
|
void dataColInit(SDataCol *pDataCol, STColumn *pCol, int maxPoints);
|
||||||
void dataColAppendVal(SDataCol *pCol, const void *value, int numOfRows, int maxPoints);
|
int dataColAppendVal(SDataCol *pCol, const void *value, int numOfRows, int maxPoints);
|
||||||
void dataColSetOffset(SDataCol *pCol, int nEle);
|
void dataColSetOffset(SDataCol *pCol, int nEle);
|
||||||
|
|
||||||
bool isNEleNull(SDataCol *pCol, int nEle);
|
bool isNEleNull(SDataCol *pCol, int nEle);
|
||||||
void dataColSetNEleNull(SDataCol *pCol, int nEle, int maxPoints);
|
|
||||||
|
|
||||||
// Get the data pointer from a column-wised data
|
// Get the data pointer from a column-wised data
|
||||||
static FORCE_INLINE const void *tdGetColDataOfRow(SDataCol *pCol, int row) {
|
static FORCE_INLINE const void *tdGetColDataOfRow(SDataCol *pCol, int row) {
|
||||||
|
@ -357,10 +367,8 @@ static FORCE_INLINE int32_t dataColGetNEleLen(SDataCol *pDataCol, int rows) {
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int maxRowSize;
|
|
||||||
int maxCols; // max number of columns
|
int maxCols; // max number of columns
|
||||||
int maxPoints; // max number of points
|
int maxPoints; // max number of points
|
||||||
|
|
||||||
int numOfRows;
|
int numOfRows;
|
||||||
int numOfCols; // Total number of cols
|
int numOfCols; // Total number of cols
|
||||||
int sversion; // TODO: set sversion
|
int sversion; // TODO: set sversion
|
||||||
|
@ -407,7 +415,7 @@ static FORCE_INLINE TSKEY dataColsKeyLast(SDataCols *pCols) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SDataCols *tdNewDataCols(int maxRowSize, int maxCols, int maxRows);
|
SDataCols *tdNewDataCols(int maxCols, int maxRows);
|
||||||
void tdResetDataCols(SDataCols *pCols);
|
void tdResetDataCols(SDataCols *pCols);
|
||||||
int tdInitDataCols(SDataCols *pCols, STSchema *pSchema);
|
int tdInitDataCols(SDataCols *pCols, STSchema *pSchema);
|
||||||
SDataCols *tdDupDataCols(SDataCols *pCols, bool keepData);
|
SDataCols *tdDupDataCols(SDataCols *pCols, bool keepData);
|
||||||
|
@ -475,9 +483,10 @@ static FORCE_INLINE void *tdGetKVRowIdxOfCol(SKVRow row, int16_t colId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// offset here not include kvRow header length
|
// offset here not include kvRow header length
|
||||||
static FORCE_INLINE int tdAppendKvColVal(SKVRow row, const void *value, int16_t colId, int8_t type, int32_t *offset) {
|
static FORCE_INLINE int tdAppendKvColVal(SKVRow row, const void *value, bool isCopyValData, int16_t colId, int8_t type,
|
||||||
|
int32_t offset) {
|
||||||
ASSERT(value != NULL);
|
ASSERT(value != NULL);
|
||||||
int32_t toffset = *offset + TD_KV_ROW_HEAD_SIZE;
|
int32_t toffset = offset + TD_KV_ROW_HEAD_SIZE;
|
||||||
SColIdx *pColIdx = (SColIdx *)POINTER_SHIFT(row, toffset);
|
SColIdx *pColIdx = (SColIdx *)POINTER_SHIFT(row, toffset);
|
||||||
char * ptr = (char *)POINTER_SHIFT(row, kvRowLen(row));
|
char * ptr = (char *)POINTER_SHIFT(row, kvRowLen(row));
|
||||||
|
|
||||||
|
@ -485,10 +494,12 @@ static FORCE_INLINE int tdAppendKvColVal(SKVRow row, const void *value, int16_t
|
||||||
pColIdx->offset = kvRowLen(row); // offset of pColIdx including the TD_KV_ROW_HEAD_SIZE
|
pColIdx->offset = kvRowLen(row); // offset of pColIdx including the TD_KV_ROW_HEAD_SIZE
|
||||||
|
|
||||||
if (IS_VAR_DATA_TYPE(type)) {
|
if (IS_VAR_DATA_TYPE(type)) {
|
||||||
|
if (isCopyValData) {
|
||||||
memcpy(ptr, value, varDataTLen(value));
|
memcpy(ptr, value, varDataTLen(value));
|
||||||
|
}
|
||||||
kvRowLen(row) += varDataTLen(value);
|
kvRowLen(row) += varDataTLen(value);
|
||||||
} else {
|
} else {
|
||||||
if (*offset == 0) {
|
if (offset == 0) {
|
||||||
ASSERT(type == TSDB_DATA_TYPE_TIMESTAMP);
|
ASSERT(type == TSDB_DATA_TYPE_TIMESTAMP);
|
||||||
TKEY tvalue = tdGetTKEY(*(TSKEY *)value);
|
TKEY tvalue = tdGetTKEY(*(TSKEY *)value);
|
||||||
memcpy(ptr, (void *)(&tvalue), TYPE_BYTES[type]);
|
memcpy(ptr, (void *)(&tvalue), TYPE_BYTES[type]);
|
||||||
|
@ -497,7 +508,6 @@ static FORCE_INLINE int tdAppendKvColVal(SKVRow row, const void *value, int16_t
|
||||||
}
|
}
|
||||||
kvRowLen(row) += TYPE_BYTES[type];
|
kvRowLen(row) += TYPE_BYTES[type];
|
||||||
}
|
}
|
||||||
*offset += sizeof(SColIdx);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -592,12 +602,24 @@ typedef void *SMemRow;
|
||||||
#define TD_MEM_ROW_DATA_HEAD_SIZE (TD_MEM_ROW_TYPE_SIZE + TD_DATA_ROW_HEAD_SIZE)
|
#define TD_MEM_ROW_DATA_HEAD_SIZE (TD_MEM_ROW_TYPE_SIZE + TD_DATA_ROW_HEAD_SIZE)
|
||||||
#define TD_MEM_ROW_KV_HEAD_SIZE (TD_MEM_ROW_TYPE_SIZE + TD_MEM_ROW_KV_VER_SIZE + TD_KV_ROW_HEAD_SIZE)
|
#define TD_MEM_ROW_KV_HEAD_SIZE (TD_MEM_ROW_TYPE_SIZE + TD_MEM_ROW_KV_VER_SIZE + TD_KV_ROW_HEAD_SIZE)
|
||||||
|
|
||||||
#define SMEM_ROW_DATA 0U // SDataRow
|
#define SMEM_ROW_DATA 0x0U // SDataRow
|
||||||
#define SMEM_ROW_KV 1U // SKVRow
|
#define SMEM_ROW_KV 0x01U // SKVRow
|
||||||
|
#define SMEM_ROW_CONVERT 0x80U // SMemRow convert flag
|
||||||
|
|
||||||
#define memRowType(r) (*(uint8_t *)(r))
|
#define KVRatioKV (0.2f) // all bool
|
||||||
|
#define KVRatioPredict (0.4f)
|
||||||
|
#define KVRatioData (0.75f) // all bigint
|
||||||
|
#define KVRatioConvert (0.9f)
|
||||||
|
|
||||||
|
#define memRowType(r) ((*(uint8_t *)(r)) & 0x01)
|
||||||
|
|
||||||
|
#define memRowSetType(r, t) ((*(uint8_t *)(r)) = (t)) // set the total byte in case of dirty memory
|
||||||
|
#define memRowSetConvert(r) ((*(uint8_t *)(r)) = (((*(uint8_t *)(r)) & 0x7F) | SMEM_ROW_CONVERT)) // highest bit
|
||||||
|
#define isDataRowT(t) (SMEM_ROW_DATA == (((uint8_t)(t)) & 0x01))
|
||||||
#define isDataRow(r) (SMEM_ROW_DATA == memRowType(r))
|
#define isDataRow(r) (SMEM_ROW_DATA == memRowType(r))
|
||||||
|
#define isKvRowT(t) (SMEM_ROW_KV == (((uint8_t)(t)) & 0x01))
|
||||||
#define isKvRow(r) (SMEM_ROW_KV == memRowType(r))
|
#define isKvRow(r) (SMEM_ROW_KV == memRowType(r))
|
||||||
|
#define isNeedConvertRow(r) (((*(uint8_t *)(r)) & 0x80) == SMEM_ROW_CONVERT)
|
||||||
|
|
||||||
#define memRowDataBody(r) POINTER_SHIFT(r, TD_MEM_ROW_TYPE_SIZE) // section after flag
|
#define memRowDataBody(r) POINTER_SHIFT(r, TD_MEM_ROW_TYPE_SIZE) // section after flag
|
||||||
#define memRowKvBody(r) \
|
#define memRowKvBody(r) \
|
||||||
|
@ -614,6 +636,14 @@ typedef void *SMemRow;
|
||||||
#define memRowLen(r) (isDataRow(r) ? memRowDataLen(r) : memRowKvLen(r))
|
#define memRowLen(r) (isDataRow(r) ? memRowDataLen(r) : memRowKvLen(r))
|
||||||
#define memRowTLen(r) (isDataRow(r) ? memRowDataTLen(r) : memRowKvTLen(r)) // using uint32_t/int32_t to store the TLen
|
#define memRowTLen(r) (isDataRow(r) ? memRowDataTLen(r) : memRowKvTLen(r)) // using uint32_t/int32_t to store the TLen
|
||||||
|
|
||||||
|
static FORCE_INLINE char *memRowEnd(SMemRow row) {
|
||||||
|
if (isDataRow(row)) {
|
||||||
|
return (char *)dataRowEnd(memRowDataBody(row));
|
||||||
|
} else {
|
||||||
|
return (char *)kvRowEnd(memRowKvBody(row));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#define memRowDataVersion(r) dataRowVersion(memRowDataBody(r))
|
#define memRowDataVersion(r) dataRowVersion(memRowDataBody(r))
|
||||||
#define memRowKvVersion(r) (*(int16_t *)POINTER_SHIFT(r, TD_MEM_ROW_TYPE_SIZE))
|
#define memRowKvVersion(r) (*(int16_t *)POINTER_SHIFT(r, TD_MEM_ROW_TYPE_SIZE))
|
||||||
#define memRowVersion(r) (isDataRow(r) ? memRowDataVersion(r) : memRowKvVersion(r)) // schema version
|
#define memRowVersion(r) (isDataRow(r) ? memRowDataVersion(r) : memRowKvVersion(r)) // schema version
|
||||||
|
@ -631,7 +661,6 @@ typedef void *SMemRow;
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define memRowSetType(r, t) (memRowType(r) = (t))
|
|
||||||
#define memRowSetLen(r, l) (isDataRow(r) ? memRowDataLen(r) = (l) : memRowKvLen(r) = (l))
|
#define memRowSetLen(r, l) (isDataRow(r) ? memRowDataLen(r) = (l) : memRowKvLen(r) = (l))
|
||||||
#define memRowSetVersion(r, v) (isDataRow(r) ? dataRowSetVersion(memRowDataBody(r), v) : memRowSetKvVersion(r, v))
|
#define memRowSetVersion(r, v) (isDataRow(r) ? dataRowSetVersion(memRowDataBody(r), v) : memRowSetKvVersion(r, v))
|
||||||
#define memRowCpy(dst, r) memcpy((dst), (r), memRowTLen(r))
|
#define memRowCpy(dst, r) memcpy((dst), (r), memRowTLen(r))
|
||||||
|
@ -664,12 +693,12 @@ static FORCE_INLINE void *tdGetMemRowDataOfColEx(void *row, int16_t colId, int8_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static FORCE_INLINE int tdAppendMemColVal(SMemRow row, const void *value, int16_t colId, int8_t type, int32_t offset,
|
static FORCE_INLINE int tdAppendMemRowColVal(SMemRow row, const void *value, bool isCopyVarData, int16_t colId,
|
||||||
int32_t *kvOffset) {
|
int8_t type, int32_t offset) {
|
||||||
if (isDataRow(row)) {
|
if (isDataRow(row)) {
|
||||||
tdAppendColVal(memRowDataBody(row), value, type, offset);
|
tdAppendDataColVal(memRowDataBody(row), value, isCopyVarData, type, offset);
|
||||||
} else {
|
} else {
|
||||||
tdAppendKvColVal(memRowKvBody(row), value, colId, type, kvOffset);
|
tdAppendKvColVal(memRowKvBody(row), value, isCopyVarData, colId, type, offset);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -691,6 +720,30 @@ static FORCE_INLINE int32_t tdGetColAppendLen(uint8_t rowType, const void *value
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. calculate the delta of AllNullLen for SDataRow.
|
||||||
|
* 2. calculate the real len for SKVRow.
|
||||||
|
*/
|
||||||
|
static FORCE_INLINE void tdGetColAppendDeltaLen(const void *value, int8_t colType, int32_t *dataLen, int32_t *kvLen) {
|
||||||
|
switch (colType) {
|
||||||
|
case TSDB_DATA_TYPE_BINARY: {
|
||||||
|
int32_t varLen = varDataLen(value);
|
||||||
|
*dataLen += (varLen - CHAR_BYTES);
|
||||||
|
*kvLen += (varLen + sizeof(SColIdx));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TSDB_DATA_TYPE_NCHAR: {
|
||||||
|
int32_t varLen = varDataLen(value);
|
||||||
|
*dataLen += (varLen - TSDB_NCHAR_SIZE);
|
||||||
|
*kvLen += (varLen + sizeof(SColIdx));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
*kvLen += (TYPE_BYTES[colType] + sizeof(SColIdx));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int16_t colId;
|
int16_t colId;
|
||||||
|
@ -706,7 +759,7 @@ static FORCE_INLINE void setSColInfo(SColInfo* colInfo, int16_t colId, uint8_t c
|
||||||
|
|
||||||
SMemRow mergeTwoMemRows(void *buffer, SMemRow row1, SMemRow row2, STSchema *pSchema1, STSchema *pSchema2);
|
SMemRow mergeTwoMemRows(void *buffer, SMemRow row1, SMemRow row2, STSchema *pSchema1, STSchema *pSchema2);
|
||||||
|
|
||||||
|
#if 0
|
||||||
// ----------------- Raw payload structure for row:
|
// ----------------- Raw payload structure for row:
|
||||||
/* |<------------ Head ------------->|<----------- body of column data tuple ------------------->|
|
/* |<------------ Head ------------->|<----------- body of column data tuple ------------------->|
|
||||||
* | |<----------------- flen ------------->|<--- value part --->|
|
* | |<----------------- flen ------------->|<--- value part --->|
|
||||||
|
@ -752,6 +805,8 @@ SMemRow mergeTwoMemRows(void *buffer, SMemRow row1, SMemRow row2, STSchema *pSch
|
||||||
|
|
||||||
static FORCE_INLINE char *payloadNextCol(char *pCol) { return (char *)POINTER_SHIFT(pCol, PAYLOAD_COL_HEAD_LEN); }
|
static FORCE_INLINE char *payloadNextCol(char *pCol) { return (char *)POINTER_SHIFT(pCol, PAYLOAD_COL_HEAD_LEN); }
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -19,10 +19,10 @@
|
||||||
#include "wchar.h"
|
#include "wchar.h"
|
||||||
#include "tarray.h"
|
#include "tarray.h"
|
||||||
|
|
||||||
|
static void dataColSetNEleNull(SDataCol *pCol, int nEle);
|
||||||
static void tdMergeTwoDataCols(SDataCols *target, SDataCols *src1, int *iter1, int limit1, SDataCols *src2, int *iter2,
|
static void tdMergeTwoDataCols(SDataCols *target, SDataCols *src1, int *iter1, int limit1, SDataCols *src2, int *iter2,
|
||||||
int limit2, int tRows, bool forceSetNull);
|
int limit2, int tRows, bool forceSetNull);
|
||||||
|
|
||||||
//TODO: change caller to use return val
|
|
||||||
int tdAllocMemForCol(SDataCol *pCol, int maxPoints) {
|
int tdAllocMemForCol(SDataCol *pCol, int maxPoints) {
|
||||||
int spaceNeeded = pCol->bytes * maxPoints;
|
int spaceNeeded = pCol->bytes * maxPoints;
|
||||||
if(IS_VAR_DATA_TYPE(pCol->type)) {
|
if(IS_VAR_DATA_TYPE(pCol->type)) {
|
||||||
|
@ -31,7 +31,7 @@ int tdAllocMemForCol(SDataCol *pCol, int maxPoints) {
|
||||||
if(pCol->spaceSize < spaceNeeded) {
|
if(pCol->spaceSize < spaceNeeded) {
|
||||||
void* ptr = realloc(pCol->pData, spaceNeeded);
|
void* ptr = realloc(pCol->pData, spaceNeeded);
|
||||||
if(ptr == NULL) {
|
if(ptr == NULL) {
|
||||||
uDebug("malloc failure, size:%" PRId64 " failed, reason:%s", (int64_t)pCol->spaceSize,
|
uDebug("malloc failure, size:%" PRId64 " failed, reason:%s", (int64_t)spaceNeeded,
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
|
@ -239,20 +239,19 @@ void dataColInit(SDataCol *pDataCol, STColumn *pCol, int maxPoints) {
|
||||||
pDataCol->len = 0;
|
pDataCol->len = 0;
|
||||||
}
|
}
|
||||||
// value from timestamp should be TKEY here instead of TSKEY
|
// value from timestamp should be TKEY here instead of TSKEY
|
||||||
void dataColAppendVal(SDataCol *pCol, const void *value, int numOfRows, int maxPoints) {
|
int dataColAppendVal(SDataCol *pCol, const void *value, int numOfRows, int maxPoints) {
|
||||||
ASSERT(pCol != NULL && value != NULL);
|
ASSERT(pCol != NULL && value != NULL);
|
||||||
|
|
||||||
if (isAllRowsNull(pCol)) {
|
if (isAllRowsNull(pCol)) {
|
||||||
if (isNull(value, pCol->type)) {
|
if (isNull(value, pCol->type)) {
|
||||||
// all null value yet, just return
|
// all null value yet, just return
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(tdAllocMemForCol(pCol, maxPoints) < 0) return -1;
|
||||||
if (numOfRows > 0) {
|
if (numOfRows > 0) {
|
||||||
// Find the first not null value, fill all previouse values as NULL
|
// Find the first not null value, fill all previouse values as NULL
|
||||||
dataColSetNEleNull(pCol, numOfRows, maxPoints);
|
dataColSetNEleNull(pCol, numOfRows);
|
||||||
} else {
|
|
||||||
tdAllocMemForCol(pCol, maxPoints);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,12 +267,21 @@ void dataColAppendVal(SDataCol *pCol, const void *value, int numOfRows, int maxP
|
||||||
memcpy(POINTER_SHIFT(pCol->pData, pCol->len), value, pCol->bytes);
|
memcpy(POINTER_SHIFT(pCol->pData, pCol->len), value, pCol->bytes);
|
||||||
pCol->len += pCol->bytes;
|
pCol->len += pCol->bytes;
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static FORCE_INLINE const void *tdGetColDataOfRowUnsafe(SDataCol *pCol, int row) {
|
||||||
|
if (IS_VAR_DATA_TYPE(pCol->type)) {
|
||||||
|
return POINTER_SHIFT(pCol->pData, pCol->dataOff[row]);
|
||||||
|
} else {
|
||||||
|
return POINTER_SHIFT(pCol->pData, TYPE_BYTES[pCol->type] * row);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isNEleNull(SDataCol *pCol, int nEle) {
|
bool isNEleNull(SDataCol *pCol, int nEle) {
|
||||||
if(isAllRowsNull(pCol)) return true;
|
if(isAllRowsNull(pCol)) return true;
|
||||||
for (int i = 0; i < nEle; i++) {
|
for (int i = 0; i < nEle; i++) {
|
||||||
if (!isNull(tdGetColDataOfRow(pCol, i), pCol->type)) return false;
|
if (!isNull(tdGetColDataOfRowUnsafe(pCol, i), pCol->type)) return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -290,9 +298,7 @@ static FORCE_INLINE void dataColSetNullAt(SDataCol *pCol, int index) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dataColSetNEleNull(SDataCol *pCol, int nEle, int maxPoints) {
|
static void dataColSetNEleNull(SDataCol *pCol, int nEle) {
|
||||||
tdAllocMemForCol(pCol, maxPoints);
|
|
||||||
|
|
||||||
if (IS_VAR_DATA_TYPE(pCol->type)) {
|
if (IS_VAR_DATA_TYPE(pCol->type)) {
|
||||||
pCol->len = 0;
|
pCol->len = 0;
|
||||||
for (int i = 0; i < nEle; i++) {
|
for (int i = 0; i < nEle; i++) {
|
||||||
|
@ -318,7 +324,7 @@ void dataColSetOffset(SDataCol *pCol, int nEle) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SDataCols *tdNewDataCols(int maxRowSize, int maxCols, int maxRows) {
|
SDataCols *tdNewDataCols(int maxCols, int maxRows) {
|
||||||
SDataCols *pCols = (SDataCols *)calloc(1, sizeof(SDataCols));
|
SDataCols *pCols = (SDataCols *)calloc(1, sizeof(SDataCols));
|
||||||
if (pCols == NULL) {
|
if (pCols == NULL) {
|
||||||
uDebug("malloc failure, size:%" PRId64 " failed, reason:%s", (int64_t)sizeof(SDataCols), strerror(errno));
|
uDebug("malloc failure, size:%" PRId64 " failed, reason:%s", (int64_t)sizeof(SDataCols), strerror(errno));
|
||||||
|
@ -326,6 +332,9 @@ SDataCols *tdNewDataCols(int maxRowSize, int maxCols, int maxRows) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pCols->maxPoints = maxRows;
|
pCols->maxPoints = maxRows;
|
||||||
|
pCols->maxCols = maxCols;
|
||||||
|
pCols->numOfRows = 0;
|
||||||
|
pCols->numOfCols = 0;
|
||||||
|
|
||||||
if (maxCols > 0) {
|
if (maxCols > 0) {
|
||||||
pCols->cols = (SDataCol *)calloc(maxCols, sizeof(SDataCol));
|
pCols->cols = (SDataCol *)calloc(maxCols, sizeof(SDataCol));
|
||||||
|
@ -342,13 +351,8 @@ SDataCols *tdNewDataCols(int maxRowSize, int maxCols, int maxRows) {
|
||||||
pCols->cols[i].pData = NULL;
|
pCols->cols[i].pData = NULL;
|
||||||
pCols->cols[i].dataOff = NULL;
|
pCols->cols[i].dataOff = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pCols->maxCols = maxCols;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pCols->maxRowSize = maxRowSize;
|
|
||||||
|
|
||||||
|
|
||||||
return pCols;
|
return pCols;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -357,8 +361,9 @@ int tdInitDataCols(SDataCols *pCols, STSchema *pSchema) {
|
||||||
int oldMaxCols = pCols->maxCols;
|
int oldMaxCols = pCols->maxCols;
|
||||||
if (schemaNCols(pSchema) > oldMaxCols) {
|
if (schemaNCols(pSchema) > oldMaxCols) {
|
||||||
pCols->maxCols = schemaNCols(pSchema);
|
pCols->maxCols = schemaNCols(pSchema);
|
||||||
pCols->cols = (SDataCol *)realloc(pCols->cols, sizeof(SDataCol) * pCols->maxCols);
|
void* ptr = (SDataCol *)realloc(pCols->cols, sizeof(SDataCol) * pCols->maxCols);
|
||||||
if (pCols->cols == NULL) return -1;
|
if (ptr == NULL) return -1;
|
||||||
|
pCols->cols = ptr;
|
||||||
for(i = oldMaxCols; i < pCols->maxCols; i++) {
|
for(i = oldMaxCols; i < pCols->maxCols; i++) {
|
||||||
pCols->cols[i].pData = NULL;
|
pCols->cols[i].pData = NULL;
|
||||||
pCols->cols[i].dataOff = NULL;
|
pCols->cols[i].dataOff = NULL;
|
||||||
|
@ -366,10 +371,6 @@ int tdInitDataCols(SDataCols *pCols, STSchema *pSchema) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (schemaTLen(pSchema) > pCols->maxRowSize) {
|
|
||||||
pCols->maxRowSize = schemaTLen(pSchema);
|
|
||||||
}
|
|
||||||
|
|
||||||
tdResetDataCols(pCols);
|
tdResetDataCols(pCols);
|
||||||
pCols->numOfCols = schemaNCols(pSchema);
|
pCols->numOfCols = schemaNCols(pSchema);
|
||||||
|
|
||||||
|
@ -398,7 +399,7 @@ SDataCols *tdFreeDataCols(SDataCols *pCols) {
|
||||||
}
|
}
|
||||||
|
|
||||||
SDataCols *tdDupDataCols(SDataCols *pDataCols, bool keepData) {
|
SDataCols *tdDupDataCols(SDataCols *pDataCols, bool keepData) {
|
||||||
SDataCols *pRet = tdNewDataCols(pDataCols->maxRowSize, pDataCols->maxCols, pDataCols->maxPoints);
|
SDataCols *pRet = tdNewDataCols(pDataCols->maxCols, pDataCols->maxPoints);
|
||||||
if (pRet == NULL) return NULL;
|
if (pRet == NULL) return NULL;
|
||||||
|
|
||||||
pRet->numOfCols = pDataCols->numOfCols;
|
pRet->numOfCols = pDataCols->numOfCols;
|
||||||
|
@ -413,7 +414,10 @@ SDataCols *tdDupDataCols(SDataCols *pDataCols, bool keepData) {
|
||||||
|
|
||||||
if (keepData) {
|
if (keepData) {
|
||||||
if (pDataCols->cols[i].len > 0) {
|
if (pDataCols->cols[i].len > 0) {
|
||||||
tdAllocMemForCol(&pRet->cols[i], pRet->maxPoints);
|
if(tdAllocMemForCol(&pRet->cols[i], pRet->maxPoints) < 0) {
|
||||||
|
tdFreeDataCols(pRet);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
pRet->cols[i].len = pDataCols->cols[i].len;
|
pRet->cols[i].len = pDataCols->cols[i].len;
|
||||||
memcpy(pRet->cols[i].pData, pDataCols->cols[i].pData, pDataCols->cols[i].len);
|
memcpy(pRet->cols[i].pData, pDataCols->cols[i].pData, pDataCols->cols[i].len);
|
||||||
if (IS_VAR_DATA_TYPE(pRet->cols[i].type)) {
|
if (IS_VAR_DATA_TYPE(pRet->cols[i].type)) {
|
||||||
|
@ -584,9 +588,12 @@ static void tdMergeTwoDataCols(SDataCols *target, SDataCols *src1, int *iter1, i
|
||||||
if ((key1 > key2) || (key1 == key2 && !TKEY_IS_DELETED(tkey2))) {
|
if ((key1 > key2) || (key1 == key2 && !TKEY_IS_DELETED(tkey2))) {
|
||||||
for (int i = 0; i < src2->numOfCols; i++) {
|
for (int i = 0; i < src2->numOfCols; i++) {
|
||||||
ASSERT(target->cols[i].type == src2->cols[i].type);
|
ASSERT(target->cols[i].type == src2->cols[i].type);
|
||||||
if (src2->cols[i].len > 0 && (forceSetNull || (!forceSetNull && !isNull(src2->cols[i].pData, src2->cols[i].type)))) {
|
if (src2->cols[i].len > 0 && !isNull(src2->cols[i].pData, src2->cols[i].type)) {
|
||||||
dataColAppendVal(&(target->cols[i]), tdGetColDataOfRow(src2->cols + i, *iter2), target->numOfRows,
|
dataColAppendVal(&(target->cols[i]), tdGetColDataOfRow(src2->cols + i, *iter2), target->numOfRows,
|
||||||
target->maxPoints);
|
target->maxPoints);
|
||||||
|
} else if(!forceSetNull && key1 == key2 && src1->cols[i].len > 0) {
|
||||||
|
dataColAppendVal(&(target->cols[i]), tdGetColDataOfRow(src1->cols + i, *iter1), target->numOfRows,
|
||||||
|
target->maxPoints);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
target->numOfRows++;
|
target->numOfRows++;
|
||||||
|
@ -844,7 +851,8 @@ SMemRow mergeTwoMemRows(void *buffer, SMemRow row1, SMemRow row2, STSchema *pSch
|
||||||
int16_t k;
|
int16_t k;
|
||||||
for (k = 0; k < nKvNCols; ++k) {
|
for (k = 0; k < nKvNCols; ++k) {
|
||||||
SColInfo *pColInfo = taosArrayGet(stashRow, k);
|
SColInfo *pColInfo = taosArrayGet(stashRow, k);
|
||||||
tdAppendKvColVal(kvRow, pColInfo->colVal, pColInfo->colId, pColInfo->colType, &toffset);
|
tdAppendKvColVal(kvRow, pColInfo->colVal, true, pColInfo->colId, pColInfo->colType, toffset);
|
||||||
|
toffset += sizeof(SColIdx);
|
||||||
}
|
}
|
||||||
ASSERT(kvLen == memRowTLen(tRow));
|
ASSERT(kvLen == memRowTLen(tRow));
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,7 +113,6 @@
|
||||||
</includes>
|
</includes>
|
||||||
<excludes>
|
<excludes>
|
||||||
<exclude>**/AppMemoryLeakTest.java</exclude>
|
<exclude>**/AppMemoryLeakTest.java</exclude>
|
||||||
<exclude>**/AuthenticationTest.java</exclude>
|
|
||||||
<exclude>**/ConnectMultiTaosdByRestfulWithDifferentTokenTest.java</exclude>
|
<exclude>**/ConnectMultiTaosdByRestfulWithDifferentTokenTest.java</exclude>
|
||||||
<exclude>**/DatetimeBefore1970Test.java</exclude>
|
<exclude>**/DatetimeBefore1970Test.java</exclude>
|
||||||
<exclude>**/FailOverTest.java</exclude>
|
<exclude>**/FailOverTest.java</exclude>
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
package com.taosdata.jdbc;
|
package com.taosdata.jdbc;
|
||||||
|
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
@ -127,6 +129,11 @@ public class TSDBDriver extends AbstractDriver {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!props.containsKey(TSDBDriver.PROPERTY_KEY_USER))
|
||||||
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_USER_IS_REQUIRED);
|
||||||
|
if (!props.containsKey(TSDBDriver.PROPERTY_KEY_PASSWORD))
|
||||||
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PASSWORD_IS_REQUIRED);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
TSDBJNIConnector.init((String) props.get(PROPERTY_KEY_CONFIG_DIR), (String) props.get(PROPERTY_KEY_LOCALE),
|
TSDBJNIConnector.init((String) props.get(PROPERTY_KEY_CONFIG_DIR), (String) props.get(PROPERTY_KEY_LOCALE),
|
||||||
(String) props.get(PROPERTY_KEY_CHARSET), (String) props.get(PROPERTY_KEY_TIME_ZONE));
|
(String) props.get(PROPERTY_KEY_CHARSET), (String) props.get(PROPERTY_KEY_TIME_ZONE));
|
||||||
|
|
|
@ -33,6 +33,8 @@ public class TSDBError {
|
||||||
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE, "numeric value out of range");
|
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE, "numeric value out of range");
|
||||||
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_UNKNOWN_TAOS_TYPE, "unknown taos type in tdengine");
|
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_UNKNOWN_TAOS_TYPE, "unknown taos type in tdengine");
|
||||||
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_UNKNOWN_TIMESTAMP_PRECISION, "unknown timestamp precision");
|
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_UNKNOWN_TIMESTAMP_PRECISION, "unknown timestamp precision");
|
||||||
|
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_USER_IS_REQUIRED, "user is required");
|
||||||
|
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_PASSWORD_IS_REQUIRED, "password is required");
|
||||||
|
|
||||||
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_UNKNOWN, "unknown error");
|
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_UNKNOWN, "unknown error");
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,9 @@ public class TSDBErrorNumbers {
|
||||||
public static final int ERROR_UNKNOWN_TIMESTAMP_PRECISION = 0x2316; // unknown timestamp precision
|
public static final int ERROR_UNKNOWN_TIMESTAMP_PRECISION = 0x2316; // unknown timestamp precision
|
||||||
public static final int ERROR_RESTFul_Client_Protocol_Exception = 0x2317;
|
public static final int ERROR_RESTFul_Client_Protocol_Exception = 0x2317;
|
||||||
public static final int ERROR_RESTFul_Client_IOException = 0x2318;
|
public static final int ERROR_RESTFul_Client_IOException = 0x2318;
|
||||||
|
public static final int ERROR_USER_IS_REQUIRED = 0x2319; // user is required
|
||||||
|
public static final int ERROR_PASSWORD_IS_REQUIRED = 0x231a; // password is required
|
||||||
|
|
||||||
|
|
||||||
public static final int ERROR_UNKNOWN = 0x2350; //unknown error
|
public static final int ERROR_UNKNOWN = 0x2350; //unknown error
|
||||||
|
|
||||||
|
@ -67,6 +70,8 @@ public class TSDBErrorNumbers {
|
||||||
errorNumbers.add(ERROR_UNKNOWN_TAOS_TYPE);
|
errorNumbers.add(ERROR_UNKNOWN_TAOS_TYPE);
|
||||||
errorNumbers.add(ERROR_UNKNOWN_TIMESTAMP_PRECISION);
|
errorNumbers.add(ERROR_UNKNOWN_TIMESTAMP_PRECISION);
|
||||||
errorNumbers.add(ERROR_RESTFul_Client_IOException);
|
errorNumbers.add(ERROR_RESTFul_Client_IOException);
|
||||||
|
errorNumbers.add(ERROR_USER_IS_REQUIRED);
|
||||||
|
errorNumbers.add(ERROR_PASSWORD_IS_REQUIRED);
|
||||||
|
|
||||||
errorNumbers.add(ERROR_RESTFul_Client_Protocol_Exception);
|
errorNumbers.add(ERROR_RESTFul_Client_Protocol_Exception);
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,6 @@ public class TSDBJNIConnector {
|
||||||
|
|
||||||
static {
|
static {
|
||||||
System.loadLibrary("taos");
|
System.loadLibrary("taos");
|
||||||
System.out.println("java.library.path:" + System.getProperty("java.library.path"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isClosed() {
|
public boolean isClosed() {
|
||||||
|
|
|
@ -7,6 +7,7 @@ import com.taosdata.jdbc.utils.HttpClientPoolUtil;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
@ -40,8 +41,13 @@ public class RestfulDriver extends AbstractDriver {
|
||||||
|
|
||||||
String loginUrl = "http://" + host + ":" + port + "/rest/login/" + props.getProperty(TSDBDriver.PROPERTY_KEY_USER) + "/" + props.getProperty(TSDBDriver.PROPERTY_KEY_PASSWORD) + "";
|
String loginUrl = "http://" + host + ":" + port + "/rest/login/" + props.getProperty(TSDBDriver.PROPERTY_KEY_USER) + "/" + props.getProperty(TSDBDriver.PROPERTY_KEY_PASSWORD) + "";
|
||||||
try {
|
try {
|
||||||
String user = URLEncoder.encode(props.getProperty(TSDBDriver.PROPERTY_KEY_USER), "UTF-8");
|
if (!props.containsKey(TSDBDriver.PROPERTY_KEY_USER))
|
||||||
String password = URLEncoder.encode(props.getProperty(TSDBDriver.PROPERTY_KEY_PASSWORD), "UTF-8");
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_USER_IS_REQUIRED);
|
||||||
|
if (!props.containsKey(TSDBDriver.PROPERTY_KEY_PASSWORD))
|
||||||
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PASSWORD_IS_REQUIRED);
|
||||||
|
|
||||||
|
String user = URLEncoder.encode(props.getProperty(TSDBDriver.PROPERTY_KEY_USER), StandardCharsets.UTF_8.displayName());
|
||||||
|
String password = URLEncoder.encode(props.getProperty(TSDBDriver.PROPERTY_KEY_PASSWORD), StandardCharsets.UTF_8.displayName());
|
||||||
loginUrl = "http://" + props.getProperty(TSDBDriver.PROPERTY_KEY_HOST) + ":" + props.getProperty(TSDBDriver.PROPERTY_KEY_PORT) + "/rest/login/" + user + "/" + password + "";
|
loginUrl = "http://" + props.getProperty(TSDBDriver.PROPERTY_KEY_HOST) + ":" + props.getProperty(TSDBDriver.PROPERTY_KEY_PORT) + "/rest/login/" + user + "/" + password + "";
|
||||||
} catch (UnsupportedEncodingException e) {
|
} catch (UnsupportedEncodingException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|
|
@ -7,6 +7,7 @@ import com.taosdata.jdbc.AbstractStatement;
|
||||||
import com.taosdata.jdbc.TSDBDriver;
|
import com.taosdata.jdbc.TSDBDriver;
|
||||||
import com.taosdata.jdbc.TSDBError;
|
import com.taosdata.jdbc.TSDBError;
|
||||||
import com.taosdata.jdbc.TSDBErrorNumbers;
|
import com.taosdata.jdbc.TSDBErrorNumbers;
|
||||||
|
import com.taosdata.jdbc.enums.TimestampFormat;
|
||||||
import com.taosdata.jdbc.utils.HttpClientPoolUtil;
|
import com.taosdata.jdbc.utils.HttpClientPoolUtil;
|
||||||
import com.taosdata.jdbc.utils.SqlSyntaxValidator;
|
import com.taosdata.jdbc.utils.SqlSyntaxValidator;
|
||||||
|
|
||||||
|
@ -45,9 +46,7 @@ public class RestfulStatement extends AbstractStatement {
|
||||||
if (!SqlSyntaxValidator.isValidForExecuteUpdate(sql))
|
if (!SqlSyntaxValidator.isValidForExecuteUpdate(sql))
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_FOR_EXECUTE_UPDATE, "not a valid sql for executeUpdate: " + sql);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_FOR_EXECUTE_UPDATE, "not a valid sql for executeUpdate: " + sql);
|
||||||
|
|
||||||
final String url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sql";
|
return executeOneUpdate(sql);
|
||||||
|
|
||||||
return executeOneUpdate(url, sql);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -62,34 +61,25 @@ public class RestfulStatement extends AbstractStatement {
|
||||||
public boolean execute(String sql) throws SQLException {
|
public boolean execute(String sql) throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
||||||
if (!SqlSyntaxValidator.isValidForExecute(sql))
|
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_FOR_EXECUTE, "not a valid sql for execute: " + sql);
|
|
||||||
|
|
||||||
//如果执行了use操作应该将当前Statement的catalog设置为新的database
|
//如果执行了use操作应该将当前Statement的catalog设置为新的database
|
||||||
boolean result = true;
|
boolean result = true;
|
||||||
String url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sql";
|
|
||||||
if (conn.getClientInfo(TSDBDriver.PROPERTY_KEY_TIMESTAMP_FORMAT).equals("TIMESTAMP")) {
|
|
||||||
url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sqlt";
|
|
||||||
}
|
|
||||||
if (conn.getClientInfo(TSDBDriver.PROPERTY_KEY_TIMESTAMP_FORMAT).equals("UTC")) {
|
|
||||||
url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sqlutc";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SqlSyntaxValidator.isUseSql(sql)) {
|
if (SqlSyntaxValidator.isUseSql(sql)) {
|
||||||
HttpClientPoolUtil.execute(url, sql, this.conn.getToken());
|
HttpClientPoolUtil.execute(getUrl(), sql, this.conn.getToken());
|
||||||
this.database = sql.trim().replace("use", "").trim();
|
this.database = sql.trim().replace("use", "").trim();
|
||||||
this.conn.setCatalog(this.database);
|
this.conn.setCatalog(this.database);
|
||||||
result = false;
|
result = false;
|
||||||
} else if (SqlSyntaxValidator.isDatabaseUnspecifiedQuery(sql)) {
|
} else if (SqlSyntaxValidator.isDatabaseUnspecifiedQuery(sql)) {
|
||||||
executeOneQuery(sql);
|
executeOneQuery(sql);
|
||||||
} else if (SqlSyntaxValidator.isDatabaseUnspecifiedUpdate(sql)) {
|
} else if (SqlSyntaxValidator.isDatabaseUnspecifiedUpdate(sql)) {
|
||||||
executeOneUpdate(url, sql);
|
executeOneUpdate(sql);
|
||||||
result = false;
|
result = false;
|
||||||
} else {
|
} else {
|
||||||
if (SqlSyntaxValidator.isValidForExecuteQuery(sql)) {
|
if (SqlSyntaxValidator.isValidForExecuteQuery(sql)) {
|
||||||
executeQuery(sql);
|
executeOneQuery(sql);
|
||||||
} else {
|
} else {
|
||||||
executeUpdate(sql);
|
executeOneUpdate(sql);
|
||||||
result = false;
|
result = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,19 +87,25 @@ public class RestfulStatement extends AbstractStatement {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResultSet executeOneQuery(String sql) throws SQLException {
|
private String getUrl() throws SQLException {
|
||||||
if (!SqlSyntaxValidator.isValidForExecuteQuery(sql))
|
TimestampFormat timestampFormat = TimestampFormat.valueOf(conn.getClientInfo(TSDBDriver.PROPERTY_KEY_TIMESTAMP_FORMAT).trim().toUpperCase());
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_FOR_EXECUTE_QUERY, "not a valid sql for executeQuery: " + sql);
|
String url;
|
||||||
|
switch (timestampFormat) {
|
||||||
// row data
|
case TIMESTAMP:
|
||||||
String url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sql";
|
|
||||||
String timestampFormat = conn.getClientInfo(TSDBDriver.PROPERTY_KEY_TIMESTAMP_FORMAT);
|
|
||||||
if ("TIMESTAMP".equalsIgnoreCase(timestampFormat))
|
|
||||||
url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sqlt";
|
url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sqlt";
|
||||||
if ("UTC".equalsIgnoreCase(timestampFormat))
|
break;
|
||||||
|
case UTC:
|
||||||
url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sqlutc";
|
url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sqlutc";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sql";
|
||||||
|
}
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
String result = HttpClientPoolUtil.execute(url, sql, this.conn.getToken());
|
private ResultSet executeOneQuery(String sql) throws SQLException {
|
||||||
|
// row data
|
||||||
|
String result = HttpClientPoolUtil.execute(getUrl(), sql, this.conn.getToken());
|
||||||
JSONObject resultJson = JSON.parseObject(result);
|
JSONObject resultJson = JSON.parseObject(result);
|
||||||
if (resultJson.getString("status").equals("error")) {
|
if (resultJson.getString("status").equals("error")) {
|
||||||
throw TSDBError.createSQLException(resultJson.getInteger("code"), resultJson.getString("desc"));
|
throw TSDBError.createSQLException(resultJson.getInteger("code"), resultJson.getString("desc"));
|
||||||
|
@ -119,11 +115,8 @@ public class RestfulStatement extends AbstractStatement {
|
||||||
return resultSet;
|
return resultSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int executeOneUpdate(String url, String sql) throws SQLException {
|
private int executeOneUpdate(String sql) throws SQLException {
|
||||||
if (!SqlSyntaxValidator.isValidForExecuteUpdate(sql))
|
String result = HttpClientPoolUtil.execute(getUrl(), sql, this.conn.getToken());
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_FOR_EXECUTE_UPDATE, "not a valid sql for executeUpdate: " + sql);
|
|
||||||
|
|
||||||
String result = HttpClientPoolUtil.execute(url, sql, this.conn.getToken());
|
|
||||||
JSONObject jsonObject = JSON.parseObject(result);
|
JSONObject jsonObject = JSON.parseObject(result);
|
||||||
if (jsonObject.getString("status").equals("error")) {
|
if (jsonObject.getString("status").equals("error")) {
|
||||||
throw TSDBError.createSQLException(jsonObject.getInteger("code"), jsonObject.getString("desc"));
|
throw TSDBError.createSQLException(jsonObject.getInteger("code"), jsonObject.getString("desc"));
|
||||||
|
@ -134,7 +127,7 @@ public class RestfulStatement extends AbstractStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getAffectedRows(JSONObject jsonObject) throws SQLException {
|
private int getAffectedRows(JSONObject jsonObject) throws SQLException {
|
||||||
// create ... SQLs should return 0 , and Restful result is this:
|
// create ... SQLs should return 0 , and Restful result like this:
|
||||||
// {"status": "succ", "head": ["affected_rows"], "data": [[0]], "rows": 1}
|
// {"status": "succ", "head": ["affected_rows"], "data": [[0]], "rows": 1}
|
||||||
JSONArray head = jsonObject.getJSONArray("head");
|
JSONArray head = jsonObject.getJSONArray("head");
|
||||||
if (head.size() != 1 || !"affected_rows".equals(head.getString(0)))
|
if (head.size() != 1 || !"affected_rows".equals(head.getString(0)))
|
||||||
|
|
|
@ -16,8 +16,7 @@ package com.taosdata.jdbc.utils;
|
||||||
|
|
||||||
public class SqlSyntaxValidator {
|
public class SqlSyntaxValidator {
|
||||||
|
|
||||||
private static final String[] SQL = {"select", "insert", "import", "create", "use", "alter", "drop", "set", "show", "describe", "reset"};
|
private static final String[] updateSQL = {"insert", "import", "create", "use", "alter", "drop", "set", "reset"};
|
||||||
private static final String[] updateSQL = {"insert", "import", "create", "use", "alter", "drop", "set"};
|
|
||||||
private static final String[] querySQL = {"select", "show", "describe"};
|
private static final String[] querySQL = {"select", "show", "describe"};
|
||||||
|
|
||||||
private static final String[] databaseUnspecifiedShow = {"databases", "dnodes", "mnodes", "variables"};
|
private static final String[] databaseUnspecifiedShow = {"databases", "dnodes", "mnodes", "variables"};
|
||||||
|
@ -38,14 +37,6 @@ public class SqlSyntaxValidator {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isValidForExecute(String sql) {
|
|
||||||
for (String prefix : SQL) {
|
|
||||||
if (sql.trim().toLowerCase().startsWith(prefix))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isDatabaseUnspecifiedQuery(String sql) {
|
public static boolean isDatabaseUnspecifiedQuery(String sql) {
|
||||||
for (String databaseObj : databaseUnspecifiedShow) {
|
for (String databaseObj : databaseUnspecifiedShow) {
|
||||||
if (sql.trim().toLowerCase().matches("show\\s+" + databaseObj + ".*"))
|
if (sql.trim().toLowerCase().matches("show\\s+" + databaseObj + ".*"))
|
||||||
|
@ -63,9 +54,5 @@ public class SqlSyntaxValidator {
|
||||||
return sql.trim().toLowerCase().startsWith("use");
|
return sql.trim().toLowerCase().startsWith("use");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isSelectSql(String sql) {
|
|
||||||
return sql.trim().toLowerCase().startsWith("select");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,6 +69,8 @@ public class SubscribeTest {
|
||||||
@Before
|
@Before
|
||||||
public void createDatabase() throws SQLException {
|
public void createDatabase() throws SQLException {
|
||||||
Properties properties = new Properties();
|
Properties properties = new Properties();
|
||||||
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_USER, "root");
|
||||||
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_PASSWORD, "taosdata");
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
package com.taosdata.jdbc.cases;
|
package com.taosdata.jdbc.cases;
|
||||||
|
|
||||||
|
import com.taosdata.jdbc.TSDBErrorNumbers;
|
||||||
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
|
@ -12,6 +15,47 @@ public class AuthenticationTest {
|
||||||
private static final String password = "taos?data";
|
private static final String password = "taos?data";
|
||||||
private Connection conn;
|
private Connection conn;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void connectWithoutUserByJni() {
|
||||||
|
try {
|
||||||
|
DriverManager.getConnection("jdbc:TAOS://" + host + ":0/?");
|
||||||
|
} catch (SQLException e) {
|
||||||
|
Assert.assertEquals(TSDBErrorNumbers.ERROR_USER_IS_REQUIRED, e.getErrorCode());
|
||||||
|
Assert.assertEquals("ERROR (2319): user is required", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void connectWithoutUserByRestful() {
|
||||||
|
try {
|
||||||
|
DriverManager.getConnection("jdbc:TAOS-RS://" + host + ":6041/?");
|
||||||
|
} catch (SQLException e) {
|
||||||
|
Assert.assertEquals(TSDBErrorNumbers.ERROR_USER_IS_REQUIRED, e.getErrorCode());
|
||||||
|
Assert.assertEquals("ERROR (2319): user is required", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void connectWithoutPasswordByJni() {
|
||||||
|
try {
|
||||||
|
DriverManager.getConnection("jdbc:TAOS://" + host + ":0/?user=root");
|
||||||
|
} catch (SQLException e) {
|
||||||
|
Assert.assertEquals(TSDBErrorNumbers.ERROR_PASSWORD_IS_REQUIRED, e.getErrorCode());
|
||||||
|
Assert.assertEquals("ERROR (231a): password is required", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void connectWithoutPasswordByRestful() {
|
||||||
|
try {
|
||||||
|
DriverManager.getConnection("jdbc:TAOS-RS://" + host + ":6041/?user=root");
|
||||||
|
} catch (SQLException e) {
|
||||||
|
Assert.assertEquals(TSDBErrorNumbers.ERROR_PASSWORD_IS_REQUIRED, e.getErrorCode());
|
||||||
|
Assert.assertEquals("ERROR (231a): password is required", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Ignore
|
||||||
@Test
|
@Test
|
||||||
public void test() {
|
public void test() {
|
||||||
// change password
|
// change password
|
||||||
|
|
|
@ -29,6 +29,8 @@ public class BatchInsertTest {
|
||||||
public void before() {
|
public void before() {
|
||||||
try {
|
try {
|
||||||
Properties properties = new Properties();
|
Properties properties = new Properties();
|
||||||
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_USER, "root");
|
||||||
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_PASSWORD, "taosdata");
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
||||||
|
|
|
@ -21,6 +21,8 @@ public class ImportTest {
|
||||||
public static void before() {
|
public static void before() {
|
||||||
try {
|
try {
|
||||||
Properties properties = new Properties();
|
Properties properties = new Properties();
|
||||||
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_USER, "root");
|
||||||
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_PASSWORD, "taosdata");
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
||||||
|
|
|
@ -270,6 +270,41 @@ public class InsertSpecialCharacterJniTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Ignore
|
||||||
|
@Test
|
||||||
|
public void testSingleQuotaEscape() throws SQLException {
|
||||||
|
final long now = System.currentTimeMillis();
|
||||||
|
final String sql = "insert into t? using ? tags(?) values(?, ?, ?) t? using " + tbname2 + " tags(?) values(?,?,?) ";
|
||||||
|
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
|
||||||
|
// t1
|
||||||
|
pstmt.setInt(1, 1);
|
||||||
|
pstmt.setString(2, tbname2);
|
||||||
|
pstmt.setString(3, special_character_str_5);
|
||||||
|
pstmt.setTimestamp(4, new Timestamp(now));
|
||||||
|
pstmt.setBytes(5, special_character_str_5.getBytes());
|
||||||
|
// t2
|
||||||
|
pstmt.setInt(7, 2);
|
||||||
|
pstmt.setString(8, special_character_str_5);
|
||||||
|
pstmt.setTimestamp(9, new Timestamp(now));
|
||||||
|
pstmt.setString(11, special_character_str_5);
|
||||||
|
|
||||||
|
int ret = pstmt.executeUpdate();
|
||||||
|
Assert.assertEquals(2, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
String query = "select * from ?.t? where ? < ? and ts >= ? and f1 is not null";
|
||||||
|
try (PreparedStatement pstmt = conn.prepareStatement(query)) {
|
||||||
|
pstmt.setString(1, dbName);
|
||||||
|
pstmt.setInt(2, 1);
|
||||||
|
pstmt.setString(3, "ts");
|
||||||
|
pstmt.setTimestamp(4, new Timestamp(System.currentTimeMillis()));
|
||||||
|
pstmt.setTimestamp(5, new Timestamp(0));
|
||||||
|
|
||||||
|
ResultSet rs = pstmt.executeQuery();
|
||||||
|
Assert.assertNotNull(rs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase10() throws SQLException {
|
public void testCase10() throws SQLException {
|
||||||
final long now = System.currentTimeMillis();
|
final long now = System.currentTimeMillis();
|
||||||
|
@ -293,13 +328,12 @@ public class InsertSpecialCharacterJniTest {
|
||||||
Assert.assertEquals(2, ret);
|
Assert.assertEquals(2, ret);
|
||||||
}
|
}
|
||||||
//query t1
|
//query t1
|
||||||
String query = "select * from ?.t? where ts < ? and ts >= ? and ? is not null";
|
String query = "select * from ?.t? where ts < ? and ts >= ? and f1 is not null";
|
||||||
try (PreparedStatement pstmt = conn.prepareStatement(query)) {
|
try (PreparedStatement pstmt = conn.prepareStatement(query)) {
|
||||||
pstmt.setString(1, dbName);
|
pstmt.setString(1, dbName);
|
||||||
pstmt.setInt(2, 1);
|
pstmt.setInt(2, 1);
|
||||||
pstmt.setTimestamp(3, new Timestamp(System.currentTimeMillis()));
|
pstmt.setTimestamp(3, new Timestamp(System.currentTimeMillis()));
|
||||||
pstmt.setTimestamp(4, new Timestamp(0));
|
pstmt.setTimestamp(4, new Timestamp(0));
|
||||||
pstmt.setString(5, "f1");
|
|
||||||
|
|
||||||
ResultSet rs = pstmt.executeQuery();
|
ResultSet rs = pstmt.executeQuery();
|
||||||
rs.next();
|
rs.next();
|
||||||
|
@ -311,12 +345,11 @@ public class InsertSpecialCharacterJniTest {
|
||||||
Assert.assertNull(f2);
|
Assert.assertNull(f2);
|
||||||
}
|
}
|
||||||
// query t2
|
// query t2
|
||||||
query = "select * from t? where ts < ? and ts >= ? and ? is not null";
|
query = "select * from t? where ts < ? and ts >= ? and f2 is not null";
|
||||||
try (PreparedStatement pstmt = conn.prepareStatement(query)) {
|
try (PreparedStatement pstmt = conn.prepareStatement(query)) {
|
||||||
pstmt.setInt(1, 2);
|
pstmt.setInt(1, 2);
|
||||||
pstmt.setTimestamp(2, new Timestamp(System.currentTimeMillis()));
|
pstmt.setTimestamp(2, new Timestamp(System.currentTimeMillis()));
|
||||||
pstmt.setTimestamp(3, new Timestamp(0));
|
pstmt.setTimestamp(3, new Timestamp(0));
|
||||||
pstmt.setString(4, "f2");
|
|
||||||
|
|
||||||
ResultSet rs = pstmt.executeQuery();
|
ResultSet rs = pstmt.executeQuery();
|
||||||
rs.next();
|
rs.next();
|
||||||
|
|
|
@ -293,13 +293,12 @@ public class InsertSpecialCharacterRestfulTest {
|
||||||
Assert.assertEquals(2, ret);
|
Assert.assertEquals(2, ret);
|
||||||
}
|
}
|
||||||
//query t1
|
//query t1
|
||||||
String query = "select * from ?.t? where ts < ? and ts >= ? and ? is not null";
|
String query = "select * from ?.t? where ts < ? and ts >= ? and f1 is not null";
|
||||||
try (PreparedStatement pstmt = conn.prepareStatement(query)) {
|
try (PreparedStatement pstmt = conn.prepareStatement(query)) {
|
||||||
pstmt.setString(1, dbName);
|
pstmt.setString(1, dbName);
|
||||||
pstmt.setInt(2, 1);
|
pstmt.setInt(2, 1);
|
||||||
pstmt.setTimestamp(3, new Timestamp(System.currentTimeMillis()));
|
pstmt.setTimestamp(3, new Timestamp(System.currentTimeMillis()));
|
||||||
pstmt.setTimestamp(4, new Timestamp(0));
|
pstmt.setTimestamp(4, new Timestamp(0));
|
||||||
pstmt.setString(5, "f1");
|
|
||||||
|
|
||||||
ResultSet rs = pstmt.executeQuery();
|
ResultSet rs = pstmt.executeQuery();
|
||||||
rs.next();
|
rs.next();
|
||||||
|
@ -311,12 +310,11 @@ public class InsertSpecialCharacterRestfulTest {
|
||||||
Assert.assertNull(f2);
|
Assert.assertNull(f2);
|
||||||
}
|
}
|
||||||
// query t2
|
// query t2
|
||||||
query = "select * from t? where ts < ? and ts >= ? and ? is not null";
|
query = "select * from t? where ts < ? and ts >= ? and f2 is not null";
|
||||||
try (PreparedStatement pstmt = conn.prepareStatement(query)) {
|
try (PreparedStatement pstmt = conn.prepareStatement(query)) {
|
||||||
pstmt.setInt(1, 2);
|
pstmt.setInt(1, 2);
|
||||||
pstmt.setTimestamp(2, new Timestamp(System.currentTimeMillis()));
|
pstmt.setTimestamp(2, new Timestamp(System.currentTimeMillis()));
|
||||||
pstmt.setTimestamp(3, new Timestamp(0));
|
pstmt.setTimestamp(3, new Timestamp(0));
|
||||||
pstmt.setString(4, "f2");
|
|
||||||
|
|
||||||
ResultSet rs = pstmt.executeQuery();
|
ResultSet rs = pstmt.executeQuery();
|
||||||
rs.next();
|
rs.next();
|
||||||
|
|
|
@ -22,6 +22,8 @@ public class QueryDataTest {
|
||||||
public void createDatabase() {
|
public void createDatabase() {
|
||||||
try {
|
try {
|
||||||
Properties properties = new Properties();
|
Properties properties = new Properties();
|
||||||
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_USER, "root");
|
||||||
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_PASSWORD, "taosdata");
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
||||||
|
|
|
@ -1,51 +1,49 @@
|
||||||
package com.taosdata.jdbc.cases;
|
package com.taosdata.jdbc.cases;
|
||||||
|
|
||||||
import com.taosdata.jdbc.TSDBDriver;
|
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.sql.*;
|
import java.sql.Connection;
|
||||||
import java.util.Properties;
|
import java.sql.DriverManager;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
|
||||||
public class ResetQueryCacheTest {
|
public class ResetQueryCacheTest {
|
||||||
|
|
||||||
static Connection connection;
|
@Test
|
||||||
static Statement statement;
|
public void jni() throws SQLException {
|
||||||
static String host = "127.0.0.1";
|
// given
|
||||||
|
Connection connection = DriverManager.getConnection("jdbc:TAOS://127.0.0.1:0/?user=root&password=taosdata&timezone=UTC-8&charset=UTF-8&locale=en_US.UTF-8");
|
||||||
|
Statement statement = connection.createStatement();
|
||||||
|
|
||||||
@Before
|
// when
|
||||||
public void init() {
|
boolean execute = statement.execute("reset query cache");
|
||||||
try {
|
|
||||||
Properties properties = new Properties();
|
// then
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
assertFalse(execute);
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
assertEquals(0, statement.getUpdateCount());
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
|
||||||
connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":0/", properties);
|
statement.close();
|
||||||
statement = connection.createStatement();
|
connection.close();
|
||||||
} catch (SQLException e) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testResetQueryCache() throws SQLException {
|
public void restful() throws SQLException {
|
||||||
String resetSql = "reset query cache";
|
// given
|
||||||
statement.execute(resetSql);
|
Connection connection = DriverManager.getConnection("jdbc:TAOS-RS://127.0.0.1:6041/?user=root&password=taosdata&timezone=UTC-8&charset=UTF-8&locale=en_US.UTF-8");
|
||||||
}
|
Statement statement = connection.createStatement();
|
||||||
|
|
||||||
|
// when
|
||||||
|
boolean execute = statement.execute("reset query cache");
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertFalse(execute);
|
||||||
|
assertEquals(0, statement.getUpdateCount());
|
||||||
|
|
||||||
@After
|
|
||||||
public void close() {
|
|
||||||
try {
|
|
||||||
if (statement != null)
|
|
||||||
statement.close();
|
statement.close();
|
||||||
if (connection != null)
|
|
||||||
connection.close();
|
connection.close();
|
||||||
} catch (SQLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -20,6 +20,8 @@ public class SelectTest {
|
||||||
public void createDatabaseAndTable() {
|
public void createDatabaseAndTable() {
|
||||||
try {
|
try {
|
||||||
Properties properties = new Properties();
|
Properties properties = new Properties();
|
||||||
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_USER, "root");
|
||||||
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_PASSWORD, "taosdata");
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
||||||
|
|
|
@ -24,6 +24,8 @@ public class StableTest {
|
||||||
public static void createDatabase() {
|
public static void createDatabase() {
|
||||||
try {
|
try {
|
||||||
Properties properties = new Properties();
|
Properties properties = new Properties();
|
||||||
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_USER, "root");
|
||||||
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_PASSWORD, "taosdata");
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
package com.taosdata.jdbc.utils;
|
|
||||||
|
|
||||||
import org.junit.Assert;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
public class SqlSyntaxValidatorTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void isSelectSQL() {
|
|
||||||
Assert.assertTrue(SqlSyntaxValidator.isSelectSql("select * from test.weather"));
|
|
||||||
Assert.assertTrue(SqlSyntaxValidator.isSelectSql(" select * from test.weather"));
|
|
||||||
Assert.assertTrue(SqlSyntaxValidator.isSelectSql(" select * from test.weather "));
|
|
||||||
Assert.assertFalse(SqlSyntaxValidator.isSelectSql("insert into test.weather values(now, 1.1, 2)"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void isUseSQL() {
|
|
||||||
Assert.assertTrue(SqlSyntaxValidator.isUseSql("use database test"));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -42,6 +42,8 @@ int32_t main(int32_t argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
} else if (strcmp(argv[i], "-C") == 0) {
|
} else if (strcmp(argv[i], "-C") == 0) {
|
||||||
dump_config = 1;
|
dump_config = 1;
|
||||||
|
} else if (strcmp(argv[i], "--force-keep-file") == 0) {
|
||||||
|
tsdbForceKeepFile = true;
|
||||||
} else if (strcmp(argv[i], "--compact-mnode-wal") == 0) {
|
} else if (strcmp(argv[i], "--compact-mnode-wal") == 0) {
|
||||||
tsCompactMnodeWal = 1;
|
tsCompactMnodeWal = 1;
|
||||||
} else if (strcmp(argv[i], "-V") == 0) {
|
} else if (strcmp(argv[i], "-V") == 0) {
|
||||||
|
|
|
@ -246,7 +246,6 @@ typedef struct SArguments_S {
|
||||||
uint32_t disorderRatio; // 0: no disorder, >0: x%
|
uint32_t disorderRatio; // 0: no disorder, >0: x%
|
||||||
int disorderRange; // ms, us or ns. accordig to database precision
|
int disorderRange; // ms, us or ns. accordig to database precision
|
||||||
uint32_t method_of_delete;
|
uint32_t method_of_delete;
|
||||||
char ** arg_list;
|
|
||||||
uint64_t totalInsertRows;
|
uint64_t totalInsertRows;
|
||||||
uint64_t totalAffectedRows;
|
uint64_t totalAffectedRows;
|
||||||
bool demo_mode; // use default column name and semi-random data
|
bool demo_mode; // use default column name and semi-random data
|
||||||
|
@ -638,7 +637,6 @@ SArguments g_args = {
|
||||||
0, // disorderRatio
|
0, // disorderRatio
|
||||||
1000, // disorderRange
|
1000, // disorderRange
|
||||||
1, // method_of_delete
|
1, // method_of_delete
|
||||||
NULL, // arg_list
|
|
||||||
0, // totalInsertRows;
|
0, // totalInsertRows;
|
||||||
0, // totalAffectedRows;
|
0, // totalAffectedRows;
|
||||||
true, // demo_mode;
|
true, // demo_mode;
|
||||||
|
@ -1010,6 +1008,7 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) {
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
arguments->datatype[0] = argv[i];
|
arguments->datatype[0] = argv[i];
|
||||||
|
arguments->datatype[1] = NULL;
|
||||||
} else {
|
} else {
|
||||||
// more than one col
|
// more than one col
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
@ -6401,6 +6400,9 @@ static void* syncWriteInterlace(threadInfo *pThreadInfo) {
|
||||||
bool flagSleep = true;
|
bool flagSleep = true;
|
||||||
uint64_t sleepTimeTotal = 0;
|
uint64_t sleepTimeTotal = 0;
|
||||||
|
|
||||||
|
int percentComplete = 0;
|
||||||
|
int64_t totalRows = insertRows * pThreadInfo->ntables;
|
||||||
|
|
||||||
while(pThreadInfo->totalInsertRows < pThreadInfo->ntables * insertRows) {
|
while(pThreadInfo->totalInsertRows < pThreadInfo->ntables * insertRows) {
|
||||||
if ((flagSleep) && (insert_interval)) {
|
if ((flagSleep) && (insert_interval)) {
|
||||||
st = taosGetTimestampMs();
|
st = taosGetTimestampMs();
|
||||||
|
@ -6577,6 +6579,11 @@ static void* syncWriteInterlace(threadInfo *pThreadInfo) {
|
||||||
|
|
||||||
pThreadInfo->totalAffectedRows += affectedRows;
|
pThreadInfo->totalAffectedRows += affectedRows;
|
||||||
|
|
||||||
|
int currentPercent = pThreadInfo->totalAffectedRows * 100 / totalRows;
|
||||||
|
if (currentPercent > percentComplete ) {
|
||||||
|
printf("[%d]:%d%%\n", pThreadInfo->threadID, currentPercent);
|
||||||
|
percentComplete = currentPercent;
|
||||||
|
}
|
||||||
int64_t currentPrintTime = taosGetTimestampMs();
|
int64_t currentPrintTime = taosGetTimestampMs();
|
||||||
if (currentPrintTime - lastPrintTime > 30*1000) {
|
if (currentPrintTime - lastPrintTime > 30*1000) {
|
||||||
printf("thread[%d] has currently inserted rows: %"PRIu64 ", affected rows: %"PRIu64 "\n",
|
printf("thread[%d] has currently inserted rows: %"PRIu64 ", affected rows: %"PRIu64 "\n",
|
||||||
|
@ -6598,6 +6605,8 @@ static void* syncWriteInterlace(threadInfo *pThreadInfo) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (percentComplete < 100)
|
||||||
|
printf("[%d]:%d%%\n", pThreadInfo->threadID, percentComplete);
|
||||||
|
|
||||||
free_of_interlace:
|
free_of_interlace:
|
||||||
tmfree(pThreadInfo->buffer);
|
tmfree(pThreadInfo->buffer);
|
||||||
|
@ -6635,6 +6644,9 @@ static void* syncWriteProgressive(threadInfo *pThreadInfo) {
|
||||||
|
|
||||||
pThreadInfo->samplePos = 0;
|
pThreadInfo->samplePos = 0;
|
||||||
|
|
||||||
|
int percentComplete = 0;
|
||||||
|
int64_t totalRows = insertRows * pThreadInfo->ntables;
|
||||||
|
|
||||||
for (uint64_t tableSeq = pThreadInfo->start_table_from;
|
for (uint64_t tableSeq = pThreadInfo->start_table_from;
|
||||||
tableSeq <= pThreadInfo->end_table_to;
|
tableSeq <= pThreadInfo->end_table_to;
|
||||||
tableSeq ++) {
|
tableSeq ++) {
|
||||||
|
@ -6740,6 +6752,11 @@ static void* syncWriteProgressive(threadInfo *pThreadInfo) {
|
||||||
|
|
||||||
pThreadInfo->totalAffectedRows += affectedRows;
|
pThreadInfo->totalAffectedRows += affectedRows;
|
||||||
|
|
||||||
|
int currentPercent = pThreadInfo->totalAffectedRows * 100 / totalRows;
|
||||||
|
if (currentPercent > percentComplete ) {
|
||||||
|
printf("[%d]:%d%%\n", pThreadInfo->threadID, currentPercent);
|
||||||
|
percentComplete = currentPercent;
|
||||||
|
}
|
||||||
int64_t currentPrintTime = taosGetTimestampMs();
|
int64_t currentPrintTime = taosGetTimestampMs();
|
||||||
if (currentPrintTime - lastPrintTime > 30*1000) {
|
if (currentPrintTime - lastPrintTime > 30*1000) {
|
||||||
printf("thread[%d] has currently inserted rows: %"PRId64 ", affected rows: %"PRId64 "\n",
|
printf("thread[%d] has currently inserted rows: %"PRId64 ", affected rows: %"PRId64 "\n",
|
||||||
|
@ -6762,6 +6779,8 @@ static void* syncWriteProgressive(threadInfo *pThreadInfo) {
|
||||||
__func__, __LINE__, pThreadInfo->samplePos);
|
__func__, __LINE__, pThreadInfo->samplePos);
|
||||||
}
|
}
|
||||||
} // tableSeq
|
} // tableSeq
|
||||||
|
if (percentComplete < 100)
|
||||||
|
printf("[%d]:%d%%\n", pThreadInfo->threadID, percentComplete);
|
||||||
|
|
||||||
free_of_progressive:
|
free_of_progressive:
|
||||||
tmfree(pThreadInfo->buffer);
|
tmfree(pThreadInfo->buffer);
|
||||||
|
|
|
@ -39,7 +39,6 @@
|
||||||
#define GET_QID(_r) (((SQInfo*)((_r)->qinfo))->qId)
|
#define GET_QID(_r) (((SQInfo*)((_r)->qinfo))->qId)
|
||||||
|
|
||||||
#define curTimeWindowIndex(_winres) ((_winres)->curIndex)
|
#define curTimeWindowIndex(_winres) ((_winres)->curIndex)
|
||||||
#define GET_ROW_PARAM_FOR_MULTIOUTPUT(_q, tbq, sq) (((tbq) && (!(sq)))? (_q)->pExpr1[1].base.param[0].i64:1)
|
|
||||||
|
|
||||||
int32_t getOutputInterResultBufSize(SQueryAttr* pQueryAttr);
|
int32_t getOutputInterResultBufSize(SQueryAttr* pQueryAttr);
|
||||||
|
|
||||||
|
@ -60,6 +59,7 @@ SResultRowCellInfo* getResultCell(const SResultRow* pRow, int32_t index, int32_t
|
||||||
|
|
||||||
void* destroyQueryFuncExpr(SExprInfo* pExprInfo, int32_t numOfExpr);
|
void* destroyQueryFuncExpr(SExprInfo* pExprInfo, int32_t numOfExpr);
|
||||||
void* freeColumnInfo(SColumnInfo* pColumnInfo, int32_t numOfCols);
|
void* freeColumnInfo(SColumnInfo* pColumnInfo, int32_t numOfCols);
|
||||||
|
int32_t getRowNumForMultioutput(SQueryAttr* pQueryAttr, bool topBottomQuery, bool stable);
|
||||||
|
|
||||||
static FORCE_INLINE SResultRow *getResultRow(SResultRowInfo *pResultRowInfo, int32_t slot) {
|
static FORCE_INLINE SResultRow *getResultRow(SResultRowInfo *pResultRowInfo, int32_t slot) {
|
||||||
assert(pResultRowInfo != NULL && slot >= 0 && slot < pResultRowInfo->size);
|
assert(pResultRowInfo != NULL && slot >= 0 && slot < pResultRowInfo->size);
|
||||||
|
@ -70,7 +70,7 @@ static FORCE_INLINE char* getPosInResultPage(SQueryAttr* pQueryAttr, tFilePage*
|
||||||
int32_t offset) {
|
int32_t offset) {
|
||||||
assert(rowOffset >= 0 && pQueryAttr != NULL);
|
assert(rowOffset >= 0 && pQueryAttr != NULL);
|
||||||
|
|
||||||
int32_t numOfRows = (int32_t)GET_ROW_PARAM_FOR_MULTIOUTPUT(pQueryAttr, pQueryAttr->topBotQuery, pQueryAttr->stableQuery);
|
int32_t numOfRows = (int32_t)getRowNumForMultioutput(pQueryAttr, pQueryAttr->topBotQuery, pQueryAttr->stableQuery);
|
||||||
return ((char *)page->data) + rowOffset + offset * numOfRows;
|
return ((char *)page->data) + rowOffset + offset * numOfRows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2706,7 +2706,7 @@ static void getIntermediateBufInfo(SQueryRuntimeEnv* pRuntimeEnv, int32_t* ps, i
|
||||||
SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr;
|
SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr;
|
||||||
int32_t MIN_ROWS_PER_PAGE = 4;
|
int32_t MIN_ROWS_PER_PAGE = 4;
|
||||||
|
|
||||||
*rowsize = (int32_t)(pQueryAttr->resultRowSize * GET_ROW_PARAM_FOR_MULTIOUTPUT(pQueryAttr, pQueryAttr->topBotQuery, pQueryAttr->stableQuery));
|
*rowsize = (int32_t)(pQueryAttr->resultRowSize * getRowNumForMultioutput(pQueryAttr, pQueryAttr->topBotQuery, pQueryAttr->stableQuery));
|
||||||
int32_t overhead = sizeof(tFilePage);
|
int32_t overhead = sizeof(tFilePage);
|
||||||
|
|
||||||
// one page contains at least two rows
|
// one page contains at least two rows
|
||||||
|
@ -3630,7 +3630,7 @@ void updateOutputBuf(SOptrBasicInfo* pBInfo, int32_t *bufCapacity, int32_t numOf
|
||||||
// re-estabilish output buffer pointer.
|
// re-estabilish output buffer pointer.
|
||||||
int32_t functionId = pBInfo->pCtx[i].functionId;
|
int32_t functionId = pBInfo->pCtx[i].functionId;
|
||||||
if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM || functionId == TSDB_FUNC_DIFF || functionId == TSDB_FUNC_DERIVATIVE) {
|
if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM || functionId == TSDB_FUNC_DIFF || functionId == TSDB_FUNC_DERIVATIVE) {
|
||||||
pBInfo->pCtx[i].ptsOutputBuf = pBInfo->pCtx[0].pOutput;
|
pBInfo->pCtx[i].ptsOutputBuf = pBInfo->pCtx[i-1].pOutput;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5298,7 +5298,7 @@ SOperatorInfo* createGlobalAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv,
|
||||||
SMultiwayMergeInfo* pInfo = calloc(1, sizeof(SMultiwayMergeInfo));
|
SMultiwayMergeInfo* pInfo = calloc(1, sizeof(SMultiwayMergeInfo));
|
||||||
|
|
||||||
pInfo->resultRowFactor =
|
pInfo->resultRowFactor =
|
||||||
(int32_t)(GET_ROW_PARAM_FOR_MULTIOUTPUT(pRuntimeEnv->pQueryAttr, pRuntimeEnv->pQueryAttr->topBotQuery, false));
|
(int32_t)(getRowNumForMultioutput(pRuntimeEnv->pQueryAttr, pRuntimeEnv->pQueryAttr->topBotQuery, false));
|
||||||
|
|
||||||
pRuntimeEnv->scanFlag = MERGE_STAGE; // TODO init when creating pCtx
|
pRuntimeEnv->scanFlag = MERGE_STAGE; // TODO init when creating pCtx
|
||||||
|
|
||||||
|
@ -6327,7 +6327,7 @@ SOperatorInfo* createAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOpera
|
||||||
SAggOperatorInfo* pInfo = calloc(1, sizeof(SAggOperatorInfo));
|
SAggOperatorInfo* pInfo = calloc(1, sizeof(SAggOperatorInfo));
|
||||||
|
|
||||||
SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr;
|
SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr;
|
||||||
int32_t numOfRows = (int32_t)(GET_ROW_PARAM_FOR_MULTIOUTPUT(pQueryAttr, pQueryAttr->topBotQuery, pQueryAttr->stableQuery));
|
int32_t numOfRows = (int32_t)(getRowNumForMultioutput(pQueryAttr, pQueryAttr->topBotQuery, pQueryAttr->stableQuery));
|
||||||
|
|
||||||
pInfo->binfo.pRes = createOutputBuf(pExpr, numOfOutput, numOfRows);
|
pInfo->binfo.pRes = createOutputBuf(pExpr, numOfOutput, numOfRows);
|
||||||
pInfo->binfo.pCtx = createSQLFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pInfo->binfo.rowCellInfoOffset);
|
pInfo->binfo.pCtx = createSQLFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pInfo->binfo.rowCellInfoOffset);
|
||||||
|
@ -6701,7 +6701,7 @@ SOperatorInfo* createGroupbyOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperato
|
||||||
SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr;
|
SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr;
|
||||||
|
|
||||||
pQueryAttr->resultRowSize = (pQueryAttr->resultRowSize *
|
pQueryAttr->resultRowSize = (pQueryAttr->resultRowSize *
|
||||||
(int32_t)(GET_ROW_PARAM_FOR_MULTIOUTPUT(pQueryAttr, pQueryAttr->topBotQuery, pQueryAttr->stableQuery)));
|
(int32_t)(getRowNumForMultioutput(pQueryAttr, pQueryAttr->topBotQuery, pQueryAttr->stableQuery)));
|
||||||
|
|
||||||
pInfo->binfo.pRes = createOutputBuf(pExpr, numOfOutput, pRuntimeEnv->resultInfo.capacity);
|
pInfo->binfo.pRes = createOutputBuf(pExpr, numOfOutput, pRuntimeEnv->resultInfo.capacity);
|
||||||
initResultRowInfo(&pInfo->binfo.resultRowInfo, 8, TSDB_DATA_TYPE_INT);
|
initResultRowInfo(&pInfo->binfo.resultRowInfo, 8, TSDB_DATA_TYPE_INT);
|
||||||
|
|
|
@ -206,6 +206,12 @@ static int32_t fillResultImpl(SFillInfo* pFillInfo, void** data, int32_t outputR
|
||||||
} else {
|
} else {
|
||||||
assert(pFillInfo->currentKey == ts);
|
assert(pFillInfo->currentKey == ts);
|
||||||
initBeforeAfterDataBuf(pFillInfo, prev);
|
initBeforeAfterDataBuf(pFillInfo, prev);
|
||||||
|
if (pFillInfo->type == TSDB_FILL_NEXT && (pFillInfo->index + 1) < pFillInfo->numOfRows) {
|
||||||
|
initBeforeAfterDataBuf(pFillInfo, next);
|
||||||
|
++pFillInfo->index;
|
||||||
|
copyCurrentRowIntoBuf(pFillInfo, srcData, *next);
|
||||||
|
--pFillInfo->index;
|
||||||
|
}
|
||||||
|
|
||||||
// assign rows to dst buffer
|
// assign rows to dst buffer
|
||||||
for (int32_t i = 0; i < pFillInfo->numOfCols; ++i) {
|
for (int32_t i = 0; i < pFillInfo->numOfCols; ++i) {
|
||||||
|
@ -227,6 +233,12 @@ static int32_t fillResultImpl(SFillInfo* pFillInfo, void** data, int32_t outputR
|
||||||
} else if (pFillInfo->type == TSDB_FILL_LINEAR) {
|
} else if (pFillInfo->type == TSDB_FILL_LINEAR) {
|
||||||
assignVal(output, src, pCol->col.bytes, pCol->col.type);
|
assignVal(output, src, pCol->col.bytes, pCol->col.type);
|
||||||
memcpy(*prev + pCol->col.offset, src, pCol->col.bytes);
|
memcpy(*prev + pCol->col.offset, src, pCol->col.bytes);
|
||||||
|
} else if (pFillInfo->type == TSDB_FILL_NEXT) {
|
||||||
|
if (*next) {
|
||||||
|
assignVal(output, *next + pCol->col.offset, pCol->col.bytes, pCol->col.type);
|
||||||
|
} else {
|
||||||
|
setNull(output, pCol->col.type, pCol->col.bytes);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
assignVal(output, (char*)&pCol->fillVal.i, pCol->col.bytes, pCol->col.type);
|
assignVal(output, (char*)&pCol->fillVal.i, pCol->col.bytes, pCol->col.type);
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,18 @@ typedef struct SCompSupporter {
|
||||||
int32_t order;
|
int32_t order;
|
||||||
} SCompSupporter;
|
} SCompSupporter;
|
||||||
|
|
||||||
|
int32_t getRowNumForMultioutput(SQueryAttr* pQueryAttr, bool topBottomQuery, bool stable) {
|
||||||
|
if (pQueryAttr && (!stable)) {
|
||||||
|
for (int16_t i = 0; i < pQueryAttr->numOfOutput; ++i) {
|
||||||
|
if (pQueryAttr->pExpr1[i].base.functionId == TSDB_FUNC_TOP || pQueryAttr->pExpr1[i].base.functionId == TSDB_FUNC_BOTTOM) {
|
||||||
|
return (int32_t)pQueryAttr->pExpr1[i].base.param[0].i64;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t getOutputInterResultBufSize(SQueryAttr* pQueryAttr) {
|
int32_t getOutputInterResultBufSize(SQueryAttr* pQueryAttr) {
|
||||||
int32_t size = 0;
|
int32_t size = 0;
|
||||||
|
|
||||||
|
|
|
@ -397,7 +397,11 @@ void *taosOpenTcpClientConnection(void *shandle, void *thandle, uint32_t ip, uin
|
||||||
SThreadObj *pThreadObj = pClientObj->pThreadObj[index];
|
SThreadObj *pThreadObj = pClientObj->pThreadObj[index];
|
||||||
|
|
||||||
SOCKET fd = taosOpenTcpClientSocket(ip, port, pThreadObj->ip);
|
SOCKET fd = taosOpenTcpClientSocket(ip, port, pThreadObj->ip);
|
||||||
|
#if defined(_TD_WINDOWS_64) || defined(_TD_WINDOWS_32)
|
||||||
|
if (fd == (SOCKET)-1) return NULL;
|
||||||
|
#else
|
||||||
if (fd <= 0) return NULL;
|
if (fd <= 0) return NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
struct sockaddr_in sin;
|
struct sockaddr_in sin;
|
||||||
uint16_t localPort = 0;
|
uint16_t localPort = 0;
|
||||||
|
|
|
@ -722,7 +722,7 @@ static int tsdbInitCommitH(SCommitH *pCommith, STsdbRepo *pRepo) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pCommith->pDataCols = tdNewDataCols(0, 0, pCfg->maxRowsPerFileBlock);
|
pCommith->pDataCols = tdNewDataCols(0, pCfg->maxRowsPerFileBlock);
|
||||||
if (pCommith->pDataCols == NULL) {
|
if (pCommith->pDataCols == NULL) {
|
||||||
terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
|
terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
|
||||||
tsdbDestroyCommitH(pCommith);
|
tsdbDestroyCommitH(pCommith);
|
||||||
|
@ -920,7 +920,6 @@ int tsdbWriteBlockImpl(STsdbRepo *pRepo, STable *pTable, SDFile *pDFile, SDataCo
|
||||||
SDataCol * pDataCol = pDataCols->cols + ncol;
|
SDataCol * pDataCol = pDataCols->cols + ncol;
|
||||||
SBlockCol *pBlockCol = pBlockData->cols + nColsNotAllNull;
|
SBlockCol *pBlockCol = pBlockData->cols + nColsNotAllNull;
|
||||||
|
|
||||||
// if (isNEleNull(pDataCol, rowsToWrite)) { // all data to commit are NULL, just ignore it
|
|
||||||
if (isAllRowsNull(pDataCol)) { // all data to commit are NULL, just ignore it
|
if (isAllRowsNull(pDataCol)) { // all data to commit are NULL, just ignore it
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1277,6 +1276,7 @@ static void tsdbLoadAndMergeFromCache(SDataCols *pDataCols, int *iter, SCommitIt
|
||||||
|
|
||||||
if (key1 < key2) {
|
if (key1 < key2) {
|
||||||
for (int i = 0; i < pDataCols->numOfCols; i++) {
|
for (int i = 0; i < pDataCols->numOfCols; i++) {
|
||||||
|
//TODO: dataColAppendVal may fail
|
||||||
dataColAppendVal(pTarget->cols + i, tdGetColDataOfRow(pDataCols->cols + i, *iter), pTarget->numOfRows,
|
dataColAppendVal(pTarget->cols + i, tdGetColDataOfRow(pDataCols->cols + i, *iter), pTarget->numOfRows,
|
||||||
pTarget->maxPoints);
|
pTarget->maxPoints);
|
||||||
}
|
}
|
||||||
|
@ -1308,6 +1308,7 @@ static void tsdbLoadAndMergeFromCache(SDataCols *pDataCols, int *iter, SCommitIt
|
||||||
ASSERT(!isRowDel);
|
ASSERT(!isRowDel);
|
||||||
|
|
||||||
for (int i = 0; i < pDataCols->numOfCols; i++) {
|
for (int i = 0; i < pDataCols->numOfCols; i++) {
|
||||||
|
//TODO: dataColAppendVal may fail
|
||||||
dataColAppendVal(pTarget->cols + i, tdGetColDataOfRow(pDataCols->cols + i, *iter), pTarget->numOfRows,
|
dataColAppendVal(pTarget->cols + i, tdGetColDataOfRow(pDataCols->cols + i, *iter), pTarget->numOfRows,
|
||||||
pTarget->maxPoints);
|
pTarget->maxPoints);
|
||||||
}
|
}
|
||||||
|
|
|
@ -296,7 +296,7 @@ static int tsdbCompactMeta(STsdbRepo *pRepo) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pComph->pDataCols = tdNewDataCols(0, 0, pCfg->maxRowsPerFileBlock);
|
pComph->pDataCols = tdNewDataCols(0, pCfg->maxRowsPerFileBlock);
|
||||||
if (pComph->pDataCols == NULL) {
|
if (pComph->pDataCols == NULL) {
|
||||||
terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
|
terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
|
||||||
tsdbDestroyCompactH(pComph);
|
tsdbDestroyCompactH(pComph);
|
||||||
|
|
|
@ -37,6 +37,8 @@ static void tsdbScanAndTryFixDFilesHeader(STsdbRepo *pRepo, int32_t *nExpired);
|
||||||
static int tsdbProcessExpiredFS(STsdbRepo *pRepo);
|
static int tsdbProcessExpiredFS(STsdbRepo *pRepo);
|
||||||
static int tsdbCreateMeta(STsdbRepo *pRepo);
|
static int tsdbCreateMeta(STsdbRepo *pRepo);
|
||||||
|
|
||||||
|
// For backward compatibility
|
||||||
|
bool tsdbForceKeepFile = false;
|
||||||
// ================== CURRENT file header info
|
// ================== CURRENT file header info
|
||||||
static int tsdbEncodeFSHeader(void **buf, SFSHeader *pHeader) {
|
static int tsdbEncodeFSHeader(void **buf, SFSHeader *pHeader) {
|
||||||
int tlen = 0;
|
int tlen = 0;
|
||||||
|
@ -1048,6 +1050,26 @@ static int tsdbRestoreMeta(STsdbRepo *pRepo) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tsdbForceKeepFile) {
|
||||||
|
struct stat tfstat;
|
||||||
|
|
||||||
|
// Get real file size
|
||||||
|
if (fstat(pfs->cstatus->pmf->fd, &tfstat) < 0) {
|
||||||
|
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||||
|
tsdbCloseMFile(pfs->cstatus->pmf);
|
||||||
|
tfsClosedir(tdir);
|
||||||
|
regfree(®ex);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pfs->cstatus->pmf->info.size != tfstat.st_size) {
|
||||||
|
int64_t tfsize = pfs->cstatus->pmf->info.size;
|
||||||
|
pfs->cstatus->pmf->info.size = tfstat.st_size;
|
||||||
|
tsdbInfo("vgId:%d file %s header size is changed from %" PRId64 " to %" PRId64, REPO_ID(pRepo),
|
||||||
|
TSDB_FILE_FULL_NAME(pfs->cstatus->pmf), tfsize, pfs->cstatus->pmf->info.size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
tsdbCloseMFile(pfs->cstatus->pmf);
|
tsdbCloseMFile(pfs->cstatus->pmf);
|
||||||
}
|
}
|
||||||
} else if (code == REG_NOMATCH) {
|
} else if (code == REG_NOMATCH) {
|
||||||
|
@ -1212,6 +1234,24 @@ static int tsdbRestoreDFileSet(STsdbRepo *pRepo) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tsdbForceKeepFile) {
|
||||||
|
struct stat tfstat;
|
||||||
|
|
||||||
|
// Get real file size
|
||||||
|
if (fstat(pDFile->fd, &tfstat) < 0) {
|
||||||
|
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||||
|
taosArrayDestroy(fArray);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pDFile->info.size != tfstat.st_size) {
|
||||||
|
int64_t tfsize = pDFile->info.size;
|
||||||
|
pDFile->info.size = tfstat.st_size;
|
||||||
|
tsdbInfo("vgId:%d file %s header size is changed from %" PRId64 " to %" PRId64, REPO_ID(pRepo),
|
||||||
|
TSDB_FILE_FULL_NAME(pDFile), tfsize, pDFile->info.size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
tsdbCloseDFile(pDFile);
|
tsdbCloseDFile(pDFile);
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -702,11 +702,12 @@ static int tsdbScanAndConvertSubmitMsg(STsdbRepo *pRepo, SSubmitMsg *pMsg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
//row1 has higher priority
|
//row1 has higher priority
|
||||||
static SMemRow tsdbInsertDupKeyMerge(SMemRow row1, SMemRow row2, STsdbRepo* pRepo, STSchema **ppSchema1, STSchema **ppSchema2, STable* pTable, int32_t* pAffectedRows, int64_t* pPoints, SMemRow* pLastRow) {
|
static SMemRow tsdbInsertDupKeyMerge(SMemRow row1, SMemRow row2, STsdbRepo* pRepo,
|
||||||
|
STSchema **ppSchema1, STSchema **ppSchema2,
|
||||||
|
STable* pTable, int32_t* pPoints, SMemRow* pLastRow) {
|
||||||
|
|
||||||
//for compatiblity, duplicate key inserted when update=0 should be also calculated as affected rows!
|
//for compatiblity, duplicate key inserted when update=0 should be also calculated as affected rows!
|
||||||
if(row1 == NULL && row2 == NULL && pRepo->config.update == TD_ROW_DISCARD_UPDATE) {
|
if(row1 == NULL && row2 == NULL && pRepo->config.update == TD_ROW_DISCARD_UPDATE) {
|
||||||
(*pAffectedRows)++;
|
|
||||||
(*pPoints)++;
|
(*pPoints)++;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -715,7 +716,6 @@ static SMemRow tsdbInsertDupKeyMerge(SMemRow row1, SMemRow row2, STsdbRepo* pRep
|
||||||
void* pMem = tsdbAllocBytes(pRepo, memRowTLen(row1));
|
void* pMem = tsdbAllocBytes(pRepo, memRowTLen(row1));
|
||||||
if(pMem == NULL) return NULL;
|
if(pMem == NULL) return NULL;
|
||||||
memRowCpy(pMem, row1);
|
memRowCpy(pMem, row1);
|
||||||
(*pAffectedRows)++;
|
|
||||||
(*pPoints)++;
|
(*pPoints)++;
|
||||||
*pLastRow = pMem;
|
*pLastRow = pMem;
|
||||||
return pMem;
|
return pMem;
|
||||||
|
@ -750,18 +750,16 @@ static SMemRow tsdbInsertDupKeyMerge(SMemRow row1, SMemRow row2, STsdbRepo* pRep
|
||||||
if(pMem == NULL) return NULL;
|
if(pMem == NULL) return NULL;
|
||||||
memRowCpy(pMem, tmp);
|
memRowCpy(pMem, tmp);
|
||||||
|
|
||||||
(*pAffectedRows)++;
|
|
||||||
(*pPoints)++;
|
(*pPoints)++;
|
||||||
|
|
||||||
*pLastRow = pMem;
|
*pLastRow = pMem;
|
||||||
return pMem;
|
return pMem;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void* tsdbInsertDupKeyMergePacked(void** args) {
|
static void* tsdbInsertDupKeyMergePacked(void** args) {
|
||||||
return tsdbInsertDupKeyMerge(args[0], args[1], args[2], (STSchema**)&args[3], (STSchema**)&args[4], args[5], args[6], args[7], args[8]);
|
return tsdbInsertDupKeyMerge(args[0], args[1], args[2], (STSchema**)&args[3], (STSchema**)&args[4], args[5], args[6], args[7]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tsdbSetupSkipListHookFns(SSkipList* pSkipList, STsdbRepo *pRepo, STable *pTable, int32_t* pAffectedRows, int64_t* pPoints, SMemRow* pLastRow) {
|
static void tsdbSetupSkipListHookFns(SSkipList* pSkipList, STsdbRepo *pRepo, STable *pTable, int32_t* pPoints, SMemRow* pLastRow) {
|
||||||
|
|
||||||
if(pSkipList->insertHandleFn == NULL) {
|
if(pSkipList->insertHandleFn == NULL) {
|
||||||
tGenericSavedFunc *dupHandleSavedFunc = genericSavedFuncInit((GenericVaFunc)&tsdbInsertDupKeyMergePacked, 9);
|
tGenericSavedFunc *dupHandleSavedFunc = genericSavedFuncInit((GenericVaFunc)&tsdbInsertDupKeyMergePacked, 9);
|
||||||
|
@ -769,17 +767,16 @@ static void tsdbSetupSkipListHookFns(SSkipList* pSkipList, STsdbRepo *pRepo, STa
|
||||||
dupHandleSavedFunc->args[3] = NULL;
|
dupHandleSavedFunc->args[3] = NULL;
|
||||||
dupHandleSavedFunc->args[4] = NULL;
|
dupHandleSavedFunc->args[4] = NULL;
|
||||||
dupHandleSavedFunc->args[5] = pTable;
|
dupHandleSavedFunc->args[5] = pTable;
|
||||||
dupHandleSavedFunc->args[6] = pAffectedRows;
|
|
||||||
dupHandleSavedFunc->args[7] = pPoints;
|
|
||||||
dupHandleSavedFunc->args[8] = pLastRow;
|
|
||||||
pSkipList->insertHandleFn = dupHandleSavedFunc;
|
pSkipList->insertHandleFn = dupHandleSavedFunc;
|
||||||
}
|
}
|
||||||
|
pSkipList->insertHandleFn->args[6] = pPoints;
|
||||||
|
pSkipList->insertHandleFn->args[7] = pLastRow;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tsdbInsertDataToTable(STsdbRepo* pRepo, SSubmitBlk* pBlock, int32_t *pAffectedRows) {
|
static int tsdbInsertDataToTable(STsdbRepo* pRepo, SSubmitBlk* pBlock, int32_t *pAffectedRows) {
|
||||||
|
|
||||||
STsdbMeta *pMeta = pRepo->tsdbMeta;
|
STsdbMeta *pMeta = pRepo->tsdbMeta;
|
||||||
int64_t points = 0;
|
int32_t points = 0;
|
||||||
STable *pTable = NULL;
|
STable *pTable = NULL;
|
||||||
SSubmitBlkIter blkIter = {0};
|
SSubmitBlkIter blkIter = {0};
|
||||||
SMemTable *pMemTable = NULL;
|
SMemTable *pMemTable = NULL;
|
||||||
|
@ -830,9 +827,10 @@ static int tsdbInsertDataToTable(STsdbRepo* pRepo, SSubmitBlk* pBlock, int32_t *
|
||||||
|
|
||||||
SMemRow lastRow = NULL;
|
SMemRow lastRow = NULL;
|
||||||
int64_t osize = SL_SIZE(pTableData->pData);
|
int64_t osize = SL_SIZE(pTableData->pData);
|
||||||
tsdbSetupSkipListHookFns(pTableData->pData, pRepo, pTable, pAffectedRows, &points, &lastRow);
|
tsdbSetupSkipListHookFns(pTableData->pData, pRepo, pTable, &points, &lastRow);
|
||||||
tSkipListPutBatchByIter(pTableData->pData, &blkIter, (iter_next_fn_t)tsdbGetSubmitBlkNext);
|
tSkipListPutBatchByIter(pTableData->pData, &blkIter, (iter_next_fn_t)tsdbGetSubmitBlkNext);
|
||||||
int64_t dsize = SL_SIZE(pTableData->pData) - osize;
|
int64_t dsize = SL_SIZE(pTableData->pData) - osize;
|
||||||
|
(*pAffectedRows) += points;
|
||||||
|
|
||||||
|
|
||||||
if(lastRow != NULL) {
|
if(lastRow != NULL) {
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
#define TSDB_SUPER_TABLE_SL_LEVEL 5
|
#define TSDB_SUPER_TABLE_SL_LEVEL 5
|
||||||
#define DEFAULT_TAG_INDEX_COLUMN 0
|
#define DEFAULT_TAG_INDEX_COLUMN 0
|
||||||
|
|
||||||
static int tsdbCompareSchemaVersion(const void *key1, const void *key2);
|
|
||||||
static char * getTagIndexKey(const void *pData);
|
static char * getTagIndexKey(const void *pData);
|
||||||
static STable *tsdbNewTable();
|
static STable *tsdbNewTable();
|
||||||
static STable *tsdbCreateTableFromCfg(STableCfg *pCfg, bool isSuper, STable *pSTable);
|
static STable *tsdbCreateTableFromCfg(STableCfg *pCfg, bool isSuper, STable *pSTable);
|
||||||
|
|
|
@ -466,7 +466,7 @@ static STsdbQueryHandle* tsdbQueryTablesImpl(STsdbRepo* tsdb, STsdbQueryCond* pC
|
||||||
STsdbMeta* pMeta = tsdbGetMeta(tsdb);
|
STsdbMeta* pMeta = tsdbGetMeta(tsdb);
|
||||||
assert(pMeta != NULL);
|
assert(pMeta != NULL);
|
||||||
|
|
||||||
pQueryHandle->pDataCols = tdNewDataCols(pMeta->maxRowBytes, pMeta->maxCols, pQueryHandle->pTsdb->config.maxRowsPerFileBlock);
|
pQueryHandle->pDataCols = tdNewDataCols(pMeta->maxCols, pQueryHandle->pTsdb->config.maxRowsPerFileBlock);
|
||||||
if (pQueryHandle->pDataCols == NULL) {
|
if (pQueryHandle->pDataCols == NULL) {
|
||||||
tsdbError("%p failed to malloc buf for pDataCols, %"PRIu64, pQueryHandle, pQueryHandle->qId);
|
tsdbError("%p failed to malloc buf for pDataCols, %"PRIu64, pQueryHandle, pQueryHandle->qId);
|
||||||
terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
|
terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
|
||||||
|
@ -1446,7 +1446,7 @@ static int doBinarySearchKey(char* pValue, int num, TSKEY key, int order) {
|
||||||
return midPos;
|
return midPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t doCopyRowsFromFileBlock(STsdbQueryHandle* pQueryHandle, int32_t capacity, int32_t numOfRows, int32_t start, int32_t end) {
|
static int32_t doCopyRowsFromFileBlock(STsdbQueryHandle* pQueryHandle, int32_t capacity, int32_t numOfRows, int32_t start, int32_t end) {
|
||||||
char* pData = NULL;
|
char* pData = NULL;
|
||||||
int32_t step = ASCENDING_TRAVERSE(pQueryHandle->order)? 1 : -1;
|
int32_t step = ASCENDING_TRAVERSE(pQueryHandle->order)? 1 : -1;
|
||||||
|
|
||||||
|
@ -1481,7 +1481,7 @@ int32_t doCopyRowsFromFileBlock(STsdbQueryHandle* pQueryHandle, int32_t capacity
|
||||||
pData = (char*)pColInfo->pData + (capacity - numOfRows - num) * pColInfo->info.bytes;
|
pData = (char*)pColInfo->pData + (capacity - numOfRows - num) * pColInfo->info.bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pColInfo->info.colId == src->colId) {
|
if (!isAllRowsNull(src) && pColInfo->info.colId == src->colId) {
|
||||||
if (pColInfo->info.type != TSDB_DATA_TYPE_BINARY && pColInfo->info.type != TSDB_DATA_TYPE_NCHAR) {
|
if (pColInfo->info.type != TSDB_DATA_TYPE_BINARY && pColInfo->info.type != TSDB_DATA_TYPE_NCHAR) {
|
||||||
memmove(pData, (char*)src->pData + bytes * start, bytes * num);
|
memmove(pData, (char*)src->pData + bytes * start, bytes * num);
|
||||||
} else { // handle the var-string
|
} else { // handle the var-string
|
||||||
|
|
|
@ -42,14 +42,14 @@ int tsdbInitReadH(SReadH *pReadh, STsdbRepo *pRepo) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pReadh->pDCols[0] = tdNewDataCols(0, 0, pCfg->maxRowsPerFileBlock);
|
pReadh->pDCols[0] = tdNewDataCols(0, pCfg->maxRowsPerFileBlock);
|
||||||
if (pReadh->pDCols[0] == NULL) {
|
if (pReadh->pDCols[0] == NULL) {
|
||||||
terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
|
terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
|
||||||
tsdbDestroyReadH(pReadh);
|
tsdbDestroyReadH(pReadh);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pReadh->pDCols[1] = tdNewDataCols(0, 0, pCfg->maxRowsPerFileBlock);
|
pReadh->pDCols[1] = tdNewDataCols(0, pCfg->maxRowsPerFileBlock);
|
||||||
if (pReadh->pDCols[1] == NULL) {
|
if (pReadh->pDCols[1] == NULL) {
|
||||||
terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
|
terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
|
||||||
tsdbDestroyReadH(pReadh);
|
tsdbDestroyReadH(pReadh);
|
||||||
|
@ -463,7 +463,7 @@ static int tsdbLoadBlockDataImpl(SReadH *pReadh, SBlock *pBlock, SDataCols *pDat
|
||||||
SDataCol *pDataCol = &(pDataCols->cols[dcol]);
|
SDataCol *pDataCol = &(pDataCols->cols[dcol]);
|
||||||
if (dcol != 0 && ccol >= pBlockData->numOfCols) {
|
if (dcol != 0 && ccol >= pBlockData->numOfCols) {
|
||||||
// Set current column as NULL and forward
|
// Set current column as NULL and forward
|
||||||
dataColSetNEleNull(pDataCol, pBlock->numOfRows, pDataCols->maxPoints);
|
dataColReset(pDataCol);
|
||||||
dcol++;
|
dcol++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -503,7 +503,7 @@ static int tsdbLoadBlockDataImpl(SReadH *pReadh, SBlock *pBlock, SDataCols *pDat
|
||||||
ccol++;
|
ccol++;
|
||||||
} else {
|
} else {
|
||||||
// Set current column as NULL and forward
|
// Set current column as NULL and forward
|
||||||
dataColSetNEleNull(pDataCol, pBlock->numOfRows, pDataCols->maxPoints);
|
dataColReset(pDataCol);
|
||||||
dcol++;
|
dcol++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -608,7 +608,7 @@ static int tsdbLoadBlockDataColsImpl(SReadH *pReadh, SBlock *pBlock, SDataCols *
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pBlockCol == NULL) {
|
if (pBlockCol == NULL) {
|
||||||
dataColSetNEleNull(pDataCol, pBlock->numOfRows, pDataCols->maxPoints);
|
dataColReset(pDataCol);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -81,6 +81,7 @@ typedef struct {
|
||||||
extern SGlobalCfg tsGlobalConfig[];
|
extern SGlobalCfg tsGlobalConfig[];
|
||||||
extern int32_t tsGlobalConfigNum;
|
extern int32_t tsGlobalConfigNum;
|
||||||
extern char * tsCfgStatusStr[];
|
extern char * tsCfgStatusStr[];
|
||||||
|
extern bool tsdbForceKeepFile;
|
||||||
|
|
||||||
void taosReadGlobalLogCfg();
|
void taosReadGlobalLogCfg();
|
||||||
bool taosReadGlobalCfg();
|
bool taosReadGlobalCfg();
|
||||||
|
|
|
@ -18109,4 +18109,3 @@
|
||||||
fun:_PyEval_EvalCodeWithName
|
fun:_PyEval_EvalCodeWithName
|
||||||
fun:_PyFunction_Vectorcall
|
fun:_PyFunction_Vectorcall
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -338,6 +338,7 @@ python3 ./test.py -f functions/function_twa.py -r 1
|
||||||
python3 ./test.py -f functions/function_twa_test2.py
|
python3 ./test.py -f functions/function_twa_test2.py
|
||||||
python3 ./test.py -f functions/function_stddev_td2555.py
|
python3 ./test.py -f functions/function_stddev_td2555.py
|
||||||
python3 ./test.py -f functions/showOfflineThresholdIs864000.py
|
python3 ./test.py -f functions/showOfflineThresholdIs864000.py
|
||||||
|
python3 ./test.py -f functions/function_interp.py
|
||||||
python3 ./test.py -f insert/metadataUpdate.py
|
python3 ./test.py -f insert/metadataUpdate.py
|
||||||
python3 ./test.py -f query/last_cache.py
|
python3 ./test.py -f query/last_cache.py
|
||||||
python3 ./test.py -f query/last_row_cache.py
|
python3 ./test.py -f query/last_row_cache.py
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
###################################################################
|
||||||
|
# Copyright (c) 2016 by TAOS Technologies, Inc.
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# This file is proprietary and confidential to TAOS Technologies.
|
||||||
|
# No part of this file may be reproduced, stored, transmitted,
|
||||||
|
# disclosed or used in any form or by any means other than as
|
||||||
|
# expressly provided by the written permission from Jianhui Tao
|
||||||
|
#
|
||||||
|
###################################################################
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import taos
|
||||||
|
from util.log import *
|
||||||
|
from util.cases import *
|
||||||
|
from util.sql import *
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
|
class TDTestCase:
|
||||||
|
def init(self, conn, logSql):
|
||||||
|
tdLog.debug("start to execute %s" % __file__)
|
||||||
|
tdSql.init(conn.cursor())
|
||||||
|
|
||||||
|
self.rowNum = 10
|
||||||
|
self.ts = 1537146000000
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
tdSql.prepare()
|
||||||
|
tdSql.execute("create table t(ts timestamp, k int)")
|
||||||
|
tdSql.execute("insert into t values('2021-1-1 1:1:1', 12);")
|
||||||
|
|
||||||
|
tdSql.query("select interp(*) from t where ts='2021-1-1 1:1:1'")
|
||||||
|
tdSql.checkRows(1)
|
||||||
|
tdSql.checkData(0, 1, 12)
|
||||||
|
|
||||||
|
tdSql.error("select interp(*) from t where ts >'2021-1-1 1:1:1' and ts < now interval(1s) fill(next)")
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
tdSql.close()
|
||||||
|
tdLog.success("%s successfully executed" % __file__)
|
||||||
|
|
||||||
|
tdCases.addWindows(__file__, TDTestCase())
|
||||||
|
tdCases.addLinux(__file__, TDTestCase())
|
|
@ -19,11 +19,16 @@ import json
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
class taosdemoPerformace:
|
class taosdemoPerformace:
|
||||||
def __init__(self, commitID, dbName, branch, type):
|
def __init__(self, commitID, dbName, branch, type, numOfTables, numOfRows, numOfInt, numOfDouble, numOfBinary):
|
||||||
self.commitID = commitID
|
self.commitID = commitID
|
||||||
self.dbName = dbName
|
self.dbName = dbName
|
||||||
self.branch = branch
|
self.branch = branch
|
||||||
self.type = type
|
self.type = type
|
||||||
|
self.numOfTables = numOfTables
|
||||||
|
self.numOfRows = numOfRows
|
||||||
|
self.numOfInt = numOfInt
|
||||||
|
self.numOfDouble = numOfDouble
|
||||||
|
self.numOfBinary = numOfBinary
|
||||||
self.host = "127.0.0.1"
|
self.host = "127.0.0.1"
|
||||||
self.user = "root"
|
self.user = "root"
|
||||||
self.password = "taosdata"
|
self.password = "taosdata"
|
||||||
|
@ -51,13 +56,13 @@ class taosdemoPerformace:
|
||||||
stb = {
|
stb = {
|
||||||
"name": "meters",
|
"name": "meters",
|
||||||
"child_table_exists": "no",
|
"child_table_exists": "no",
|
||||||
"childtable_count": 10000,
|
"childtable_count": self.numOfTables,
|
||||||
"childtable_prefix": "stb_",
|
"childtable_prefix": "stb_",
|
||||||
"auto_create_table": "no",
|
"auto_create_table": "no",
|
||||||
"data_source": "rand",
|
"data_source": "rand",
|
||||||
"batch_create_tbl_num": 10,
|
"batch_create_tbl_num": 10,
|
||||||
"insert_mode": "taosc",
|
"insert_mode": "taosc",
|
||||||
"insert_rows": 100000,
|
"insert_rows": self.numOfRows,
|
||||||
"interlace_rows": 100,
|
"interlace_rows": 100,
|
||||||
"max_sql_len": 1024000,
|
"max_sql_len": 1024000,
|
||||||
"disorder_ratio": 0,
|
"disorder_ratio": 0,
|
||||||
|
@ -68,7 +73,9 @@ class taosdemoPerformace:
|
||||||
"sample_file": "./sample.csv",
|
"sample_file": "./sample.csv",
|
||||||
"tags_file": "",
|
"tags_file": "",
|
||||||
"columns": [
|
"columns": [
|
||||||
{"type": "INT", "count": 4}
|
{"type": "INT", "count": self.numOfInt},
|
||||||
|
{"type": "DOUBLE", "count": self.numOfDouble},
|
||||||
|
{"type": "BINARY", "len": 128, "count": self.numOfBinary}
|
||||||
],
|
],
|
||||||
"tags": [
|
"tags": [
|
||||||
{"type": "INT", "count": 1},
|
{"type": "INT", "count": 1},
|
||||||
|
@ -76,6 +83,7 @@ class taosdemoPerformace:
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
stables = []
|
stables = []
|
||||||
stables.append(stb)
|
stables.append(stb)
|
||||||
|
|
||||||
|
@ -163,7 +171,7 @@ class taosdemoPerformace:
|
||||||
|
|
||||||
cursor.execute("create database if not exists %s" % self.dbName)
|
cursor.execute("create database if not exists %s" % self.dbName)
|
||||||
cursor.execute("use %s" % self.dbName)
|
cursor.execute("use %s" % self.dbName)
|
||||||
cursor.execute("create table if not exists taosdemo_perf (ts timestamp, create_table_time float, insert_records_time float, records_per_second float, commit_id binary(50), avg_delay float, max_delay float, min_delay float, branch binary(50), type binary(20))")
|
cursor.execute("create table if not exists taosdemo_perf (ts timestamp, create_table_time float, insert_records_time float, records_per_second float, commit_id binary(50), avg_delay float, max_delay float, min_delay float, branch binary(50), type binary(20), numoftables int, numofrows int, numofint int, numofdouble int, numofbinary int)")
|
||||||
print("==================== taosdemo performance ====================")
|
print("==================== taosdemo performance ====================")
|
||||||
print("create tables time: %f" % float(self.createTableTime))
|
print("create tables time: %f" % float(self.createTableTime))
|
||||||
print("insert records time: %f" % float(self.insertRecordsTime))
|
print("insert records time: %f" % float(self.insertRecordsTime))
|
||||||
|
@ -171,13 +179,14 @@ class taosdemoPerformace:
|
||||||
print("avg delay: %f" % float(self.avgDelay))
|
print("avg delay: %f" % float(self.avgDelay))
|
||||||
print("max delay: %f" % float(self.maxDelay))
|
print("max delay: %f" % float(self.maxDelay))
|
||||||
print("min delay: %f" % float(self.minDelay))
|
print("min delay: %f" % float(self.minDelay))
|
||||||
cursor.execute("insert into taosdemo_perf values(now, %f, %f, %f, '%s', %f, %f, %f, '%s', '%s')" %
|
cursor.execute("insert into taosdemo_perf values(now, %f, %f, %f, '%s', %f, %f, %f, '%s', '%s', %d, %d, %d, %d, %d)" %
|
||||||
(float(self.createTableTime), float(self.insertRecordsTime), float(self.recordsPerSecond),
|
(float(self.createTableTime), float(self.insertRecordsTime), float(self.recordsPerSecond),
|
||||||
self.commitID, float(self.avgDelay), float(self.maxDelay), float(self.minDelay), self.branch, self.type))
|
self.commitID, float(self.avgDelay), float(self.maxDelay), float(self.minDelay), self.branch,
|
||||||
|
self.type, self.numOfTables, self.numOfRows, self.numOfInt, self.numOfDouble, self.numOfBinary))
|
||||||
cursor.close()
|
cursor.close()
|
||||||
|
|
||||||
cursor1 = self.conn.cursor()
|
cursor1 = self.conn.cursor()
|
||||||
cursor1.execute("drop database if exists %s" % self.insertDB)
|
# cursor1.execute("drop database if exists %s" % self.insertDB)
|
||||||
cursor1.close()
|
cursor1.close()
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
@ -209,8 +218,43 @@ if __name__ == '__main__':
|
||||||
default='glibc',
|
default='glibc',
|
||||||
type=str,
|
type=str,
|
||||||
help='build type (default: glibc)')
|
help='build type (default: glibc)')
|
||||||
|
parser.add_argument(
|
||||||
|
'-i',
|
||||||
|
'--num-of-int',
|
||||||
|
action='store',
|
||||||
|
default=4,
|
||||||
|
type=int,
|
||||||
|
help='num of int columns (default: 4)')
|
||||||
|
parser.add_argument(
|
||||||
|
'-D',
|
||||||
|
'--num-of-double',
|
||||||
|
action='store',
|
||||||
|
default=0,
|
||||||
|
type=int,
|
||||||
|
help='num of double columns (default: 4)')
|
||||||
|
parser.add_argument(
|
||||||
|
'-B',
|
||||||
|
'--num-of-binary',
|
||||||
|
action='store',
|
||||||
|
default=0,
|
||||||
|
type=int,
|
||||||
|
help='num of binary columns (default: 4)')
|
||||||
|
parser.add_argument(
|
||||||
|
'-t',
|
||||||
|
'--num-of-tables',
|
||||||
|
action='store',
|
||||||
|
default=10000,
|
||||||
|
type=int,
|
||||||
|
help='num of tables (default: 10000)')
|
||||||
|
parser.add_argument(
|
||||||
|
'-r',
|
||||||
|
'--num-of-rows',
|
||||||
|
action='store',
|
||||||
|
default=100000,
|
||||||
|
type=int,
|
||||||
|
help='num of rows (default: 100000)')
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
perftest = taosdemoPerformace(args.commit_id, args.database_name, args.git_branch, args.build_type)
|
perftest = taosdemoPerformace(args.commit_id, args.database_name, args.git_branch, args.build_type, args.num_of_tables, args.num_of_rows, args.num_of_int, args.num_of_double, args.num_of_binary)
|
||||||
perftest.insertData()
|
perftest.insertData()
|
||||||
perftest.createTablesAndStoreData()
|
perftest.createTablesAndStoreData()
|
||||||
|
|
|
@ -1050,6 +1050,27 @@ sql_error select min(c3) from m_fl_mt0 interval(10w) fill(value, 20)
|
||||||
sql_error select max(c3) from m_fl_mt0 interval(1n) fill(prev)
|
sql_error select max(c3) from m_fl_mt0 interval(1n) fill(prev)
|
||||||
sql_error select min(c3) from m_fl_mt0 interval(1y) fill(value, 20)
|
sql_error select min(c3) from m_fl_mt0 interval(1y) fill(value, 20)
|
||||||
|
|
||||||
|
sql create table nexttb1 (ts timestamp, f1 int);
|
||||||
|
sql insert into nexttb1 values ('2021-08-08 1:1:1', NULL);
|
||||||
|
sql insert into nexttb1 values ('2021-08-08 1:1:5', 3);
|
||||||
|
|
||||||
|
sql select last(*) from nexttb1 where ts >= '2021-08-08 1:1:1' and ts < '2021-08-08 1:1:10' interval(1s) fill(next);
|
||||||
|
if $rows != 9 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
if $data00 != @21-08-08 01:01:01.000@ then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
if $data01 != @21-08-08 01:01:01.000@ then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
if $data02 != 3 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
print =============== clear
|
print =============== clear
|
||||||
#sql drop database $db
|
#sql drop database $db
|
||||||
#sql show databases
|
#sql show databases
|
||||||
|
|
|
@ -1148,3 +1148,21 @@ endi
|
||||||
|
|
||||||
|
|
||||||
sql select derivative(test_column_alias_name, 1s, 0) from (select avg(k) test_column_alias_name from t1 interval(1s));
|
sql select derivative(test_column_alias_name, 1s, 0) from (select avg(k) test_column_alias_name from t1 interval(1s));
|
||||||
|
|
||||||
|
sql create table smeters (ts timestamp, current float, voltage int);
|
||||||
|
sql insert into smeters values ('2021-08-08 10:10:10', 10, 1);
|
||||||
|
sql insert into smeters values ('2021-08-08 10:10:12', 10, 2);
|
||||||
|
|
||||||
|
sql select stddev(voltage) from smeters where ts>='2021-08-08 10:10:10.000' and ts < '2021-08-08 10:10:20.000' and current=10 interval(1000a);
|
||||||
|
if $rows != 2 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
if $data00 != @21-08-08 10:10:10.000@ then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
if $data10 != @21-08-08 10:10:12.000@ then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue