Merge remote-tracking branch 'origin/3.0' into feat/TD-30268

This commit is contained in:
dapan1121 2024-12-09 15:35:35 +08:00
commit 20a8c92d3e
12 changed files with 153 additions and 53 deletions

View File

@ -12,7 +12,7 @@ TDengine is configured by default with only one root user, who has the highest p
Only the root user can perform the operation of creating users, with the syntax as follows.
```sql
create user user_name pass'password' [sysinfo {1|0}]
create user user_name pass'password' [sysinfo {1|0}] [createdb {1|0}]
```
The parameters are explained as follows.
@ -20,6 +20,7 @@ The parameters are explained as follows.
- user_name: Up to 23 B long.
- password: Up to 128 B long, valid characters include letters and numbers as well as special characters other than single and double quotes, apostrophes, backslashes, and spaces, and it cannot be empty.
- sysinfo: Whether the user can view system information. 1 means they can view it, 0 means they cannot. System information includes server configuration information, various node information such as dnode, query node (qnode), etc., as well as storage-related information, etc. The default is to view system information.
- createdb: Whether the user can create databases. 1 means they can create databases, 0 means they cannot. The default value is 0. // Supported starting from TDengine Enterprise version 3.3.2.0
The following SQL can create a user named test with the password 123456 who can view system information.
@ -51,6 +52,7 @@ alter_user_clause: {
pass 'literal'
| enable value
| sysinfo value
| createdb value
}
```
@ -59,6 +61,7 @@ The parameters are explained as follows.
- pass: Modify the user's password.
- enable: Whether to enable the user. 1 means to enable this user, 0 means to disable this user.
- sysinfo: Whether the user can view system information. 1 means they can view system information, 0 means they cannot.
- createdb: Whether the user can create databases. 1 means they can create databases, 0 means they cannot. // Supported starting from TDengine Enterprise version 3.3.2.0
The following SQL disables the user test.

View File

@ -8,7 +8,7 @@ User and permission management is a feature of TDengine Enterprise Edition. This
## Create User
```sql
CREATE USER user_name PASS 'password' [SYSINFO {1|0}];
CREATE USER user_name PASS 'password' [SYSINFO {1|0}] [CREATEDB {1|0}];
```
The username can be up to 23 bytes long.
@ -17,6 +17,8 @@ The password can be up to 31 bytes long. The password can include letters, numbe
`SYSINFO` indicates whether the user can view system information. `1` means they can view, `0` means they have no permission to view. System information includes service configuration, dnode, vnode, storage, etc. The default value is `1`.
`CREATEDB` indicates whether the user can create databases. `1` means they can create databases, `0` means they have no permission to create databases. The default value is `0`. // Supported starting from TDengine Enterprise version 3.3.2.0
In the example below, we create a user with the password `123456` who can view system information.
```sql
@ -76,7 +78,7 @@ alter_user_clause: {
- PASS: Change the password, followed by the new password
- ENABLE: Enable or disable the user, `1` means enable, `0` means disable
- SYSINFO: Allow or prohibit viewing system information, `1` means allow, `0` means prohibit
- CREATEDB: Allow or prohibit creating databases, `1` means allow, `0` means prohibit
- CREATEDB: Allow or prohibit creating databases, `1` means allow, `0` means prohibit. // Supported starting from TDengine Enterprise version 3.3.2.0
The following example disables the user named `test`:

View File

@ -12,13 +12,14 @@ TDengine 默认仅配置了一个 root 用户该用户拥有最高权限。TD
创建用户的操作只能由 root 用户进行,语法如下。
```sql
create user user_name pass'password' [sysinfo {1|0}]
create user user_name pass'password' [sysinfo {1|0}] [createdb {1|0}]
```
相关参数说明如下。
- user_name最长为 23 B。
- password最长为 128 B合法字符包括字母和数字以及单双引号、撇号、反斜杠和空格以外的特殊字符且不可以为空。
- sysinfo 用户是否可以查看系统信息。1 表示可以查看0 表示不可以查看。系统信息包括服务端配置信息、服务端各种节点信息,如 dnode、查询节点qnode以及与存储相关的信息等。默认为可以查看系统信息。
- createdb用户是否可以创建数据库。1 表示可以创建0 表示不可以创建。缺省值为 0。// 从 TDengine 企业版 3.3.2.0 开始支持
如下 SQL 可以创建密码为 123456 且可以查看系统信息的用户 test。
@ -47,6 +48,7 @@ alter_user_clause: {
pass 'literal'
| enable value
| sysinfo value
| createdb value
}
```
@ -54,6 +56,7 @@ alter_user_clause: {
- pass修改用户密码。
- enable是否启用用户。1 表示启用此用户0 表示禁用此用户。
- sysinfo 用户是否可查看系统信息。1 表示可以查看系统信息0 表示不可以查看系统信息
- createdb用户是否可创建数据库。1 表示可以创建数据库0 表示不可以创建数据库。// 从 TDengine 企业版 3.3.2.0 开始支持
如下 SQL 禁用 test 用户。
```sql

View File

@ -9,7 +9,7 @@ description: 本节讲述基本的用户管理功能
## 创建用户
```sql
CREATE USER user_name PASS 'password' [SYSINFO {1|0}];
CREATE USER user_name PASS 'password' [SYSINFO {1|0}] [CREATEDB {1|0}];
```
用户名最长不超过 23 个字节。
@ -18,6 +18,8 @@ CREATE USER user_name PASS 'password' [SYSINFO {1|0}];
`SYSINFO` 表示该用户是否能够查看系统信息。`1` 表示可以查看,`0` 表示无权查看。系统信息包括服务配置、dnode、vnode、存储等信息。缺省值为 `1`
`CREATEDB` 表示该用户是否能够创建数据库。`1` 表示可以创建,`0` 表示无权创建。缺省值为 `0`。// 从 TDengine 企业版 3.3.2.0 开始支持
在下面的示例中,我们创建一个密码为 `123456` 且可以查看系统信息的用户。
```sql
@ -77,7 +79,7 @@ alter_user_clause: {
- PASS: 修改密码,后跟新密码
- ENABLE: 启用或禁用该用户,`1` 表示启用,`0` 表示禁用
- SYSINFO: 允许或禁止查看系统信息,`1` 表示允许,`0` 表示禁止
- CREATEDB: 允许或禁止创建数据库,`1` 表示允许,`0` 表示禁止
- CREATEDB: 允许或禁止创建数据库,`1` 表示允许,`0` 表示禁止。// 从 TDengine 企业版 3.3.2.0 开始支持
下面的示例禁用了名为 `test` 的用户:

View File

@ -194,6 +194,7 @@ typedef struct SBoundColInfo {
int32_t numOfCols;
int32_t numOfBound;
bool hasBoundCols;
bool mixTagsCols;
} SBoundColInfo;
typedef struct STableColsData {

View File

@ -1094,6 +1094,13 @@ static int stmtFetchStbColFields2(STscStmt2* pStmt, int32_t* fieldNum, TAOS_FIEL
}
STMT_ERR_RET(qBuildStmtStbColFields(*pDataBlock, pStmt->bInfo.boundTags, pStmt->bInfo.preCtbname, fieldNum, fields));
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;
}

View File

@ -14,13 +14,13 @@
*/
#define _DEFAULT_SOURCE
#include "mndTrans.h"
#include "mndDb.h"
#include "mndPrivilege.h"
#include "mndShow.h"
#include "mndStb.h"
#include "mndSubscribe.h"
#include "mndSync.h"
#include "mndTrans.h"
#include "mndUser.h"
#define TRANS_VER1_NUMBER 1
@ -216,7 +216,7 @@ SSdbRaw *mndTransEncode(STrans *pTrans) {
SDB_SET_RESERVE(pRaw, dataPos, TRANS_RESERVE_SIZE, _OVER)
SDB_SET_DATALEN(pRaw, dataPos, _OVER)
terrno = 0;
terrno = 0;
_OVER:
if (terrno != 0) {
@ -287,8 +287,8 @@ _OVER:
SSdbRow *mndTransDecode(SSdbRaw *pRaw) {
terrno = TSDB_CODE_INVALID_MSG;
int32_t code = 0;
int32_t lino = 0;
int32_t code = 0;
int32_t lino = 0;
SSdbRow *pRow = NULL;
STrans *pTrans = NULL;
char *pData = NULL;
@ -890,7 +890,7 @@ static bool mndCheckTransConflict(SMnode *pMnode, STrans *pNew) {
if (pNew->conflict == TRN_CONFLICT_ARBGROUP) {
if (pTrans->conflict == TRN_CONFLICT_GLOBAL) conflict = true;
if (pTrans->conflict == TRN_CONFLICT_ARBGROUP) {
void* pGidIter = taosHashIterate(pNew->arbGroupIds, NULL);
void *pGidIter = taosHashIterate(pNew->arbGroupIds, NULL);
while (pGidIter != NULL) {
int32_t groupId = *(int32_t *)pGidIter;
if (taosHashGet(pTrans->arbGroupIds, &groupId, sizeof(int32_t)) != NULL) {
@ -1033,7 +1033,7 @@ static int32_t mndTransCheckCommitActions(SMnode *pMnode, STrans *pTrans) {
int32_t mndTransPrepare(SMnode *pMnode, STrans *pTrans) {
int32_t code = 0;
if (pTrans == NULL) {
return TSDB_CODE_INVALID_PARA;
return TSDB_CODE_INVALID_PARA;
}
TAOS_CHECK_RETURN(mndTransCheckConflict(pMnode, pTrans));
@ -1305,6 +1305,14 @@ static int32_t mndTransWriteSingleLog(SMnode *pMnode, STrans *pTrans, STransActi
TAOS_RETURN(TSDB_CODE_MND_TRANS_CTX_SWITCH);
}
if (pAction->pRaw->type >= SDB_MAX) {
pAction->rawWritten = true;
pAction->errCode = 0;
mndSetTransLastAction(pTrans, pAction);
mInfo("skip sdb raw type:%d since it is not supported", pAction->pRaw->type);
TAOS_RETURN(TSDB_CODE_SUCCESS);
}
int32_t code = sdbWriteWithoutFree(pMnode->pSdb, pAction->pRaw);
if (code == 0 || terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) {
pAction->rawWritten = true;
@ -1348,10 +1356,10 @@ static int32_t mndTransSendSingleMsg(SMnode *pMnode, STrans *pTrans, STransActio
char detail[1024] = {0};
int32_t len = tsnprintf(detail, sizeof(detail), "msgType:%s numOfEps:%d inUse:%d", TMSG_INFO(pAction->msgType),
pAction->epSet.numOfEps, pAction->epSet.inUse);
pAction->epSet.numOfEps, pAction->epSet.inUse);
for (int32_t i = 0; i < pAction->epSet.numOfEps; ++i) {
len += tsnprintf(detail + len, sizeof(detail) - len, " ep:%d-%s:%u", i, pAction->epSet.eps[i].fqdn,
pAction->epSet.eps[i].port);
pAction->epSet.eps[i].port);
}
int32_t code = tmsgSendReq(&pAction->epSet, &rpcMsg);
@ -1454,9 +1462,9 @@ static int32_t mndTransExecuteActions(SMnode *pMnode, STrans *pTrans, SArray *pA
for (int32_t action = 0; action < numOfActions; ++action) {
STransAction *pAction = taosArrayGet(pArray, action);
mDebug("trans:%d, %s:%d Sent:%d, Received:%d, errCode:0x%x, acceptableCode:0x%x, retryCode:0x%x",
pTrans->id, mndTransStr(pAction->stage), pAction->id, pAction->msgSent, pAction->msgReceived,
pAction->errCode, pAction->acceptableCode, pAction->retryCode);
mDebug("trans:%d, %s:%d Sent:%d, Received:%d, errCode:0x%x, acceptableCode:0x%x, retryCode:0x%x", pTrans->id,
mndTransStr(pAction->stage), pAction->id, pAction->msgSent, pAction->msgReceived, pAction->errCode,
pAction->acceptableCode, pAction->retryCode);
if (pAction->msgSent) {
if (pAction->msgReceived) {
if (pAction->errCode != 0 && pAction->errCode != pAction->acceptableCode) {
@ -2038,11 +2046,11 @@ static int32_t mndRetrieveTrans(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBl
char lastInfo[TSDB_TRANS_ERROR_LEN + VARSTR_HEADER_SIZE] = {0};
char detail[TSDB_TRANS_ERROR_LEN + 1] = {0};
int32_t len = tsnprintf(detail, sizeof(detail), "action:%d code:0x%x(%s) ", pTrans->lastAction,
pTrans->lastErrorNo & 0xFFFF, tstrerror(pTrans->lastErrorNo));
pTrans->lastErrorNo & 0xFFFF, tstrerror(pTrans->lastErrorNo));
SEpSet epset = pTrans->lastEpset;
if (epset.numOfEps > 0) {
len += tsnprintf(detail + len, sizeof(detail) - len, "msgType:%s numOfEps:%d inUse:%d ",
TMSG_INFO(pTrans->lastMsgType), epset.numOfEps, epset.inUse);
TMSG_INFO(pTrans->lastMsgType), epset.numOfEps, epset.inUse);
for (int32_t i = 0; i < pTrans->lastEpset.numOfEps; ++i) {
len += tsnprintf(detail + len, sizeof(detail) - len, "ep:%d-%s:%u ", i, epset.eps[i].fqdn, epset.eps[i].port);
}

View File

@ -388,6 +388,11 @@ static int32_t sdbReadFileImp(SSdb *pSdb) {
goto _OVER;
}
if (pRaw->type >= SDB_MAX) {
mInfo("skip sdb raw type:%d since it is not supported", pRaw->type);
continue;
}
code = sdbWriteWithoutFree(pSdb, pRaw);
if (code != 0) {
mError("failed to read sdb file:%s since %s", file, terrstr());

View File

@ -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);
@ -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;
@ -1831,13 +1842,37 @@ 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 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) {
@ -1882,6 +1917,7 @@ static int32_t doGetStbRowValues(SInsertParseContext* pCxt, SVnodeModifyOpStmt*
}
}
}
return code;
}
@ -1901,13 +1937,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 +2090,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) {

View File

@ -941,8 +941,8 @@ int32_t buildBoundFields(int32_t numOfBound, int16_t* boundColumns, SSchema* pSc
int32_t buildStbBoundFields(SBoundColInfo boundColsInfo, SSchema* pSchema, int32_t* fieldNum, TAOS_FIELD_STB** fields,
STableMeta* pMeta, void* boundTags, bool preCtbname) {
SBoundColInfo* tags = (SBoundColInfo*)boundTags;
int32_t numOfBound = boundColsInfo.numOfBound + tags->numOfBound + (preCtbname ? 1 : 0);
int32_t idx = 0;
int32_t numOfBound = boundColsInfo.numOfBound + (tags->mixTagsCols ? 0 : tags->numOfBound) + (preCtbname ? 1 : 0);
int32_t idx = 0;
if (fields != NULL) {
*fields = taosMemoryCalloc(numOfBound, sizeof(TAOS_FIELD_STB));
if (NULL == *fields) {
@ -957,13 +957,13 @@ int32_t buildStbBoundFields(SBoundColInfo boundColsInfo, SSchema* pSchema, int32
idx++;
}
if (tags->numOfBound > 0) {
SSchema* pSchema = getTableTagSchema(pMeta);
if (tags->numOfBound > 0 && !tags->mixTagsCols) {
SSchema* tagSchema = getTableTagSchema(pMeta);
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;

View File

@ -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;
}
@ -739,7 +741,7 @@ int32_t insMergeTableDataCxt(SHashObj* pTableHash, SArray** pVgDataBlocks, bool
STableDataCxt* pTableCxt = *(STableDataCxt**)p;
if (colFormat) {
SColData* pCol = taosArrayGet(pTableCxt->pData->aCol, 0);
if (pCol->nVal <= 0) {
if (pCol && pCol->nVal <= 0) {
p = taosHashIterate(pTableHash, p);
continue;
}

View File

@ -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] = {&params[0][0], &params[1][0]};
TAOS_STMT2_BINDV bindv = {2, &tbs[0], &tagv[0], &paramv[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);