Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion source/common/src/tdatablock.c
Original file line number Diff line number Diff line change
Expand Up @@ -1559,7 +1559,10 @@ int32_t blockDataSort(SSDataBlock* pDataBlock, SArray* pOrderInfo) {

terrno = 0;
taosqsort_r(index, rows, sizeof(int32_t), &helper, dataBlockCompar);
if (terrno) return terrno;
if (terrno) {
destroyTupleIndex(index);
return terrno;
}

int64_t p1 = taosGetTimestampUs();

Expand Down
2 changes: 1 addition & 1 deletion source/libs/command/src/command.c
Original file line number Diff line number Diff line change
Expand Up @@ -713,7 +713,7 @@ static int32_t appendTagValues(char* buf, int32_t* len, STableCfg* pCfg, void* c
return terrno;
}
*len += tsnprintf(buf + VARSTR_HEADER_SIZE + *len, SHOW_CREATE_TB_RESULT_FIELD2_LEN - (VARSTR_HEADER_SIZE + *len),
"%s", pJson);
"\'%s\'", pJson);
taosMemoryFree(pJson);
Comment on lines 715 to 717
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

While adding single quotes is correct for SQL string literals, this change doesn't handle cases where the JSON string pJson itself contains single quotes. This would lead to a syntax error in the generated CREATE TABLE statement. The single quotes within the JSON string must be escaped, typically by doubling them (e.g., ' becomes '').

    // Allocate a buffer that can hold the escaped string. In the worst case, every character is a single quote.
    char* escapedJson = taosMemoryAlloc(strlen(pJson) * 2 + 1);
    if (escapedJson) {
      char* writer = escapedJson;
      for (char* reader = pJson; *reader; ++reader) {
        if (*reader == '\'') {
          *writer++ = '\''; // Escape single quote by doubling it
        }
        *writer++ = *reader;
      }
      *writer = '\0';

      *len += tsnprintf(buf + VARSTR_HEADER_SIZE + *len, SHOW_CREATE_TB_RESULT_FIELD2_LEN - (VARSTR_HEADER_SIZE + *len),
                        "'%s'", escapedJson);
      taosMemoryFree(escapedJson);
    }
    taosMemoryFree(pJson);


return TSDB_CODE_SUCCESS;
Expand Down
8 changes: 4 additions & 4 deletions source/libs/executor/src/executil.c
Original file line number Diff line number Diff line change
Expand Up @@ -1350,10 +1350,10 @@ int32_t getColInfoResultForGroupby(void* pVnode, SNodeList* group, STableListInf
isNull[j] = 0;
char* data = colDataGetData(pValue, i);
if (pValue->info.type == TSDB_DATA_TYPE_JSON) {
if (tTagIsJson(data)) {
code = TSDB_CODE_QRY_JSON_IN_GROUP_ERROR;
goto end;
}
// if (tTagIsJson(data)) {
// code = TSDB_CODE_QRY_JSON_IN_GROUP_ERROR;
// goto end;
// }
if (tTagIsJsonNull(data)) {
isNull[j] = 1;
continue;
Expand Down
8 changes: 4 additions & 4 deletions source/libs/executor/src/groupoperator.c
Original file line number Diff line number Diff line change
Expand Up @@ -222,10 +222,10 @@ static void recordNewGroupKeys(SArray* pGroupCols, SArray* pGroupColVals, SSData
pkey->isNull = false;
char* val = colDataGetData(pColInfoData, rowIndex);
if (pkey->type == TSDB_DATA_TYPE_JSON) {
if (tTagIsJson(val)) {
terrno = TSDB_CODE_QRY_JSON_IN_GROUP_ERROR;
return;
}
// if (tTagIsJson(val)) {
// terrno = TSDB_CODE_QRY_JSON_IN_GROUP_ERROR;
// return;
// }
int32_t dataLen = getJsonValueLen(val);
memcpy(pkey->pData, val, dataLen);
} else if (IS_VAR_DATA_TYPE(pkey->type)) {
Expand Down
60 changes: 57 additions & 3 deletions test/cases/11-Functions/01-Scalar/test_fun_sca_to_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,8 @@ def test_fun_sca_to_json(self):
tdSql.execute(f"insert into {dbname}.jsons1_14 using {dbname}.jsons1 tags('{{\"tag1\":\"收到货\",\"tag2\":\"\",\"tag3\":null}}') values(1591062628000, 2, NULL, '你就会', 'dws')")
tdSql.query(f"select distinct jtag->'tag1' from {dbname}.jsons1")
tdSql.checkRows(8)
tdSql.error(f"select distinct jtag from {dbname}.jsons1")
tdSql.query(f"select distinct jtag from {dbname}.jsons1")
tdSql.checkRows(8)

#test dumplicate key with normal colomn
tdSql.execute(f"insert into {dbname}.jsons1_15 using {dbname}.jsons1 tags('{{\"tbname\":\"tt\",\"databool\":true,\"datastr\":\"是是是\"}}') values(1591060828000, 4, false, 'jjsf', \"你就会\")")
Expand Down Expand Up @@ -425,8 +426,8 @@ def test_fun_sca_to_json(self):
tdSql.checkData(2, 1, '"femail"')
tdSql.checkData(7, 1, "false")

tdSql.error(f"select count(*) from {dbname}.jsons1 group by jtag")
tdSql.error(f"select count(*) from {dbname}.jsons1 partition by jtag")
tdSql.query(f"select count(*) from {dbname}.jsons1 group by jtag")
tdSql.query(f"select count(*) from {dbname}.jsons1 partition by jtag")
tdSql.error(f"select count(*) from {dbname}.jsons1 group by jtag order by jtag")
tdSql.error(f"select count(*) from {dbname}.jsons1 group by jtag->'tag1' order by jtag->'tag2'")
tdSql.error(f"select count(*) from {dbname}.jsons1 group by jtag->'tag1' order by jtag")
Expand Down Expand Up @@ -704,6 +705,59 @@ def test_fun_sca_to_json(self):
tdSql.execute(f"insert into {dbname}.jsons_13918_4 using {dbname}.jsons_stb tags(\"NULL\") values(1591061628006, 11)")
tdSql.query(f"select * from {dbname}.jsons_stb")
tdSql.checkRows(4)

createSql = r'''CREATE TABLE `jsons1_t1` USING `jsons1` (`jtag`) TAGS ('{"tag1":5,"tag2":"beijing"}')'''
tdSql.execute(createSql)
tdSql.query(f"show create table {dbname}.jsons1_t1")
tdSql.checkRows(1)
tdSql.checkData(0, 1, createSql)

createSql = r'''CREATE TABLE `jsons1_t2` USING `jsons1` (`jtag`) TAGS ('{"tag1":false,"tag2":"beijing"}')'''
tdSql.execute(createSql)
tdSql.query(f"show create table {dbname}.jsons1_t2")
tdSql.checkRows(1)

createSql = r'''CREATE TABLE `jsons1_t3` USING `jsons1` (`jtag`) TAGS ('null')'''
tdSql.execute(createSql)
tdSql.query(f"show create table {dbname}.jsons1_t3")
tdSql.checkRows(1)
tdSql.checkData(0, 1, createSql)


sql = f"SELECT distinct tbname, jtag from {dbname}.jsons1 where tbname IN('jsons1_t1', 'jsons1_t2', 'jsons1_t3')"
tdSql.query(sql)
tdSql.checkRows(3)

# select count(*) from db.jsons1;
sql = f"select jtag->'tag1', count(*) from {dbname}.jsons1 group by jtag->'tag1'"
tdSql.query(sql)
tdSql.checkRows(7)

sql = f"select jtag, count(*) from {dbname}.jsons1 group by jtag"
tdSql.query(sql)
tdSql.checkRows(10)

sql = f"select jtag->'tag1', count(*) from {dbname}.jsons1 group by jtag"
tdSql.query(sql)
tdSql.checkRows(10)

sql = f"select jtag, count(*) from {dbname}.jsons1 group by jtag->'tag1'"
tdSql.error(sql)

sql = f"select jtag->'tag1', count(*) from {dbname}.jsons1 partition by jtag->'tag1'"
tdSql.query(sql)
tdSql.checkRows(7)

sql = f"select jtag, count(*) from {dbname}.jsons1 partition by jtag"
tdSql.query(sql)
tdSql.checkRows(10)

sql = f"select jtag->'tag1', count(*) from {dbname}.jsons1 partition by jtag"
tdSql.query(sql)
tdSql.checkRows(10)

sql = f"select jtag, count(*) from {dbname}.jsons1 partition by jtag->'tag1'"
tdSql.error(sql)

#tdSql.close()
tdLog.success("%s successfully executed" % __file__)
Loading