isStmtBind
This commit is contained in:
parent
2f970dbc03
commit
d69c5b1840
|
@ -30,6 +30,7 @@ typedef struct SInsertParseContext {
|
||||||
bool forceUpdate;
|
bool forceUpdate;
|
||||||
bool needTableTagVal;
|
bool needTableTagVal;
|
||||||
bool needRequest; // whether or not request server
|
bool needRequest; // whether or not request server
|
||||||
|
bool isStmtBind; // whether is stmt
|
||||||
} SInsertParseContext;
|
} SInsertParseContext;
|
||||||
|
|
||||||
typedef int32_t (*_row_append_fn_t)(SMsgBuf* pMsgBuf, const void* value, int32_t len, void* param);
|
typedef int32_t (*_row_append_fn_t)(SMsgBuf* pMsgBuf, const void* value, int32_t len, void* param);
|
||||||
|
@ -1978,7 +1979,6 @@ static int32_t parseOneStbRow(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pSt
|
||||||
static int parseOneRow(SInsertParseContext* pCxt, const char** pSql, STableDataCxt* pTableCxt, bool* pGotRow,
|
static int parseOneRow(SInsertParseContext* pCxt, const char** pSql, STableDataCxt* pTableCxt, bool* pGotRow,
|
||||||
SToken* pToken) {
|
SToken* pToken) {
|
||||||
SBoundColInfo* pCols = &pTableCxt->boundColsInfo;
|
SBoundColInfo* pCols = &pTableCxt->boundColsInfo;
|
||||||
bool isParseBindParam = false;
|
|
||||||
SSchema* pSchemas = getTableColumnSchema(pTableCxt->pMeta);
|
SSchema* pSchemas = getTableColumnSchema(pTableCxt->pMeta);
|
||||||
|
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
@ -1996,7 +1996,7 @@ static int parseOneRow(SInsertParseContext* pCxt, const char** pSql, STableDataC
|
||||||
SColVal* pVal = taosArrayGet(pTableCxt->pValues, pCols->pColIndex[i]);
|
SColVal* pVal = taosArrayGet(pTableCxt->pValues, pCols->pColIndex[i]);
|
||||||
|
|
||||||
if (pToken->type == TK_NK_QUESTION) {
|
if (pToken->type == TK_NK_QUESTION) {
|
||||||
isParseBindParam = true;
|
pCxt->isStmtBind = true;
|
||||||
if (NULL == pCxt->pComCxt->pStmtCb) {
|
if (NULL == pCxt->pComCxt->pStmtCb) {
|
||||||
code = buildSyntaxErrMsg(&pCxt->msg, "? only used in stmt", pToken->z);
|
code = buildSyntaxErrMsg(&pCxt->msg, "? only used in stmt", pToken->z);
|
||||||
break;
|
break;
|
||||||
|
@ -2007,8 +2007,8 @@ static int parseOneRow(SInsertParseContext* pCxt, const char** pSql, STableDataC
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isParseBindParam) {
|
if (pCxt->isStmtBind) {
|
||||||
code = buildInvalidOperationMsg(&pCxt->msg, "no mix usage for ? and values");
|
code = buildInvalidOperationMsg(&pCxt->msg, "stmt bind param does not support normal value in sql");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2025,7 +2025,7 @@ static int parseOneRow(SInsertParseContext* pCxt, const char** pSql, STableDataC
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TSDB_CODE_SUCCESS == code && !isParseBindParam) {
|
if (TSDB_CODE_SUCCESS == code && !pCxt->isStmtBind) {
|
||||||
SRow** pRow = taosArrayReserve(pTableCxt->pData->aRowP, 1);
|
SRow** pRow = taosArrayReserve(pTableCxt->pData->aRowP, 1);
|
||||||
code = tRowBuild(pTableCxt->pValues, pTableCxt->pSchema, pRow);
|
code = tRowBuild(pTableCxt->pValues, pTableCxt->pSchema, pRow);
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
@ -2035,7 +2035,7 @@ static int parseOneRow(SInsertParseContext* pCxt, const char** pSql, STableDataC
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TSDB_CODE_SUCCESS == code && !isParseBindParam) {
|
if (TSDB_CODE_SUCCESS == code && !pCxt->isStmtBind) {
|
||||||
*pGotRow = true;
|
*pGotRow = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2410,6 +2410,7 @@ static int32_t checkTableClauseFirstToken(SInsertParseContext* pCxt, SVnodeModif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TK_NK_QUESTION == pTbName->type) {
|
if (TK_NK_QUESTION == pTbName->type) {
|
||||||
|
pCxt->isStmtBind = true;
|
||||||
if (NULL == pCxt->pComCxt->pStmtCb) {
|
if (NULL == pCxt->pComCxt->pStmtCb) {
|
||||||
return buildSyntaxErrMsg(&pCxt->msg, "? only used in stmt", pTbName->z);
|
return buildSyntaxErrMsg(&pCxt->msg, "? only used in stmt", pTbName->z);
|
||||||
}
|
}
|
||||||
|
@ -2935,7 +2936,8 @@ int32_t parseInsertSql(SParseContext* pCxt, SQuery** pQuery, SCatalogReq* pCatal
|
||||||
.missCache = false,
|
.missCache = false,
|
||||||
.usingDuplicateTable = false,
|
.usingDuplicateTable = false,
|
||||||
.needRequest = true,
|
.needRequest = true,
|
||||||
.forceUpdate = (NULL != pCatalogReq ? pCatalogReq->forceUpdate : false)};
|
.forceUpdate = (NULL != pCatalogReq ? pCatalogReq->forceUpdate : false),
|
||||||
|
.isStmtBind = false};
|
||||||
|
|
||||||
int32_t code = initInsertQuery(&context, pCatalogReq, pMetaData, pQuery);
|
int32_t code = initInsertQuery(&context, pCatalogReq, pMetaData, pQuery);
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
|
|
@ -32,29 +32,29 @@
|
||||||
class taoscTest : public ::testing::Test {
|
class taoscTest : public ::testing::Test {
|
||||||
protected:
|
protected:
|
||||||
static void SetUpTestCase() {
|
static void SetUpTestCase() {
|
||||||
printf("start test setup.\n");
|
// printf("start test setup.\n");
|
||||||
TAOS* taos = taos_connect("localhost", "root", "taosdata", NULL, 0);
|
// TAOS* taos = taos_connect("localhost", "root", "taosdata", NULL, 0);
|
||||||
ASSERT_TRUE(taos != nullptr);
|
// ASSERT_TRUE(taos != nullptr);
|
||||||
|
//
|
||||||
TAOS_RES* res = taos_query(taos, "drop database IF EXISTS taosc_test_db;");
|
// TAOS_RES* res = taos_query(taos, "drop database IF EXISTS taosc_test_db;");
|
||||||
if (taos_errno(res) != 0) {
|
// if (taos_errno(res) != 0) {
|
||||||
printf("error in drop database taosc_test_db, reason:%s\n", taos_errstr(res));
|
// printf("error in drop database taosc_test_db, reason:%s\n", taos_errstr(res));
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
taosSsleep(5);
|
// taosSsleep(5);
|
||||||
taos_free_result(res);
|
// taos_free_result(res);
|
||||||
printf("drop database taosc_test_db,finished.\n");
|
// printf("drop database taosc_test_db,finished.\n");
|
||||||
|
//
|
||||||
res = taos_query(taos, "create database taosc_test_db;");
|
// res = taos_query(taos, "create database taosc_test_db;");
|
||||||
if (taos_errno(res) != 0) {
|
// if (taos_errno(res) != 0) {
|
||||||
printf("error in create database taosc_test_db, reason:%s\n", taos_errstr(res));
|
// printf("error in create database taosc_test_db, reason:%s\n", taos_errstr(res));
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
taosSsleep(5);
|
// taosSsleep(5);
|
||||||
taos_free_result(res);
|
// taos_free_result(res);
|
||||||
printf("create database taosc_test_db,finished.\n");
|
// printf("create database taosc_test_db,finished.\n");
|
||||||
|
//
|
||||||
taos_close(taos);
|
// taos_close(taos);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void TearDownTestCase() {}
|
static void TearDownTestCase() {}
|
||||||
|
@ -99,6 +99,154 @@ void queryCallback(void* param, void* res, int32_t code) {
|
||||||
taos_fetch_raw_block_a(res, fetchCallback, param);
|
taos_fetch_raw_block_a(res, fetchCallback, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief execute sql only.
|
||||||
|
*
|
||||||
|
* @param taos
|
||||||
|
* @param sql
|
||||||
|
*/
|
||||||
|
void executeSQL(TAOS *taos, const char *sql) {
|
||||||
|
TAOS_RES *res = taos_query(taos, sql);
|
||||||
|
int code = taos_errno(res);
|
||||||
|
if (code != 0) {
|
||||||
|
printf("%s\n", taos_errstr(res));
|
||||||
|
taos_free_result(res);
|
||||||
|
taos_close(taos);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
taos_free_result(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief check return status and exit program when error occur.
|
||||||
|
*
|
||||||
|
* @param stmt
|
||||||
|
* @param code
|
||||||
|
* @param msg
|
||||||
|
*/
|
||||||
|
void checkErrorCode(TAOS_STMT *stmt, int code, const char* msg) {
|
||||||
|
if (code != 0) {
|
||||||
|
printf("%s. error: %s\n", msg, taos_stmt_errstr(stmt));
|
||||||
|
taos_stmt_close(stmt);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int64_t ts;
|
||||||
|
float current;
|
||||||
|
int voltage;
|
||||||
|
float phase;
|
||||||
|
} Row;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief insert data using stmt API
|
||||||
|
*
|
||||||
|
* @param taos
|
||||||
|
*/
|
||||||
|
void insertData(TAOS *taos) {
|
||||||
|
// init
|
||||||
|
TAOS_STMT *stmt = taos_stmt_init(taos);
|
||||||
|
// prepare
|
||||||
|
// const char *sql = "INSERT INTO ?.d1001 USING meters TAGS(?, ?) values(?, ?, ?, ?)";
|
||||||
|
// const char *sql = "INSERT INTO ?.? USING meters TAGS(?, ?) values(?, ?, ?, ?)";
|
||||||
|
// const char *sql = "INSERT INTO power.? USING meters TAGS(?, ?) values(?, ?, ?, ?)";
|
||||||
|
// const char *sql = "INSERT INTO ? USING meters TAGS(?, ?) values(?, ?, ?, ?)";
|
||||||
|
// const char *sql = "INSERT INTO ? USING meters TAGS(?, ?) values(?, ?, ?, ?)";
|
||||||
|
const char *sql = "insert into huawei USING meters TAGS(?, ?) values(?, ?, ?, ?)";
|
||||||
|
int code = taos_stmt_prepare(stmt, sql, 0);
|
||||||
|
checkErrorCode(stmt, code, "failed to execute taos_stmt_prepare");
|
||||||
|
// bind table name and tags
|
||||||
|
TAOS_MULTI_BIND tags[2];
|
||||||
|
char *location = "California.SanFrancisco";
|
||||||
|
int groupId = 2;
|
||||||
|
tags[0].buffer_type = TSDB_DATA_TYPE_BINARY;
|
||||||
|
tags[0].buffer_length = strlen(location);
|
||||||
|
tags[0].length = (int32_t *)&tags[0].buffer_length;
|
||||||
|
tags[0].buffer = location;
|
||||||
|
tags[0].is_null = NULL;
|
||||||
|
|
||||||
|
tags[1].buffer_type = TSDB_DATA_TYPE_INT;
|
||||||
|
tags[1].buffer_length = sizeof(int);
|
||||||
|
tags[1].length = (int32_t *)&tags[1].buffer_length;
|
||||||
|
tags[1].buffer = &groupId;
|
||||||
|
tags[1].is_null = NULL;
|
||||||
|
|
||||||
|
// code = taos_stmt_set_tbname_tags(stmt, "duck", tags);
|
||||||
|
// checkErrorCode(stmt, code, "failed to execute taos_stmt_set_dbname_tbname_tags");
|
||||||
|
|
||||||
|
// insert two rows with multi binds
|
||||||
|
TAOS_MULTI_BIND params[4];
|
||||||
|
// values to bind
|
||||||
|
int64_t ts[] = {1648432611250, 1648432611778};
|
||||||
|
float current[] = {10.3, 12.6};
|
||||||
|
int voltage[] = {219, 218};
|
||||||
|
float phase[] = {0.31, 0.33};
|
||||||
|
// is_null array
|
||||||
|
char is_null[2] = {0};
|
||||||
|
// length array
|
||||||
|
int32_t int64Len[2] = {sizeof(int64_t)};
|
||||||
|
int32_t floatLen[2] = {sizeof(float)};
|
||||||
|
int32_t intLen[2] = {sizeof(int)};
|
||||||
|
|
||||||
|
params[0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP;
|
||||||
|
params[0].buffer_length = sizeof(int64_t);
|
||||||
|
params[0].buffer = ts;
|
||||||
|
params[0].length = int64Len;
|
||||||
|
params[0].is_null = is_null;
|
||||||
|
params[0].num = 2;
|
||||||
|
|
||||||
|
params[1].buffer_type = TSDB_DATA_TYPE_FLOAT;
|
||||||
|
params[1].buffer_length = sizeof(float);
|
||||||
|
params[1].buffer = current;
|
||||||
|
params[1].length = floatLen;
|
||||||
|
params[1].is_null = is_null;
|
||||||
|
params[1].num = 2;
|
||||||
|
|
||||||
|
params[2].buffer_type = TSDB_DATA_TYPE_INT;
|
||||||
|
params[2].buffer_length = sizeof(int);
|
||||||
|
params[2].buffer = voltage;
|
||||||
|
params[2].length = intLen;
|
||||||
|
params[2].is_null = is_null;
|
||||||
|
params[2].num = 2;
|
||||||
|
|
||||||
|
params[3].buffer_type = TSDB_DATA_TYPE_FLOAT;
|
||||||
|
params[3].buffer_length = sizeof(float);
|
||||||
|
params[3].buffer = phase;
|
||||||
|
params[3].length = floatLen;
|
||||||
|
params[3].is_null = is_null;
|
||||||
|
params[3].num = 2;
|
||||||
|
|
||||||
|
code = taos_stmt_bind_param_batch(stmt, params); // bind batch
|
||||||
|
checkErrorCode(stmt, code, "failed to execute taos_stmt_bind_param_batch");
|
||||||
|
code = taos_stmt_add_batch(stmt); // add batch
|
||||||
|
checkErrorCode(stmt, code, "failed to execute taos_stmt_add_batch");
|
||||||
|
// execute
|
||||||
|
code = taos_stmt_execute(stmt);
|
||||||
|
checkErrorCode(stmt, code, "failed to execute taos_stmt_execute");
|
||||||
|
int affectedRows = taos_stmt_affected_rows(stmt);
|
||||||
|
printf("successfully inserted %d rows\n", affectedRows);
|
||||||
|
|
||||||
|
// close
|
||||||
|
taos_stmt_close(stmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(taoscTest, taos_stmt_test) {
|
||||||
|
TAOS *taos = taos_connect("localhost", "root", "taosdata", NULL, 6030);
|
||||||
|
if (taos == NULL) {
|
||||||
|
printf("failed to connect to server");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
// executeSQL(taos, "drop database if exists power");
|
||||||
|
// executeSQL(taos, "create database power");
|
||||||
|
executeSQL(taos, "use power");
|
||||||
|
// executeSQL(taos, "create stable meters (ts timestamp, current float, voltage int, phase float) tags (location binary(64), groupId int)");
|
||||||
|
insertData(taos);
|
||||||
|
taos_close(taos);
|
||||||
|
taos_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(taoscTest, taos_query_a_test) {
|
TEST_F(taoscTest, taos_query_a_test) {
|
||||||
char sql[1024] = {0};
|
char sql[1024] = {0};
|
||||||
int32_t code = 0;
|
int32_t code = 0;
|
||||||
|
|
Loading…
Reference in New Issue