TDengine/source/libs/parser/src/parInsertSql.c

3738 lines
131 KiB
C
Raw Normal View History

/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
2024-03-26 07:11:15 +00:00
#include "geosWrapper.h"
2022-10-24 08:38:16 +00:00
#include "parInsertUtil.h"
2022-03-10 07:36:06 +00:00
#include "parToken.h"
#include "scalar.h"
#include "tglobal.h"
#include "ttime.h"
feat(decimal): support decimal data type (#30060) * decimal: create table * decimal: add test case decimal.py * decimal: add decimal.c * support input decimal * decimal test * refactor svalue * fix test cases * add decimal unit test * add decimal test cmake * support insert and query decimal type * define wide integer, support decimal128 * support decimal128 divide * set decimal type expr res types * scalar decimal * convert to decimal * fix decimal64/128 from str and to str * fix decimal from str and decimal to str * decimal simple conversion * unit test for decimal * decimal conversion and unit tests * decimal + - * / * decimal scalar ops and comparision * start to refactor GET_TYPED_DATA * support decimal max func, cast func * refactor GET_TYPED_DATA interface * decimal scalar comparision * start to implement sum for decimal * support sum and avg for decimal type * decimal tests * add decimal test * decimal add test cases * decimal use int256/int128 * decimal testing * fix decimal table meta and add tests for decimal col streams * fix create stream and create tsma * test insert decimal values * decimal from str * test decimal input * test parse decimal from string * add taos_fetch_field_e api * decimal insert tests * test decimal operators * decimal operator test * feat:support decimal in raw block * decimal operator tests * decimal test * feat:support decimal in raw block * feat:support decimal in raw block * feat:add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * decimal test operators * decimal operator test * test decimal operators * test decimal compare operators * decimal unary operator test * decimal col with decimal col oper test * test decimal col filtering * fix decimal float operator test * decimal test where filtering * fix decimal filtering * fix decimal order by * fix decimal op test * test decimal agg funcs * test decimal functions * remove assert * fix ci build for ret check * fix decimal windows build * fix ci ret check * skip decimal ret check * skip decimal ret check * fix decimal tests * fix decimal ci test * decimal test * fix(tmq): heap user after free * fix(tmq): double free * fix(tmq): double free * fix decimal tests * fix(decimal): decimal test ci build * fix(decimal): windows build * fix(decimal): decimal test build * fix(decimal): fix decimal build and tests * fix(decimal): fix decimal tests * fix(decimal): fix taos_fetch_fields_e api * fix(decimal): fix decimal taos_fetch_fields_e api * fix(decimal): rebase 3.0 * fix(decimal): fix decimal functions * fix(decimal): fix decimal test case memory leak * fix(decimal): fix decimal tests * fix(decimal): fix decimal test case * fix(decimal): fix decimal tests * feat(decimal): fix unit tests * feat(decimal): fix deicmal unit test --------- Co-authored-by: wangmm0220 <wangmm0220@gmail.com> Co-authored-by: yihaoDeng <yhdeng@taosdata.com>
2025-03-14 10:08:07 +00:00
#include "decimal.h"
// CSV delimiter and quote character definitions
#define CSV_DEFAULT_DELIMITER ','
#define CSV_QUOTE_SINGLE '\''
#define CSV_QUOTE_DOUBLE '"'
#define CSV_ESCAPE_CHAR '\\'
#define CSV_QUOTE_NONE '\0'
typedef struct SCsvParser {
char delimiter; // Field delimiter (default: ',')
char quote; // Quote character (default: '"')
char escape; // Escape character (default: '\')
bool allowNewlineInField; // Allow newlines in quoted fields
char* buffer; // Read buffer
size_t bufferSize; // Buffer size
size_t bufferPos; // Current position in buffer
size_t bufferLen; // Valid data length in buffer
bool eof; // End of file reached
TdFilePtr pFile; // File pointer
// Line buffer for reuse to avoid frequent memory allocation
char* lineBuffer; // Reusable line buffer
size_t lineBufferCapacity; // Line buffer capacity
} SCsvParser;
2022-11-04 07:21:38 +00:00
typedef struct SInsertParseContext {
2022-12-07 11:12:55 +00:00
SParseContext* pComCxt;
SMsgBuf msg;
char tmpTokenBuf[TSDB_MAX_BYTES_PER_ROW];
SBoundColInfo tags; // for stmt
bool missCache;
bool usingDuplicateTable;
bool forceUpdate;
2023-04-25 09:39:28 +00:00
bool needTableTagVal;
2024-03-26 07:11:15 +00:00
bool needRequest; // whether or not request server
bool isStmtBind; // whether is stmt bind
uint8_t stmtTbNameFlag;
2022-11-04 07:21:38 +00:00
} SInsertParseContext;
2022-04-19 02:18:11 +00:00
typedef int32_t (*_row_append_fn_t)(SMsgBuf* pMsgBuf, const void* value, int32_t len, void* param);
static int32_t parseBoundTagsClause(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt);
static int32_t parseTagsClause(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt, bool autoCreate);
2022-02-28 09:02:43 +00:00
// CSV parser function declarations
static int32_t csvParserInit(SCsvParser* parser, TdFilePtr pFile);
static void csvParserDestroy(SCsvParser* parser);
static int32_t csvParserFillBuffer(SCsvParser* parser);
static int32_t csvParserReadLine(SCsvParser* parser);
static void destroySavedCsvParser(SVnodeModifyOpStmt* pStmt);
static int32_t csvParserExpandLineBuffer(SCsvParser* parser, size_t requiredLen);
2022-02-28 09:02:43 +00:00
static uint8_t TRUE_VALUE = (uint8_t)TSDB_TRUE;
static uint8_t FALSE_VALUE = (uint8_t)TSDB_FALSE;
2024-03-10 14:14:57 +00:00
static FORCE_INLINE bool isNullValue(int8_t dataType, SToken* pToken) {
return TK_NULL == pToken->type ||
(TK_NK_STRING == pToken->type && !IS_STR_DATA_TYPE(dataType) && IS_NULL_STR(pToken->z, pToken->n));
2022-11-04 07:21:38 +00:00
}
static FORCE_INLINE int32_t toDouble(SToken* pToken, double* value, char** endPtr) {
feat: support customized taos/taosd (#29736) * feat: support TDAcoreOS * chore: cmake options for TD_ACORE * chore: disable lemon for TD_ACORE * chore: add lzma2 and msvcregex * chore: cmake for lzma2 * chore: adapt for TD_ACORE * chore: adapt strcasecmp for TD_ACORE * chore: adapt for geos/threadName * chore: build adapt for TD_ACORE * chore: build adapt for TD_ACORE * chore: build adapt for TD_ACORE * chore: build adapt for TD_ACORE * chore: build adapt for TD_ACORE termio * chore: refact transComm.h for TD_ACORE * chore: refact transportInt.h for TD_ACORE * chore: refact trans.c for TD_ACORE * chore: refact trpc.h for TD_ACORE * chore: refact transCli.c/transComm.c/transSvr.c for TD_ACORE * chore: refact uv.h for TD_ACORE * chore: refact geosWrapper.h for TD_ACORE * chore: refact token/builtins/udf for TD_ACORE * chore: refact rocks for TD_ACORE * chore: refact tsdbCache.c for TD_ACORE, use LRU cache for last/last_row, not use rocksdb * chore: refact FAIL to _ERR to solve conflicts for TD_ACORE * chore: restore lemon.c/lempar.c * chore: support build lemon for TD_ACORE * chore: refact trpc and siginfo_t for TD_ACORE * chore: refact timezone for TD_ACORE * chore: refact lz4 for TD_ACORE * chore: refact TD_ACORE to make compile pass * chore: code optimization for TD_ASTRA * feat: support run taos with taosd integrated * feat: support invoke taos shell * feat: support invoke taos shell * feat: support invoke taos shell * chore: code optimization * chore: fix undefined reference problem os TD_ASTRA * chore: resolve compile problem for TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix getpid * chore: fix typo * chore: set stack size and ajust min pack size for TD_ASTRA * chore: fix pthread create parameters * chore: chmod adapt for TD_ASTRA * chore: fix trans compile problem * chore: adapt chmod for TD_ASTRA * chore: byte alignment for TD_ASTRA * chore: more code for adaption of TD_ASTRA * chore: more code for adaption of TD_ASTRA * chore: more code for adaption of TD_ASTRA * chore: byte alignment for TD_ASTRA * chore: conditional compile option * chore: adapt for TD_ASTRA * chore: adjust taosPId and msvcregex for TD_ASTRA * chore: log dir separator for wal build name * chore: fix type of pointer parameter * chore: fix compile problem of tsdbGetS3Size * enh: get last ver from wal log for TD_ASTRA * enh: refact wal meta ver * enh: refact wal meta ver * fix: typo of taosUcs4Compare * enh: process return value of CI * chore: more code for TD_ASTRA adaption * chore: return value of taosCloseFile in walMeta.c * chore: fix compile problem * chore: fix compile problem of TD_ASTRA * fix: update macro for tq and stream task * chore: code optimization for TD_ASTRA * chore: restore create log and init cfg interface * chore: restore strncasecmp and strcasecmp * fix: adjust the field position of SDataBlockInfo * fix: pragma pack min size * fix: pragma pack min size * chore: more code for TD_ASTRA adaption * fix: type of parameters * chore: adapt strncasecmp and strcasecmp for TD_ASTRA * chore: restore interface of init log * enh: pack push optimization * fix: taos init cfg * add astra support * fix: fetch the value of suid * chore: switch of build with udf * add temp code * chore: more code for TD_ASTRA adaption * chore: add macro ERRNO to replace errno * chore: bytes align for TD_ASTRA * fix: remove obsolete codes * enh: support USE_UDF macro * fix compile error * fix: resolve redefinition problem * fix: compile problem of log.cpp * fix: compile problem of osTimezone * fix: resolve compile problem of udf * fix: pragma definition on windows * fix: ucs4 and stpncpy for TD_ASTRA * fix: memory align problem for TD_ASTRA * enh: solve memory leak for TD_ASTRA_RPC * fix: compile problem of taosSetInt64Aligned * fix: restore mndSubscribe.c * fix: scalar for udf * chore: code adaption for TD_ASTRA * chore: code optimization for TD_ASTRA * fix: typo of add definition * fix: typo of macro in tudf.h * chore: remove void to make CI pass * enh: move macro from cmake.platform to cmake.options * enh: byte align for hash node and error code * chore: restore the size for lru cache * enh: restore some code about pack push * chore: restore the pack push in tmsg.h * fix: add macro of pack pop for windows --------- Co-authored-by: yihaoDeng <luomoxyz@126.com>
2025-03-14 05:32:13 +00:00
SET_ERRNO(0);
2022-11-04 07:21:38 +00:00
*value = taosStr2Double(pToken->z, endPtr);
// not a valid integer number, return error
if ((*endPtr - pToken->z) != pToken->n) {
return TK_NK_ILLEGAL;
}
return pToken->type;
}
static int32_t skipInsertInto(const char** pSql, SMsgBuf* pMsg) {
SToken token;
NEXT_TOKEN(*pSql, token);
if (TK_INSERT != token.type && TK_IMPORT != token.type) {
return buildSyntaxErrMsg(pMsg, "keyword INSERT is expected", token.z);
}
2022-11-04 07:21:38 +00:00
NEXT_TOKEN(*pSql, token);
if (TK_INTO != token.type) {
return buildSyntaxErrMsg(pMsg, "keyword INTO is expected", token.z);
}
return TSDB_CODE_SUCCESS;
}
2022-11-04 07:21:38 +00:00
static int32_t skipParentheses(SInsertParseContext* pCxt, const char** pSql) {
SToken token;
int32_t expectRightParenthesis = 1;
while (1) {
NEXT_TOKEN(*pSql, token);
if (TK_NK_LP == token.type) {
++expectRightParenthesis;
} else if (TK_NK_RP == token.type && 0 == --expectRightParenthesis) {
break;
}
if (0 == token.n) {
return buildSyntaxErrMsg(&pCxt->msg, ") expected", NULL);
}
}
2022-11-04 07:21:38 +00:00
return TSDB_CODE_SUCCESS;
}
2022-06-10 09:07:24 +00:00
2022-11-04 07:21:38 +00:00
static int32_t skipTableOptions(SInsertParseContext* pCxt, const char** pSql) {
do {
int32_t index = 0;
SToken token;
NEXT_TOKEN_KEEP_SQL(*pSql, token, index);
if (TK_TTL == token.type || TK_COMMENT == token.type) {
*pSql += index;
NEXT_TOKEN_WITH_PREV(*pSql, token);
} else {
break;
}
} while (1);
return TSDB_CODE_SUCCESS;
}
2022-11-04 07:21:38 +00:00
// pSql -> stb_name [(tag1_name, ...)] TAGS (tag1_value, ...)
static int32_t ignoreUsingClause(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt) {
const char** pSql = &pStmt->pSql;
2022-11-04 07:21:38 +00:00
int32_t code = TSDB_CODE_SUCCESS;
SToken token;
NEXT_TOKEN(*pSql, token);
NEXT_TOKEN(*pSql, token);
if (TK_NK_LP == token.type) {
code = skipParentheses(pCxt, pSql);
if (TSDB_CODE_SUCCESS == code) {
NEXT_TOKEN(*pSql, token);
}
}
2022-06-21 07:37:59 +00:00
2022-11-04 07:21:38 +00:00
// pSql -> TAGS (tag1_value, ...)
if (TSDB_CODE_SUCCESS == code) {
if (TK_TAGS != token.type) {
code = buildSyntaxErrMsg(&pCxt->msg, "TAGS is expected", token.z);
} else {
NEXT_TOKEN(*pSql, token);
}
}
if (TSDB_CODE_SUCCESS == code) {
if (TK_NK_LP != token.type) {
code = buildSyntaxErrMsg(&pCxt->msg, "( is expected", token.z);
} else {
code = skipParentheses(pCxt, pSql);
}
}
2022-11-04 07:21:38 +00:00
if (TSDB_CODE_SUCCESS == code) {
code = skipTableOptions(pCxt, pSql);
}
2022-11-04 07:21:38 +00:00
return code;
}
2022-05-09 08:03:56 +00:00
static int32_t ignoreUsingClauseAndCheckTagValues(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt) {
const char** pSql = &pStmt->pSql;
int32_t code = TSDB_CODE_SUCCESS;
code = parseBoundTagsClause(pCxt, pStmt);
if (TSDB_CODE_SUCCESS != code) {
return code;
}
// pSql -> TAGS (tag1_value, ...)
code = parseTagsClause(pCxt, pStmt, true);
if (TSDB_CODE_SUCCESS != code) {
return code;
}
if (TSDB_CODE_SUCCESS == code) {
code = skipTableOptions(pCxt, pSql);
}
return code;
}
2022-05-09 08:03:56 +00:00
2022-12-20 08:53:08 +00:00
static int32_t parseDuplicateUsingClause(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt, bool* pDuplicate) {
2023-11-03 09:41:08 +00:00
int32_t code = TSDB_CODE_SUCCESS;
2022-11-04 07:21:38 +00:00
*pDuplicate = false;
char tbFName[TSDB_TABLE_FNAME_LEN];
2024-07-23 07:59:10 +00:00
code = tNameExtractFullName(&pStmt->targetTableName, tbFName);
if (TSDB_CODE_SUCCESS != code) {
return code;
}
2022-11-04 07:21:38 +00:00
STableMeta** pMeta = taosHashGet(pStmt->pSubTableHashObj, tbFName, strlen(tbFName));
if (NULL != pMeta) {
*pDuplicate = true;
pCxt->missCache = false;
code = cloneTableMeta(*pMeta, &pStmt->pTableMeta);
if (TSDB_CODE_SUCCESS != code) {
return code;
2022-11-04 07:21:38 +00:00
}
return ignoreUsingClause(pCxt, pStmt);
2022-04-13 09:52:26 +00:00
}
2022-11-04 07:21:38 +00:00
2023-11-03 09:41:08 +00:00
return code;
2022-04-13 09:52:26 +00:00
}
2024-03-26 07:11:15 +00:00
typedef enum { BOUND_TAGS, BOUND_COLUMNS, BOUND_ALL_AND_TBNAME } EBoundColumnsType;
static int32_t getTbnameSchemaIndex(STableMeta* pTableMeta) {
return pTableMeta->tableInfo.numOfTags + pTableMeta->tableInfo.numOfColumns;
}
2022-11-04 07:21:38 +00:00
// pStmt->pSql -> field1_name, ...)
2024-03-26 07:11:15 +00:00
static int32_t parseBoundColumns(SInsertParseContext* pCxt, const char** pSql, EBoundColumnsType boundColsType,
STableMeta* pTableMeta, SBoundColInfo* pBoundInfo) {
SSchema* pSchema = NULL;
if (boundColsType == BOUND_TAGS) {
pSchema = getTableTagSchema(pTableMeta);
} else if (boundColsType == BOUND_COLUMNS) {
pSchema = getTableColumnSchema(pTableMeta);
} else {
pSchema = pTableMeta->schema;
if (pBoundInfo->numOfCols != getTbnameSchemaIndex(pTableMeta) + 1) {
return TSDB_CODE_PAR_INTERNAL_ERROR;
}
}
int32_t tbnameSchemaIndex = getTbnameSchemaIndex(pTableMeta);
2022-11-27 09:09:02 +00:00
bool* pUseCols = taosMemoryCalloc(pBoundInfo->numOfCols, sizeof(bool));
if (NULL == pUseCols) {
2024-09-10 10:42:00 +00:00
return terrno;
2022-11-04 07:21:38 +00:00
}
2022-04-13 09:52:26 +00:00
2022-11-27 09:09:02 +00:00
pBoundInfo->numOfBound = 0;
pBoundInfo->hasBoundCols = true;
2022-11-27 09:09:02 +00:00
bool hasPK = pTableMeta->tableInfo.numOfPKs;
int16_t numOfBoundPKs = 0;
2022-11-30 08:57:24 +00:00
int16_t lastColIdx = -1; // last column found
2022-11-27 09:09:02 +00:00
int32_t code = TSDB_CODE_SUCCESS;
while (TSDB_CODE_SUCCESS == code) {
SToken token;
2022-11-04 07:21:38 +00:00
NEXT_TOKEN(*pSql, token);
if (TK_NK_RP == token.type) {
break;
}
char tmpTokenBuf[TSDB_COL_NAME_LEN + 2] = {0}; // used for deleting Escape character backstick(`)
strncpy(tmpTokenBuf, token.z, token.n);
token.z = tmpTokenBuf;
token.n = strdequote(token.z);
2024-03-26 07:11:15 +00:00
if (boundColsType == BOUND_ALL_AND_TBNAME && token.n == strlen("tbname") && (strcasecmp(token.z, "tbname") == 0)) {
2023-10-31 02:48:10 +00:00
pBoundInfo->pColIndex[pBoundInfo->numOfBound] = tbnameSchemaIndex;
pUseCols[tbnameSchemaIndex] = true;
++pBoundInfo->numOfBound;
continue;
}
2022-11-30 08:57:24 +00:00
int16_t t = lastColIdx + 1;
2023-11-01 05:25:54 +00:00
int16_t end = (boundColsType == BOUND_ALL_AND_TBNAME) ? (pBoundInfo->numOfCols - 1) : pBoundInfo->numOfCols;
int16_t index = insFindCol(&token, t, end, pSchema);
2022-11-04 07:21:38 +00:00
if (index < 0 && t > 0) {
index = insFindCol(&token, 0, t, pSchema);
}
if (index < 0) {
2022-11-27 09:09:02 +00:00
code = generateSyntaxErrMsg(&pCxt->msg, TSDB_CODE_PAR_INVALID_COLUMN, token.z);
} else if (pUseCols[index]) {
code = buildSyntaxErrMsg(&pCxt->msg, "duplicated column name", token.z);
} else {
lastColIdx = index;
pUseCols[index] = true;
pBoundInfo->pColIndex[pBoundInfo->numOfBound] = index;
++pBoundInfo->numOfBound;
if (hasPK && (pSchema[index].flags & COL_IS_KEY)) ++numOfBoundPKs;
2022-11-04 07:21:38 +00:00
}
}
if (TSDB_CODE_SUCCESS == code && (BOUND_TAGS != boundColsType)) {
if (!pUseCols[0]) {
2024-04-02 07:04:13 +00:00
code = buildInvalidOperationMsg(&pCxt->msg, "Primary timestamp column should not be null");
}
if (numOfBoundPKs != pTableMeta->tableInfo.numOfPKs) {
2024-04-02 07:04:13 +00:00
code = buildInvalidOperationMsg(&pCxt->msg, "Primary key column should not be none");
}
2022-11-22 12:55:24 +00:00
}
2024-03-26 07:11:15 +00:00
if (TSDB_CODE_SUCCESS == code && (BOUND_ALL_AND_TBNAME == boundColsType) && !pUseCols[tbnameSchemaIndex]) {
code = buildInvalidOperationMsg(&pCxt->msg, "tbname column should not be null");
}
2022-11-27 09:09:02 +00:00
taosMemoryFree(pUseCols);
2022-11-04 07:21:38 +00:00
2022-11-27 09:09:02 +00:00
return code;
2022-06-04 13:31:07 +00:00
}
2024-11-07 05:36:53 +00:00
static int32_t parseTimestampOrInterval(const char** end, SToken* pToken, int16_t timePrec, int64_t* ts, int64_t* interval,
2024-11-22 10:31:51 +00:00
SMsgBuf* pMsgBuf, bool* isTs, timezone_t tz) {
if (pToken->type == TK_NOW) {
*isTs = true;
*ts = taosGetTimestamp(timePrec);
} else if (pToken->type == TK_TODAY) {
*isTs = true;
2024-11-22 10:31:51 +00:00
*ts = taosGetTimestampToday(timePrec, tz);
} else if (pToken->type == TK_NK_INTEGER) {
*isTs = true;
if (TSDB_CODE_SUCCESS != toInteger(pToken->z, pToken->n, 10, ts)) {
2022-10-13 08:43:56 +00:00
return buildSyntaxErrMsg(pMsgBuf, "invalid timestamp format", pToken->z);
}
} else if (pToken->type == TK_NK_VARIABLE) {
char unit = 0;
*isTs = false;
if (parseAbsoluteDuration(pToken->z, pToken->n, interval, &unit, timePrec) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
2022-04-19 02:18:11 +00:00
} else { // parse the RFC-3339/ISO-8601 timestamp format string
*isTs = true;
2024-11-22 10:31:51 +00:00
if (taosParseTime(pToken->z, ts, pToken->n, timePrec, tz) != TSDB_CODE_SUCCESS) {
2024-03-13 07:12:21 +00:00
if ((pToken->n == 0) ||
(pToken->type != TK_NK_STRING && pToken->type != TK_NK_HEX && pToken->type != TK_NK_BIN)) {
2024-03-10 14:14:57 +00:00
return buildSyntaxErrMsg(pMsgBuf, "invalid timestamp format", pToken->z);
}
2024-03-11 11:54:42 +00:00
if (IS_NOW_STR(pToken->z, pToken->n)) {
*isTs = true;
*ts = taosGetTimestamp(timePrec);
} else if (IS_TODAY_STR(pToken->z, pToken->n)) {
*isTs = true;
2024-11-22 10:31:51 +00:00
*ts = taosGetTimestampToday(timePrec, tz);
2024-03-13 07:12:21 +00:00
} else if (TSDB_CODE_SUCCESS == toIntegerPure(pToken->z, pToken->n, 10, ts)) {
2024-03-11 11:54:42 +00:00
*isTs = true;
} else {
return buildSyntaxErrMsg(pMsgBuf, "invalid timestamp format", pToken->z);
2024-03-10 14:14:57 +00:00
}
}
}
return TSDB_CODE_SUCCESS;
}
2024-11-22 10:31:51 +00:00
static int parseTime(const char** end, SToken* pToken, int16_t timePrec, int64_t* time, SMsgBuf* pMsgBuf, timezone_t tz) {
int32_t index = 0, i = 0;
int64_t interval = 0, tempInterval = 0;
int64_t ts = 0, tempTs = 0;
2024-03-26 07:11:15 +00:00
bool firstIsTS = false, secondIsTs = false;
const char* pTokenEnd = *end;
2024-03-26 07:11:15 +00:00
if (TSDB_CODE_SUCCESS !=
2024-11-22 10:31:51 +00:00
parseTimestampOrInterval(&pTokenEnd, pToken, timePrec, &ts, &interval, pMsgBuf, &firstIsTS, tz)) {
return buildSyntaxErrMsg(pMsgBuf, "invalid timestamp format", pToken->z);
}
if (firstIsTS) {
*time = ts;
}
for (int k = pToken->n; pToken->z[k] != '\0'; k++) {
if (pToken->z[k] == ' ' || pToken->z[k] == '\t') continue;
2024-03-10 14:14:57 +00:00
if (pToken->z[k] == '(') { // for insert NOW()/TODAY()
if (pToken->z[k + 1] == ')') {
*end = pTokenEnd = &pToken->z[k + 2];
++k;
continue;
} else {
char nc = pToken->z[k + 1];
while (nc == ' ' || nc == '\t' || nc == '\n' || nc == '\r' || nc == '\f') {
nc = pToken->z[(++k) + 1];
}
if (nc == ')') {
*end = pTokenEnd = &pToken->z[k + 2];
++k;
continue;
}
}
}
if (pToken->z[k] == ',') {
*end = pTokenEnd;
if (!firstIsTS) {
return buildSyntaxErrMsg(pMsgBuf, "invalid timestamp format", pToken->z);
}
*time = ts;
return TSDB_CODE_SUCCESS;
}
break;
}
while (pTokenEnd[i] != '\0') {
if (pTokenEnd[i] == ' ' || pTokenEnd[i] == '\t') {
i++;
continue;
2024-03-26 07:11:15 +00:00
} else if (pTokenEnd[i] == ',' || pTokenEnd[i] == ')') {
*end = pTokenEnd + i;
if (!firstIsTS) {
return buildSyntaxErrMsg(pMsgBuf, "invalid timestamp format", pToken->z);
}
*time = ts;
return TSDB_CODE_SUCCESS;
} else {
break;
}
}
pTokenEnd = pTokenEnd + i;
index = 0;
2023-02-05 02:11:26 +00:00
SToken token = tStrGetToken(pTokenEnd, &index, false, NULL);
2022-11-04 07:21:38 +00:00
if (token.type == TK_NK_MINUS || token.type == TK_NK_PLUS) {
pTokenEnd += index;
index = 0;
2023-02-05 02:11:26 +00:00
SToken valueToken = tStrGetToken(pTokenEnd, &index, false, NULL);
pTokenEnd += index;
char tmpTokenBuf[TSDB_MAX_BYTES_PER_ROW];
if (TK_NK_STRING == valueToken.type) {
if (valueToken.n >= TSDB_MAX_BYTES_PER_ROW) {
return buildSyntaxErrMsg(pMsgBuf, "invalid timestamp format", valueToken.z);
}
int32_t len = trimString(valueToken.z, valueToken.n, tmpTokenBuf, TSDB_MAX_BYTES_PER_ROW);
valueToken.z = tmpTokenBuf;
valueToken.n = len;
}
2024-03-26 07:11:15 +00:00
if (TSDB_CODE_SUCCESS !=
2024-11-22 10:31:51 +00:00
parseTimestampOrInterval(&pTokenEnd, &valueToken, timePrec, &tempTs, &tempInterval, pMsgBuf, &secondIsTs, tz)) {
return buildSyntaxErrMsg(pMsgBuf, "invalid timestamp format", pToken->z);
}
if (valueToken.n < 2) {
2022-11-04 07:21:38 +00:00
return buildSyntaxErrMsg(pMsgBuf, "value expected in timestamp", token.z);
}
if (secondIsTs) {
// not support operator between tow timestamp, such as today() + now()
if (firstIsTS) {
return buildSyntaxErrMsg(pMsgBuf, "invalid timestamp format", pToken->z);
}
ts = tempTs;
2024-03-26 07:11:15 +00:00
} else {
// not support operator between tow interval, such as 2h + 3s
if (!firstIsTS) {
return buildSyntaxErrMsg(pMsgBuf, "invalid timestamp format", pToken->z);
}
interval = tempInterval;
}
if (token.type == TK_NK_MINUS) {
// not support interval - ts,such as 2h - today()
if (secondIsTs) {
return buildSyntaxErrMsg(pMsgBuf, "invalid timestamp format", pToken->z);
}
*time = ts - interval;
} else {
*time = ts + interval;
}
for (int k = valueToken.n; valueToken.z[k] != '\0'; k++) {
if (valueToken.z[k] == ' ' || valueToken.z[k] == '\t') continue;
if (valueToken.z[k] == '(' && valueToken.z[k + 1] == ')') { // for insert NOW()/TODAY()
*end = pTokenEnd = &valueToken.z[k + 2];
k++;
continue;
}
if (valueToken.z[k] == ',' || valueToken.z[k] == ')') {
*end = pTokenEnd;
return TSDB_CODE_SUCCESS;
}
return buildSyntaxErrMsg(pMsgBuf, "invalid timestamp format", pToken->z);
}
}
*end = pTokenEnd;
return TSDB_CODE_SUCCESS;
}
Feature/3.0 geometry (#21037) * Add GEOMETRY data type and make sql.c able to parse it. The GEMETRY works like BINARY so far. * add GEOMETRY type into gConvertTypes to fix some issues like DELETE calling * change some test cases to make sure no same timestamp is inserted, and add my smoketest.sh * Add a function MakePoint() and introduce a lib geometry * implement sql functions GeomFromText() and AsText() * Use GEOS *_r funcions instead for thread safety * Handle with TSDB_DATA_TYPE_GEOMETRY when INSERT geometry data by converting WKT. Add geosWrapper to wrap the basic GEOS functions for TDEngine. * refactor AsText and MakePoint functions to be like GeomFromText * Show WKT when print geometry data in screen Dump hex data when dump geometry data in a file * define TYPE_BYTES item for TSDB_DATA_TYPE_GEOMETRY, which casued some strange issues. * set number of decimals of WKT to 6 * Implement SQL function Intersects() * refactor geometry sql functions * Add geosErrMsgeHandler() to get the GEOS error detail * use threadlocal to instantiate SGeosContext call destroyGeosContext() only if the thread exists * remove SGeosContext *context param for all geometry functions since we use thread local one, so that all caller do not need to know the context. * Modify Intersects() to call PreparedIntersects() when one of param is a constant, which has higher performance. * rename prepareFn() to initCtxFn() to avoid confusion with PreparedFn * Add prefix "ST_" for all geometry functions * move getThreadLocalGeosCtx() and destroyThreadLocalGeosCtx() into util, so that all unit test tools can compile * Add unit test for geometry lib, only test MakePoint so far * refactor and enhance existing cases in geomFuncTest * implement NULL type and NULL value test for geomFuncTest * add test on geomFromText() * add unit test on AsText() in geomFuncTest * combine some makePointFunction test items * add intersectsFunctionTwoColumns test refactor on callGeomFromTextWrapper functions * enhance intersectsFunction test to add cases like input constant , NULL type, NULL value, or wrong content * add more cases into intersectsFunction test * Add basic test on geometry in system test * Add ST_GeomFromText and ST_AsText function test in system test on geometry * add ST_Intersects function test in system test on geometry * support to check expectedErrno in system test on geometry * adjust geomTest unit test and geometry system test * add geometry data type and functions in doc english version * implement touchesFunction() in geometry lib refactor geometry relation functions model * separate gemFuncTest into several src files * add unit test on touchesFunction * support sql function ST_Touches() add system test on ST_Touches * add docs for ST_Touches() * Add ST_Contains() * Add ST_Covers() * Add ST_Equals() * add swapAllowed param for geomRelationFunction() read geom2 earlier intead of at doGeosRelation() * Add ST_ContainsProperly() * build on windows * Merge from 3.0 to 3.0_geometry * change macro definition TSDB_DATA_TYPE_GEOMETRY as the last one for compatibility * change '\\NULL' to 'NULL' back in shellDumpFieldToFile() * add /usr/local/include into include directory * add /usr/local/inlcude and /usr/local/lib in cmake.platform for DARWIN
2023-05-24 07:36:46 +00:00
// need to call geosFreeBuffer(*output) later
2024-03-26 07:11:15 +00:00
static int parseGeometry(SToken* pToken, unsigned char** output, size_t* size) {
feat: support customized taos/taosd (#29736) * feat: support TDAcoreOS * chore: cmake options for TD_ACORE * chore: disable lemon for TD_ACORE * chore: add lzma2 and msvcregex * chore: cmake for lzma2 * chore: adapt for TD_ACORE * chore: adapt strcasecmp for TD_ACORE * chore: adapt for geos/threadName * chore: build adapt for TD_ACORE * chore: build adapt for TD_ACORE * chore: build adapt for TD_ACORE * chore: build adapt for TD_ACORE * chore: build adapt for TD_ACORE termio * chore: refact transComm.h for TD_ACORE * chore: refact transportInt.h for TD_ACORE * chore: refact trans.c for TD_ACORE * chore: refact trpc.h for TD_ACORE * chore: refact transCli.c/transComm.c/transSvr.c for TD_ACORE * chore: refact uv.h for TD_ACORE * chore: refact geosWrapper.h for TD_ACORE * chore: refact token/builtins/udf for TD_ACORE * chore: refact rocks for TD_ACORE * chore: refact tsdbCache.c for TD_ACORE, use LRU cache for last/last_row, not use rocksdb * chore: refact FAIL to _ERR to solve conflicts for TD_ACORE * chore: restore lemon.c/lempar.c * chore: support build lemon for TD_ACORE * chore: refact trpc and siginfo_t for TD_ACORE * chore: refact timezone for TD_ACORE * chore: refact lz4 for TD_ACORE * chore: refact TD_ACORE to make compile pass * chore: code optimization for TD_ASTRA * feat: support run taos with taosd integrated * feat: support invoke taos shell * feat: support invoke taos shell * feat: support invoke taos shell * chore: code optimization * chore: fix undefined reference problem os TD_ASTRA * chore: resolve compile problem for TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix getpid * chore: fix typo * chore: set stack size and ajust min pack size for TD_ASTRA * chore: fix pthread create parameters * chore: chmod adapt for TD_ASTRA * chore: fix trans compile problem * chore: adapt chmod for TD_ASTRA * chore: byte alignment for TD_ASTRA * chore: more code for adaption of TD_ASTRA * chore: more code for adaption of TD_ASTRA * chore: more code for adaption of TD_ASTRA * chore: byte alignment for TD_ASTRA * chore: conditional compile option * chore: adapt for TD_ASTRA * chore: adjust taosPId and msvcregex for TD_ASTRA * chore: log dir separator for wal build name * chore: fix type of pointer parameter * chore: fix compile problem of tsdbGetS3Size * enh: get last ver from wal log for TD_ASTRA * enh: refact wal meta ver * enh: refact wal meta ver * fix: typo of taosUcs4Compare * enh: process return value of CI * chore: more code for TD_ASTRA adaption * chore: return value of taosCloseFile in walMeta.c * chore: fix compile problem * chore: fix compile problem of TD_ASTRA * fix: update macro for tq and stream task * chore: code optimization for TD_ASTRA * chore: restore create log and init cfg interface * chore: restore strncasecmp and strcasecmp * fix: adjust the field position of SDataBlockInfo * fix: pragma pack min size * fix: pragma pack min size * chore: more code for TD_ASTRA adaption * fix: type of parameters * chore: adapt strncasecmp and strcasecmp for TD_ASTRA * chore: restore interface of init log * enh: pack push optimization * fix: taos init cfg * add astra support * fix: fetch the value of suid * chore: switch of build with udf * add temp code * chore: more code for TD_ASTRA adaption * chore: add macro ERRNO to replace errno * chore: bytes align for TD_ASTRA * fix: remove obsolete codes * enh: support USE_UDF macro * fix compile error * fix: resolve redefinition problem * fix: compile problem of log.cpp * fix: compile problem of osTimezone * fix: resolve compile problem of udf * fix: pragma definition on windows * fix: ucs4 and stpncpy for TD_ASTRA * fix: memory align problem for TD_ASTRA * enh: solve memory leak for TD_ASTRA_RPC * fix: compile problem of taosSetInt64Aligned * fix: restore mndSubscribe.c * fix: scalar for udf * chore: code adaption for TD_ASTRA * chore: code optimization for TD_ASTRA * fix: typo of add definition * fix: typo of macro in tudf.h * chore: remove void to make CI pass * enh: move macro from cmake.platform to cmake.options * enh: byte align for hash node and error code * chore: restore the size for lru cache * enh: restore some code about pack push * chore: restore the pack push in tmsg.h * fix: add macro of pack pop for windows --------- Co-authored-by: yihaoDeng <luomoxyz@126.com>
2025-03-14 05:32:13 +00:00
#ifdef USE_GEOS
Feature/3.0 geometry (#21037) * Add GEOMETRY data type and make sql.c able to parse it. The GEMETRY works like BINARY so far. * add GEOMETRY type into gConvertTypes to fix some issues like DELETE calling * change some test cases to make sure no same timestamp is inserted, and add my smoketest.sh * Add a function MakePoint() and introduce a lib geometry * implement sql functions GeomFromText() and AsText() * Use GEOS *_r funcions instead for thread safety * Handle with TSDB_DATA_TYPE_GEOMETRY when INSERT geometry data by converting WKT. Add geosWrapper to wrap the basic GEOS functions for TDEngine. * refactor AsText and MakePoint functions to be like GeomFromText * Show WKT when print geometry data in screen Dump hex data when dump geometry data in a file * define TYPE_BYTES item for TSDB_DATA_TYPE_GEOMETRY, which casued some strange issues. * set number of decimals of WKT to 6 * Implement SQL function Intersects() * refactor geometry sql functions * Add geosErrMsgeHandler() to get the GEOS error detail * use threadlocal to instantiate SGeosContext call destroyGeosContext() only if the thread exists * remove SGeosContext *context param for all geometry functions since we use thread local one, so that all caller do not need to know the context. * Modify Intersects() to call PreparedIntersects() when one of param is a constant, which has higher performance. * rename prepareFn() to initCtxFn() to avoid confusion with PreparedFn * Add prefix "ST_" for all geometry functions * move getThreadLocalGeosCtx() and destroyThreadLocalGeosCtx() into util, so that all unit test tools can compile * Add unit test for geometry lib, only test MakePoint so far * refactor and enhance existing cases in geomFuncTest * implement NULL type and NULL value test for geomFuncTest * add test on geomFromText() * add unit test on AsText() in geomFuncTest * combine some makePointFunction test items * add intersectsFunctionTwoColumns test refactor on callGeomFromTextWrapper functions * enhance intersectsFunction test to add cases like input constant , NULL type, NULL value, or wrong content * add more cases into intersectsFunction test * Add basic test on geometry in system test * Add ST_GeomFromText and ST_AsText function test in system test on geometry * add ST_Intersects function test in system test on geometry * support to check expectedErrno in system test on geometry * adjust geomTest unit test and geometry system test * add geometry data type and functions in doc english version * implement touchesFunction() in geometry lib refactor geometry relation functions model * separate gemFuncTest into several src files * add unit test on touchesFunction * support sql function ST_Touches() add system test on ST_Touches * add docs for ST_Touches() * Add ST_Contains() * Add ST_Covers() * Add ST_Equals() * add swapAllowed param for geomRelationFunction() read geom2 earlier intead of at doGeosRelation() * Add ST_ContainsProperly() * build on windows * Merge from 3.0 to 3.0_geometry * change macro definition TSDB_DATA_TYPE_GEOMETRY as the last one for compatibility * change '\\NULL' to 'NULL' back in shellDumpFieldToFile() * add /usr/local/include into include directory * add /usr/local/inlcude and /usr/local/lib in cmake.platform for DARWIN
2023-05-24 07:36:46 +00:00
int32_t code = TSDB_CODE_FAILED;
//[ToDo] support to parse WKB as well as WKT
if (pToken->type == TK_NK_STRING) {
code = initCtxGeomFromText();
if (code != TSDB_CODE_SUCCESS) {
return code;
}
code = doGeomFromText(pToken->z, output, size);
if (code != TSDB_CODE_SUCCESS) {
return code;
}
}
return code;
feat: support customized taos/taosd (#29736) * feat: support TDAcoreOS * chore: cmake options for TD_ACORE * chore: disable lemon for TD_ACORE * chore: add lzma2 and msvcregex * chore: cmake for lzma2 * chore: adapt for TD_ACORE * chore: adapt strcasecmp for TD_ACORE * chore: adapt for geos/threadName * chore: build adapt for TD_ACORE * chore: build adapt for TD_ACORE * chore: build adapt for TD_ACORE * chore: build adapt for TD_ACORE * chore: build adapt for TD_ACORE termio * chore: refact transComm.h for TD_ACORE * chore: refact transportInt.h for TD_ACORE * chore: refact trans.c for TD_ACORE * chore: refact trpc.h for TD_ACORE * chore: refact transCli.c/transComm.c/transSvr.c for TD_ACORE * chore: refact uv.h for TD_ACORE * chore: refact geosWrapper.h for TD_ACORE * chore: refact token/builtins/udf for TD_ACORE * chore: refact rocks for TD_ACORE * chore: refact tsdbCache.c for TD_ACORE, use LRU cache for last/last_row, not use rocksdb * chore: refact FAIL to _ERR to solve conflicts for TD_ACORE * chore: restore lemon.c/lempar.c * chore: support build lemon for TD_ACORE * chore: refact trpc and siginfo_t for TD_ACORE * chore: refact timezone for TD_ACORE * chore: refact lz4 for TD_ACORE * chore: refact TD_ACORE to make compile pass * chore: code optimization for TD_ASTRA * feat: support run taos with taosd integrated * feat: support invoke taos shell * feat: support invoke taos shell * feat: support invoke taos shell * chore: code optimization * chore: fix undefined reference problem os TD_ASTRA * chore: resolve compile problem for TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix getpid * chore: fix typo * chore: set stack size and ajust min pack size for TD_ASTRA * chore: fix pthread create parameters * chore: chmod adapt for TD_ASTRA * chore: fix trans compile problem * chore: adapt chmod for TD_ASTRA * chore: byte alignment for TD_ASTRA * chore: more code for adaption of TD_ASTRA * chore: more code for adaption of TD_ASTRA * chore: more code for adaption of TD_ASTRA * chore: byte alignment for TD_ASTRA * chore: conditional compile option * chore: adapt for TD_ASTRA * chore: adjust taosPId and msvcregex for TD_ASTRA * chore: log dir separator for wal build name * chore: fix type of pointer parameter * chore: fix compile problem of tsdbGetS3Size * enh: get last ver from wal log for TD_ASTRA * enh: refact wal meta ver * enh: refact wal meta ver * fix: typo of taosUcs4Compare * enh: process return value of CI * chore: more code for TD_ASTRA adaption * chore: return value of taosCloseFile in walMeta.c * chore: fix compile problem * chore: fix compile problem of TD_ASTRA * fix: update macro for tq and stream task * chore: code optimization for TD_ASTRA * chore: restore create log and init cfg interface * chore: restore strncasecmp and strcasecmp * fix: adjust the field position of SDataBlockInfo * fix: pragma pack min size * fix: pragma pack min size * chore: more code for TD_ASTRA adaption * fix: type of parameters * chore: adapt strncasecmp and strcasecmp for TD_ASTRA * chore: restore interface of init log * enh: pack push optimization * fix: taos init cfg * add astra support * fix: fetch the value of suid * chore: switch of build with udf * add temp code * chore: more code for TD_ASTRA adaption * chore: add macro ERRNO to replace errno * chore: bytes align for TD_ASTRA * fix: remove obsolete codes * enh: support USE_UDF macro * fix compile error * fix: resolve redefinition problem * fix: compile problem of log.cpp * fix: compile problem of osTimezone * fix: resolve compile problem of udf * fix: pragma definition on windows * fix: ucs4 and stpncpy for TD_ASTRA * fix: memory align problem for TD_ASTRA * enh: solve memory leak for TD_ASTRA_RPC * fix: compile problem of taosSetInt64Aligned * fix: restore mndSubscribe.c * fix: scalar for udf * chore: code adaption for TD_ASTRA * chore: code optimization for TD_ASTRA * fix: typo of add definition * fix: typo of macro in tudf.h * chore: remove void to make CI pass * enh: move macro from cmake.platform to cmake.options * enh: byte align for hash node and error code * chore: restore the size for lru cache * enh: restore some code about pack push * chore: restore the pack push in tmsg.h * fix: add macro of pack pop for windows --------- Co-authored-by: yihaoDeng <luomoxyz@126.com>
2025-03-14 05:32:13 +00:00
#else
TAOS_RETURN(TSDB_CODE_OPS_NOT_SUPPORT);
#endif
Feature/3.0 geometry (#21037) * Add GEOMETRY data type and make sql.c able to parse it. The GEMETRY works like BINARY so far. * add GEOMETRY type into gConvertTypes to fix some issues like DELETE calling * change some test cases to make sure no same timestamp is inserted, and add my smoketest.sh * Add a function MakePoint() and introduce a lib geometry * implement sql functions GeomFromText() and AsText() * Use GEOS *_r funcions instead for thread safety * Handle with TSDB_DATA_TYPE_GEOMETRY when INSERT geometry data by converting WKT. Add geosWrapper to wrap the basic GEOS functions for TDEngine. * refactor AsText and MakePoint functions to be like GeomFromText * Show WKT when print geometry data in screen Dump hex data when dump geometry data in a file * define TYPE_BYTES item for TSDB_DATA_TYPE_GEOMETRY, which casued some strange issues. * set number of decimals of WKT to 6 * Implement SQL function Intersects() * refactor geometry sql functions * Add geosErrMsgeHandler() to get the GEOS error detail * use threadlocal to instantiate SGeosContext call destroyGeosContext() only if the thread exists * remove SGeosContext *context param for all geometry functions since we use thread local one, so that all caller do not need to know the context. * Modify Intersects() to call PreparedIntersects() when one of param is a constant, which has higher performance. * rename prepareFn() to initCtxFn() to avoid confusion with PreparedFn * Add prefix "ST_" for all geometry functions * move getThreadLocalGeosCtx() and destroyThreadLocalGeosCtx() into util, so that all unit test tools can compile * Add unit test for geometry lib, only test MakePoint so far * refactor and enhance existing cases in geomFuncTest * implement NULL type and NULL value test for geomFuncTest * add test on geomFromText() * add unit test on AsText() in geomFuncTest * combine some makePointFunction test items * add intersectsFunctionTwoColumns test refactor on callGeomFromTextWrapper functions * enhance intersectsFunction test to add cases like input constant , NULL type, NULL value, or wrong content * add more cases into intersectsFunction test * Add basic test on geometry in system test * Add ST_GeomFromText and ST_AsText function test in system test on geometry * add ST_Intersects function test in system test on geometry * support to check expectedErrno in system test on geometry * adjust geomTest unit test and geometry system test * add geometry data type and functions in doc english version * implement touchesFunction() in geometry lib refactor geometry relation functions model * separate gemFuncTest into several src files * add unit test on touchesFunction * support sql function ST_Touches() add system test on ST_Touches * add docs for ST_Touches() * Add ST_Contains() * Add ST_Covers() * Add ST_Equals() * add swapAllowed param for geomRelationFunction() read geom2 earlier intead of at doGeosRelation() * Add ST_ContainsProperly() * build on windows * Merge from 3.0 to 3.0_geometry * change macro definition TSDB_DATA_TYPE_GEOMETRY as the last one for compatibility * change '\\NULL' to 'NULL' back in shellDumpFieldToFile() * add /usr/local/include into include directory * add /usr/local/inlcude and /usr/local/lib in cmake.platform for DARWIN
2023-05-24 07:36:46 +00:00
}
2024-03-26 07:11:15 +00:00
static int32_t parseVarbinary(SToken* pToken, uint8_t** pData, uint32_t* nData, int32_t bytes) {
if (pToken->type != TK_NK_STRING) {
2023-08-25 07:43:45 +00:00
return TSDB_CODE_PAR_INVALID_VARBINARY;
}
2024-03-26 07:11:15 +00:00
if (isHex(pToken->z + 1, pToken->n - 2)) {
if (!isValidateHex(pToken->z + 1, pToken->n - 2)) {
2023-08-25 07:43:45 +00:00
return TSDB_CODE_PAR_INVALID_VARBINARY;
}
2024-03-26 07:11:15 +00:00
void* data = NULL;
2023-08-25 07:43:45 +00:00
uint32_t size = 0;
2024-03-26 07:11:15 +00:00
if (taosHex2Ascii(pToken->z + 1, pToken->n - 2, &data, &size) < 0) {
2023-08-25 07:43:45 +00:00
return TSDB_CODE_OUT_OF_MEMORY;
}
if (size + VARSTR_HEADER_SIZE > bytes) {
taosMemoryFree(data);
return TSDB_CODE_PAR_VALUE_TOO_LONG;
}
*pData = data;
*nData = size;
2024-03-26 07:11:15 +00:00
} else {
*pData = taosMemoryCalloc(1, pToken->n);
2024-09-18 06:27:51 +00:00
if (!pData) return terrno;
int32_t len = trimString(pToken->z, pToken->n, *pData, pToken->n);
*nData = len;
if (*nData + VARSTR_HEADER_SIZE > bytes) {
2023-08-25 07:43:45 +00:00
return TSDB_CODE_PAR_VALUE_TOO_LONG;
}
}
return TSDB_CODE_SUCCESS;
}
2022-11-04 07:21:38 +00:00
static int32_t parseTagToken(const char** end, SToken* pToken, SSchema* pSchema, int16_t timePrec, STagVal* val,
SMsgBuf* pMsgBuf, timezone_t tz, void *charsetCxt) {
2022-05-11 11:03:59 +00:00
int64_t iv;
uint64_t uv;
char* endptr = NULL;
int32_t code = TSDB_CODE_SUCCESS;
2022-02-28 09:02:43 +00:00
#if 0
if (isNullValue(pSchema->type, pToken)) {
2022-02-28 09:02:43 +00:00
if (TSDB_DATA_TYPE_TIMESTAMP == pSchema->type && PRIMARYKEY_TIMESTAMP_COL_ID == pSchema->colId) {
2024-04-02 07:04:13 +00:00
return buildSyntaxErrMsg(pMsgBuf, "Primary timestamp column can not be null", pToken->z);
2022-02-28 09:02:43 +00:00
}
2022-11-04 07:21:38 +00:00
return TSDB_CODE_SUCCESS;
2022-02-28 09:02:43 +00:00
}
#endif
2022-02-28 09:02:43 +00:00
2022-11-04 07:21:38 +00:00
// strcpy(val->colName, pSchema->name);
val->cid = pSchema->colId;
val->type = pSchema->type;
2022-08-29 09:23:29 +00:00
2022-02-28 09:02:43 +00:00
switch (pSchema->type) {
case TSDB_DATA_TYPE_BOOL: {
if ((pToken->type == TK_NK_BOOL || pToken->type == TK_NK_STRING) && (pToken->n != 0)) {
2024-03-10 14:14:57 +00:00
if (IS_TRUE_STR(pToken->z, pToken->n)) {
2022-11-04 07:21:38 +00:00
*(int8_t*)(&val->i64) = TRUE_VALUE;
2024-03-10 14:14:57 +00:00
} else if (IS_FALSE_STR(pToken->z, pToken->n)) {
2022-11-04 07:21:38 +00:00
*(int8_t*)(&val->i64) = FALSE_VALUE;
2024-03-14 03:16:17 +00:00
} else if (TSDB_CODE_SUCCESS == toDoubleEx(pToken->z, pToken->n, pToken->type, (double*)&iv)) {
2024-03-15 05:16:42 +00:00
*(int8_t*)(&val->i64) = (*(double*)&iv == 0 ? FALSE_VALUE : TRUE_VALUE);
2022-02-28 09:02:43 +00:00
} else {
return buildSyntaxErrMsg(pMsgBuf, "invalid bool data", pToken->z);
}
} else if (pToken->type == TK_NK_INTEGER) {
2022-11-04 07:21:38 +00:00
*(int8_t*)(&val->i64) = ((taosStr2Int64(pToken->z, NULL, 10) == 0) ? FALSE_VALUE : TRUE_VALUE);
} else if (pToken->type == TK_NK_FLOAT) {
2022-11-04 07:21:38 +00:00
*(int8_t*)(&val->i64) = ((taosStr2Double(pToken->z, NULL) == 0) ? FALSE_VALUE : TRUE_VALUE);
2024-03-13 07:12:21 +00:00
} else if ((pToken->type == TK_NK_HEX || pToken->type == TK_NK_BIN) &&
(TSDB_CODE_SUCCESS == toDoubleEx(pToken->z, pToken->n, pToken->type, (double*)&iv))) {
2024-03-15 05:16:42 +00:00
*(int8_t*)(&val->i64) = (*(double*)&iv == 0 ? FALSE_VALUE : TRUE_VALUE);
2022-02-28 09:02:43 +00:00
} else {
return buildSyntaxErrMsg(pMsgBuf, "invalid bool data", pToken->z);
}
2022-11-04 07:21:38 +00:00
break;
2022-02-28 09:02:43 +00:00
}
case TSDB_DATA_TYPE_TINYINT: {
2023-12-01 15:44:05 +00:00
code = toIntegerEx(pToken->z, pToken->n, pToken->type, &iv);
2023-11-30 13:06:06 +00:00
if (TSDB_CODE_SUCCESS != code) {
2022-02-28 09:02:43 +00:00
return buildSyntaxErrMsg(pMsgBuf, "invalid tinyint data", pToken->z);
} else if (!IS_VALID_TINYINT(iv)) {
return buildSyntaxErrMsg(pMsgBuf, "tinyint data overflow", pToken->z);
}
2022-11-04 07:21:38 +00:00
*(int8_t*)(&val->i64) = iv;
break;
2022-02-28 09:02:43 +00:00
}
2022-04-19 02:18:11 +00:00
case TSDB_DATA_TYPE_UTINYINT: {
2023-12-01 15:44:05 +00:00
code = toUIntegerEx(pToken->z, pToken->n, pToken->type, &uv);
2023-11-30 13:06:06 +00:00
if (TSDB_CODE_SUCCESS != code) {
2022-02-28 09:02:43 +00:00
return buildSyntaxErrMsg(pMsgBuf, "invalid unsigned tinyint data", pToken->z);
2022-10-17 07:43:42 +00:00
} else if (uv > UINT8_MAX) {
2022-02-28 09:02:43 +00:00
return buildSyntaxErrMsg(pMsgBuf, "unsigned tinyint data overflow", pToken->z);
}
2022-11-04 07:21:38 +00:00
*(uint8_t*)(&val->i64) = uv;
break;
2022-02-28 09:02:43 +00:00
}
case TSDB_DATA_TYPE_SMALLINT: {
2023-12-01 15:44:05 +00:00
code = toIntegerEx(pToken->z, pToken->n, pToken->type, &iv);
2023-11-30 13:06:06 +00:00
if (TSDB_CODE_SUCCESS != code) {
2022-02-28 09:02:43 +00:00
return buildSyntaxErrMsg(pMsgBuf, "invalid smallint data", pToken->z);
} else if (!IS_VALID_SMALLINT(iv)) {
return buildSyntaxErrMsg(pMsgBuf, "smallint data overflow", pToken->z);
}
2022-11-04 07:21:38 +00:00
*(int16_t*)(&val->i64) = iv;
break;
2022-02-28 09:02:43 +00:00
}
case TSDB_DATA_TYPE_USMALLINT: {
2023-12-01 15:44:05 +00:00
code = toUIntegerEx(pToken->z, pToken->n, pToken->type, &uv);
2023-11-30 13:06:06 +00:00
if (TSDB_CODE_SUCCESS != code) {
2022-02-28 09:02:43 +00:00
return buildSyntaxErrMsg(pMsgBuf, "invalid unsigned smallint data", pToken->z);
2022-10-17 07:43:42 +00:00
} else if (uv > UINT16_MAX) {
2022-02-28 09:02:43 +00:00
return buildSyntaxErrMsg(pMsgBuf, "unsigned smallint data overflow", pToken->z);
}
2022-11-04 07:21:38 +00:00
*(uint16_t*)(&val->i64) = uv;
break;
2022-02-28 09:02:43 +00:00
}
case TSDB_DATA_TYPE_INT: {
2023-12-01 15:44:05 +00:00
code = toIntegerEx(pToken->z, pToken->n, pToken->type, &iv);
2023-11-30 13:06:06 +00:00
if (TSDB_CODE_SUCCESS != code) {
2022-02-28 09:02:43 +00:00
return buildSyntaxErrMsg(pMsgBuf, "invalid int data", pToken->z);
} else if (!IS_VALID_INT(iv)) {
return buildSyntaxErrMsg(pMsgBuf, "int data overflow", pToken->z);
}
2022-11-04 07:21:38 +00:00
*(int32_t*)(&val->i64) = iv;
break;
2022-02-28 09:02:43 +00:00
}
case TSDB_DATA_TYPE_UINT: {
2023-12-01 15:44:05 +00:00
code = toUIntegerEx(pToken->z, pToken->n, pToken->type, &uv);
2023-11-30 13:06:06 +00:00
if (TSDB_CODE_SUCCESS != code) {
2022-02-28 09:02:43 +00:00
return buildSyntaxErrMsg(pMsgBuf, "invalid unsigned int data", pToken->z);
2022-10-17 07:43:42 +00:00
} else if (uv > UINT32_MAX) {
2022-02-28 09:02:43 +00:00
return buildSyntaxErrMsg(pMsgBuf, "unsigned int data overflow", pToken->z);
}
2022-11-04 07:21:38 +00:00
*(uint32_t*)(&val->i64) = uv;
break;
2022-02-28 09:02:43 +00:00
}
case TSDB_DATA_TYPE_BIGINT: {
2023-12-01 15:44:05 +00:00
code = toIntegerEx(pToken->z, pToken->n, pToken->type, &iv);
2023-11-30 13:06:06 +00:00
if (TSDB_CODE_SUCCESS != code) {
2022-02-28 09:02:43 +00:00
return buildSyntaxErrMsg(pMsgBuf, "invalid bigint data", pToken->z);
}
2022-11-04 07:21:38 +00:00
val->i64 = iv;
break;
2022-02-28 09:02:43 +00:00
}
case TSDB_DATA_TYPE_UBIGINT: {
2023-12-01 15:44:05 +00:00
code = toUIntegerEx(pToken->z, pToken->n, pToken->type, &uv);
2023-11-30 13:06:06 +00:00
if (TSDB_CODE_SUCCESS != code) {
2022-02-28 09:02:43 +00:00
return buildSyntaxErrMsg(pMsgBuf, "invalid unsigned bigint data", pToken->z);
}
2022-11-04 07:21:38 +00:00
*(uint64_t*)(&val->i64) = uv;
break;
2022-02-28 09:02:43 +00:00
}
case TSDB_DATA_TYPE_FLOAT: {
double dv;
2023-12-01 15:44:05 +00:00
code = toDoubleEx(pToken->z, pToken->n, pToken->type, &dv);
if (TSDB_CODE_SUCCESS != code) {
2022-02-28 09:02:43 +00:00
return buildSyntaxErrMsg(pMsgBuf, "illegal float data", pToken->z);
}
2023-12-01 15:44:05 +00:00
if (dv > FLT_MAX || dv < -FLT_MAX || isinf(dv) || isnan(dv)) {
2022-02-28 09:02:43 +00:00
return buildSyntaxErrMsg(pMsgBuf, "illegal float data", pToken->z);
}
2022-11-04 07:21:38 +00:00
*(float*)(&val->i64) = dv;
break;
2022-02-28 09:02:43 +00:00
}
case TSDB_DATA_TYPE_DOUBLE: {
double dv;
2023-12-01 15:44:05 +00:00
code = toDoubleEx(pToken->z, pToken->n, pToken->type, &dv);
if (TSDB_CODE_SUCCESS != code) {
return buildSyntaxErrMsg(pMsgBuf, "illegal float data", pToken->z);
2022-02-28 09:02:43 +00:00
}
feat: support customized taos/taosd (#29736) * feat: support TDAcoreOS * chore: cmake options for TD_ACORE * chore: disable lemon for TD_ACORE * chore: add lzma2 and msvcregex * chore: cmake for lzma2 * chore: adapt for TD_ACORE * chore: adapt strcasecmp for TD_ACORE * chore: adapt for geos/threadName * chore: build adapt for TD_ACORE * chore: build adapt for TD_ACORE * chore: build adapt for TD_ACORE * chore: build adapt for TD_ACORE * chore: build adapt for TD_ACORE termio * chore: refact transComm.h for TD_ACORE * chore: refact transportInt.h for TD_ACORE * chore: refact trans.c for TD_ACORE * chore: refact trpc.h for TD_ACORE * chore: refact transCli.c/transComm.c/transSvr.c for TD_ACORE * chore: refact uv.h for TD_ACORE * chore: refact geosWrapper.h for TD_ACORE * chore: refact token/builtins/udf for TD_ACORE * chore: refact rocks for TD_ACORE * chore: refact tsdbCache.c for TD_ACORE, use LRU cache for last/last_row, not use rocksdb * chore: refact FAIL to _ERR to solve conflicts for TD_ACORE * chore: restore lemon.c/lempar.c * chore: support build lemon for TD_ACORE * chore: refact trpc and siginfo_t for TD_ACORE * chore: refact timezone for TD_ACORE * chore: refact lz4 for TD_ACORE * chore: refact TD_ACORE to make compile pass * chore: code optimization for TD_ASTRA * feat: support run taos with taosd integrated * feat: support invoke taos shell * feat: support invoke taos shell * feat: support invoke taos shell * chore: code optimization * chore: fix undefined reference problem os TD_ASTRA * chore: resolve compile problem for TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix getpid * chore: fix typo * chore: set stack size and ajust min pack size for TD_ASTRA * chore: fix pthread create parameters * chore: chmod adapt for TD_ASTRA * chore: fix trans compile problem * chore: adapt chmod for TD_ASTRA * chore: byte alignment for TD_ASTRA * chore: more code for adaption of TD_ASTRA * chore: more code for adaption of TD_ASTRA * chore: more code for adaption of TD_ASTRA * chore: byte alignment for TD_ASTRA * chore: conditional compile option * chore: adapt for TD_ASTRA * chore: adjust taosPId and msvcregex for TD_ASTRA * chore: log dir separator for wal build name * chore: fix type of pointer parameter * chore: fix compile problem of tsdbGetS3Size * enh: get last ver from wal log for TD_ASTRA * enh: refact wal meta ver * enh: refact wal meta ver * fix: typo of taosUcs4Compare * enh: process return value of CI * chore: more code for TD_ASTRA adaption * chore: return value of taosCloseFile in walMeta.c * chore: fix compile problem * chore: fix compile problem of TD_ASTRA * fix: update macro for tq and stream task * chore: code optimization for TD_ASTRA * chore: restore create log and init cfg interface * chore: restore strncasecmp and strcasecmp * fix: adjust the field position of SDataBlockInfo * fix: pragma pack min size * fix: pragma pack min size * chore: more code for TD_ASTRA adaption * fix: type of parameters * chore: adapt strncasecmp and strcasecmp for TD_ASTRA * chore: restore interface of init log * enh: pack push optimization * fix: taos init cfg * add astra support * fix: fetch the value of suid * chore: switch of build with udf * add temp code * chore: more code for TD_ASTRA adaption * chore: add macro ERRNO to replace errno * chore: bytes align for TD_ASTRA * fix: remove obsolete codes * enh: support USE_UDF macro * fix compile error * fix: resolve redefinition problem * fix: compile problem of log.cpp * fix: compile problem of osTimezone * fix: resolve compile problem of udf * fix: pragma definition on windows * fix: ucs4 and stpncpy for TD_ASTRA * fix: memory align problem for TD_ASTRA * enh: solve memory leak for TD_ASTRA_RPC * fix: compile problem of taosSetInt64Aligned * fix: restore mndSubscribe.c * fix: scalar for udf * chore: code adaption for TD_ASTRA * chore: code optimization for TD_ASTRA * fix: typo of add definition * fix: typo of macro in tudf.h * chore: remove void to make CI pass * enh: move macro from cmake.platform to cmake.options * enh: byte align for hash node and error code * chore: restore the size for lru cache * enh: restore some code about pack push * chore: restore the pack push in tmsg.h * fix: add macro of pack pop for windows --------- Co-authored-by: yihaoDeng <luomoxyz@126.com>
2025-03-14 05:32:13 +00:00
if (((dv == HUGE_VAL || dv == -HUGE_VAL) && ERRNO == ERANGE) || isinf(dv) || isnan(dv)) {
2022-02-28 09:02:43 +00:00
return buildSyntaxErrMsg(pMsgBuf, "illegal double data", pToken->z);
}
2022-11-04 07:21:38 +00:00
*(double*)(&val->i64) = dv;
break;
2022-02-28 09:02:43 +00:00
}
case TSDB_DATA_TYPE_BINARY: {
2022-02-28 09:02:43 +00:00
// Too long values will raise the invalid sql error message
if (pToken->n + VARSTR_HEADER_SIZE > pSchema->bytes) {
2022-05-26 10:00:44 +00:00
return generateSyntaxErrMsg(pMsgBuf, TSDB_CODE_PAR_VALUE_TOO_LONG, pSchema->name);
2022-02-28 09:02:43 +00:00
}
val->pData = taosStrdup(pToken->z);
2024-09-18 06:27:51 +00:00
if (!val->pData) {
return terrno;
}
2022-11-04 07:21:38 +00:00
val->nData = pToken->n;
break;
2022-02-28 09:02:43 +00:00
}
2023-08-15 05:57:05 +00:00
case TSDB_DATA_TYPE_VARBINARY: {
2023-08-25 07:43:45 +00:00
code = parseVarbinary(pToken, &val->pData, &val->nData, pSchema->bytes);
2024-03-26 07:11:15 +00:00
if (code != TSDB_CODE_SUCCESS) {
2023-08-25 07:43:45 +00:00
return generateSyntaxErrMsg(pMsgBuf, code, pSchema->name);
2023-08-16 11:05:07 +00:00
}
2023-08-15 05:57:05 +00:00
break;
}
case TSDB_DATA_TYPE_GEOMETRY: {
unsigned char* output = NULL;
size_t size = 0;
code = parseGeometry(pToken, &output, &size);
if (code != TSDB_CODE_SUCCESS) {
2024-08-21 07:45:57 +00:00
code = buildSyntaxErrMsg(pMsgBuf, getGeosErrMsg(code), pToken->z);
} else if (size + VARSTR_HEADER_SIZE > pSchema->bytes) {
// Too long values will raise the invalid sql error message
code = generateSyntaxErrMsg(pMsgBuf, TSDB_CODE_PAR_VALUE_TOO_LONG, pSchema->name);
} else {
val->pData = taosMemoryMalloc(size);
if (NULL == val->pData) {
2024-09-20 09:48:04 +00:00
code = terrno;
} else {
memcpy(val->pData, output, size);
val->nData = size;
}
}
geosFreeBuffer(output);
break;
}
2022-02-28 09:02:43 +00:00
case TSDB_DATA_TYPE_NCHAR: {
2022-11-04 07:21:38 +00:00
int32_t output = 0;
2024-04-10 02:23:48 +00:00
int64_t realLen = pToken->n << 2;
if (realLen > pSchema->bytes - VARSTR_HEADER_SIZE) realLen = pSchema->bytes - VARSTR_HEADER_SIZE;
void* p = taosMemoryMalloc(realLen);
2022-11-04 07:21:38 +00:00
if (p == NULL) {
2024-09-20 09:48:04 +00:00
return terrno;
2022-11-04 07:21:38 +00:00
}
if (!taosMbsToUcs4(pToken->z, pToken->n, (TdUcs4*)(p), realLen, &output, charsetCxt)) {
2024-09-12 06:02:19 +00:00
if (terrno == TAOS_SYSTEM_ERROR(E2BIG)) {
2022-11-04 07:21:38 +00:00
taosMemoryFree(p);
return generateSyntaxErrMsg(pMsgBuf, TSDB_CODE_PAR_VALUE_TOO_LONG, pSchema->name);
}
char buf[512] = {0};
feat: support customized taos/taosd (#29736) * feat: support TDAcoreOS * chore: cmake options for TD_ACORE * chore: disable lemon for TD_ACORE * chore: add lzma2 and msvcregex * chore: cmake for lzma2 * chore: adapt for TD_ACORE * chore: adapt strcasecmp for TD_ACORE * chore: adapt for geos/threadName * chore: build adapt for TD_ACORE * chore: build adapt for TD_ACORE * chore: build adapt for TD_ACORE * chore: build adapt for TD_ACORE * chore: build adapt for TD_ACORE termio * chore: refact transComm.h for TD_ACORE * chore: refact transportInt.h for TD_ACORE * chore: refact trans.c for TD_ACORE * chore: refact trpc.h for TD_ACORE * chore: refact transCli.c/transComm.c/transSvr.c for TD_ACORE * chore: refact uv.h for TD_ACORE * chore: refact geosWrapper.h for TD_ACORE * chore: refact token/builtins/udf for TD_ACORE * chore: refact rocks for TD_ACORE * chore: refact tsdbCache.c for TD_ACORE, use LRU cache for last/last_row, not use rocksdb * chore: refact FAIL to _ERR to solve conflicts for TD_ACORE * chore: restore lemon.c/lempar.c * chore: support build lemon for TD_ACORE * chore: refact trpc and siginfo_t for TD_ACORE * chore: refact timezone for TD_ACORE * chore: refact lz4 for TD_ACORE * chore: refact TD_ACORE to make compile pass * chore: code optimization for TD_ASTRA * feat: support run taos with taosd integrated * feat: support invoke taos shell * feat: support invoke taos shell * feat: support invoke taos shell * chore: code optimization * chore: fix undefined reference problem os TD_ASTRA * chore: resolve compile problem for TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix undefined reference problem os TD_ASTRA * chore: fix getpid * chore: fix typo * chore: set stack size and ajust min pack size for TD_ASTRA * chore: fix pthread create parameters * chore: chmod adapt for TD_ASTRA * chore: fix trans compile problem * chore: adapt chmod for TD_ASTRA * chore: byte alignment for TD_ASTRA * chore: more code for adaption of TD_ASTRA * chore: more code for adaption of TD_ASTRA * chore: more code for adaption of TD_ASTRA * chore: byte alignment for TD_ASTRA * chore: conditional compile option * chore: adapt for TD_ASTRA * chore: adjust taosPId and msvcregex for TD_ASTRA * chore: log dir separator for wal build name * chore: fix type of pointer parameter * chore: fix compile problem of tsdbGetS3Size * enh: get last ver from wal log for TD_ASTRA * enh: refact wal meta ver * enh: refact wal meta ver * fix: typo of taosUcs4Compare * enh: process return value of CI * chore: more code for TD_ASTRA adaption * chore: return value of taosCloseFile in walMeta.c * chore: fix compile problem * chore: fix compile problem of TD_ASTRA * fix: update macro for tq and stream task * chore: code optimization for TD_ASTRA * chore: restore create log and init cfg interface * chore: restore strncasecmp and strcasecmp * fix: adjust the field position of SDataBlockInfo * fix: pragma pack min size * fix: pragma pack min size * chore: more code for TD_ASTRA adaption * fix: type of parameters * chore: adapt strncasecmp and strcasecmp for TD_ASTRA * chore: restore interface of init log * enh: pack push optimization * fix: taos init cfg * add astra support * fix: fetch the value of suid * chore: switch of build with udf * add temp code * chore: more code for TD_ASTRA adaption * chore: add macro ERRNO to replace errno * chore: bytes align for TD_ASTRA * fix: remove obsolete codes * enh: support USE_UDF macro * fix compile error * fix: resolve redefinition problem * fix: compile problem of log.cpp * fix: compile problem of osTimezone * fix: resolve compile problem of udf * fix: pragma definition on windows * fix: ucs4 and stpncpy for TD_ASTRA * fix: memory align problem for TD_ASTRA * enh: solve memory leak for TD_ASTRA_RPC * fix: compile problem of taosSetInt64Aligned * fix: restore mndSubscribe.c * fix: scalar for udf * chore: code adaption for TD_ASTRA * chore: code optimization for TD_ASTRA * fix: typo of add definition * fix: typo of macro in tudf.h * chore: remove void to make CI pass * enh: move macro from cmake.platform to cmake.options * enh: byte align for hash node and error code * chore: restore the size for lru cache * enh: restore some code about pack push * chore: restore the pack push in tmsg.h * fix: add macro of pack pop for windows --------- Co-authored-by: yihaoDeng <luomoxyz@126.com>
2025-03-14 05:32:13 +00:00
snprintf(buf, tListLen(buf), " taosMbsToUcs4 error:%s %d %d", strerror(terrno), ERRNO, EILSEQ);
2022-11-04 07:21:38 +00:00
taosMemoryFree(p);
return buildSyntaxErrMsg(pMsgBuf, buf, pToken->z);
}
2022-11-04 07:21:38 +00:00
val->pData = p;
val->nData = output;
break;
}
2022-02-28 09:02:43 +00:00
case TSDB_DATA_TYPE_TIMESTAMP: {
2024-11-22 10:31:51 +00:00
if (parseTime(end, pToken, timePrec, &iv, pMsgBuf, tz) != TSDB_CODE_SUCCESS) {
2022-02-28 09:02:43 +00:00
return buildSyntaxErrMsg(pMsgBuf, "invalid timestamp", pToken->z);
}
2022-11-04 07:21:38 +00:00
val->i64 = iv;
break;
2022-02-28 09:02:43 +00:00
}
}
return code;
2022-02-28 09:02:43 +00:00
}
2022-11-04 07:21:38 +00:00
// input pStmt->pSql: [(tag1_name, ...)] TAGS (tag1_value, ...) ...
// output pStmt->pSql: TAGS (tag1_value, ...) ...
2022-12-20 08:53:08 +00:00
static int32_t parseBoundTagsClause(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt) {
2024-07-23 07:59:10 +00:00
int32_t code = insInitBoundColsInfo(getNumOfTags(pStmt->pTableMeta), &pCxt->tags);
if (TSDB_CODE_SUCCESS != code) {
return code;
}
2022-11-04 07:21:38 +00:00
SToken token;
int32_t index = 0;
NEXT_TOKEN_KEEP_SQL(pStmt->pSql, token, index);
if (TK_NK_LP != token.type) {
return TSDB_CODE_SUCCESS;
}
2022-11-04 07:21:38 +00:00
pStmt->pSql += index;
return parseBoundColumns(pCxt, &pStmt->pSql, BOUND_TAGS, pStmt->pTableMeta, &pCxt->tags);
2022-11-04 07:21:38 +00:00
}
2024-03-10 14:14:57 +00:00
int32_t parseTagValue(SMsgBuf* pMsgBuf, const char** pSql, uint8_t precision, SSchema* pTagSchema, SToken* pToken,
SArray* pTagName, SArray* pTagVals, STag** pTag, timezone_t tz, void *charsetCxt) {
2023-12-04 12:08:46 +00:00
bool isNull = isNullValue(pTagSchema->type, pToken);
2024-03-10 14:14:57 +00:00
if (!isNull && pTagName) {
2024-07-23 07:59:10 +00:00
if (NULL == taosArrayPush(pTagName, pTagSchema->name)) {
2024-09-20 09:48:04 +00:00
return terrno;
2024-07-23 07:59:10 +00:00
}
2022-11-04 07:21:38 +00:00
}
if (pTagSchema->type == TSDB_DATA_TYPE_JSON) {
if (pToken->n > (TSDB_MAX_JSON_TAG_LEN - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE) {
2024-03-10 14:14:57 +00:00
return buildSyntaxErrMsg(pMsgBuf, "json string too long than 4095", pToken->z);
}
2023-12-04 12:08:46 +00:00
if (isNull) {
2022-11-04 07:21:38 +00:00
return tTagNew(pTagVals, 1, true, pTag);
} else {
return parseJsontoTagData(pToken->z, pTagVals, pTag, pMsgBuf, charsetCxt);
2022-11-04 07:21:38 +00:00
}
}
2023-12-04 12:08:46 +00:00
if (isNull) return 0;
2022-11-04 07:21:38 +00:00
STagVal val = {0};
int32_t code = parseTagToken(pSql, pToken, pTagSchema, precision, &val, pMsgBuf, tz, charsetCxt);
2022-11-04 07:21:38 +00:00
if (TSDB_CODE_SUCCESS == code) {
if (NULL == taosArrayPush(pTagVals, &val)) {
2024-09-20 09:48:04 +00:00
code = terrno;
2024-07-23 07:59:10 +00:00
}
2022-11-04 07:21:38 +00:00
}
return code;
}
2022-12-23 09:50:05 +00:00
static int32_t buildCreateTbReq(SVnodeModifyOpStmt* pStmt, STag* pTag, SArray* pTagName) {
2023-11-28 17:53:13 +00:00
if (pStmt->pCreateTblReq) {
tdDestroySVCreateTbReq(pStmt->pCreateTblReq);
taosMemoryFreeClear(pStmt->pCreateTblReq);
}
2022-11-28 02:43:55 +00:00
pStmt->pCreateTblReq = taosMemoryCalloc(1, sizeof(SVCreateTbReq));
if (NULL == pStmt->pCreateTblReq) {
2024-09-10 10:42:00 +00:00
return terrno;
2022-11-28 02:43:55 +00:00
}
2024-09-18 06:27:51 +00:00
return insBuildCreateTbReq(pStmt->pCreateTblReq, pStmt->targetTableName.tname, pTag, pStmt->pTableMeta->suid,
pStmt->usingTableName.tname, pTagName, pStmt->pTableMeta->tableInfo.numOfTags,
TSDB_DEFAULT_TABLE_TTL);
2022-11-04 07:21:38 +00:00
}
2024-03-10 14:14:57 +00:00
int32_t checkAndTrimValue(SToken* pToken, char* tmpTokenBuf, SMsgBuf* pMsgBuf, int8_t type) {
if (pToken->type == TK_NK_QUESTION) {
return buildInvalidOperationMsg(pMsgBuf, "insert into super table syntax is not supported for stmt");
}
2022-11-04 07:21:38 +00:00
if ((pToken->type != TK_NOW && pToken->type != TK_TODAY && pToken->type != TK_NK_INTEGER &&
pToken->type != TK_NK_STRING && pToken->type != TK_NK_FLOAT && pToken->type != TK_NK_BOOL &&
2024-03-26 07:11:15 +00:00
pToken->type != TK_NULL && pToken->type != TK_NK_HEX && pToken->type != TK_NK_OCT && pToken->type != TK_NK_BIN &&
pToken->type != TK_NK_VARIABLE) ||
2022-11-04 07:21:38 +00:00
(pToken->n == 0) || (pToken->type == TK_NK_RP)) {
return buildSyntaxErrMsg(pMsgBuf, "invalid data or symbol", pToken->z);
}
// Remove quotation marks
if (TK_NK_STRING == pToken->type && type != TSDB_DATA_TYPE_VARBINARY) {
2022-11-04 07:21:38 +00:00
if (pToken->n >= TSDB_MAX_BYTES_PER_ROW) {
return buildSyntaxErrMsg(pMsgBuf, "too long string", pToken->z);
}
2022-11-04 07:21:38 +00:00
int32_t len = trimString(pToken->z, pToken->n, tmpTokenBuf, TSDB_MAX_BYTES_PER_ROW);
pToken->z = tmpTokenBuf;
pToken->n = len;
}
return TSDB_CODE_SUCCESS;
}
typedef struct SRewriteTagCondCxt {
SArray* pTagVals;
SArray* pTagName;
int32_t code;
} SRewriteTagCondCxt;
static int32_t rewriteTagCondColumnImpl(STagVal* pVal, SNode** pNode) {
2024-07-21 10:20:30 +00:00
SValueNode* pValue = NULL;
int32_t code = nodesMakeNode(QUERY_NODE_VALUE, (SNode**)&pValue);
if (NULL == pValue) {
2024-07-21 10:20:30 +00:00
return code;
}
2023-04-25 09:39:28 +00:00
pValue->node.resType = ((SColumnNode*)*pNode)->node.resType;
nodesDestroyNode(*pNode);
*pNode = (SNode*)pValue;
switch (pVal->type) {
case TSDB_DATA_TYPE_BOOL:
pValue->datum.b = *(int8_t*)(&pVal->i64);
2023-04-25 09:39:28 +00:00
*(bool*)&pValue->typeData = pValue->datum.b;
break;
case TSDB_DATA_TYPE_TINYINT:
pValue->datum.i = *(int8_t*)(&pVal->i64);
2023-04-25 09:39:28 +00:00
*(int8_t*)&pValue->typeData = pValue->datum.i;
break;
case TSDB_DATA_TYPE_SMALLINT:
pValue->datum.i = *(int16_t*)(&pVal->i64);
2023-04-25 09:39:28 +00:00
*(int16_t*)&pValue->typeData = pValue->datum.i;
break;
case TSDB_DATA_TYPE_INT:
pValue->datum.i = *(int32_t*)(&pVal->i64);
2023-04-25 09:39:28 +00:00
*(int32_t*)&pValue->typeData = pValue->datum.i;
break;
case TSDB_DATA_TYPE_BIGINT:
pValue->datum.i = pVal->i64;
2023-04-25 09:39:28 +00:00
pValue->typeData = pValue->datum.i;
break;
case TSDB_DATA_TYPE_FLOAT:
pValue->datum.d = *(float*)(&pVal->i64);
2023-04-25 09:39:28 +00:00
*(float*)&pValue->typeData = pValue->datum.d;
break;
case TSDB_DATA_TYPE_DOUBLE:
pValue->datum.d = *(double*)(&pVal->i64);
2023-04-25 09:39:28 +00:00
*(double*)&pValue->typeData = pValue->datum.d;
break;
case TSDB_DATA_TYPE_VARCHAR:
2023-08-16 11:05:07 +00:00
case TSDB_DATA_TYPE_VARBINARY:
case TSDB_DATA_TYPE_NCHAR:
pValue->datum.p = taosMemoryCalloc(1, pVal->nData + VARSTR_HEADER_SIZE);
if (NULL == pValue->datum.p) {
2024-09-10 10:42:00 +00:00
return terrno;
}
varDataSetLen(pValue->datum.p, pVal->nData);
memcpy(varDataVal(pValue->datum.p), pVal->pData, pVal->nData);
break;
case TSDB_DATA_TYPE_TIMESTAMP:
pValue->datum.i = pVal->i64;
2023-04-25 09:39:28 +00:00
pValue->typeData = pValue->datum.i;
break;
case TSDB_DATA_TYPE_UTINYINT:
pValue->datum.i = *(uint8_t*)(&pVal->i64);
2023-04-25 09:39:28 +00:00
*(uint8_t*)&pValue->typeData = pValue->datum.i;
break;
case TSDB_DATA_TYPE_USMALLINT:
pValue->datum.i = *(uint16_t*)(&pVal->i64);
2023-04-25 09:39:28 +00:00
*(uint16_t*)&pValue->typeData = pValue->datum.i;
break;
case TSDB_DATA_TYPE_UINT:
pValue->datum.i = *(uint32_t*)(&pVal->i64);
2023-04-25 09:39:28 +00:00
*(uint32_t*)&pValue->typeData = pValue->datum.i;
break;
case TSDB_DATA_TYPE_UBIGINT:
pValue->datum.i = *(uint64_t*)(&pVal->i64);
2023-04-25 09:39:28 +00:00
*(uint64_t*)&pValue->typeData = pValue->datum.i;
break;
case TSDB_DATA_TYPE_JSON:
case TSDB_DATA_TYPE_DECIMAL:
case TSDB_DATA_TYPE_BLOB:
case TSDB_DATA_TYPE_MEDIUMBLOB:
default:
return TSDB_CODE_FAILED;
}
return TSDB_CODE_SUCCESS;
}
static int32_t rewriteTagCondColumn(SArray* pTagVals, SArray* pTagName, SNode** pNode) {
SColumnNode* pCol = (SColumnNode*)*pNode;
int32_t ntags = taosArrayGetSize(pTagName);
for (int32_t i = 0; i < ntags; ++i) {
char* pTagColName = taosArrayGet(pTagName, i);
if (0 == strcmp(pTagColName, pCol->colName)) {
return rewriteTagCondColumnImpl(taosArrayGet(pTagVals, i), pNode);
}
}
return TSDB_CODE_PAR_PERMISSION_DENIED;
}
static EDealRes rewriteTagCond(SNode** pNode, void* pContext) {
if (QUERY_NODE_COLUMN == nodeType(*pNode)) {
SRewriteTagCondCxt* pCxt = pContext;
pCxt->code = rewriteTagCondColumn(pCxt->pTagVals, pCxt->pTagName, pNode);
return (TSDB_CODE_SUCCESS == pCxt->code ? DEAL_RES_IGNORE_CHILD : DEAL_RES_ERROR);
}
return DEAL_RES_CONTINUE;
}
static int32_t setTagVal(SArray* pTagVals, SArray* pTagName, SNode* pCond) {
SRewriteTagCondCxt cxt = {.code = TSDB_CODE_SUCCESS, .pTagVals = pTagVals, .pTagName = pTagName};
nodesRewriteExpr(&pCond, rewriteTagCond, &cxt);
return cxt.code;
}
static int32_t checkTagCondResult(SNode* pResult) {
return (QUERY_NODE_VALUE == nodeType(pResult) && ((SValueNode*)pResult)->datum.b) ? TSDB_CODE_SUCCESS
: TSDB_CODE_PAR_PERMISSION_DENIED;
}
2023-04-25 09:39:28 +00:00
static int32_t checkSubtablePrivilege(SArray* pTagVals, SArray* pTagName, SNode** pCond) {
int32_t code = setTagVal(pTagVals, pTagName, *pCond);
if (TSDB_CODE_SUCCESS == code) {
2023-04-25 09:39:28 +00:00
code = scalarCalculateConstants(*pCond, pCond);
}
if (TSDB_CODE_SUCCESS == code) {
2023-04-25 09:39:28 +00:00
code = checkTagCondResult(*pCond);
}
2023-04-25 09:39:28 +00:00
NODES_DESTORY_NODE(*pCond);
return code;
}
2022-11-04 07:21:38 +00:00
// pSql -> tag1_value, ...)
static int32_t parseTagsClauseImpl(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt, bool autoCreate) {
2022-11-04 07:21:38 +00:00
int32_t code = TSDB_CODE_SUCCESS;
SSchema* pSchema = getTableTagSchema(pStmt->pTableMeta);
2024-03-10 14:14:57 +00:00
SArray* pTagVals = NULL;
SArray* pTagName = NULL;
uint8_t precision = pStmt->pTableMeta->tableInfo.precision;
2022-11-04 07:21:38 +00:00
SToken token;
bool isParseBindParam = false;
bool isJson = false;
STag* pTag = NULL;
2024-03-10 14:14:57 +00:00
if (!(pTagVals = taosArrayInit(pCxt->tags.numOfBound, sizeof(STagVal))) ||
!(pTagName = taosArrayInit(pCxt->tags.numOfBound, TSDB_COL_NAME_LEN))) {
2024-09-20 09:48:04 +00:00
code = terrno;
goto _exit;
2024-03-10 14:14:57 +00:00
}
2022-11-04 07:21:38 +00:00
for (int i = 0; TSDB_CODE_SUCCESS == code && i < pCxt->tags.numOfBound; ++i) {
NEXT_TOKEN_WITH_PREV(pStmt->pSql, token);
if (token.type == TK_NK_QUESTION) {
isParseBindParam = true;
if (NULL == pCxt->pComCxt->pStmtCb) {
code = buildSyntaxErrMsg(&pCxt->msg, "? only used in stmt", token.z);
break;
}
if (pTagVals->size != 0) {
code = buildSyntaxErrMsg(&pCxt->msg, "no mix usage for ? and tag values", token.z);
break;
}
2022-11-04 07:21:38 +00:00
continue;
}
2022-11-04 07:21:38 +00:00
if (isParseBindParam) {
code = buildInvalidOperationMsg(&pCxt->msg, "no mix usage for ? and tag values");
break;
}
2022-11-04 07:21:38 +00:00
2022-11-27 09:09:02 +00:00
SSchema* pTagSchema = &pSchema[pCxt->tags.pColIndex[i]];
2022-11-04 07:21:38 +00:00
isJson = pTagSchema->type == TSDB_DATA_TYPE_JSON;
code = checkAndTrimValue(&token, pCxt->tmpTokenBuf, &pCxt->msg, pTagSchema->type);
2024-03-10 14:14:57 +00:00
if (TSDB_CODE_SUCCESS == code && TK_NK_VARIABLE == token.type) {
code = buildSyntaxErrMsg(&pCxt->msg, "not expected tags values ", token.z);
}
2022-11-04 07:21:38 +00:00
if (TSDB_CODE_SUCCESS == code) {
code = parseTagValue(&pCxt->msg, &pStmt->pSql, precision, pTagSchema, &token, pTagName, pTagVals, &pTag, pCxt->pComCxt->timezone, pCxt->pComCxt->charsetCxt);
}
}
2023-04-25 09:39:28 +00:00
if (TSDB_CODE_SUCCESS == code && NULL != pStmt->pTagCond) {
code = checkSubtablePrivilege(pTagVals, pTagName, &pStmt->pTagCond);
}
2022-11-04 07:21:38 +00:00
if (TSDB_CODE_SUCCESS == code && !isParseBindParam && !isJson) {
code = tTagNew(pTagVals, 1, false, &pTag);
}
if (TSDB_CODE_SUCCESS == code && !isParseBindParam && !autoCreate) {
2022-11-28 02:43:55 +00:00
code = buildCreateTbReq(pStmt, pTag, pTagName);
2022-11-04 07:21:38 +00:00
pTag = NULL;
}
if (code == TSDB_CODE_SUCCESS && !isParseBindParam) {
pCxt->stmtTbNameFlag |= IS_FIXED_TAG;
}
_exit:
2024-03-18 10:06:18 +00:00
for (int32_t i = 0; i < taosArrayGetSize(pTagVals); ++i) {
2024-03-10 14:14:57 +00:00
STagVal* p = (STagVal*)TARRAY_GET_ELEM(pTagVals, i);
2022-11-04 07:21:38 +00:00
if (IS_VAR_DATA_TYPE(p->type)) {
taosMemoryFreeClear(p->pData);
}
2022-11-04 07:21:38 +00:00
}
taosArrayDestroy(pTagVals);
taosArrayDestroy(pTagName);
tTagFree(pTag);
return code;
}
// input pStmt->pSql: TAGS (tag1_value, ...) [table_options] ...
// output pStmt->pSql: [table_options] ...
static int32_t parseTagsClause(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt, bool autoCreate) {
2022-11-04 07:21:38 +00:00
SToken token;
NEXT_TOKEN(pStmt->pSql, token);
if (TK_TAGS != token.type) {
return buildSyntaxErrMsg(&pCxt->msg, "TAGS is expected", token.z);
}
NEXT_TOKEN(pStmt->pSql, token);
if (TK_NK_LP != token.type) {
return buildSyntaxErrMsg(&pCxt->msg, "( is expected", token.z);
}
int32_t code = parseTagsClauseImpl(pCxt, pStmt, autoCreate);
2022-11-04 07:21:38 +00:00
if (TSDB_CODE_SUCCESS == code) {
NEXT_VALID_TOKEN(pStmt->pSql, token);
if (TK_NK_COMMA == token.type) {
code = generateSyntaxErrMsg(&pCxt->msg, TSDB_CODE_PAR_TAGS_NOT_MATCHED);
} else if (TK_NK_RP != token.type) {
code = buildSyntaxErrMsg(&pCxt->msg, ") is expected", token.z);
}
}
2022-11-04 07:21:38 +00:00
return code;
}
static int32_t storeChildTableMeta(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt) {
2022-11-04 10:01:39 +00:00
pStmt->pTableMeta->suid = pStmt->pTableMeta->uid;
2022-11-04 07:21:38 +00:00
pStmt->pTableMeta->uid = pStmt->totalTbNum;
pStmt->pTableMeta->tableType = TSDB_CHILD_TABLE;
STableMeta* pBackup = NULL;
if (TSDB_CODE_SUCCESS != cloneTableMeta(pStmt->pTableMeta, &pBackup)) {
return TSDB_CODE_OUT_OF_MEMORY;
}
char tbFName[TSDB_TABLE_FNAME_LEN];
2024-07-23 07:59:10 +00:00
int32_t code = tNameExtractFullName(&pStmt->targetTableName, tbFName);
if (TSDB_CODE_SUCCESS != code) {
taosMemoryFree(pBackup);
return code;
}
code = taosHashPut(pStmt->pSubTableHashObj, tbFName, strlen(tbFName), &pBackup, POINTER_BYTES);
if (TSDB_CODE_SUCCESS != code) {
taosMemoryFree(pBackup);
}
return code;
2022-11-04 07:21:38 +00:00
}
2022-12-20 08:53:08 +00:00
static int32_t parseTableOptions(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt) {
2022-11-04 07:21:38 +00:00
do {
int32_t index = 0;
SToken token;
NEXT_TOKEN_KEEP_SQL(pStmt->pSql, token, index);
if (TK_TTL == token.type) {
pStmt->pSql += index;
NEXT_TOKEN_WITH_PREV(pStmt->pSql, token);
if (TK_NK_INTEGER != token.type) {
return buildSyntaxErrMsg(&pCxt->msg, "Invalid option ttl", token.z);
}
2022-11-27 09:09:02 +00:00
pStmt->pCreateTblReq->ttl = taosStr2Int32(token.z, NULL, 10);
if (pStmt->pCreateTblReq->ttl < 0) {
2022-11-04 07:21:38 +00:00
return buildSyntaxErrMsg(&pCxt->msg, "Invalid option ttl", token.z);
}
} else if (TK_COMMENT == token.type) {
pStmt->pSql += index;
NEXT_TOKEN(pStmt->pSql, token);
if (TK_NK_STRING != token.type) {
return buildSyntaxErrMsg(&pCxt->msg, "Invalid option comment", token.z);
}
if (token.n >= TSDB_TB_COMMENT_LEN) {
return buildSyntaxErrMsg(&pCxt->msg, "comment too long", token.z);
}
int32_t len = trimString(token.z, token.n, pCxt->tmpTokenBuf, TSDB_TB_COMMENT_LEN);
2024-09-26 06:46:53 +00:00
pStmt->pCreateTblReq->comment = taosStrndup(pCxt->tmpTokenBuf, len);
2022-11-27 09:09:02 +00:00
if (NULL == pStmt->pCreateTblReq->comment) {
2024-09-26 06:46:53 +00:00
return terrno;
2022-11-04 07:21:38 +00:00
}
2022-11-27 09:09:02 +00:00
pStmt->pCreateTblReq->commentLen = len;
2022-11-04 07:21:38 +00:00
} else {
break;
}
} while (1);
return TSDB_CODE_SUCCESS;
}
2022-11-04 07:21:38 +00:00
// input pStmt->pSql:
// 1. [(tag1_name, ...)] ...
// 2. VALUES ... | FILE ...
// output pStmt->pSql:
// 1. [(field1_name, ...)]
// 2. VALUES ... | FILE ...
2022-12-20 08:53:08 +00:00
static int32_t parseUsingClauseBottom(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt) {
2022-11-06 06:26:19 +00:00
if (!pStmt->usingTableProcessing || pCxt->usingDuplicateTable) {
2022-11-04 07:21:38 +00:00
return TSDB_CODE_SUCCESS;
}
2022-05-31 09:49:33 +00:00
2022-11-04 07:21:38 +00:00
int32_t code = parseBoundTagsClause(pCxt, pStmt);
if (TSDB_CODE_SUCCESS == code) {
code = parseTagsClause(pCxt, pStmt, false);
2022-11-04 07:21:38 +00:00
}
if (TSDB_CODE_SUCCESS == code) {
code = parseTableOptions(pCxt, pStmt);
}
return code;
}
2023-04-07 08:39:40 +00:00
static void setUserAuthInfo(SParseContext* pCxt, SName* pTbName, SUserAuthInfo* pInfo) {
snprintf(pInfo->user, sizeof(pInfo->user), "%s", pCxt->pUser);
memcpy(&pInfo->tbName, pTbName, sizeof(SName));
pInfo->type = AUTH_TYPE_WRITE;
}
2023-04-25 09:39:28 +00:00
static int32_t checkAuth(SParseContext* pCxt, SName* pTbName, bool* pMissCache, SNode** pTagCond) {
2023-04-07 08:39:40 +00:00
int32_t code = TSDB_CODE_SUCCESS;
SUserAuthInfo authInfo = {0};
setUserAuthInfo(pCxt, pTbName, &authInfo);
SUserAuthRes authRes = {0};
bool exists = true;
2022-11-04 07:21:38 +00:00
if (pCxt->async) {
2023-04-06 02:01:27 +00:00
code = catalogChkAuthFromCache(pCxt->pCatalog, &authInfo, &authRes, &exists);
2022-11-04 07:21:38 +00:00
} else {
2022-11-05 04:09:11 +00:00
SRequestConnInfo conn = {.pTrans = pCxt->pTransporter,
.requestId = pCxt->requestId,
.requestObjRefId = pCxt->requestRid,
.mgmtEps = pCxt->mgmtEpSet};
2023-04-06 02:01:27 +00:00
code = catalogChkAuth(pCxt->pCatalog, &conn, &authInfo, &authRes);
2022-11-04 07:21:38 +00:00
}
2022-11-05 04:09:11 +00:00
if (TSDB_CODE_SUCCESS == code) {
if (!exists) {
*pMissCache = true;
2023-10-20 00:41:49 +00:00
} else if (!authRes.pass[AUTH_RES_BASIC]) {
2022-11-05 04:09:11 +00:00
code = TSDB_CODE_PAR_PERMISSION_DENIED;
2023-10-20 00:41:49 +00:00
} else if (NULL != authRes.pCond[AUTH_RES_BASIC]) {
*pTagCond = authRes.pCond[AUTH_RES_BASIC];
2022-11-05 04:09:11 +00:00
}
2022-11-04 07:21:38 +00:00
}
return code;
}
2024-03-26 07:11:15 +00:00
static int32_t getTableMeta(SInsertParseContext* pCxt, SName* pTbName, STableMeta** pTableMeta, bool* pMissCache,
bool bUsingTable) {
2022-11-05 04:09:11 +00:00
SParseContext* pComCxt = pCxt->pComCxt;
int32_t code = TSDB_CODE_SUCCESS;
2022-11-04 07:21:38 +00:00
if (pComCxt->async) {
if (bUsingTable) {
2022-11-05 04:09:11 +00:00
code = catalogGetCachedSTableMeta(pComCxt->pCatalog, pTbName, pTableMeta);
2022-11-04 07:21:38 +00:00
} else {
2022-11-05 04:09:11 +00:00
code = catalogGetCachedTableMeta(pComCxt->pCatalog, pTbName, pTableMeta);
2022-11-04 07:21:38 +00:00
}
} else {
2022-11-05 04:09:11 +00:00
SRequestConnInfo conn = {.pTrans = pComCxt->pTransporter,
.requestId = pComCxt->requestId,
.requestObjRefId = pComCxt->requestRid,
.mgmtEps = pComCxt->mgmtEpSet};
if (bUsingTable) {
2022-11-04 07:21:38 +00:00
code = catalogGetSTableMeta(pComCxt->pCatalog, &conn, pTbName, pTableMeta);
} else {
code = catalogGetTableMeta(pComCxt->pCatalog, &conn, pTbName, pTableMeta);
2022-05-31 09:49:33 +00:00
}
2022-11-04 07:21:38 +00:00
}
if (TSDB_CODE_SUCCESS == code) {
if (NULL == *pTableMeta) {
*pMissCache = true;
} else if (bUsingTable && TSDB_SUPER_TABLE != (*pTableMeta)->tableType) {
2022-11-04 07:21:38 +00:00
code = buildInvalidOperationMsg(&pCxt->msg, "create table only from super table is allowed");
} else if (((*pTableMeta)->virtualStb) ||
TSDB_VIRTUAL_CHILD_TABLE == (*pTableMeta)->tableType ||
TSDB_VIRTUAL_NORMAL_TABLE == (*pTableMeta)->tableType) {
code = TSDB_CODE_VTABLE_NOT_SUPPORT_STMT;
2022-11-04 07:21:38 +00:00
}
}
return code;
}
static int32_t getTargetTableVgroup(SParseContext* pCxt, SVnodeModifyOpStmt* pStmt, bool isStb, bool* pMissCache) {
2022-11-05 04:09:11 +00:00
int32_t code = TSDB_CODE_SUCCESS;
SVgroupInfo vg;
bool exists = true;
2022-11-04 07:21:38 +00:00
if (pCxt->async) {
2022-11-05 04:09:11 +00:00
code = catalogGetCachedTableHashVgroup(pCxt->pCatalog, &pStmt->targetTableName, &vg, &exists);
2022-11-04 07:21:38 +00:00
} else {
2022-11-05 04:09:11 +00:00
SRequestConnInfo conn = {.pTrans = pCxt->pTransporter,
.requestId = pCxt->requestId,
.requestObjRefId = pCxt->requestRid,
.mgmtEps = pCxt->mgmtEpSet};
2022-11-04 07:21:38 +00:00
code = catalogGetTableHashVgroup(pCxt->pCatalog, &conn, &pStmt->targetTableName, &vg);
}
if (TSDB_CODE_SUCCESS == code) {
if (exists) {
if (isStb) {
pStmt->pTableMeta->vgId = vg.vgId;
}
code = taosHashPut(pStmt->pVgroupsHashObj, (const char*)&vg.vgId, sizeof(vg.vgId), (char*)&vg, sizeof(vg));
}
*pMissCache = !exists;
}
return code;
}
static int32_t getTargetTableMetaAndVgroup(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt, bool* pMissCache) {
SParseContext* pComCxt = pCxt->pComCxt;
int32_t code = TSDB_CODE_SUCCESS;
if (pComCxt->async) {
{
SVgroupInfo vg;
code = catalogGetCachedTableVgMeta(pComCxt->pCatalog, &pStmt->targetTableName, &vg, &pStmt->pTableMeta);
if (TSDB_CODE_SUCCESS == code) {
if (NULL != pStmt->pTableMeta) {
if (pStmt->pTableMeta->tableType == TSDB_SUPER_TABLE) {
pStmt->stbSyntax = true;
} else {
code = taosHashPut(pStmt->pVgroupsHashObj, (const char*)&vg.vgId, sizeof(vg.vgId), (char*)&vg, sizeof(vg));
}
}
*pMissCache = (NULL == pStmt->pTableMeta);
}
}
} else {
bool bUsingTable = false;
code = getTableMeta(pCxt, &pStmt->targetTableName, &pStmt->pTableMeta, pMissCache, bUsingTable);
if (TSDB_CODE_SUCCESS == code && !pCxt->missCache) {
if (TSDB_SUPER_TABLE == pStmt->pTableMeta->tableType) {
pStmt->stbSyntax = true;
}
if (!pStmt->stbSyntax) {
code = getTargetTableVgroup(pCxt->pComCxt, pStmt, false, &pCxt->missCache);
}
}
}
return code;
}
static int32_t collectUseTable(const SName* pName, SHashObj* pTable) {
char fullName[TSDB_TABLE_FNAME_LEN];
2024-07-23 07:59:10 +00:00
int32_t code = tNameExtractFullName(pName, fullName);
if (TSDB_CODE_SUCCESS != code) {
return code;
}
return taosHashPut(pTable, fullName, strlen(fullName), pName, sizeof(SName));
}
static int32_t collectUseDatabase(const SName* pName, SHashObj* pDbs) {
char dbFName[TSDB_DB_FNAME_LEN] = {0};
2024-07-23 11:04:01 +00:00
(void)tNameGetFullDbName(pName, dbFName);
return taosHashPut(pDbs, dbFName, strlen(dbFName), dbFName, sizeof(dbFName));
}
2022-12-20 08:53:08 +00:00
static int32_t getTargetTableSchema(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt) {
if (pCxt->forceUpdate) {
pCxt->missCache = true;
return TSDB_CODE_SUCCESS;
}
2024-03-26 07:11:15 +00:00
SNode* pTagCond = NULL;
int32_t code = checkAuth(pCxt->pComCxt, &pStmt->targetTableName, &pCxt->missCache, &pTagCond);
2022-11-05 04:09:11 +00:00
if (TSDB_CODE_SUCCESS == code && !pCxt->missCache) {
code = getTargetTableMetaAndVgroup(pCxt, pStmt, &pCxt->missCache);
2022-11-04 07:21:38 +00:00
}
if (TSDB_CODE_SUCCESS == code && !pCxt->missCache) {
if (TSDB_SUPER_TABLE != pStmt->pTableMeta->tableType) {
pCxt->needTableTagVal = (NULL != pTagCond);
pCxt->missCache = (NULL != pTagCond);
} else {
2024-07-21 10:20:30 +00:00
pStmt->pTagCond = NULL;
code = nodesCloneNode(pTagCond, &pStmt->pTagCond);
}
}
nodesDestroyNode(pTagCond);
if (TSDB_CODE_SUCCESS == code && !pCxt->pComCxt->async) {
code = collectUseDatabase(&pStmt->targetTableName, pStmt->pDbFNameHashObj);
if (TSDB_CODE_SUCCESS == code) {
code = collectUseTable(&pStmt->targetTableName, pStmt->pTableNameHashObj);
}
}
2022-11-04 07:21:38 +00:00
return code;
}
2022-12-20 08:53:08 +00:00
static int32_t preParseUsingTableName(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt, SToken* pTbName) {
2022-11-04 07:21:38 +00:00
return insCreateSName(&pStmt->usingTableName, pTbName, pCxt->pComCxt->acctId, pCxt->pComCxt->db, &pCxt->msg);
}
static int32_t getUsingTableSchema(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt, bool* ctbCacheHit) {
int32_t code = TSDB_CODE_SUCCESS;
STableMeta* pStableMeta = NULL;
STableMeta* pCtableMeta = NULL;
if (pCxt->forceUpdate) {
pCxt->missCache = true;
return TSDB_CODE_SUCCESS;
}
char stableFName[TSDB_TABLE_FNAME_LEN];
code = tNameExtractFullName(&pStmt->usingTableName, stableFName);
if (TSDB_CODE_SUCCESS != code) {
return code;
}
char ctableFName[TSDB_TABLE_FNAME_LEN];
code = tNameExtractFullName(&pStmt->targetTableName, ctableFName);
if (TSDB_CODE_SUCCESS != code) {
return code;
}
if (strcmp(stableFName, ctableFName) == 0) {
return TSDB_CODE_TDB_TABLE_IN_OTHER_STABLE;
}
if (!pCxt->missCache) {
char tbFName[TSDB_TABLE_FNAME_LEN];
code = tNameExtractFullName(&pStmt->usingTableName, tbFName);
if (TSDB_CODE_SUCCESS != code) {
return code;
}
STableMeta** ppStableMeta = taosHashGet(pStmt->pSuperTableHashObj, tbFName, strlen(tbFName));
if (NULL != ppStableMeta) {
pStableMeta = *ppStableMeta;
}
if (NULL == pStableMeta) {
bool bUsingTable = true;
code = getTableMeta(pCxt, &pStmt->usingTableName, &pStableMeta, &pCxt->missCache, bUsingTable);
if (TSDB_CODE_SUCCESS == code) {
code = taosHashPut(pStmt->pSuperTableHashObj, tbFName, strlen(tbFName), &pStableMeta, POINTER_BYTES);
} else {
taosMemoryFreeClear(pStableMeta);
}
}
}
if (pCxt->isStmtBind) {
goto _no_ctb_cache;
}
2022-11-05 04:09:11 +00:00
if (TSDB_CODE_SUCCESS == code && !pCxt->missCache) {
bool bUsingTable = false;
code = getTableMeta(pCxt, &pStmt->targetTableName, &pCtableMeta, &pCxt->missCache, bUsingTable);
2022-11-04 07:21:38 +00:00
}
if (TSDB_CODE_SUCCESS == code && !pCxt->missCache) {
code = (pStableMeta->suid == pCtableMeta->suid) ? TSDB_CODE_SUCCESS : TSDB_CODE_TDB_TABLE_IN_OTHER_STABLE;
*ctbCacheHit = true;
}
_no_ctb_cache:
if (TSDB_CODE_SUCCESS == code) {
if (*ctbCacheHit) {
code = cloneTableMeta(pCtableMeta, &pStmt->pTableMeta);
} else {
code = cloneTableMeta(pStableMeta, &pStmt->pTableMeta);
}
2022-11-04 07:21:38 +00:00
}
taosMemoryFree(pCtableMeta);
2022-11-04 07:21:38 +00:00
if (TSDB_CODE_SUCCESS == code && !pCxt->missCache) {
code = getTargetTableVgroup(pCxt->pComCxt, pStmt, true, &pCxt->missCache);
2022-11-04 07:21:38 +00:00
}
if (TSDB_CODE_SUCCESS == code && !pCxt->pComCxt->async) {
code = collectUseDatabase(&pStmt->usingTableName, pStmt->pDbFNameHashObj);
if (TSDB_CODE_SUCCESS == code) {
code = collectUseTable(&pStmt->usingTableName, pStmt->pTableNameHashObj);
}
}
2022-11-04 07:21:38 +00:00
return code;
}
2022-12-20 08:53:08 +00:00
static int32_t parseUsingTableNameImpl(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt) {
2022-11-04 07:21:38 +00:00
SToken token;
NEXT_TOKEN(pStmt->pSql, token);
bool ctbCacheHit = false;
2022-11-04 07:21:38 +00:00
int32_t code = preParseUsingTableName(pCxt, pStmt, &token);
if (TSDB_CODE_SUCCESS == code) {
code = getUsingTableSchema(pCxt, pStmt, &ctbCacheHit);
if (TSDB_CODE_SUCCESS == code && ctbCacheHit && !pCxt->missCache) {
pStmt->usingTableProcessing = false;
return ignoreUsingClauseAndCheckTagValues(pCxt, pStmt);
}
2022-11-04 07:21:38 +00:00
}
2022-11-06 06:26:19 +00:00
if (TSDB_CODE_SUCCESS == code && !pCxt->missCache) {
code = storeChildTableMeta(pCxt, pStmt);
2022-11-04 07:21:38 +00:00
}
return code;
}
// input pStmt->pSql:
// 1(care). [USING stb_name [(tag1_name, ...)] TAGS (tag1_value, ...) [table_options]] ...
// 2. VALUES ... | FILE ...
// output pStmt->pSql:
// 1. [(tag1_name, ...)] TAGS (tag1_value, ...) [table_options]] ...
// 2. VALUES ... | FILE ...
2022-12-20 08:53:08 +00:00
static int32_t parseUsingTableName(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt) {
2022-11-04 07:21:38 +00:00
SToken token;
int32_t index = 0;
NEXT_TOKEN_KEEP_SQL(pStmt->pSql, token, index);
if (TK_USING != token.type) {
return getTargetTableSchema(pCxt, pStmt);
}
2022-11-06 06:26:19 +00:00
pStmt->usingTableProcessing = true;
pCxt->stmtTbNameFlag |= USING_CLAUSE;
2022-11-04 07:21:38 +00:00
// pStmt->pSql -> stb_name [(tag1_name, ...)
pStmt->pSql += index;
2022-11-06 06:26:19 +00:00
int32_t code = parseDuplicateUsingClause(pCxt, pStmt, &pCxt->usingDuplicateTable);
if (TSDB_CODE_SUCCESS == code && !pCxt->usingDuplicateTable) {
2022-11-04 07:21:38 +00:00
return parseUsingTableNameImpl(pCxt, pStmt);
}
return code;
}
2022-12-20 08:53:08 +00:00
static int32_t preParseTargetTableName(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt, SToken* pTbName) {
2023-10-19 00:31:31 +00:00
int32_t code = insCreateSName(&pStmt->targetTableName, pTbName, pCxt->pComCxt->acctId, pCxt->pComCxt->db, &pCxt->msg);
if (TSDB_CODE_SUCCESS == code) {
if (IS_SYS_DBNAME(pStmt->targetTableName.dbname)) {
return TSDB_CODE_PAR_SYSTABLE_NOT_ALLOWED;
}
}
return code;
2022-11-04 07:21:38 +00:00
}
// input pStmt->pSql:
// 1(care). [(field1_name, ...)] ...
// 2. [ USING ... ] ...
// 3. VALUES ... | FILE ...
// output pStmt->pSql:
// 1. [ USING ... ] ...
// 2. VALUES ... | FILE ...
2022-12-20 08:53:08 +00:00
static int32_t preParseBoundColumnsClause(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt) {
2022-11-04 07:21:38 +00:00
SToken token;
int32_t index = 0;
NEXT_TOKEN_KEEP_SQL(pStmt->pSql, token, index);
if (TK_NK_LP != token.type) {
return TSDB_CODE_SUCCESS;
}
2022-11-04 07:21:38 +00:00
// pStmt->pSql -> field1_name, ...)
pStmt->pSql += index;
pStmt->pBoundCols = pStmt->pSql;
return skipParentheses(pCxt, &pStmt->pSql);
}
2022-12-23 09:50:05 +00:00
static int32_t getTableDataCxt(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt, STableDataCxt** pTableCxt) {
2022-11-04 07:21:38 +00:00
if (pCxt->pComCxt->async) {
2022-12-04 02:09:10 +00:00
return insGetTableDataCxt(pStmt->pTableBlockHashObj, &pStmt->pTableMeta->uid, sizeof(pStmt->pTableMeta->uid),
pStmt->pTableMeta, &pStmt->pCreateTblReq, pTableCxt, false, false);
2022-11-04 07:21:38 +00:00
}
2022-12-04 02:09:10 +00:00
char tbFName[TSDB_TABLE_FNAME_LEN];
int32_t code = 0;
if ((pCxt->stmtTbNameFlag & NO_DATA_USING_CLAUSE) == USING_CLAUSE) {
tstrncpy(pStmt->targetTableName.tname, pStmt->usingTableName.tname, sizeof(pStmt->targetTableName.tname));
tstrncpy(pStmt->targetTableName.dbname, pStmt->usingTableName.dbname, sizeof(pStmt->targetTableName.dbname));
pStmt->targetTableName.type = TSDB_SUPER_TABLE;
pStmt->pTableMeta->tableType = TSDB_SUPER_TABLE;
}
code = tNameExtractFullName(&pStmt->targetTableName, tbFName);
2024-07-23 07:59:10 +00:00
if (TSDB_CODE_SUCCESS != code) {
return code;
}
2022-11-30 08:57:24 +00:00
if (pStmt->usingTableProcessing) {
pStmt->pTableMeta->uid = 0;
}
2022-11-27 09:09:02 +00:00
return insGetTableDataCxt(pStmt->pTableBlockHashObj, tbFName, strlen(tbFName), pStmt->pTableMeta,
&pStmt->pCreateTblReq, pTableCxt, NULL != pCxt->pComCxt->pStmtCb, false);
2022-11-04 07:21:38 +00:00
}
2022-12-23 09:50:05 +00:00
static int32_t parseBoundColumnsClause(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt, STableDataCxt* pTableCxt) {
2022-11-04 07:21:38 +00:00
SToken token;
int32_t index = 0;
NEXT_TOKEN_KEEP_SQL(pStmt->pSql, token, index);
if (TK_NK_LP == token.type) {
pStmt->pSql += index;
if (NULL != pStmt->pBoundCols) {
return buildSyntaxErrMsg(&pCxt->msg, "keyword VALUES or FILE is expected", token.z);
}
// pStmt->pSql -> field1_name, ...)
2024-03-26 07:11:15 +00:00
return parseBoundColumns(pCxt, &pStmt->pSql, BOUND_COLUMNS, pStmt->pTableMeta, &pTableCxt->boundColsInfo);
2022-11-04 07:21:38 +00:00
}
if (NULL != pStmt->pBoundCols) {
2024-03-26 07:11:15 +00:00
return parseBoundColumns(pCxt, &pStmt->pBoundCols, BOUND_COLUMNS, pStmt->pTableMeta, &pTableCxt->boundColsInfo);
} else if (pTableCxt->boundColsInfo.hasBoundCols) {
insResetBoundColsInfo(&pTableCxt->boundColsInfo);
2022-11-04 07:21:38 +00:00
}
return TSDB_CODE_SUCCESS;
}
2022-11-30 08:57:24 +00:00
int32_t initTableColSubmitData(STableDataCxt* pTableCxt) {
if (0 == (pTableCxt->pData->flags & SUBMIT_REQ_COLUMN_DATA_FORMAT)) {
return TSDB_CODE_SUCCESS;
}
for (int32_t i = 0; i < pTableCxt->boundColsInfo.numOfBound; ++i) {
2022-12-04 02:09:10 +00:00
SSchema* pSchema = &pTableCxt->pMeta->schema[pTableCxt->boundColsInfo.pColIndex[i]];
2022-11-30 08:57:24 +00:00
SColData* pCol = taosArrayReserve(pTableCxt->pData->aCol, 1);
if (NULL == pCol) {
2024-09-20 09:48:04 +00:00
return terrno;
2022-11-30 08:57:24 +00:00
}
2024-04-08 03:18:53 +00:00
tColDataInit(pCol, pSchema->colId, pSchema->type, pSchema->flags);
2022-11-30 08:57:24 +00:00
}
return TSDB_CODE_SUCCESS;
}
2025-01-02 12:07:58 +00:00
int32_t initTableColSubmitDataWithBoundInfo(STableDataCxt* pTableCxt, SBoundColInfo pBoundColsInfo) {
insDestroyBoundColInfo(&(pTableCxt->boundColsInfo));
pTableCxt->boundColsInfo = pBoundColsInfo;
for (int32_t i = 0; i < pBoundColsInfo.numOfBound; ++i) {
SSchema* pSchema = &pTableCxt->pMeta->schema[pTableCxt->boundColsInfo.pColIndex[i]];
SColData* pCol = taosArrayReserve(pTableCxt->pData->aCol, 1);
if (NULL == pCol) {
return terrno;
}
tColDataInit(pCol, pSchema->colId, pSchema->type, pSchema->flags);
}
return TSDB_CODE_SUCCESS;
}
2022-11-04 07:21:38 +00:00
// input pStmt->pSql:
// 1. [(tag1_name, ...)] ...
// 2. VALUES ... | FILE ...
// output pStmt->pSql: VALUES ... | FILE ...
2022-12-20 08:53:08 +00:00
static int32_t parseSchemaClauseBottom(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt,
2022-12-23 09:50:05 +00:00
STableDataCxt** pTableCxt) {
2022-11-04 07:21:38 +00:00
int32_t code = parseUsingClauseBottom(pCxt, pStmt);
if (TSDB_CODE_SUCCESS == code) {
2022-11-27 09:09:02 +00:00
code = getTableDataCxt(pCxt, pStmt, pTableCxt);
2022-11-04 07:21:38 +00:00
}
if (TSDB_CODE_SUCCESS == code) {
2022-11-27 09:09:02 +00:00
code = parseBoundColumnsClause(pCxt, pStmt, *pTableCxt);
2022-11-04 07:21:38 +00:00
}
2022-11-30 08:57:24 +00:00
if (TSDB_CODE_SUCCESS == code) {
code = initTableColSubmitData(*pTableCxt);
}
2022-11-04 07:21:38 +00:00
return code;
}
// input pStmt->pSql: [(field1_name, ...)] [ USING ... ] VALUES ... | FILE ...
// output pStmt->pSql:
// 1. [(tag1_name, ...)] ...
// 2. VALUES ... | FILE ...
2022-12-20 08:53:08 +00:00
static int32_t parseSchemaClauseTop(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt, SToken* pTbName) {
2022-11-04 07:21:38 +00:00
int32_t code = preParseTargetTableName(pCxt, pStmt, pTbName);
if (TSDB_CODE_SUCCESS == code) {
// option: [(field1_name, ...)]
code = preParseBoundColumnsClause(pCxt, pStmt);
}
if (TSDB_CODE_SUCCESS == code) {
// option: [USING stb_name]
code = parseUsingTableName(pCxt, pStmt);
}
return code;
}
static int32_t parseValueTokenImpl(SInsertParseContext* pCxt, const char** pSql, SToken* pToken, SSchema* pSchema,
feat(decimal): support decimal data type (#30060) * decimal: create table * decimal: add test case decimal.py * decimal: add decimal.c * support input decimal * decimal test * refactor svalue * fix test cases * add decimal unit test * add decimal test cmake * support insert and query decimal type * define wide integer, support decimal128 * support decimal128 divide * set decimal type expr res types * scalar decimal * convert to decimal * fix decimal64/128 from str and to str * fix decimal from str and decimal to str * decimal simple conversion * unit test for decimal * decimal conversion and unit tests * decimal + - * / * decimal scalar ops and comparision * start to refactor GET_TYPED_DATA * support decimal max func, cast func * refactor GET_TYPED_DATA interface * decimal scalar comparision * start to implement sum for decimal * support sum and avg for decimal type * decimal tests * add decimal test * decimal add test cases * decimal use int256/int128 * decimal testing * fix decimal table meta and add tests for decimal col streams * fix create stream and create tsma * test insert decimal values * decimal from str * test decimal input * test parse decimal from string * add taos_fetch_field_e api * decimal insert tests * test decimal operators * decimal operator test * feat:support decimal in raw block * decimal operator tests * decimal test * feat:support decimal in raw block * feat:support decimal in raw block * feat:add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * decimal test operators * decimal operator test * test decimal operators * test decimal compare operators * decimal unary operator test * decimal col with decimal col oper test * test decimal col filtering * fix decimal float operator test * decimal test where filtering * fix decimal filtering * fix decimal order by * fix decimal op test * test decimal agg funcs * test decimal functions * remove assert * fix ci build for ret check * fix decimal windows build * fix ci ret check * skip decimal ret check * skip decimal ret check * fix decimal tests * fix decimal ci test * decimal test * fix(tmq): heap user after free * fix(tmq): double free * fix(tmq): double free * fix decimal tests * fix(decimal): decimal test ci build * fix(decimal): windows build * fix(decimal): decimal test build * fix(decimal): fix decimal build and tests * fix(decimal): fix decimal tests * fix(decimal): fix taos_fetch_fields_e api * fix(decimal): fix decimal taos_fetch_fields_e api * fix(decimal): rebase 3.0 * fix(decimal): fix decimal functions * fix(decimal): fix decimal test case memory leak * fix(decimal): fix decimal tests * fix(decimal): fix decimal test case * fix(decimal): fix decimal tests * feat(decimal): fix unit tests * feat(decimal): fix deicmal unit test --------- Co-authored-by: wangmm0220 <wangmm0220@gmail.com> Co-authored-by: yihaoDeng <yhdeng@taosdata.com>
2025-03-14 10:08:07 +00:00
const SSchemaExt* pExtSchema, int16_t timePrec, SColVal* pVal) {
2022-05-31 09:49:33 +00:00
switch (pSchema->type) {
case TSDB_DATA_TYPE_BOOL: {
if ((pToken->type == TK_NK_BOOL || pToken->type == TK_NK_STRING) && (pToken->n != 0)) {
2024-03-10 14:14:57 +00:00
if (IS_TRUE_STR(pToken->z, pToken->n)) {
feat(decimal): support decimal data type (#30060) * decimal: create table * decimal: add test case decimal.py * decimal: add decimal.c * support input decimal * decimal test * refactor svalue * fix test cases * add decimal unit test * add decimal test cmake * support insert and query decimal type * define wide integer, support decimal128 * support decimal128 divide * set decimal type expr res types * scalar decimal * convert to decimal * fix decimal64/128 from str and to str * fix decimal from str and decimal to str * decimal simple conversion * unit test for decimal * decimal conversion and unit tests * decimal + - * / * decimal scalar ops and comparision * start to refactor GET_TYPED_DATA * support decimal max func, cast func * refactor GET_TYPED_DATA interface * decimal scalar comparision * start to implement sum for decimal * support sum and avg for decimal type * decimal tests * add decimal test * decimal add test cases * decimal use int256/int128 * decimal testing * fix decimal table meta and add tests for decimal col streams * fix create stream and create tsma * test insert decimal values * decimal from str * test decimal input * test parse decimal from string * add taos_fetch_field_e api * decimal insert tests * test decimal operators * decimal operator test * feat:support decimal in raw block * decimal operator tests * decimal test * feat:support decimal in raw block * feat:support decimal in raw block * feat:add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * decimal test operators * decimal operator test * test decimal operators * test decimal compare operators * decimal unary operator test * decimal col with decimal col oper test * test decimal col filtering * fix decimal float operator test * decimal test where filtering * fix decimal filtering * fix decimal order by * fix decimal op test * test decimal agg funcs * test decimal functions * remove assert * fix ci build for ret check * fix decimal windows build * fix ci ret check * skip decimal ret check * skip decimal ret check * fix decimal tests * fix decimal ci test * decimal test * fix(tmq): heap user after free * fix(tmq): double free * fix(tmq): double free * fix decimal tests * fix(decimal): decimal test ci build * fix(decimal): windows build * fix(decimal): decimal test build * fix(decimal): fix decimal build and tests * fix(decimal): fix decimal tests * fix(decimal): fix taos_fetch_fields_e api * fix(decimal): fix decimal taos_fetch_fields_e api * fix(decimal): rebase 3.0 * fix(decimal): fix decimal functions * fix(decimal): fix decimal test case memory leak * fix(decimal): fix decimal tests * fix(decimal): fix decimal test case * fix(decimal): fix decimal tests * feat(decimal): fix unit tests * feat(decimal): fix deicmal unit test --------- Co-authored-by: wangmm0220 <wangmm0220@gmail.com> Co-authored-by: yihaoDeng <yhdeng@taosdata.com>
2025-03-14 10:08:07 +00:00
VALUE_SET_TRIVIAL_DATUM(&pVal->value, TRUE_VALUE);
2024-03-10 14:14:57 +00:00
} else if (IS_FALSE_STR(pToken->z, pToken->n)) {
feat(decimal): support decimal data type (#30060) * decimal: create table * decimal: add test case decimal.py * decimal: add decimal.c * support input decimal * decimal test * refactor svalue * fix test cases * add decimal unit test * add decimal test cmake * support insert and query decimal type * define wide integer, support decimal128 * support decimal128 divide * set decimal type expr res types * scalar decimal * convert to decimal * fix decimal64/128 from str and to str * fix decimal from str and decimal to str * decimal simple conversion * unit test for decimal * decimal conversion and unit tests * decimal + - * / * decimal scalar ops and comparision * start to refactor GET_TYPED_DATA * support decimal max func, cast func * refactor GET_TYPED_DATA interface * decimal scalar comparision * start to implement sum for decimal * support sum and avg for decimal type * decimal tests * add decimal test * decimal add test cases * decimal use int256/int128 * decimal testing * fix decimal table meta and add tests for decimal col streams * fix create stream and create tsma * test insert decimal values * decimal from str * test decimal input * test parse decimal from string * add taos_fetch_field_e api * decimal insert tests * test decimal operators * decimal operator test * feat:support decimal in raw block * decimal operator tests * decimal test * feat:support decimal in raw block * feat:support decimal in raw block * feat:add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * decimal test operators * decimal operator test * test decimal operators * test decimal compare operators * decimal unary operator test * decimal col with decimal col oper test * test decimal col filtering * fix decimal float operator test * decimal test where filtering * fix decimal filtering * fix decimal order by * fix decimal op test * test decimal agg funcs * test decimal functions * remove assert * fix ci build for ret check * fix decimal windows build * fix ci ret check * skip decimal ret check * skip decimal ret check * fix decimal tests * fix decimal ci test * decimal test * fix(tmq): heap user after free * fix(tmq): double free * fix(tmq): double free * fix decimal tests * fix(decimal): decimal test ci build * fix(decimal): windows build * fix(decimal): decimal test build * fix(decimal): fix decimal build and tests * fix(decimal): fix decimal tests * fix(decimal): fix taos_fetch_fields_e api * fix(decimal): fix decimal taos_fetch_fields_e api * fix(decimal): rebase 3.0 * fix(decimal): fix decimal functions * fix(decimal): fix decimal test case memory leak * fix(decimal): fix decimal tests * fix(decimal): fix decimal test case * fix(decimal): fix decimal tests * feat(decimal): fix unit tests * feat(decimal): fix deicmal unit test --------- Co-authored-by: wangmm0220 <wangmm0220@gmail.com> Co-authored-by: yihaoDeng <yhdeng@taosdata.com>
2025-03-14 10:08:07 +00:00
VALUE_SET_TRIVIAL_DATUM(&pVal->value, FALSE_VALUE);
} else if (TSDB_CODE_SUCCESS ==
toDoubleEx(pToken->z, pToken->n, pToken->type, (double*)&VALUE_GET_TRIVIAL_DATUM(&pVal->value))) {
int8_t v = (*(double*)&VALUE_GET_TRIVIAL_DATUM(&pVal->value) == 0 ? FALSE_VALUE : TRUE_VALUE);
valueSetDatum(&pVal->value, TSDB_DATA_TYPE_BOOL, &v, tDataTypes[TSDB_DATA_TYPE_BOOL].bytes);
2022-05-31 09:49:33 +00:00
} else {
2022-11-04 07:21:38 +00:00
return buildSyntaxErrMsg(&pCxt->msg, "invalid bool data", pToken->z);
2022-05-31 09:49:33 +00:00
}
} else if (pToken->type == TK_NK_INTEGER) {
feat(decimal): support decimal data type (#30060) * decimal: create table * decimal: add test case decimal.py * decimal: add decimal.c * support input decimal * decimal test * refactor svalue * fix test cases * add decimal unit test * add decimal test cmake * support insert and query decimal type * define wide integer, support decimal128 * support decimal128 divide * set decimal type expr res types * scalar decimal * convert to decimal * fix decimal64/128 from str and to str * fix decimal from str and decimal to str * decimal simple conversion * unit test for decimal * decimal conversion and unit tests * decimal + - * / * decimal scalar ops and comparision * start to refactor GET_TYPED_DATA * support decimal max func, cast func * refactor GET_TYPED_DATA interface * decimal scalar comparision * start to implement sum for decimal * support sum and avg for decimal type * decimal tests * add decimal test * decimal add test cases * decimal use int256/int128 * decimal testing * fix decimal table meta and add tests for decimal col streams * fix create stream and create tsma * test insert decimal values * decimal from str * test decimal input * test parse decimal from string * add taos_fetch_field_e api * decimal insert tests * test decimal operators * decimal operator test * feat:support decimal in raw block * decimal operator tests * decimal test * feat:support decimal in raw block * feat:support decimal in raw block * feat:add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * decimal test operators * decimal operator test * test decimal operators * test decimal compare operators * decimal unary operator test * decimal col with decimal col oper test * test decimal col filtering * fix decimal float operator test * decimal test where filtering * fix decimal filtering * fix decimal order by * fix decimal op test * test decimal agg funcs * test decimal functions * remove assert * fix ci build for ret check * fix decimal windows build * fix ci ret check * skip decimal ret check * skip decimal ret check * fix decimal tests * fix decimal ci test * decimal test * fix(tmq): heap user after free * fix(tmq): double free * fix(tmq): double free * fix decimal tests * fix(decimal): decimal test ci build * fix(decimal): windows build * fix(decimal): decimal test build * fix(decimal): fix decimal build and tests * fix(decimal): fix decimal tests * fix(decimal): fix taos_fetch_fields_e api * fix(decimal): fix decimal taos_fetch_fields_e api * fix(decimal): rebase 3.0 * fix(decimal): fix decimal functions * fix(decimal): fix decimal test case memory leak * fix(decimal): fix decimal tests * fix(decimal): fix decimal test case * fix(decimal): fix decimal tests * feat(decimal): fix unit tests * feat(decimal): fix deicmal unit test --------- Co-authored-by: wangmm0220 <wangmm0220@gmail.com> Co-authored-by: yihaoDeng <yhdeng@taosdata.com>
2025-03-14 10:08:07 +00:00
int8_t v = ((taosStr2Int64(pToken->z, NULL, 10) == 0) ? FALSE_VALUE : TRUE_VALUE);
VALUE_SET_TRIVIAL_DATUM(&pVal->value, v);
2022-05-31 09:49:33 +00:00
} else if (pToken->type == TK_NK_FLOAT) {
feat(decimal): support decimal data type (#30060) * decimal: create table * decimal: add test case decimal.py * decimal: add decimal.c * support input decimal * decimal test * refactor svalue * fix test cases * add decimal unit test * add decimal test cmake * support insert and query decimal type * define wide integer, support decimal128 * support decimal128 divide * set decimal type expr res types * scalar decimal * convert to decimal * fix decimal64/128 from str and to str * fix decimal from str and decimal to str * decimal simple conversion * unit test for decimal * decimal conversion and unit tests * decimal + - * / * decimal scalar ops and comparision * start to refactor GET_TYPED_DATA * support decimal max func, cast func * refactor GET_TYPED_DATA interface * decimal scalar comparision * start to implement sum for decimal * support sum and avg for decimal type * decimal tests * add decimal test * decimal add test cases * decimal use int256/int128 * decimal testing * fix decimal table meta and add tests for decimal col streams * fix create stream and create tsma * test insert decimal values * decimal from str * test decimal input * test parse decimal from string * add taos_fetch_field_e api * decimal insert tests * test decimal operators * decimal operator test * feat:support decimal in raw block * decimal operator tests * decimal test * feat:support decimal in raw block * feat:support decimal in raw block * feat:add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * decimal test operators * decimal operator test * test decimal operators * test decimal compare operators * decimal unary operator test * decimal col with decimal col oper test * test decimal col filtering * fix decimal float operator test * decimal test where filtering * fix decimal filtering * fix decimal order by * fix decimal op test * test decimal agg funcs * test decimal functions * remove assert * fix ci build for ret check * fix decimal windows build * fix ci ret check * skip decimal ret check * skip decimal ret check * fix decimal tests * fix decimal ci test * decimal test * fix(tmq): heap user after free * fix(tmq): double free * fix(tmq): double free * fix decimal tests * fix(decimal): decimal test ci build * fix(decimal): windows build * fix(decimal): decimal test build * fix(decimal): fix decimal build and tests * fix(decimal): fix decimal tests * fix(decimal): fix taos_fetch_fields_e api * fix(decimal): fix decimal taos_fetch_fields_e api * fix(decimal): rebase 3.0 * fix(decimal): fix decimal functions * fix(decimal): fix decimal test case memory leak * fix(decimal): fix decimal tests * fix(decimal): fix decimal test case * fix(decimal): fix decimal tests * feat(decimal): fix unit tests * feat(decimal): fix deicmal unit test --------- Co-authored-by: wangmm0220 <wangmm0220@gmail.com> Co-authored-by: yihaoDeng <yhdeng@taosdata.com>
2025-03-14 10:08:07 +00:00
int8_t v = ((taosStr2Double(pToken->z, NULL) == 0) ? FALSE_VALUE : TRUE_VALUE);
VALUE_SET_TRIVIAL_DATUM(&pVal->value, v);
2024-03-13 07:12:21 +00:00
} else if ((pToken->type == TK_NK_HEX || pToken->type == TK_NK_BIN) &&
feat(decimal): support decimal data type (#30060) * decimal: create table * decimal: add test case decimal.py * decimal: add decimal.c * support input decimal * decimal test * refactor svalue * fix test cases * add decimal unit test * add decimal test cmake * support insert and query decimal type * define wide integer, support decimal128 * support decimal128 divide * set decimal type expr res types * scalar decimal * convert to decimal * fix decimal64/128 from str and to str * fix decimal from str and decimal to str * decimal simple conversion * unit test for decimal * decimal conversion and unit tests * decimal + - * / * decimal scalar ops and comparision * start to refactor GET_TYPED_DATA * support decimal max func, cast func * refactor GET_TYPED_DATA interface * decimal scalar comparision * start to implement sum for decimal * support sum and avg for decimal type * decimal tests * add decimal test * decimal add test cases * decimal use int256/int128 * decimal testing * fix decimal table meta and add tests for decimal col streams * fix create stream and create tsma * test insert decimal values * decimal from str * test decimal input * test parse decimal from string * add taos_fetch_field_e api * decimal insert tests * test decimal operators * decimal operator test * feat:support decimal in raw block * decimal operator tests * decimal test * feat:support decimal in raw block * feat:support decimal in raw block * feat:add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * decimal test operators * decimal operator test * test decimal operators * test decimal compare operators * decimal unary operator test * decimal col with decimal col oper test * test decimal col filtering * fix decimal float operator test * decimal test where filtering * fix decimal filtering * fix decimal order by * fix decimal op test * test decimal agg funcs * test decimal functions * remove assert * fix ci build for ret check * fix decimal windows build * fix ci ret check * skip decimal ret check * skip decimal ret check * fix decimal tests * fix decimal ci test * decimal test * fix(tmq): heap user after free * fix(tmq): double free * fix(tmq): double free * fix decimal tests * fix(decimal): decimal test ci build * fix(decimal): windows build * fix(decimal): decimal test build * fix(decimal): fix decimal build and tests * fix(decimal): fix decimal tests * fix(decimal): fix taos_fetch_fields_e api * fix(decimal): fix decimal taos_fetch_fields_e api * fix(decimal): rebase 3.0 * fix(decimal): fix decimal functions * fix(decimal): fix decimal test case memory leak * fix(decimal): fix decimal tests * fix(decimal): fix decimal test case * fix(decimal): fix decimal tests * feat(decimal): fix unit tests * feat(decimal): fix deicmal unit test --------- Co-authored-by: wangmm0220 <wangmm0220@gmail.com> Co-authored-by: yihaoDeng <yhdeng@taosdata.com>
2025-03-14 10:08:07 +00:00
(TSDB_CODE_SUCCESS ==
toDoubleEx(pToken->z, pToken->n, pToken->type, (double*)&VALUE_GET_TRIVIAL_DATUM(&pVal->value)))) {
int8_t v = *(double*)&VALUE_GET_TRIVIAL_DATUM(&pVal->value) == 0 ? FALSE_VALUE : TRUE_VALUE;
valueSetDatum(&pVal->value, TSDB_DATA_TYPE_BOOL, &v, tDataTypes[TSDB_DATA_TYPE_BOOL].bytes);
2022-05-31 09:49:33 +00:00
} else {
2022-11-04 07:21:38 +00:00
return buildSyntaxErrMsg(&pCxt->msg, "invalid bool data", pToken->z);
2022-05-26 10:00:44 +00:00
}
2022-11-27 09:09:02 +00:00
break;
2022-05-31 09:49:33 +00:00
}
case TSDB_DATA_TYPE_TINYINT: {
feat(decimal): support decimal data type (#30060) * decimal: create table * decimal: add test case decimal.py * decimal: add decimal.c * support input decimal * decimal test * refactor svalue * fix test cases * add decimal unit test * add decimal test cmake * support insert and query decimal type * define wide integer, support decimal128 * support decimal128 divide * set decimal type expr res types * scalar decimal * convert to decimal * fix decimal64/128 from str and to str * fix decimal from str and decimal to str * decimal simple conversion * unit test for decimal * decimal conversion and unit tests * decimal + - * / * decimal scalar ops and comparision * start to refactor GET_TYPED_DATA * support decimal max func, cast func * refactor GET_TYPED_DATA interface * decimal scalar comparision * start to implement sum for decimal * support sum and avg for decimal type * decimal tests * add decimal test * decimal add test cases * decimal use int256/int128 * decimal testing * fix decimal table meta and add tests for decimal col streams * fix create stream and create tsma * test insert decimal values * decimal from str * test decimal input * test parse decimal from string * add taos_fetch_field_e api * decimal insert tests * test decimal operators * decimal operator test * feat:support decimal in raw block * decimal operator tests * decimal test * feat:support decimal in raw block * feat:support decimal in raw block * feat:add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * decimal test operators * decimal operator test * test decimal operators * test decimal compare operators * decimal unary operator test * decimal col with decimal col oper test * test decimal col filtering * fix decimal float operator test * decimal test where filtering * fix decimal filtering * fix decimal order by * fix decimal op test * test decimal agg funcs * test decimal functions * remove assert * fix ci build for ret check * fix decimal windows build * fix ci ret check * skip decimal ret check * skip decimal ret check * fix decimal tests * fix decimal ci test * decimal test * fix(tmq): heap user after free * fix(tmq): double free * fix(tmq): double free * fix decimal tests * fix(decimal): decimal test ci build * fix(decimal): windows build * fix(decimal): decimal test build * fix(decimal): fix decimal build and tests * fix(decimal): fix decimal tests * fix(decimal): fix taos_fetch_fields_e api * fix(decimal): fix decimal taos_fetch_fields_e api * fix(decimal): rebase 3.0 * fix(decimal): fix decimal functions * fix(decimal): fix decimal test case memory leak * fix(decimal): fix decimal tests * fix(decimal): fix decimal test case * fix(decimal): fix decimal tests * feat(decimal): fix unit tests * feat(decimal): fix deicmal unit test --------- Co-authored-by: wangmm0220 <wangmm0220@gmail.com> Co-authored-by: yihaoDeng <yhdeng@taosdata.com>
2025-03-14 10:08:07 +00:00
int32_t code = toIntegerEx(pToken->z, pToken->n, pToken->type, &VALUE_GET_TRIVIAL_DATUM(&pVal->value));
2023-11-30 13:06:06 +00:00
if (TSDB_CODE_SUCCESS != code) {
2022-11-04 07:21:38 +00:00
return buildSyntaxErrMsg(&pCxt->msg, "invalid tinyint data", pToken->z);
feat(decimal): support decimal data type (#30060) * decimal: create table * decimal: add test case decimal.py * decimal: add decimal.c * support input decimal * decimal test * refactor svalue * fix test cases * add decimal unit test * add decimal test cmake * support insert and query decimal type * define wide integer, support decimal128 * support decimal128 divide * set decimal type expr res types * scalar decimal * convert to decimal * fix decimal64/128 from str and to str * fix decimal from str and decimal to str * decimal simple conversion * unit test for decimal * decimal conversion and unit tests * decimal + - * / * decimal scalar ops and comparision * start to refactor GET_TYPED_DATA * support decimal max func, cast func * refactor GET_TYPED_DATA interface * decimal scalar comparision * start to implement sum for decimal * support sum and avg for decimal type * decimal tests * add decimal test * decimal add test cases * decimal use int256/int128 * decimal testing * fix decimal table meta and add tests for decimal col streams * fix create stream and create tsma * test insert decimal values * decimal from str * test decimal input * test parse decimal from string * add taos_fetch_field_e api * decimal insert tests * test decimal operators * decimal operator test * feat:support decimal in raw block * decimal operator tests * decimal test * feat:support decimal in raw block * feat:support decimal in raw block * feat:add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * decimal test operators * decimal operator test * test decimal operators * test decimal compare operators * decimal unary operator test * decimal col with decimal col oper test * test decimal col filtering * fix decimal float operator test * decimal test where filtering * fix decimal filtering * fix decimal order by * fix decimal op test * test decimal agg funcs * test decimal functions * remove assert * fix ci build for ret check * fix decimal windows build * fix ci ret check * skip decimal ret check * skip decimal ret check * fix decimal tests * fix decimal ci test * decimal test * fix(tmq): heap user after free * fix(tmq): double free * fix(tmq): double free * fix decimal tests * fix(decimal): decimal test ci build * fix(decimal): windows build * fix(decimal): decimal test build * fix(decimal): fix decimal build and tests * fix(decimal): fix decimal tests * fix(decimal): fix taos_fetch_fields_e api * fix(decimal): fix decimal taos_fetch_fields_e api * fix(decimal): rebase 3.0 * fix(decimal): fix decimal functions * fix(decimal): fix decimal test case memory leak * fix(decimal): fix decimal tests * fix(decimal): fix decimal test case * fix(decimal): fix decimal tests * feat(decimal): fix unit tests * feat(decimal): fix deicmal unit test --------- Co-authored-by: wangmm0220 <wangmm0220@gmail.com> Co-authored-by: yihaoDeng <yhdeng@taosdata.com>
2025-03-14 10:08:07 +00:00
} else if (!IS_VALID_TINYINT(VALUE_GET_TRIVIAL_DATUM(&pVal->value))) {
2022-11-04 07:21:38 +00:00
return buildSyntaxErrMsg(&pCxt->msg, "tinyint data overflow", pToken->z);
2022-05-26 10:00:44 +00:00
}
2022-11-27 09:09:02 +00:00
break;
2022-03-05 23:12:08 +00:00
}
2022-05-31 09:49:33 +00:00
case TSDB_DATA_TYPE_UTINYINT: {
feat(decimal): support decimal data type (#30060) * decimal: create table * decimal: add test case decimal.py * decimal: add decimal.c * support input decimal * decimal test * refactor svalue * fix test cases * add decimal unit test * add decimal test cmake * support insert and query decimal type * define wide integer, support decimal128 * support decimal128 divide * set decimal type expr res types * scalar decimal * convert to decimal * fix decimal64/128 from str and to str * fix decimal from str and decimal to str * decimal simple conversion * unit test for decimal * decimal conversion and unit tests * decimal + - * / * decimal scalar ops and comparision * start to refactor GET_TYPED_DATA * support decimal max func, cast func * refactor GET_TYPED_DATA interface * decimal scalar comparision * start to implement sum for decimal * support sum and avg for decimal type * decimal tests * add decimal test * decimal add test cases * decimal use int256/int128 * decimal testing * fix decimal table meta and add tests for decimal col streams * fix create stream and create tsma * test insert decimal values * decimal from str * test decimal input * test parse decimal from string * add taos_fetch_field_e api * decimal insert tests * test decimal operators * decimal operator test * feat:support decimal in raw block * decimal operator tests * decimal test * feat:support decimal in raw block * feat:support decimal in raw block * feat:add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * decimal test operators * decimal operator test * test decimal operators * test decimal compare operators * decimal unary operator test * decimal col with decimal col oper test * test decimal col filtering * fix decimal float operator test * decimal test where filtering * fix decimal filtering * fix decimal order by * fix decimal op test * test decimal agg funcs * test decimal functions * remove assert * fix ci build for ret check * fix decimal windows build * fix ci ret check * skip decimal ret check * skip decimal ret check * fix decimal tests * fix decimal ci test * decimal test * fix(tmq): heap user after free * fix(tmq): double free * fix(tmq): double free * fix decimal tests * fix(decimal): decimal test ci build * fix(decimal): windows build * fix(decimal): decimal test build * fix(decimal): fix decimal build and tests * fix(decimal): fix decimal tests * fix(decimal): fix taos_fetch_fields_e api * fix(decimal): fix decimal taos_fetch_fields_e api * fix(decimal): rebase 3.0 * fix(decimal): fix decimal functions * fix(decimal): fix decimal test case memory leak * fix(decimal): fix decimal tests * fix(decimal): fix decimal test case * fix(decimal): fix decimal tests * feat(decimal): fix unit tests * feat(decimal): fix deicmal unit test --------- Co-authored-by: wangmm0220 <wangmm0220@gmail.com> Co-authored-by: yihaoDeng <yhdeng@taosdata.com>
2025-03-14 10:08:07 +00:00
int32_t code = toUIntegerEx(pToken->z, pToken->n, pToken->type, (uint64_t*)&VALUE_GET_TRIVIAL_DATUM(&pVal->value));
2023-11-30 13:06:06 +00:00
if (TSDB_CODE_SUCCESS != code) {
2022-11-04 07:21:38 +00:00
return buildSyntaxErrMsg(&pCxt->msg, "invalid unsigned tinyint data", pToken->z);
feat(decimal): support decimal data type (#30060) * decimal: create table * decimal: add test case decimal.py * decimal: add decimal.c * support input decimal * decimal test * refactor svalue * fix test cases * add decimal unit test * add decimal test cmake * support insert and query decimal type * define wide integer, support decimal128 * support decimal128 divide * set decimal type expr res types * scalar decimal * convert to decimal * fix decimal64/128 from str and to str * fix decimal from str and decimal to str * decimal simple conversion * unit test for decimal * decimal conversion and unit tests * decimal + - * / * decimal scalar ops and comparision * start to refactor GET_TYPED_DATA * support decimal max func, cast func * refactor GET_TYPED_DATA interface * decimal scalar comparision * start to implement sum for decimal * support sum and avg for decimal type * decimal tests * add decimal test * decimal add test cases * decimal use int256/int128 * decimal testing * fix decimal table meta and add tests for decimal col streams * fix create stream and create tsma * test insert decimal values * decimal from str * test decimal input * test parse decimal from string * add taos_fetch_field_e api * decimal insert tests * test decimal operators * decimal operator test * feat:support decimal in raw block * decimal operator tests * decimal test * feat:support decimal in raw block * feat:support decimal in raw block * feat:add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * decimal test operators * decimal operator test * test decimal operators * test decimal compare operators * decimal unary operator test * decimal col with decimal col oper test * test decimal col filtering * fix decimal float operator test * decimal test where filtering * fix decimal filtering * fix decimal order by * fix decimal op test * test decimal agg funcs * test decimal functions * remove assert * fix ci build for ret check * fix decimal windows build * fix ci ret check * skip decimal ret check * skip decimal ret check * fix decimal tests * fix decimal ci test * decimal test * fix(tmq): heap user after free * fix(tmq): double free * fix(tmq): double free * fix decimal tests * fix(decimal): decimal test ci build * fix(decimal): windows build * fix(decimal): decimal test build * fix(decimal): fix decimal build and tests * fix(decimal): fix decimal tests * fix(decimal): fix taos_fetch_fields_e api * fix(decimal): fix decimal taos_fetch_fields_e api * fix(decimal): rebase 3.0 * fix(decimal): fix decimal functions * fix(decimal): fix decimal test case memory leak * fix(decimal): fix decimal tests * fix(decimal): fix decimal test case * fix(decimal): fix decimal tests * feat(decimal): fix unit tests * feat(decimal): fix deicmal unit test --------- Co-authored-by: wangmm0220 <wangmm0220@gmail.com> Co-authored-by: yihaoDeng <yhdeng@taosdata.com>
2025-03-14 10:08:07 +00:00
} else if (VALUE_GET_TRIVIAL_DATUM(&pVal->value) > UINT8_MAX) {
2022-11-04 07:21:38 +00:00
return buildSyntaxErrMsg(&pCxt->msg, "unsigned tinyint data overflow", pToken->z);
2022-05-31 09:49:33 +00:00
}
2022-11-27 09:09:02 +00:00
break;
2022-05-31 09:49:33 +00:00
}
case TSDB_DATA_TYPE_SMALLINT: {
feat(decimal): support decimal data type (#30060) * decimal: create table * decimal: add test case decimal.py * decimal: add decimal.c * support input decimal * decimal test * refactor svalue * fix test cases * add decimal unit test * add decimal test cmake * support insert and query decimal type * define wide integer, support decimal128 * support decimal128 divide * set decimal type expr res types * scalar decimal * convert to decimal * fix decimal64/128 from str and to str * fix decimal from str and decimal to str * decimal simple conversion * unit test for decimal * decimal conversion and unit tests * decimal + - * / * decimal scalar ops and comparision * start to refactor GET_TYPED_DATA * support decimal max func, cast func * refactor GET_TYPED_DATA interface * decimal scalar comparision * start to implement sum for decimal * support sum and avg for decimal type * decimal tests * add decimal test * decimal add test cases * decimal use int256/int128 * decimal testing * fix decimal table meta and add tests for decimal col streams * fix create stream and create tsma * test insert decimal values * decimal from str * test decimal input * test parse decimal from string * add taos_fetch_field_e api * decimal insert tests * test decimal operators * decimal operator test * feat:support decimal in raw block * decimal operator tests * decimal test * feat:support decimal in raw block * feat:support decimal in raw block * feat:add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * decimal test operators * decimal operator test * test decimal operators * test decimal compare operators * decimal unary operator test * decimal col with decimal col oper test * test decimal col filtering * fix decimal float operator test * decimal test where filtering * fix decimal filtering * fix decimal order by * fix decimal op test * test decimal agg funcs * test decimal functions * remove assert * fix ci build for ret check * fix decimal windows build * fix ci ret check * skip decimal ret check * skip decimal ret check * fix decimal tests * fix decimal ci test * decimal test * fix(tmq): heap user after free * fix(tmq): double free * fix(tmq): double free * fix decimal tests * fix(decimal): decimal test ci build * fix(decimal): windows build * fix(decimal): decimal test build * fix(decimal): fix decimal build and tests * fix(decimal): fix decimal tests * fix(decimal): fix taos_fetch_fields_e api * fix(decimal): fix decimal taos_fetch_fields_e api * fix(decimal): rebase 3.0 * fix(decimal): fix decimal functions * fix(decimal): fix decimal test case memory leak * fix(decimal): fix decimal tests * fix(decimal): fix decimal test case * fix(decimal): fix decimal tests * feat(decimal): fix unit tests * feat(decimal): fix deicmal unit test --------- Co-authored-by: wangmm0220 <wangmm0220@gmail.com> Co-authored-by: yihaoDeng <yhdeng@taosdata.com>
2025-03-14 10:08:07 +00:00
int32_t code = toIntegerEx(pToken->z, pToken->n, pToken->type, &VALUE_GET_TRIVIAL_DATUM(&pVal->value));
2023-11-30 13:06:06 +00:00
if (TSDB_CODE_SUCCESS != code) {
2022-11-04 07:21:38 +00:00
return buildSyntaxErrMsg(&pCxt->msg, "invalid smallint data", pToken->z);
feat(decimal): support decimal data type (#30060) * decimal: create table * decimal: add test case decimal.py * decimal: add decimal.c * support input decimal * decimal test * refactor svalue * fix test cases * add decimal unit test * add decimal test cmake * support insert and query decimal type * define wide integer, support decimal128 * support decimal128 divide * set decimal type expr res types * scalar decimal * convert to decimal * fix decimal64/128 from str and to str * fix decimal from str and decimal to str * decimal simple conversion * unit test for decimal * decimal conversion and unit tests * decimal + - * / * decimal scalar ops and comparision * start to refactor GET_TYPED_DATA * support decimal max func, cast func * refactor GET_TYPED_DATA interface * decimal scalar comparision * start to implement sum for decimal * support sum and avg for decimal type * decimal tests * add decimal test * decimal add test cases * decimal use int256/int128 * decimal testing * fix decimal table meta and add tests for decimal col streams * fix create stream and create tsma * test insert decimal values * decimal from str * test decimal input * test parse decimal from string * add taos_fetch_field_e api * decimal insert tests * test decimal operators * decimal operator test * feat:support decimal in raw block * decimal operator tests * decimal test * feat:support decimal in raw block * feat:support decimal in raw block * feat:add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * decimal test operators * decimal operator test * test decimal operators * test decimal compare operators * decimal unary operator test * decimal col with decimal col oper test * test decimal col filtering * fix decimal float operator test * decimal test where filtering * fix decimal filtering * fix decimal order by * fix decimal op test * test decimal agg funcs * test decimal functions * remove assert * fix ci build for ret check * fix decimal windows build * fix ci ret check * skip decimal ret check * skip decimal ret check * fix decimal tests * fix decimal ci test * decimal test * fix(tmq): heap user after free * fix(tmq): double free * fix(tmq): double free * fix decimal tests * fix(decimal): decimal test ci build * fix(decimal): windows build * fix(decimal): decimal test build * fix(decimal): fix decimal build and tests * fix(decimal): fix decimal tests * fix(decimal): fix taos_fetch_fields_e api * fix(decimal): fix decimal taos_fetch_fields_e api * fix(decimal): rebase 3.0 * fix(decimal): fix decimal functions * fix(decimal): fix decimal test case memory leak * fix(decimal): fix decimal tests * fix(decimal): fix decimal test case * fix(decimal): fix decimal tests * feat(decimal): fix unit tests * feat(decimal): fix deicmal unit test --------- Co-authored-by: wangmm0220 <wangmm0220@gmail.com> Co-authored-by: yihaoDeng <yhdeng@taosdata.com>
2025-03-14 10:08:07 +00:00
} else if (!IS_VALID_SMALLINT(VALUE_GET_TRIVIAL_DATUM(&pVal->value))) {
2022-11-04 07:21:38 +00:00
return buildSyntaxErrMsg(&pCxt->msg, "smallint data overflow", pToken->z);
2022-05-31 09:49:33 +00:00
}
2022-11-27 09:09:02 +00:00
break;
2022-05-31 09:49:33 +00:00
}
case TSDB_DATA_TYPE_USMALLINT: {
feat(decimal): support decimal data type (#30060) * decimal: create table * decimal: add test case decimal.py * decimal: add decimal.c * support input decimal * decimal test * refactor svalue * fix test cases * add decimal unit test * add decimal test cmake * support insert and query decimal type * define wide integer, support decimal128 * support decimal128 divide * set decimal type expr res types * scalar decimal * convert to decimal * fix decimal64/128 from str and to str * fix decimal from str and decimal to str * decimal simple conversion * unit test for decimal * decimal conversion and unit tests * decimal + - * / * decimal scalar ops and comparision * start to refactor GET_TYPED_DATA * support decimal max func, cast func * refactor GET_TYPED_DATA interface * decimal scalar comparision * start to implement sum for decimal * support sum and avg for decimal type * decimal tests * add decimal test * decimal add test cases * decimal use int256/int128 * decimal testing * fix decimal table meta and add tests for decimal col streams * fix create stream and create tsma * test insert decimal values * decimal from str * test decimal input * test parse decimal from string * add taos_fetch_field_e api * decimal insert tests * test decimal operators * decimal operator test * feat:support decimal in raw block * decimal operator tests * decimal test * feat:support decimal in raw block * feat:support decimal in raw block * feat:add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * decimal test operators * decimal operator test * test decimal operators * test decimal compare operators * decimal unary operator test * decimal col with decimal col oper test * test decimal col filtering * fix decimal float operator test * decimal test where filtering * fix decimal filtering * fix decimal order by * fix decimal op test * test decimal agg funcs * test decimal functions * remove assert * fix ci build for ret check * fix decimal windows build * fix ci ret check * skip decimal ret check * skip decimal ret check * fix decimal tests * fix decimal ci test * decimal test * fix(tmq): heap user after free * fix(tmq): double free * fix(tmq): double free * fix decimal tests * fix(decimal): decimal test ci build * fix(decimal): windows build * fix(decimal): decimal test build * fix(decimal): fix decimal build and tests * fix(decimal): fix decimal tests * fix(decimal): fix taos_fetch_fields_e api * fix(decimal): fix decimal taos_fetch_fields_e api * fix(decimal): rebase 3.0 * fix(decimal): fix decimal functions * fix(decimal): fix decimal test case memory leak * fix(decimal): fix decimal tests * fix(decimal): fix decimal test case * fix(decimal): fix decimal tests * feat(decimal): fix unit tests * feat(decimal): fix deicmal unit test --------- Co-authored-by: wangmm0220 <wangmm0220@gmail.com> Co-authored-by: yihaoDeng <yhdeng@taosdata.com>
2025-03-14 10:08:07 +00:00
int32_t code = toUIntegerEx(pToken->z, pToken->n, pToken->type, &VALUE_GET_TRIVIAL_DATUM(&pVal->value));
2023-11-30 13:06:06 +00:00
if (TSDB_CODE_SUCCESS != code) {
2022-11-04 07:21:38 +00:00
return buildSyntaxErrMsg(&pCxt->msg, "invalid unsigned smallint data", pToken->z);
feat(decimal): support decimal data type (#30060) * decimal: create table * decimal: add test case decimal.py * decimal: add decimal.c * support input decimal * decimal test * refactor svalue * fix test cases * add decimal unit test * add decimal test cmake * support insert and query decimal type * define wide integer, support decimal128 * support decimal128 divide * set decimal type expr res types * scalar decimal * convert to decimal * fix decimal64/128 from str and to str * fix decimal from str and decimal to str * decimal simple conversion * unit test for decimal * decimal conversion and unit tests * decimal + - * / * decimal scalar ops and comparision * start to refactor GET_TYPED_DATA * support decimal max func, cast func * refactor GET_TYPED_DATA interface * decimal scalar comparision * start to implement sum for decimal * support sum and avg for decimal type * decimal tests * add decimal test * decimal add test cases * decimal use int256/int128 * decimal testing * fix decimal table meta and add tests for decimal col streams * fix create stream and create tsma * test insert decimal values * decimal from str * test decimal input * test parse decimal from string * add taos_fetch_field_e api * decimal insert tests * test decimal operators * decimal operator test * feat:support decimal in raw block * decimal operator tests * decimal test * feat:support decimal in raw block * feat:support decimal in raw block * feat:add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * decimal test operators * decimal operator test * test decimal operators * test decimal compare operators * decimal unary operator test * decimal col with decimal col oper test * test decimal col filtering * fix decimal float operator test * decimal test where filtering * fix decimal filtering * fix decimal order by * fix decimal op test * test decimal agg funcs * test decimal functions * remove assert * fix ci build for ret check * fix decimal windows build * fix ci ret check * skip decimal ret check * skip decimal ret check * fix decimal tests * fix decimal ci test * decimal test * fix(tmq): heap user after free * fix(tmq): double free * fix(tmq): double free * fix decimal tests * fix(decimal): decimal test ci build * fix(decimal): windows build * fix(decimal): decimal test build * fix(decimal): fix decimal build and tests * fix(decimal): fix decimal tests * fix(decimal): fix taos_fetch_fields_e api * fix(decimal): fix decimal taos_fetch_fields_e api * fix(decimal): rebase 3.0 * fix(decimal): fix decimal functions * fix(decimal): fix decimal test case memory leak * fix(decimal): fix decimal tests * fix(decimal): fix decimal test case * fix(decimal): fix decimal tests * feat(decimal): fix unit tests * feat(decimal): fix deicmal unit test --------- Co-authored-by: wangmm0220 <wangmm0220@gmail.com> Co-authored-by: yihaoDeng <yhdeng@taosdata.com>
2025-03-14 10:08:07 +00:00
} else if (VALUE_GET_TRIVIAL_DATUM(&pVal->value) > UINT16_MAX) {
2022-11-04 07:21:38 +00:00
return buildSyntaxErrMsg(&pCxt->msg, "unsigned smallint data overflow", pToken->z);
2022-05-31 09:49:33 +00:00
}
2022-11-27 09:09:02 +00:00
break;
2022-05-31 09:49:33 +00:00
}
case TSDB_DATA_TYPE_INT: {
feat(decimal): support decimal data type (#30060) * decimal: create table * decimal: add test case decimal.py * decimal: add decimal.c * support input decimal * decimal test * refactor svalue * fix test cases * add decimal unit test * add decimal test cmake * support insert and query decimal type * define wide integer, support decimal128 * support decimal128 divide * set decimal type expr res types * scalar decimal * convert to decimal * fix decimal64/128 from str and to str * fix decimal from str and decimal to str * decimal simple conversion * unit test for decimal * decimal conversion and unit tests * decimal + - * / * decimal scalar ops and comparision * start to refactor GET_TYPED_DATA * support decimal max func, cast func * refactor GET_TYPED_DATA interface * decimal scalar comparision * start to implement sum for decimal * support sum and avg for decimal type * decimal tests * add decimal test * decimal add test cases * decimal use int256/int128 * decimal testing * fix decimal table meta and add tests for decimal col streams * fix create stream and create tsma * test insert decimal values * decimal from str * test decimal input * test parse decimal from string * add taos_fetch_field_e api * decimal insert tests * test decimal operators * decimal operator test * feat:support decimal in raw block * decimal operator tests * decimal test * feat:support decimal in raw block * feat:support decimal in raw block * feat:add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * decimal test operators * decimal operator test * test decimal operators * test decimal compare operators * decimal unary operator test * decimal col with decimal col oper test * test decimal col filtering * fix decimal float operator test * decimal test where filtering * fix decimal filtering * fix decimal order by * fix decimal op test * test decimal agg funcs * test decimal functions * remove assert * fix ci build for ret check * fix decimal windows build * fix ci ret check * skip decimal ret check * skip decimal ret check * fix decimal tests * fix decimal ci test * decimal test * fix(tmq): heap user after free * fix(tmq): double free * fix(tmq): double free * fix decimal tests * fix(decimal): decimal test ci build * fix(decimal): windows build * fix(decimal): decimal test build * fix(decimal): fix decimal build and tests * fix(decimal): fix decimal tests * fix(decimal): fix taos_fetch_fields_e api * fix(decimal): fix decimal taos_fetch_fields_e api * fix(decimal): rebase 3.0 * fix(decimal): fix decimal functions * fix(decimal): fix decimal test case memory leak * fix(decimal): fix decimal tests * fix(decimal): fix decimal test case * fix(decimal): fix decimal tests * feat(decimal): fix unit tests * feat(decimal): fix deicmal unit test --------- Co-authored-by: wangmm0220 <wangmm0220@gmail.com> Co-authored-by: yihaoDeng <yhdeng@taosdata.com>
2025-03-14 10:08:07 +00:00
int32_t code = toIntegerEx(pToken->z, pToken->n, pToken->type, &VALUE_GET_TRIVIAL_DATUM(&pVal->value));
2023-11-30 13:06:06 +00:00
if (TSDB_CODE_SUCCESS != code) {
2022-11-04 07:21:38 +00:00
return buildSyntaxErrMsg(&pCxt->msg, "invalid int data", pToken->z);
feat(decimal): support decimal data type (#30060) * decimal: create table * decimal: add test case decimal.py * decimal: add decimal.c * support input decimal * decimal test * refactor svalue * fix test cases * add decimal unit test * add decimal test cmake * support insert and query decimal type * define wide integer, support decimal128 * support decimal128 divide * set decimal type expr res types * scalar decimal * convert to decimal * fix decimal64/128 from str and to str * fix decimal from str and decimal to str * decimal simple conversion * unit test for decimal * decimal conversion and unit tests * decimal + - * / * decimal scalar ops and comparision * start to refactor GET_TYPED_DATA * support decimal max func, cast func * refactor GET_TYPED_DATA interface * decimal scalar comparision * start to implement sum for decimal * support sum and avg for decimal type * decimal tests * add decimal test * decimal add test cases * decimal use int256/int128 * decimal testing * fix decimal table meta and add tests for decimal col streams * fix create stream and create tsma * test insert decimal values * decimal from str * test decimal input * test parse decimal from string * add taos_fetch_field_e api * decimal insert tests * test decimal operators * decimal operator test * feat:support decimal in raw block * decimal operator tests * decimal test * feat:support decimal in raw block * feat:support decimal in raw block * feat:add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * decimal test operators * decimal operator test * test decimal operators * test decimal compare operators * decimal unary operator test * decimal col with decimal col oper test * test decimal col filtering * fix decimal float operator test * decimal test where filtering * fix decimal filtering * fix decimal order by * fix decimal op test * test decimal agg funcs * test decimal functions * remove assert * fix ci build for ret check * fix decimal windows build * fix ci ret check * skip decimal ret check * skip decimal ret check * fix decimal tests * fix decimal ci test * decimal test * fix(tmq): heap user after free * fix(tmq): double free * fix(tmq): double free * fix decimal tests * fix(decimal): decimal test ci build * fix(decimal): windows build * fix(decimal): decimal test build * fix(decimal): fix decimal build and tests * fix(decimal): fix decimal tests * fix(decimal): fix taos_fetch_fields_e api * fix(decimal): fix decimal taos_fetch_fields_e api * fix(decimal): rebase 3.0 * fix(decimal): fix decimal functions * fix(decimal): fix decimal test case memory leak * fix(decimal): fix decimal tests * fix(decimal): fix decimal test case * fix(decimal): fix decimal tests * feat(decimal): fix unit tests * feat(decimal): fix deicmal unit test --------- Co-authored-by: wangmm0220 <wangmm0220@gmail.com> Co-authored-by: yihaoDeng <yhdeng@taosdata.com>
2025-03-14 10:08:07 +00:00
} else if (!IS_VALID_INT(VALUE_GET_TRIVIAL_DATUM(&pVal->value))) {
2022-11-04 07:21:38 +00:00
return buildSyntaxErrMsg(&pCxt->msg, "int data overflow", pToken->z);
2022-05-31 09:49:33 +00:00
}
2022-11-27 09:09:02 +00:00
break;
2022-05-31 09:49:33 +00:00
}
case TSDB_DATA_TYPE_UINT: {
feat(decimal): support decimal data type (#30060) * decimal: create table * decimal: add test case decimal.py * decimal: add decimal.c * support input decimal * decimal test * refactor svalue * fix test cases * add decimal unit test * add decimal test cmake * support insert and query decimal type * define wide integer, support decimal128 * support decimal128 divide * set decimal type expr res types * scalar decimal * convert to decimal * fix decimal64/128 from str and to str * fix decimal from str and decimal to str * decimal simple conversion * unit test for decimal * decimal conversion and unit tests * decimal + - * / * decimal scalar ops and comparision * start to refactor GET_TYPED_DATA * support decimal max func, cast func * refactor GET_TYPED_DATA interface * decimal scalar comparision * start to implement sum for decimal * support sum and avg for decimal type * decimal tests * add decimal test * decimal add test cases * decimal use int256/int128 * decimal testing * fix decimal table meta and add tests for decimal col streams * fix create stream and create tsma * test insert decimal values * decimal from str * test decimal input * test parse decimal from string * add taos_fetch_field_e api * decimal insert tests * test decimal operators * decimal operator test * feat:support decimal in raw block * decimal operator tests * decimal test * feat:support decimal in raw block * feat:support decimal in raw block * feat:add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * decimal test operators * decimal operator test * test decimal operators * test decimal compare operators * decimal unary operator test * decimal col with decimal col oper test * test decimal col filtering * fix decimal float operator test * decimal test where filtering * fix decimal filtering * fix decimal order by * fix decimal op test * test decimal agg funcs * test decimal functions * remove assert * fix ci build for ret check * fix decimal windows build * fix ci ret check * skip decimal ret check * skip decimal ret check * fix decimal tests * fix decimal ci test * decimal test * fix(tmq): heap user after free * fix(tmq): double free * fix(tmq): double free * fix decimal tests * fix(decimal): decimal test ci build * fix(decimal): windows build * fix(decimal): decimal test build * fix(decimal): fix decimal build and tests * fix(decimal): fix decimal tests * fix(decimal): fix taos_fetch_fields_e api * fix(decimal): fix decimal taos_fetch_fields_e api * fix(decimal): rebase 3.0 * fix(decimal): fix decimal functions * fix(decimal): fix decimal test case memory leak * fix(decimal): fix decimal tests * fix(decimal): fix decimal test case * fix(decimal): fix decimal tests * feat(decimal): fix unit tests * feat(decimal): fix deicmal unit test --------- Co-authored-by: wangmm0220 <wangmm0220@gmail.com> Co-authored-by: yihaoDeng <yhdeng@taosdata.com>
2025-03-14 10:08:07 +00:00
int32_t code = toUIntegerEx(pToken->z, pToken->n, pToken->type, &VALUE_GET_TRIVIAL_DATUM(&pVal->value));
2023-11-30 13:06:06 +00:00
if (TSDB_CODE_SUCCESS != code) {
2022-11-04 07:21:38 +00:00
return buildSyntaxErrMsg(&pCxt->msg, "invalid unsigned int data", pToken->z);
feat(decimal): support decimal data type (#30060) * decimal: create table * decimal: add test case decimal.py * decimal: add decimal.c * support input decimal * decimal test * refactor svalue * fix test cases * add decimal unit test * add decimal test cmake * support insert and query decimal type * define wide integer, support decimal128 * support decimal128 divide * set decimal type expr res types * scalar decimal * convert to decimal * fix decimal64/128 from str and to str * fix decimal from str and decimal to str * decimal simple conversion * unit test for decimal * decimal conversion and unit tests * decimal + - * / * decimal scalar ops and comparision * start to refactor GET_TYPED_DATA * support decimal max func, cast func * refactor GET_TYPED_DATA interface * decimal scalar comparision * start to implement sum for decimal * support sum and avg for decimal type * decimal tests * add decimal test * decimal add test cases * decimal use int256/int128 * decimal testing * fix decimal table meta and add tests for decimal col streams * fix create stream and create tsma * test insert decimal values * decimal from str * test decimal input * test parse decimal from string * add taos_fetch_field_e api * decimal insert tests * test decimal operators * decimal operator test * feat:support decimal in raw block * decimal operator tests * decimal test * feat:support decimal in raw block * feat:support decimal in raw block * feat:add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * decimal test operators * decimal operator test * test decimal operators * test decimal compare operators * decimal unary operator test * decimal col with decimal col oper test * test decimal col filtering * fix decimal float operator test * decimal test where filtering * fix decimal filtering * fix decimal order by * fix decimal op test * test decimal agg funcs * test decimal functions * remove assert * fix ci build for ret check * fix decimal windows build * fix ci ret check * skip decimal ret check * skip decimal ret check * fix decimal tests * fix decimal ci test * decimal test * fix(tmq): heap user after free * fix(tmq): double free * fix(tmq): double free * fix decimal tests * fix(decimal): decimal test ci build * fix(decimal): windows build * fix(decimal): decimal test build * fix(decimal): fix decimal build and tests * fix(decimal): fix decimal tests * fix(decimal): fix taos_fetch_fields_e api * fix(decimal): fix decimal taos_fetch_fields_e api * fix(decimal): rebase 3.0 * fix(decimal): fix decimal functions * fix(decimal): fix decimal test case memory leak * fix(decimal): fix decimal tests * fix(decimal): fix decimal test case * fix(decimal): fix decimal tests * feat(decimal): fix unit tests * feat(decimal): fix deicmal unit test --------- Co-authored-by: wangmm0220 <wangmm0220@gmail.com> Co-authored-by: yihaoDeng <yhdeng@taosdata.com>
2025-03-14 10:08:07 +00:00
} else if (VALUE_GET_TRIVIAL_DATUM(&pVal->value) > UINT32_MAX) {
2022-11-04 07:21:38 +00:00
return buildSyntaxErrMsg(&pCxt->msg, "unsigned int data overflow", pToken->z);
2022-05-31 09:49:33 +00:00
}
2022-11-27 09:09:02 +00:00
break;
2022-05-31 09:49:33 +00:00
}
case TSDB_DATA_TYPE_BIGINT: {
feat(decimal): support decimal data type (#30060) * decimal: create table * decimal: add test case decimal.py * decimal: add decimal.c * support input decimal * decimal test * refactor svalue * fix test cases * add decimal unit test * add decimal test cmake * support insert and query decimal type * define wide integer, support decimal128 * support decimal128 divide * set decimal type expr res types * scalar decimal * convert to decimal * fix decimal64/128 from str and to str * fix decimal from str and decimal to str * decimal simple conversion * unit test for decimal * decimal conversion and unit tests * decimal + - * / * decimal scalar ops and comparision * start to refactor GET_TYPED_DATA * support decimal max func, cast func * refactor GET_TYPED_DATA interface * decimal scalar comparision * start to implement sum for decimal * support sum and avg for decimal type * decimal tests * add decimal test * decimal add test cases * decimal use int256/int128 * decimal testing * fix decimal table meta and add tests for decimal col streams * fix create stream and create tsma * test insert decimal values * decimal from str * test decimal input * test parse decimal from string * add taos_fetch_field_e api * decimal insert tests * test decimal operators * decimal operator test * feat:support decimal in raw block * decimal operator tests * decimal test * feat:support decimal in raw block * feat:support decimal in raw block * feat:add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * decimal test operators * decimal operator test * test decimal operators * test decimal compare operators * decimal unary operator test * decimal col with decimal col oper test * test decimal col filtering * fix decimal float operator test * decimal test where filtering * fix decimal filtering * fix decimal order by * fix decimal op test * test decimal agg funcs * test decimal functions * remove assert * fix ci build for ret check * fix decimal windows build * fix ci ret check * skip decimal ret check * skip decimal ret check * fix decimal tests * fix decimal ci test * decimal test * fix(tmq): heap user after free * fix(tmq): double free * fix(tmq): double free * fix decimal tests * fix(decimal): decimal test ci build * fix(decimal): windows build * fix(decimal): decimal test build * fix(decimal): fix decimal build and tests * fix(decimal): fix decimal tests * fix(decimal): fix taos_fetch_fields_e api * fix(decimal): fix decimal taos_fetch_fields_e api * fix(decimal): rebase 3.0 * fix(decimal): fix decimal functions * fix(decimal): fix decimal test case memory leak * fix(decimal): fix decimal tests * fix(decimal): fix decimal test case * fix(decimal): fix decimal tests * feat(decimal): fix unit tests * feat(decimal): fix deicmal unit test --------- Co-authored-by: wangmm0220 <wangmm0220@gmail.com> Co-authored-by: yihaoDeng <yhdeng@taosdata.com>
2025-03-14 10:08:07 +00:00
int32_t code = toIntegerEx(pToken->z, pToken->n, pToken->type, &VALUE_GET_TRIVIAL_DATUM(&pVal->value));
2023-11-30 13:06:06 +00:00
if (TSDB_CODE_SUCCESS != code) {
2022-11-04 07:21:38 +00:00
return buildSyntaxErrMsg(&pCxt->msg, "invalid bigint data", pToken->z);
2022-05-31 09:49:33 +00:00
}
2022-11-27 09:09:02 +00:00
break;
2022-05-31 09:49:33 +00:00
}
case TSDB_DATA_TYPE_UBIGINT: {
feat(decimal): support decimal data type (#30060) * decimal: create table * decimal: add test case decimal.py * decimal: add decimal.c * support input decimal * decimal test * refactor svalue * fix test cases * add decimal unit test * add decimal test cmake * support insert and query decimal type * define wide integer, support decimal128 * support decimal128 divide * set decimal type expr res types * scalar decimal * convert to decimal * fix decimal64/128 from str and to str * fix decimal from str and decimal to str * decimal simple conversion * unit test for decimal * decimal conversion and unit tests * decimal + - * / * decimal scalar ops and comparision * start to refactor GET_TYPED_DATA * support decimal max func, cast func * refactor GET_TYPED_DATA interface * decimal scalar comparision * start to implement sum for decimal * support sum and avg for decimal type * decimal tests * add decimal test * decimal add test cases * decimal use int256/int128 * decimal testing * fix decimal table meta and add tests for decimal col streams * fix create stream and create tsma * test insert decimal values * decimal from str * test decimal input * test parse decimal from string * add taos_fetch_field_e api * decimal insert tests * test decimal operators * decimal operator test * feat:support decimal in raw block * decimal operator tests * decimal test * feat:support decimal in raw block * feat:support decimal in raw block * feat:add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * decimal test operators * decimal operator test * test decimal operators * test decimal compare operators * decimal unary operator test * decimal col with decimal col oper test * test decimal col filtering * fix decimal float operator test * decimal test where filtering * fix decimal filtering * fix decimal order by * fix decimal op test * test decimal agg funcs * test decimal functions * remove assert * fix ci build for ret check * fix decimal windows build * fix ci ret check * skip decimal ret check * skip decimal ret check * fix decimal tests * fix decimal ci test * decimal test * fix(tmq): heap user after free * fix(tmq): double free * fix(tmq): double free * fix decimal tests * fix(decimal): decimal test ci build * fix(decimal): windows build * fix(decimal): decimal test build * fix(decimal): fix decimal build and tests * fix(decimal): fix decimal tests * fix(decimal): fix taos_fetch_fields_e api * fix(decimal): fix decimal taos_fetch_fields_e api * fix(decimal): rebase 3.0 * fix(decimal): fix decimal functions * fix(decimal): fix decimal test case memory leak * fix(decimal): fix decimal tests * fix(decimal): fix decimal test case * fix(decimal): fix decimal tests * feat(decimal): fix unit tests * feat(decimal): fix deicmal unit test --------- Co-authored-by: wangmm0220 <wangmm0220@gmail.com> Co-authored-by: yihaoDeng <yhdeng@taosdata.com>
2025-03-14 10:08:07 +00:00
int32_t code = toUIntegerEx(pToken->z, pToken->n, pToken->type, &VALUE_GET_TRIVIAL_DATUM(&pVal->value));
2023-11-30 13:06:06 +00:00
if (TSDB_CODE_SUCCESS != code) {
2022-11-04 07:21:38 +00:00
return buildSyntaxErrMsg(&pCxt->msg, "invalid unsigned bigint data", pToken->z);
2022-05-31 09:49:33 +00:00
}
2022-11-27 09:09:02 +00:00
break;
2022-05-31 09:49:33 +00:00
}
case TSDB_DATA_TYPE_FLOAT: {
2024-03-10 14:14:57 +00:00
double dv;
2023-12-01 15:44:05 +00:00
int32_t code = toDoubleEx(pToken->z, pToken->n, pToken->type, &dv);
if (TSDB_CODE_SUCCESS != code) {
2022-11-04 07:21:38 +00:00
return buildSyntaxErrMsg(&pCxt->msg, "illegal float data", pToken->z);
2022-05-31 09:49:33 +00:00
}
2023-12-01 15:44:05 +00:00
if (dv > FLT_MAX || dv < -FLT_MAX || isinf(dv) || isnan(dv)) {
2022-11-04 07:21:38 +00:00
return buildSyntaxErrMsg(&pCxt->msg, "illegal float data", pToken->z);
2022-05-31 09:49:33 +00:00
}
2022-12-04 02:09:10 +00:00
float f = dv;
feat(decimal): support decimal data type (#30060) * decimal: create table * decimal: add test case decimal.py * decimal: add decimal.c * support input decimal * decimal test * refactor svalue * fix test cases * add decimal unit test * add decimal test cmake * support insert and query decimal type * define wide integer, support decimal128 * support decimal128 divide * set decimal type expr res types * scalar decimal * convert to decimal * fix decimal64/128 from str and to str * fix decimal from str and decimal to str * decimal simple conversion * unit test for decimal * decimal conversion and unit tests * decimal + - * / * decimal scalar ops and comparision * start to refactor GET_TYPED_DATA * support decimal max func, cast func * refactor GET_TYPED_DATA interface * decimal scalar comparision * start to implement sum for decimal * support sum and avg for decimal type * decimal tests * add decimal test * decimal add test cases * decimal use int256/int128 * decimal testing * fix decimal table meta and add tests for decimal col streams * fix create stream and create tsma * test insert decimal values * decimal from str * test decimal input * test parse decimal from string * add taos_fetch_field_e api * decimal insert tests * test decimal operators * decimal operator test * feat:support decimal in raw block * decimal operator tests * decimal test * feat:support decimal in raw block * feat:support decimal in raw block * feat:add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * decimal test operators * decimal operator test * test decimal operators * test decimal compare operators * decimal unary operator test * decimal col with decimal col oper test * test decimal col filtering * fix decimal float operator test * decimal test where filtering * fix decimal filtering * fix decimal order by * fix decimal op test * test decimal agg funcs * test decimal functions * remove assert * fix ci build for ret check * fix decimal windows build * fix ci ret check * skip decimal ret check * skip decimal ret check * fix decimal tests * fix decimal ci test * decimal test * fix(tmq): heap user after free * fix(tmq): double free * fix(tmq): double free * fix decimal tests * fix(decimal): decimal test ci build * fix(decimal): windows build * fix(decimal): decimal test build * fix(decimal): fix decimal build and tests * fix(decimal): fix decimal tests * fix(decimal): fix taos_fetch_fields_e api * fix(decimal): fix decimal taos_fetch_fields_e api * fix(decimal): rebase 3.0 * fix(decimal): fix decimal functions * fix(decimal): fix decimal test case memory leak * fix(decimal): fix decimal tests * fix(decimal): fix decimal test case * fix(decimal): fix decimal tests * feat(decimal): fix unit tests * feat(decimal): fix deicmal unit test --------- Co-authored-by: wangmm0220 <wangmm0220@gmail.com> Co-authored-by: yihaoDeng <yhdeng@taosdata.com>
2025-03-14 10:08:07 +00:00
valueSetDatum(&pVal->value, TSDB_DATA_TYPE_FLOAT, &f, sizeof(f));
2022-11-27 09:09:02 +00:00
break;
2022-05-31 09:49:33 +00:00
}
case TSDB_DATA_TYPE_DOUBLE: {
2024-03-10 14:14:57 +00:00
double dv;
2023-12-01 15:44:05 +00:00
int32_t code = toDoubleEx(pToken->z, pToken->n, pToken->type, &dv);
if (TSDB_CODE_SUCCESS != code) {
return buildSyntaxErrMsg(&pCxt->msg, "illegal float data", pToken->z);
2022-05-31 09:49:33 +00:00
}
2023-12-01 15:44:05 +00:00
if (isinf(dv) || isnan(dv)) {
2022-11-04 07:21:38 +00:00
return buildSyntaxErrMsg(&pCxt->msg, "illegal double data", pToken->z);
2022-05-31 09:49:33 +00:00
}
feat(decimal): support decimal data type (#30060) * decimal: create table * decimal: add test case decimal.py * decimal: add decimal.c * support input decimal * decimal test * refactor svalue * fix test cases * add decimal unit test * add decimal test cmake * support insert and query decimal type * define wide integer, support decimal128 * support decimal128 divide * set decimal type expr res types * scalar decimal * convert to decimal * fix decimal64/128 from str and to str * fix decimal from str and decimal to str * decimal simple conversion * unit test for decimal * decimal conversion and unit tests * decimal + - * / * decimal scalar ops and comparision * start to refactor GET_TYPED_DATA * support decimal max func, cast func * refactor GET_TYPED_DATA interface * decimal scalar comparision * start to implement sum for decimal * support sum and avg for decimal type * decimal tests * add decimal test * decimal add test cases * decimal use int256/int128 * decimal testing * fix decimal table meta and add tests for decimal col streams * fix create stream and create tsma * test insert decimal values * decimal from str * test decimal input * test parse decimal from string * add taos_fetch_field_e api * decimal insert tests * test decimal operators * decimal operator test * feat:support decimal in raw block * decimal operator tests * decimal test * feat:support decimal in raw block * feat:support decimal in raw block * feat:add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * decimal test operators * decimal operator test * test decimal operators * test decimal compare operators * decimal unary operator test * decimal col with decimal col oper test * test decimal col filtering * fix decimal float operator test * decimal test where filtering * fix decimal filtering * fix decimal order by * fix decimal op test * test decimal agg funcs * test decimal functions * remove assert * fix ci build for ret check * fix decimal windows build * fix ci ret check * skip decimal ret check * skip decimal ret check * fix decimal tests * fix decimal ci test * decimal test * fix(tmq): heap user after free * fix(tmq): double free * fix(tmq): double free * fix decimal tests * fix(decimal): decimal test ci build * fix(decimal): windows build * fix(decimal): decimal test build * fix(decimal): fix decimal build and tests * fix(decimal): fix decimal tests * fix(decimal): fix taos_fetch_fields_e api * fix(decimal): fix decimal taos_fetch_fields_e api * fix(decimal): rebase 3.0 * fix(decimal): fix decimal functions * fix(decimal): fix decimal test case memory leak * fix(decimal): fix decimal tests * fix(decimal): fix decimal test case * fix(decimal): fix decimal tests * feat(decimal): fix unit tests * feat(decimal): fix deicmal unit test --------- Co-authored-by: wangmm0220 <wangmm0220@gmail.com> Co-authored-by: yihaoDeng <yhdeng@taosdata.com>
2025-03-14 10:08:07 +00:00
VALUE_SET_TRIVIAL_DATUM(&pVal->value, (*(int64_t*)&dv));
2022-11-27 09:09:02 +00:00
break;
2022-05-31 09:49:33 +00:00
}
case TSDB_DATA_TYPE_BINARY: {
// Too long values will raise the invalid sql error message
if (pToken->n + VARSTR_HEADER_SIZE > pSchema->bytes) {
2022-11-04 07:21:38 +00:00
return generateSyntaxErrMsg(&pCxt->msg, TSDB_CODE_PAR_VALUE_TOO_LONG, pSchema->name);
2022-04-16 09:47:42 +00:00
}
2022-12-07 02:29:17 +00:00
pVal->value.pData = taosMemoryMalloc(pToken->n);
if (NULL == pVal->value.pData) {
2024-09-20 09:48:04 +00:00
return terrno;
2022-12-07 02:29:17 +00:00
}
memcpy(pVal->value.pData, pToken->z, pToken->n);
2022-11-27 09:09:02 +00:00
pVal->value.nData = pToken->n;
break;
2022-10-17 08:54:12 +00:00
}
2023-08-15 05:57:05 +00:00
case TSDB_DATA_TYPE_VARBINARY: {
2023-08-25 07:43:45 +00:00
int32_t code = parseVarbinary(pToken, &pVal->value.pData, &pVal->value.nData, pSchema->bytes);
2024-03-10 14:14:57 +00:00
if (code != TSDB_CODE_SUCCESS) {
2023-08-25 07:43:45 +00:00
return generateSyntaxErrMsg(&pCxt->msg, code, pSchema->name);
2023-08-15 05:57:05 +00:00
}
break;
}
2022-11-04 07:21:38 +00:00
case TSDB_DATA_TYPE_NCHAR: {
2022-11-27 09:09:02 +00:00
// if the converted output len is over than pColumnModel->bytes, return error: 'Argument list too long'
int32_t len = 0;
2024-04-09 11:33:32 +00:00
int64_t realLen = pToken->n << 2;
if (realLen > pSchema->bytes - VARSTR_HEADER_SIZE) realLen = pSchema->bytes - VARSTR_HEADER_SIZE;
char* pUcs4 = taosMemoryMalloc(realLen);
2022-11-27 09:09:02 +00:00
if (NULL == pUcs4) {
2024-09-20 09:48:04 +00:00
return terrno;
2022-11-27 09:09:02 +00:00
}
if (!taosMbsToUcs4(pToken->z, pToken->n, (TdUcs4*)pUcs4, realLen, &len, pCxt->pComCxt->charsetCxt)) {
taosMemoryFree(pUcs4);
2024-09-12 06:02:19 +00:00
if (terrno == TAOS_SYSTEM_ERROR(E2BIG)) {
2022-11-27 09:09:02 +00:00
return generateSyntaxErrMsg(&pCxt->msg, TSDB_CODE_PAR_VALUE_TOO_LONG, pSchema->name);
}
char buf[512] = {0};
2024-09-12 06:02:19 +00:00
snprintf(buf, tListLen(buf), "%s", strerror(terrno));
2022-11-27 09:09:02 +00:00
return buildSyntaxErrMsg(&pCxt->msg, buf, pToken->z);
}
pVal->value.pData = pUcs4;
pVal->value.nData = len;
break;
}
2022-11-04 07:21:38 +00:00
case TSDB_DATA_TYPE_JSON: {
if (pToken->n > (TSDB_MAX_JSON_TAG_LEN - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE) {
return buildSyntaxErrMsg(&pCxt->msg, "json string too long than 4095", pToken->z);
}
2022-12-07 02:29:17 +00:00
pVal->value.pData = taosMemoryMalloc(pToken->n);
if (NULL == pVal->value.pData) {
2024-09-20 09:48:04 +00:00
return terrno;
2022-12-07 02:29:17 +00:00
}
memcpy(pVal->value.pData, pToken->z, pToken->n);
2022-11-27 09:09:02 +00:00
pVal->value.nData = pToken->n;
break;
}
Feature/3.0 geometry (#21037) * Add GEOMETRY data type and make sql.c able to parse it. The GEMETRY works like BINARY so far. * add GEOMETRY type into gConvertTypes to fix some issues like DELETE calling * change some test cases to make sure no same timestamp is inserted, and add my smoketest.sh * Add a function MakePoint() and introduce a lib geometry * implement sql functions GeomFromText() and AsText() * Use GEOS *_r funcions instead for thread safety * Handle with TSDB_DATA_TYPE_GEOMETRY when INSERT geometry data by converting WKT. Add geosWrapper to wrap the basic GEOS functions for TDEngine. * refactor AsText and MakePoint functions to be like GeomFromText * Show WKT when print geometry data in screen Dump hex data when dump geometry data in a file * define TYPE_BYTES item for TSDB_DATA_TYPE_GEOMETRY, which casued some strange issues. * set number of decimals of WKT to 6 * Implement SQL function Intersects() * refactor geometry sql functions * Add geosErrMsgeHandler() to get the GEOS error detail * use threadlocal to instantiate SGeosContext call destroyGeosContext() only if the thread exists * remove SGeosContext *context param for all geometry functions since we use thread local one, so that all caller do not need to know the context. * Modify Intersects() to call PreparedIntersects() when one of param is a constant, which has higher performance. * rename prepareFn() to initCtxFn() to avoid confusion with PreparedFn * Add prefix "ST_" for all geometry functions * move getThreadLocalGeosCtx() and destroyThreadLocalGeosCtx() into util, so that all unit test tools can compile * Add unit test for geometry lib, only test MakePoint so far * refactor and enhance existing cases in geomFuncTest * implement NULL type and NULL value test for geomFuncTest * add test on geomFromText() * add unit test on AsText() in geomFuncTest * combine some makePointFunction test items * add intersectsFunctionTwoColumns test refactor on callGeomFromTextWrapper functions * enhance intersectsFunction test to add cases like input constant , NULL type, NULL value, or wrong content * add more cases into intersectsFunction test * Add basic test on geometry in system test * Add ST_GeomFromText and ST_AsText function test in system test on geometry * add ST_Intersects function test in system test on geometry * support to check expectedErrno in system test on geometry * adjust geomTest unit test and geometry system test * add geometry data type and functions in doc english version * implement touchesFunction() in geometry lib refactor geometry relation functions model * separate gemFuncTest into several src files * add unit test on touchesFunction * support sql function ST_Touches() add system test on ST_Touches * add docs for ST_Touches() * Add ST_Contains() * Add ST_Covers() * Add ST_Equals() * add swapAllowed param for geomRelationFunction() read geom2 earlier intead of at doGeosRelation() * Add ST_ContainsProperly() * build on windows * Merge from 3.0 to 3.0_geometry * change macro definition TSDB_DATA_TYPE_GEOMETRY as the last one for compatibility * change '\\NULL' to 'NULL' back in shellDumpFieldToFile() * add /usr/local/include into include directory * add /usr/local/inlcude and /usr/local/lib in cmake.platform for DARWIN
2023-05-24 07:36:46 +00:00
case TSDB_DATA_TYPE_GEOMETRY: {
2024-03-10 14:14:57 +00:00
int32_t code = TSDB_CODE_FAILED;
unsigned char* output = NULL;
size_t size = 0;
Feature/3.0 geometry (#21037) * Add GEOMETRY data type and make sql.c able to parse it. The GEMETRY works like BINARY so far. * add GEOMETRY type into gConvertTypes to fix some issues like DELETE calling * change some test cases to make sure no same timestamp is inserted, and add my smoketest.sh * Add a function MakePoint() and introduce a lib geometry * implement sql functions GeomFromText() and AsText() * Use GEOS *_r funcions instead for thread safety * Handle with TSDB_DATA_TYPE_GEOMETRY when INSERT geometry data by converting WKT. Add geosWrapper to wrap the basic GEOS functions for TDEngine. * refactor AsText and MakePoint functions to be like GeomFromText * Show WKT when print geometry data in screen Dump hex data when dump geometry data in a file * define TYPE_BYTES item for TSDB_DATA_TYPE_GEOMETRY, which casued some strange issues. * set number of decimals of WKT to 6 * Implement SQL function Intersects() * refactor geometry sql functions * Add geosErrMsgeHandler() to get the GEOS error detail * use threadlocal to instantiate SGeosContext call destroyGeosContext() only if the thread exists * remove SGeosContext *context param for all geometry functions since we use thread local one, so that all caller do not need to know the context. * Modify Intersects() to call PreparedIntersects() when one of param is a constant, which has higher performance. * rename prepareFn() to initCtxFn() to avoid confusion with PreparedFn * Add prefix "ST_" for all geometry functions * move getThreadLocalGeosCtx() and destroyThreadLocalGeosCtx() into util, so that all unit test tools can compile * Add unit test for geometry lib, only test MakePoint so far * refactor and enhance existing cases in geomFuncTest * implement NULL type and NULL value test for geomFuncTest * add test on geomFromText() * add unit test on AsText() in geomFuncTest * combine some makePointFunction test items * add intersectsFunctionTwoColumns test refactor on callGeomFromTextWrapper functions * enhance intersectsFunction test to add cases like input constant , NULL type, NULL value, or wrong content * add more cases into intersectsFunction test * Add basic test on geometry in system test * Add ST_GeomFromText and ST_AsText function test in system test on geometry * add ST_Intersects function test in system test on geometry * support to check expectedErrno in system test on geometry * adjust geomTest unit test and geometry system test * add geometry data type and functions in doc english version * implement touchesFunction() in geometry lib refactor geometry relation functions model * separate gemFuncTest into several src files * add unit test on touchesFunction * support sql function ST_Touches() add system test on ST_Touches * add docs for ST_Touches() * Add ST_Contains() * Add ST_Covers() * Add ST_Equals() * add swapAllowed param for geomRelationFunction() read geom2 earlier intead of at doGeosRelation() * Add ST_ContainsProperly() * build on windows * Merge from 3.0 to 3.0_geometry * change macro definition TSDB_DATA_TYPE_GEOMETRY as the last one for compatibility * change '\\NULL' to 'NULL' back in shellDumpFieldToFile() * add /usr/local/include into include directory * add /usr/local/inlcude and /usr/local/lib in cmake.platform for DARWIN
2023-05-24 07:36:46 +00:00
code = parseGeometry(pToken, &output, &size);
if (code != TSDB_CODE_SUCCESS) {
2024-08-21 07:45:57 +00:00
code = buildSyntaxErrMsg(&pCxt->msg, getGeosErrMsg(code), pToken->z);
Feature/3.0 geometry (#21037) * Add GEOMETRY data type and make sql.c able to parse it. The GEMETRY works like BINARY so far. * add GEOMETRY type into gConvertTypes to fix some issues like DELETE calling * change some test cases to make sure no same timestamp is inserted, and add my smoketest.sh * Add a function MakePoint() and introduce a lib geometry * implement sql functions GeomFromText() and AsText() * Use GEOS *_r funcions instead for thread safety * Handle with TSDB_DATA_TYPE_GEOMETRY when INSERT geometry data by converting WKT. Add geosWrapper to wrap the basic GEOS functions for TDEngine. * refactor AsText and MakePoint functions to be like GeomFromText * Show WKT when print geometry data in screen Dump hex data when dump geometry data in a file * define TYPE_BYTES item for TSDB_DATA_TYPE_GEOMETRY, which casued some strange issues. * set number of decimals of WKT to 6 * Implement SQL function Intersects() * refactor geometry sql functions * Add geosErrMsgeHandler() to get the GEOS error detail * use threadlocal to instantiate SGeosContext call destroyGeosContext() only if the thread exists * remove SGeosContext *context param for all geometry functions since we use thread local one, so that all caller do not need to know the context. * Modify Intersects() to call PreparedIntersects() when one of param is a constant, which has higher performance. * rename prepareFn() to initCtxFn() to avoid confusion with PreparedFn * Add prefix "ST_" for all geometry functions * move getThreadLocalGeosCtx() and destroyThreadLocalGeosCtx() into util, so that all unit test tools can compile * Add unit test for geometry lib, only test MakePoint so far * refactor and enhance existing cases in geomFuncTest * implement NULL type and NULL value test for geomFuncTest * add test on geomFromText() * add unit test on AsText() in geomFuncTest * combine some makePointFunction test items * add intersectsFunctionTwoColumns test refactor on callGeomFromTextWrapper functions * enhance intersectsFunction test to add cases like input constant , NULL type, NULL value, or wrong content * add more cases into intersectsFunction test * Add basic test on geometry in system test * Add ST_GeomFromText and ST_AsText function test in system test on geometry * add ST_Intersects function test in system test on geometry * support to check expectedErrno in system test on geometry * adjust geomTest unit test and geometry system test * add geometry data type and functions in doc english version * implement touchesFunction() in geometry lib refactor geometry relation functions model * separate gemFuncTest into several src files * add unit test on touchesFunction * support sql function ST_Touches() add system test on ST_Touches * add docs for ST_Touches() * Add ST_Contains() * Add ST_Covers() * Add ST_Equals() * add swapAllowed param for geomRelationFunction() read geom2 earlier intead of at doGeosRelation() * Add ST_ContainsProperly() * build on windows * Merge from 3.0 to 3.0_geometry * change macro definition TSDB_DATA_TYPE_GEOMETRY as the last one for compatibility * change '\\NULL' to 'NULL' back in shellDumpFieldToFile() * add /usr/local/include into include directory * add /usr/local/inlcude and /usr/local/lib in cmake.platform for DARWIN
2023-05-24 07:36:46 +00:00
}
// Too long values will raise the invalid sql error message
else if (size + VARSTR_HEADER_SIZE > pSchema->bytes) {
Feature/3.0 geometry (#21037) * Add GEOMETRY data type and make sql.c able to parse it. The GEMETRY works like BINARY so far. * add GEOMETRY type into gConvertTypes to fix some issues like DELETE calling * change some test cases to make sure no same timestamp is inserted, and add my smoketest.sh * Add a function MakePoint() and introduce a lib geometry * implement sql functions GeomFromText() and AsText() * Use GEOS *_r funcions instead for thread safety * Handle with TSDB_DATA_TYPE_GEOMETRY when INSERT geometry data by converting WKT. Add geosWrapper to wrap the basic GEOS functions for TDEngine. * refactor AsText and MakePoint functions to be like GeomFromText * Show WKT when print geometry data in screen Dump hex data when dump geometry data in a file * define TYPE_BYTES item for TSDB_DATA_TYPE_GEOMETRY, which casued some strange issues. * set number of decimals of WKT to 6 * Implement SQL function Intersects() * refactor geometry sql functions * Add geosErrMsgeHandler() to get the GEOS error detail * use threadlocal to instantiate SGeosContext call destroyGeosContext() only if the thread exists * remove SGeosContext *context param for all geometry functions since we use thread local one, so that all caller do not need to know the context. * Modify Intersects() to call PreparedIntersects() when one of param is a constant, which has higher performance. * rename prepareFn() to initCtxFn() to avoid confusion with PreparedFn * Add prefix "ST_" for all geometry functions * move getThreadLocalGeosCtx() and destroyThreadLocalGeosCtx() into util, so that all unit test tools can compile * Add unit test for geometry lib, only test MakePoint so far * refactor and enhance existing cases in geomFuncTest * implement NULL type and NULL value test for geomFuncTest * add test on geomFromText() * add unit test on AsText() in geomFuncTest * combine some makePointFunction test items * add intersectsFunctionTwoColumns test refactor on callGeomFromTextWrapper functions * enhance intersectsFunction test to add cases like input constant , NULL type, NULL value, or wrong content * add more cases into intersectsFunction test * Add basic test on geometry in system test * Add ST_GeomFromText and ST_AsText function test in system test on geometry * add ST_Intersects function test in system test on geometry * support to check expectedErrno in system test on geometry * adjust geomTest unit test and geometry system test * add geometry data type and functions in doc english version * implement touchesFunction() in geometry lib refactor geometry relation functions model * separate gemFuncTest into several src files * add unit test on touchesFunction * support sql function ST_Touches() add system test on ST_Touches * add docs for ST_Touches() * Add ST_Contains() * Add ST_Covers() * Add ST_Equals() * add swapAllowed param for geomRelationFunction() read geom2 earlier intead of at doGeosRelation() * Add ST_ContainsProperly() * build on windows * Merge from 3.0 to 3.0_geometry * change macro definition TSDB_DATA_TYPE_GEOMETRY as the last one for compatibility * change '\\NULL' to 'NULL' back in shellDumpFieldToFile() * add /usr/local/include into include directory * add /usr/local/inlcude and /usr/local/lib in cmake.platform for DARWIN
2023-05-24 07:36:46 +00:00
code = generateSyntaxErrMsg(&pCxt->msg, TSDB_CODE_PAR_VALUE_TOO_LONG, pSchema->name);
2024-03-10 14:14:57 +00:00
} else {
Feature/3.0 geometry (#21037) * Add GEOMETRY data type and make sql.c able to parse it. The GEMETRY works like BINARY so far. * add GEOMETRY type into gConvertTypes to fix some issues like DELETE calling * change some test cases to make sure no same timestamp is inserted, and add my smoketest.sh * Add a function MakePoint() and introduce a lib geometry * implement sql functions GeomFromText() and AsText() * Use GEOS *_r funcions instead for thread safety * Handle with TSDB_DATA_TYPE_GEOMETRY when INSERT geometry data by converting WKT. Add geosWrapper to wrap the basic GEOS functions for TDEngine. * refactor AsText and MakePoint functions to be like GeomFromText * Show WKT when print geometry data in screen Dump hex data when dump geometry data in a file * define TYPE_BYTES item for TSDB_DATA_TYPE_GEOMETRY, which casued some strange issues. * set number of decimals of WKT to 6 * Implement SQL function Intersects() * refactor geometry sql functions * Add geosErrMsgeHandler() to get the GEOS error detail * use threadlocal to instantiate SGeosContext call destroyGeosContext() only if the thread exists * remove SGeosContext *context param for all geometry functions since we use thread local one, so that all caller do not need to know the context. * Modify Intersects() to call PreparedIntersects() when one of param is a constant, which has higher performance. * rename prepareFn() to initCtxFn() to avoid confusion with PreparedFn * Add prefix "ST_" for all geometry functions * move getThreadLocalGeosCtx() and destroyThreadLocalGeosCtx() into util, so that all unit test tools can compile * Add unit test for geometry lib, only test MakePoint so far * refactor and enhance existing cases in geomFuncTest * implement NULL type and NULL value test for geomFuncTest * add test on geomFromText() * add unit test on AsText() in geomFuncTest * combine some makePointFunction test items * add intersectsFunctionTwoColumns test refactor on callGeomFromTextWrapper functions * enhance intersectsFunction test to add cases like input constant , NULL type, NULL value, or wrong content * add more cases into intersectsFunction test * Add basic test on geometry in system test * Add ST_GeomFromText and ST_AsText function test in system test on geometry * add ST_Intersects function test in system test on geometry * support to check expectedErrno in system test on geometry * adjust geomTest unit test and geometry system test * add geometry data type and functions in doc english version * implement touchesFunction() in geometry lib refactor geometry relation functions model * separate gemFuncTest into several src files * add unit test on touchesFunction * support sql function ST_Touches() add system test on ST_Touches * add docs for ST_Touches() * Add ST_Contains() * Add ST_Covers() * Add ST_Equals() * add swapAllowed param for geomRelationFunction() read geom2 earlier intead of at doGeosRelation() * Add ST_ContainsProperly() * build on windows * Merge from 3.0 to 3.0_geometry * change macro definition TSDB_DATA_TYPE_GEOMETRY as the last one for compatibility * change '\\NULL' to 'NULL' back in shellDumpFieldToFile() * add /usr/local/include into include directory * add /usr/local/inlcude and /usr/local/lib in cmake.platform for DARWIN
2023-05-24 07:36:46 +00:00
pVal->value.pData = taosMemoryMalloc(size);
if (NULL == pVal->value.pData) {
2024-09-20 09:48:04 +00:00
code = terrno;
2024-03-10 14:14:57 +00:00
} else {
Feature/3.0 geometry (#21037) * Add GEOMETRY data type and make sql.c able to parse it. The GEMETRY works like BINARY so far. * add GEOMETRY type into gConvertTypes to fix some issues like DELETE calling * change some test cases to make sure no same timestamp is inserted, and add my smoketest.sh * Add a function MakePoint() and introduce a lib geometry * implement sql functions GeomFromText() and AsText() * Use GEOS *_r funcions instead for thread safety * Handle with TSDB_DATA_TYPE_GEOMETRY when INSERT geometry data by converting WKT. Add geosWrapper to wrap the basic GEOS functions for TDEngine. * refactor AsText and MakePoint functions to be like GeomFromText * Show WKT when print geometry data in screen Dump hex data when dump geometry data in a file * define TYPE_BYTES item for TSDB_DATA_TYPE_GEOMETRY, which casued some strange issues. * set number of decimals of WKT to 6 * Implement SQL function Intersects() * refactor geometry sql functions * Add geosErrMsgeHandler() to get the GEOS error detail * use threadlocal to instantiate SGeosContext call destroyGeosContext() only if the thread exists * remove SGeosContext *context param for all geometry functions since we use thread local one, so that all caller do not need to know the context. * Modify Intersects() to call PreparedIntersects() when one of param is a constant, which has higher performance. * rename prepareFn() to initCtxFn() to avoid confusion with PreparedFn * Add prefix "ST_" for all geometry functions * move getThreadLocalGeosCtx() and destroyThreadLocalGeosCtx() into util, so that all unit test tools can compile * Add unit test for geometry lib, only test MakePoint so far * refactor and enhance existing cases in geomFuncTest * implement NULL type and NULL value test for geomFuncTest * add test on geomFromText() * add unit test on AsText() in geomFuncTest * combine some makePointFunction test items * add intersectsFunctionTwoColumns test refactor on callGeomFromTextWrapper functions * enhance intersectsFunction test to add cases like input constant , NULL type, NULL value, or wrong content * add more cases into intersectsFunction test * Add basic test on geometry in system test * Add ST_GeomFromText and ST_AsText function test in system test on geometry * add ST_Intersects function test in system test on geometry * support to check expectedErrno in system test on geometry * adjust geomTest unit test and geometry system test * add geometry data type and functions in doc english version * implement touchesFunction() in geometry lib refactor geometry relation functions model * separate gemFuncTest into several src files * add unit test on touchesFunction * support sql function ST_Touches() add system test on ST_Touches * add docs for ST_Touches() * Add ST_Contains() * Add ST_Covers() * Add ST_Equals() * add swapAllowed param for geomRelationFunction() read geom2 earlier intead of at doGeosRelation() * Add ST_ContainsProperly() * build on windows * Merge from 3.0 to 3.0_geometry * change macro definition TSDB_DATA_TYPE_GEOMETRY as the last one for compatibility * change '\\NULL' to 'NULL' back in shellDumpFieldToFile() * add /usr/local/include into include directory * add /usr/local/inlcude and /usr/local/lib in cmake.platform for DARWIN
2023-05-24 07:36:46 +00:00
memcpy(pVal->value.pData, output, size);
pVal->value.nData = size;
}
}
geosFreeBuffer(output);
if (code != TSDB_CODE_SUCCESS) {
return code;
}
break;
}
2022-11-04 07:21:38 +00:00
case TSDB_DATA_TYPE_TIMESTAMP: {
feat(decimal): support decimal data type (#30060) * decimal: create table * decimal: add test case decimal.py * decimal: add decimal.c * support input decimal * decimal test * refactor svalue * fix test cases * add decimal unit test * add decimal test cmake * support insert and query decimal type * define wide integer, support decimal128 * support decimal128 divide * set decimal type expr res types * scalar decimal * convert to decimal * fix decimal64/128 from str and to str * fix decimal from str and decimal to str * decimal simple conversion * unit test for decimal * decimal conversion and unit tests * decimal + - * / * decimal scalar ops and comparision * start to refactor GET_TYPED_DATA * support decimal max func, cast func * refactor GET_TYPED_DATA interface * decimal scalar comparision * start to implement sum for decimal * support sum and avg for decimal type * decimal tests * add decimal test * decimal add test cases * decimal use int256/int128 * decimal testing * fix decimal table meta and add tests for decimal col streams * fix create stream and create tsma * test insert decimal values * decimal from str * test decimal input * test parse decimal from string * add taos_fetch_field_e api * decimal insert tests * test decimal operators * decimal operator test * feat:support decimal in raw block * decimal operator tests * decimal test * feat:support decimal in raw block * feat:support decimal in raw block * feat:add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * decimal test operators * decimal operator test * test decimal operators * test decimal compare operators * decimal unary operator test * decimal col with decimal col oper test * test decimal col filtering * fix decimal float operator test * decimal test where filtering * fix decimal filtering * fix decimal order by * fix decimal op test * test decimal agg funcs * test decimal functions * remove assert * fix ci build for ret check * fix decimal windows build * fix ci ret check * skip decimal ret check * skip decimal ret check * fix decimal tests * fix decimal ci test * decimal test * fix(tmq): heap user after free * fix(tmq): double free * fix(tmq): double free * fix decimal tests * fix(decimal): decimal test ci build * fix(decimal): windows build * fix(decimal): decimal test build * fix(decimal): fix decimal build and tests * fix(decimal): fix decimal tests * fix(decimal): fix taos_fetch_fields_e api * fix(decimal): fix decimal taos_fetch_fields_e api * fix(decimal): rebase 3.0 * fix(decimal): fix decimal functions * fix(decimal): fix decimal test case memory leak * fix(decimal): fix decimal tests * fix(decimal): fix decimal test case * fix(decimal): fix decimal tests * feat(decimal): fix unit tests * feat(decimal): fix deicmal unit test --------- Co-authored-by: wangmm0220 <wangmm0220@gmail.com> Co-authored-by: yihaoDeng <yhdeng@taosdata.com>
2025-03-14 10:08:07 +00:00
if (parseTime(pSql, pToken, timePrec, &VALUE_GET_TRIVIAL_DATUM(&pVal->value), &pCxt->msg,
pCxt->pComCxt->timezone) != TSDB_CODE_SUCCESS) {
2022-11-04 07:21:38 +00:00
return buildSyntaxErrMsg(&pCxt->msg, "invalid timestamp", pToken->z);
}
2022-11-27 09:09:02 +00:00
break;
2022-11-04 07:21:38 +00:00
}
feat(decimal): support decimal data type (#30060) * decimal: create table * decimal: add test case decimal.py * decimal: add decimal.c * support input decimal * decimal test * refactor svalue * fix test cases * add decimal unit test * add decimal test cmake * support insert and query decimal type * define wide integer, support decimal128 * support decimal128 divide * set decimal type expr res types * scalar decimal * convert to decimal * fix decimal64/128 from str and to str * fix decimal from str and decimal to str * decimal simple conversion * unit test for decimal * decimal conversion and unit tests * decimal + - * / * decimal scalar ops and comparision * start to refactor GET_TYPED_DATA * support decimal max func, cast func * refactor GET_TYPED_DATA interface * decimal scalar comparision * start to implement sum for decimal * support sum and avg for decimal type * decimal tests * add decimal test * decimal add test cases * decimal use int256/int128 * decimal testing * fix decimal table meta and add tests for decimal col streams * fix create stream and create tsma * test insert decimal values * decimal from str * test decimal input * test parse decimal from string * add taos_fetch_field_e api * decimal insert tests * test decimal operators * decimal operator test * feat:support decimal in raw block * decimal operator tests * decimal test * feat:support decimal in raw block * feat:support decimal in raw block * feat:add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * decimal test operators * decimal operator test * test decimal operators * test decimal compare operators * decimal unary operator test * decimal col with decimal col oper test * test decimal col filtering * fix decimal float operator test * decimal test where filtering * fix decimal filtering * fix decimal order by * fix decimal op test * test decimal agg funcs * test decimal functions * remove assert * fix ci build for ret check * fix decimal windows build * fix ci ret check * skip decimal ret check * skip decimal ret check * fix decimal tests * fix decimal ci test * decimal test * fix(tmq): heap user after free * fix(tmq): double free * fix(tmq): double free * fix decimal tests * fix(decimal): decimal test ci build * fix(decimal): windows build * fix(decimal): decimal test build * fix(decimal): fix decimal build and tests * fix(decimal): fix decimal tests * fix(decimal): fix taos_fetch_fields_e api * fix(decimal): fix decimal taos_fetch_fields_e api * fix(decimal): rebase 3.0 * fix(decimal): fix decimal functions * fix(decimal): fix decimal test case memory leak * fix(decimal): fix decimal tests * fix(decimal): fix decimal test case * fix(decimal): fix decimal tests * feat(decimal): fix unit tests * feat(decimal): fix deicmal unit test --------- Co-authored-by: wangmm0220 <wangmm0220@gmail.com> Co-authored-by: yihaoDeng <yhdeng@taosdata.com>
2025-03-14 10:08:07 +00:00
case TSDB_DATA_TYPE_DECIMAL: {
if (!pExtSchema) {
qError("Decimal type without ext schema info, cannot parse decimal values");
return TSDB_CODE_PAR_INTERNAL_ERROR;
}
uint8_t precision = 0, scale = 0;
decimalFromTypeMod(pExtSchema->typeMod, &precision, &scale);
Decimal128 dec = {0};
int32_t code = decimal128FromStr(pToken->z, pToken->n, precision, scale, &dec);
if (TSDB_CODE_SUCCESS != code) {
return code;
}
// precision check
// scale auto fit
code = decimal128ToDataVal(&dec, &pVal->value);
if (TSDB_CODE_SUCCESS != code) {
return code;
}
break;
}
case TSDB_DATA_TYPE_DECIMAL64: {
if (!pExtSchema) {
qError("Decimal type without ext schema info, cannot parse decimal values");
return TSDB_CODE_PAR_INTERNAL_ERROR;
}
uint8_t precision = 0, scale = 0;
decimalFromTypeMod(pExtSchema->typeMod, &precision, &scale);
Decimal64 dec = {0};
int32_t code = decimal64FromStr(pToken->z, pToken->n, precision, scale, &dec);
if (TSDB_CODE_SUCCESS != code) {
return code;
}
code = decimal64ToDataVal(&dec, &pVal->value);
if (TSDB_CODE_SUCCESS != code) {
return code;
}
break;
}
2022-11-27 09:09:02 +00:00
default:
return TSDB_CODE_FAILED;
2022-04-02 02:37:47 +00:00
}
2022-11-27 16:08:41 +00:00
pVal->flag = CV_FLAG_VALUE;
2022-11-27 09:09:02 +00:00
return TSDB_CODE_SUCCESS;
2022-11-04 07:21:38 +00:00
}
2022-05-10 07:50:41 +00:00
2022-11-04 07:21:38 +00:00
static int32_t parseValueToken(SInsertParseContext* pCxt, const char** pSql, SToken* pToken, SSchema* pSchema,
feat(decimal): support decimal data type (#30060) * decimal: create table * decimal: add test case decimal.py * decimal: add decimal.c * support input decimal * decimal test * refactor svalue * fix test cases * add decimal unit test * add decimal test cmake * support insert and query decimal type * define wide integer, support decimal128 * support decimal128 divide * set decimal type expr res types * scalar decimal * convert to decimal * fix decimal64/128 from str and to str * fix decimal from str and decimal to str * decimal simple conversion * unit test for decimal * decimal conversion and unit tests * decimal + - * / * decimal scalar ops and comparision * start to refactor GET_TYPED_DATA * support decimal max func, cast func * refactor GET_TYPED_DATA interface * decimal scalar comparision * start to implement sum for decimal * support sum and avg for decimal type * decimal tests * add decimal test * decimal add test cases * decimal use int256/int128 * decimal testing * fix decimal table meta and add tests for decimal col streams * fix create stream and create tsma * test insert decimal values * decimal from str * test decimal input * test parse decimal from string * add taos_fetch_field_e api * decimal insert tests * test decimal operators * decimal operator test * feat:support decimal in raw block * decimal operator tests * decimal test * feat:support decimal in raw block * feat:support decimal in raw block * feat:add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * decimal test operators * decimal operator test * test decimal operators * test decimal compare operators * decimal unary operator test * decimal col with decimal col oper test * test decimal col filtering * fix decimal float operator test * decimal test where filtering * fix decimal filtering * fix decimal order by * fix decimal op test * test decimal agg funcs * test decimal functions * remove assert * fix ci build for ret check * fix decimal windows build * fix ci ret check * skip decimal ret check * skip decimal ret check * fix decimal tests * fix decimal ci test * decimal test * fix(tmq): heap user after free * fix(tmq): double free * fix(tmq): double free * fix decimal tests * fix(decimal): decimal test ci build * fix(decimal): windows build * fix(decimal): decimal test build * fix(decimal): fix decimal build and tests * fix(decimal): fix decimal tests * fix(decimal): fix taos_fetch_fields_e api * fix(decimal): fix decimal taos_fetch_fields_e api * fix(decimal): rebase 3.0 * fix(decimal): fix decimal functions * fix(decimal): fix decimal test case memory leak * fix(decimal): fix decimal tests * fix(decimal): fix decimal test case * fix(decimal): fix decimal tests * feat(decimal): fix unit tests * feat(decimal): fix deicmal unit test --------- Co-authored-by: wangmm0220 <wangmm0220@gmail.com> Co-authored-by: yihaoDeng <yhdeng@taosdata.com>
2025-03-14 10:08:07 +00:00
const SSchemaExt* pExtSchema, int16_t timePrec, SColVal* pVal) {
int32_t code = checkAndTrimValue(pToken, pCxt->tmpTokenBuf, &pCxt->msg, pSchema->type);
2022-11-04 07:21:38 +00:00
if (TSDB_CODE_SUCCESS == code && isNullValue(pSchema->type, pToken)) {
if (TSDB_DATA_TYPE_TIMESTAMP == pSchema->type && PRIMARYKEY_TIMESTAMP_COL_ID == pSchema->colId) {
2024-04-02 07:04:13 +00:00
return buildSyntaxErrMsg(&pCxt->msg, "Primary timestamp column should not be null", pToken->z);
2022-11-04 07:21:38 +00:00
}
2022-11-27 09:09:02 +00:00
pVal->flag = CV_FLAG_NULL;
return TSDB_CODE_SUCCESS;
}
2022-11-04 07:21:38 +00:00
if (TSDB_CODE_SUCCESS == code) {
2024-03-10 14:14:57 +00:00
if (pToken->n == 0 && IS_NUMERIC_TYPE(pSchema->type)) {
return buildSyntaxErrMsg(&pCxt->msg, "invalid numeric data", pToken->z);
}
feat(decimal): support decimal data type (#30060) * decimal: create table * decimal: add test case decimal.py * decimal: add decimal.c * support input decimal * decimal test * refactor svalue * fix test cases * add decimal unit test * add decimal test cmake * support insert and query decimal type * define wide integer, support decimal128 * support decimal128 divide * set decimal type expr res types * scalar decimal * convert to decimal * fix decimal64/128 from str and to str * fix decimal from str and decimal to str * decimal simple conversion * unit test for decimal * decimal conversion and unit tests * decimal + - * / * decimal scalar ops and comparision * start to refactor GET_TYPED_DATA * support decimal max func, cast func * refactor GET_TYPED_DATA interface * decimal scalar comparision * start to implement sum for decimal * support sum and avg for decimal type * decimal tests * add decimal test * decimal add test cases * decimal use int256/int128 * decimal testing * fix decimal table meta and add tests for decimal col streams * fix create stream and create tsma * test insert decimal values * decimal from str * test decimal input * test parse decimal from string * add taos_fetch_field_e api * decimal insert tests * test decimal operators * decimal operator test * feat:support decimal in raw block * decimal operator tests * decimal test * feat:support decimal in raw block * feat:support decimal in raw block * feat:add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * decimal test operators * decimal operator test * test decimal operators * test decimal compare operators * decimal unary operator test * decimal col with decimal col oper test * test decimal col filtering * fix decimal float operator test * decimal test where filtering * fix decimal filtering * fix decimal order by * fix decimal op test * test decimal agg funcs * test decimal functions * remove assert * fix ci build for ret check * fix decimal windows build * fix ci ret check * skip decimal ret check * skip decimal ret check * fix decimal tests * fix decimal ci test * decimal test * fix(tmq): heap user after free * fix(tmq): double free * fix(tmq): double free * fix decimal tests * fix(decimal): decimal test ci build * fix(decimal): windows build * fix(decimal): decimal test build * fix(decimal): fix decimal build and tests * fix(decimal): fix decimal tests * fix(decimal): fix taos_fetch_fields_e api * fix(decimal): fix decimal taos_fetch_fields_e api * fix(decimal): rebase 3.0 * fix(decimal): fix decimal functions * fix(decimal): fix decimal test case memory leak * fix(decimal): fix decimal tests * fix(decimal): fix decimal test case * fix(decimal): fix decimal tests * feat(decimal): fix unit tests * feat(decimal): fix deicmal unit test --------- Co-authored-by: wangmm0220 <wangmm0220@gmail.com> Co-authored-by: yihaoDeng <yhdeng@taosdata.com>
2025-03-14 10:08:07 +00:00
code = parseValueTokenImpl(pCxt, pSql, pToken, pSchema, pExtSchema, timePrec, pVal);
2022-04-02 07:27:07 +00:00
}
2022-11-04 07:21:38 +00:00
return code;
}
2023-08-25 08:32:01 +00:00
static void clearColValArray(SArray* pCols) {
2022-12-06 12:40:18 +00:00
int32_t num = taosArrayGetSize(pCols);
for (int32_t i = 0; i < num; ++i) {
SColVal* pCol = taosArrayGet(pCols, i);
feat(decimal): support decimal data type (#30060) * decimal: create table * decimal: add test case decimal.py * decimal: add decimal.c * support input decimal * decimal test * refactor svalue * fix test cases * add decimal unit test * add decimal test cmake * support insert and query decimal type * define wide integer, support decimal128 * support decimal128 divide * set decimal type expr res types * scalar decimal * convert to decimal * fix decimal64/128 from str and to str * fix decimal from str and decimal to str * decimal simple conversion * unit test for decimal * decimal conversion and unit tests * decimal + - * / * decimal scalar ops and comparision * start to refactor GET_TYPED_DATA * support decimal max func, cast func * refactor GET_TYPED_DATA interface * decimal scalar comparision * start to implement sum for decimal * support sum and avg for decimal type * decimal tests * add decimal test * decimal add test cases * decimal use int256/int128 * decimal testing * fix decimal table meta and add tests for decimal col streams * fix create stream and create tsma * test insert decimal values * decimal from str * test decimal input * test parse decimal from string * add taos_fetch_field_e api * decimal insert tests * test decimal operators * decimal operator test * feat:support decimal in raw block * decimal operator tests * decimal test * feat:support decimal in raw block * feat:support decimal in raw block * feat:add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * decimal test operators * decimal operator test * test decimal operators * test decimal compare operators * decimal unary operator test * decimal col with decimal col oper test * test decimal col filtering * fix decimal float operator test * decimal test where filtering * fix decimal filtering * fix decimal order by * fix decimal op test * test decimal agg funcs * test decimal functions * remove assert * fix ci build for ret check * fix decimal windows build * fix ci ret check * skip decimal ret check * skip decimal ret check * fix decimal tests * fix decimal ci test * decimal test * fix(tmq): heap user after free * fix(tmq): double free * fix(tmq): double free * fix decimal tests * fix(decimal): decimal test ci build * fix(decimal): windows build * fix(decimal): decimal test build * fix(decimal): fix decimal build and tests * fix(decimal): fix decimal tests * fix(decimal): fix taos_fetch_fields_e api * fix(decimal): fix decimal taos_fetch_fields_e api * fix(decimal): rebase 3.0 * fix(decimal): fix decimal functions * fix(decimal): fix decimal test case memory leak * fix(decimal): fix decimal tests * fix(decimal): fix decimal test case * fix(decimal): fix decimal tests * feat(decimal): fix unit tests * feat(decimal): fix deicmal unit test --------- Co-authored-by: wangmm0220 <wangmm0220@gmail.com> Co-authored-by: yihaoDeng <yhdeng@taosdata.com>
2025-03-14 10:08:07 +00:00
if (IS_VAR_DATA_TYPE(pCol->value.type) || pCol->value.type == TSDB_DATA_TYPE_DECIMAL) {
2022-12-06 12:40:18 +00:00
taosMemoryFreeClear(pCol->value.pData);
}
}
}
typedef struct SStbRowsDataContext {
SName stbName;
2024-03-26 07:11:15 +00:00
STableMeta* pStbMeta;
SNode* pTagCond;
2023-10-24 08:08:08 +00:00
SBoundColInfo boundColsInfo;
2023-10-24 08:08:08 +00:00
// the following fields are for each stb row
2024-03-26 07:11:15 +00:00
SArray* aTagVals;
SArray* aColVals;
SArray* aTagNames;
SName ctbName;
STag* pTag;
STableMeta* pCtbMeta;
2023-10-24 08:08:08 +00:00
SVCreateTbReq* pCreateCtbReq;
2023-10-31 02:48:10 +00:00
bool hasTimestampTag;
2023-11-01 00:32:31 +00:00
bool isJsonTag;
} SStbRowsDataContext;
2024-03-26 07:11:15 +00:00
typedef union SRowsDataContext {
STableDataCxt* pTableDataCxt;
SStbRowsDataContext* pStbRowsCxt;
} SRowsDataContext;
2024-06-24 14:13:03 +00:00
int32_t parseTbnameToken(SMsgBuf* pMsgBuf, char* tname, SToken* pToken, bool* pFoundCtbName) {
2023-10-31 06:44:06 +00:00
*pFoundCtbName = false;
2024-06-24 14:13:03 +00:00
if (isNullValue(TSDB_DATA_TYPE_BINARY, pToken)) {
return buildInvalidOperationMsg(pMsgBuf, "tbname can not be null value");
}
2023-10-31 06:44:06 +00:00
2024-06-24 14:13:03 +00:00
if (pToken->n > 0) {
if (pToken->n <= TSDB_TABLE_NAME_LEN - 1) {
for (int i = 0; i < pToken->n; ++i) {
if (pToken->z[i] == '.') {
return buildInvalidOperationMsg(pMsgBuf, "tbname can not contain '.'");
} else {
tname[i] = pToken->z[i];
2023-11-07 03:03:42 +00:00
}
2023-10-31 06:44:06 +00:00
}
2024-06-24 14:13:03 +00:00
tname[pToken->n] = '\0';
*pFoundCtbName = true;
2023-10-31 06:44:06 +00:00
} else {
2024-06-24 14:13:03 +00:00
return buildInvalidOperationMsg(pMsgBuf, "tbname is too long");
2023-10-31 06:44:06 +00:00
}
2024-06-24 14:13:03 +00:00
} else {
return buildInvalidOperationMsg(pMsgBuf, "tbname can not be empty");
2023-10-31 06:44:06 +00:00
}
2024-06-24 14:13:03 +00:00
return TSDB_CODE_SUCCESS;
2023-10-31 06:44:06 +00:00
}
2023-11-01 00:32:31 +00:00
static int32_t processCtbTagsAfterCtbName(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt,
2024-03-26 07:11:15 +00:00
SStbRowsDataContext* pStbRowsCxt, bool ctbFirst, const SToken* tagTokens,
SSchema* const* tagSchemas, int numOfTagTokens) {
2023-11-01 00:32:31 +00:00
int32_t code = TSDB_CODE_SUCCESS;
2024-03-10 14:14:57 +00:00
uint8_t precision = pStmt->pTableMeta->tableInfo.precision;
2023-11-01 00:32:31 +00:00
if (code == TSDB_CODE_SUCCESS && ctbFirst) {
for (int32_t i = 0; code == TSDB_CODE_SUCCESS && i < numOfTagTokens; ++i) {
SToken* pTagToken = (SToken*)(tagTokens + i);
SSchema* pTagSchema = tagSchemas[i];
code = checkAndTrimValue(pTagToken, pCxt->tmpTokenBuf, &pCxt->msg, pTagSchema->type);
2024-03-10 14:14:57 +00:00
if (code == TSDB_CODE_SUCCESS && TK_NK_VARIABLE == pTagToken->type) {
code = buildInvalidOperationMsg(&pCxt->msg, "not expected tag");
}
2023-11-01 00:32:31 +00:00
if (code == TSDB_CODE_SUCCESS) {
2024-03-26 07:11:15 +00:00
code = parseTagValue(&pCxt->msg, NULL, precision, pTagSchema, pTagToken, pStbRowsCxt->aTagNames,
pStbRowsCxt->aTagVals, &pStbRowsCxt->pTag, pCxt->pComCxt->timezone, pCxt->pComCxt->charsetCxt);
2023-11-01 00:32:31 +00:00
}
}
if (code == TSDB_CODE_SUCCESS && !pStbRowsCxt->isJsonTag) {
code = tTagNew(pStbRowsCxt->aTagVals, 1, false, &pStbRowsCxt->pTag);
}
}
2023-10-24 08:08:08 +00:00
2023-11-01 00:32:31 +00:00
if (code == TSDB_CODE_SUCCESS && pStbRowsCxt->pTagCond) {
code = checkSubtablePrivilege(pStbRowsCxt->aTagVals, pStbRowsCxt->aTagNames, &pStbRowsCxt->pTagCond);
}
return code;
}
2023-11-01 00:43:29 +00:00
static int32_t doGetStbRowValues(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt, const char** ppSql,
2024-03-26 07:11:15 +00:00
SStbRowsDataContext* pStbRowsCxt, SToken* pToken, const SBoundColInfo* pCols,
feat(decimal): support decimal data type (#30060) * decimal: create table * decimal: add test case decimal.py * decimal: add decimal.c * support input decimal * decimal test * refactor svalue * fix test cases * add decimal unit test * add decimal test cmake * support insert and query decimal type * define wide integer, support decimal128 * support decimal128 divide * set decimal type expr res types * scalar decimal * convert to decimal * fix decimal64/128 from str and to str * fix decimal from str and decimal to str * decimal simple conversion * unit test for decimal * decimal conversion and unit tests * decimal + - * / * decimal scalar ops and comparision * start to refactor GET_TYPED_DATA * support decimal max func, cast func * refactor GET_TYPED_DATA interface * decimal scalar comparision * start to implement sum for decimal * support sum and avg for decimal type * decimal tests * add decimal test * decimal add test cases * decimal use int256/int128 * decimal testing * fix decimal table meta and add tests for decimal col streams * fix create stream and create tsma * test insert decimal values * decimal from str * test decimal input * test parse decimal from string * add taos_fetch_field_e api * decimal insert tests * test decimal operators * decimal operator test * feat:support decimal in raw block * decimal operator tests * decimal test * feat:support decimal in raw block * feat:support decimal in raw block * feat:add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * decimal test operators * decimal operator test * test decimal operators * test decimal compare operators * decimal unary operator test * decimal col with decimal col oper test * test decimal col filtering * fix decimal float operator test * decimal test where filtering * fix decimal filtering * fix decimal order by * fix decimal op test * test decimal agg funcs * test decimal functions * remove assert * fix ci build for ret check * fix decimal windows build * fix ci ret check * skip decimal ret check * skip decimal ret check * fix decimal tests * fix decimal ci test * decimal test * fix(tmq): heap user after free * fix(tmq): double free * fix(tmq): double free * fix decimal tests * fix(decimal): decimal test ci build * fix(decimal): windows build * fix(decimal): decimal test build * fix(decimal): fix decimal build and tests * fix(decimal): fix decimal tests * fix(decimal): fix taos_fetch_fields_e api * fix(decimal): fix decimal taos_fetch_fields_e api * fix(decimal): rebase 3.0 * fix(decimal): fix decimal functions * fix(decimal): fix decimal test case memory leak * fix(decimal): fix decimal tests * fix(decimal): fix decimal test case * fix(decimal): fix decimal tests * feat(decimal): fix unit tests * feat(decimal): fix deicmal unit test --------- Co-authored-by: wangmm0220 <wangmm0220@gmail.com> Co-authored-by: yihaoDeng <yhdeng@taosdata.com>
2025-03-14 10:08:07 +00:00
const SSchema* pSchemas, const SSchemaExt* pExtSchemas, SToken* tagTokens,
SSchema** tagSchemas, int* pNumOfTagTokens, bool* bFoundTbName, bool* setCtbName,
SBoundColInfo* ctbCols) {
int32_t code = TSDB_CODE_SUCCESS;
2024-03-10 14:14:57 +00:00
SArray* pTagNames = pStbRowsCxt->aTagNames;
SArray* pTagVals = pStbRowsCxt->aTagVals;
bool canParseTagsAfter = !pStbRowsCxt->pTagCond && !pStbRowsCxt->hasTimestampTag;
2023-11-03 06:03:25 +00:00
int32_t numOfCols = getNumOfColumns(pStbRowsCxt->pStbMeta);
int32_t numOfTags = getNumOfTags(pStbRowsCxt->pStbMeta);
2023-11-03 06:03:25 +00:00
int32_t tbnameIdx = getTbnameSchemaIndex(pStbRowsCxt->pStbMeta);
2024-03-10 14:14:57 +00:00
uint8_t precision = getTableInfo(pStbRowsCxt->pStbMeta).precision;
2025-01-02 12:07:58 +00:00
int tag_index = 0;
int col_index = 0;
2023-11-01 00:32:31 +00:00
for (int i = 0; i < pCols->numOfBound && (code) == TSDB_CODE_SUCCESS; ++i) {
2023-10-24 08:08:08 +00:00
const char* pTmpSql = *ppSql;
bool ignoreComma = false;
NEXT_TOKEN_WITH_PREV_EXT(*ppSql, *pToken, &ignoreComma);
2023-11-03 02:38:43 +00:00
if (ignoreComma) {
2023-10-24 08:08:08 +00:00
code = buildSyntaxErrMsg(&pCxt->msg, "invalid data or symbol", pTmpSql);
break;
}
if (TK_NK_RP == pToken->type) {
code = generateSyntaxErrMsg(&pCxt->msg, TSDB_CODE_PAR_INVALID_COLUMNS_NUM);
break;
}
if (TK_NK_QUESTION == pToken->type) {
2024-12-26 04:35:12 +00:00
if (!pCxt->pComCxt->isStmtBind && i != 0) {
return buildInvalidOperationMsg(&pCxt->msg, "not support mixed bind and non-bind values");
}
2025-05-15 10:18:08 +00:00
if (pCxt->pComCxt->pStmtCb == NULL) {
return buildInvalidOperationMsg(&pCxt->msg, "symbol ? only support in stmt mode");
}
pCxt->isStmtBind = true;
if (pCols->pColIndex[i] == tbnameIdx) {
2025-01-02 12:07:58 +00:00
*bFoundTbName = true;
char* tbName = NULL;
if ((*pCxt->pComCxt->pStmtCb->getTbNameFn)(pCxt->pComCxt->pStmtCb->pStmt, &tbName) == TSDB_CODE_SUCCESS) {
tstrncpy(pStbRowsCxt->ctbName.tname, tbName, sizeof(pStbRowsCxt->ctbName.tname));
tstrncpy(pStmt->usingTableName.tname, pStmt->targetTableName.tname, sizeof(pStmt->usingTableName.tname));
tstrncpy(pStmt->targetTableName.tname, tbName, sizeof(pStmt->targetTableName.tname));
tstrncpy(pStmt->usingTableName.dbname, pStmt->targetTableName.dbname, sizeof(pStmt->usingTableName.dbname));
pStmt->usingTableName.type = 1;
pStmt->pTableMeta->tableType = TSDB_CHILD_TABLE; // set the table type to child table for parse cache
2025-01-02 12:07:58 +00:00
*setCtbName = true;
}
} else if (pCols->pColIndex[i] < numOfCols) {
// bind column
2025-01-02 12:07:58 +00:00
if (ctbCols->pColIndex == NULL) {
ctbCols->pColIndex = taosMemoryCalloc(numOfCols, sizeof(int16_t));
if (NULL == ctbCols->pColIndex) {
return terrno;
}
}
ctbCols->pColIndex[col_index++] = pCols->pColIndex[i];
ctbCols->numOfBound++;
ctbCols->numOfCols++;
} else if (pCols->pColIndex[i] < tbnameIdx) {
if (pCxt->tags.pColIndex == NULL) {
pCxt->tags.pColIndex = taosMemoryCalloc(numOfTags, sizeof(int16_t));
if (NULL == pCxt->tags.pColIndex) {
return terrno;
}
}
2025-01-02 12:07:58 +00:00
if (!(tag_index < numOfTags)) {
return buildInvalidOperationMsg(&pCxt->msg, "not expected numOfTags");
}
pStmt->usingTableProcessing = true;
2025-01-02 12:07:58 +00:00
pCxt->tags.pColIndex[tag_index++] = pCols->pColIndex[i] - numOfCols;
pCxt->tags.mixTagsCols = true;
pCxt->tags.numOfBound++;
pCxt->tags.numOfCols++;
} else {
return buildInvalidOperationMsg(&pCxt->msg, "not expected numOfBound");
}
} else {
2024-12-26 04:35:12 +00:00
if (pCxt->pComCxt->isStmtBind) {
return buildInvalidOperationMsg(&pCxt->msg, "not support mixed bind and non-bind values");
}
if (pCols->pColIndex[i] < numOfCols) {
feat(decimal): support decimal data type (#30060) * decimal: create table * decimal: add test case decimal.py * decimal: add decimal.c * support input decimal * decimal test * refactor svalue * fix test cases * add decimal unit test * add decimal test cmake * support insert and query decimal type * define wide integer, support decimal128 * support decimal128 divide * set decimal type expr res types * scalar decimal * convert to decimal * fix decimal64/128 from str and to str * fix decimal from str and decimal to str * decimal simple conversion * unit test for decimal * decimal conversion and unit tests * decimal + - * / * decimal scalar ops and comparision * start to refactor GET_TYPED_DATA * support decimal max func, cast func * refactor GET_TYPED_DATA interface * decimal scalar comparision * start to implement sum for decimal * support sum and avg for decimal type * decimal tests * add decimal test * decimal add test cases * decimal use int256/int128 * decimal testing * fix decimal table meta and add tests for decimal col streams * fix create stream and create tsma * test insert decimal values * decimal from str * test decimal input * test parse decimal from string * add taos_fetch_field_e api * decimal insert tests * test decimal operators * decimal operator test * feat:support decimal in raw block * decimal operator tests * decimal test * feat:support decimal in raw block * feat:support decimal in raw block * feat:add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * decimal test operators * decimal operator test * test decimal operators * test decimal compare operators * decimal unary operator test * decimal col with decimal col oper test * test decimal col filtering * fix decimal float operator test * decimal test where filtering * fix decimal filtering * fix decimal order by * fix decimal op test * test decimal agg funcs * test decimal functions * remove assert * fix ci build for ret check * fix decimal windows build * fix ci ret check * skip decimal ret check * skip decimal ret check * fix decimal tests * fix decimal ci test * decimal test * fix(tmq): heap user after free * fix(tmq): double free * fix(tmq): double free * fix decimal tests * fix(decimal): decimal test ci build * fix(decimal): windows build * fix(decimal): decimal test build * fix(decimal): fix decimal build and tests * fix(decimal): fix decimal tests * fix(decimal): fix taos_fetch_fields_e api * fix(decimal): fix decimal taos_fetch_fields_e api * fix(decimal): rebase 3.0 * fix(decimal): fix decimal functions * fix(decimal): fix decimal test case memory leak * fix(decimal): fix decimal tests * fix(decimal): fix decimal test case * fix(decimal): fix decimal tests * feat(decimal): fix unit tests * feat(decimal): fix deicmal unit test --------- Co-authored-by: wangmm0220 <wangmm0220@gmail.com> Co-authored-by: yihaoDeng <yhdeng@taosdata.com>
2025-03-14 10:08:07 +00:00
const SSchema* pSchema = &pSchemas[pCols->pColIndex[i]];
const SSchemaExt* pExtSchema = pExtSchemas + pCols->pColIndex[i];
SColVal* pVal = taosArrayGet(pStbRowsCxt->aColVals, pCols->pColIndex[i]);
feat(decimal): support decimal data type (#30060) * decimal: create table * decimal: add test case decimal.py * decimal: add decimal.c * support input decimal * decimal test * refactor svalue * fix test cases * add decimal unit test * add decimal test cmake * support insert and query decimal type * define wide integer, support decimal128 * support decimal128 divide * set decimal type expr res types * scalar decimal * convert to decimal * fix decimal64/128 from str and to str * fix decimal from str and decimal to str * decimal simple conversion * unit test for decimal * decimal conversion and unit tests * decimal + - * / * decimal scalar ops and comparision * start to refactor GET_TYPED_DATA * support decimal max func, cast func * refactor GET_TYPED_DATA interface * decimal scalar comparision * start to implement sum for decimal * support sum and avg for decimal type * decimal tests * add decimal test * decimal add test cases * decimal use int256/int128 * decimal testing * fix decimal table meta and add tests for decimal col streams * fix create stream and create tsma * test insert decimal values * decimal from str * test decimal input * test parse decimal from string * add taos_fetch_field_e api * decimal insert tests * test decimal operators * decimal operator test * feat:support decimal in raw block * decimal operator tests * decimal test * feat:support decimal in raw block * feat:support decimal in raw block * feat:add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * decimal test operators * decimal operator test * test decimal operators * test decimal compare operators * decimal unary operator test * decimal col with decimal col oper test * test decimal col filtering * fix decimal float operator test * decimal test where filtering * fix decimal filtering * fix decimal order by * fix decimal op test * test decimal agg funcs * test decimal functions * remove assert * fix ci build for ret check * fix decimal windows build * fix ci ret check * skip decimal ret check * skip decimal ret check * fix decimal tests * fix decimal ci test * decimal test * fix(tmq): heap user after free * fix(tmq): double free * fix(tmq): double free * fix decimal tests * fix(decimal): decimal test ci build * fix(decimal): windows build * fix(decimal): decimal test build * fix(decimal): fix decimal build and tests * fix(decimal): fix decimal tests * fix(decimal): fix taos_fetch_fields_e api * fix(decimal): fix decimal taos_fetch_fields_e api * fix(decimal): rebase 3.0 * fix(decimal): fix decimal functions * fix(decimal): fix decimal test case memory leak * fix(decimal): fix decimal tests * fix(decimal): fix decimal test case * fix(decimal): fix decimal tests * feat(decimal): fix unit tests * feat(decimal): fix deicmal unit test --------- Co-authored-by: wangmm0220 <wangmm0220@gmail.com> Co-authored-by: yihaoDeng <yhdeng@taosdata.com>
2025-03-14 10:08:07 +00:00
code = parseValueToken(pCxt, ppSql, pToken, (SSchema*)pSchema, pExtSchema, precision, pVal);
if (TK_NK_VARIABLE == pToken->type) {
code = buildInvalidOperationMsg(&pCxt->msg, "not expected row value");
}
} else if (pCols->pColIndex[i] < tbnameIdx) {
const SSchema* pTagSchema = &pSchemas[pCols->pColIndex[i]];
if (canParseTagsAfter) {
tagTokens[(*pNumOfTagTokens)] = *pToken;
tagSchemas[(*pNumOfTagTokens)] = (SSchema*)pTagSchema;
++(*pNumOfTagTokens);
} else {
code = checkAndTrimValue(pToken, pCxt->tmpTokenBuf, &pCxt->msg, pTagSchema->type);
if (code == TSDB_CODE_SUCCESS && TK_NK_VARIABLE == pToken->type) {
code = buildInvalidOperationMsg(&pCxt->msg, "not expected row value");
}
if (code == TSDB_CODE_SUCCESS) {
code = parseTagValue(&pCxt->msg, ppSql, precision, (SSchema*)pTagSchema, pToken, pTagNames, pTagVals,
&pStbRowsCxt->pTag, pCxt->pComCxt->timezone, pCxt->pComCxt->charsetCxt);
}
}
} else if (pCols->pColIndex[i] == tbnameIdx) {
code = checkAndTrimValue(pToken, pCxt->tmpTokenBuf, &pCxt->msg, TSDB_DATA_TYPE_BINARY);
if (TK_NK_VARIABLE == pToken->type) {
code = buildInvalidOperationMsg(&pCxt->msg, "not expected tbname");
2023-10-31 02:48:10 +00:00
}
2024-06-24 14:13:03 +00:00
if (code == TSDB_CODE_SUCCESS) {
code = parseTbnameToken(&pCxt->msg, pStbRowsCxt->ctbName.tname, pToken, bFoundTbName);
}
2024-06-24 14:13:03 +00:00
}
}
2023-10-24 08:08:08 +00:00
if (code == TSDB_CODE_SUCCESS && i < pCols->numOfBound - 1) {
NEXT_VALID_TOKEN(*ppSql, *pToken);
if (TK_NK_COMMA != pToken->type) {
code = buildSyntaxErrMsg(&pCxt->msg, ", expected", pToken->z);
}
}
}
2024-12-05 06:56:32 +00:00
2023-11-01 00:32:31 +00:00
return code;
}
2024-03-26 07:11:15 +00:00
static int32_t getStbRowValues(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt, const char** ppSql,
2025-01-02 12:07:58 +00:00
SStbRowsDataContext* pStbRowsCxt, bool* pGotRow, SToken* pToken, bool* pCtbFirst,
bool* setCtbName, SBoundColInfo* ctbCols) {
2023-11-01 00:32:31 +00:00
SBoundColInfo* pCols = &pStbRowsCxt->boundColsInfo;
SSchema* pSchemas = getTableColumnSchema(pStbRowsCxt->pStbMeta);
feat(decimal): support decimal data type (#30060) * decimal: create table * decimal: add test case decimal.py * decimal: add decimal.c * support input decimal * decimal test * refactor svalue * fix test cases * add decimal unit test * add decimal test cmake * support insert and query decimal type * define wide integer, support decimal128 * support decimal128 divide * set decimal type expr res types * scalar decimal * convert to decimal * fix decimal64/128 from str and to str * fix decimal from str and decimal to str * decimal simple conversion * unit test for decimal * decimal conversion and unit tests * decimal + - * / * decimal scalar ops and comparision * start to refactor GET_TYPED_DATA * support decimal max func, cast func * refactor GET_TYPED_DATA interface * decimal scalar comparision * start to implement sum for decimal * support sum and avg for decimal type * decimal tests * add decimal test * decimal add test cases * decimal use int256/int128 * decimal testing * fix decimal table meta and add tests for decimal col streams * fix create stream and create tsma * test insert decimal values * decimal from str * test decimal input * test parse decimal from string * add taos_fetch_field_e api * decimal insert tests * test decimal operators * decimal operator test * feat:support decimal in raw block * decimal operator tests * decimal test * feat:support decimal in raw block * feat:support decimal in raw block * feat:add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * decimal test operators * decimal operator test * test decimal operators * test decimal compare operators * decimal unary operator test * decimal col with decimal col oper test * test decimal col filtering * fix decimal float operator test * decimal test where filtering * fix decimal filtering * fix decimal order by * fix decimal op test * test decimal agg funcs * test decimal functions * remove assert * fix ci build for ret check * fix decimal windows build * fix ci ret check * skip decimal ret check * skip decimal ret check * fix decimal tests * fix decimal ci test * decimal test * fix(tmq): heap user after free * fix(tmq): double free * fix(tmq): double free * fix decimal tests * fix(decimal): decimal test ci build * fix(decimal): windows build * fix(decimal): decimal test build * fix(decimal): fix decimal build and tests * fix(decimal): fix decimal tests * fix(decimal): fix taos_fetch_fields_e api * fix(decimal): fix decimal taos_fetch_fields_e api * fix(decimal): rebase 3.0 * fix(decimal): fix decimal functions * fix(decimal): fix decimal test case memory leak * fix(decimal): fix decimal tests * fix(decimal): fix decimal test case * fix(decimal): fix decimal tests * feat(decimal): fix unit tests * feat(decimal): fix deicmal unit test --------- Co-authored-by: wangmm0220 <wangmm0220@gmail.com> Co-authored-by: yihaoDeng <yhdeng@taosdata.com>
2025-03-14 10:08:07 +00:00
SSchemaExt* pExtSchemas = getTableColumnExtSchema(pStbRowsCxt->pStbMeta);
2023-11-01 00:32:31 +00:00
2024-03-26 07:11:15 +00:00
bool bFoundTbName = false;
2023-11-01 00:32:31 +00:00
const char* pOrigSql = *ppSql;
2024-03-26 07:11:15 +00:00
int32_t code = TSDB_CODE_SUCCESS;
SToken tagTokens[TSDB_MAX_TAGS] = {0};
2023-11-01 00:32:31 +00:00
SSchema* tagSchemas[TSDB_MAX_TAGS] = {0};
2024-03-26 07:11:15 +00:00
int numOfTagTokens = 0;
2023-11-01 00:32:31 +00:00
feat(decimal): support decimal data type (#30060) * decimal: create table * decimal: add test case decimal.py * decimal: add decimal.c * support input decimal * decimal test * refactor svalue * fix test cases * add decimal unit test * add decimal test cmake * support insert and query decimal type * define wide integer, support decimal128 * support decimal128 divide * set decimal type expr res types * scalar decimal * convert to decimal * fix decimal64/128 from str and to str * fix decimal from str and decimal to str * decimal simple conversion * unit test for decimal * decimal conversion and unit tests * decimal + - * / * decimal scalar ops and comparision * start to refactor GET_TYPED_DATA * support decimal max func, cast func * refactor GET_TYPED_DATA interface * decimal scalar comparision * start to implement sum for decimal * support sum and avg for decimal type * decimal tests * add decimal test * decimal add test cases * decimal use int256/int128 * decimal testing * fix decimal table meta and add tests for decimal col streams * fix create stream and create tsma * test insert decimal values * decimal from str * test decimal input * test parse decimal from string * add taos_fetch_field_e api * decimal insert tests * test decimal operators * decimal operator test * feat:support decimal in raw block * decimal operator tests * decimal test * feat:support decimal in raw block * feat:support decimal in raw block * feat:add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * decimal test operators * decimal operator test * test decimal operators * test decimal compare operators * decimal unary operator test * decimal col with decimal col oper test * test decimal col filtering * fix decimal float operator test * decimal test where filtering * fix decimal filtering * fix decimal order by * fix decimal op test * test decimal agg funcs * test decimal functions * remove assert * fix ci build for ret check * fix decimal windows build * fix ci ret check * skip decimal ret check * skip decimal ret check * fix decimal tests * fix decimal ci test * decimal test * fix(tmq): heap user after free * fix(tmq): double free * fix(tmq): double free * fix decimal tests * fix(decimal): decimal test ci build * fix(decimal): windows build * fix(decimal): decimal test build * fix(decimal): fix decimal build and tests * fix(decimal): fix decimal tests * fix(decimal): fix taos_fetch_fields_e api * fix(decimal): fix decimal taos_fetch_fields_e api * fix(decimal): rebase 3.0 * fix(decimal): fix decimal functions * fix(decimal): fix decimal test case memory leak * fix(decimal): fix decimal tests * fix(decimal): fix decimal test case * fix(decimal): fix decimal tests * feat(decimal): fix unit tests * feat(decimal): fix deicmal unit test --------- Co-authored-by: wangmm0220 <wangmm0220@gmail.com> Co-authored-by: yihaoDeng <yhdeng@taosdata.com>
2025-03-14 10:08:07 +00:00
code = doGetStbRowValues(pCxt, pStmt, ppSql, pStbRowsCxt, pToken, pCols, pSchemas, pExtSchemas, tagTokens, tagSchemas,
2025-01-02 12:07:58 +00:00
&numOfTagTokens, &bFoundTbName, setCtbName, ctbCols);
2023-11-01 00:35:38 +00:00
if (code != TSDB_CODE_SUCCESS) {
return code;
2023-10-24 08:08:08 +00:00
}
2023-11-01 00:32:31 +00:00
if (!bFoundTbName) {
2025-01-02 12:07:58 +00:00
code = buildSyntaxErrMsg(&pCxt->msg, "tbname value expected", pOrigSql);
}
2023-10-31 02:48:10 +00:00
bool ctbFirst = true;
2024-07-23 07:59:10 +00:00
char ctbFName[TSDB_TABLE_FNAME_LEN];
2023-10-31 02:48:10 +00:00
if (code == TSDB_CODE_SUCCESS) {
2024-07-23 07:59:10 +00:00
code = tNameExtractFullName(&pStbRowsCxt->ctbName, ctbFName);
}
if (TSDB_CODE_SUCCESS == code) {
2023-10-31 02:48:10 +00:00
STableMeta** pCtbMeta = taosHashGet(pStmt->pSubTableHashObj, ctbFName, strlen(ctbFName));
2023-11-01 00:32:31 +00:00
ctbFirst = (pCtbMeta == NULL);
2023-10-31 02:48:10 +00:00
if (!ctbFirst) {
pStbRowsCxt->pCtbMeta->uid = (*pCtbMeta)->uid;
pStbRowsCxt->pCtbMeta->vgId = (*pCtbMeta)->vgId;
2023-10-31 02:48:10 +00:00
}
2023-11-01 00:32:31 +00:00
*pCtbFirst = ctbFirst;
2023-10-31 02:48:10 +00:00
}
2023-11-01 00:32:31 +00:00
if (code == TSDB_CODE_SUCCESS) {
code = processCtbTagsAfterCtbName(pCxt, pStmt, pStbRowsCxt, ctbFirst, tagTokens, tagSchemas, numOfTagTokens);
2023-10-24 08:08:08 +00:00
}
2023-10-31 02:48:10 +00:00
if (code == TSDB_CODE_SUCCESS) {
*pGotRow = true;
}
2023-10-24 08:08:08 +00:00
return code;
}
2024-03-26 07:11:15 +00:00
static int32_t processCtbAutoCreationAndCtbMeta(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt,
SStbRowsDataContext* pStbRowsCxt) {
2023-10-25 00:50:08 +00:00
int32_t code = TSDB_CODE_SUCCESS;
2023-10-24 08:08:08 +00:00
2023-10-25 00:50:08 +00:00
pStbRowsCxt->pCreateCtbReq = taosMemoryCalloc(1, sizeof(SVCreateTbReq));
if (pStbRowsCxt->pCreateCtbReq == NULL) {
2024-09-10 10:42:00 +00:00
code = terrno;
2023-10-25 00:50:08 +00:00
}
if (code == TSDB_CODE_SUCCESS) {
2024-09-18 06:27:51 +00:00
code = insBuildCreateTbReq(pStbRowsCxt->pCreateCtbReq, pStbRowsCxt->ctbName.tname, pStbRowsCxt->pTag,
pStbRowsCxt->pStbMeta->uid, pStbRowsCxt->stbName.tname, pStbRowsCxt->aTagNames,
getNumOfTags(pStbRowsCxt->pStbMeta), TSDB_DEFAULT_TABLE_TTL);
2023-10-25 00:50:08 +00:00
pStbRowsCxt->pTag = NULL;
}
2023-10-24 08:08:08 +00:00
if (code == TSDB_CODE_SUCCESS) {
char ctbFName[TSDB_TABLE_FNAME_LEN];
2024-07-23 07:59:10 +00:00
code = tNameExtractFullName(&pStbRowsCxt->ctbName, ctbFName);
2024-03-26 07:11:15 +00:00
SVgroupInfo vg;
2023-10-31 02:48:10 +00:00
SRequestConnInfo conn = {.pTrans = pCxt->pComCxt->pTransporter,
.requestId = pCxt->pComCxt->requestId,
.requestObjRefId = pCxt->pComCxt->requestRid,
.mgmtEps = pCxt->pComCxt->mgmtEpSet};
2024-07-23 07:59:10 +00:00
if (TSDB_CODE_SUCCESS == code) {
code = catalogGetTableHashVgroup(pCxt->pComCxt->pCatalog, &conn, &pStbRowsCxt->ctbName, &vg);
}
2023-10-31 02:48:10 +00:00
if (code == TSDB_CODE_SUCCESS) {
2024-07-23 07:59:10 +00:00
code = taosHashPut(pStmt->pVgroupsHashObj, (const char*)(&vg.vgId), sizeof(vg.vgId), &vg, sizeof(vg));
}
STableMeta* pBackup = NULL;
if (TSDB_CODE_SUCCESS == code) {
2023-10-24 08:08:08 +00:00
pStbRowsCxt->pCtbMeta->uid = taosHashGetSize(pStmt->pSubTableHashObj) + 1;
pStbRowsCxt->pCtbMeta->vgId = vg.vgId;
2023-10-31 02:48:10 +00:00
2024-07-23 07:59:10 +00:00
code = cloneTableMeta(pStbRowsCxt->pCtbMeta, &pBackup);
}
if (TSDB_CODE_SUCCESS == code) {
code = taosHashPut(pStmt->pSubTableHashObj, ctbFName, strlen(ctbFName), &pBackup, POINTER_BYTES);
}
if (TSDB_CODE_SUCCESS == code) {
code = collectUseTable(&pStbRowsCxt->ctbName, pStmt->pTableNameHashObj);
2023-10-24 08:08:08 +00:00
}
}
2023-10-25 00:50:08 +00:00
return code;
}
2023-10-24 08:08:08 +00:00
2023-10-25 00:50:08 +00:00
static void clearStbRowsDataContext(SStbRowsDataContext* pStbRowsCxt) {
if (pStbRowsCxt == NULL) return;
2023-10-25 00:50:08 +00:00
taosArrayClear(pStbRowsCxt->aTagNames);
for (int i = 0; i < taosArrayGetSize(pStbRowsCxt->aTagVals); ++i) {
STagVal* p = (STagVal*)taosArrayGet(pStbRowsCxt->aTagVals, i);
if (IS_VAR_DATA_TYPE(p->type)) {
taosMemoryFreeClear(p->pData);
}
}
taosArrayClear(pStbRowsCxt->aTagVals);
clearColValArray(pStbRowsCxt->aColVals);
2023-10-25 00:50:08 +00:00
tTagFree(pStbRowsCxt->pTag);
pStbRowsCxt->pTag = NULL;
tdDestroySVCreateTbReq(pStbRowsCxt->pCreateCtbReq);
taosMemoryFreeClear(pStbRowsCxt->pCreateCtbReq);
}
static int32_t parseStbBoundInfo(SVnodeModifyOpStmt* pStmt, SStbRowsDataContext* pStbRowsCxt,
STableDataCxt** ppTableDataCxt) {
char tbFName[TSDB_TABLE_FNAME_LEN];
int32_t code = tNameExtractFullName(&pStmt->targetTableName, tbFName);
if (TSDB_CODE_SUCCESS != code) {
return code;
}
if (pStmt->usingTableProcessing) {
pStmt->pTableMeta->uid = 0;
}
code = insGetTableDataCxt(pStmt->pTableBlockHashObj, tbFName, strlen(tbFName), pStmt->pTableMeta,
&pStmt->pCreateTblReq, ppTableDataCxt, false, true);
if (code != TSDB_CODE_SUCCESS) {
return code;
}
insDestroyBoundColInfo(&((*ppTableDataCxt)->boundColsInfo));
(*ppTableDataCxt)->boundColsInfo = pStbRowsCxt->boundColsInfo;
2024-12-14 04:18:48 +00:00
(*ppTableDataCxt)->boundColsInfo.pColIndex = taosMemoryCalloc(pStbRowsCxt->boundColsInfo.numOfBound, sizeof(int16_t));
if (NULL == (*ppTableDataCxt)->boundColsInfo.pColIndex) {
return terrno;
}
(void)memcpy((*ppTableDataCxt)->boundColsInfo.pColIndex, pStbRowsCxt->boundColsInfo.pColIndex,
sizeof(int16_t) * pStmt->pStbRowsCxt->boundColsInfo.numOfBound);
return TSDB_CODE_SUCCESS;
}
2023-11-29 16:25:05 +00:00
static int32_t parseOneStbRow(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt, const char** ppSql,
SStbRowsDataContext* pStbRowsCxt, bool* pGotRow, SToken* pToken,
STableDataCxt** ppTableDataCxt) {
bool bFirstTable = false;
2025-01-02 12:07:58 +00:00
bool setCtbName = false;
SBoundColInfo ctbCols = {0};
int32_t code = getStbRowValues(pCxt, pStmt, ppSql, pStbRowsCxt, pGotRow, pToken, &bFirstTable, &setCtbName, &ctbCols);
2025-01-02 12:07:58 +00:00
if (!setCtbName && pCxt->isStmtBind) {
taosMemoryFreeClear(ctbCols.pColIndex);
return parseStbBoundInfo(pStmt, pStbRowsCxt, ppTableDataCxt);
}
2023-10-25 00:50:08 +00:00
if (code != TSDB_CODE_SUCCESS || !*pGotRow) {
return code;
2023-10-24 08:08:08 +00:00
}
2023-10-25 00:50:08 +00:00
2023-10-31 02:48:10 +00:00
if (code == TSDB_CODE_SUCCESS && bFirstTable) {
2024-03-26 07:11:15 +00:00
code = processCtbAutoCreationAndCtbMeta(pCxt, pStmt, pStbRowsCxt);
2023-10-24 08:08:08 +00:00
}
2024-04-12 02:53:43 +00:00
if (code == TSDB_CODE_SUCCESS) {
if (pCxt->isStmtBind) {
char ctbFName[TSDB_TABLE_FNAME_LEN];
code = tNameExtractFullName(&pStbRowsCxt->ctbName, ctbFName);
if (code != TSDB_CODE_SUCCESS) {
return code;
}
code = insGetTableDataCxt(pStmt->pTableBlockHashObj, ctbFName, strlen(ctbFName), pStbRowsCxt->pCtbMeta,
&pStbRowsCxt->pCreateCtbReq, ppTableDataCxt, true, true);
} else {
code =
insGetTableDataCxt(pStmt->pTableBlockHashObj, &pStbRowsCxt->pCtbMeta->uid, sizeof(pStbRowsCxt->pCtbMeta->uid),
pStbRowsCxt->pCtbMeta, &pStbRowsCxt->pCreateCtbReq, ppTableDataCxt, false, true);
}
2024-04-12 02:53:43 +00:00
}
if (code == TSDB_CODE_SUCCESS) {
2025-01-02 12:07:58 +00:00
if (pCxt->isStmtBind) {
int32_t tbnameIdx = getTbnameSchemaIndex(pStbRowsCxt->pStbMeta);
code = initTableColSubmitDataWithBoundInfo(*ppTableDataCxt, ctbCols);
} else {
code = initTableColSubmitData(*ppTableDataCxt);
}
2023-10-24 08:08:08 +00:00
}
if (code == TSDB_CODE_SUCCESS && !pCxt->isStmtBind) {
2023-11-29 16:25:05 +00:00
SRow** pRow = taosArrayReserve((*ppTableDataCxt)->pData->aRowP, 1);
code = tRowBuild(pStbRowsCxt->aColVals, (*ppTableDataCxt)->pSchema, pRow);
2023-10-24 08:08:08 +00:00
if (TSDB_CODE_SUCCESS == code) {
2024-03-26 07:11:15 +00:00
SRowKey key;
tRowGetKey(*pRow, &key);
insCheckTableDataOrder(*ppTableDataCxt, &key);
2023-10-24 08:08:08 +00:00
}
}
2023-11-03 02:38:43 +00:00
2023-10-24 08:08:08 +00:00
if (code == TSDB_CODE_SUCCESS) {
*pGotRow = true;
}
2023-10-25 00:27:02 +00:00
2023-10-25 00:50:08 +00:00
clearStbRowsDataContext(pStbRowsCxt);
2024-03-26 07:11:15 +00:00
return code;
}
2024-03-26 07:11:15 +00:00
static int parseOneRow(SInsertParseContext* pCxt, const char** pSql, STableDataCxt* pTableCxt, bool* pGotRow,
SToken* pToken) {
feat(decimal): support decimal data type (#30060) * decimal: create table * decimal: add test case decimal.py * decimal: add decimal.c * support input decimal * decimal test * refactor svalue * fix test cases * add decimal unit test * add decimal test cmake * support insert and query decimal type * define wide integer, support decimal128 * support decimal128 divide * set decimal type expr res types * scalar decimal * convert to decimal * fix decimal64/128 from str and to str * fix decimal from str and decimal to str * decimal simple conversion * unit test for decimal * decimal conversion and unit tests * decimal + - * / * decimal scalar ops and comparision * start to refactor GET_TYPED_DATA * support decimal max func, cast func * refactor GET_TYPED_DATA interface * decimal scalar comparision * start to implement sum for decimal * support sum and avg for decimal type * decimal tests * add decimal test * decimal add test cases * decimal use int256/int128 * decimal testing * fix decimal table meta and add tests for decimal col streams * fix create stream and create tsma * test insert decimal values * decimal from str * test decimal input * test parse decimal from string * add taos_fetch_field_e api * decimal insert tests * test decimal operators * decimal operator test * feat:support decimal in raw block * decimal operator tests * decimal test * feat:support decimal in raw block * feat:support decimal in raw block * feat:add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * decimal test operators * decimal operator test * test decimal operators * test decimal compare operators * decimal unary operator test * decimal col with decimal col oper test * test decimal col filtering * fix decimal float operator test * decimal test where filtering * fix decimal filtering * fix decimal order by * fix decimal op test * test decimal agg funcs * test decimal functions * remove assert * fix ci build for ret check * fix decimal windows build * fix ci ret check * skip decimal ret check * skip decimal ret check * fix decimal tests * fix decimal ci test * decimal test * fix(tmq): heap user after free * fix(tmq): double free * fix(tmq): double free * fix decimal tests * fix(decimal): decimal test ci build * fix(decimal): windows build * fix(decimal): decimal test build * fix(decimal): fix decimal build and tests * fix(decimal): fix decimal tests * fix(decimal): fix taos_fetch_fields_e api * fix(decimal): fix decimal taos_fetch_fields_e api * fix(decimal): rebase 3.0 * fix(decimal): fix decimal functions * fix(decimal): fix decimal test case memory leak * fix(decimal): fix decimal tests * fix(decimal): fix decimal test case * fix(decimal): fix decimal tests * feat(decimal): fix unit tests * feat(decimal): fix deicmal unit test --------- Co-authored-by: wangmm0220 <wangmm0220@gmail.com> Co-authored-by: yihaoDeng <yhdeng@taosdata.com>
2025-03-14 10:08:07 +00:00
SBoundColInfo* pCols = &pTableCxt->boundColsInfo;
SSchema* pSchemas = getTableColumnSchema(pTableCxt->pMeta);
const SSchemaExt* pExtSchemas = getTableColumnExtSchema(pTableCxt->pMeta);
2022-11-27 09:09:02 +00:00
int32_t code = TSDB_CODE_SUCCESS;
// 1. set the parsed value from sql string
2022-11-04 07:21:38 +00:00
for (int i = 0; i < pCols->numOfBound && TSDB_CODE_SUCCESS == code; ++i) {
2023-02-05 02:11:26 +00:00
const char* pOrigSql = *pSql;
bool ignoreComma = false;
NEXT_TOKEN_WITH_PREV_EXT(*pSql, *pToken, &ignoreComma);
if (ignoreComma) {
code = buildSyntaxErrMsg(&pCxt->msg, "invalid data or symbol", pOrigSql);
2023-02-06 03:07:51 +00:00
break;
2023-02-05 02:11:26 +00:00
}
2022-04-14 12:14:52 +00:00
feat(decimal): support decimal data type (#30060) * decimal: create table * decimal: add test case decimal.py * decimal: add decimal.c * support input decimal * decimal test * refactor svalue * fix test cases * add decimal unit test * add decimal test cmake * support insert and query decimal type * define wide integer, support decimal128 * support decimal128 divide * set decimal type expr res types * scalar decimal * convert to decimal * fix decimal64/128 from str and to str * fix decimal from str and decimal to str * decimal simple conversion * unit test for decimal * decimal conversion and unit tests * decimal + - * / * decimal scalar ops and comparision * start to refactor GET_TYPED_DATA * support decimal max func, cast func * refactor GET_TYPED_DATA interface * decimal scalar comparision * start to implement sum for decimal * support sum and avg for decimal type * decimal tests * add decimal test * decimal add test cases * decimal use int256/int128 * decimal testing * fix decimal table meta and add tests for decimal col streams * fix create stream and create tsma * test insert decimal values * decimal from str * test decimal input * test parse decimal from string * add taos_fetch_field_e api * decimal insert tests * test decimal operators * decimal operator test * feat:support decimal in raw block * decimal operator tests * decimal test * feat:support decimal in raw block * feat:support decimal in raw block * feat:add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * decimal test operators * decimal operator test * test decimal operators * test decimal compare operators * decimal unary operator test * decimal col with decimal col oper test * test decimal col filtering * fix decimal float operator test * decimal test where filtering * fix decimal filtering * fix decimal order by * fix decimal op test * test decimal agg funcs * test decimal functions * remove assert * fix ci build for ret check * fix decimal windows build * fix ci ret check * skip decimal ret check * skip decimal ret check * fix decimal tests * fix decimal ci test * decimal test * fix(tmq): heap user after free * fix(tmq): double free * fix(tmq): double free * fix decimal tests * fix(decimal): decimal test ci build * fix(decimal): windows build * fix(decimal): decimal test build * fix(decimal): fix decimal build and tests * fix(decimal): fix decimal tests * fix(decimal): fix taos_fetch_fields_e api * fix(decimal): fix decimal taos_fetch_fields_e api * fix(decimal): rebase 3.0 * fix(decimal): fix decimal functions * fix(decimal): fix decimal test case memory leak * fix(decimal): fix decimal tests * fix(decimal): fix decimal test case * fix(decimal): fix decimal tests * feat(decimal): fix unit tests * feat(decimal): fix deicmal unit test --------- Co-authored-by: wangmm0220 <wangmm0220@gmail.com> Co-authored-by: yihaoDeng <yhdeng@taosdata.com>
2025-03-14 10:08:07 +00:00
SSchema* pSchema = &pSchemas[pCols->pColIndex[i]];
const SSchemaExt* pExtSchema = pExtSchemas + pCols->pColIndex[i];
SColVal* pVal = taosArrayGet(pTableCxt->pValues, pCols->pColIndex[i]);
2022-04-14 12:14:52 +00:00
2022-11-04 07:21:38 +00:00
if (pToken->type == TK_NK_QUESTION) {
2024-07-02 02:18:56 +00:00
pCxt->isStmtBind = true;
2022-11-04 07:21:38 +00:00
if (NULL == pCxt->pComCxt->pStmtCb) {
code = buildSyntaxErrMsg(&pCxt->msg, "? only used in stmt", pToken->z);
2023-02-06 03:07:51 +00:00
break;
}
} else {
if (TK_NK_RP == pToken->type) {
code = generateSyntaxErrMsg(&pCxt->msg, TSDB_CODE_PAR_INVALID_COLUMNS_NUM);
break;
2022-04-14 12:14:52 +00:00
}
2022-06-02 04:34:35 +00:00
2024-07-02 02:18:56 +00:00
if (pCxt->isStmtBind) {
code = buildInvalidOperationMsg(&pCxt->msg, "stmt bind param does not support normal value in sql");
2023-02-06 03:07:51 +00:00
break;
}
2022-04-26 03:50:35 +00:00
2023-02-08 01:51:52 +00:00
if (TSDB_CODE_SUCCESS == code) {
feat(decimal): support decimal data type (#30060) * decimal: create table * decimal: add test case decimal.py * decimal: add decimal.c * support input decimal * decimal test * refactor svalue * fix test cases * add decimal unit test * add decimal test cmake * support insert and query decimal type * define wide integer, support decimal128 * support decimal128 divide * set decimal type expr res types * scalar decimal * convert to decimal * fix decimal64/128 from str and to str * fix decimal from str and decimal to str * decimal simple conversion * unit test for decimal * decimal conversion and unit tests * decimal + - * / * decimal scalar ops and comparision * start to refactor GET_TYPED_DATA * support decimal max func, cast func * refactor GET_TYPED_DATA interface * decimal scalar comparision * start to implement sum for decimal * support sum and avg for decimal type * decimal tests * add decimal test * decimal add test cases * decimal use int256/int128 * decimal testing * fix decimal table meta and add tests for decimal col streams * fix create stream and create tsma * test insert decimal values * decimal from str * test decimal input * test parse decimal from string * add taos_fetch_field_e api * decimal insert tests * test decimal operators * decimal operator test * feat:support decimal in raw block * decimal operator tests * decimal test * feat:support decimal in raw block * feat:support decimal in raw block * feat:add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * feat:remove add schemaExt to SMqDataRsp * decimal test operators * decimal operator test * test decimal operators * test decimal compare operators * decimal unary operator test * decimal col with decimal col oper test * test decimal col filtering * fix decimal float operator test * decimal test where filtering * fix decimal filtering * fix decimal order by * fix decimal op test * test decimal agg funcs * test decimal functions * remove assert * fix ci build for ret check * fix decimal windows build * fix ci ret check * skip decimal ret check * skip decimal ret check * fix decimal tests * fix decimal ci test * decimal test * fix(tmq): heap user after free * fix(tmq): double free * fix(tmq): double free * fix decimal tests * fix(decimal): decimal test ci build * fix(decimal): windows build * fix(decimal): decimal test build * fix(decimal): fix decimal build and tests * fix(decimal): fix decimal tests * fix(decimal): fix taos_fetch_fields_e api * fix(decimal): fix decimal taos_fetch_fields_e api * fix(decimal): rebase 3.0 * fix(decimal): fix decimal functions * fix(decimal): fix decimal test case memory leak * fix(decimal): fix decimal tests * fix(decimal): fix decimal test case * fix(decimal): fix decimal tests * feat(decimal): fix unit tests * feat(decimal): fix deicmal unit test --------- Co-authored-by: wangmm0220 <wangmm0220@gmail.com> Co-authored-by: yihaoDeng <yhdeng@taosdata.com>
2025-03-14 10:08:07 +00:00
code = parseValueToken(pCxt, pSql, pToken, pSchema, pExtSchema, getTableInfo(pTableCxt->pMeta).precision, pVal);
2023-02-08 01:51:52 +00:00
}
2022-11-04 07:21:38 +00:00
}
2022-11-04 07:21:38 +00:00
if (TSDB_CODE_SUCCESS == code && i < pCols->numOfBound - 1) {
NEXT_VALID_TOKEN(*pSql, *pToken);
if (TK_NK_COMMA != pToken->type) {
code = buildSyntaxErrMsg(&pCxt->msg, ", expected", pToken->z);
2022-07-14 08:58:54 +00:00
}
}
}
2024-07-02 02:18:56 +00:00
if (TSDB_CODE_SUCCESS == code && !pCxt->isStmtBind) {
2022-11-27 16:08:41 +00:00
SRow** pRow = taosArrayReserve(pTableCxt->pData->aRowP, 1);
2022-11-27 09:09:02 +00:00
code = tRowBuild(pTableCxt->pValues, pTableCxt->pSchema, pRow);
2022-11-30 02:22:43 +00:00
if (TSDB_CODE_SUCCESS == code) {
2024-03-26 07:11:15 +00:00
SRowKey key;
tRowGetKey(*pRow, &key);
insCheckTableDataOrder(pTableCxt, &key);
2022-11-30 02:22:43 +00:00
}
2022-11-04 07:21:38 +00:00
}
2022-07-30 11:23:06 +00:00
2024-07-02 02:18:56 +00:00
if (TSDB_CODE_SUCCESS == code && !pCxt->isStmtBind) {
2022-11-04 07:21:38 +00:00
*pGotRow = true;
}
2022-12-06 12:40:18 +00:00
clearColValArray(pTableCxt->pValues);
2022-11-04 07:21:38 +00:00
return code;
}
// pSql -> (field1_value, ...) [(field1_value2, ...) ...]
static int32_t parseValues(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt, SRowsDataContext rowsDataCxt,
2022-11-27 09:09:02 +00:00
int32_t* pNumOfRows, SToken* pToken) {
int32_t code = TSDB_CODE_SUCCESS;
2022-11-04 07:21:38 +00:00
(*pNumOfRows) = 0;
while (TSDB_CODE_SUCCESS == code) {
int32_t index = 0;
2022-11-04 07:21:38 +00:00
NEXT_TOKEN_KEEP_SQL(pStmt->pSql, *pToken, index);
if (TK_NK_LP != pToken->type) {
break;
}
2022-11-04 07:21:38 +00:00
pStmt->pSql += index;
2022-04-18 11:08:27 +00:00
bool gotRow = false;
2022-11-04 07:21:38 +00:00
if (TSDB_CODE_SUCCESS == code) {
if (!pStmt->stbSyntax) {
code = parseOneRow(pCxt, &pStmt->pSql, rowsDataCxt.pTableDataCxt, &gotRow, pToken);
} else {
2025-03-13 09:30:01 +00:00
// foreach subtable
2023-11-29 16:25:05 +00:00
STableDataCxt* pTableDataCxt = NULL;
code = parseOneStbRow(pCxt, pStmt, &pStmt->pSql, rowsDataCxt.pStbRowsCxt, &gotRow, pToken, &pTableDataCxt);
}
2022-04-18 11:08:27 +00:00
}
2022-11-04 07:21:38 +00:00
if (TSDB_CODE_SUCCESS == code) {
NEXT_VALID_TOKEN(pStmt->pSql, *pToken);
if (TK_NK_COMMA == pToken->type) {
code = generateSyntaxErrMsg(&pCxt->msg, TSDB_CODE_PAR_INVALID_COLUMNS_NUM);
} else if (TK_NK_RP != pToken->type) {
code = buildSyntaxErrMsg(&pCxt->msg, ") expected", pToken->z);
}
}
2022-11-04 07:21:38 +00:00
if (TSDB_CODE_SUCCESS == code && gotRow) {
(*pNumOfRows)++;
2022-04-18 11:08:27 +00:00
}
}
2022-11-04 07:21:38 +00:00
if (TSDB_CODE_SUCCESS == code && 0 == (*pNumOfRows) &&
(!TSDB_QUERY_HAS_TYPE(pStmt->insertType, TSDB_QUERY_TYPE_STMT_INSERT))) {
code = buildSyntaxErrMsg(&pCxt->msg, "no any data points", NULL);
}
2022-11-04 07:21:38 +00:00
return code;
}
2022-11-04 07:21:38 +00:00
// VALUES (field1_value, ...) [(field1_value2, ...) ...]
static int32_t parseValuesClause(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt, SRowsDataContext rowsDataContext,
2022-11-04 07:21:38 +00:00
SToken* pToken) {
int32_t numOfRows = 0;
int32_t code = parseValues(pCxt, pStmt, rowsDataContext, &numOfRows, pToken);
2022-11-04 07:21:38 +00:00
if (TSDB_CODE_SUCCESS == code) {
pStmt->totalRowsNum += numOfRows;
pStmt->totalTbNum += 1;
TSDB_QUERY_SET_TYPE(pStmt->insertType, TSDB_QUERY_TYPE_INSERT);
}
return code;
}
// Simplified CSV parser - only handles newlines within quotes
static int32_t csvParserReadLine(SCsvParser* parser) {
if (!parser) {
return TSDB_CODE_INVALID_PARA;
}
size_t lineLen = 0;
bool inQuotes = false;
char currentQuote = '\0'; // Track which quote character we're inside
int32_t code = TSDB_CODE_SUCCESS;
while (true) {
// Fill buffer if needed
if (parser->bufferPos >= parser->bufferLen) {
code = csvParserFillBuffer(parser);
if (code != TSDB_CODE_SUCCESS) {
break;
}
if (parser->bufferPos >= parser->bufferLen && parser->eof) {
// End of file
if (lineLen == 0) {
code = TSDB_CODE_TSC_QUERY_CANCELLED; // Use this to indicate EOF
}
break;
}
}
char ch = parser->buffer[parser->bufferPos++];
// Handle quotes - support both single and double quotes
if (!inQuotes && (ch == CSV_QUOTE_SINGLE || ch == CSV_QUOTE_DOUBLE)) {
// Starting a quoted section
inQuotes = true;
currentQuote = ch;
} else if (inQuotes && ch == currentQuote) {
// Check for escaped quote (double quote)
if (parser->bufferPos < parser->bufferLen && parser->buffer[parser->bufferPos] == currentQuote) {
// Escaped quote - keep both quotes in line for subsequent processing
// Ensure enough space for both quote characters
code = csvParserExpandLineBuffer(parser, lineLen + 2);
if (code != TSDB_CODE_SUCCESS) {
break;
}
// Add the first quote character to the line
parser->lineBuffer[lineLen++] = ch;
// Consume and add the second quote character
parser->bufferPos++;
ch = parser->buffer[parser->bufferPos - 1]; // The second quote
parser->lineBuffer[lineLen++] = ch;
continue;
} else {
// End of quoted section
inQuotes = false;
currentQuote = '\0';
}
}
// Handle newlines
if (ch == '\n' && !inQuotes) {
// End of line (not inside quotes)
break;
}
// Skip \r characters only when outside quotes
if (ch == '\r' && !inQuotes) {
continue;
}
// Expand buffer if needed
code = csvParserExpandLineBuffer(parser, lineLen + 1);
if (code != TSDB_CODE_SUCCESS) {
break;
}
// Add character to line
parser->lineBuffer[lineLen++] = ch;
}
if (code == TSDB_CODE_SUCCESS) {
parser->lineBuffer[lineLen] = '\0';
}
return code;
}
static int32_t parseCsvFile(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt, SRowsDataContext rowsDataCxt,
2022-11-27 09:09:02 +00:00
int32_t* pNumOfRows) {
int32_t code = TSDB_CODE_SUCCESS;
2022-11-04 07:21:38 +00:00
(*pNumOfRows) = 0;
// Initialize or use existing CSV parser in pStmt
if (pStmt->pCsvParser == NULL) {
// First time - allocate and initialize CSV parser
pStmt->pCsvParser = taosMemoryMalloc(sizeof(SCsvParser));
if (!pStmt->pCsvParser) {
return terrno;
}
code = csvParserInit(pStmt->pCsvParser, pStmt->fp);
if (code != TSDB_CODE_SUCCESS) {
taosMemoryFree(pStmt->pCsvParser);
pStmt->pCsvParser = NULL;
return code;
}
}
// If pStmt->pCsvParser exists, we continue from where we left off
bool firstLine = (pStmt->fileProcessing == false);
2022-11-06 06:26:19 +00:00
pStmt->fileProcessing = false;
while (TSDB_CODE_SUCCESS == code) {
// Read one line from CSV using the parser in pStmt
code = csvParserReadLine(pStmt->pCsvParser);
if (code == TSDB_CODE_TSC_QUERY_CANCELLED) {
// End of file
code = TSDB_CODE_SUCCESS;
break;
}
if (code != TSDB_CODE_SUCCESS) {
break;
2022-06-30 07:04:54 +00:00
}
// Skip empty lines
if (!pStmt->pCsvParser->lineBuffer || strlen(pStmt->pCsvParser->lineBuffer) == 0) {
2022-12-14 08:34:56 +00:00
firstLine = false;
2022-06-30 07:04:54 +00:00
continue;
}
bool gotRow = false;
SToken token;
(void)strtolower(pStmt->pCsvParser->lineBuffer, pStmt->pCsvParser->lineBuffer);
const char* pRow = pStmt->pCsvParser->lineBuffer;
if (!pStmt->stbSyntax) {
code = parseOneRow(pCxt, (const char**)&pRow, rowsDataCxt.pTableDataCxt, &gotRow, &token);
} else {
STableDataCxt* pTableDataCxt = NULL;
code = parseOneStbRow(pCxt, pStmt, (const char**)&pRow, rowsDataCxt.pStbRowsCxt, &gotRow, &token, &pTableDataCxt);
if (code == TSDB_CODE_SUCCESS) {
SStbRowsDataContext* pStbRowsCxt = rowsDataCxt.pStbRowsCxt;
void* pData = pTableDataCxt;
code = taosHashPut(pStmt->pTableCxtHashObj, &pStbRowsCxt->pCtbMeta->uid, sizeof(pStbRowsCxt->pCtbMeta->uid),
&pData, POINTER_BYTES);
if (TSDB_CODE_SUCCESS != code) {
break;
}
}
}
if (code && firstLine) {
firstLine = false;
code = 0;
continue;
2022-10-19 05:56:39 +00:00
}
2022-11-04 07:21:38 +00:00
if (TSDB_CODE_SUCCESS == code && gotRow) {
(*pNumOfRows)++;
2022-06-30 07:04:54 +00:00
}
2023-11-28 17:53:13 +00:00
if (TSDB_CODE_SUCCESS == code && (*pNumOfRows) >= tsMaxInsertBatchRows) {
// Reached batch limit - keep the parser in pStmt for next batch
2022-11-06 06:26:19 +00:00
pStmt->fileProcessing = true;
break;
}
2022-12-14 08:34:56 +00:00
firstLine = false;
2022-06-30 07:04:54 +00:00
}
// Don't destroy the parser here - it will be cleaned up when file processing is complete
2022-06-30 07:04:54 +00:00
2025-02-26 03:34:50 +00:00
parserDebug("QID:0x%" PRIx64 ", %d rows have been parsed", pCxt->pComCxt->requestId, *pNumOfRows);
2023-11-28 17:53:13 +00:00
if (TSDB_CODE_SUCCESS == code && 0 == (*pNumOfRows) && 0 == pStmt->totalRowsNum &&
2022-11-06 06:26:19 +00:00
(!TSDB_QUERY_HAS_TYPE(pStmt->insertType, TSDB_QUERY_TYPE_STMT_INSERT)) && !pStmt->fileProcessing) {
2022-11-04 07:21:38 +00:00
code = buildSyntaxErrMsg(&pCxt->msg, "no any data points", NULL);
2022-06-30 07:04:54 +00:00
}
2022-11-04 07:21:38 +00:00
return code;
2022-06-30 07:04:54 +00:00
}
2024-03-26 07:11:15 +00:00
static int32_t parseDataFromFileImpl(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt,
SRowsDataContext rowsDataCxt) {
// init only for file
if (NULL == pStmt->pTableCxtHashObj) {
2024-03-26 07:11:15 +00:00
pStmt->pTableCxtHashObj = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK);
2024-07-23 11:04:01 +00:00
if (!pStmt->pTableCxtHashObj) {
2024-09-20 09:48:04 +00:00
return terrno;
2024-07-23 11:04:01 +00:00
}
}
2022-06-30 07:04:54 +00:00
int32_t numOfRows = 0;
int32_t code = parseCsvFile(pCxt, pStmt, rowsDataCxt, &numOfRows);
2022-11-04 07:21:38 +00:00
if (TSDB_CODE_SUCCESS == code) {
pStmt->totalRowsNum += numOfRows;
pStmt->totalTbNum += 1;
TSDB_QUERY_SET_TYPE(pStmt->insertType, TSDB_QUERY_TYPE_FILE_INSERT);
2024-02-04 04:28:00 +00:00
if (rowsDataCxt.pTableDataCxt && rowsDataCxt.pTableDataCxt->pData) {
rowsDataCxt.pTableDataCxt->pData->flags |= SUBMIT_REQ_FROM_FILE;
}
2022-11-06 06:26:19 +00:00
if (!pStmt->fileProcessing) {
// File processing is complete, clean up saved CSV parser
destroySavedCsvParser(pStmt);
2024-07-23 07:59:10 +00:00
code = taosCloseFile(&pStmt->fp);
if (TSDB_CODE_SUCCESS != code) {
2025-02-26 03:34:50 +00:00
parserWarn("QID:0x%" PRIx64 ", failed to close file.", pCxt->pComCxt->requestId);
2024-07-23 07:59:10 +00:00
}
2022-11-04 07:21:38 +00:00
} else {
2025-02-26 03:34:50 +00:00
parserDebug("QID:0x%" PRIx64 ", insert from csv. File is too large, do it in batches.", pCxt->pComCxt->requestId);
2022-11-04 07:21:38 +00:00
}
2023-11-28 17:53:13 +00:00
if (pStmt->insertType != TSDB_QUERY_TYPE_FILE_INSERT) {
destroySavedCsvParser(pStmt);
2023-11-28 17:53:13 +00:00
return buildSyntaxErrMsg(&pCxt->msg, "keyword VALUES or FILE is exclusive", NULL);
}
} else {
// On error, also clean up saved CSV parser
destroySavedCsvParser(pStmt);
return buildInvalidOperationMsg(&pCxt->msg, tstrerror(code));
2023-11-28 17:53:13 +00:00
}
// just record pTableCxt whose data come from file
2023-11-28 18:44:55 +00:00
if (!pStmt->stbSyntax && numOfRows > 0) {
2023-11-28 17:53:13 +00:00
void* pData = rowsDataCxt.pTableDataCxt;
2024-07-23 07:59:10 +00:00
code = taosHashPut(pStmt->pTableCxtHashObj, &pStmt->pTableMeta->uid, sizeof(pStmt->pTableMeta->uid), &pData,
POINTER_BYTES);
}
2023-11-28 17:53:13 +00:00
2022-11-06 06:26:19 +00:00
return code;
2022-06-30 07:04:54 +00:00
}
2022-12-20 08:53:08 +00:00
static int32_t parseDataFromFile(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt, SToken* pFilePath,
SRowsDataContext rowsDataCxt) {
char filePathStr[PATH_MAX + 16] = {0};
2022-11-04 07:21:38 +00:00
if (TK_NK_STRING == pFilePath->type) {
2024-07-23 07:59:10 +00:00
(void)trimString(pFilePath->z, pFilePath->n, filePathStr, sizeof(filePathStr));
if (strlen(filePathStr) >= PATH_MAX) {
return buildSyntaxErrMsg(&pCxt->msg, "file path is too long, max length is 4096", pFilePath->z);
}
} else {
if (pFilePath->n >= PATH_MAX) {
return buildSyntaxErrMsg(&pCxt->msg, "file path is too long, max length is 4096", pFilePath->z);
}
2022-11-04 07:21:38 +00:00
strncpy(filePathStr, pFilePath->z, pFilePath->n);
}
pStmt->fp = taosOpenFile(filePathStr, TD_FILE_READ);
2022-11-04 07:21:38 +00:00
if (NULL == pStmt->fp) {
2024-09-10 09:40:19 +00:00
return terrno;
}
return parseDataFromFileImpl(pCxt, pStmt, rowsDataCxt);
}
static int32_t parseFileClause(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt, SRowsDataContext rowsDataCxt,
2022-11-04 07:21:38 +00:00
SToken* pToken) {
if (tsUseAdapter) {
return buildInvalidOperationMsg(&pCxt->msg, "proxy mode does not support csv loading");
}
2022-11-04 07:21:38 +00:00
NEXT_TOKEN(pStmt->pSql, *pToken);
if (0 == pToken->n || (TK_NK_STRING != pToken->type && TK_NK_ID != pToken->type)) {
return buildSyntaxErrMsg(&pCxt->msg, "file path is required following keyword FILE", pToken->z);
}
return parseDataFromFile(pCxt, pStmt, pToken, rowsDataCxt);
2021-12-22 05:39:11 +00:00
}
2022-11-04 07:21:38 +00:00
// VALUES (field1_value, ...) [(field1_value2, ...) ...] | FILE csv_file_path
static int32_t parseDataClause(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt, SRowsDataContext rowsDataCxt) {
2022-11-04 07:21:38 +00:00
SToken token;
NEXT_TOKEN(pStmt->pSql, token);
switch (token.type) {
case TK_VALUES:
2023-11-28 17:53:13 +00:00
if (TSDB_QUERY_HAS_TYPE(pStmt->insertType, TSDB_QUERY_TYPE_FILE_INSERT)) {
return buildSyntaxErrMsg(&pCxt->msg, "keyword VALUES or FILE is exclusive", token.z);
}
return parseValuesClause(pCxt, pStmt, rowsDataCxt, &token);
2022-11-04 07:21:38 +00:00
case TK_FILE:
return parseFileClause(pCxt, pStmt, rowsDataCxt, &token);
2022-11-04 07:21:38 +00:00
default:
break;
}
return buildSyntaxErrMsg(&pCxt->msg, "keyword VALUES or FILE is expected", token.z);
2021-12-22 05:39:11 +00:00
}
2023-10-24 08:23:03 +00:00
static void destroyStbRowsDataContext(SStbRowsDataContext* pStbRowsCxt) {
if (pStbRowsCxt == NULL) return;
clearStbRowsDataContext(pStbRowsCxt);
2023-10-24 08:23:03 +00:00
taosArrayDestroy(pStbRowsCxt->aColVals);
pStbRowsCxt->aColVals = NULL;
2023-10-24 08:23:03 +00:00
taosArrayDestroy(pStbRowsCxt->aTagVals);
pStbRowsCxt->aTagVals = NULL;
2023-10-24 08:23:03 +00:00
taosArrayDestroy(pStbRowsCxt->aTagNames);
pStbRowsCxt->aTagNames = NULL;
2023-10-24 08:23:03 +00:00
insDestroyBoundColInfo(&pStbRowsCxt->boundColsInfo);
tTagFree(pStbRowsCxt->pTag);
pStbRowsCxt->pTag = NULL;
taosMemoryFreeClear(pStbRowsCxt->pCtbMeta);
2023-10-24 08:23:03 +00:00
tdDestroySVCreateTbReq(pStbRowsCxt->pCreateCtbReq);
taosMemoryFreeClear(pStbRowsCxt->pCreateCtbReq);
2023-10-24 08:08:08 +00:00
}
static int32_t constructStbRowsDataContext(SVnodeModifyOpStmt* pStmt, SStbRowsDataContext** ppStbRowsCxt) {
2023-10-24 08:23:03 +00:00
SStbRowsDataContext* pStbRowsCxt = taosMemoryCalloc(1, sizeof(SStbRowsDataContext));
2023-10-24 08:08:08 +00:00
if (!pStbRowsCxt) {
2024-09-10 10:42:00 +00:00
return terrno;
2023-10-24 08:08:08 +00:00
}
tNameAssign(&pStbRowsCxt->stbName, &pStmt->targetTableName);
2024-07-22 01:40:19 +00:00
int32_t code = collectUseTable(&pStbRowsCxt->stbName, pStmt->pTableNameHashObj);
if (TSDB_CODE_SUCCESS == code) {
code = collectUseDatabase(&pStbRowsCxt->stbName, pStmt->pDbFNameHashObj);
}
if (TSDB_CODE_SUCCESS == code) {
pStbRowsCxt->ctbName.type = TSDB_TABLE_NAME_T;
pStbRowsCxt->ctbName.acctId = pStbRowsCxt->stbName.acctId;
memcpy(pStbRowsCxt->ctbName.dbname, pStbRowsCxt->stbName.dbname, sizeof(pStbRowsCxt->stbName.dbname));
2023-11-03 08:13:35 +00:00
2024-07-22 01:40:19 +00:00
pStbRowsCxt->pTagCond = pStmt->pTagCond;
pStbRowsCxt->pStbMeta = pStmt->pTableMeta;
2024-07-22 01:40:19 +00:00
code = cloneTableMeta(pStbRowsCxt->pStbMeta, &pStbRowsCxt->pCtbMeta);
}
if (TSDB_CODE_SUCCESS == code) {
pStbRowsCxt->pCtbMeta->tableType = TSDB_CHILD_TABLE;
pStbRowsCxt->pCtbMeta->suid = pStbRowsCxt->pStbMeta->uid;
2024-03-26 07:11:15 +00:00
2024-07-22 01:40:19 +00:00
pStbRowsCxt->aTagNames = taosArrayInit(8, TSDB_COL_NAME_LEN);
2024-07-23 07:59:10 +00:00
if (!pStbRowsCxt->aTagNames) {
2024-09-20 09:48:04 +00:00
code = terrno;
2024-07-23 07:59:10 +00:00
}
2024-07-22 01:40:19 +00:00
}
2024-07-23 07:59:10 +00:00
if (TSDB_CODE_SUCCESS == code) {
pStbRowsCxt->aTagVals = taosArrayInit(8, sizeof(STagVal));
if (!pStbRowsCxt->aTagVals) {
2024-09-20 09:48:04 +00:00
code = terrno;
2024-07-23 07:59:10 +00:00
}
}
if (TSDB_CODE_SUCCESS == code) {
// col values and bound cols info of STableDataContext is not used
pStbRowsCxt->aColVals = taosArrayInit(getNumOfColumns(pStbRowsCxt->pStbMeta), sizeof(SColVal));
if (!pStbRowsCxt->aColVals) code = terrno;
2024-07-23 07:59:10 +00:00
}
if (TSDB_CODE_SUCCESS == code) {
code = insInitColValues(pStbRowsCxt->pStbMeta, pStbRowsCxt->aColVals);
}
if (TSDB_CODE_SUCCESS == code) {
STableComInfo tblInfo = getTableInfo(pStmt->pTableMeta);
code = insInitBoundColsInfo(tblInfo.numOfColumns + tblInfo.numOfTags + 1, &pStbRowsCxt->boundColsInfo);
}
if (TSDB_CODE_SUCCESS == code) {
*ppStbRowsCxt = pStbRowsCxt;
} else {
clearStbRowsDataContext(pStbRowsCxt);
}
return code;
}
static int32_t parseInsertStbClauseBottom(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt) {
int32_t code = TSDB_CODE_SUCCESS;
if (!pStmt->pBoundCols) {
2024-03-26 07:11:15 +00:00
return buildSyntaxErrMsg(&pCxt->msg, "(...tbname, ts...) bounded cols is expected for supertable insertion",
pStmt->pSql);
}
SStbRowsDataContext* pStbRowsCxt = NULL;
code = constructStbRowsDataContext(pStmt, &pStbRowsCxt);
if (code == TSDB_CODE_SUCCESS) {
code = parseBoundColumns(pCxt, &pStmt->pBoundCols, BOUND_ALL_AND_TBNAME, pStmt->pTableMeta,
&pStbRowsCxt->boundColsInfo);
2023-10-31 02:48:10 +00:00
pStbRowsCxt->hasTimestampTag = false;
for (int32_t i = 0; i < pStbRowsCxt->boundColsInfo.numOfBound; ++i) {
int16_t schemaIndex = pStbRowsCxt->boundColsInfo.pColIndex[i];
2024-03-26 07:11:15 +00:00
if (schemaIndex != getTbnameSchemaIndex(pStmt->pTableMeta) && schemaIndex >= getNumOfColumns(pStmt->pTableMeta)) {
2023-11-01 00:32:31 +00:00
if (pStmt->pTableMeta->schema[schemaIndex].type == TSDB_DATA_TYPE_TIMESTAMP) {
pStbRowsCxt->hasTimestampTag = true;
}
if (pStmt->pTableMeta->schema[schemaIndex].type == TSDB_DATA_TYPE_JSON) {
pStbRowsCxt->isJsonTag = true;
}
2023-10-31 02:48:10 +00:00
}
}
pStmt->pStbRowsCxt = pStbRowsCxt;
}
2023-10-25 01:35:37 +00:00
if (code == TSDB_CODE_SUCCESS) {
SRowsDataContext rowsDataCxt;
rowsDataCxt.pStbRowsCxt = pStbRowsCxt;
code = parseDataClause(pCxt, pStmt, rowsDataCxt);
2023-10-22 03:21:36 +00:00
}
2023-10-25 01:35:37 +00:00
return code;
}
2022-11-04 07:21:38 +00:00
// input pStmt->pSql:
// 1. [(tag1_name, ...)] ...
// 2. VALUES ... | FILE ...
2022-12-20 08:53:08 +00:00
static int32_t parseInsertTableClauseBottom(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt) {
if (!pStmt->stbSyntax) {
2024-03-26 07:11:15 +00:00
STableDataCxt* pTableCxt = NULL;
int32_t code = parseSchemaClauseBottom(pCxt, pStmt, &pTableCxt);
SRowsDataContext rowsDataCxt;
rowsDataCxt.pTableDataCxt = pTableCxt;
if (TSDB_CODE_SUCCESS == code) {
code = parseDataClause(pCxt, pStmt, rowsDataCxt);
}
return code;
} else {
int32_t code = parseInsertStbClauseBottom(pCxt, pStmt);
return code;
2022-08-15 06:45:59 +00:00
}
}
2022-12-20 08:53:08 +00:00
static void resetEnvPreTable(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt) {
2022-12-28 02:49:38 +00:00
insDestroyBoundColInfo(&pCxt->tags);
2022-11-06 10:42:53 +00:00
taosMemoryFreeClear(pStmt->pTableMeta);
2023-04-25 09:39:28 +00:00
nodesDestroyNode(pStmt->pTagCond);
taosArrayDestroy(pStmt->pTableTag);
2022-11-27 09:09:02 +00:00
tdDestroySVCreateTbReq(pStmt->pCreateTblReq);
taosMemoryFreeClear(pStmt->pCreateTblReq);
2022-11-06 10:42:53 +00:00
pCxt->missCache = false;
pCxt->usingDuplicateTable = false;
2022-11-07 03:31:45 +00:00
pStmt->pBoundCols = NULL;
2022-11-06 10:42:53 +00:00
pStmt->usingTableProcessing = false;
pStmt->fileProcessing = false;
pStmt->usingTableName.type = 0;
2023-10-25 01:35:37 +00:00
destroyStbRowsDataContext(pStmt->pStbRowsCxt);
taosMemoryFreeClear(pStmt->pStbRowsCxt);
pStmt->stbSyntax = false;
2022-11-06 10:42:53 +00:00
}
2022-11-04 07:21:38 +00:00
// input pStmt->pSql: [(field1_name, ...)] [ USING ... ] VALUES ... | FILE ...
2022-12-20 08:53:08 +00:00
static int32_t parseInsertTableClause(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt, SToken* pTbName) {
2022-11-06 10:42:53 +00:00
resetEnvPreTable(pCxt, pStmt);
2022-11-04 07:21:38 +00:00
int32_t code = parseSchemaClauseTop(pCxt, pStmt, pTbName);
if (TSDB_CODE_SUCCESS == code && !pCxt->missCache) {
code = parseInsertTableClauseBottom(pCxt, pStmt);
2022-11-04 07:21:38 +00:00
}
2022-11-04 07:21:38 +00:00
return code;
}
2022-05-24 09:37:53 +00:00
2022-12-20 08:53:08 +00:00
static int32_t checkTableClauseFirstToken(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt, SToken* pTbName,
2022-11-04 07:21:38 +00:00
bool* pHasData) {
// no data in the sql string anymore.
if (0 == pTbName->n) {
if (0 != pTbName->type && '\0' != pStmt->pSql[0]) {
return buildSyntaxErrMsg(&pCxt->msg, "invalid table name", pTbName->z);
}
2022-11-04 07:21:38 +00:00
if (0 == pStmt->totalRowsNum && (!TSDB_QUERY_HAS_TYPE(pStmt->insertType, TSDB_QUERY_TYPE_STMT_INSERT))) {
return buildInvalidOperationMsg(&pCxt->msg, "no data in sql");
2022-04-14 12:14:52 +00:00
}
2022-11-04 07:21:38 +00:00
*pHasData = false;
return TSDB_CODE_SUCCESS;
}
2022-04-26 03:50:35 +00:00
2022-11-04 07:21:38 +00:00
if (TSDB_QUERY_HAS_TYPE(pStmt->insertType, TSDB_QUERY_TYPE_STMT_INSERT) && pStmt->totalTbNum > 0) {
return buildInvalidOperationMsg(&pCxt->msg, "single table allowed in one stmt");
}
2022-11-04 07:21:38 +00:00
if (TK_NK_QUESTION == pTbName->type) {
pCxt->stmtTbNameFlag &= ~IS_FIXED_VALUE;
2024-07-02 02:18:56 +00:00
pCxt->isStmtBind = true;
2022-11-04 07:21:38 +00:00
if (NULL == pCxt->pComCxt->pStmtCb) {
return buildSyntaxErrMsg(&pCxt->msg, "? only used in stmt", pTbName->z);
2022-08-10 09:47:28 +00:00
}
2022-05-12 10:59:02 +00:00
2022-11-04 07:21:38 +00:00
char* tbName = NULL;
int32_t code = (*pCxt->pComCxt->pStmtCb->getTbNameFn)(pCxt->pComCxt->pStmtCb->pStmt, &tbName);
if (TSDB_CODE_SUCCESS == code) {
pCxt->stmtTbNameFlag |= HAS_BIND_VALUE;
2022-11-04 07:21:38 +00:00
pTbName->z = tbName;
pTbName->n = strlen(tbName);
}
if (code == TSDB_CODE_TSC_STMT_TBNAME_ERROR) {
pCxt->stmtTbNameFlag &= ~HAS_BIND_VALUE;
2024-12-03 02:49:01 +00:00
code = TSDB_CODE_SUCCESS;
}
return code;
2022-11-04 07:21:38 +00:00
}
if (TK_NK_ID != pTbName->type && TK_NK_STRING != pTbName->type && TK_NK_QUESTION != pTbName->type) {
return buildSyntaxErrMsg(&pCxt->msg, "table_name is expected", pTbName->z);
}
2024-06-25 08:16:32 +00:00
// db.? situationensure that the only thing following the '.' mark is '?'
char* tbNameAfterDbName = strnchr(pTbName->z, '.', pTbName->n, true);
if (tbNameAfterDbName != NULL) {
if (*(tbNameAfterDbName + 1) == '?') {
pCxt->stmtTbNameFlag &= ~IS_FIXED_VALUE;
char* tbName = NULL;
if (NULL == pCxt->pComCxt->pStmtCb) {
return buildSyntaxErrMsg(&pCxt->msg, "? only used in stmt", pTbName->z);
}
int32_t code = (*pCxt->pComCxt->pStmtCb->getTbNameFn)(pCxt->pComCxt->pStmtCb->pStmt, &tbName);
if (TSDB_CODE_SUCCESS == code) {
pCxt->stmtTbNameFlag |= HAS_BIND_VALUE;
pTbName->z = tbName;
pTbName->n = strlen(tbName);
}
if (code == TSDB_CODE_TSC_STMT_TBNAME_ERROR) {
pCxt->stmtTbNameFlag &= ~HAS_BIND_VALUE;
code = TSDB_CODE_SUCCESS;
}
} else {
pCxt->stmtTbNameFlag |= IS_FIXED_VALUE;
2025-02-26 03:34:50 +00:00
parserWarn("QID:0x%" PRIx64 ", table name is specified in sql, ignore the table name in bind param",
pCxt->pComCxt->requestId);
*pHasData = true;
2024-07-05 06:18:51 +00:00
}
return TSDB_CODE_SUCCESS;
}
if (TK_NK_ID == pTbName->type) {
pCxt->stmtTbNameFlag |= IS_FIXED_VALUE;
2024-07-05 06:18:51 +00:00
}
2022-11-04 07:21:38 +00:00
*pHasData = true;
return TSDB_CODE_SUCCESS;
}
2022-12-20 08:53:08 +00:00
static int32_t setStmtInfo(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt) {
2022-12-28 02:49:38 +00:00
SBoundColInfo* tags = taosMemoryMalloc(sizeof(pCxt->tags));
2022-11-04 07:21:38 +00:00
if (NULL == tags) {
2024-09-20 09:48:04 +00:00
return terrno;
2022-11-04 07:21:38 +00:00
}
memcpy(tags, &pCxt->tags, sizeof(pCxt->tags));
2022-11-04 07:21:38 +00:00
SStmtCallback* pStmtCb = pCxt->pComCxt->pStmtCb;
2022-12-04 02:09:10 +00:00
int32_t code = (*pStmtCb->setInfoFn)(pStmtCb->pStmt, pStmt->pTableMeta, tags, &pStmt->targetTableName,
pStmt->usingTableProcessing, pStmt->pVgroupsHashObj, pStmt->pTableBlockHashObj,
pStmt->usingTableName.tname, pCxt->stmtTbNameFlag);
2022-11-04 07:21:38 +00:00
memset(&pCxt->tags, 0, sizeof(pCxt->tags));
pStmt->pVgroupsHashObj = NULL;
pStmt->pTableBlockHashObj = NULL;
return code;
}
2022-12-20 08:53:08 +00:00
static int32_t parseInsertBodyBottom(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt) {
2022-11-04 07:21:38 +00:00
if (TSDB_QUERY_HAS_TYPE(pStmt->insertType, TSDB_QUERY_TYPE_STMT_INSERT)) {
return setStmtInfo(pCxt, pStmt);
}
2022-04-14 12:14:52 +00:00
2023-11-28 17:53:13 +00:00
// release old array alloced by merge
pStmt->freeArrayFunc(pStmt->pVgDataBlocks);
pStmt->pVgDataBlocks = NULL;
bool fileOnly = (pStmt->insertType == TSDB_QUERY_TYPE_FILE_INSERT);
2023-11-28 17:53:13 +00:00
if (fileOnly) {
2024-03-26 07:11:15 +00:00
// none data, skip merge & buildvgdata
2023-11-28 17:53:13 +00:00
if (0 == taosHashGetSize(pStmt->pTableCxtHashObj)) {
pCxt->needRequest = false;
return TSDB_CODE_SUCCESS;
}
}
2022-11-04 07:21:38 +00:00
// merge according to vgId
2023-11-28 17:53:13 +00:00
int32_t code = insMergeTableDataCxt(fileOnly ? pStmt->pTableCxtHashObj : pStmt->pTableBlockHashObj,
&pStmt->pVgDataBlocks, pStmt->fileProcessing);
// clear tmp hashobj only
taosHashClear(pStmt->pTableCxtHashObj);
2022-11-04 07:21:38 +00:00
if (TSDB_CODE_SUCCESS == code) {
2024-05-30 05:26:17 +00:00
code = insBuildVgDataBlocks(pStmt->pVgroupsHashObj, pStmt->pVgDataBlocks, &pStmt->pDataBlocks, false);
2022-11-04 07:21:38 +00:00
}
2022-11-27 09:09:02 +00:00
2022-11-04 07:21:38 +00:00
return code;
}
2022-11-04 07:21:38 +00:00
// tb_name
// [USING stb_name [(tag1_name, ...)] TAGS (tag1_value, ...)]
// [(field1_name, ...)]
// VALUES (field1_value, ...) [(field1_value2, ...) ...] | FILE csv_file_path
// [...];
2022-12-20 08:53:08 +00:00
static int32_t parseInsertBody(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt) {
2022-11-04 07:21:38 +00:00
SToken token;
int32_t code = TSDB_CODE_SUCCESS;
bool hasData = true;
// for each table
2022-11-06 06:26:19 +00:00
while (TSDB_CODE_SUCCESS == code && hasData && !pCxt->missCache && !pStmt->fileProcessing) {
2022-11-04 07:21:38 +00:00
// pStmt->pSql -> tb_name ...
NEXT_TOKEN(pStmt->pSql, token);
code = checkTableClauseFirstToken(pCxt, pStmt, &token, &hasData);
if (TSDB_CODE_SUCCESS == code && hasData) {
code = parseInsertTableClause(pCxt, pStmt, &token);
}
if( TSDB_CODE_SUCCESS == code && pStmt->pTableMeta &&
(((pStmt->pTableMeta->virtualStb == 1) && (pStmt->pTableMeta->tableType == TSDB_SUPER_TABLE)) ||
(pStmt->pTableMeta->tableType == TSDB_VIRTUAL_NORMAL_TABLE ||
pStmt->pTableMeta->tableType == TSDB_VIRTUAL_CHILD_TABLE))) {
code = buildInvalidOperationMsg(&pCxt->msg, "Virtual table can not be written");
}
}
2022-04-26 03:50:35 +00:00
2022-11-04 07:21:38 +00:00
if (TSDB_CODE_SUCCESS == code && !pCxt->missCache) {
code = parseInsertBodyBottom(pCxt, pStmt);
}
return code;
}
2022-04-14 12:14:52 +00:00
2022-11-04 07:21:38 +00:00
static void destroySubTableHashElem(void* p) { taosMemoryFree(*(STableMeta**)p); }
2022-04-26 03:50:35 +00:00
2022-11-22 10:18:31 +00:00
static int32_t createVnodeModifOpStmt(SInsertParseContext* pCxt, bool reentry, SNode** pOutput) {
2024-07-21 10:20:30 +00:00
SVnodeModifyOpStmt* pStmt = NULL;
int32_t code = nodesMakeNode(QUERY_NODE_VNODE_MODIFY_STMT, (SNode**)&pStmt);
2022-11-04 07:21:38 +00:00
if (NULL == pStmt) {
2024-07-21 10:20:30 +00:00
return code;
2022-04-14 12:14:52 +00:00
}
2022-04-26 03:50:35 +00:00
2022-11-22 10:18:31 +00:00
if (pCxt->pComCxt->pStmtCb) {
2022-11-04 07:21:38 +00:00
TSDB_QUERY_SET_TYPE(pStmt->insertType, TSDB_QUERY_TYPE_STMT_INSERT);
}
2022-11-22 10:18:31 +00:00
pStmt->pSql = pCxt->pComCxt->pSql;
2022-11-27 09:09:02 +00:00
pStmt->freeHashFunc = insDestroyTableDataCxtHashMap;
pStmt->freeArrayFunc = insDestroyVgroupDataCxtList;
pStmt->freeStbRowsCxtFunc = destroyStbRowsDataContext;
pStmt->pCsvParser = NULL;
2024-03-26 07:11:15 +00:00
2022-11-07 03:31:45 +00:00
if (!reentry) {
2024-05-30 05:26:17 +00:00
pStmt->pVgroupsHashObj = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_ENTRY_LOCK);
if (pCxt->pComCxt->pStmtCb) {
pStmt->pTableBlockHashObj =
taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK);
} else {
pStmt->pTableBlockHashObj =
taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, HASH_NO_LOCK);
}
2022-11-07 03:31:45 +00:00
}
2022-11-04 07:21:38 +00:00
pStmt->pSubTableHashObj = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), true, HASH_NO_LOCK);
pStmt->pSuperTableHashObj = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), true, HASH_NO_LOCK);
2022-11-04 07:21:38 +00:00
pStmt->pTableNameHashObj = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), true, HASH_NO_LOCK);
pStmt->pDbFNameHashObj = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), true, HASH_NO_LOCK);
2022-11-07 03:31:45 +00:00
if ((!reentry && (NULL == pStmt->pVgroupsHashObj || NULL == pStmt->pTableBlockHashObj)) ||
NULL == pStmt->pSubTableHashObj || NULL == pStmt->pTableNameHashObj || NULL == pStmt->pDbFNameHashObj) {
2022-11-04 07:21:38 +00:00
nodesDestroyNode((SNode*)pStmt);
return TSDB_CODE_OUT_OF_MEMORY;
}
2022-11-04 07:21:38 +00:00
taosHashSetFreeFp(pStmt->pSubTableHashObj, destroySubTableHashElem);
taosHashSetFreeFp(pStmt->pSuperTableHashObj, destroySubTableHashElem);
2022-11-04 07:21:38 +00:00
*pOutput = (SNode*)pStmt;
return TSDB_CODE_SUCCESS;
}
2022-11-22 10:18:31 +00:00
static int32_t createInsertQuery(SInsertParseContext* pCxt, SQuery** pOutput) {
2024-07-21 10:20:30 +00:00
SQuery* pQuery = NULL;
int32_t code = nodesMakeNode(QUERY_NODE_QUERY, (SNode**)&pQuery);
2022-11-04 07:21:38 +00:00
if (NULL == pQuery) {
2024-07-21 10:20:30 +00:00
return code;
2022-04-16 07:59:19 +00:00
}
2022-04-26 03:50:35 +00:00
2022-11-04 07:21:38 +00:00
pQuery->execMode = QUERY_EXEC_MODE_SCHEDULE;
pQuery->haveResultSet = false;
pQuery->msgType = TDMT_VND_SUBMIT;
2024-07-21 10:20:30 +00:00
code = createVnodeModifOpStmt(pCxt, false, &pQuery->pRoot);
2022-11-04 07:21:38 +00:00
if (TSDB_CODE_SUCCESS == code) {
*pOutput = pQuery;
} else {
nodesDestroyNode((SNode*)pQuery);
2022-04-14 12:14:52 +00:00
}
2022-11-04 07:21:38 +00:00
return code;
}
2022-04-14 12:14:52 +00:00
2023-04-25 09:39:28 +00:00
static int32_t checkAuthFromMetaData(const SArray* pUsers, SNode** pTagCond) {
2022-11-04 07:21:38 +00:00
if (1 != taosArrayGetSize(pUsers)) {
return TSDB_CODE_FAILED;
}
2022-11-04 07:21:38 +00:00
SMetaRes* pRes = taosArrayGet(pUsers, 0);
if (TSDB_CODE_SUCCESS == pRes->code) {
2023-04-25 09:39:28 +00:00
SUserAuthRes* pAuth = pRes->pRes;
2024-07-21 10:20:30 +00:00
pRes->code = nodesCloneNode(pAuth->pCond[AUTH_RES_BASIC], pTagCond);
if (TSDB_CODE_SUCCESS == pRes->code) {
return pAuth->pass[AUTH_RES_BASIC] ? TSDB_CODE_SUCCESS : TSDB_CODE_PAR_PERMISSION_DENIED;
2023-04-25 09:39:28 +00:00
}
2022-11-04 07:21:38 +00:00
}
return pRes->code;
}
2022-04-26 03:50:35 +00:00
2022-11-04 07:21:38 +00:00
static int32_t getTableMetaFromMetaData(const SArray* pTables, STableMeta** pMeta) {
if (1 != taosArrayGetSize(pTables) && 2 != taosArrayGetSize(pTables)) {
2022-11-04 07:21:38 +00:00
return TSDB_CODE_FAILED;
}
2022-12-19 02:25:14 +00:00
taosMemoryFreeClear(*pMeta);
2022-11-04 07:21:38 +00:00
SMetaRes* pRes = taosArrayGet(pTables, 0);
if (TSDB_CODE_SUCCESS == pRes->code) {
*pMeta = tableMetaDup((const STableMeta*)pRes->pRes);
if (NULL == *pMeta) {
2022-05-13 08:35:19 +00:00
return TSDB_CODE_OUT_OF_MEMORY;
}
}
2022-11-04 07:21:38 +00:00
return pRes->code;
}
static int32_t addTableVgroupFromMetaData(const SArray* pTables, SVnodeModifyOpStmt* pStmt, bool isStb) {
2022-11-04 07:21:38 +00:00
if (1 != taosArrayGetSize(pTables)) {
return TSDB_CODE_FAILED;
2022-06-02 04:34:35 +00:00
}
2022-11-04 07:21:38 +00:00
SMetaRes* pRes = taosArrayGet(pTables, 0);
if (TSDB_CODE_SUCCESS != pRes->code) {
return pRes->code;
}
2022-11-04 07:21:38 +00:00
SVgroupInfo* pVg = pRes->pRes;
if (isStb) {
pStmt->pTableMeta->vgId = pVg->vgId;
}
return taosHashPut(pStmt->pVgroupsHashObj, (const char*)&pVg->vgId, sizeof(pVg->vgId), (char*)pVg,
sizeof(SVgroupInfo));
}
2022-06-02 04:34:35 +00:00
2023-04-25 09:39:28 +00:00
static int32_t buildTagNameFromMeta(STableMeta* pMeta, SArray** pTagName) {
*pTagName = taosArrayInit(pMeta->tableInfo.numOfTags, TSDB_COL_NAME_LEN);
if (NULL == *pTagName) {
2024-09-20 09:48:04 +00:00
return terrno;
2023-04-25 09:39:28 +00:00
}
SSchema* pSchema = getTableTagSchema(pMeta);
int32_t code = 0;
2023-04-25 09:39:28 +00:00
for (int32_t i = 0; i < pMeta->tableInfo.numOfTags; ++i) {
2024-07-22 01:40:19 +00:00
if (NULL == taosArrayPush(*pTagName, pSchema[i].name)) {
2024-09-20 09:48:04 +00:00
code = terrno;
2024-07-22 01:40:19 +00:00
taosArrayDestroy(*pTagName);
*pTagName = NULL;
break;
}
2023-04-25 09:39:28 +00:00
}
2024-07-22 01:40:19 +00:00
return code;
2023-04-25 09:39:28 +00:00
}
static int32_t checkSubtablePrivilegeForTable(const SArray* pTables, SVnodeModifyOpStmt* pStmt) {
if (1 != taosArrayGetSize(pTables)) {
return TSDB_CODE_FAILED;
}
SMetaRes* pRes = taosArrayGet(pTables, 0);
if (TSDB_CODE_SUCCESS != pRes->code) {
return pRes->code;
}
SArray* pTagName = NULL;
int32_t code = buildTagNameFromMeta(pStmt->pTableMeta, &pTagName);
if (TSDB_CODE_SUCCESS == code) {
code = checkSubtablePrivilege((SArray*)pRes->pRes, pTagName, &pStmt->pTagCond);
}
taosArrayDestroy(pTagName);
return code;
}
static int32_t processTableSchemaFromMetaData(SInsertParseContext* pCxt, const SMetaData* pMetaData,
2024-03-26 07:11:15 +00:00
SVnodeModifyOpStmt* pStmt, bool isStb) {
int32_t code = TSDB_CODE_SUCCESS;
if (!isStb && TSDB_SUPER_TABLE == pStmt->pTableMeta->tableType) {
2022-11-22 10:18:31 +00:00
code = buildInvalidOperationMsg(&pCxt->msg, "insert data into super table is not supported");
}
2023-02-01 02:15:42 +00:00
if (TSDB_CODE_SUCCESS == code && isStb) {
code = storeChildTableMeta(pCxt, pStmt);
2023-02-01 02:15:42 +00:00
}
2022-11-04 07:21:38 +00:00
if (TSDB_CODE_SUCCESS == code) {
code = addTableVgroupFromMetaData(pMetaData->pTableHash, pStmt, isStb);
}
2023-04-25 09:39:28 +00:00
if (TSDB_CODE_SUCCESS == code && !isStb && NULL != pStmt->pTagCond) {
code = checkSubtablePrivilegeForTable(pMetaData->pTableTag, pStmt);
}
2022-01-06 23:34:51 +00:00
return code;
}
2022-04-16 11:41:18 +00:00
2022-11-06 06:26:19 +00:00
static void destoryTablesReq(void* p) {
STablesReq* pRes = (STablesReq*)p;
taosArrayDestroy(pRes->pTables);
}
static void clearCatalogReq(SCatalogReq* pCatalogReq) {
2022-11-07 03:31:45 +00:00
if (NULL == pCatalogReq) {
return;
}
2022-11-06 06:26:19 +00:00
taosArrayDestroyEx(pCatalogReq->pTableMeta, destoryTablesReq);
pCatalogReq->pTableMeta = NULL;
taosArrayDestroyEx(pCatalogReq->pTableHash, destoryTablesReq);
pCatalogReq->pTableHash = NULL;
taosArrayDestroy(pCatalogReq->pUser);
pCatalogReq->pUser = NULL;
2023-04-25 09:39:28 +00:00
taosArrayDestroy(pCatalogReq->pTableTag);
pCatalogReq->pTableTag = NULL;
2022-11-06 06:26:19 +00:00
}
2022-11-22 10:18:31 +00:00
static int32_t setVnodeModifOpStmt(SInsertParseContext* pCxt, SCatalogReq* pCatalogReq, const SMetaData* pMetaData,
2022-12-20 08:53:08 +00:00
SVnodeModifyOpStmt* pStmt) {
2022-11-06 06:26:19 +00:00
clearCatalogReq(pCatalogReq);
int32_t code = checkAuthFromMetaData(pMetaData->pUser, &pStmt->pTagCond);
if (code == TSDB_CODE_SUCCESS) {
code = getTableMetaFromMetaData(pMetaData->pTableMeta, &pStmt->pTableMeta);
2023-10-19 05:28:48 +00:00
}
if (code == TSDB_CODE_SUCCESS) {
if (pStmt->pTableMeta->tableType == TSDB_SUPER_TABLE && !pStmt->usingTableProcessing) {
pStmt->stbSyntax = true;
}
if (!pStmt->stbSyntax) {
if (pStmt->usingTableProcessing) {
return processTableSchemaFromMetaData(pCxt, pMetaData, pStmt, true);
}
return processTableSchemaFromMetaData(pCxt, pMetaData, pStmt, false);
}
}
2023-10-19 05:28:48 +00:00
return code;
2022-11-07 03:31:45 +00:00
}
2022-11-22 10:18:31 +00:00
static int32_t resetVnodeModifOpStmt(SInsertParseContext* pCxt, SQuery* pQuery) {
2022-11-07 03:31:45 +00:00
nodesDestroyNode(pQuery->pRoot);
int32_t code = createVnodeModifOpStmt(pCxt, true, &pQuery->pRoot);
if (TSDB_CODE_SUCCESS == code) {
2022-12-20 08:53:08 +00:00
SVnodeModifyOpStmt* pStmt = (SVnodeModifyOpStmt*)pQuery->pRoot;
2022-11-07 03:31:45 +00:00
2024-07-22 01:40:19 +00:00
code = (*pCxt->pComCxt->pStmtCb->getExecInfoFn)(pCxt->pComCxt->pStmtCb->pStmt, &pStmt->pVgroupsHashObj,
&pStmt->pTableBlockHashObj);
if (TSDB_CODE_SUCCESS == code) {
if (NULL == pStmt->pVgroupsHashObj) {
pStmt->pVgroupsHashObj = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_NO_LOCK);
}
if (NULL == pStmt->pTableBlockHashObj) {
pStmt->pTableBlockHashObj =
taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK);
2024-07-22 01:40:19 +00:00
}
if (NULL == pStmt->pVgroupsHashObj || NULL == pStmt->pTableBlockHashObj) {
code = TSDB_CODE_OUT_OF_MEMORY;
}
2022-11-07 03:31:45 +00:00
}
}
2022-11-04 07:21:38 +00:00
2022-11-07 03:31:45 +00:00
return code;
}
2022-11-22 10:18:31 +00:00
static int32_t initInsertQuery(SInsertParseContext* pCxt, SCatalogReq* pCatalogReq, const SMetaData* pMetaData,
2022-11-06 06:26:19 +00:00
SQuery** pQuery) {
2022-11-04 07:21:38 +00:00
if (NULL == *pQuery) {
return createInsertQuery(pCxt, pQuery);
}
2022-11-06 06:26:19 +00:00
2022-11-22 10:18:31 +00:00
if (NULL != pCxt->pComCxt->pStmtCb) {
2022-11-07 03:31:45 +00:00
return resetVnodeModifOpStmt(pCxt, *pQuery);
}
2022-12-20 08:53:08 +00:00
SVnodeModifyOpStmt* pStmt = (SVnodeModifyOpStmt*)(*pQuery)->pRoot;
2022-11-07 03:31:45 +00:00
if (!pStmt->fileProcessing) {
return setVnodeModifOpStmt(pCxt, pCatalogReq, pMetaData, pStmt);
2022-11-06 06:26:19 +00:00
}
return TSDB_CODE_SUCCESS;
}
static int32_t setRefreshMeta(SQuery* pQuery) {
2022-12-20 08:53:08 +00:00
SVnodeModifyOpStmt* pStmt = (SVnodeModifyOpStmt*)pQuery->pRoot;
int32_t code = 0;
if (taosHashGetSize(pStmt->pTableNameHashObj) > 0) {
taosArrayDestroy(pQuery->pTableList);
pQuery->pTableList = taosArrayInit(taosHashGetSize(pStmt->pTableNameHashObj), sizeof(SName));
2024-07-22 01:40:19 +00:00
if (!pQuery->pTableList) {
2024-09-20 09:48:04 +00:00
code = terrno;
2024-07-22 01:40:19 +00:00
} else {
SName* pTable = taosHashIterate(pStmt->pTableNameHashObj, NULL);
while (NULL != pTable) {
if (NULL == taosArrayPush(pQuery->pTableList, pTable)) {
2024-09-20 09:48:04 +00:00
code = terrno;
2024-07-22 01:40:19 +00:00
taosHashCancelIterate(pStmt->pTableNameHashObj, pTable);
break;
}
pTable = taosHashIterate(pStmt->pTableNameHashObj, pTable);
}
}
}
2024-07-22 01:40:19 +00:00
if (TSDB_CODE_SUCCESS == code && taosHashGetSize(pStmt->pDbFNameHashObj) > 0) {
taosArrayDestroy(pQuery->pDbList);
pQuery->pDbList = taosArrayInit(taosHashGetSize(pStmt->pDbFNameHashObj), TSDB_DB_FNAME_LEN);
2024-07-22 01:40:19 +00:00
if (!pQuery->pDbList) {
2024-09-20 09:48:04 +00:00
code = terrno;
2024-07-22 01:40:19 +00:00
} else {
char* pDb = taosHashIterate(pStmt->pDbFNameHashObj, NULL);
while (NULL != pDb) {
if (NULL == taosArrayPush(pQuery->pDbList, pDb)) {
2024-09-20 09:48:04 +00:00
code = terrno;
2024-07-22 01:40:19 +00:00
taosHashCancelIterate(pStmt->pDbFNameHashObj, pDb);
break;
}
pDb = taosHashIterate(pStmt->pDbFNameHashObj, pDb);
}
}
}
2024-07-22 01:40:19 +00:00
return code;
}
2022-11-04 07:21:38 +00:00
// INSERT INTO
// tb_name
// [USING stb_name [(tag1_name, ...)] TAGS (tag1_value, ...) [table_options]]
// [(field1_name, ...)]
// VALUES (field1_value, ...) [(field1_value2, ...) ...] | FILE csv_file_path
// [...];
2022-12-20 08:53:08 +00:00
static int32_t parseInsertSqlFromStart(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt) {
2022-11-04 07:21:38 +00:00
int32_t code = skipInsertInto(&pStmt->pSql, &pCxt->msg);
if (TSDB_CODE_SUCCESS == code) {
code = parseInsertBody(pCxt, pStmt);
}
return code;
}
2022-12-20 08:53:08 +00:00
static int32_t parseInsertSqlFromCsv(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt) {
2024-03-26 07:11:15 +00:00
int32_t code = TSDB_CODE_SUCCESS;
SRowsDataContext rowsDataCxt;
if (!pStmt->stbSyntax) {
2024-03-26 07:11:15 +00:00
STableDataCxt* pTableCxt = NULL;
code = getTableDataCxt(pCxt, pStmt, &pTableCxt);
rowsDataCxt.pTableDataCxt = pTableCxt;
} else {
rowsDataCxt.pStbRowsCxt = pStmt->pStbRowsCxt;
}
2022-11-04 07:21:38 +00:00
if (TSDB_CODE_SUCCESS == code) {
code = parseDataFromFileImpl(pCxt, pStmt, rowsDataCxt);
}
2022-11-04 07:21:38 +00:00
if (TSDB_CODE_SUCCESS == code) {
if (pStmt->fileProcessing) {
code = parseInsertBodyBottom(pCxt, pStmt);
} else {
code = parseInsertBody(pCxt, pStmt);
}
}
return code;
2022-06-04 13:31:07 +00:00
}
2022-12-20 08:53:08 +00:00
static int32_t parseInsertSqlFromTable(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt) {
2022-11-04 07:21:38 +00:00
int32_t code = parseInsertTableClauseBottom(pCxt, pStmt);
if (TSDB_CODE_SUCCESS == code) {
code = parseInsertBody(pCxt, pStmt);
}
return code;
}
2022-12-20 08:53:08 +00:00
static int32_t parseInsertSqlImpl(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt) {
2022-11-04 07:21:38 +00:00
if (pStmt->pSql == pCxt->pComCxt->pSql || NULL != pCxt->pComCxt->pStmtCb) {
return parseInsertSqlFromStart(pCxt, pStmt);
}
2022-11-04 07:21:38 +00:00
if (pStmt->fileProcessing) {
return parseInsertSqlFromCsv(pCxt, pStmt);
}
2022-11-04 07:21:38 +00:00
return parseInsertSqlFromTable(pCxt, pStmt);
}
static int32_t buildUsingInsertTableReq(SName* pSName, SName* pCName, SArray** pTables) {
if (NULL == *pTables) {
*pTables = taosArrayInit(2, sizeof(SName));
if (NULL == *pTables) {
goto _err;
}
}
if (NULL == taosArrayPush(*pTables, pSName)) {
goto _err;
}
if (NULL == taosArrayPush(*pTables, pCName)) {
goto _err;
}
return TSDB_CODE_SUCCESS;
_err:
if (NULL != *pTables) {
taosArrayDestroy(*pTables);
*pTables = NULL;
}
return terrno;
}
2022-11-04 07:21:38 +00:00
static int32_t buildInsertTableReq(SName* pName, SArray** pTables) {
*pTables = taosArrayInit(1, sizeof(SName));
if (NULL == *pTables) {
2024-09-20 09:48:04 +00:00
return terrno;
2022-11-04 07:21:38 +00:00
}
2024-07-22 01:40:19 +00:00
if (NULL == taosArrayPush(*pTables, pName)) {
taosArrayDestroy(*pTables);
*pTables = NULL;
2024-09-20 09:48:04 +00:00
return terrno;
2024-07-22 01:40:19 +00:00
}
2022-11-04 07:21:38 +00:00
return TSDB_CODE_SUCCESS;
}
static int32_t buildInsertUsingDbReq(SName* pSName, SName* pCName, SArray** pDbs) {
if (NULL == *pDbs) {
*pDbs = taosArrayInit(1, sizeof(STablesReq));
if (NULL == *pDbs) {
return terrno;
}
}
STablesReq req = {0};
req.autoCreate = 1;
(void)tNameGetFullDbName(pSName, req.dbFName);
(void)tNameGetFullDbName(pCName, req.dbFName);
int32_t code = buildUsingInsertTableReq(pSName, pCName, &req.pTables);
if (TSDB_CODE_SUCCESS == code && NULL == taosArrayPush(*pDbs, &req)) {
code = TSDB_CODE_OUT_OF_MEMORY;
}
return code;
}
2022-11-04 07:21:38 +00:00
static int32_t buildInsertDbReq(SName* pName, SArray** pDbs) {
if (NULL == *pDbs) {
*pDbs = taosArrayInit(1, sizeof(STablesReq));
if (NULL == *pDbs) {
2024-09-20 09:48:04 +00:00
return terrno;
}
2022-11-04 07:21:38 +00:00
}
2022-11-04 07:21:38 +00:00
STablesReq req = {0};
2024-07-22 01:40:19 +00:00
(void)tNameGetFullDbName(pName, req.dbFName);
int32_t code = buildInsertTableReq(pName, &req.pTables);
if (TSDB_CODE_SUCCESS == code && NULL == taosArrayPush(*pDbs, &req)) {
code = TSDB_CODE_OUT_OF_MEMORY;
}
2024-07-22 01:40:19 +00:00
return code;
2022-11-04 07:21:38 +00:00
}
2022-11-04 07:21:38 +00:00
static int32_t buildInsertUserAuthReq(const char* pUser, SName* pName, SArray** pUserAuth) {
*pUserAuth = taosArrayInit(1, sizeof(SUserAuthInfo));
if (NULL == *pUserAuth) {
2024-09-20 09:48:04 +00:00
return terrno;
2022-11-04 07:21:38 +00:00
}
2022-08-10 09:47:28 +00:00
2022-11-04 07:21:38 +00:00
SUserAuthInfo userAuth = {.type = AUTH_TYPE_WRITE};
snprintf(userAuth.user, sizeof(userAuth.user), "%s", pUser);
2023-04-11 07:08:42 +00:00
memcpy(&userAuth.tbName, pName, sizeof(SName));
2024-07-22 01:40:19 +00:00
if (NULL == taosArrayPush(*pUserAuth, &userAuth)) {
taosArrayDestroy(*pUserAuth);
*pUserAuth = NULL;
2024-09-20 09:48:04 +00:00
return terrno;
2024-07-22 01:40:19 +00:00
}
2022-11-04 07:21:38 +00:00
return TSDB_CODE_SUCCESS;
}
2023-04-25 09:39:28 +00:00
static int32_t buildInsertTableTagReq(SName* pName, SArray** pTables) { return buildInsertTableReq(pName, pTables); }
2022-12-20 08:53:08 +00:00
static int32_t buildInsertCatalogReq(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt, SCatalogReq* pCatalogReq) {
2023-04-25 09:39:28 +00:00
int32_t code = buildInsertUserAuthReq(
pCxt->pComCxt->pUser, (0 == pStmt->usingTableName.type ? &pStmt->targetTableName : &pStmt->usingTableName),
&pCatalogReq->pUser);
if (TSDB_CODE_SUCCESS == code && pCxt->needTableTagVal) {
code = buildInsertTableTagReq(&pStmt->targetTableName, &pCatalogReq->pTableTag);
}
2022-11-04 07:21:38 +00:00
if (TSDB_CODE_SUCCESS == code) {
if (0 == pStmt->usingTableName.type) {
code = buildInsertDbReq(&pStmt->targetTableName, &pCatalogReq->pTableMeta);
} else {
code = buildInsertUsingDbReq(&pStmt->usingTableName, &pStmt->targetTableName, &pCatalogReq->pTableMeta);
}
2022-11-04 07:21:38 +00:00
}
if (TSDB_CODE_SUCCESS == code) {
code = buildInsertDbReq(&pStmt->targetTableName, &pCatalogReq->pTableHash);
}
return code;
}
2022-11-04 07:21:38 +00:00
static int32_t setNextStageInfo(SInsertParseContext* pCxt, SQuery* pQuery, SCatalogReq* pCatalogReq) {
2022-12-20 08:53:08 +00:00
SVnodeModifyOpStmt* pStmt = (SVnodeModifyOpStmt*)pQuery->pRoot;
2022-11-04 07:21:38 +00:00
if (pCxt->missCache) {
parserDebug("QID:0x%" PRIx64 ", %d rows of %d tables will be inserted before obtain the cache", pCxt->pComCxt->requestId,
pStmt->totalRowsNum, pStmt->totalTbNum);
2022-11-06 06:26:19 +00:00
2022-11-04 07:21:38 +00:00
pQuery->execStage = QUERY_EXEC_STAGE_PARSE;
return buildInsertCatalogReq(pCxt, pStmt, pCatalogReq);
}
2025-02-27 06:27:46 +00:00
parserDebug("QID:0x%" PRIx64 ", %d rows of %d tables will be inserted", pCxt->pComCxt->requestId, pStmt->totalRowsNum,
pStmt->totalTbNum);
2022-11-06 06:26:19 +00:00
2022-11-04 07:21:38 +00:00
pQuery->execStage = QUERY_EXEC_STAGE_SCHEDULE;
return TSDB_CODE_SUCCESS;
}
2022-11-04 07:21:38 +00:00
int32_t parseInsertSql(SParseContext* pCxt, SQuery** pQuery, SCatalogReq* pCatalogReq, const SMetaData* pMetaData) {
2022-12-07 11:12:55 +00:00
SInsertParseContext context = {.pComCxt = pCxt,
.msg = {.buf = pCxt->pMsg, .len = pCxt->msgLen},
.missCache = false,
.usingDuplicateTable = false,
2023-11-28 17:53:13 +00:00
.needRequest = true,
2024-07-02 02:18:56 +00:00
.forceUpdate = (NULL != pCatalogReq ? pCatalogReq->forceUpdate : false),
2024-07-04 08:45:10 +00:00
.isStmtBind = pCxt->isStmtBind};
2022-11-04 07:21:38 +00:00
2025-01-02 12:07:58 +00:00
int32_t code = initInsertQuery(&context, pCatalogReq, pMetaData, pQuery);
if (TSDB_CODE_SUCCESS == code) {
2024-12-14 04:18:48 +00:00
code = parseInsertSqlImpl(&context, (SVnodeModifyOpStmt*)((*pQuery)->pRoot));
}
if (TSDB_CODE_SUCCESS == code) {
2022-11-04 07:21:38 +00:00
code = setNextStageInfo(&context, *pQuery, pCatalogReq);
}
if ((TSDB_CODE_SUCCESS == code || NEED_CLIENT_HANDLE_ERROR(code)) &&
QUERY_EXEC_STAGE_SCHEDULE == (*pQuery)->execStage) {
code = setRefreshMeta(*pQuery);
}
insDestroyBoundColInfo(&context.tags);
2023-11-28 17:53:13 +00:00
// if no data to insert, set emptyMode to avoid request server
if (!context.needRequest) {
(*pQuery)->execMode = QUERY_EXEC_MODE_EMPTY_RESULT;
}
return code;
}
// CSV Parser Implementation
static int32_t csvParserInit(SCsvParser* parser, TdFilePtr pFile) {
if (!parser || !pFile) {
return TSDB_CODE_INVALID_PARA;
}
memset(parser, 0, sizeof(SCsvParser));
// Set default CSV format
parser->delimiter = CSV_DEFAULT_DELIMITER;
parser->quote = CSV_QUOTE_SINGLE; // Default to single quote for TDengine compatibility
parser->escape = CSV_ESCAPE_CHAR;
parser->allowNewlineInField = true;
// Initialize buffer
parser->bufferSize = 64 * 1024; // 64KB buffer
parser->buffer = taosMemoryMalloc(parser->bufferSize);
if (!parser->buffer) {
return terrno;
}
// Initialize line buffer for reuse
parser->lineBufferCapacity = 64 * 1024; // Initial 64KB line buffer
parser->lineBuffer = taosMemoryMalloc(parser->lineBufferCapacity);
if (!parser->lineBuffer) {
return terrno;
}
parser->bufferPos = 0;
parser->bufferLen = 0;
parser->eof = false;
parser->pFile = pFile;
// Fill initial buffer to detect quote type
int32_t code = csvParserFillBuffer(parser);
if (code != TSDB_CODE_SUCCESS) {
return code;
}
// Auto-detect quote character by finding the first quote in the file
// Skip the header line and look for the first quote character in data
bool foundFirstQuote = false;
bool inFirstLine = true;
for (size_t i = 0; i < parser->bufferLen && !foundFirstQuote; i++) {
char ch = parser->buffer[i];
// Skip the first line (header)
if (inFirstLine) {
if (ch == '\n') {
inFirstLine = false;
}
continue;
}
// Look for the first quote character in data lines
if (ch == CSV_QUOTE_SINGLE) {
parser->quote = CSV_QUOTE_SINGLE;
foundFirstQuote = true;
} else if (ch == CSV_QUOTE_DOUBLE) {
parser->quote = CSV_QUOTE_DOUBLE;
foundFirstQuote = true;
}
}
// If no quotes found, keep default (single quote for TDengine compatibility)
// Reset buffer position for actual parsing
parser->bufferPos = 0;
return TSDB_CODE_SUCCESS;
}
static void csvParserDestroy(SCsvParser* parser) {
if (parser) {
taosMemoryFree(parser->buffer);
taosMemoryFree(parser->lineBuffer);
memset(parser, 0, sizeof(SCsvParser));
}
}
static int32_t csvParserFillBuffer(SCsvParser* parser) {
if (!parser || parser->eof) {
return TSDB_CODE_SUCCESS;
}
// Move remaining data to beginning of buffer
// Since this function is only called when bufferPos >= bufferLen,
// we can simplify by always resetting the buffer
parser->bufferLen = 0;
parser->bufferPos = 0;
// Read more data
size_t spaceLeft = parser->bufferSize - parser->bufferLen;
if (spaceLeft > 0) {
int64_t bytesRead = taosReadFile(parser->pFile, parser->buffer + parser->bufferLen, spaceLeft);
if (bytesRead < 0) {
return TAOS_SYSTEM_ERROR(errno);
}
if (bytesRead == 0) {
parser->eof = true;
} else {
parser->bufferLen += bytesRead;
}
}
return TSDB_CODE_SUCCESS;
}
// Destroy saved CSV parser in SVnodeModifyOpStmt
static void destroySavedCsvParser(SVnodeModifyOpStmt* pStmt) {
if (pStmt && pStmt->pCsvParser) {
csvParserDestroy(pStmt->pCsvParser);
taosMemoryFree(pStmt->pCsvParser);
pStmt->pCsvParser = NULL;
}
}
static int32_t csvParserExpandLineBuffer(SCsvParser* parser, size_t requiredLen) {
if (!parser || requiredLen <= parser->lineBufferCapacity) {
return TSDB_CODE_SUCCESS;
}
size_t newCapacity = parser->lineBufferCapacity;
while (newCapacity < requiredLen) {
newCapacity *= 2;
}
char* newLineBuffer = taosMemoryRealloc(parser->lineBuffer, newCapacity);
if (!newLineBuffer) {
return TSDB_CODE_OUT_OF_MEMORY;
}
parser->lineBuffer = newLineBuffer;
parser->lineBufferCapacity = newCapacity;
return TSDB_CODE_SUCCESS;
}