From ad9ed168eee48453558cab72201839ce5c29d0cb Mon Sep 17 00:00:00 2001 From: Pengrongkun Date: Fri, 6 Dec 2024 11:27:36 +0800 Subject: [PATCH] add test and fix tagbound schema problem --- source/client/src/clientStmt2.c | 10 ++++--- source/libs/parser/src/parInsertSql.c | 36 +++++++++++++++++-------- source/libs/parser/src/parInsertStmt.c | 11 ++------ tests/script/api/stmt2-example.c | 37 +++++++++++++++++++------- 4 files changed, 61 insertions(+), 33 deletions(-) diff --git a/source/client/src/clientStmt2.c b/source/client/src/clientStmt2.c index 76eec9d95c..be883ba9f0 100644 --- a/source/client/src/clientStmt2.c +++ b/source/client/src/clientStmt2.c @@ -1094,10 +1094,14 @@ static int stmtFetchStbColFields2(STscStmt2* pStmt, int32_t* fieldNum, TAOS_FIEL } STMT_ERR_RET(qBuildStmtStbColFields(*pDataBlock, pStmt->bInfo.boundTags, pStmt->bInfo.preCtbname, fieldNum, fields)); - if (taosHashRemove(pStmt->exec.pBlockHash, pStmt->bInfo.tbFName, strlen(pStmt->bInfo.tbFName)) != 0) { - tscError("get fileds %s remove exec blockHash fail", pStmt->bInfo.tbFName); - STMT_ERR_RET(TSDB_CODE_APP_ERROR); + if (pStmt->bInfo.tbType == TSDB_SUPER_TABLE) { + pStmt->bInfo.needParse = true; + if (taosHashRemove(pStmt->exec.pBlockHash, pStmt->bInfo.tbFName, strlen(pStmt->bInfo.tbFName)) != 0) { + tscError("get fileds %s remove exec blockHash fail", pStmt->bInfo.tbFName); + STMT_ERR_RET(TSDB_CODE_APP_ERROR); + } } + return TSDB_CODE_SUCCESS; } /* diff --git a/source/libs/parser/src/parInsertSql.c b/source/libs/parser/src/parInsertSql.c index 7336ada30c..5d34809c12 100644 --- a/source/libs/parser/src/parInsertSql.c +++ b/source/libs/parser/src/parInsertSql.c @@ -1387,7 +1387,16 @@ static int32_t getTableDataCxt(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pS } char tbFName[TSDB_TABLE_FNAME_LEN]; - int32_t code = tNameExtractFullName(&pStmt->targetTableName, tbFName); + int32_t code = 0; + if (pCxt->preCtbname) { + 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); + if (TSDB_CODE_SUCCESS != code) { return code; } @@ -1812,8 +1821,10 @@ static int32_t doGetStbRowValues(SInsertParseContext* pCxt, SVnodeModifyOpStmt* SArray* pTagVals = pStbRowsCxt->aTagVals; bool canParseTagsAfter = !pStbRowsCxt->pTagCond && !pStbRowsCxt->hasTimestampTag; int32_t numOfCols = getNumOfColumns(pStbRowsCxt->pStbMeta); + int32_t numOfTags = getNumOfTags(pStbRowsCxt->pStbMeta); int32_t tbnameIdx = getTbnameSchemaIndex(pStbRowsCxt->pStbMeta); uint8_t precision = getTableInfo(pStbRowsCxt->pStbMeta).precision; + int idx = 0; for (int i = 0; i < pCols->numOfBound && (code) == TSDB_CODE_SUCCESS; ++i) { const char* pTmpSql = *ppSql; bool ignoreComma = false; @@ -1846,10 +1857,22 @@ static int32_t doGetStbRowValues(SInsertParseContext* pCxt, SVnodeModifyOpStmt* } } else if (pCols->pColIndex[i] < numOfCols) { // bind column - } else { + } 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; + } + } + if (!(idx < numOfTags)) { + return buildInvalidOperationMsg(&pCxt->msg, "not expected numOfTags"); + } + pCxt->tags.pColIndex[idx++] = pCols->pColIndex[i] - numOfCols; pCxt->tags.mixTagsCols = true; pCxt->tags.numOfBound++; pCxt->tags.numOfCols++; + } else { + return buildInvalidOperationMsg(&pCxt->msg, "not expected numOfBound"); } } else { if (pCols->pColIndex[i] < numOfCols) { @@ -1895,15 +1918,6 @@ static int32_t doGetStbRowValues(SInsertParseContext* pCxt, SVnodeModifyOpStmt* } } - if (pCxt->isStmtBind && pCxt->tags.mixTagsCols) { - taosMemoryFreeClear(pCxt->tags.pColIndex); - pCxt->tags.pColIndex = taosMemoryCalloc(pStbRowsCxt->boundColsInfo.numOfBound, sizeof(int16_t)); - if (NULL == pCxt->tags.pColIndex) { - return terrno; - } - (void)memcpy(pCxt->tags.pColIndex, pStbRowsCxt->boundColsInfo.pColIndex, - sizeof(int16_t) * pStbRowsCxt->boundColsInfo.numOfBound); - } return code; } diff --git a/source/libs/parser/src/parInsertStmt.c b/source/libs/parser/src/parInsertStmt.c index dd52277df8..8a161b2118 100644 --- a/source/libs/parser/src/parInsertStmt.c +++ b/source/libs/parser/src/parInsertStmt.c @@ -503,14 +503,7 @@ int32_t qBindStmtTagsValue2(void* pBlock, void* boundTags, int64_t suid, const c goto end; } - SSchema* pSchema; - int start = 0; - if (!tags->mixTagsCols) { - pSchema = getTableTagSchema(pDataBlock->pMeta); - } else { - pSchema = getTableColumnSchema(pDataBlock->pMeta); - start = pDataBlock->pMeta->tableInfo.numOfColumns; - } + SSchema* pSchema = getTableTagSchema(pDataBlock->pMeta); bool isJson = false; STag* pTag = NULL; @@ -520,7 +513,7 @@ int32_t qBindStmtTagsValue2(void* pBlock, void* boundTags, int64_t suid, const c continue; } - SSchema* pTagSchema = &pSchema[tags->pColIndex[start + c]]; + SSchema* pTagSchema = &pSchema[tags->pColIndex[c]]; int32_t colLen = pTagSchema->bytes; if (IS_VAR_DATA_TYPE(pTagSchema->type)) { if (!bind[c].length) { diff --git a/tests/script/api/stmt2-example.c b/tests/script/api/stmt2-example.c index 803e54c156..692ff90a06 100644 --- a/tests/script/api/stmt2-example.c +++ b/tests/script/api/stmt2-example.c @@ -33,30 +33,47 @@ void do_stmt(TAOS* taos) { char* tbs[2] = {"tb", "tb2"}; int t1_val[2] = {0, 1}; - int t2_len[2] = {3, 3}; - TAOS_STMT2_BIND tags[2][2] = {{{0, &t1_val[0], NULL, NULL, 0}, {0, "a1", &t2_len[0], NULL, 0}}, - {{0, &t1_val[1], NULL, NULL, 0}, {0, "a2", &t2_len[1], NULL, 0}}}; + int t2_len[2] = {10, 10}; + int t3_len[2] = {sizeof(int), sizeof(int)}; + TAOS_STMT2_BIND tags[2][2] = {{{0, &t1_val[0], &t3_len[0], NULL, 0}, {0, "after1", &t2_len[0], NULL, 0}}, + {{0, &t1_val[1], &t3_len[1], NULL, 0}, {0, "after2", &t2_len[1], NULL, 0}}}; TAOS_STMT2_BIND params[2][2] = { - {{TSDB_DATA_TYPE_TIMESTAMP, v.ts, NULL, is_null, 2}, {TSDB_DATA_TYPE_BINARY, v.b, b_len, is_null2, 2}}, - {{TSDB_DATA_TYPE_TIMESTAMP, v.ts, NULL, is_null, 2}, {TSDB_DATA_TYPE_BINARY, v.b, b_len, is_null2, 2}}}; + {{TSDB_DATA_TYPE_TIMESTAMP, v.ts, t64_len, is_null, 2}, {TSDB_DATA_TYPE_BINARY, v.b, b_len, NULL, 2}}, + {{TSDB_DATA_TYPE_TIMESTAMP, v.ts, t64_len, is_null, 2}, {TSDB_DATA_TYPE_BINARY, v.b, b_len, NULL, 2}}}; TAOS_STMT2_BIND* tagv[2] = {&tags[0][0], &tags[1][0]}; TAOS_STMT2_BIND* paramv[2] = {¶ms[0][0], ¶ms[1][0]}; TAOS_STMT2_BINDV bindv = {2, &tbs[0], &tagv[0], ¶mv[0]}; TAOS_STMT2* stmt = taos_stmt2_init(taos, &option); - const char* sql = "insert into db.? using db.stb tags(?, ?) values(?,?)"; - int code = taos_stmt2_prepare(stmt, sql, 0); + + // Equivalent to : + // const char* sql = "insert into db.? using db.stb tags(?, ?) values(?,?)"; + const char* sql = "insert into db.stb(tbname,ts,b,t1,t2) values(?,?,?,?,?)"; + + int code = taos_stmt2_prepare(stmt, sql, 0); if (code != 0) { printf("failed to execute taos_stmt2_prepare. error:%s\n", taos_stmt2_error(stmt)); taos_stmt2_close(stmt); return; } + int fieldNum = 0; + TAOS_FIELD_STB* pFields = NULL; + code = taos_stmt2_get_stb_fields(stmt, &fieldNum, &pFields); + if (code != 0) { + printf("failed get col,ErrCode: 0x%x, ErrMessage: %s.\n", code, taos_stmt2_error(stmt)); + } else { + printf("col nums:%d\n", fieldNum); + for (int i = 0; i < fieldNum; i++) { + printf("field[%d]: %s, data_type:%d, field_type:%d\n", i, pFields[i].name, pFields[i].type, + pFields[i].field_type); + } + } + int64_t ts = 1591060628000; for (int i = 0; i < 2; ++i) { - // v.ts[i] = ts++; - v.ts[i] = ts; - // t64_len[i] = sizeof(int64_t); + v.ts[i] = ts++; + t64_len[i] = sizeof(int64_t); } strcpy(v.b, "abcdefg"); b_len[0] = (int)strlen(v.b);