From ede70d04658bce4fcc2249ca0c5fa1c42ee81df7 Mon Sep 17 00:00:00 2001 From: Pengrongkun Date: Thu, 5 Dec 2024 13:59:24 +0800 Subject: [PATCH] stmt2 support insert into stb(?)values(tbname) --- include/libs/qcom/query.h | 1 + source/libs/parser/src/parInsertSql.c | 61 +++++++++++++++++++------- source/libs/parser/src/parInsertStmt.c | 13 ++++-- source/libs/parser/src/parInsertUtil.c | 2 + 4 files changed, 56 insertions(+), 21 deletions(-) diff --git a/include/libs/qcom/query.h b/include/libs/qcom/query.h index d2f714f400..d62edb158d 100644 --- a/include/libs/qcom/query.h +++ b/include/libs/qcom/query.h @@ -194,6 +194,7 @@ typedef struct SBoundColInfo { int32_t numOfCols; int32_t numOfBound; bool hasBoundCols; + bool mixTagsCols; } SBoundColInfo; typedef struct STableColsData { diff --git a/source/libs/parser/src/parInsertSql.c b/source/libs/parser/src/parInsertSql.c index ad439a11ff..10df426709 100644 --- a/source/libs/parser/src/parInsertSql.c +++ b/source/libs/parser/src/parInsertSql.c @@ -247,8 +247,8 @@ static int32_t parseBoundColumns(SInsertParseContext* pCxt, const char** pSql, E return code; } -static int32_t parseTimestampOrInterval(const char** end, SToken* pToken, int16_t timePrec, int64_t* ts, int64_t* interval, - SMsgBuf* pMsgBuf, bool* isTs) { +static int32_t parseTimestampOrInterval(const char** end, SToken* pToken, int16_t timePrec, int64_t* ts, + int64_t* interval, SMsgBuf* pMsgBuf, bool* isTs) { if (pToken->type == TK_NOW) { *isTs = true; *ts = taosGetTimestamp(timePrec); @@ -1831,13 +1831,26 @@ static int32_t doGetStbRowValues(SInsertParseContext* pCxt, SVnodeModifyOpStmt* if (TK_NK_QUESTION == pToken->type) { pCxt->isStmtBind = true; + pStmt->usingTableProcessing = true; if (pCols->pColIndex[i] == tbnameIdx) { - pCxt->preCtbname = false; - *bFoundTbName = true; - } - if (NULL == pCxt->pComCxt->pStmtCb) { - code = buildSyntaxErrMsg(&pCxt->msg, "? only used in stmt", pToken->z); - break; + 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; + + *bFoundTbName = true; + } + } else if (pCols->pColIndex[i] < numOfCols) { + // bind column + } else { + pCxt->tags.mixTagsCols = true; + pCxt->tags.pColIndex = pStbRowsCxt->boundColsInfo.pColIndex; + pCxt->tags.numOfBound++; + pCxt->tags.numOfCols++; } } else { if (pCols->pColIndex[i] < numOfCols) { @@ -1901,13 +1914,17 @@ static int32_t getStbRowValues(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pS code = doGetStbRowValues(pCxt, pStmt, ppSql, pStbRowsCxt, pToken, pCols, pSchemas, tagTokens, tagSchemas, &numOfTagTokens, &bFoundTbName); - if (code == TSDB_CODE_SUCCESS && !bFoundTbName) { - code = buildSyntaxErrMsg(&pCxt->msg, "tbname value expected", pOrigSql); + if (code != TSDB_CODE_SUCCESS) { + return code; } - if (code == TSDB_CODE_SUCCESS && pStbRowsCxt->ctbName.tname[0] == '\0') { - *pGotRow = true; - return TSDB_CODE_TSC_STMT_TBNAME_ERROR; + if (!bFoundTbName) { + if (!pCxt->isStmtBind) { + code = buildSyntaxErrMsg(&pCxt->msg, "tbname value expected", pOrigSql); + } else { + *pGotRow = true; + return TSDB_CODE_TSC_STMT_TBNAME_ERROR; + } } bool ctbFirst = true; @@ -2050,14 +2067,24 @@ static int32_t parseOneStbRow(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pSt code = processCtbAutoCreationAndCtbMeta(pCxt, pStmt, pStbRowsCxt); } if (code == TSDB_CODE_SUCCESS) { - code = - insGetTableDataCxt(pStmt->pTableBlockHashObj, &pStbRowsCxt->pCtbMeta->uid, sizeof(pStbRowsCxt->pCtbMeta->uid), - pStbRowsCxt->pCtbMeta, &pStbRowsCxt->pCreateCtbReq, ppTableDataCxt, false, true); + 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); + } } if (code == TSDB_CODE_SUCCESS) { code = initTableColSubmitData(*ppTableDataCxt); } - if (code == TSDB_CODE_SUCCESS) { + if (code == TSDB_CODE_SUCCESS && !pCxt->isStmtBind) { SRow** pRow = taosArrayReserve((*ppTableDataCxt)->pData->aRowP, 1); code = tRowBuild(pStbRowsCxt->aColVals, (*ppTableDataCxt)->pSchema, pRow); if (TSDB_CODE_SUCCESS == code) { diff --git a/source/libs/parser/src/parInsertStmt.c b/source/libs/parser/src/parInsertStmt.c index db732f9b6e..d9dc878b3e 100644 --- a/source/libs/parser/src/parInsertStmt.c +++ b/source/libs/parser/src/parInsertStmt.c @@ -503,7 +503,12 @@ int32_t qBindStmtTagsValue2(void* pBlock, void* boundTags, int64_t suid, const c goto end; } - SSchema* pSchema = getTableTagSchema(pDataBlock->pMeta); + SSchema* pSchema; + if (!tags->mixTagsCols) { + pSchema = getTableTagSchema(pDataBlock->pMeta); + } else { + pSchema = getTableColumnSchema(pDataBlock->pMeta); + } bool isJson = false; STag* pTag = NULL; @@ -958,16 +963,16 @@ int32_t buildStbBoundFields(SBoundColInfo boundColsInfo, SSchema* pSchema, int32 } if (tags->numOfBound > 0) { - SSchema* pSchema = getTableTagSchema(pMeta); + SSchema* tagSchema = getTableTagSchema(pMeta); - if (TSDB_DATA_TYPE_TIMESTAMP == pSchema->type) { + if (TSDB_DATA_TYPE_TIMESTAMP == tagSchema->type) { (*fields)[0].precision = pMeta->tableInfo.precision; } for (int32_t i = 0; i < tags->numOfBound; ++i) { (*fields)[idx].field_type = TAOS_FIELD_TAG; - SSchema* schema = &pSchema[tags->pColIndex[i]]; + SSchema* schema = &tagSchema[tags->pColIndex[i]]; tstrncpy((*fields)[idx].name, schema->name, sizeof((*fields)[i].name)); (*fields)[idx].type = schema->type; (*fields)[idx].bytes = schema->bytes; diff --git a/source/libs/parser/src/parInsertUtil.c b/source/libs/parser/src/parInsertUtil.c index bcb560ab5e..875419d99d 100644 --- a/source/libs/parser/src/parInsertUtil.c +++ b/source/libs/parser/src/parInsertUtil.c @@ -191,6 +191,7 @@ int32_t insInitBoundColsInfo(int32_t numOfBound, SBoundColInfo* pInfo) { pInfo->numOfCols = numOfBound; pInfo->numOfBound = numOfBound; pInfo->hasBoundCols = false; + pInfo->mixTagsCols = false; pInfo->pColIndex = taosMemoryCalloc(numOfBound, sizeof(int16_t)); if (NULL == pInfo->pColIndex) { return terrno; @@ -204,6 +205,7 @@ int32_t insInitBoundColsInfo(int32_t numOfBound, SBoundColInfo* pInfo) { void insResetBoundColsInfo(SBoundColInfo* pInfo) { pInfo->numOfBound = pInfo->numOfCols; pInfo->hasBoundCols = false; + pInfo->mixTagsCols = false; for (int32_t i = 0; i < pInfo->numOfCols; ++i) { pInfo->pColIndex[i] = i; }