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. Only the root user can perform the operation of creating users, with the syntax as follows.
```sql ```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. The parameters are explained as follows.
@ -20,6 +20,7 @@ The parameters are explained as follows.
- user_name: Up to 23 B long. - 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. - 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. - 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. 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' pass 'literal'
| enable value | enable value
| sysinfo value | sysinfo value
| createdb value
} }
``` ```
@ -59,6 +61,7 @@ The parameters are explained as follows.
- pass: Modify the user's password. - pass: Modify the user's password.
- enable: Whether to enable the user. 1 means to enable this user, 0 means to disable this user. - 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. - 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. 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 ## Create User
```sql ```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. 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`. `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. In the example below, we create a user with the password `123456` who can view system information.
```sql ```sql
@ -76,7 +78,7 @@ alter_user_clause: {
- PASS: Change the password, followed by the new password - PASS: Change the password, followed by the new password
- ENABLE: Enable or disable the user, `1` means enable, `0` means disable - 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 - 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`: The following example disables the user named `test`:

View File

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

View File

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

View File

@ -194,6 +194,7 @@ typedef struct SBoundColInfo {
int32_t numOfCols; int32_t numOfCols;
int32_t numOfBound; int32_t numOfBound;
bool hasBoundCols; bool hasBoundCols;
bool mixTagsCols;
} SBoundColInfo; } SBoundColInfo;
typedef struct STableColsData { 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)); 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; return TSDB_CODE_SUCCESS;
} }

View File

@ -14,13 +14,13 @@
*/ */
#define _DEFAULT_SOURCE #define _DEFAULT_SOURCE
#include "mndTrans.h"
#include "mndDb.h" #include "mndDb.h"
#include "mndPrivilege.h" #include "mndPrivilege.h"
#include "mndShow.h" #include "mndShow.h"
#include "mndStb.h" #include "mndStb.h"
#include "mndSubscribe.h" #include "mndSubscribe.h"
#include "mndSync.h" #include "mndSync.h"
#include "mndTrans.h"
#include "mndUser.h" #include "mndUser.h"
#define TRANS_VER1_NUMBER 1 #define TRANS_VER1_NUMBER 1
@ -890,7 +890,7 @@ static bool mndCheckTransConflict(SMnode *pMnode, STrans *pNew) {
if (pNew->conflict == TRN_CONFLICT_ARBGROUP) { if (pNew->conflict == TRN_CONFLICT_ARBGROUP) {
if (pTrans->conflict == TRN_CONFLICT_GLOBAL) conflict = true; if (pTrans->conflict == TRN_CONFLICT_GLOBAL) conflict = true;
if (pTrans->conflict == TRN_CONFLICT_ARBGROUP) { if (pTrans->conflict == TRN_CONFLICT_ARBGROUP) {
void* pGidIter = taosHashIterate(pNew->arbGroupIds, NULL); void *pGidIter = taosHashIterate(pNew->arbGroupIds, NULL);
while (pGidIter != NULL) { while (pGidIter != NULL) {
int32_t groupId = *(int32_t *)pGidIter; int32_t groupId = *(int32_t *)pGidIter;
if (taosHashGet(pTrans->arbGroupIds, &groupId, sizeof(int32_t)) != NULL) { if (taosHashGet(pTrans->arbGroupIds, &groupId, sizeof(int32_t)) != NULL) {
@ -1305,6 +1305,14 @@ static int32_t mndTransWriteSingleLog(SMnode *pMnode, STrans *pTrans, STransActi
TAOS_RETURN(TSDB_CODE_MND_TRANS_CTX_SWITCH); 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); int32_t code = sdbWriteWithoutFree(pMnode->pSdb, pAction->pRaw);
if (code == 0 || terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) { if (code == 0 || terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) {
pAction->rawWritten = true; pAction->rawWritten = true;
@ -1454,9 +1462,9 @@ static int32_t mndTransExecuteActions(SMnode *pMnode, STrans *pTrans, SArray *pA
for (int32_t action = 0; action < numOfActions; ++action) { for (int32_t action = 0; action < numOfActions; ++action) {
STransAction *pAction = taosArrayGet(pArray, action); STransAction *pAction = taosArrayGet(pArray, action);
mDebug("trans:%d, %s:%d Sent:%d, Received:%d, errCode:0x%x, acceptableCode:0x%x, retryCode:0x%x", mDebug("trans:%d, %s:%d Sent:%d, Received:%d, errCode:0x%x, acceptableCode:0x%x, retryCode:0x%x", pTrans->id,
pTrans->id, mndTransStr(pAction->stage), pAction->id, pAction->msgSent, pAction->msgReceived, mndTransStr(pAction->stage), pAction->id, pAction->msgSent, pAction->msgReceived, pAction->errCode,
pAction->errCode, pAction->acceptableCode, pAction->retryCode); pAction->acceptableCode, pAction->retryCode);
if (pAction->msgSent) { if (pAction->msgSent) {
if (pAction->msgReceived) { if (pAction->msgReceived) {
if (pAction->errCode != 0 && pAction->errCode != pAction->acceptableCode) { if (pAction->errCode != 0 && pAction->errCode != pAction->acceptableCode) {

View File

@ -388,6 +388,11 @@ static int32_t sdbReadFileImp(SSdb *pSdb) {
goto _OVER; 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); code = sdbWriteWithoutFree(pSdb, pRaw);
if (code != 0) { if (code != 0) {
mError("failed to read sdb file:%s since %s", file, terrstr()); 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; return code;
} }
static int32_t parseTimestampOrInterval(const char** end, SToken* pToken, int16_t timePrec, int64_t* ts, int64_t* interval, static int32_t parseTimestampOrInterval(const char** end, SToken* pToken, int16_t timePrec, int64_t* ts,
SMsgBuf* pMsgBuf, bool* isTs) { int64_t* interval, SMsgBuf* pMsgBuf, bool* isTs) {
if (pToken->type == TK_NOW) { if (pToken->type == TK_NOW) {
*isTs = true; *isTs = true;
*ts = taosGetTimestamp(timePrec); *ts = taosGetTimestamp(timePrec);
@ -1387,7 +1387,16 @@ static int32_t getTableDataCxt(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pS
} }
char tbFName[TSDB_TABLE_FNAME_LEN]; 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) { if (TSDB_CODE_SUCCESS != code) {
return code; return code;
} }
@ -1812,8 +1821,10 @@ static int32_t doGetStbRowValues(SInsertParseContext* pCxt, SVnodeModifyOpStmt*
SArray* pTagVals = pStbRowsCxt->aTagVals; SArray* pTagVals = pStbRowsCxt->aTagVals;
bool canParseTagsAfter = !pStbRowsCxt->pTagCond && !pStbRowsCxt->hasTimestampTag; bool canParseTagsAfter = !pStbRowsCxt->pTagCond && !pStbRowsCxt->hasTimestampTag;
int32_t numOfCols = getNumOfColumns(pStbRowsCxt->pStbMeta); int32_t numOfCols = getNumOfColumns(pStbRowsCxt->pStbMeta);
int32_t numOfTags = getNumOfTags(pStbRowsCxt->pStbMeta);
int32_t tbnameIdx = getTbnameSchemaIndex(pStbRowsCxt->pStbMeta); int32_t tbnameIdx = getTbnameSchemaIndex(pStbRowsCxt->pStbMeta);
uint8_t precision = getTableInfo(pStbRowsCxt->pStbMeta).precision; uint8_t precision = getTableInfo(pStbRowsCxt->pStbMeta).precision;
int idx = 0;
for (int i = 0; i < pCols->numOfBound && (code) == TSDB_CODE_SUCCESS; ++i) { for (int i = 0; i < pCols->numOfBound && (code) == TSDB_CODE_SUCCESS; ++i) {
const char* pTmpSql = *ppSql; const char* pTmpSql = *ppSql;
bool ignoreComma = false; bool ignoreComma = false;
@ -1831,13 +1842,37 @@ static int32_t doGetStbRowValues(SInsertParseContext* pCxt, SVnodeModifyOpStmt*
if (TK_NK_QUESTION == pToken->type) { if (TK_NK_QUESTION == pToken->type) {
pCxt->isStmtBind = true; pCxt->isStmtBind = true;
pStmt->usingTableProcessing = true;
if (pCols->pColIndex[i] == tbnameIdx) { if (pCols->pColIndex[i] == tbnameIdx) {
pCxt->preCtbname = false; 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; *bFoundTbName = true;
} }
if (NULL == pCxt->pComCxt->pStmtCb) { } else if (pCols->pColIndex[i] < numOfCols) {
code = buildSyntaxErrMsg(&pCxt->msg, "? only used in stmt", pToken->z); // bind column
break; } 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 { } else {
if (pCols->pColIndex[i] < numOfCols) { if (pCols->pColIndex[i] < numOfCols) {
@ -1882,6 +1917,7 @@ static int32_t doGetStbRowValues(SInsertParseContext* pCxt, SVnodeModifyOpStmt*
} }
} }
} }
return code; return code;
} }
@ -1901,14 +1937,18 @@ static int32_t getStbRowValues(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pS
code = doGetStbRowValues(pCxt, pStmt, ppSql, pStbRowsCxt, pToken, pCols, pSchemas, tagTokens, tagSchemas, code = doGetStbRowValues(pCxt, pStmt, ppSql, pStbRowsCxt, pToken, pCols, pSchemas, tagTokens, tagSchemas,
&numOfTagTokens, &bFoundTbName); &numOfTagTokens, &bFoundTbName);
if (code == TSDB_CODE_SUCCESS && !bFoundTbName) { if (code != TSDB_CODE_SUCCESS) {
code = buildSyntaxErrMsg(&pCxt->msg, "tbname value expected", pOrigSql); return code;
} }
if (code == TSDB_CODE_SUCCESS && pStbRowsCxt->ctbName.tname[0] == '\0') { if (!bFoundTbName) {
if (!pCxt->isStmtBind) {
code = buildSyntaxErrMsg(&pCxt->msg, "tbname value expected", pOrigSql);
} else {
*pGotRow = true; *pGotRow = true;
return TSDB_CODE_TSC_STMT_TBNAME_ERROR; return TSDB_CODE_TSC_STMT_TBNAME_ERROR;
} }
}
bool ctbFirst = true; bool ctbFirst = true;
char ctbFName[TSDB_TABLE_FNAME_LEN]; char ctbFName[TSDB_TABLE_FNAME_LEN];
@ -2050,14 +2090,24 @@ static int32_t parseOneStbRow(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pSt
code = processCtbAutoCreationAndCtbMeta(pCxt, pStmt, pStbRowsCxt); code = processCtbAutoCreationAndCtbMeta(pCxt, pStmt, pStbRowsCxt);
} }
if (code == TSDB_CODE_SUCCESS) { if (code == TSDB_CODE_SUCCESS) {
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 = code =
insGetTableDataCxt(pStmt->pTableBlockHashObj, &pStbRowsCxt->pCtbMeta->uid, sizeof(pStbRowsCxt->pCtbMeta->uid), insGetTableDataCxt(pStmt->pTableBlockHashObj, &pStbRowsCxt->pCtbMeta->uid, sizeof(pStbRowsCxt->pCtbMeta->uid),
pStbRowsCxt->pCtbMeta, &pStbRowsCxt->pCreateCtbReq, ppTableDataCxt, false, true); pStbRowsCxt->pCtbMeta, &pStbRowsCxt->pCreateCtbReq, ppTableDataCxt, false, true);
} }
}
if (code == TSDB_CODE_SUCCESS) { if (code == TSDB_CODE_SUCCESS) {
code = initTableColSubmitData(*ppTableDataCxt); code = initTableColSubmitData(*ppTableDataCxt);
} }
if (code == TSDB_CODE_SUCCESS) { if (code == TSDB_CODE_SUCCESS && !pCxt->isStmtBind) {
SRow** pRow = taosArrayReserve((*ppTableDataCxt)->pData->aRowP, 1); SRow** pRow = taosArrayReserve((*ppTableDataCxt)->pData->aRowP, 1);
code = tRowBuild(pStbRowsCxt->aColVals, (*ppTableDataCxt)->pSchema, pRow); code = tRowBuild(pStbRowsCxt->aColVals, (*ppTableDataCxt)->pSchema, pRow);
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {

View File

@ -941,7 +941,7 @@ 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, int32_t buildStbBoundFields(SBoundColInfo boundColsInfo, SSchema* pSchema, int32_t* fieldNum, TAOS_FIELD_STB** fields,
STableMeta* pMeta, void* boundTags, bool preCtbname) { STableMeta* pMeta, void* boundTags, bool preCtbname) {
SBoundColInfo* tags = (SBoundColInfo*)boundTags; SBoundColInfo* tags = (SBoundColInfo*)boundTags;
int32_t numOfBound = boundColsInfo.numOfBound + tags->numOfBound + (preCtbname ? 1 : 0); int32_t numOfBound = boundColsInfo.numOfBound + (tags->mixTagsCols ? 0 : tags->numOfBound) + (preCtbname ? 1 : 0);
int32_t idx = 0; int32_t idx = 0;
if (fields != NULL) { if (fields != NULL) {
*fields = taosMemoryCalloc(numOfBound, sizeof(TAOS_FIELD_STB)); *fields = taosMemoryCalloc(numOfBound, sizeof(TAOS_FIELD_STB));
@ -957,13 +957,13 @@ int32_t buildStbBoundFields(SBoundColInfo boundColsInfo, SSchema* pSchema, int32
idx++; idx++;
} }
if (tags->numOfBound > 0) { if (tags->numOfBound > 0 && !tags->mixTagsCols) {
SSchema* pSchema = getTableTagSchema(pMeta); SSchema* tagSchema = getTableTagSchema(pMeta);
for (int32_t i = 0; i < tags->numOfBound; ++i) { for (int32_t i = 0; i < tags->numOfBound; ++i) {
(*fields)[idx].field_type = TAOS_FIELD_TAG; (*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)); tstrncpy((*fields)[idx].name, schema->name, sizeof((*fields)[i].name));
(*fields)[idx].type = schema->type; (*fields)[idx].type = schema->type;
(*fields)[idx].bytes = schema->bytes; (*fields)[idx].bytes = schema->bytes;

View File

@ -191,6 +191,7 @@ int32_t insInitBoundColsInfo(int32_t numOfBound, SBoundColInfo* pInfo) {
pInfo->numOfCols = numOfBound; pInfo->numOfCols = numOfBound;
pInfo->numOfBound = numOfBound; pInfo->numOfBound = numOfBound;
pInfo->hasBoundCols = false; pInfo->hasBoundCols = false;
pInfo->mixTagsCols = false;
pInfo->pColIndex = taosMemoryCalloc(numOfBound, sizeof(int16_t)); pInfo->pColIndex = taosMemoryCalloc(numOfBound, sizeof(int16_t));
if (NULL == pInfo->pColIndex) { if (NULL == pInfo->pColIndex) {
return terrno; return terrno;
@ -204,6 +205,7 @@ int32_t insInitBoundColsInfo(int32_t numOfBound, SBoundColInfo* pInfo) {
void insResetBoundColsInfo(SBoundColInfo* pInfo) { void insResetBoundColsInfo(SBoundColInfo* pInfo) {
pInfo->numOfBound = pInfo->numOfCols; pInfo->numOfBound = pInfo->numOfCols;
pInfo->hasBoundCols = false; pInfo->hasBoundCols = false;
pInfo->mixTagsCols = false;
for (int32_t i = 0; i < pInfo->numOfCols; ++i) { for (int32_t i = 0; i < pInfo->numOfCols; ++i) {
pInfo->pColIndex[i] = i; pInfo->pColIndex[i] = i;
} }
@ -739,7 +741,7 @@ int32_t insMergeTableDataCxt(SHashObj* pTableHash, SArray** pVgDataBlocks, bool
STableDataCxt* pTableCxt = *(STableDataCxt**)p; STableDataCxt* pTableCxt = *(STableDataCxt**)p;
if (colFormat) { if (colFormat) {
SColData* pCol = taosArrayGet(pTableCxt->pData->aCol, 0); SColData* pCol = taosArrayGet(pTableCxt->pData->aCol, 0);
if (pCol->nVal <= 0) { if (pCol && pCol->nVal <= 0) {
p = taosHashIterate(pTableHash, p); p = taosHashIterate(pTableHash, p);
continue; continue;
} }

View File

@ -33,18 +33,23 @@ void do_stmt(TAOS* taos) {
char* tbs[2] = {"tb", "tb2"}; char* tbs[2] = {"tb", "tb2"};
int t1_val[2] = {0, 1}; int t1_val[2] = {0, 1};
int t2_len[2] = {3, 3}; int t2_len[2] = {10, 10};
TAOS_STMT2_BIND tags[2][2] = {{{0, &t1_val[0], NULL, NULL, 0}, {0, "a1", &t2_len[0], NULL, 0}}, int t3_len[2] = {sizeof(int), sizeof(int)};
{{0, &t1_val[1], NULL, NULL, 0}, {0, "a2", &t2_len[1], NULL, 0}}}; 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] = { 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, t64_len, is_null, 2}, {TSDB_DATA_TYPE_BINARY, v.b, b_len, NULL, 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}}};
TAOS_STMT2_BIND* tagv[2] = {&tags[0][0], &tags[1][0]}; TAOS_STMT2_BIND* tagv[2] = {&tags[0][0], &tags[1][0]};
TAOS_STMT2_BIND* paramv[2] = {&params[0][0], &params[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_BINDV bindv = {2, &tbs[0], &tagv[0], &paramv[0]};
TAOS_STMT2* stmt = taos_stmt2_init(taos, &option); TAOS_STMT2* stmt = taos_stmt2_init(taos, &option);
const char* sql = "insert into db.? using db.stb tags(?, ?) values(?,?)";
// 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); int code = taos_stmt2_prepare(stmt, sql, 0);
if (code != 0) { if (code != 0) {
printf("failed to execute taos_stmt2_prepare. error:%s\n", taos_stmt2_error(stmt)); printf("failed to execute taos_stmt2_prepare. error:%s\n", taos_stmt2_error(stmt));
@ -52,11 +57,23 @@ void do_stmt(TAOS* taos) {
return; 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; int64_t ts = 1591060628000;
for (int i = 0; i < 2; ++i) { for (int i = 0; i < 2; ++i) {
// v.ts[i] = ts++; v.ts[i] = ts++;
v.ts[i] = ts; t64_len[i] = sizeof(int64_t);
// t64_len[i] = sizeof(int64_t);
} }
strcpy(v.b, "abcdefg"); strcpy(v.b, "abcdefg");
b_len[0] = (int)strlen(v.b); b_len[0] = (int)strlen(v.b);