From 6f3c6548cbe5b1635b8525db0fbf5b7b008dfa7e Mon Sep 17 00:00:00 2001 From: Pengrongkun Date: Wed, 13 Nov 2024 16:53:15 +0800 Subject: [PATCH 1/5] add geometry check during stmt_bind_param --- include/common/tdataformat.h | 1 + source/common/CMakeLists.txt | 1 + source/common/src/tdataformat.c | 65 +++++++++++++++-- source/libs/parser/src/parInsertStmt.c | 41 +++++++++-- source/libs/parser/src/parUtil.c | 30 ++++++++ tests/script/api/stmt2-geometry-test.c | 99 ++++++++++++++++++++++++++ 6 files changed, 226 insertions(+), 11 deletions(-) create mode 100644 tests/script/api/stmt2-geometry-test.c diff --git a/include/common/tdataformat.h b/include/common/tdataformat.h index 19f3e222d1..cc578fbee9 100644 --- a/include/common/tdataformat.h +++ b/include/common/tdataformat.h @@ -155,6 +155,7 @@ int32_t tDecodeTag(SDecoder *pDecoder, STag **ppTag); int32_t tTagToValArray(const STag *pTag, SArray **ppArray); void debugPrintSTag(STag *pTag, const char *tag, int32_t ln); // TODO: remove int32_t parseJsontoTagData(const char *json, SArray *pTagVals, STag **ppTag, void *pMsgBuf); +int32_t parseGeotoTagData(const char *g, SArray *pTagVals, SSchema *pTagSchema, unsigned char *output); // SColData ================================ typedef struct { diff --git a/source/common/CMakeLists.txt b/source/common/CMakeLists.txt index f10eb6a611..e9b8727ce8 100644 --- a/source/common/CMakeLists.txt +++ b/source/common/CMakeLists.txt @@ -49,6 +49,7 @@ target_link_libraries( PUBLIC os PUBLIC util INTERFACE api + PRIVATE geometry ) if(${BUILD_S3}) diff --git a/source/common/src/tdataformat.c b/source/common/src/tdataformat.c index e580ad33bd..7a6557fd28 100644 --- a/source/common/src/tdataformat.c +++ b/source/common/src/tdataformat.c @@ -15,6 +15,7 @@ #define _DEFAULT_SOURCE #include "tdataformat.h" +#include "geosWrapper.h" #include "tRealloc.h" #include "tdatablock.h" #include "tlog.h" @@ -3036,6 +3037,35 @@ _exit: return code; } +int32_t formatGeometry(SColData *pColData, int8_t *buf, int32_t lenght, int32_t buffMaxLen) { + int32_t code = 0; + unsigned char *output = NULL; + size_t size = 0; + uint8_t *g = NULL; + code = tRealloc(&g, lenght); + if (code) { + return code; + } + + (void)memcpy(g, buf, lenght); + code = doGeomFromText(g, &output, &size); + tFree(g); + + if (code != TSDB_CODE_SUCCESS) { + goto _exit; + } + if (size > buffMaxLen) { + code = TSDB_CODE_PAR_VALUE_TOO_LONG; + goto _exit; + } + + code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, output, size); + +_exit: + geosFreeBuffer(output); + return code; +} + int32_t tColDataAddValueByBind(SColData *pColData, TAOS_MULTI_BIND *pBind, int32_t buffMaxLen) { int32_t code = 0; @@ -3046,6 +3076,13 @@ int32_t tColDataAddValueByBind(SColData *pColData, TAOS_MULTI_BIND *pBind, int32 } if (IS_VAR_DATA_TYPE(pColData->type)) { // var-length data type + if (pColData->type == TSDB_DATA_TYPE_GEOMETRY) { + code = initCtxGeomFromText(); + if (code != TSDB_CODE_SUCCESS) { + uError("init geom from text failed, code:%d", code); + return code; + } + } for (int32_t i = 0; i < pBind->num; ++i) { if (pBind->is_null && pBind->is_null[i]) { if (pColData->cflag & COL_IS_KEY) { @@ -3055,11 +3092,15 @@ int32_t tColDataAddValueByBind(SColData *pColData, TAOS_MULTI_BIND *pBind, int32 code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0); if (code) goto _exit; } else if (pBind->length[i] > buffMaxLen) { - uError("var data length too big, len:%d, max:%d", pBind->length[i], buffMaxLen); - return TSDB_CODE_INVALID_PARA; + return TSDB_CODE_PAR_VALUE_TOO_LONG; } else { - code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE]( - pColData, (uint8_t *)pBind->buffer + pBind->buffer_length * i, pBind->length[i]); + if (pColData->type == TSDB_DATA_TYPE_GEOMETRY) { + code = formatGeometry(pColData, (uint8_t *)pBind->buffer + pBind->buffer_length * i, pBind->length[i], + buffMaxLen); + } else { + code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE]( + pColData, (uint8_t *)pBind->buffer + pBind->buffer_length * i, pBind->length[i]); + } } } } else { // fixed-length data type @@ -3119,6 +3160,13 @@ int32_t tColDataAddValueByBind2(SColData *pColData, TAOS_STMT2_BIND *pBind, int3 if (IS_VAR_DATA_TYPE(pColData->type)) { // var-length data type uint8_t *buf = pBind->buffer; + if (pColData->type == TSDB_DATA_TYPE_GEOMETRY) { + code = initCtxGeomFromText(); + if (code != TSDB_CODE_SUCCESS) { + uError("init geom from text failed, code:%d", code); + return code; + } + } for (int32_t i = 0; i < pBind->num; ++i) { if (pBind->is_null && pBind->is_null[i]) { if (pColData->cflag & COL_IS_KEY) { @@ -3133,10 +3181,13 @@ int32_t tColDataAddValueByBind2(SColData *pColData, TAOS_STMT2_BIND *pBind, int3 if (code) goto _exit; } } else if (pBind->length[i] > buffMaxLen) { - uError("var data length too big, len:%d, max:%d", pBind->length[i], buffMaxLen); - return TSDB_CODE_INVALID_PARA; + return TSDB_CODE_PAR_VALUE_TOO_LONG; } else { - code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, buf, pBind->length[i]); + if (pColData->type == TSDB_DATA_TYPE_GEOMETRY) { + code = formatGeometry(pColData, buf, pBind->length[i], buffMaxLen); + } else { + code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, buf, pBind->length[i]); + } buf += pBind->length[i]; } } diff --git a/source/libs/parser/src/parInsertStmt.c b/source/libs/parser/src/parInsertStmt.c index 0979028e6d..9e78d53cc9 100644 --- a/source/libs/parser/src/parInsertStmt.c +++ b/source/libs/parser/src/parInsertStmt.c @@ -13,6 +13,7 @@ * along with this program. If not, see . */ +#include "geosWrapper.h" #include "os.h" #include "parInsertUtil.h" #include "parInt.h" @@ -187,11 +188,24 @@ int32_t qBindStmtTagsValue(void* pBlock, void* boundTags, int64_t suid, const ch if (code != TSDB_CODE_SUCCESS) { goto end; } + } else if (pTagSchema->type == TSDB_DATA_TYPE_GEOMETRY) { + char* tmp = taosMemoryCalloc(1, colLen); + if (!tmp) { + code = terrno; + goto end; + } + memcpy(tmp, bind[c].buffer, colLen); + unsigned char* out = NULL; + code = parseGeotoTagData(tmp, pTagArray, pTagSchema, out); + taosMemoryFree(tmp); + if (code != TSDB_CODE_SUCCESS) { + geosFreeBuffer(out); + goto end; + } } else { STagVal val = {.cid = pTagSchema->colId, .type = pTagSchema->type}; // strcpy(val.colName, pTagSchema->name); - if (pTagSchema->type == TSDB_DATA_TYPE_BINARY || pTagSchema->type == TSDB_DATA_TYPE_VARBINARY || - pTagSchema->type == TSDB_DATA_TYPE_GEOMETRY) { + if (pTagSchema->type == TSDB_DATA_TYPE_BINARY || pTagSchema->type == TSDB_DATA_TYPE_VARBINARY) { val.pData = (uint8_t*)bind[c].buffer; val.nData = colLen; } else if (pTagSchema->type == TSDB_DATA_TYPE_NCHAR) { @@ -251,6 +265,9 @@ end: if (p->type == TSDB_DATA_TYPE_NCHAR) { taosMemoryFreeClear(p->pData); } + if (p->type == TSDB_DATA_TYPE_GEOMETRY) { + geosFreeBuffer(p->pData); + } } taosArrayDestroy(pTagArray); taosArrayDestroy(tagName); @@ -539,11 +556,24 @@ int32_t qBindStmtTagsValue2(void* pBlock, void* boundTags, int64_t suid, const c if (code != TSDB_CODE_SUCCESS) { goto end; } + } else if (pTagSchema->type == TSDB_DATA_TYPE_GEOMETRY) { + char* tmp = taosMemoryCalloc(1, colLen); + if (!tmp) { + code = terrno; + goto end; + } + memcpy(tmp, bind[c].buffer, colLen); + unsigned char* out = NULL; + code = parseGeotoTagData(tmp, pTagArray, pTagSchema, out); + taosMemoryFree(tmp); + if (code != TSDB_CODE_SUCCESS) { + geosFreeBuffer(out); + goto end; + } } else { STagVal val = {.cid = pTagSchema->colId, .type = pTagSchema->type}; // strcpy(val.colName, pTagSchema->name); - if (pTagSchema->type == TSDB_DATA_TYPE_BINARY || pTagSchema->type == TSDB_DATA_TYPE_VARBINARY || - pTagSchema->type == TSDB_DATA_TYPE_GEOMETRY) { + if (pTagSchema->type == TSDB_DATA_TYPE_BINARY || pTagSchema->type == TSDB_DATA_TYPE_VARBINARY) { val.pData = (uint8_t*)bind[c].buffer; val.nData = colLen; } else if (pTagSchema->type == TSDB_DATA_TYPE_NCHAR) { @@ -603,6 +633,9 @@ end: if (p->type == TSDB_DATA_TYPE_NCHAR) { taosMemoryFreeClear(p->pData); } + if (p->type == TSDB_DATA_TYPE_GEOMETRY) { + geosFreeBuffer(p->pData); + } } taosArrayDestroy(pTagArray); taosArrayDestroy(tagName); diff --git a/source/libs/parser/src/parUtil.c b/source/libs/parser/src/parUtil.c index e35eea9e72..fc6ed0d7b0 100644 --- a/source/libs/parser/src/parUtil.c +++ b/source/libs/parser/src/parUtil.c @@ -15,6 +15,7 @@ #include "parUtil.h" #include "cJSON.h" +#include "geosWrapper.h" #include "querynodes.h" #include "tarray.h" #include "tlog.h" @@ -518,6 +519,35 @@ end: return retCode; } +int32_t parseGeotoTagData(const char* g, SArray* pTagVals, SSchema* pTagSchema, unsigned char* output) { + int32_t code = 0; + size_t size = 0; + STagVal val = {.cid = pTagSchema->colId, .type = pTagSchema->type}; + code = initCtxGeomFromText(); + if (code != TSDB_CODE_SUCCESS) { + goto end; + } + code = doGeomFromText(g, &output, &size); + if (code != TSDB_CODE_SUCCESS) { + goto end; + } + if (size > pTagSchema->bytes) { + code = TSDB_CODE_PAR_VALUE_TOO_LONG; + goto end; + } + + val.pData = (uint8_t*)output; + val.nData = (uint32_t)size; + + if (NULL == taosArrayPush(pTagVals, &val)) { + code = terrno; + goto end; + } + +end: + return code; +} + static int32_t getInsTagsTableTargetNameFromOp(int32_t acctId, SOperatorNode* pOper, SName* pName) { if (OP_TYPE_EQUAL != pOper->opType) { return TSDB_CODE_SUCCESS; diff --git a/tests/script/api/stmt2-geometry-test.c b/tests/script/api/stmt2-geometry-test.c new file mode 100644 index 0000000000..bb53e6e42b --- /dev/null +++ b/tests/script/api/stmt2-geometry-test.c @@ -0,0 +1,99 @@ +#include +#include +#include +#include "taos.h" + +void do_query(TAOS* taos, const char* sql) { + printf("[sql]%s\n", sql); + TAOS_RES* result = taos_query(taos, sql); + int code = taos_errno(result); + if (code) { + printf(" failed to query: %s, reason:%s\n", sql, taos_errstr(result)); + taos_free_result(result); + return; + } + taos_free_result(result); +} + +void execute_test(TAOS* taos, const char* tbname, const char* tag2, const char* col2, const char* case_desc) { + // prepare stmt + TAOS_STMT2_OPTION option = {0, true, false, NULL, NULL}; + TAOS_STMT2* stmt = taos_stmt2_init(taos, &option); + const char* sql; + if (tbname == "tb4") { + sql = "insert into db.? using db.stb2 tags(?, ?) values(?,?)"; + } else { + sql = "insert into db.? using db.stb tags(?, ?) values(?,?)"; + } + int code = taos_stmt2_prepare(stmt, sql, 0); + printf("\n%s\n insert into db.? using db.stb tags(?, ?) values(?,?)\n bind_tag : %s, bind_col : %s\n", case_desc, + tag2, col2); + if (code != 0) { + printf(" failed to execute taos_stmt2_prepare. error:%s\n", taos_stmt2_error(stmt)); + taos_stmt2_close(stmt); + return; + } + + // prepare data + int t1_val = 0; + int64_t ts = 1591060628000; + int32_t length[5] = {sizeof(int), 2, sizeof(int64_t), (int32_t)strlen(tag2), (int32_t)strlen(col2)}; + TAOS_STMT2_BIND tags[2] = {{TSDB_DATA_TYPE_INT, &t1_val, &length[0], NULL, 1}, + {TSDB_DATA_TYPE_GEOMETRY, (void*)tag2, &length[3], NULL, 1}}; + TAOS_STMT2_BIND params[2] = {{TSDB_DATA_TYPE_TIMESTAMP, &ts, &length[2], NULL, 1}, + {TSDB_DATA_TYPE_GEOMETRY, (void*)col2, &length[4], NULL, 1}}; + TAOS_STMT2_BIND* tagv[1] = {&tags[0]}; + TAOS_STMT2_BIND* paramv[1] = {¶ms[0]}; + + TAOS_STMT2_BINDV bindv = {1, &tbname, &tagv[0], ¶mv[0]}; + code = taos_stmt2_bind_param(stmt, &bindv, -1); + if (code != 0) { + printf(" failed to bind param. error:%s\n", taos_stmt2_error(stmt)); + taos_stmt2_close(stmt); + return; + } + + if (taos_stmt2_exec(stmt, NULL)) { + printf(" failed to execute insert statement.error:%s\n", taos_stmt2_error(stmt)); + taos_stmt2_close(stmt); + return; + } + printf("[ok]\n"); + + taos_stmt2_close(stmt); +} + +void test1(TAOS* taos) { + execute_test(taos, "tb1", "POINT(1.0 1.0)", "LINESTRING(1.0 1.0, 2.0 2.0, 3.0 3.0)", "[normal]case 1"); +} + +void test2(TAOS* taos) { + execute_test(taos, "tb2", "hello", "LINESTRING(1.0 1.0, 2.0 2.0, 3.0 3.0)", "[wrong tag]case 2"); +} + +void test3(TAOS* taos) { execute_test(taos, "tb3", "POLYGON((0 0, 4 0, 4 4, 0 4, 0 0))", "1", "[wrong col]case 3"); } + +void test4(TAOS* taos) { + execute_test(taos, "tb4", "POLYGON((0 0, 4 0, 4 4, 0 4, 0 0))", "POINT(1.0 1.0)", "[wrong size]case 4"); +} + +int main() { + TAOS* taos = taos_connect("localhost", "root", "taosdata", "", 0); + if (!taos) { + printf("failed to connect to db, reason:%s\n", taos_errstr(taos)); + exit(1); + } + // init test db & stb table + do_query(taos, "drop database if exists db"); + do_query(taos, "create database db"); + do_query(taos, "create table db.stb (ts timestamp, b geometry(100)) tags(t1 int, t2 geometry(100))"); + do_query(taos, "create table db.stb2 (ts timestamp, b geometry(100)) tags(t1 int, t2 geometry(10))"); + + test1(taos); + test2(taos); + test3(taos); + test4(taos); + + taos_close(taos); + taos_cleanup(); +} From 8d5508a7a60b3f2bfd410b37218c927ba51b5ada Mon Sep 17 00:00:00 2001 From: Pengrongkun Date: Fri, 15 Nov 2024 12:26:36 +0800 Subject: [PATCH 2/5] fix compile problem --- include/common/tdataformat.h | 9 ++-- source/common/CMakeLists.txt | 1 - source/common/src/tdataformat.c | 71 ++++++++------------------ source/libs/parser/src/parInsertStmt.c | 49 +++++++++++++++--- tests/script/api/stmt2-geometry-test.c | 40 +++++++++------ 5 files changed, 92 insertions(+), 78 deletions(-) diff --git a/include/common/tdataformat.h b/include/common/tdataformat.h index cc578fbee9..4d289b6780 100644 --- a/include/common/tdataformat.h +++ b/include/common/tdataformat.h @@ -57,9 +57,9 @@ const static uint8_t BIT2_MAP[4] = {0b11111100, 0b11110011, 0b11001111, 0b001111 #define ONE ((uint8_t)1) #define THREE ((uint8_t)3) #define DIV_8(i) ((i) >> 3) -#define MOD_8(i) ((i)&7) +#define MOD_8(i) ((i) & 7) #define DIV_4(i) ((i) >> 2) -#define MOD_4(i) ((i)&3) +#define MOD_4(i) ((i) & 3) #define MOD_4_TIME_2(i) (MOD_4(i) << 1) #define BIT1_SIZE(n) (DIV_8((n)-1) + 1) #define BIT2_SIZE(n) (DIV_4((n)-1) + 1) @@ -174,6 +174,7 @@ typedef struct { } SColDataCompressInfo; typedef void *(*xMallocFn)(void *, int32_t); +typedef int32_t (*formatGeometryFn)(char *geoStr, int32_t lenght, int32_t buffMaxLen, char **out, int32_t *size); void tColDataDestroy(void *ph); void tColDataInit(SColData *pColData, int16_t cid, int8_t type, int8_t cflag); @@ -192,7 +193,7 @@ int32_t tColDataCompress(SColData *colData, SColDataCompressInfo *info, SBuffer int32_t tColDataDecompress(void *input, SColDataCompressInfo *info, SColData *colData, SBuffer *assist); // for stmt bind -int32_t tColDataAddValueByBind(SColData *pColData, TAOS_MULTI_BIND *pBind, int32_t buffMaxLen); +int32_t tColDataAddValueByBind(SColData *pColData, TAOS_MULTI_BIND *pBind, int32_t buffMaxLen, formatGeometryFn fg); int32_t tColDataSortMerge(SArray **arr); // for raw block @@ -379,7 +380,7 @@ int32_t tRowBuildFromBind(SBindInfo *infos, int32_t numOfInfos, bool infoSorted, SArray *rowArray); // stmt2 binding -int32_t tColDataAddValueByBind2(SColData *pColData, TAOS_STMT2_BIND *pBind, int32_t buffMaxLen); +int32_t tColDataAddValueByBind2(SColData *pColData, TAOS_STMT2_BIND *pBind, int32_t buffMaxLen, formatGeometryFn fg); typedef struct { int32_t columnId; diff --git a/source/common/CMakeLists.txt b/source/common/CMakeLists.txt index e9b8727ce8..f10eb6a611 100644 --- a/source/common/CMakeLists.txt +++ b/source/common/CMakeLists.txt @@ -49,7 +49,6 @@ target_link_libraries( PUBLIC os PUBLIC util INTERFACE api - PRIVATE geometry ) if(${BUILD_S3}) diff --git a/source/common/src/tdataformat.c b/source/common/src/tdataformat.c index 7a6557fd28..81651517cd 100644 --- a/source/common/src/tdataformat.c +++ b/source/common/src/tdataformat.c @@ -15,7 +15,6 @@ #define _DEFAULT_SOURCE #include "tdataformat.h" -#include "geosWrapper.h" #include "tRealloc.h" #include "tdatablock.h" #include "tlog.h" @@ -3037,36 +3036,7 @@ _exit: return code; } -int32_t formatGeometry(SColData *pColData, int8_t *buf, int32_t lenght, int32_t buffMaxLen) { - int32_t code = 0; - unsigned char *output = NULL; - size_t size = 0; - uint8_t *g = NULL; - code = tRealloc(&g, lenght); - if (code) { - return code; - } - - (void)memcpy(g, buf, lenght); - code = doGeomFromText(g, &output, &size); - tFree(g); - - if (code != TSDB_CODE_SUCCESS) { - goto _exit; - } - if (size > buffMaxLen) { - code = TSDB_CODE_PAR_VALUE_TOO_LONG; - goto _exit; - } - - code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, output, size); - -_exit: - geosFreeBuffer(output); - return code; -} - -int32_t tColDataAddValueByBind(SColData *pColData, TAOS_MULTI_BIND *pBind, int32_t buffMaxLen) { +int32_t tColDataAddValueByBind(SColData *pColData, TAOS_MULTI_BIND *pBind, int32_t buffMaxLen, formatGeometryFn fg) { int32_t code = 0; if (!(pBind->num == 1 && pBind->is_null && *pBind->is_null)) { @@ -3076,13 +3046,6 @@ int32_t tColDataAddValueByBind(SColData *pColData, TAOS_MULTI_BIND *pBind, int32 } if (IS_VAR_DATA_TYPE(pColData->type)) { // var-length data type - if (pColData->type == TSDB_DATA_TYPE_GEOMETRY) { - code = initCtxGeomFromText(); - if (code != TSDB_CODE_SUCCESS) { - uError("init geom from text failed, code:%d", code); - return code; - } - } for (int32_t i = 0; i < pBind->num; ++i) { if (pBind->is_null && pBind->is_null[i]) { if (pColData->cflag & COL_IS_KEY) { @@ -3095,8 +3058,16 @@ int32_t tColDataAddValueByBind(SColData *pColData, TAOS_MULTI_BIND *pBind, int32 return TSDB_CODE_PAR_VALUE_TOO_LONG; } else { if (pColData->type == TSDB_DATA_TYPE_GEOMETRY) { - code = formatGeometry(pColData, (uint8_t *)pBind->buffer + pBind->buffer_length * i, pBind->length[i], - buffMaxLen); + int32_t size = 0; + char *out = NULL; + code = fg((char *)pBind->buffer + pBind->buffer_length * i, pBind->length[i], buffMaxLen, &out, &size); + if (code) { + taosMemoryFree(out); + goto _exit; + } + + code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, out, size); + taosMemoryFree(out); } else { code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE]( pColData, (uint8_t *)pBind->buffer + pBind->buffer_length * i, pBind->length[i]); @@ -3149,7 +3120,7 @@ _exit: return code; } -int32_t tColDataAddValueByBind2(SColData *pColData, TAOS_STMT2_BIND *pBind, int32_t buffMaxLen) { +int32_t tColDataAddValueByBind2(SColData *pColData, TAOS_STMT2_BIND *pBind, int32_t buffMaxLen, formatGeometryFn fg) { int32_t code = 0; if (!(pBind->num == 1 && pBind->is_null && *pBind->is_null)) { @@ -3160,13 +3131,6 @@ int32_t tColDataAddValueByBind2(SColData *pColData, TAOS_STMT2_BIND *pBind, int3 if (IS_VAR_DATA_TYPE(pColData->type)) { // var-length data type uint8_t *buf = pBind->buffer; - if (pColData->type == TSDB_DATA_TYPE_GEOMETRY) { - code = initCtxGeomFromText(); - if (code != TSDB_CODE_SUCCESS) { - uError("init geom from text failed, code:%d", code); - return code; - } - } for (int32_t i = 0; i < pBind->num; ++i) { if (pBind->is_null && pBind->is_null[i]) { if (pColData->cflag & COL_IS_KEY) { @@ -3184,7 +3148,16 @@ int32_t tColDataAddValueByBind2(SColData *pColData, TAOS_STMT2_BIND *pBind, int3 return TSDB_CODE_PAR_VALUE_TOO_LONG; } else { if (pColData->type == TSDB_DATA_TYPE_GEOMETRY) { - code = formatGeometry(pColData, buf, pBind->length[i], buffMaxLen); + int32_t size = 0; + char *out = NULL; + code = fg((char *)buf, pBind->length[i], buffMaxLen, &out, &size); + if (code) { + taosMemoryFree(out); + goto _exit; + } + + code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, out, size); + taosMemoryFree(out); } else { code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, buf, pBind->length[i]); } diff --git a/source/libs/parser/src/parInsertStmt.c b/source/libs/parser/src/parInsertStmt.c index 9e78d53cc9..819f47180f 100644 --- a/source/libs/parser/src/parInsertStmt.c +++ b/source/libs/parser/src/parInsertStmt.c @@ -321,6 +321,39 @@ int32_t convertStmtNcharCol(SMsgBuf* pMsgBuf, SSchema* pSchema, TAOS_MULTI_BIND* return TSDB_CODE_SUCCESS; } +int32_t formatGeometry(char* geoStr, int32_t lenght, int32_t buffMaxLen, char** out, int32_t* size) { + int32_t code = 0; + unsigned char* output = NULL; + char* tmp = NULL; + code = initCtxGeomFromText(); + if (code != TSDB_CODE_SUCCESS) { + uError("init geom from text failed, code:%d", code); + return code; + } + + code = doGeomFromText(geoStr, &output, (size_t*)size); + + if (code != TSDB_CODE_SUCCESS) { + goto _exit; + } + if (*size > buffMaxLen) { + code = TSDB_CODE_PAR_VALUE_TOO_LONG; + goto _exit; + } + + tmp = taosMemoryCalloc(1, *size); + if (NULL == tmp) { + code = terrno; + goto _exit; + } + memcpy(tmp, output, *size); + *out = tmp; + +_exit: + geosFreeBuffer(output); + return code; +} + int32_t qBindStmtStbColsValue(void* pBlock, SArray* pCols, TAOS_MULTI_BIND* bind, char* msgBuf, int32_t msgBufLen, STSchema** pTSchema, SBindInfo* pBindInfos) { STableDataCxt* pDataBlock = (STableDataCxt*)pBlock; @@ -425,8 +458,8 @@ int32_t qBindStmtColsValue(void* pBlock, SArray* pCols, TAOS_MULTI_BIND* bind, c pBind = bind + c; } - code = tColDataAddValueByBind(pCol, pBind, - IS_VAR_DATA_TYPE(pColSchema->type) ? pColSchema->bytes - VARSTR_HEADER_SIZE : -1); + code = tColDataAddValueByBind( + pCol, pBind, IS_VAR_DATA_TYPE(pColSchema->type) ? pColSchema->bytes - VARSTR_HEADER_SIZE : -1, formatGeometry); if (code) { goto _return; } @@ -477,8 +510,8 @@ int32_t qBindStmtSingleColValue(void* pBlock, SArray* pCols, TAOS_MULTI_BIND* bi pBind = bind; } - code = tColDataAddValueByBind(pCol, pBind, - IS_VAR_DATA_TYPE(pColSchema->type) ? pColSchema->bytes - VARSTR_HEADER_SIZE : -1); + code = tColDataAddValueByBind( + pCol, pBind, IS_VAR_DATA_TYPE(pColSchema->type) ? pColSchema->bytes - VARSTR_HEADER_SIZE : -1, formatGeometry); qDebug("stmt col %d bind %d rows data", colIdx, rowNum); @@ -856,8 +889,8 @@ int32_t qBindStmtColsValue2(void* pBlock, SArray* pCols, TAOS_STMT2_BIND* bind, pBind = bind + c; } - code = tColDataAddValueByBind2(pCol, pBind, - IS_VAR_DATA_TYPE(pColSchema->type) ? pColSchema->bytes - VARSTR_HEADER_SIZE : -1); + code = tColDataAddValueByBind2( + pCol, pBind, IS_VAR_DATA_TYPE(pColSchema->type) ? pColSchema->bytes - VARSTR_HEADER_SIZE : -1, formatGeometry); if (code) { goto _return; } @@ -908,8 +941,8 @@ int32_t qBindStmtSingleColValue2(void* pBlock, SArray* pCols, TAOS_STMT2_BIND* b pBind = bind; } - code = tColDataAddValueByBind2(pCol, pBind, - IS_VAR_DATA_TYPE(pColSchema->type) ? pColSchema->bytes - VARSTR_HEADER_SIZE : -1); + code = tColDataAddValueByBind2( + pCol, pBind, IS_VAR_DATA_TYPE(pColSchema->type) ? pColSchema->bytes - VARSTR_HEADER_SIZE : -1, formatGeometry); qDebug("stmt col %d bind %d rows data", colIdx, rowNum); diff --git a/tests/script/api/stmt2-geometry-test.c b/tests/script/api/stmt2-geometry-test.c index bb53e6e42b..e1af5879eb 100644 --- a/tests/script/api/stmt2-geometry-test.c +++ b/tests/script/api/stmt2-geometry-test.c @@ -15,12 +15,13 @@ void do_query(TAOS* taos, const char* sql) { taos_free_result(result); } -void execute_test(TAOS* taos, const char* tbname, const char* tag2, const char* col2, const char* case_desc) { +void execute_test(TAOS* taos, const char* tbname1, const char* tbname2, const char* tag2, const char* col2, + const char* case_desc) { // prepare stmt TAOS_STMT2_OPTION option = {0, true, false, NULL, NULL}; TAOS_STMT2* stmt = taos_stmt2_init(taos, &option); const char* sql; - if (tbname == "tb4") { + if (tbname1 == "tb41") { sql = "insert into db.? using db.stb2 tags(?, ?) values(?,?)"; } else { sql = "insert into db.? using db.stb tags(?, ?) values(?,?)"; @@ -35,17 +36,22 @@ void execute_test(TAOS* taos, const char* tbname, const char* tag2, const char* } // prepare data - int t1_val = 0; - int64_t ts = 1591060628000; - int32_t length[5] = {sizeof(int), 2, sizeof(int64_t), (int32_t)strlen(tag2), (int32_t)strlen(col2)}; - TAOS_STMT2_BIND tags[2] = {{TSDB_DATA_TYPE_INT, &t1_val, &length[0], NULL, 1}, - {TSDB_DATA_TYPE_GEOMETRY, (void*)tag2, &length[3], NULL, 1}}; - TAOS_STMT2_BIND params[2] = {{TSDB_DATA_TYPE_TIMESTAMP, &ts, &length[2], NULL, 1}, - {TSDB_DATA_TYPE_GEOMETRY, (void*)col2, &length[4], NULL, 1}}; - TAOS_STMT2_BIND* tagv[1] = {&tags[0]}; - TAOS_STMT2_BIND* paramv[1] = {¶ms[0]}; + int t1_val = 0; + int64_t ts = 1591060628000; + const char* tbname[2] = {tbname1, tbname2}; + int32_t length[5] = {sizeof(int), 2, sizeof(int64_t), (int32_t)strlen(tag2), (int32_t)strlen(col2)}; + TAOS_STMT2_BIND tags[2][2] = { + {{TSDB_DATA_TYPE_INT, &t1_val, &length[0], NULL, 2}, {TSDB_DATA_TYPE_GEOMETRY, (void*)tag2, &length[3], NULL, 2}}, + {{TSDB_DATA_TYPE_INT, &t1_val, &length[0], NULL, 2}, + {TSDB_DATA_TYPE_GEOMETRY, (void*)tag2, &length[3], NULL, 2}}}; + TAOS_STMT2_BIND params[2][2] = {{{TSDB_DATA_TYPE_TIMESTAMP, &ts, &length[2], NULL, 1}, + {TSDB_DATA_TYPE_GEOMETRY, (void*)col2, &length[4], NULL, 1}}, + {{TSDB_DATA_TYPE_TIMESTAMP, &ts, &length[2], NULL, 1}, + {TSDB_DATA_TYPE_GEOMETRY, (void*)col2, &length[4], NULL, 1}}}; + 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 = {1, &tbname, &tagv[0], ¶mv[0]}; + TAOS_STMT2_BINDV bindv = {2, &tbname[0], &tagv[0], ¶mv[0]}; code = taos_stmt2_bind_param(stmt, &bindv, -1); if (code != 0) { printf(" failed to bind param. error:%s\n", taos_stmt2_error(stmt)); @@ -64,17 +70,19 @@ void execute_test(TAOS* taos, const char* tbname, const char* tag2, const char* } void test1(TAOS* taos) { - execute_test(taos, "tb1", "POINT(1.0 1.0)", "LINESTRING(1.0 1.0, 2.0 2.0, 3.0 3.0)", "[normal]case 1"); + execute_test(taos, "tb11", "tb12", "POINT(1.0 1.0)", "LINESTRING(1.0 1.0, 2.0 2.0, 3.0 3.0)", "[normal]case 1"); } void test2(TAOS* taos) { - execute_test(taos, "tb2", "hello", "LINESTRING(1.0 1.0, 2.0 2.0, 3.0 3.0)", "[wrong tag]case 2"); + execute_test(taos, "tb21", "tb22", "hello", "LINESTRING(1.0 1.0, 2.0 2.0, 3.0 3.0)", "[wrong tag]case 2"); } -void test3(TAOS* taos) { execute_test(taos, "tb3", "POLYGON((0 0, 4 0, 4 4, 0 4, 0 0))", "1", "[wrong col]case 3"); } +void test3(TAOS* taos) { + execute_test(taos, "tb31", "tb32", "POLYGON((0 0, 4 0, 4 4, 0 4, 0 0))", "1", "[wrong col]case 3"); +} void test4(TAOS* taos) { - execute_test(taos, "tb4", "POLYGON((0 0, 4 0, 4 4, 0 4, 0 0))", "POINT(1.0 1.0)", "[wrong size]case 4"); + execute_test(taos, "tb41", "tb42", "POLYGON((0 0, 4 0, 4 4, 0 4, 0 0))", "POINT(1.0 1.0)", "[wrong size]case 4"); } int main() { From a774d3b428dc277a3960981f609b5a0285f7d731 Mon Sep 17 00:00:00 2001 From: Pengrongkun Date: Sat, 16 Nov 2024 09:27:52 +0800 Subject: [PATCH 3/5] fix some review problem --- include/common/tdataformat.h | 2 +- source/libs/parser/src/parInsertStmt.c | 28 ++------------------------ source/libs/parser/src/parUtil.c | 12 ++++++----- 3 files changed, 10 insertions(+), 32 deletions(-) diff --git a/include/common/tdataformat.h b/include/common/tdataformat.h index 4d289b6780..c0b899b6aa 100644 --- a/include/common/tdataformat.h +++ b/include/common/tdataformat.h @@ -155,7 +155,7 @@ int32_t tDecodeTag(SDecoder *pDecoder, STag **ppTag); int32_t tTagToValArray(const STag *pTag, SArray **ppArray); void debugPrintSTag(STag *pTag, const char *tag, int32_t ln); // TODO: remove int32_t parseJsontoTagData(const char *json, SArray *pTagVals, STag **ppTag, void *pMsgBuf); -int32_t parseGeotoTagData(const char *g, SArray *pTagVals, SSchema *pTagSchema, unsigned char *output); +int32_t parseGeotoTagData(const char *g, SArray *pTagVals, SSchema *pTagSchema); // SColData ================================ typedef struct { diff --git a/source/libs/parser/src/parInsertStmt.c b/source/libs/parser/src/parInsertStmt.c index 819f47180f..8715d1d3ec 100644 --- a/source/libs/parser/src/parInsertStmt.c +++ b/source/libs/parser/src/parInsertStmt.c @@ -189,19 +189,7 @@ int32_t qBindStmtTagsValue(void* pBlock, void* boundTags, int64_t suid, const ch goto end; } } else if (pTagSchema->type == TSDB_DATA_TYPE_GEOMETRY) { - char* tmp = taosMemoryCalloc(1, colLen); - if (!tmp) { - code = terrno; - goto end; - } - memcpy(tmp, bind[c].buffer, colLen); - unsigned char* out = NULL; - code = parseGeotoTagData(tmp, pTagArray, pTagSchema, out); - taosMemoryFree(tmp); - if (code != TSDB_CODE_SUCCESS) { - geosFreeBuffer(out); - goto end; - } + code = parseGeotoTagData(bind[c].buffer, pTagArray, pTagSchema); } else { STagVal val = {.cid = pTagSchema->colId, .type = pTagSchema->type}; // strcpy(val.colName, pTagSchema->name); @@ -590,19 +578,7 @@ int32_t qBindStmtTagsValue2(void* pBlock, void* boundTags, int64_t suid, const c goto end; } } else if (pTagSchema->type == TSDB_DATA_TYPE_GEOMETRY) { - char* tmp = taosMemoryCalloc(1, colLen); - if (!tmp) { - code = terrno; - goto end; - } - memcpy(tmp, bind[c].buffer, colLen); - unsigned char* out = NULL; - code = parseGeotoTagData(tmp, pTagArray, pTagSchema, out); - taosMemoryFree(tmp); - if (code != TSDB_CODE_SUCCESS) { - geosFreeBuffer(out); - goto end; - } + code = parseGeotoTagData(bind[c].buffer, pTagArray, pTagSchema); } else { STagVal val = {.cid = pTagSchema->colId, .type = pTagSchema->type}; // strcpy(val.colName, pTagSchema->name); diff --git a/source/libs/parser/src/parUtil.c b/source/libs/parser/src/parUtil.c index fc6ed0d7b0..33b36c98fb 100644 --- a/source/libs/parser/src/parUtil.c +++ b/source/libs/parser/src/parUtil.c @@ -519,13 +519,14 @@ end: return retCode; } -int32_t parseGeotoTagData(const char* g, SArray* pTagVals, SSchema* pTagSchema, unsigned char* output) { - int32_t code = 0; - size_t size = 0; - STagVal val = {.cid = pTagSchema->colId, .type = pTagSchema->type}; +int32_t parseGeotoTagData(const char* g, SArray* pTagVals, SSchema* pTagSchema) { + int32_t code = 0; + size_t size = 0; + unsigned char* output = NULL; + STagVal val = {.cid = pTagSchema->colId, .type = pTagSchema->type}; code = initCtxGeomFromText(); if (code != TSDB_CODE_SUCCESS) { - goto end; + return code; } code = doGeomFromText(g, &output, &size); if (code != TSDB_CODE_SUCCESS) { @@ -541,6 +542,7 @@ int32_t parseGeotoTagData(const char* g, SArray* pTagVals, SSchema* pTagSchema, if (NULL == taosArrayPush(pTagVals, &val)) { code = terrno; + geosFreeBuffer(output); goto end; } From ff2d0e6d67faeabf59d4d98626ec1966ef92d3ef Mon Sep 17 00:00:00 2001 From: Pengrongkun Date: Mon, 18 Nov 2024 20:55:51 +0800 Subject: [PATCH 4/5] fix CI problem --- .../node/websocketexample/all_type_stmt.js | 4 +- include/common/tdataformat.h | 3 +- source/common/src/tdataformat.c | 32 ++------- source/libs/parser/src/parInsertStmt.c | 72 +++++++------------ source/libs/parser/src/parUtil.c | 32 --------- tests/script/api/stmt2-geometry-test.c | 43 +++++------ 6 files changed, 59 insertions(+), 127 deletions(-) mode change 100644 => 100755 docs/examples/node/websocketexample/all_type_stmt.js diff --git a/docs/examples/node/websocketexample/all_type_stmt.js b/docs/examples/node/websocketexample/all_type_stmt.js old mode 100644 new mode 100755 index f095bee090..2297923e75 --- a/docs/examples/node/websocketexample/all_type_stmt.js +++ b/docs/examples/node/websocketexample/all_type_stmt.js @@ -95,8 +95,8 @@ async function all_type_example() { tagParams.setBoolean([true]); tagParams.setVarchar(["hello"]); tagParams.setNchar(["stmt"]); - tagParams.setGeometry([geometryData]); tagParams.setVarBinary([vbData]); + tagParams.setGeometry([geometryData]); await stmt.setTags(tagParams); @@ -108,8 +108,8 @@ async function all_type_example() { bindParams.setBoolean([true]); bindParams.setVarchar(["hello"]); bindParams.setNchar(["stmt"]); - bindParams.setGeometry([geometryData]); bindParams.setVarBinary([vbData]); + bindParams.setGeometry([geometryData]); await stmt.bind(bindParams); await stmt.batch(); diff --git a/include/common/tdataformat.h b/include/common/tdataformat.h index c0b899b6aa..f71459d6aa 100644 --- a/include/common/tdataformat.h +++ b/include/common/tdataformat.h @@ -155,7 +155,6 @@ int32_t tDecodeTag(SDecoder *pDecoder, STag **ppTag); int32_t tTagToValArray(const STag *pTag, SArray **ppArray); void debugPrintSTag(STag *pTag, const char *tag, int32_t ln); // TODO: remove int32_t parseJsontoTagData(const char *json, SArray *pTagVals, STag **ppTag, void *pMsgBuf); -int32_t parseGeotoTagData(const char *g, SArray *pTagVals, SSchema *pTagSchema); // SColData ================================ typedef struct { @@ -174,7 +173,7 @@ typedef struct { } SColDataCompressInfo; typedef void *(*xMallocFn)(void *, int32_t); -typedef int32_t (*formatGeometryFn)(char *geoStr, int32_t lenght, int32_t buffMaxLen, char **out, int32_t *size); +typedef int32_t (*formatGeometryFn)(char *geoWKB, size_t nGeom); void tColDataDestroy(void *ph); void tColDataInit(SColData *pColData, int16_t cid, int8_t type, int8_t cflag); diff --git a/source/common/src/tdataformat.c b/source/common/src/tdataformat.c index 81651517cd..23986b265d 100644 --- a/source/common/src/tdataformat.c +++ b/source/common/src/tdataformat.c @@ -3058,20 +3058,11 @@ int32_t tColDataAddValueByBind(SColData *pColData, TAOS_MULTI_BIND *pBind, int32 return TSDB_CODE_PAR_VALUE_TOO_LONG; } else { if (pColData->type == TSDB_DATA_TYPE_GEOMETRY) { - int32_t size = 0; - char *out = NULL; - code = fg((char *)pBind->buffer + pBind->buffer_length * i, pBind->length[i], buffMaxLen, &out, &size); - if (code) { - taosMemoryFree(out); - goto _exit; - } - - code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, out, size); - taosMemoryFree(out); - } else { - code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE]( - pColData, (uint8_t *)pBind->buffer + pBind->buffer_length * i, pBind->length[i]); + code = fg((char *)pBind->buffer + pBind->buffer_length * i, (size_t)pBind->length[i]); + if (code) goto _exit; } + code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE]( + pColData, (uint8_t *)pBind->buffer + pBind->buffer_length * i, pBind->length[i]); } } } else { // fixed-length data type @@ -3148,19 +3139,10 @@ int32_t tColDataAddValueByBind2(SColData *pColData, TAOS_STMT2_BIND *pBind, int3 return TSDB_CODE_PAR_VALUE_TOO_LONG; } else { if (pColData->type == TSDB_DATA_TYPE_GEOMETRY) { - int32_t size = 0; - char *out = NULL; - code = fg((char *)buf, pBind->length[i], buffMaxLen, &out, &size); - if (code) { - taosMemoryFree(out); - goto _exit; - } - - code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, out, size); - taosMemoryFree(out); - } else { - code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, buf, pBind->length[i]); + code = fg(buf, pBind->length[i]); + if (code) goto _exit; } + code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, buf, pBind->length[i]); buf += pBind->length[i]; } } diff --git a/source/libs/parser/src/parInsertStmt.c b/source/libs/parser/src/parInsertStmt.c index 8715d1d3ec..b515f9df9d 100644 --- a/source/libs/parser/src/parInsertStmt.c +++ b/source/libs/parser/src/parInsertStmt.c @@ -102,6 +102,21 @@ pStmt = (SVnodeModifyOpStmt*)pQuery->pRoot; } */ +int32_t formatGeometry(char* geoWKB, size_t nGeom) { + int32_t code = TSDB_CODE_SUCCESS; + char* outputWKT = NULL; + + if (TSDB_CODE_SUCCESS != (code = initCtxAsText()) || + TSDB_CODE_SUCCESS != (code = doAsText(geoWKB, nGeom, &outputWKT))) { + code = TSDB_CODE_INVALID_PARA; + goto _exit; + } + +_exit: + geosFreeBuffer(outputWKT); + return code; +} + int32_t qBuildStmtOutput(SQuery* pQuery, SHashObj* pVgHash, SHashObj* pBlockHash) { int32_t code = TSDB_CODE_SUCCESS; SArray* pVgDataBlocks = NULL; @@ -188,12 +203,15 @@ int32_t qBindStmtTagsValue(void* pBlock, void* boundTags, int64_t suid, const ch if (code != TSDB_CODE_SUCCESS) { goto end; } - } else if (pTagSchema->type == TSDB_DATA_TYPE_GEOMETRY) { - code = parseGeotoTagData(bind[c].buffer, pTagArray, pTagSchema); } else { STagVal val = {.cid = pTagSchema->colId, .type = pTagSchema->type}; // strcpy(val.colName, pTagSchema->name); - if (pTagSchema->type == TSDB_DATA_TYPE_BINARY || pTagSchema->type == TSDB_DATA_TYPE_VARBINARY) { + if (pTagSchema->type == TSDB_DATA_TYPE_BINARY || pTagSchema->type == TSDB_DATA_TYPE_VARBINARY || + pTagSchema->type == TSDB_DATA_TYPE_GEOMETRY) { + if (pTagSchema->type == TSDB_DATA_TYPE_GEOMETRY) { + code = formatGeometry(bind[c].buffer, colLen); + if (code != TSDB_CODE_SUCCESS) goto end; + } val.pData = (uint8_t*)bind[c].buffer; val.nData = colLen; } else if (pTagSchema->type == TSDB_DATA_TYPE_NCHAR) { @@ -253,9 +271,6 @@ end: if (p->type == TSDB_DATA_TYPE_NCHAR) { taosMemoryFreeClear(p->pData); } - if (p->type == TSDB_DATA_TYPE_GEOMETRY) { - geosFreeBuffer(p->pData); - } } taosArrayDestroy(pTagArray); taosArrayDestroy(tagName); @@ -309,39 +324,6 @@ int32_t convertStmtNcharCol(SMsgBuf* pMsgBuf, SSchema* pSchema, TAOS_MULTI_BIND* return TSDB_CODE_SUCCESS; } -int32_t formatGeometry(char* geoStr, int32_t lenght, int32_t buffMaxLen, char** out, int32_t* size) { - int32_t code = 0; - unsigned char* output = NULL; - char* tmp = NULL; - code = initCtxGeomFromText(); - if (code != TSDB_CODE_SUCCESS) { - uError("init geom from text failed, code:%d", code); - return code; - } - - code = doGeomFromText(geoStr, &output, (size_t*)size); - - if (code != TSDB_CODE_SUCCESS) { - goto _exit; - } - if (*size > buffMaxLen) { - code = TSDB_CODE_PAR_VALUE_TOO_LONG; - goto _exit; - } - - tmp = taosMemoryCalloc(1, *size); - if (NULL == tmp) { - code = terrno; - goto _exit; - } - memcpy(tmp, output, *size); - *out = tmp; - -_exit: - geosFreeBuffer(output); - return code; -} - int32_t qBindStmtStbColsValue(void* pBlock, SArray* pCols, TAOS_MULTI_BIND* bind, char* msgBuf, int32_t msgBufLen, STSchema** pTSchema, SBindInfo* pBindInfos) { STableDataCxt* pDataBlock = (STableDataCxt*)pBlock; @@ -577,12 +559,15 @@ int32_t qBindStmtTagsValue2(void* pBlock, void* boundTags, int64_t suid, const c if (code != TSDB_CODE_SUCCESS) { goto end; } - } else if (pTagSchema->type == TSDB_DATA_TYPE_GEOMETRY) { - code = parseGeotoTagData(bind[c].buffer, pTagArray, pTagSchema); } else { STagVal val = {.cid = pTagSchema->colId, .type = pTagSchema->type}; // strcpy(val.colName, pTagSchema->name); - if (pTagSchema->type == TSDB_DATA_TYPE_BINARY || pTagSchema->type == TSDB_DATA_TYPE_VARBINARY) { + if (pTagSchema->type == TSDB_DATA_TYPE_BINARY || pTagSchema->type == TSDB_DATA_TYPE_VARBINARY || + pTagSchema->type == TSDB_DATA_TYPE_GEOMETRY) { + if (pTagSchema->type == TSDB_DATA_TYPE_GEOMETRY) { + code = formatGeometry(bind[c].buffer, colLen); + if (code != TSDB_CODE_SUCCESS) goto end; + } val.pData = (uint8_t*)bind[c].buffer; val.nData = colLen; } else if (pTagSchema->type == TSDB_DATA_TYPE_NCHAR) { @@ -642,9 +627,6 @@ end: if (p->type == TSDB_DATA_TYPE_NCHAR) { taosMemoryFreeClear(p->pData); } - if (p->type == TSDB_DATA_TYPE_GEOMETRY) { - geosFreeBuffer(p->pData); - } } taosArrayDestroy(pTagArray); taosArrayDestroy(tagName); diff --git a/source/libs/parser/src/parUtil.c b/source/libs/parser/src/parUtil.c index 33b36c98fb..e35eea9e72 100644 --- a/source/libs/parser/src/parUtil.c +++ b/source/libs/parser/src/parUtil.c @@ -15,7 +15,6 @@ #include "parUtil.h" #include "cJSON.h" -#include "geosWrapper.h" #include "querynodes.h" #include "tarray.h" #include "tlog.h" @@ -519,37 +518,6 @@ end: return retCode; } -int32_t parseGeotoTagData(const char* g, SArray* pTagVals, SSchema* pTagSchema) { - int32_t code = 0; - size_t size = 0; - unsigned char* output = NULL; - STagVal val = {.cid = pTagSchema->colId, .type = pTagSchema->type}; - code = initCtxGeomFromText(); - if (code != TSDB_CODE_SUCCESS) { - return code; - } - code = doGeomFromText(g, &output, &size); - if (code != TSDB_CODE_SUCCESS) { - goto end; - } - if (size > pTagSchema->bytes) { - code = TSDB_CODE_PAR_VALUE_TOO_LONG; - goto end; - } - - val.pData = (uint8_t*)output; - val.nData = (uint32_t)size; - - if (NULL == taosArrayPush(pTagVals, &val)) { - code = terrno; - geosFreeBuffer(output); - goto end; - } - -end: - return code; -} - static int32_t getInsTagsTableTargetNameFromOp(int32_t acctId, SOperatorNode* pOper, SName* pName) { if (OP_TYPE_EQUAL != pOper->opType) { return TSDB_CODE_SUCCESS; diff --git a/tests/script/api/stmt2-geometry-test.c b/tests/script/api/stmt2-geometry-test.c index e1af5879eb..3bda05f5ee 100644 --- a/tests/script/api/stmt2-geometry-test.c +++ b/tests/script/api/stmt2-geometry-test.c @@ -3,6 +3,11 @@ #include #include "taos.h" +int8_t byteArray[21] = {0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x59, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0x40}; +int8_t worngArray[21] = {0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x59, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0x40}; + void do_query(TAOS* taos, const char* sql) { printf("[sql]%s\n", sql); TAOS_RES* result = taos_query(taos, sql); @@ -15,8 +20,8 @@ void do_query(TAOS* taos, const char* sql) { taos_free_result(result); } -void execute_test(TAOS* taos, const char* tbname1, const char* tbname2, const char* tag2, const char* col2, - const char* case_desc) { +void execute_test(TAOS* taos, const char* tbname1, const char* tbname2, int8_t* tag2, int8_t* col2, + const char* case_desc, int size) { // prepare stmt TAOS_STMT2_OPTION option = {0, true, false, NULL, NULL}; TAOS_STMT2* stmt = taos_stmt2_init(taos, &option); @@ -36,18 +41,17 @@ void execute_test(TAOS* taos, const char* tbname1, const char* tbname2, const ch } // prepare data - int t1_val = 0; - int64_t ts = 1591060628000; - const char* tbname[2] = {tbname1, tbname2}; - int32_t length[5] = {sizeof(int), 2, sizeof(int64_t), (int32_t)strlen(tag2), (int32_t)strlen(col2)}; + int t1_val = 0; + int64_t ts = 1591060628000; + const char* tbname[2] = {tbname1, tbname2}; + int32_t length[5] = {sizeof(int), 2, sizeof(int64_t), size, 20, sizeof(col2)}; + TAOS_STMT2_BIND tags[2][2] = { - {{TSDB_DATA_TYPE_INT, &t1_val, &length[0], NULL, 2}, {TSDB_DATA_TYPE_GEOMETRY, (void*)tag2, &length[3], NULL, 2}}, - {{TSDB_DATA_TYPE_INT, &t1_val, &length[0], NULL, 2}, - {TSDB_DATA_TYPE_GEOMETRY, (void*)tag2, &length[3], NULL, 2}}}; - TAOS_STMT2_BIND params[2][2] = {{{TSDB_DATA_TYPE_TIMESTAMP, &ts, &length[2], NULL, 1}, - {TSDB_DATA_TYPE_GEOMETRY, (void*)col2, &length[4], NULL, 1}}, - {{TSDB_DATA_TYPE_TIMESTAMP, &ts, &length[2], NULL, 1}, - {TSDB_DATA_TYPE_GEOMETRY, (void*)col2, &length[4], NULL, 1}}}; + {{TSDB_DATA_TYPE_INT, &t1_val, &length[0], NULL, 2}, {TSDB_DATA_TYPE_GEOMETRY, tag2, &length[3], NULL, 2}}, + {{TSDB_DATA_TYPE_INT, &t1_val, &length[0], NULL, 2}, {TSDB_DATA_TYPE_GEOMETRY, tag2, &length[3], NULL, 2}}}; + TAOS_STMT2_BIND params[2][2] = { + {{TSDB_DATA_TYPE_TIMESTAMP, &ts, &length[2], NULL, 1}, {TSDB_DATA_TYPE_GEOMETRY, col2, &length[3], NULL, 1}}, + {{TSDB_DATA_TYPE_TIMESTAMP, &ts, &length[2], NULL, 1}, {TSDB_DATA_TYPE_GEOMETRY, col2, &length[3], NULL, 1}}}; TAOS_STMT2_BIND* tagv[2] = {&tags[0][0], &tags[1][0]}; TAOS_STMT2_BIND* paramv[2] = {¶ms[0][0], ¶ms[1][0]}; @@ -69,21 +73,18 @@ void execute_test(TAOS* taos, const char* tbname1, const char* tbname2, const ch taos_stmt2_close(stmt); } -void test1(TAOS* taos) { - execute_test(taos, "tb11", "tb12", "POINT(1.0 1.0)", "LINESTRING(1.0 1.0, 2.0 2.0, 3.0 3.0)", "[normal]case 1"); -} +void test1(TAOS* taos) { execute_test(taos, "tb11", "tb12", &byteArray[0], &byteArray[0], "[normal]case 1", 21); } void test2(TAOS* taos) { - execute_test(taos, "tb21", "tb22", "hello", "LINESTRING(1.0 1.0, 2.0 2.0, 3.0 3.0)", "[wrong tag]case 2"); + execute_test(taos, "tb21", "tb22", &worngArray[0], &byteArray[0], "[wrong WKB tag]case 2", 21); } void test3(TAOS* taos) { - execute_test(taos, "tb31", "tb32", "POLYGON((0 0, 4 0, 4 4, 0 4, 0 0))", "1", "[wrong col]case 3"); + execute_test(taos, "tb31", "tb32", "POLYGON((0 0, 4 0, 4 4, 0 4, 0 0))", "POLYGON((0 0, 4 0, 4 4, 0 4, 0 0))", + "[wrong WKT col]case 3", sizeof("POLYGON((0 0, 4 0, 4 4, 0 4, 0 0))")); } -void test4(TAOS* taos) { - execute_test(taos, "tb41", "tb42", "POLYGON((0 0, 4 0, 4 4, 0 4, 0 0))", "POINT(1.0 1.0)", "[wrong size]case 4"); -} +void test4(TAOS* taos) { execute_test(taos, "tb41", "tb42", &byteArray[0], &byteArray[0], "[wrong size]case 4", 21); } int main() { TAOS* taos = taos_connect("localhost", "root", "taosdata", "", 0); From f3b4aa14be10a6cec404ed358d13e674e0e1fca9 Mon Sep 17 00:00:00 2001 From: Pengrongkun Date: Tue, 19 Nov 2024 16:44:28 +0800 Subject: [PATCH 5/5] add checkWKBGeometry function --- include/common/tdataformat.h | 9 +++-- include/libs/geometry/geosWrapper.h | 10 +++--- source/common/src/tdataformat.c | 23 ++++++++++--- source/libs/geometry/src/geosWrapper.c | 43 ++++++++++++++++++----- source/libs/parser/src/parInsertStmt.c | 47 +++++++++++--------------- tests/script/api/stmt2-geometry-test.c | 3 +- 6 files changed, 86 insertions(+), 49 deletions(-) diff --git a/include/common/tdataformat.h b/include/common/tdataformat.h index f71459d6aa..f899fc5589 100644 --- a/include/common/tdataformat.h +++ b/include/common/tdataformat.h @@ -173,7 +173,8 @@ typedef struct { } SColDataCompressInfo; typedef void *(*xMallocFn)(void *, int32_t); -typedef int32_t (*formatGeometryFn)(char *geoWKB, size_t nGeom); +typedef int32_t (*checkWKBGeometryFn)(const unsigned char *geoWKB, size_t nGeom); +typedef int32_t (*initGeosFn)(); void tColDataDestroy(void *ph); void tColDataInit(SColData *pColData, int16_t cid, int8_t type, int8_t cflag); @@ -192,7 +193,8 @@ int32_t tColDataCompress(SColData *colData, SColDataCompressInfo *info, SBuffer int32_t tColDataDecompress(void *input, SColDataCompressInfo *info, SColData *colData, SBuffer *assist); // for stmt bind -int32_t tColDataAddValueByBind(SColData *pColData, TAOS_MULTI_BIND *pBind, int32_t buffMaxLen, formatGeometryFn fg); +int32_t tColDataAddValueByBind(SColData *pColData, TAOS_MULTI_BIND *pBind, int32_t buffMaxLen, initGeosFn igeos, + checkWKBGeometryFn cgeos); int32_t tColDataSortMerge(SArray **arr); // for raw block @@ -379,7 +381,8 @@ int32_t tRowBuildFromBind(SBindInfo *infos, int32_t numOfInfos, bool infoSorted, SArray *rowArray); // stmt2 binding -int32_t tColDataAddValueByBind2(SColData *pColData, TAOS_STMT2_BIND *pBind, int32_t buffMaxLen, formatGeometryFn fg); +int32_t tColDataAddValueByBind2(SColData *pColData, TAOS_STMT2_BIND *pBind, int32_t buffMaxLen, initGeosFn igeos, + checkWKBGeometryFn cgeos); typedef struct { int32_t columnId; diff --git a/include/libs/geometry/geosWrapper.h b/include/libs/geometry/geosWrapper.h index a5bc0cec17..d27d300b82 100644 --- a/include/libs/geometry/geosWrapper.h +++ b/include/libs/geometry/geosWrapper.h @@ -35,6 +35,7 @@ int32_t doGeomFromText(const char *inputWKT, unsigned char **outputGeom, size_t int32_t initCtxAsText(); int32_t doAsText(const unsigned char *inputGeom, size_t size, char **outputWKT); +int32_t checkWKB(const unsigned char *wkb, size_t size); int32_t initCtxRelationFunc(); int32_t doIntersects(const GEOSGeometry *geom1, const GEOSPreparedGeometry *preparedGeom1, const GEOSGeometry *geom2, @@ -47,11 +48,12 @@ int32_t doCovers(const GEOSGeometry *geom1, const GEOSPreparedGeometry *prepared bool swapped, char *res); int32_t doContains(const GEOSGeometry *geom1, const GEOSPreparedGeometry *preparedGeom1, const GEOSGeometry *geom2, bool swapped, char *res); -int32_t doContainsProperly(const GEOSGeometry *geom1, const GEOSPreparedGeometry *preparedGeom1, const GEOSGeometry *geom2, - bool swapped, char *res); +int32_t doContainsProperly(const GEOSGeometry *geom1, const GEOSPreparedGeometry *preparedGeom1, + const GEOSGeometry *geom2, bool swapped, char *res); -int32_t readGeometry(const unsigned char *input, GEOSGeometry **outputGeom, const GEOSPreparedGeometry **outputPreparedGeom); -void destroyGeometry(GEOSGeometry **geom, const GEOSPreparedGeometry **preparedGeom); +int32_t readGeometry(const unsigned char *input, GEOSGeometry **outputGeom, + const GEOSPreparedGeometry **outputPreparedGeom); +void destroyGeometry(GEOSGeometry **geom, const GEOSPreparedGeometry **preparedGeom); #ifdef __cplusplus } diff --git a/source/common/src/tdataformat.c b/source/common/src/tdataformat.c index 23986b265d..a38842735c 100644 --- a/source/common/src/tdataformat.c +++ b/source/common/src/tdataformat.c @@ -3036,7 +3036,8 @@ _exit: return code; } -int32_t tColDataAddValueByBind(SColData *pColData, TAOS_MULTI_BIND *pBind, int32_t buffMaxLen, formatGeometryFn fg) { +int32_t tColDataAddValueByBind(SColData *pColData, TAOS_MULTI_BIND *pBind, int32_t buffMaxLen, initGeosFn igeos, + checkWKBGeometryFn cgeos) { int32_t code = 0; if (!(pBind->num == 1 && pBind->is_null && *pBind->is_null)) { @@ -3046,6 +3047,12 @@ int32_t tColDataAddValueByBind(SColData *pColData, TAOS_MULTI_BIND *pBind, int32 } if (IS_VAR_DATA_TYPE(pColData->type)) { // var-length data type + if (pColData->type == TSDB_DATA_TYPE_GEOMETRY) { + code = igeos(); + if (code) { + return code; + } + } for (int32_t i = 0; i < pBind->num; ++i) { if (pBind->is_null && pBind->is_null[i]) { if (pColData->cflag & COL_IS_KEY) { @@ -3058,7 +3065,7 @@ int32_t tColDataAddValueByBind(SColData *pColData, TAOS_MULTI_BIND *pBind, int32 return TSDB_CODE_PAR_VALUE_TOO_LONG; } else { if (pColData->type == TSDB_DATA_TYPE_GEOMETRY) { - code = fg((char *)pBind->buffer + pBind->buffer_length * i, (size_t)pBind->length[i]); + code = cgeos((char *)pBind->buffer + pBind->buffer_length * i, (size_t)pBind->length[i]); if (code) goto _exit; } code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE]( @@ -3111,7 +3118,8 @@ _exit: return code; } -int32_t tColDataAddValueByBind2(SColData *pColData, TAOS_STMT2_BIND *pBind, int32_t buffMaxLen, formatGeometryFn fg) { +int32_t tColDataAddValueByBind2(SColData *pColData, TAOS_STMT2_BIND *pBind, int32_t buffMaxLen, initGeosFn igeos, + checkWKBGeometryFn cgeos) { int32_t code = 0; if (!(pBind->num == 1 && pBind->is_null && *pBind->is_null)) { @@ -3121,6 +3129,13 @@ int32_t tColDataAddValueByBind2(SColData *pColData, TAOS_STMT2_BIND *pBind, int3 } if (IS_VAR_DATA_TYPE(pColData->type)) { // var-length data type + if (pColData->type == TSDB_DATA_TYPE_GEOMETRY) { + code = igeos(); + if (code) { + return code; + } + } + uint8_t *buf = pBind->buffer; for (int32_t i = 0; i < pBind->num; ++i) { if (pBind->is_null && pBind->is_null[i]) { @@ -3139,7 +3154,7 @@ int32_t tColDataAddValueByBind2(SColData *pColData, TAOS_STMT2_BIND *pBind, int3 return TSDB_CODE_PAR_VALUE_TOO_LONG; } else { if (pColData->type == TSDB_DATA_TYPE_GEOMETRY) { - code = fg(buf, pBind->length[i]); + code = cgeos(buf, pBind->length[i]); if (code) goto _exit; } code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, buf, pBind->length[i]); diff --git a/source/libs/geometry/src/geosWrapper.c b/source/libs/geometry/src/geosWrapper.c index 13c5f7208e..8789762a85 100644 --- a/source/libs/geometry/src/geosWrapper.c +++ b/source/libs/geometry/src/geosWrapper.c @@ -63,7 +63,7 @@ int32_t initCtxMakePoint() { int32_t doMakePoint(double x, double y, unsigned char **outputGeom, size_t *size) { int32_t code = TSDB_CODE_FAILED; SGeosContext *geosCtx = NULL; - + TAOS_CHECK_RETURN(getThreadLocalGeosCtx(&geosCtx)); GEOSGeometry *geom = NULL; @@ -170,7 +170,7 @@ static int32_t initWktRegex(pcre2_code **ppRegex, pcre2_match_data **ppMatchData int32_t initCtxGeomFromText() { int32_t code = TSDB_CODE_FAILED; SGeosContext *geosCtx = NULL; - + TAOS_CHECK_RETURN(getThreadLocalGeosCtx(&geosCtx)); if (geosCtx->handle == NULL) { @@ -208,7 +208,7 @@ int32_t initCtxGeomFromText() { int32_t doGeomFromText(const char *inputWKT, unsigned char **outputGeom, size_t *size) { int32_t code = TSDB_CODE_FAILED; SGeosContext *geosCtx = NULL; - + TAOS_CHECK_RETURN(getThreadLocalGeosCtx(&geosCtx)); GEOSGeometry *geom = NULL; @@ -245,7 +245,7 @@ _exit: int32_t initCtxAsText() { int32_t code = TSDB_CODE_FAILED; SGeosContext *geosCtx = NULL; - + TAOS_CHECK_RETURN(getThreadLocalGeosCtx(&geosCtx)); if (geosCtx->handle == NULL) { @@ -283,11 +283,11 @@ int32_t initCtxAsText() { int32_t doAsText(const unsigned char *inputGeom, size_t size, char **outputWKT) { int32_t code = TSDB_CODE_FAILED; SGeosContext *geosCtx = NULL; - + TAOS_CHECK_RETURN(getThreadLocalGeosCtx(&geosCtx)); - GEOSGeometry *geom = NULL; - char *wkt = NULL; + GEOSGeometry *geom = NULL; + char *wkt = NULL; geom = GEOSWKBReader_read_r(geosCtx->handle, geosCtx->WKBReader, inputGeom, size); if (geom == NULL) { @@ -313,10 +313,35 @@ _exit: return code; } +int32_t checkWKB(const unsigned char *wkb, size_t size) { + int32_t code = TSDB_CODE_SUCCESS; + GEOSGeometry *geom = NULL; + SGeosContext *geosCtx = NULL; + + TAOS_CHECK_RETURN(getThreadLocalGeosCtx(&geosCtx)); + + geom = GEOSWKBReader_read_r(geosCtx->handle, geosCtx->WKBReader, wkb, size); + if (geom == NULL) { + return TSDB_CODE_FUNC_FUNTION_PARA_VALUE; + } + + if (!GEOSisValid_r(geosCtx->handle, geom)) { + code = TSDB_CODE_FUNC_FUNTION_PARA_VALUE; + goto _exit; + } + +_exit: + if (geom) { + GEOSGeom_destroy_r(geosCtx->handle, geom); + geom = NULL; + } + return code; +} + int32_t initCtxRelationFunc() { int32_t code = TSDB_CODE_FAILED; SGeosContext *geosCtx = NULL; - + TAOS_CHECK_RETURN(getThreadLocalGeosCtx(&geosCtx)); if (geosCtx->handle == NULL) { @@ -343,7 +368,7 @@ int32_t doGeosRelation(const GEOSGeometry *geom1, const GEOSPreparedGeometry *pr _geosPreparedRelationFunc_t preparedRelationFn, _geosPreparedRelationFunc_t swappedPreparedRelationFn) { SGeosContext *geosCtx = NULL; - + TAOS_CHECK_RETURN(getThreadLocalGeosCtx(&geosCtx)); if (!preparedGeom1) { diff --git a/source/libs/parser/src/parInsertStmt.c b/source/libs/parser/src/parInsertStmt.c index b515f9df9d..bedd4fa540 100644 --- a/source/libs/parser/src/parInsertStmt.c +++ b/source/libs/parser/src/parInsertStmt.c @@ -102,21 +102,6 @@ pStmt = (SVnodeModifyOpStmt*)pQuery->pRoot; } */ -int32_t formatGeometry(char* geoWKB, size_t nGeom) { - int32_t code = TSDB_CODE_SUCCESS; - char* outputWKT = NULL; - - if (TSDB_CODE_SUCCESS != (code = initCtxAsText()) || - TSDB_CODE_SUCCESS != (code = doAsText(geoWKB, nGeom, &outputWKT))) { - code = TSDB_CODE_INVALID_PARA; - goto _exit; - } - -_exit: - geosFreeBuffer(outputWKT); - return code; -} - int32_t qBuildStmtOutput(SQuery* pQuery, SHashObj* pVgHash, SHashObj* pBlockHash) { int32_t code = TSDB_CODE_SUCCESS; SArray* pVgDataBlocks = NULL; @@ -209,8 +194,10 @@ int32_t qBindStmtTagsValue(void* pBlock, void* boundTags, int64_t suid, const ch if (pTagSchema->type == TSDB_DATA_TYPE_BINARY || pTagSchema->type == TSDB_DATA_TYPE_VARBINARY || pTagSchema->type == TSDB_DATA_TYPE_GEOMETRY) { if (pTagSchema->type == TSDB_DATA_TYPE_GEOMETRY) { - code = formatGeometry(bind[c].buffer, colLen); - if (code != TSDB_CODE_SUCCESS) goto end; + if (initCtxAsText() || checkWKB(bind[c].buffer, colLen)) { + code = buildSyntaxErrMsg(&pBuf, "invalid geometry tag", bind[c].buffer); + goto end; + } } val.pData = (uint8_t*)bind[c].buffer; val.nData = colLen; @@ -428,8 +415,9 @@ int32_t qBindStmtColsValue(void* pBlock, SArray* pCols, TAOS_MULTI_BIND* bind, c pBind = bind + c; } - code = tColDataAddValueByBind( - pCol, pBind, IS_VAR_DATA_TYPE(pColSchema->type) ? pColSchema->bytes - VARSTR_HEADER_SIZE : -1, formatGeometry); + code = tColDataAddValueByBind(pCol, pBind, + IS_VAR_DATA_TYPE(pColSchema->type) ? pColSchema->bytes - VARSTR_HEADER_SIZE : -1, + initCtxAsText, checkWKB); if (code) { goto _return; } @@ -480,8 +468,9 @@ int32_t qBindStmtSingleColValue(void* pBlock, SArray* pCols, TAOS_MULTI_BIND* bi pBind = bind; } - code = tColDataAddValueByBind( - pCol, pBind, IS_VAR_DATA_TYPE(pColSchema->type) ? pColSchema->bytes - VARSTR_HEADER_SIZE : -1, formatGeometry); + code = tColDataAddValueByBind(pCol, pBind, + IS_VAR_DATA_TYPE(pColSchema->type) ? pColSchema->bytes - VARSTR_HEADER_SIZE : -1, + initCtxAsText, checkWKB); qDebug("stmt col %d bind %d rows data", colIdx, rowNum); @@ -565,8 +554,10 @@ int32_t qBindStmtTagsValue2(void* pBlock, void* boundTags, int64_t suid, const c if (pTagSchema->type == TSDB_DATA_TYPE_BINARY || pTagSchema->type == TSDB_DATA_TYPE_VARBINARY || pTagSchema->type == TSDB_DATA_TYPE_GEOMETRY) { if (pTagSchema->type == TSDB_DATA_TYPE_GEOMETRY) { - code = formatGeometry(bind[c].buffer, colLen); - if (code != TSDB_CODE_SUCCESS) goto end; + if (initCtxAsText() || checkWKB(bind[c].buffer, colLen)) { + code = buildSyntaxErrMsg(&pBuf, "invalid geometry tag", bind[c].buffer); + goto end; + } } val.pData = (uint8_t*)bind[c].buffer; val.nData = colLen; @@ -847,8 +838,9 @@ int32_t qBindStmtColsValue2(void* pBlock, SArray* pCols, TAOS_STMT2_BIND* bind, pBind = bind + c; } - code = tColDataAddValueByBind2( - pCol, pBind, IS_VAR_DATA_TYPE(pColSchema->type) ? pColSchema->bytes - VARSTR_HEADER_SIZE : -1, formatGeometry); + code = tColDataAddValueByBind2(pCol, pBind, + IS_VAR_DATA_TYPE(pColSchema->type) ? pColSchema->bytes - VARSTR_HEADER_SIZE : -1, + initCtxAsText, checkWKB); if (code) { goto _return; } @@ -899,8 +891,9 @@ int32_t qBindStmtSingleColValue2(void* pBlock, SArray* pCols, TAOS_STMT2_BIND* b pBind = bind; } - code = tColDataAddValueByBind2( - pCol, pBind, IS_VAR_DATA_TYPE(pColSchema->type) ? pColSchema->bytes - VARSTR_HEADER_SIZE : -1, formatGeometry); + code = tColDataAddValueByBind2(pCol, pBind, + IS_VAR_DATA_TYPE(pColSchema->type) ? pColSchema->bytes - VARSTR_HEADER_SIZE : -1, + initCtxAsText, checkWKB); qDebug("stmt col %d bind %d rows data", colIdx, rowNum); diff --git a/tests/script/api/stmt2-geometry-test.c b/tests/script/api/stmt2-geometry-test.c index 3bda05f5ee..46fd9081ae 100644 --- a/tests/script/api/stmt2-geometry-test.c +++ b/tests/script/api/stmt2-geometry-test.c @@ -32,8 +32,7 @@ void execute_test(TAOS* taos, const char* tbname1, const char* tbname2, int8_t* sql = "insert into db.? using db.stb tags(?, ?) values(?,?)"; } int code = taos_stmt2_prepare(stmt, sql, 0); - printf("\n%s\n insert into db.? using db.stb tags(?, ?) values(?,?)\n bind_tag : %s, bind_col : %s\n", case_desc, - tag2, col2); + printf("\n%s\n insert into db.? using db.stb tags(?, ?) values(?,?)\n", case_desc); if (code != 0) { printf(" failed to execute taos_stmt2_prepare. error:%s\n", taos_stmt2_error(stmt)); taos_stmt2_close(stmt);