|
|
|
@ -15,8 +15,8 @@
|
|
|
|
|
|
|
|
|
|
#include "parInsertData.h"
|
|
|
|
|
#include "parInt.h"
|
|
|
|
|
#include "parUtil.h"
|
|
|
|
|
#include "parToken.h"
|
|
|
|
|
#include "parUtil.h"
|
|
|
|
|
#include "tglobal.h"
|
|
|
|
|
#include "ttime.h"
|
|
|
|
|
#include "ttypes.h"
|
|
|
|
@ -228,25 +228,23 @@ static int32_t getTableMetaImpl(SInsertParseContext* pCxt, SToken* pTname, bool
|
|
|
|
|
SName name = {0};
|
|
|
|
|
createSName(&name, pTname, pBasicCtx, &pCxt->msg);
|
|
|
|
|
if (isStb) {
|
|
|
|
|
CHECK_CODE(catalogGetSTableMeta(pBasicCtx->pCatalog, pBasicCtx->pTransporter, &pBasicCtx->mgmtEpSet, &name, &pCxt->pTableMeta));
|
|
|
|
|
CHECK_CODE(catalogGetSTableMeta(pBasicCtx->pCatalog, pBasicCtx->pTransporter, &pBasicCtx->mgmtEpSet, &name,
|
|
|
|
|
&pCxt->pTableMeta));
|
|
|
|
|
} else {
|
|
|
|
|
CHECK_CODE(catalogGetTableMeta(pBasicCtx->pCatalog, pBasicCtx->pTransporter, &pBasicCtx->mgmtEpSet, &name, &pCxt->pTableMeta));
|
|
|
|
|
CHECK_CODE(catalogGetTableMeta(pBasicCtx->pCatalog, pBasicCtx->pTransporter, &pBasicCtx->mgmtEpSet, &name,
|
|
|
|
|
&pCxt->pTableMeta));
|
|
|
|
|
}
|
|
|
|
|
SVgroupInfo vg;
|
|
|
|
|
CHECK_CODE(catalogGetTableHashVgroup(pBasicCtx->pCatalog, pBasicCtx->pTransporter, &pBasicCtx->mgmtEpSet, &name, &vg));
|
|
|
|
|
CHECK_CODE(
|
|
|
|
|
catalogGetTableHashVgroup(pBasicCtx->pCatalog, pBasicCtx->pTransporter, &pBasicCtx->mgmtEpSet, &name, &vg));
|
|
|
|
|
CHECK_CODE(taosHashPut(pCxt->pVgroupsHashObj, (const char*)&vg.vgId, sizeof(vg.vgId), (char*)&vg, sizeof(vg)));
|
|
|
|
|
|
|
|
|
|
return TSDB_CODE_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int32_t getTableMeta(SInsertParseContext* pCxt, SToken* pTname) {
|
|
|
|
|
return getTableMetaImpl(pCxt, pTname, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int32_t getSTableMeta(SInsertParseContext* pCxt, SToken* pTname) {
|
|
|
|
|
return getTableMetaImpl(pCxt, pTname, true);
|
|
|
|
|
}
|
|
|
|
|
static int32_t getTableMeta(SInsertParseContext* pCxt, SToken* pTname) { return getTableMetaImpl(pCxt, pTname, false); }
|
|
|
|
|
|
|
|
|
|
static int32_t getSTableMeta(SInsertParseContext* pCxt, SToken* pTname) { return getTableMetaImpl(pCxt, pTname, true); }
|
|
|
|
|
|
|
|
|
|
static int32_t findCol(SToken* pColname, int32_t start, int32_t end, SSchema* pSchema) {
|
|
|
|
|
while (start < end) {
|
|
|
|
@ -391,8 +389,10 @@ static int parseTime(char **end, SToken *pToken, int16_t timePrec, int64_t *time
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static FORCE_INLINE int32_t checkAndTrimValue(SToken* pToken, uint32_t type, char* tmpTokenBuf, SMsgBuf* pMsgBuf) {
|
|
|
|
|
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 && pToken->type != TK_NULL && pToken->type != TK_NK_HEX && pToken->type != TK_NK_OCT && pToken->type != TK_NK_BIN) ||
|
|
|
|
|
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 &&
|
|
|
|
|
pToken->type != TK_NULL && pToken->type != TK_NK_HEX && pToken->type != TK_NK_OCT &&
|
|
|
|
|
pToken->type != TK_NK_BIN) ||
|
|
|
|
|
(pToken->n == 0) || (pToken->type == TK_NK_RP)) {
|
|
|
|
|
return buildSyntaxErrMsg(pMsgBuf, "invalid data or symbol", pToken->z);
|
|
|
|
|
}
|
|
|
|
@ -448,7 +448,8 @@ static FORCE_INLINE int32_t toDouble(SToken *pToken, double *value, char **endPt
|
|
|
|
|
return pToken->type;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int32_t parseValueToken(char** end, SToken* pToken, SSchema* pSchema, int16_t timePrec, char* tmpTokenBuf, _row_append_fn_t func, void* param, SMsgBuf* pMsgBuf) {
|
|
|
|
|
static int32_t parseValueToken(char** end, SToken* pToken, SSchema* pSchema, int16_t timePrec, char* tmpTokenBuf,
|
|
|
|
|
_row_append_fn_t func, void* param, SMsgBuf* pMsgBuf) {
|
|
|
|
|
int64_t iv;
|
|
|
|
|
char* endptr = NULL;
|
|
|
|
|
bool isSigned = false;
|
|
|
|
@ -571,7 +572,8 @@ static int32_t parseValueToken(char** end, SToken* pToken, SSchema* pSchema, int
|
|
|
|
|
if (TK_NK_ILLEGAL == toDouble(pToken, &dv, &endptr)) {
|
|
|
|
|
return buildSyntaxErrMsg(pMsgBuf, "illegal float data", pToken->z);
|
|
|
|
|
}
|
|
|
|
|
if (((dv == HUGE_VAL || dv == -HUGE_VAL) && errno == ERANGE) || dv > FLT_MAX || dv < -FLT_MAX || isinf(dv) || isnan(dv)) {
|
|
|
|
|
if (((dv == HUGE_VAL || dv == -HUGE_VAL) && errno == ERANGE) || dv > FLT_MAX || dv < -FLT_MAX || isinf(dv) ||
|
|
|
|
|
isnan(dv)) {
|
|
|
|
|
return buildSyntaxErrMsg(pMsgBuf, "illegal float data", pToken->z);
|
|
|
|
|
}
|
|
|
|
|
float tmpVal = (float)dv;
|
|
|
|
@ -749,7 +751,8 @@ static int32_t KvRowAppend(SMsgBuf* pMsgBuf, const void *value, int32_t len, voi
|
|
|
|
|
if (!taosMbsToUcs4(value, len, (TdUcs4*)varDataVal(pa->buf), pa->schema->bytes - VARSTR_HEADER_SIZE, &output)) {
|
|
|
|
|
char buf[512] = {0};
|
|
|
|
|
snprintf(buf, tListLen(buf), "%s", strerror(errno));
|
|
|
|
|
return buildSyntaxErrMsg(pMsgBuf, buf, value);;
|
|
|
|
|
return buildSyntaxErrMsg(pMsgBuf, buf, value);
|
|
|
|
|
;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
varDataSetLen(pa->buf, output);
|
|
|
|
@ -765,7 +768,6 @@ static int32_t buildCreateTbReq(SInsertParseContext* pCxt, const SName* pName, S
|
|
|
|
|
char dbFName[TSDB_DB_FNAME_LEN] = {0};
|
|
|
|
|
tNameGetFullDbName(pName, dbFName);
|
|
|
|
|
pCxt->createTblReq.type = TD_CHILD_TABLE;
|
|
|
|
|
pCxt->createTblReq.dbFName = strdup(dbFName);
|
|
|
|
|
pCxt->createTblReq.name = strdup(pName->tname);
|
|
|
|
|
pCxt->createTblReq.ctbCfg.suid = pCxt->pTableMeta->suid;
|
|
|
|
|
pCxt->createTblReq.ctbCfg.pTag = row;
|
|
|
|
@ -786,7 +788,8 @@ static int32_t parseTagsClause(SInsertParseContext* pCxt, SSchema* pSchema, uint
|
|
|
|
|
NEXT_TOKEN_WITH_PREV(pCxt->pSql, sToken);
|
|
|
|
|
SSchema* pTagSchema = &pSchema[pCxt->tags.boundColumns[i] - 1]; // colId starts with 1
|
|
|
|
|
param.schema = pTagSchema;
|
|
|
|
|
CHECK_CODE(parseValueToken(&pCxt->pSql, &sToken, pTagSchema, precision, tmpTokenBuf, KvRowAppend, ¶m, &pCxt->msg));
|
|
|
|
|
CHECK_CODE(
|
|
|
|
|
parseValueToken(&pCxt->pSql, &sToken, pTagSchema, precision, tmpTokenBuf, KvRowAppend, ¶m, &pCxt->msg));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SKVRow row = tdGetKVRowFromBuilder(&pCxt->tagsBuilder);
|
|
|
|
@ -864,7 +867,8 @@ static int32_t parseUsingClause(SInsertParseContext* pCxt, SToken* pTbnameToken)
|
|
|
|
|
return TSDB_CODE_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int parseOneRow(SInsertParseContext* pCxt, STableDataBlocks* pDataBlocks, int16_t timePrec, int32_t* len, char* tmpTokenBuf) {
|
|
|
|
|
static int parseOneRow(SInsertParseContext* pCxt, STableDataBlocks* pDataBlocks, int16_t timePrec, int32_t* len,
|
|
|
|
|
char* tmpTokenBuf) {
|
|
|
|
|
SParsedDataColInfo* spd = &pDataBlocks->boundColumnInfo;
|
|
|
|
|
SRowBuilder* pBuilder = &pDataBlocks->rowBuilder;
|
|
|
|
|
STSRow* row = (STSRow*)(pDataBlocks->pData + pDataBlocks->size); // skip the SSubmitBlk header
|
|
|
|
@ -968,7 +972,6 @@ static int32_t parseValuesClause(SInsertParseContext* pCxt, STableDataBlocks* da
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void destroyCreateSubTbReq(SVCreateTbReq* pReq) {
|
|
|
|
|
taosMemoryFreeClear(pReq->dbFName);
|
|
|
|
|
taosMemoryFreeClear(pReq->name);
|
|
|
|
|
taosMemoryFreeClear(pReq->ctbCfg.pTag);
|
|
|
|
|
}
|
|
|
|
@ -1023,7 +1026,8 @@ static int32_t parseInsertBody(SInsertParseContext* pCxt) {
|
|
|
|
|
// no data in the sql string anymore.
|
|
|
|
|
if (sToken.n == 0) {
|
|
|
|
|
if (0 == pCxt->totalNum) {
|
|
|
|
|
return buildInvalidOperationMsg(&pCxt->msg, "no data in sql");;
|
|
|
|
|
return buildInvalidOperationMsg(&pCxt->msg, "no data in sql");
|
|
|
|
|
;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
@ -1041,7 +1045,8 @@ static int32_t parseInsertBody(SInsertParseContext* pCxt) {
|
|
|
|
|
|
|
|
|
|
STableDataBlocks* dataBuf = NULL;
|
|
|
|
|
CHECK_CODE(getDataBlockFromList(pCxt->pTableBlockHashObj, pCxt->pTableMeta->uid, TSDB_DEFAULT_PAYLOAD_SIZE,
|
|
|
|
|
sizeof(SSubmitBlk), getTableInfo(pCxt->pTableMeta).rowSize, pCxt->pTableMeta, &dataBuf, NULL, &pCxt->createTblReq));
|
|
|
|
|
sizeof(SSubmitBlk), getTableInfo(pCxt->pTableMeta).rowSize, pCxt->pTableMeta,
|
|
|
|
|
&dataBuf, NULL, &pCxt->createTblReq));
|
|
|
|
|
|
|
|
|
|
if (TK_NK_LP == sToken.type) {
|
|
|
|
|
// pSql -> field1_name, ...)
|
|
|
|
@ -1071,7 +1076,8 @@ static int32_t parseInsertBody(SInsertParseContext* pCxt) {
|
|
|
|
|
return buildSyntaxErrMsg(&pCxt->msg, "keyword VALUES or FILE is expected", sToken.z);
|
|
|
|
|
}
|
|
|
|
|
// merge according to vgId
|
|
|
|
|
if (!TSDB_QUERY_HAS_TYPE(pCxt->pOutput->insertType, TSDB_QUERY_TYPE_STMT_INSERT) && taosHashGetSize(pCxt->pTableBlockHashObj) > 0) {
|
|
|
|
|
if (!TSDB_QUERY_HAS_TYPE(pCxt->pOutput->insertType, TSDB_QUERY_TYPE_STMT_INSERT) &&
|
|
|
|
|
taosHashGetSize(pCxt->pTableBlockHashObj) > 0) {
|
|
|
|
|
CHECK_CODE(mergeTableDataBlocks(pCxt->pTableBlockHashObj, pCxt->pOutput->payloadType, &pCxt->pVgDataBlocks));
|
|
|
|
|
}
|
|
|
|
|
return buildOutput(pCxt);
|
|
|
|
@ -1093,11 +1099,10 @@ int32_t parseInsertSql(SParseContext* pContext, SQuery** pQuery) {
|
|
|
|
|
.pTableBlockHashObj = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false),
|
|
|
|
|
.pSubTableHashObj = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), true, false),
|
|
|
|
|
.totalNum = 0,
|
|
|
|
|
.pOutput = (SVnodeModifOpStmt*)nodesMakeNode(QUERY_NODE_VNODE_MODIF_STMT)
|
|
|
|
|
};
|
|
|
|
|
.pOutput = (SVnodeModifOpStmt*)nodesMakeNode(QUERY_NODE_VNODE_MODIF_STMT)};
|
|
|
|
|
|
|
|
|
|
if (NULL == context.pVgroupsHashObj || NULL == context.pTableBlockHashObj ||
|
|
|
|
|
NULL == context.pSubTableHashObj || NULL == context.pOutput) {
|
|
|
|
|
if (NULL == context.pVgroupsHashObj || NULL == context.pTableBlockHashObj || NULL == context.pSubTableHashObj ||
|
|
|
|
|
NULL == context.pOutput) {
|
|
|
|
|
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|