fix(stmt2):stmt2 get fields return wrong when tag is value(3.3.6) (#30308)

* fix: add case

* fix: stmt2 get fields return wrong when tag is value

* enh: replace preCtb bool to flag,handle more situation

* fix: some unit test error

* diff: add case and fix some problem

* fix: remove async test, handle in TD-34077

* fix: review

---------

Co-authored-by: Simon Guan <slguan@taosdata.com>
This commit is contained in:
Mario Peng 2025-03-22 21:13:47 +08:00 committed by GitHub
parent 2e42a4b046
commit d3f537275f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 155 additions and 70 deletions

View File

@ -49,10 +49,16 @@ extern "C" {
} \
} while (0)
#define HAS_BIND_VALUE ((uint8_t)0x1)
#define IS_FIXED_VALUE ((uint8_t)0x2)
#define USING_CLAUSE ((uint8_t)0x4)
#define IS_FIXED_TAG ((uint8_t)0x8)
#define NO_DATA_USING_CLAUSE ((uint8_t)0x7)
typedef struct SStmtCallback {
TAOS_STMT* pStmt;
int32_t (*getTbNameFn)(TAOS_STMT*, char**);
int32_t (*setInfoFn)(TAOS_STMT*, STableMeta*, void*, SName*, bool, SHashObj*, SHashObj*, const char*, bool);
int32_t (*setInfoFn)(TAOS_STMT*, STableMeta*, void*, SName*, bool, SHashObj*, SHashObj*, const char*, uint8_t);
int32_t (*getExecInfoFn)(TAOS_STMT*, SHashObj**, SHashObj**);
} SStmtCallback;
@ -175,7 +181,7 @@ int32_t qBindStmtColsValue(void* pBlock, SArray* pCols, TAOS_MULTI_BIND* bind, c
int32_t qBindStmtSingleColValue(void* pBlock, SArray* pCols, TAOS_MULTI_BIND* bind, char* msgBuf, int32_t msgBufLen,
int32_t colIdx, int32_t rowNum, void* charsetCxt);
int32_t qBuildStmtColFields(void* pDataBlock, int32_t* fieldNum, TAOS_FIELD_E** fields);
int32_t qBuildStmtStbColFields(void* pBlock, void* boundTags, bool hasCtbName, int32_t* fieldNum,
int32_t qBuildStmtStbColFields(void* pBlock, void* boundTags, uint8_t tbNameFlag, int32_t* fieldNum,
TAOS_FIELD_ALL** fields);
int32_t qBuildStmtTagFields(void* pBlock, void* boundTags, int32_t* fieldNum, TAOS_FIELD_E** fields);
int32_t qBindStmtTagsValue(void* pBlock, void* boundTags, int64_t suid, const char* sTableName, char* tName,

View File

@ -64,7 +64,7 @@ typedef struct SStmtBindInfo {
int32_t sBindLastIdx;
int8_t tbType;
bool tagsCached;
bool preCtbname;
uint8_t tbNameFlag;
void *boundTags;
char tbName[TSDB_TABLE_FNAME_LEN];
char tbFName[TSDB_TABLE_FNAME_LEN];

View File

@ -238,7 +238,7 @@ int32_t stmtRestoreQueryFields(STscStmt* pStmt) {
}
*/
int32_t stmtUpdateBindInfo(TAOS_STMT* stmt, STableMeta* pTableMeta, void* tags, SName* tbName, const char* sTableName,
bool autoCreateTbl) {
bool autoCreateTbl, uint8_t tbNameFlag) {
STscStmt* pStmt = (STscStmt*)stmt;
char tbFName[TSDB_TABLE_FNAME_LEN];
int32_t code = tNameExtractFullName(tbName, tbFName);
@ -256,6 +256,7 @@ int32_t stmtUpdateBindInfo(TAOS_STMT* stmt, STableMeta* pTableMeta, void* tags,
pStmt->bInfo.tbType = pTableMeta->tableType;
pStmt->bInfo.boundTags = tags;
pStmt->bInfo.tagsCached = false;
pStmt->bInfo.tbNameFlag = tbNameFlag;
tstrncpy(pStmt->bInfo.stbFName, sTableName, sizeof(pStmt->bInfo.stbFName));
return TSDB_CODE_SUCCESS;
@ -271,10 +272,10 @@ int32_t stmtUpdateExecInfo(TAOS_STMT* stmt, SHashObj* pVgHash, SHashObj* pBlockH
}
int32_t stmtUpdateInfo(TAOS_STMT* stmt, STableMeta* pTableMeta, void* tags, SName* tbName, bool autoCreateTbl,
SHashObj* pVgHash, SHashObj* pBlockHash, const char* sTableName, bool preCtbname) {
SHashObj* pVgHash, SHashObj* pBlockHash, const char* sTableName, uint8_t tbNameFlag) {
STscStmt* pStmt = (STscStmt*)stmt;
STMT_ERR_RET(stmtUpdateBindInfo(stmt, pTableMeta, tags, tbName, sTableName, autoCreateTbl));
STMT_ERR_RET(stmtUpdateBindInfo(stmt, pTableMeta, tags, tbName, sTableName, autoCreateTbl, tbNameFlag));
STMT_ERR_RET(stmtUpdateExecInfo(stmt, pVgHash, pBlockHash));
pStmt->sql.autoCreateTbl = autoCreateTbl;
@ -1729,7 +1730,10 @@ int stmtGetTagFields(TAOS_STMT* stmt, int* nums, TAOS_FIELD_E** fields) {
STMT_ERRI_JRET(stmtFetchTagFields(stmt, nums, fields));
_return:
// compatible with previous versions
if (code == TSDB_CODE_PAR_TABLE_NOT_EXIST && (pStmt->bInfo.tbNameFlag & NO_DATA_USING_CLAUSE) == 0x0) {
code = TSDB_CODE_TSC_STMT_TBNAME_ERROR;
}
pStmt->errCode = preCode;
return code;

View File

@ -193,7 +193,7 @@ static int32_t stmtGetTbName(TAOS_STMT2* stmt, char** tbName) {
}
static int32_t stmtUpdateBindInfo(TAOS_STMT2* stmt, STableMeta* pTableMeta, void* tags, SName* tbName,
const char* sTableName, bool autoCreateTbl, bool preCtbname) {
const char* sTableName, bool autoCreateTbl, int8_t tbNameFlag) {
STscStmt2* pStmt = (STscStmt2*)stmt;
char tbFName[TSDB_TABLE_FNAME_LEN];
int32_t code = tNameExtractFullName(tbName, tbFName);
@ -217,7 +217,7 @@ static int32_t stmtUpdateBindInfo(TAOS_STMT2* stmt, STableMeta* pTableMeta, void
pStmt->bInfo.boundTags = tags;
pStmt->bInfo.tagsCached = false;
pStmt->bInfo.preCtbname = preCtbname;
pStmt->bInfo.tbNameFlag = tbNameFlag;
tstrncpy(pStmt->bInfo.stbFName, sTableName, sizeof(pStmt->bInfo.stbFName));
return TSDB_CODE_SUCCESS;
@ -233,10 +233,10 @@ static int32_t stmtUpdateExecInfo(TAOS_STMT2* stmt, SHashObj* pVgHash, SHashObj*
}
static int32_t stmtUpdateInfo(TAOS_STMT2* stmt, STableMeta* pTableMeta, void* tags, SName* tbName, bool autoCreateTbl,
SHashObj* pVgHash, SHashObj* pBlockHash, const char* sTableName, bool preCtbname) {
SHashObj* pVgHash, SHashObj* pBlockHash, const char* sTableName, uint8_t tbNameFlag) {
STscStmt2* pStmt = (STscStmt2*)stmt;
STMT_ERR_RET(stmtUpdateBindInfo(stmt, pTableMeta, tags, tbName, sTableName, autoCreateTbl, preCtbname));
STMT_ERR_RET(stmtUpdateBindInfo(stmt, pTableMeta, tags, tbName, sTableName, autoCreateTbl, tbNameFlag));
STMT_ERR_RET(stmtUpdateExecInfo(stmt, pVgHash, pBlockHash));
pStmt->sql.autoCreateTbl = autoCreateTbl;
@ -1233,7 +1233,8 @@ static int stmtFetchStbColFields2(STscStmt2* pStmt, int32_t* fieldNum, TAOS_FIEL
}
STMT_ERRI_JRET(
qBuildStmtStbColFields(*pDataBlock, pStmt->bInfo.boundTags, pStmt->bInfo.preCtbname, fieldNum, fields));
qBuildStmtStbColFields(*pDataBlock, pStmt->bInfo.boundTags, pStmt->bInfo.tbNameFlag, fieldNum, fields));
if (pStmt->bInfo.tbType == TSDB_SUPER_TABLE && cleanStb) {
pStmt->bInfo.needParse = true;
qDestroyStmtDataBlock(*pDataBlock);
@ -2022,7 +2023,9 @@ int stmtParseColFields2(TAOS_STMT2* stmt) {
STMT_TYPE_MULTI_INSERT != pStmt->sql.type) {
pStmt->bInfo.needParse = false;
}
if (pStmt->sql.stbInterlaceMode && pStmt->sql.siInfo.pDataCtx != NULL) {
pStmt->bInfo.needParse = false;
}
if (pStmt->exec.pRequest && STMT_TYPE_QUERY == pStmt->sql.type && pStmt->sql.runTimes) {
taos_free_result(pStmt->exec.pRequest);
pStmt->exec.pRequest = NULL;
@ -2036,6 +2039,10 @@ int stmtParseColFields2(TAOS_STMT2* stmt) {
}
_return:
// compatible with previous versions
if (code == TSDB_CODE_PAR_TABLE_NOT_EXIST && (pStmt->bInfo.tbNameFlag & NO_DATA_USING_CLAUSE) == 0x0) {
code = TSDB_CODE_TSC_STMT_TBNAME_ERROR;
}
pStmt->errCode = preCode;

View File

@ -634,9 +634,20 @@ TEST(stmt2Case, insert_ctb_using_get_fields_Test) {
printf("case 9 : %s\n", sql);
getFieldsSuccess(taos, sql, expectedFields, 5);
}
// case 11: TD-34097
{
do_query(taos, "use stmt2_testdb_3");
const char* sql = "INSERT INTO ? using stb (t1,t2) TAGS(1,'abc') (ts,b)VALUES(?,?)";
TAOS_FIELD_ALL expectedFields[3] = {{"tbname", TSDB_DATA_TYPE_BINARY, 0, 0, 271, TAOS_FIELD_TBNAME},
{"ts", TSDB_DATA_TYPE_TIMESTAMP, 2, 0, 8, TAOS_FIELD_COL},
{"b", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_COL}};
printf("case 11 : %s\n", sql);
getFieldsSuccess(taos, sql, expectedFields, 3);
}
// case 10 : test all types
{
do_query(taos, "use stmt2_testdb_3");
const char* sql =
"insert into ? using all_stb tags(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
TAOS_FIELD_ALL expectedFields[33] = {{"tbname", TSDB_DATA_TYPE_BINARY, 0, 0, 271, TAOS_FIELD_TBNAME},
@ -711,7 +722,27 @@ TEST(stmt2Case, insert_ctb_using_get_fields_Test) {
printf("case 5 : %s\n", sql);
getFieldsError(taos, sql, TSDB_CODE_TSC_SQL_SYNTAX_ERROR);
}
// case 6 : mix value and ?
{
do_query(taos, "use stmt2_testdb_3");
const char* sql = "INSERT INTO ? using stb (t1,t2) TAGS(1,?) (ts,b)VALUES(?,?)";
printf("case 6 : %s\n", sql);
getFieldsError(taos, sql, TSDB_CODE_TSC_SQL_SYNTAX_ERROR);
}
// case 7 : mix value and ?
{
do_query(taos, "use stmt2_testdb_3");
const char* sql = "INSERT INTO ? using stb (t1,t2) TAGS(?,?) (ts,b)VALUES(15910606280001,?)";
printf("case 7 : %s\n", sql);
getFieldsError(taos, sql, TSDB_CODE_TSC_INVALID_OPERATION);
}
// case 8 : mix value and ?
{
do_query(taos, "use stmt2_testdb_3");
const char* sql = "INSERT INTO ? using stb (t1,t2) TAGS(?,?) (ts,b)VALUES(15910606280001,'abc')";
printf("case 8 : %s\n", sql);
getFieldsError(taos, sql, TSDB_CODE_TSC_INVALID_OPERATION);
}
do_query(taos, "drop database if exists stmt2_testdb_3");
taos_close(taos);
}
@ -1002,6 +1033,15 @@ TEST(stmt2Case, stmt2_insert_non_statndard) {
printf("stmt2 [%s] : %s\n", "less params", sql);
int code = taos_stmt2_prepare(stmt, sql, 0);
checkError(stmt, code);
// test get fields
int fieldNum = 0;
TAOS_FIELD_ALL* pFields = NULL;
code = taos_stmt2_get_fields(stmt, &fieldNum, &pFields);
checkError(stmt, code);
ASSERT_EQ(fieldNum, 2);
ASSERT_STREQ(pFields[0].name, "tbname");
ASSERT_STREQ(pFields[1].name, "ts");
int total_affect_rows = 0;
int t64_len[2] = {sizeof(int64_t), sizeof(int64_t)};
@ -1024,11 +1064,22 @@ TEST(stmt2Case, stmt2_insert_non_statndard) {
code = taos_stmt2_bind_param(stmt, &bindv, -1);
checkError(stmt, code);
code = taos_stmt2_get_fields(stmt, &fieldNum, &pFields);
checkError(stmt, code);
ASSERT_EQ(fieldNum, 2);
ASSERT_STREQ(pFields[0].name, "tbname");
ASSERT_STREQ(pFields[1].name, "ts");
int affected_rows;
taos_stmt2_exec(stmt, &affected_rows);
total_affect_rows += affected_rows;
checkError(stmt, code);
code = taos_stmt2_get_fields(stmt, &fieldNum, &pFields);
checkError(stmt, code);
ASSERT_EQ(fieldNum, 2);
ASSERT_STREQ(pFields[0].name, "tbname");
ASSERT_STREQ(pFields[1].name, "ts");
}
ASSERT_EQ(total_affect_rows, 12);
@ -1959,27 +2010,27 @@ void stmt2_async_test(std::atomic<bool>& stop_task) {
stop_task = true;
}
TEST(stmt2Case, async_order) {
std::atomic<bool> stop_task(false);
std::thread t(stmt2_async_test, std::ref(stop_task));
// TEST(stmt2Case, async_order) {
// std::atomic<bool> stop_task(false);
// std::thread t(stmt2_async_test, std::ref(stop_task));
// 等待 60 秒钟
auto start_time = std::chrono::steady_clock::now();
while (!stop_task) {
auto elapsed_time = std::chrono::steady_clock::now() - start_time;
if (std::chrono::duration_cast<std::chrono::seconds>(elapsed_time).count() > 100) {
if (t.joinable()) {
t.detach();
}
FAIL() << "Test[stmt2_async_test] timed out";
break;
}
std::this_thread::sleep_for(std::chrono::seconds(1)); // 每 1s 检查一次
}
if (t.joinable()) {
t.join();
}
}
// // 等待 60 秒钟
// auto start_time = std::chrono::steady_clock::now();
// while (!stop_task) {
// auto elapsed_time = std::chrono::steady_clock::now() - start_time;
// if (std::chrono::duration_cast<std::chrono::seconds>(elapsed_time).count() > 100) {
// if (t.joinable()) {
// t.detach();
// }
// FAIL() << "Test[stmt2_async_test] timed out";
// break;
// }
// std::this_thread::sleep_for(std::chrono::seconds(1)); // 每 1s 检查一次
// }
// if (t.joinable()) {
// t.join();
// }
// }
TEST(stmt2Case, rowformat_bind) {
TAOS* taos = taos_connect("localhost", "root", "taosdata", "", 0);

View File

@ -32,7 +32,7 @@ typedef struct SInsertParseContext {
bool needTableTagVal;
bool needRequest; // whether or not request server
bool isStmtBind; // whether is stmt bind
bool preCtbname;
uint8_t stmtTbNameFlag;
} SInsertParseContext;
typedef int32_t (*_row_append_fn_t)(SMsgBuf* pMsgBuf, const void* value, int32_t len, void* param);
@ -993,6 +993,10 @@ static int32_t parseTagsClauseImpl(SInsertParseContext* pCxt, SVnodeModifyOpStmt
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;
}
continue;
}
@ -1026,6 +1030,10 @@ static int32_t parseTagsClauseImpl(SInsertParseContext* pCxt, SVnodeModifyOpStmt
pTag = NULL;
}
if (code == TSDB_CODE_SUCCESS && !isParseBindParam) {
pCxt->stmtTbNameFlag |= IS_FIXED_TAG;
}
_exit:
for (int32_t i = 0; i < taosArrayGetSize(pTagVals); ++i) {
STagVal* p = (STagVal*)TARRAY_GET_ELEM(pTagVals, i);
@ -1416,6 +1424,7 @@ static int32_t parseUsingTableName(SInsertParseContext* pCxt, SVnodeModifyOpStmt
return getTargetTableSchema(pCxt, pStmt);
}
pStmt->usingTableProcessing = true;
pCxt->stmtTbNameFlag |= USING_CLAUSE;
// pStmt->pSql -> stb_name [(tag1_name, ...)
pStmt->pSql += index;
int32_t code = parseDuplicateUsingClause(pCxt, pStmt, &pCxt->usingDuplicateTable);
@ -1465,7 +1474,7 @@ static int32_t getTableDataCxt(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pS
char tbFName[TSDB_TABLE_FNAME_LEN];
int32_t code = 0;
if (pCxt->preCtbname) {
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;
@ -2764,6 +2773,7 @@ static int32_t checkTableClauseFirstToken(SInsertParseContext* pCxt, SVnodeModif
}
if (TK_NK_QUESTION == pTbName->type) {
pCxt->stmtTbNameFlag &= ~IS_FIXED_VALUE;
pCxt->isStmtBind = true;
if (NULL == pCxt->pComCxt->pStmtCb) {
return buildSyntaxErrMsg(&pCxt->msg, "? only used in stmt", pTbName->z);
@ -2772,14 +2782,15 @@ static int32_t checkTableClauseFirstToken(SInsertParseContext* pCxt, SVnodeModif
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;
pTbName->z = tbName;
pTbName->n = strlen(tbName);
} else if (code == TSDB_CODE_TSC_STMT_TBNAME_ERROR) {
pCxt->preCtbname = true;
code = TSDB_CODE_SUCCESS;
} else {
return code;
}
if (code == TSDB_CODE_TSC_STMT_TBNAME_ERROR) {
pCxt->stmtTbNameFlag &= ~HAS_BIND_VALUE;
code = TSDB_CODE_SUCCESS;
}
return code;
}
if (TK_NK_ID != pTbName->type && TK_NK_STRING != pTbName->type && TK_NK_QUESTION != pTbName->type) {
@ -2788,26 +2799,34 @@ static int32_t checkTableClauseFirstToken(SInsertParseContext* pCxt, SVnodeModif
// db.? situationensure that the only thing following the '.' mark is '?'
char* tbNameAfterDbName = strnchr(pTbName->z, '.', pTbName->n, true);
if ((tbNameAfterDbName != NULL) && (*(tbNameAfterDbName + 1) == '?')) {
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 (code != TSDB_CODE_SUCCESS) {
pCxt->preCtbname = true;
} else {
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;
}
if (pCxt->isStmtBind) {
if (TK_NK_ID == pTbName->type || (tbNameAfterDbName != NULL && *(tbNameAfterDbName + 1) != '?')) {
// In SQL statements, the table name has already been specified.
} else {
pCxt->stmtTbNameFlag |= IS_FIXED_VALUE;
parserWarn("QID:0x%" PRIx64 ", table name is specified in sql, ignore the table name in bind param",
pCxt->pComCxt->requestId);
*pHasData = true;
}
return TSDB_CODE_SUCCESS;
}
if (TK_NK_ID == pTbName->type) {
pCxt->stmtTbNameFlag |= IS_FIXED_VALUE;
}
*pHasData = true;
@ -2824,7 +2843,7 @@ static int32_t setStmtInfo(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt)
SStmtCallback* pStmtCb = pCxt->pComCxt->pStmtCb;
int32_t code = (*pStmtCb->setInfoFn)(pStmtCb->pStmt, pStmt->pTableMeta, tags, &pStmt->targetTableName,
pStmt->usingTableProcessing, pStmt->pVgroupsHashObj, pStmt->pTableBlockHashObj,
pStmt->usingTableName.tname, pCxt->preCtbname);
pStmt->usingTableName.tname, pCxt->stmtTbNameFlag);
memset(&pCxt->tags, 0, sizeof(pCxt->tags));
pStmt->pVgroupsHashObj = NULL;
@ -2880,9 +2899,6 @@ static int32_t parseInsertBody(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pS
if (TSDB_CODE_SUCCESS == code && hasData) {
code = parseInsertTableClause(pCxt, pStmt, &token);
}
if (TSDB_CODE_PAR_TABLE_NOT_EXIST == code && pCxt->preCtbname) {
code = TSDB_CODE_TSC_STMT_TBNAME_ERROR;
}
}
if (TSDB_CODE_SUCCESS == code && !pCxt->missCache) {

View File

@ -1070,10 +1070,11 @@ int32_t buildBoundFields(int32_t numOfBound, int16_t* boundColumns, SSchema* pSc
}
int32_t buildStbBoundFields(SBoundColInfo boundColsInfo, SSchema* pSchema, int32_t* fieldNum, TAOS_FIELD_ALL** fields,
STableMeta* pMeta, void* boundTags, bool preCtbname) {
STableMeta* pMeta, void* boundTags, uint8_t tbNameFlag) {
SBoundColInfo* tags = (SBoundColInfo*)boundTags;
bool hastag = tags != NULL;
int32_t numOfBound = boundColsInfo.numOfBound + (preCtbname ? 1 : 0);
bool hastag = (tags != NULL) && !(tbNameFlag & IS_FIXED_TAG);
int32_t numOfBound =
boundColsInfo.numOfBound + ((tbNameFlag & IS_FIXED_VALUE) == 0 && (tbNameFlag & USING_CLAUSE) != 0 ? 1 : 0);
if (hastag) {
numOfBound += tags->mixTagsCols ? 0 : tags->numOfBound;
}
@ -1084,7 +1085,7 @@ int32_t buildStbBoundFields(SBoundColInfo boundColsInfo, SSchema* pSchema, int32
return terrno;
}
if (preCtbname && numOfBound != boundColsInfo.numOfBound) {
if ((tbNameFlag & IS_FIXED_VALUE) == 0 && (tbNameFlag & USING_CLAUSE) != 0) {
(*fields)[idx].field_type = TAOS_FIELD_TBNAME;
tstrncpy((*fields)[idx].name, "tbname", sizeof((*fields)[idx].name));
(*fields)[idx].type = TSDB_DATA_TYPE_BINARY;
@ -1188,7 +1189,7 @@ int32_t qBuildStmtColFields(void* pBlock, int32_t* fieldNum, TAOS_FIELD_E** fiel
return TSDB_CODE_SUCCESS;
}
int32_t qBuildStmtStbColFields(void* pBlock, void* boundTags, bool preCtbname, int32_t* fieldNum,
int32_t qBuildStmtStbColFields(void* pBlock, void* boundTags, uint8_t tbNameFlag, int32_t* fieldNum,
TAOS_FIELD_ALL** fields) {
STableDataCxt* pDataBlock = (STableDataCxt*)pBlock;
SSchema* pSchema = getTableColumnSchema(pDataBlock->pMeta);
@ -1202,7 +1203,7 @@ int32_t qBuildStmtStbColFields(void* pBlock, void* boundTags, bool preCtbname, i
}
CHECK_CODE(buildStbBoundFields(pDataBlock->boundColsInfo, pSchema, fieldNum, fields, pDataBlock->pMeta, boundTags,
preCtbname));
tbNameFlag));
return TSDB_CODE_SUCCESS;
}