From c7e7694a55d55476c89bd4282c23c4d07aa1bb0c Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Sat, 21 May 2022 16:21:56 +0800 Subject: [PATCH 1/4] fea: add null tag support in schemaless --- source/client/src/clientSml.c | 16 +++++++--------- source/client/test/smlTest.cpp | 3 ++- source/common/src/tdataformat.c | 8 +++++--- source/common/src/tname.c | 7 ++----- source/libs/parser/src/parInsert.c | 6 +++--- 5 files changed, 19 insertions(+), 21 deletions(-) diff --git a/source/client/src/clientSml.c b/source/client/src/clientSml.c index e884748fff..61282ae76a 100644 --- a/source/client/src/clientSml.c +++ b/source/client/src/clientSml.c @@ -263,7 +263,7 @@ static int32_t smlBuildColumnDescription(SSmlKv* field, char* buf, int32_t bufSi memcpy(tname, field->key, field->keyLen); if (type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR) { int32_t bytes = field->length > CHAR_SAVE_LENGTH ? (2*field->length) : CHAR_SAVE_LENGTH; - int out = snprintf(buf, bufSize,"`%s` %s(%d)", + int out = snprintf(buf, bufSize, "`%s` %s(%d)", tname, tDataTypes[field->type].name, bytes); *outBytes = out; } else { @@ -400,6 +400,12 @@ static int32_t smlApplySchemaAction(SSmlHandle* info, SSchemaAction* action) { pos += outBytes; freeBytes -= outBytes; *pos = ','; ++pos; --freeBytes; } + if(taosArrayGetSize(cols) == 0){ + outBytes = snprintf(pos, freeBytes,"`%s` %s(%d)", + TAG, tDataTypes[TSDB_DATA_TYPE_NCHAR].name, CHAR_SAVE_LENGTH); + pos += outBytes; freeBytes -= outBytes; + *pos = ','; ++pos; --freeBytes; + } pos--; ++freeBytes; outBytes = snprintf(pos, freeBytes, ")"); TAOS_RES* res = taos_query(info->taos, result); @@ -1112,14 +1118,6 @@ static int32_t smlParseTelnetString(SSmlHandle *info, const char* sql, SSmlTable static int32_t smlParseCols(const char* data, int32_t len, SArray *cols, char *childTableName, bool isTag, SHashObj *dumplicateKey, SSmlMsgBuf *msg){ if(isTag && len == 0){ - SSmlKv *kv = (SSmlKv *)taosMemoryCalloc(sizeof(SSmlKv), 1); - if(!kv) return TSDB_CODE_OUT_OF_MEMORY; - kv->key = TAG; - kv->keyLen = TAG_LEN; - kv->value = TAG_VALUE; - kv->length = TAG_VALUE_LEN; - kv->type = TSDB_DATA_TYPE_NCHAR; - if(cols) taosArrayPush(cols, &kv); return TSDB_CODE_SUCCESS; } diff --git a/source/client/test/smlTest.cpp b/source/client/test/smlTest.cpp index c7935b351c..2165189153 100644 --- a/source/client/test/smlTest.cpp +++ b/source/client/test/smlTest.cpp @@ -1207,7 +1207,8 @@ TEST(testCase, sml_TD15662_Test) { ASSERT_NE(info, nullptr); const char *sql[] = { - "hetrey,id=sub_table_0123456,t0=f,t1=127i8,t2=32767i16,t3=2147483647i32,t4=9223372036854775807i64,t5=11.12345f32,t6=22.123456789f64,t7=\"binaryTagValue\",t8=L\"ncharTagValue\" c0=f,c1=127i8,c2=32767i16,c3=2147483647i32,c4=9223372036854775807i64,c5=11.12345f32,c6=22.123456789f64,c7=\"binaryColValue\",c8=L\"ncharColValue\",c9=7u64", + "hetrey c0=f,c1=127i8 1626006833639", + "hetrey,t1=r c0=f,c1=127i8 1626006833640", }; int ret = smlProcess(info, (char **)sql, sizeof(sql) / sizeof(sql[0])); ASSERT_EQ(ret, 0); diff --git a/source/common/src/tdataformat.c b/source/common/src/tdataformat.c index 8aa8ed2f14..fe112ba67e 100644 --- a/source/common/src/tdataformat.c +++ b/source/common/src/tdataformat.c @@ -1077,7 +1077,7 @@ void tdResetKVRowBuilder(SKVRowBuilder *pBuilder) { SKVRow tdGetKVRowFromBuilder(SKVRowBuilder *pBuilder) { int tlen = sizeof(SColIdx) * pBuilder->nCols + pBuilder->size; - if (tlen == 0) return NULL; + // if (tlen == 0) return NULL; // nCols == 0 means no tags tlen += TD_KV_ROW_HEAD_SIZE; @@ -1087,8 +1087,10 @@ SKVRow tdGetKVRowFromBuilder(SKVRowBuilder *pBuilder) { kvRowSetNCols(row, pBuilder->nCols); kvRowSetLen(row, tlen); - memcpy(kvRowColIdx(row), pBuilder->pColIdx, sizeof(SColIdx) * pBuilder->nCols); - memcpy(kvRowValues(row), pBuilder->buf, pBuilder->size); + if(pBuilder->nCols > 0){ + memcpy(kvRowColIdx(row), pBuilder->pColIdx, sizeof(SColIdx) * pBuilder->nCols); + memcpy(kvRowValues(row), pBuilder->buf, pBuilder->size); + } return row; } diff --git a/source/common/src/tname.c b/source/common/src/tname.c index 0764ea84b9..104dee261c 100644 --- a/source/common/src/tname.c +++ b/source/common/src/tname.c @@ -308,13 +308,10 @@ static int compareKv(const void* p1, const void* p2) { * use stable name and tags to grearate child table name */ void buildChildTableName(RandTableName* rName) { - int32_t size = taosArrayGetSize(rName->tags); - ASSERT(size > 0); - taosArraySort(rName->tags, compareKv); - SStringBuilder sb = {0}; taosStringBuilderAppendStringLen(&sb, rName->sTableName, rName->sTableNameLen); - for (int j = 0; j < size; ++j) { + taosArraySort(rName->tags, compareKv); + for (int j = 0; j < taosArrayGetSize(rName->tags); ++j) { SSmlKv* tagKv = taosArrayGetP(rName->tags, j); taosStringBuilderAppendStringLen(&sb, tagKv->key, tagKv->keyLen); if(IS_VAR_DATA_TYPE(tagKv->type)){ diff --git a/source/libs/parser/src/parInsert.c b/source/libs/parser/src/parInsert.c index d1b4a745b9..795bed3a05 100644 --- a/source/libs/parser/src/parInsert.c +++ b/source/libs/parser/src/parInsert.c @@ -818,7 +818,7 @@ static int32_t parseTagsClause(SInsertParseContext* pCxt, SSchema* pSchema, uint SKVRow row = tdGetKVRowFromBuilder(&pCxt->tagsBuilder); if (NULL == row) { - return buildInvalidOperationMsg(&pCxt->msg, "tag value expected"); + return buildInvalidOperationMsg(&pCxt->msg, "out of memory"); } tdSortKVRowByColIdx(row); @@ -1333,7 +1333,7 @@ int32_t qBindStmtTagsValue(void* pBlock, void* boundTags, int64_t suid, char* tN SKVRow row = tdGetKVRowFromBuilder(&tagBuilder); if (NULL == row) { tdDestroyKVRowBuilder(&tagBuilder); - return buildInvalidOperationMsg(&pBuf, "tag value expected"); + return buildInvalidOperationMsg(&pBuf, "out of memory"); } tdSortKVRowByColIdx(row); @@ -1682,7 +1682,7 @@ static int32_t smlBuildTagRow(SArray* cols, SKVRowBuilder* tagsBuilder, SParsedD *row = tdGetKVRowFromBuilder(tagsBuilder); if (*row == NULL) { - return TSDB_CODE_SML_INVALID_DATA; + return TSDB_CODE_OUT_OF_MEMORY; } tdSortKVRowByColIdx(*row); return TSDB_CODE_SUCCESS; From 0000fa8418ee95b7a6ca59fa0c07b75c4d76d4f7 Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Sat, 21 May 2022 16:37:37 +0800 Subject: [PATCH 2/4] fea: add null tag support in schemaless --- include/common/tglobal.h | 1 + source/client/src/clientSml.c | 6 +----- source/common/src/tglobal.c | 2 ++ 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/include/common/tglobal.h b/include/common/tglobal.h index 111241cf03..2a4ef565dd 100644 --- a/include/common/tglobal.h +++ b/include/common/tglobal.h @@ -128,6 +128,7 @@ extern bool tsStartUdfd; // schemaless extern char tsSmlChildTableName[]; +extern char tsSmlTagName[]; extern bool tsSmlDataFormat; // internal diff --git a/source/client/src/clientSml.c b/source/client/src/clientSml.c index 61282ae76a..8b2f47b295 100644 --- a/source/client/src/clientSml.c +++ b/source/client/src/clientSml.c @@ -63,10 +63,6 @@ for (int i = 1; i < keyLen; ++i) { \ #define TS "_ts" #define TS_LEN 3 -#define TAG "_tag" -#define TAG_LEN 4 -#define TAG_VALUE "NULL" -#define TAG_VALUE_LEN 4 #define VALUE "value" #define VALUE_LEN 5 @@ -402,7 +398,7 @@ static int32_t smlApplySchemaAction(SSmlHandle* info, SSchemaAction* action) { } if(taosArrayGetSize(cols) == 0){ outBytes = snprintf(pos, freeBytes,"`%s` %s(%d)", - TAG, tDataTypes[TSDB_DATA_TYPE_NCHAR].name, CHAR_SAVE_LENGTH); + tsSmlTagName, tDataTypes[TSDB_DATA_TYPE_NCHAR].name, CHAR_SAVE_LENGTH); pos += outBytes; freeBytes -= outBytes; *pos = ','; ++pos; --freeBytes; } diff --git a/source/common/src/tglobal.c b/source/common/src/tglobal.c index d74d5a4d4e..bd7a04c991 100644 --- a/source/common/src/tglobal.c +++ b/source/common/src/tglobal.c @@ -78,6 +78,7 @@ char tsTelemServer[TSDB_FQDN_LEN] = "telemetry.taosdata.com"; uint16_t tsTelemPort = 80; // schemaless +char tsSmlTagName[TSDB_COL_NAME_LEN] = "__tag"; char tsSmlChildTableName[TSDB_TABLE_NAME_LEN] = ""; //user defined child table name can be specified in tag value. //If set to empty system will generate table name using MD5 hash. bool tsSmlDataFormat = true; // true means that the name and order of cols in each line are the same(only for influx protocol) @@ -522,6 +523,7 @@ static int32_t taosSetClientCfg(SConfig *pCfg) { } tstrncpy(tsSmlChildTableName, cfgGetItem(pCfg, "smlChildTableName")->str, TSDB_TABLE_NAME_LEN); + tstrncpy(tsSmlTagName, cfgGetItem(pCfg, "smlTagName")->str, TSDB_COL_NAME_LEN); tsSmlDataFormat = cfgGetItem(pCfg, "smlDataFormat")->bval; tsShellActivityTimer = cfgGetItem(pCfg, "shellActivityTimer")->i32; From db93c49ab0b67bd16213fdaa267ea933aef891b4 Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Sat, 21 May 2022 16:53:25 +0800 Subject: [PATCH 3/4] fea: add null tag support in schemaless --- source/client/test/smlTest.cpp | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/source/client/test/smlTest.cpp b/source/client/test/smlTest.cpp index 2165189153..217699e360 100644 --- a/source/client/test/smlTest.cpp +++ b/source/client/test/smlTest.cpp @@ -269,16 +269,7 @@ TEST(testCase, smlParseCols_tag_Test) { ret = smlParseCols(data, len, cols, NULL, true, dumplicateKey, &msgBuf); ASSERT_EQ(ret, TSDB_CODE_SUCCESS); size = taosArrayGetSize(cols); - ASSERT_EQ(size, 1); - - // nchar - kv = (SSmlKv *)taosArrayGetP(cols, 0); - ASSERT_EQ(strncasecmp(kv->key, TAG, TAG_LEN), 0); - ASSERT_EQ(kv->keyLen, TAG_LEN); - ASSERT_EQ(kv->type, TSDB_DATA_TYPE_NCHAR); - ASSERT_EQ(kv->length, TAG_LEN); - ASSERT_EQ(strncasecmp(kv->value, TAG_VALUE, TAG_VALUE_LEN), 0); - taosMemoryFree(kv); + ASSERT_EQ(size, 0); taosArrayDestroy(cols); taosHashCleanup(dumplicateKey); From 8fdaa1c12ff1c9101eac4da00c40b8333ec5e71e Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Sat, 21 May 2022 17:29:27 +0800 Subject: [PATCH 4/4] fea: add null tag support in schemaless --- source/common/src/tglobal.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/common/src/tglobal.c b/source/common/src/tglobal.c index bd7a04c991..b8dd33b915 100644 --- a/source/common/src/tglobal.c +++ b/source/common/src/tglobal.c @@ -327,6 +327,7 @@ static int32_t taosAddClientCfg(SConfig *pCfg) { if (cfgAddBool(pCfg, "keepColumnName", tsKeepOriginalColumnName, 1) != 0) return -1; if (cfgAddInt32(pCfg, "queryPolicy", tsQueryPolicy, 1, 3, 1) != 0) return -1; if (cfgAddString(pCfg, "smlChildTableName", "", 1) != 0) return -1; + if (cfgAddString(pCfg, "smlTagName", "", 1) != 0) return -1; if (cfgAddBool(pCfg, "smlDataFormat", tsSmlDataFormat, 1) != 0) return -1; tsNumOfTaskQueueThreads = tsNumOfCores / 4;