add checkWKBGeometry function

This commit is contained in:
Pengrongkun 2024-11-19 16:44:28 +08:00
parent ff2d0e6d67
commit f3b4aa14be
6 changed files with 86 additions and 49 deletions

View File

@ -173,7 +173,8 @@ typedef struct {
} SColDataCompressInfo; } SColDataCompressInfo;
typedef void *(*xMallocFn)(void *, int32_t); 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 tColDataDestroy(void *ph);
void tColDataInit(SColData *pColData, int16_t cid, int8_t type, int8_t cflag); 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); int32_t tColDataDecompress(void *input, SColDataCompressInfo *info, SColData *colData, SBuffer *assist);
// for stmt bind // 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); int32_t tColDataSortMerge(SArray **arr);
// for raw block // for raw block
@ -379,7 +381,8 @@ int32_t tRowBuildFromBind(SBindInfo *infos, int32_t numOfInfos, bool infoSorted,
SArray *rowArray); SArray *rowArray);
// stmt2 binding // 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 { typedef struct {
int32_t columnId; int32_t columnId;

View File

@ -35,6 +35,7 @@ int32_t doGeomFromText(const char *inputWKT, unsigned char **outputGeom, size_t
int32_t initCtxAsText(); int32_t initCtxAsText();
int32_t doAsText(const unsigned char *inputGeom, size_t size, char **outputWKT); 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 initCtxRelationFunc();
int32_t doIntersects(const GEOSGeometry *geom1, const GEOSPreparedGeometry *preparedGeom1, const GEOSGeometry *geom2, 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); bool swapped, char *res);
int32_t doContains(const GEOSGeometry *geom1, const GEOSPreparedGeometry *preparedGeom1, const GEOSGeometry *geom2, int32_t doContains(const GEOSGeometry *geom1, const GEOSPreparedGeometry *preparedGeom1, const GEOSGeometry *geom2,
bool swapped, char *res); bool swapped, char *res);
int32_t doContainsProperly(const GEOSGeometry *geom1, const GEOSPreparedGeometry *preparedGeom1, const GEOSGeometry *geom2, int32_t doContainsProperly(const GEOSGeometry *geom1, const GEOSPreparedGeometry *preparedGeom1,
bool swapped, char *res); const GEOSGeometry *geom2, bool swapped, char *res);
int32_t readGeometry(const unsigned char *input, GEOSGeometry **outputGeom, const GEOSPreparedGeometry **outputPreparedGeom); int32_t readGeometry(const unsigned char *input, GEOSGeometry **outputGeom,
void destroyGeometry(GEOSGeometry **geom, const GEOSPreparedGeometry **preparedGeom); const GEOSPreparedGeometry **outputPreparedGeom);
void destroyGeometry(GEOSGeometry **geom, const GEOSPreparedGeometry **preparedGeom);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -3036,7 +3036,8 @@ _exit:
return code; 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; int32_t code = 0;
if (!(pBind->num == 1 && pBind->is_null && *pBind->is_null)) { 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 (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) { for (int32_t i = 0; i < pBind->num; ++i) {
if (pBind->is_null && pBind->is_null[i]) { if (pBind->is_null && pBind->is_null[i]) {
if (pColData->cflag & COL_IS_KEY) { 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; return TSDB_CODE_PAR_VALUE_TOO_LONG;
} else { } else {
if (pColData->type == TSDB_DATA_TYPE_GEOMETRY) { 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; if (code) goto _exit;
} }
code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE]( code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](
@ -3111,7 +3118,8 @@ _exit:
return code; 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; int32_t code = 0;
if (!(pBind->num == 1 && pBind->is_null && *pBind->is_null)) { 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 (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; uint8_t *buf = pBind->buffer;
for (int32_t i = 0; i < pBind->num; ++i) { for (int32_t i = 0; i < pBind->num; ++i) {
if (pBind->is_null && pBind->is_null[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; return TSDB_CODE_PAR_VALUE_TOO_LONG;
} else { } else {
if (pColData->type == TSDB_DATA_TYPE_GEOMETRY) { if (pColData->type == TSDB_DATA_TYPE_GEOMETRY) {
code = fg(buf, pBind->length[i]); code = cgeos(buf, pBind->length[i]);
if (code) goto _exit; if (code) goto _exit;
} }
code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, buf, pBind->length[i]); code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_VALUE](pColData, buf, pBind->length[i]);

View File

@ -63,7 +63,7 @@ int32_t initCtxMakePoint() {
int32_t doMakePoint(double x, double y, unsigned char **outputGeom, size_t *size) { int32_t doMakePoint(double x, double y, unsigned char **outputGeom, size_t *size) {
int32_t code = TSDB_CODE_FAILED; int32_t code = TSDB_CODE_FAILED;
SGeosContext *geosCtx = NULL; SGeosContext *geosCtx = NULL;
TAOS_CHECK_RETURN(getThreadLocalGeosCtx(&geosCtx)); TAOS_CHECK_RETURN(getThreadLocalGeosCtx(&geosCtx));
GEOSGeometry *geom = NULL; GEOSGeometry *geom = NULL;
@ -170,7 +170,7 @@ static int32_t initWktRegex(pcre2_code **ppRegex, pcre2_match_data **ppMatchData
int32_t initCtxGeomFromText() { int32_t initCtxGeomFromText() {
int32_t code = TSDB_CODE_FAILED; int32_t code = TSDB_CODE_FAILED;
SGeosContext *geosCtx = NULL; SGeosContext *geosCtx = NULL;
TAOS_CHECK_RETURN(getThreadLocalGeosCtx(&geosCtx)); TAOS_CHECK_RETURN(getThreadLocalGeosCtx(&geosCtx));
if (geosCtx->handle == NULL) { 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 doGeomFromText(const char *inputWKT, unsigned char **outputGeom, size_t *size) {
int32_t code = TSDB_CODE_FAILED; int32_t code = TSDB_CODE_FAILED;
SGeosContext *geosCtx = NULL; SGeosContext *geosCtx = NULL;
TAOS_CHECK_RETURN(getThreadLocalGeosCtx(&geosCtx)); TAOS_CHECK_RETURN(getThreadLocalGeosCtx(&geosCtx));
GEOSGeometry *geom = NULL; GEOSGeometry *geom = NULL;
@ -245,7 +245,7 @@ _exit:
int32_t initCtxAsText() { int32_t initCtxAsText() {
int32_t code = TSDB_CODE_FAILED; int32_t code = TSDB_CODE_FAILED;
SGeosContext *geosCtx = NULL; SGeosContext *geosCtx = NULL;
TAOS_CHECK_RETURN(getThreadLocalGeosCtx(&geosCtx)); TAOS_CHECK_RETURN(getThreadLocalGeosCtx(&geosCtx));
if (geosCtx->handle == NULL) { 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 doAsText(const unsigned char *inputGeom, size_t size, char **outputWKT) {
int32_t code = TSDB_CODE_FAILED; int32_t code = TSDB_CODE_FAILED;
SGeosContext *geosCtx = NULL; SGeosContext *geosCtx = NULL;
TAOS_CHECK_RETURN(getThreadLocalGeosCtx(&geosCtx)); TAOS_CHECK_RETURN(getThreadLocalGeosCtx(&geosCtx));
GEOSGeometry *geom = NULL; GEOSGeometry *geom = NULL;
char *wkt = NULL; char *wkt = NULL;
geom = GEOSWKBReader_read_r(geosCtx->handle, geosCtx->WKBReader, inputGeom, size); geom = GEOSWKBReader_read_r(geosCtx->handle, geosCtx->WKBReader, inputGeom, size);
if (geom == NULL) { if (geom == NULL) {
@ -313,10 +313,35 @@ _exit:
return code; 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 initCtxRelationFunc() {
int32_t code = TSDB_CODE_FAILED; int32_t code = TSDB_CODE_FAILED;
SGeosContext *geosCtx = NULL; SGeosContext *geosCtx = NULL;
TAOS_CHECK_RETURN(getThreadLocalGeosCtx(&geosCtx)); TAOS_CHECK_RETURN(getThreadLocalGeosCtx(&geosCtx));
if (geosCtx->handle == NULL) { if (geosCtx->handle == NULL) {
@ -343,7 +368,7 @@ int32_t doGeosRelation(const GEOSGeometry *geom1, const GEOSPreparedGeometry *pr
_geosPreparedRelationFunc_t preparedRelationFn, _geosPreparedRelationFunc_t preparedRelationFn,
_geosPreparedRelationFunc_t swappedPreparedRelationFn) { _geosPreparedRelationFunc_t swappedPreparedRelationFn) {
SGeosContext *geosCtx = NULL; SGeosContext *geosCtx = NULL;
TAOS_CHECK_RETURN(getThreadLocalGeosCtx(&geosCtx)); TAOS_CHECK_RETURN(getThreadLocalGeosCtx(&geosCtx));
if (!preparedGeom1) { if (!preparedGeom1) {

View File

@ -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 qBuildStmtOutput(SQuery* pQuery, SHashObj* pVgHash, SHashObj* pBlockHash) {
int32_t code = TSDB_CODE_SUCCESS; int32_t code = TSDB_CODE_SUCCESS;
SArray* pVgDataBlocks = NULL; 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 || if (pTagSchema->type == TSDB_DATA_TYPE_BINARY || pTagSchema->type == TSDB_DATA_TYPE_VARBINARY ||
pTagSchema->type == TSDB_DATA_TYPE_GEOMETRY) { pTagSchema->type == TSDB_DATA_TYPE_GEOMETRY) {
if (pTagSchema->type == TSDB_DATA_TYPE_GEOMETRY) { if (pTagSchema->type == TSDB_DATA_TYPE_GEOMETRY) {
code = formatGeometry(bind[c].buffer, colLen); if (initCtxAsText() || checkWKB(bind[c].buffer, colLen)) {
if (code != TSDB_CODE_SUCCESS) goto end; code = buildSyntaxErrMsg(&pBuf, "invalid geometry tag", bind[c].buffer);
goto end;
}
} }
val.pData = (uint8_t*)bind[c].buffer; val.pData = (uint8_t*)bind[c].buffer;
val.nData = colLen; val.nData = colLen;
@ -428,8 +415,9 @@ int32_t qBindStmtColsValue(void* pBlock, SArray* pCols, TAOS_MULTI_BIND* bind, c
pBind = bind + c; pBind = bind + c;
} }
code = tColDataAddValueByBind( code = tColDataAddValueByBind(pCol, pBind,
pCol, pBind, IS_VAR_DATA_TYPE(pColSchema->type) ? pColSchema->bytes - VARSTR_HEADER_SIZE : -1, formatGeometry); IS_VAR_DATA_TYPE(pColSchema->type) ? pColSchema->bytes - VARSTR_HEADER_SIZE : -1,
initCtxAsText, checkWKB);
if (code) { if (code) {
goto _return; goto _return;
} }
@ -480,8 +468,9 @@ int32_t qBindStmtSingleColValue(void* pBlock, SArray* pCols, TAOS_MULTI_BIND* bi
pBind = bind; pBind = bind;
} }
code = tColDataAddValueByBind( code = tColDataAddValueByBind(pCol, pBind,
pCol, pBind, IS_VAR_DATA_TYPE(pColSchema->type) ? pColSchema->bytes - VARSTR_HEADER_SIZE : -1, formatGeometry); IS_VAR_DATA_TYPE(pColSchema->type) ? pColSchema->bytes - VARSTR_HEADER_SIZE : -1,
initCtxAsText, checkWKB);
qDebug("stmt col %d bind %d rows data", colIdx, rowNum); 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 || if (pTagSchema->type == TSDB_DATA_TYPE_BINARY || pTagSchema->type == TSDB_DATA_TYPE_VARBINARY ||
pTagSchema->type == TSDB_DATA_TYPE_GEOMETRY) { pTagSchema->type == TSDB_DATA_TYPE_GEOMETRY) {
if (pTagSchema->type == TSDB_DATA_TYPE_GEOMETRY) { if (pTagSchema->type == TSDB_DATA_TYPE_GEOMETRY) {
code = formatGeometry(bind[c].buffer, colLen); if (initCtxAsText() || checkWKB(bind[c].buffer, colLen)) {
if (code != TSDB_CODE_SUCCESS) goto end; code = buildSyntaxErrMsg(&pBuf, "invalid geometry tag", bind[c].buffer);
goto end;
}
} }
val.pData = (uint8_t*)bind[c].buffer; val.pData = (uint8_t*)bind[c].buffer;
val.nData = colLen; val.nData = colLen;
@ -847,8 +838,9 @@ int32_t qBindStmtColsValue2(void* pBlock, SArray* pCols, TAOS_STMT2_BIND* bind,
pBind = bind + c; pBind = bind + c;
} }
code = tColDataAddValueByBind2( code = tColDataAddValueByBind2(pCol, pBind,
pCol, pBind, IS_VAR_DATA_TYPE(pColSchema->type) ? pColSchema->bytes - VARSTR_HEADER_SIZE : -1, formatGeometry); IS_VAR_DATA_TYPE(pColSchema->type) ? pColSchema->bytes - VARSTR_HEADER_SIZE : -1,
initCtxAsText, checkWKB);
if (code) { if (code) {
goto _return; goto _return;
} }
@ -899,8 +891,9 @@ int32_t qBindStmtSingleColValue2(void* pBlock, SArray* pCols, TAOS_STMT2_BIND* b
pBind = bind; pBind = bind;
} }
code = tColDataAddValueByBind2( code = tColDataAddValueByBind2(pCol, pBind,
pCol, pBind, IS_VAR_DATA_TYPE(pColSchema->type) ? pColSchema->bytes - VARSTR_HEADER_SIZE : -1, formatGeometry); IS_VAR_DATA_TYPE(pColSchema->type) ? pColSchema->bytes - VARSTR_HEADER_SIZE : -1,
initCtxAsText, checkWKB);
qDebug("stmt col %d bind %d rows data", colIdx, rowNum); qDebug("stmt col %d bind %d rows data", colIdx, rowNum);

View File

@ -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(?,?)"; sql = "insert into db.? using db.stb tags(?, ?) values(?,?)";
} }
int code = taos_stmt2_prepare(stmt, sql, 0); 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, printf("\n%s\n insert into db.? using db.stb tags(?, ?) values(?,?)\n", case_desc);
tag2, col2);
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));
taos_stmt2_close(stmt); taos_stmt2_close(stmt);