From 7a7d49d3a0d0b7fc997b10729cacf5ff930e0022 Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Wed, 1 Dec 2021 11:44:09 +0800 Subject: [PATCH] enable different value type of the same key in json --- src/client/src/tscSQLParser.c | 3 +++ src/query/src/qFilter.c | 28 ++++++++++++++++++++++++++++ src/util/src/tcompare.c | 2 ++ tests/pytest/stable/json_tag.py | 15 +++++---------- 4 files changed, 38 insertions(+), 10 deletions(-) diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index b40b879daf..321137cb6b 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -4716,6 +4716,7 @@ static int32_t validateJsonTagExpr(tSqlExpr* pExpr, char* msgBuf) { const char* msg1 = "not support json tag column filter"; const char* msg2 = "tag json key is invalidate"; const char* msg3 = "tag json key must be string"; + const char* msg4 = "in operation not support in tag json"; tSqlExpr* pLeft = pExpr->pLeft; tSqlExpr* pRight = pExpr->pRight; @@ -4726,6 +4727,8 @@ static int32_t validateJsonTagExpr(tSqlExpr* pExpr, char* msgBuf) { if (pRight != NULL && (pRight->value.nLen > TSDB_MAX_JSON_KEY_LEN || pRight->value.nLen <= 0)) return invalidOperationMsg(msgBuf, msg2); + } else if(pExpr->tokenId == TK_IN){ + return invalidOperationMsg(msgBuf, msg4); } else { if (pLeft != NULL && pLeft->tokenId == TK_ID && pExpr->tokenId != TK_ISNULL && pExpr->tokenId != TK_NOTNULL) { return invalidOperationMsg(msgBuf, msg1); diff --git a/src/query/src/qFilter.c b/src/query/src/qFilter.c index 45661ee982..e72acd788a 100644 --- a/src/query/src/qFilter.c +++ b/src/query/src/qFilter.c @@ -234,6 +234,8 @@ int8_t filterGetCompFuncIdx(int32_t type, int32_t optr) { comparFn = 19; } else if (optr == TSDB_RELATION_NMATCH) { comparFn = 20; + } else if (optr == TSDB_RELATION_LIKE) { /* wildcard query using like operator */ + comparFn = 9; } else if (optr == TSDB_RELATION_QUESTION) { comparFn = 21; } else { @@ -3061,6 +3063,19 @@ bool filterExecuteImplMisc(void *pinfo, int32_t numOfRows, int8_t** p, SDataStat (*p)[i] = filterDoCompare(gDataCompare[info->cunits[uidx].func], info->cunits[uidx].optr, newColData, newValData); tfree(newColData); } + }else if(info->cunits[uidx].optr == TSDB_RELATION_LIKE){ + uint8_t jsonType = *(char*)colData; + char* realData = colData + CHAR_BYTES; + if (jsonType != TSDB_DATA_TYPE_NCHAR){ + (*p)[i] = false; + }else{ + tVariant* val = info->cunits[uidx].valData; + char* newValData = calloc(val->nLen + VARSTR_HEADER_SIZE, 1); + memcpy(varDataVal(newValData), val->pz, val->nLen); + varDataSetLen(newValData, val->nLen); + (*p)[i] = filterDoCompare(gDataCompare[info->cunits[uidx].func], info->cunits[uidx].optr, realData, newValData); + tfree(newValData); + } }else{ (*p)[i] = filterDoCompare(gDataCompare[info->cunits[uidx].func], info->cunits[uidx].optr, colData, info->cunits[uidx].valData); } @@ -3138,6 +3153,19 @@ bool filterExecuteImpl(void *pinfo, int32_t numOfRows, int8_t** p, SDataStatis * (*p)[i] = filterDoCompare(gDataCompare[cunit->func], cunit->optr, newColData, newValData); tfree(newColData); } + }else if(cunit->optr == TSDB_RELATION_LIKE){ + uint8_t jsonType = *(char*)colData; + char* realData = colData + CHAR_BYTES; + if (jsonType != TSDB_DATA_TYPE_NCHAR){ + (*p)[i] = false; + }else{ + tVariant* val = cunit->valData; + char* newValData = calloc(val->nLen + VARSTR_HEADER_SIZE, 1); + memcpy(varDataVal(newValData), val->pz, val->nLen); + varDataSetLen(newValData, val->nLen); + (*p)[i] = filterDoCompare(gDataCompare[cunit->func], cunit->optr, realData, newValData); + tfree(newValData); + } }else{ (*p)[i] = filterDoCompare(gDataCompare[cunit->func], cunit->optr, colData, cunit->valData); } diff --git a/src/util/src/tcompare.c b/src/util/src/tcompare.c index 07bd8061e0..1697d4304e 100644 --- a/src/util/src/tcompare.c +++ b/src/util/src/tcompare.c @@ -540,6 +540,8 @@ __compar_fn_t getComparFunc(int32_t type, int32_t optr) { comparFn = compareStrRegexCompMatch; } else if (optr == TSDB_RELATION_NMATCH) { comparFn = compareStrRegexCompNMatch; + } else if (optr == TSDB_RELATION_LIKE) { /* wildcard query using like operator */ + comparFn = compareWStrPatternComp; } else if (optr == TSDB_RELATION_QUESTION) { comparFn = compareStrContainJson; } else { diff --git a/tests/pytest/stable/json_tag.py b/tests/pytest/stable/json_tag.py index a144aa0449..5d551e107b 100644 --- a/tests/pytest/stable/json_tag.py +++ b/tests/pytest/stable/json_tag.py @@ -142,20 +142,14 @@ class TDTestCase: tdSql.query("select *,tbname from db_json_tag_test.jsons1 where (jtag->'location' like 'bei%' or jtag->'num'=34) and jtag->'class'=55") tdSql.checkRows(0) - tdSql.error("select * from db_json_tag_test.jsons1 where jtag->'num' like '5%'") + tdSql.query("select * from db_json_tag_test.jsons1 where jtag->'num' like '5%'") + tdSql.checkRows(0) # test where condition in - tdSql.query("select * from db_json_tag_test.jsons1 where jtag->'location' in ('beijing')") - tdSql.checkRows(2) - - tdSql.query("select * from db_json_tag_test.jsons1 where jtag->'num' in (5,34)") - tdSql.checkRows(2) + tdSql.error("select * from db_json_tag_test.jsons1 where jtag->'location' in ('beijing')") tdSql.error("select * from db_json_tag_test.jsons1 where jtag->'num' in ('5',34)") - tdSql.query("select * from db_json_tag_test.jsons1 where jtag->'location' in ('shanghai') and jtag->'class'=55") - tdSql.checkRows(1) - # test where condition match tdSql.query("select * from db_json_tag_test.jsons1 where jtag->'location' match 'jin$'") tdSql.checkRows(0) @@ -166,7 +160,8 @@ class TDTestCase: tdSql.query("select * from db_json_tag_test.jsons1 where datastr match 'json' and jtag->'location' match 'jin'") tdSql.checkRows(2) - tdSql.error("select * from db_json_tag_test.jsons1 where jtag->'num' match '5'") + tdSql.query("select * from db_json_tag_test.jsons1 where jtag->'num' match '5'") + tdSql.checkRows(0) # test json string parse tdSql.error("CREATE TABLE if not exists db_json_tag_test.jsons1_5 using db_json_tag_test.jsons1 tags('efwewf')") -- GitLab