diff --git a/include/common/tcommon.h b/include/common/tcommon.h index 80125d67880043759e86fddb70483480edd7cecf..9e3ad42a82fe779bc507417d84718b342a98a34e 100644 --- a/include/common/tcommon.h +++ b/include/common/tcommon.h @@ -201,18 +201,17 @@ typedef struct SExprInfo { } SExprInfo; typedef struct { - const char* key; - int32_t keyLen; - uint8_t type; - int16_t length; + const char* key; + int32_t keyLen; + uint8_t type; union{ const char* value; - int64_t i; - uint64_t u; - double d; - float f; + int64_t i; + uint64_t u; + double d; + float f; }; - int32_t valueLen; + int32_t length; } SSmlKv; #define QUERY_ASC_FORWARD_STEP 1 diff --git a/source/client/src/clientSml.c b/source/client/src/clientSml.c index dfb1942824404a8ec6a2207a82065c7bcf7c2f51..605d71ffedddbda4b8dcb66f9495df281fc6dd92 100644 --- a/source/client/src/clientSml.c +++ b/source/client/src/clientSml.c @@ -54,29 +54,29 @@ typedef enum { } ESchemaAction; typedef struct { - char sTableName[TSDB_TABLE_NAME_LEN]; - SArray *tags; - SArray *fields; + char sTableName[TSDB_TABLE_NAME_LEN]; + SArray *tags; + SArray *fields; } SCreateSTableActionInfo; typedef struct { - char sTableName[TSDB_TABLE_NAME_LEN]; - SSmlKv * field; + char sTableName[TSDB_TABLE_NAME_LEN]; + SSmlKv *field; } SAlterSTableActionInfo; typedef struct { - ESchemaAction action; + ESchemaAction action; union { SCreateSTableActionInfo createSTable; - SAlterSTableActionInfo alterSTable; + SAlterSTableActionInfo alterSTable; }; } SSchemaAction; typedef struct { - const char* measure; - const char* tags; - const char* cols; - const char* timestamp; + const char *measure; + const char *tags; + const char *cols; + const char *timestamp; int32_t measureLen; int32_t measureTagsLen; @@ -103,7 +103,7 @@ typedef struct { SHashObj *tagHash; // elements are SArray *cols; - SHashObj *fieldHash; + SHashObj *colHash; STableMeta *tableMeta; } SSmlSTableMeta; @@ -180,6 +180,7 @@ static inline bool smlCheckDuplicateKey(const char *key, int32_t keyLen, SHashOb } static int32_t smlBuildInvalidDataMsg(SSmlMsgBuf* pBuf, const char *msg1, const char *msg2) { + memset(pBuf->buf, 0 , pBuf->len); if(msg1) strncat(pBuf->buf, msg1, pBuf->len); int32_t left = pBuf->len - strlen(pBuf->buf); if(left > 2 && msg2) { @@ -189,47 +190,39 @@ static int32_t smlBuildInvalidDataMsg(SSmlMsgBuf* pBuf, const char *msg1, const return TSDB_CODE_SML_INVALID_DATA; } -static int32_t smlGenerateSchemaAction(SSchema* pointColField, SHashObj* dbAttrHash, SArray* dbAttrArray, bool isTag, char sTableName[], +static int32_t smlGenerateSchemaAction(SSchema* colField, SHashObj* colHash, SSmlKv* kv, bool isTag, SSchemaAction* action, bool* actionNeeded, SSmlHandle* info) { -// char fieldName[TSDB_COL_NAME_LEN] = {0}; -// strcpy(fieldName, pointColField->name); -// -// size_t* pDbIndex = taosHashGet(dbAttrHash, fieldName, strlen(fieldName)); -// if (pDbIndex) { -// SSchema* dbAttr = taosArrayGet(dbAttrArray, *pDbIndex); -// assert(strcasecmp(dbAttr->name, pointColField->name) == 0); -// if (pointColField->type != dbAttr->type) { -// uError("SML:0x%"PRIx64" point type and db type mismatch. key: %s. point type: %d, db type: %d", info->id, pointColField->name, -// pointColField->type, dbAttr->type); -// return TSDB_CODE_TSC_INVALID_VALUE; -// } -// -// if (IS_VAR_DATA_TYPE(pointColField->type) && (pointColField->bytes > dbAttr->bytes)) { -// if (isTag) { -// action->action = SCHEMA_ACTION_CHANGE_TAG_SIZE; -// } else { -// action->action = SCHEMA_ACTION_CHANGE_COLUMN_SIZE; -// } -// memset(&action->alterSTable, 0, sizeof(SAlterSTableActionInfo)); -// memcpy(action->alterSTable.sTableName, sTableName, TSDB_TABLE_NAME_LEN); -// action->alterSTable.field = pointColField; -// *actionNeeded = true; -// } -// } else { -// if (isTag) { -// action->action = SCHEMA_ACTION_ADD_TAG; -// } else { -// action->action = SCHEMA_ACTION_ADD_COLUMN; -// } -// memset(&action->alterSTable, 0, sizeof(SAlterSTableActionInfo)); -// memcpy(action->alterSTable.sTableName, sTableName, TSDB_TABLE_NAME_LEN); -// action->alterSTable.field = pointColField; -// *actionNeeded = true; -// } -// if (*actionNeeded) { -// uDebug("SML:0x%" PRIx64 " generate schema action. column name: %s, action: %d", info->id, fieldName, -// action->action); -// } + uint16_t *index = (uint16_t *)taosHashGet(colHash, kv->key, kv->keyLen); + if (index) { + if (colField[*index].type != kv->type) { + uError("SML:0x%"PRIx64" point type and db type mismatch. key: %s. point type: %d, db type: %d", info->id, kv->key, + colField[*index].type, kv->type); + return TSDB_CODE_TSC_INVALID_VALUE; + } + + if ((colField[*index].type == TSDB_DATA_TYPE_VARCHAR && (colField[*index].bytes - VARSTR_HEADER_SIZE) < kv->length) || + (colField[*index].type == TSDB_DATA_TYPE_NCHAR &&((colField[*index].bytes - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE < kv->length))) { + if (isTag) { + action->action = SCHEMA_ACTION_CHANGE_TAG_SIZE; + } else { + action->action = SCHEMA_ACTION_CHANGE_COLUMN_SIZE; + } + action->alterSTable.field = kv; + *actionNeeded = true; + } + } else { + if (isTag) { + action->action = SCHEMA_ACTION_ADD_TAG; + } else { + action->action = SCHEMA_ACTION_ADD_COLUMN; + } + action->alterSTable.field = kv; + *actionNeeded = true; + } + if (*actionNeeded) { + uDebug("SML:0x%" PRIx64 " generate schema action. column name: %s, action: %d", info->id, colField->name, + action->action); + } return 0; } @@ -238,9 +231,9 @@ static int32_t smlBuildColumnDescription(SSmlKv* field, char* buf, int32_t bufSi char tname[TSDB_TABLE_NAME_LEN] = {0}; memcpy(tname, field->key, field->keyLen); if (type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR) { - int32_t bytes = field->valueLen; // todo + int32_t bytes = field->length; // todo int out = snprintf(buf, bufSize,"`%s` %s(%d)", - tname,tDataTypes[field->type].name, bytes); + tname, tDataTypes[field->type].name, bytes); *outBytes = out; } else { int out = snprintf(buf, bufSize, "`%s` %s", tname, tDataTypes[type].name); @@ -259,7 +252,7 @@ static int32_t smlApplySchemaAction(SSmlHandle* info, SSchemaAction* action) { uDebug("SML:0x%"PRIx64" apply schema action. action: %d", info->id, action->action); switch (action->action) { case SCHEMA_ACTION_ADD_COLUMN: { - int n = sprintf(result, "alter stable %s add column ", action->alterSTable.sTableName); + int n = sprintf(result, "alter stable `%s` add column ", action->alterSTable.sTableName); smlBuildColumnDescription(action->alterSTable.field, result+n, capacity-n, &outBytes); TAOS_RES* res = taos_query(info->taos, result); //TODO async doAsyncQuery code = taos_errno(res); @@ -282,7 +275,7 @@ static int32_t smlApplySchemaAction(SSmlHandle* info, SSchemaAction* action) { break; } case SCHEMA_ACTION_ADD_TAG: { - int n = sprintf(result, "alter stable %s add tag ", action->alterSTable.sTableName); + int n = sprintf(result, "alter stable `%s` add tag ", action->alterSTable.sTableName); smlBuildColumnDescription(action->alterSTable.field, result+n, capacity-n, &outBytes); TAOS_RES* res = taos_query(info->taos, result); //TODO async doAsyncQuery @@ -306,7 +299,7 @@ static int32_t smlApplySchemaAction(SSmlHandle* info, SSchemaAction* action) { break; } case SCHEMA_ACTION_CHANGE_COLUMN_SIZE: { - int n = sprintf(result, "alter stable %s modify column ", action->alterSTable.sTableName); + int n = sprintf(result, "alter stable `%s` modify column ", action->alterSTable.sTableName); smlBuildColumnDescription(action->alterSTable.field, result+n, capacity-n, &outBytes); TAOS_RES* res = taos_query(info->taos, result); //TODO async doAsyncQuery @@ -329,7 +322,7 @@ static int32_t smlApplySchemaAction(SSmlHandle* info, SSchemaAction* action) { break; } case SCHEMA_ACTION_CHANGE_TAG_SIZE: { - int n = sprintf(result, "alter stable %s modify tag ", action->alterSTable.sTableName); + int n = sprintf(result, "alter stable `%s` modify tag ", action->alterSTable.sTableName); smlBuildColumnDescription(action->alterSTable.field, result+n, capacity-n, &outBytes); TAOS_RES* res = taos_query(info->taos, result); //TODO async doAsyncQuery @@ -408,6 +401,25 @@ static int32_t smlApplySchemaAction(SSmlHandle* info, SSchemaAction* action) { return code; } +static int32_t smlProcessSchemaAction(SSmlHandle* info, SSchema* schemaField, SHashObj* schemaHash, SArray *cols, SSchemaAction* action, bool isTag){ + int32_t code = TSDB_CODE_SUCCESS; + for (int j = 0; j < taosArrayGetSize(cols); ++j) { + SSmlKv* kv = (SSmlKv*)taosArrayGetP(cols, j); + bool actionNeeded = false; + code = smlGenerateSchemaAction(schemaField, schemaHash, kv, isTag, action, &actionNeeded, info); + if(code != TSDB_CODE_SUCCESS){ + return code; + } + if (actionNeeded) { + code = smlApplySchemaAction(info, action); + if (code != TSDB_CODE_SUCCESS) { + return code; + } + } + } + return TSDB_CODE_SUCCESS; +} + static int32_t smlModifyDBSchemas(SSmlHandle* info) { int32_t code = 0; @@ -427,27 +439,50 @@ static int32_t smlModifyDBSchemas(SSmlHandle* info) { code = catalogGetSTableMeta(info->pCatalog, info->taos->pAppInfo->pTransporter, &ep, &pName, &pTableMeta); if (code == TSDB_CODE_PAR_TABLE_NOT_EXIST || code == TSDB_CODE_MND_INVALID_STB) { - SSchemaAction schemaAction = { SCHEMA_ACTION_CREATE_STABLE, 0}; + SSchemaAction schemaAction = { .action = SCHEMA_ACTION_CREATE_STABLE, .createSTable = {0}}; memcpy(schemaAction.createSTable.sTableName, superTable, superTableLen); schemaAction.createSTable.tags = sTableData->tags; schemaAction.createSTable.fields = sTableData->cols; code = smlApplySchemaAction(info, &schemaAction); - if (code != 0) { + if (code != TSDB_CODE_SUCCESS) { uError("SML:0x%"PRIx64" smlApplySchemaAction failed. can not create %s", info->id, schemaAction.createSTable.sTableName); return code; } + info->cost.numOfCreateSTables++; + }else if (code == TSDB_CODE_SUCCESS) { + SHashObj *hashTmp = taosHashInit(pTableMeta->tableInfo.numOfTags, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK); + for(uint16_t i = pTableMeta->tableInfo.numOfColumns; i < pTableMeta->tableInfo.numOfColumns + pTableMeta->tableInfo.numOfTags; i++){ + taosHashPut(hashTmp, pTableMeta->schema[i].name, strlen(pTableMeta->schema[i].name), &i, SHORT_BYTES); + } - code = catalogGetSTableMeta(info->pCatalog, info->taos->pAppInfo->pTransporter, &ep, &pName, &pTableMeta); - if (code != 0) { - uError("SML:0x%"PRIx64" catalogGetSTableMeta failed. super table name %s", info->id, schemaAction.createSTable.sTableName); + SSchemaAction schemaAction = {.alterSTable = {0}}; + memcpy(schemaAction.createSTable.sTableName, superTable, superTableLen); + code = smlProcessSchemaAction(info, pTableMeta->schema, hashTmp, sTableData->tags, &schemaAction, true); + if (code != TSDB_CODE_SUCCESS) { + taosHashCleanup(hashTmp); + return code; + } + + taosHashClear(hashTmp); + for(uint16_t i = 0; i < pTableMeta->tableInfo.numOfColumns; i++){ + taosHashPut(hashTmp, pTableMeta->schema[i].name, strlen(pTableMeta->schema[i].name), &i, SHORT_BYTES); + } + code = smlProcessSchemaAction(info, pTableMeta->schema, hashTmp, sTableData->cols, &schemaAction, false); + taosHashCleanup(hashTmp); + if (code != TSDB_CODE_SUCCESS) { return code; } - info->cost.numOfCreateSTables++; - }else if (code == TSDB_CODE_SUCCESS) { } else { uError("SML:0x%"PRIx64" load table meta error: %s", info->id, tstrerror(code)); return code; } + if(pTableMeta) taosMemoryFree(pTableMeta); + + code = catalogGetSTableMeta(info->pCatalog, info->taos->pAppInfo->pTransporter, &ep, &pName, &pTableMeta); + if (code != TSDB_CODE_SUCCESS) { + uError("SML:0x%"PRIx64" catalogGetSTableMeta failed. super table name %s", info->id, (char*)superTable); + return code; + } sTableData->tableMeta = pTableMeta; tableMetaSml = (SSmlSTableMeta**)taosHashIterate(info->superTables, tableMetaSml); @@ -507,7 +542,7 @@ static int32_t smlModifyDBSchemas(SSmlHandle* info) { static bool smlParseNumber(SSmlKv *kvVal, SSmlMsgBuf *msg){ const char *pVal = kvVal->value; - int32_t len = kvVal->valueLen; + int32_t len = kvVal->length; char *endptr = NULL; double result = strtod(pVal, &endptr); if(pVal == endptr){ @@ -591,7 +626,7 @@ static bool smlParseNumber(SSmlKv *kvVal, SSmlMsgBuf *msg){ static bool smlParseBool(SSmlKv *kvVal) { const char *pVal = kvVal->value; - int32_t len = kvVal->valueLen; + int32_t len = kvVal->length; if ((len == 1) && pVal[0] == 't') { kvVal->i = true; return true; @@ -690,7 +725,7 @@ static int8_t smlGetTsTypeByLen(int32_t len) { if (len == TSDB_TIME_PRECISION_SEC_DIGITS) { return TSDB_TIME_PRECISION_SECONDS; } else if (len == TSDB_TIME_PRECISION_MILLI_DIGITS) { - return TSDB_TIME_PRECISION_MILLI_DIGITS; + return TSDB_TIME_PRECISION_MILLI; } else { return -1; } @@ -756,9 +791,12 @@ static int32_t smlParseTS(SSmlHandle* info, const char* data, int32_t len, SArra int64_t ts = 0; if(info->protocol == TSDB_SML_LINE_PROTOCOL){ ts = smlParseInfluxTime(info, data, len); - }else{ + }else if(info->protocol == TSDB_SML_TELNET_PROTOCOL){ ts = smlParseOpenTsdbTime(info, data, len); + }else{ + ASSERT(0); } + if(ts == -1) return TSDB_CODE_TSC_INVALID_TIME_STAMP; // add ts to @@ -778,18 +816,16 @@ static int32_t smlParseTS(SSmlHandle* info, const char* data, int32_t len, SArra static bool smlParseValue(SSmlKv *pVal, SSmlMsgBuf *msg) { //binary - if (smlIsBinary(pVal->value, pVal->valueLen)) { + if (smlIsBinary(pVal->value, pVal->length)) { pVal->type = TSDB_DATA_TYPE_BINARY; - pVal->valueLen -= BINARY_ADD_LEN; - pVal->length = pVal->valueLen; + pVal->length -= BINARY_ADD_LEN; pVal->value += (BINARY_ADD_LEN - 1); return true; } //nchar - if (smlIsNchar(pVal->value, pVal->valueLen)) { + if (smlIsNchar(pVal->value, pVal->length)) { pVal->type = TSDB_DATA_TYPE_NCHAR; - pVal->valueLen -= NCHAR_ADD_LEN; - pVal->length = pVal->valueLen; + pVal->length -= NCHAR_ADD_LEN; pVal->value += (NCHAR_ADD_LEN - 1); return true; } @@ -953,8 +989,8 @@ static int32_t smlParseTelnetTags(const char* data, int32_t len, SArray *cols, S kv->key = key; kv->keyLen = keyLen; kv->value = value; - kv->valueLen = valueLen; - kv->type = TSDB_DATA_TYPE_NCHAR; + kv->length = valueLen; + kv->type = TSDB_DATA_TYPE_NCHAR; //todo if(cols) taosArrayPush(cols, &kv); } @@ -1002,7 +1038,7 @@ static int32_t smlParseTelnetString(SSmlHandle *info, const char* sql, SSmlTable kv->key = VALUE; kv->keyLen = VALUE_LEN; kv->value = value; - kv->valueLen = valueLen; + kv->length = valueLen; if(!smlParseValue(kv, &info->msgBuf) || kv->type == TSDB_DATA_TYPE_BINARY || kv->type == TSDB_DATA_TYPE_NCHAR || kv->type == TSDB_DATA_TYPE_BOOL){ return TSDB_CODE_SML_INVALID_DATA; @@ -1028,7 +1064,7 @@ static int32_t smlParseCols(const char* data, int32_t len, SArray *cols, bool is kv->key = TAG; kv->keyLen = TAG_LEN; kv->value = TAG; - kv->valueLen = TAG_LEN; + kv->length = TAG_LEN; kv->type = TSDB_DATA_TYPE_NCHAR; if(cols) taosArrayPush(cols, &kv); return TSDB_CODE_SUCCESS; @@ -1086,7 +1122,7 @@ static int32_t smlParseCols(const char* data, int32_t len, SArray *cols, bool is kv->key = key; kv->keyLen = keyLen; kv->value = value; - kv->valueLen = valueLen; + kv->length = valueLen; if(isTag){ kv->type = TSDB_DATA_TYPE_NCHAR; }else{ @@ -1142,73 +1178,40 @@ static int32_t smlParseCols(const char* data, int32_t len, SArray *cols, bool is // return TSDB_CODE_SUCCESS; //} -static bool smlUpdateMeta(SSmlSTableMeta* tableMeta, SArray *tags, SArray *cols, SSmlMsgBuf *msg){ - if(tags){ - for (int i = 0; i < taosArrayGetSize(tags); ++i) { - SSmlKv *kv = (SSmlKv *)taosArrayGetP(tags, i); - ASSERT(kv->type == TSDB_DATA_TYPE_NCHAR); - - uint8_t *index = (uint8_t *)taosHashGet(tableMeta->tagHash, kv->key, kv->keyLen); - if(index){ - SSmlKv **value = (SSmlKv **)taosArrayGet(tableMeta->tags, *index); - ASSERT((*value)->type == TSDB_DATA_TYPE_NCHAR); - if(kv->valueLen > (*value)->valueLen){ // tags type is nchar - *value = kv; - } - }else{ - size_t tmp = taosArrayGetSize(tableMeta->tags); - ASSERT(tmp <= UINT8_MAX); - uint8_t size = tmp; - taosArrayPush(tableMeta->tags, &kv); - taosHashPut(tableMeta->tagHash, kv->key, kv->keyLen, &size, CHAR_BYTES); - } - } - } - - if(cols){ - for (int i = 1; i < taosArrayGetSize(cols); ++i) { //jump timestamp - SSmlKv *kv = (SSmlKv *)taosArrayGetP(cols, i); +static bool smlUpdateMeta(SHashObj *metaHash, SArray *metaArray, SArray *cols, SSmlMsgBuf *msg){ + for (int i = 0; i < taosArrayGetSize(cols); ++i) { //jump timestamp + SSmlKv *kv = (SSmlKv *)taosArrayGetP(cols, i); - int16_t *index = (int16_t *)taosHashGet(tableMeta->fieldHash, kv->key, kv->keyLen); - if(index){ - SSmlKv **value = (SSmlKv **)taosArrayGet(tableMeta->cols, *index); - if(kv->type != (*value)->type){ - smlBuildInvalidDataMsg(msg, "the type is not the same like before", kv->key); - return false; - }else{ - if(IS_VAR_DATA_TYPE(kv->type)){ // update string len, if bigger - if(kv->valueLen > (*value)->valueLen){ - *value = kv; - } + int16_t *index = (int16_t *)taosHashGet(metaHash, kv->key, kv->keyLen); + if(index){ + SSmlKv **value = (SSmlKv **)taosArrayGet(metaArray, *index); + if(kv->type != (*value)->type){ + smlBuildInvalidDataMsg(msg, "the type is not the same like before", kv->key); + return false; + }else{ + if(IS_VAR_DATA_TYPE(kv->type)){ // update string len, if bigger + if(kv->length > (*value)->length){ + *value = kv; } } - }else{ - size_t tmp = taosArrayGetSize(tableMeta->cols); - ASSERT(tmp <= INT16_MAX); - int16_t size = tmp; - taosArrayPush(tableMeta->cols, &kv); - taosHashPut(tableMeta->fieldHash, kv->key, kv->keyLen, &size, SHORT_BYTES); } + }else{ + size_t tmp = taosArrayGetSize(metaArray); + ASSERT(tmp <= INT16_MAX); + int16_t size = tmp; + taosArrayPush(metaArray, &kv); + taosHashPut(metaHash, kv->key, kv->keyLen, &size, SHORT_BYTES); } } + return true; } -static void smlInsertMeta(SSmlSTableMeta* tableMeta, SArray *tags, SArray *cols){ - if(tags){ - for (uint8_t i = 0; i < taosArrayGetSize(tags); ++i) { - SSmlKv *kv = (SSmlKv *)taosArrayGetP(tags, i); - taosArrayPush(tableMeta->tags, &kv); - taosHashPut(tableMeta->tagHash, kv->key, kv->keyLen, &i, CHAR_BYTES); - } - } - - if(cols){ - for (int16_t i = 0; i < taosArrayGetSize(cols); ++i) { - SSmlKv *kv = (SSmlKv *)taosArrayGetP(cols, i); - taosArrayPush(tableMeta->cols, &kv); - taosHashPut(tableMeta->fieldHash, kv->key, kv->keyLen, &i, SHORT_BYTES); - } +static void smlInsertMeta(SHashObj *metaHash, SArray *metaArray, SArray *cols){ + for (int16_t i = 0; i < taosArrayGetSize(cols); ++i) { + SSmlKv *kv = (SSmlKv *)taosArrayGetP(cols, i); + taosArrayPush(metaArray, &kv); + taosHashPut(metaHash, kv->key, kv->keyLen, &i, SHORT_BYTES); } } @@ -1236,12 +1239,16 @@ cleanup: return NULL; } -static void smlDestroyTableInfo(SSmlTableInfo *tag, bool format){ - if(format){ +static void smlDestroyTableInfo(SSmlHandle* info, SSmlTableInfo *tag){ + if(info->dataFormat){ for(size_t i = 0; i < taosArrayGetSize(tag->cols); i++){ SArray *kvArray = (SArray *)taosArrayGetP(tag->cols, i); for (int j = 0; j < taosArrayGetSize(kvArray); ++j) { - void *p = taosArrayGetP(kvArray, j); + SSmlKv *p = (SSmlKv *)taosArrayGetP(kvArray, j); + if(info->protocol == TSDB_SML_JSON_PROTOCOL && + (p->type == TSDB_DATA_TYPE_NCHAR || p->type == TSDB_DATA_TYPE_BINARY)){ + taosMemoryFree((void*)p->value); + } taosMemoryFree(p); } taosArrayDestroy(kvArray); @@ -1257,6 +1264,19 @@ static void smlDestroyTableInfo(SSmlTableInfo *tag, bool format){ taosHashCleanup(kvHash); } } + for(size_t i = 0; i < taosArrayGetSize(tag->tags); i++){ + SSmlKv *p = (SSmlKv *)taosArrayGetP(tag->tags, i); + if(info->protocol == TSDB_SML_JSON_PROTOCOL){ + taosMemoryFree((void*)p->key); + if(p->type == TSDB_DATA_TYPE_NCHAR || p->type == TSDB_DATA_TYPE_BINARY){ + taosMemoryFree((void*)p->value); + } + } + taosMemoryFree(p); + } + if(info->protocol == TSDB_SML_JSON_PROTOCOL && tag->sTableName){ + taosMemoryFree((void*)tag->sTableName); + } taosArrayDestroy(tag->cols); taosArrayDestroy(tag->tags); taosMemoryFree(tag); @@ -1293,8 +1313,8 @@ static SSmlSTableMeta* smlBuildSTableMeta(){ goto cleanup; } - meta->fieldHash = taosHashInit(32, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK); - if (meta->fieldHash == NULL) { + meta->colHash = taosHashInit(32, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK); + if (meta->colHash == NULL) { uError("SML:smlBuildSTableMeta failed to allocate memory"); goto cleanup; } @@ -1319,7 +1339,7 @@ cleanup: static void smlDestroySTableMeta(SSmlSTableMeta *meta){ taosHashCleanup(meta->tagHash); - taosHashCleanup(meta->fieldHash); + taosHashCleanup(meta->colHash); taosArrayDestroy(meta->tags); taosArrayDestroy(meta->cols); taosMemoryFree(meta->tableMeta); @@ -1341,7 +1361,7 @@ static void smlDestroyInfo(SSmlHandle* info){ // destroy info->childTables void** p1 = (void**)taosHashIterate(info->childTables, NULL); while (p1) { - smlDestroyTableInfo((SSmlTableInfo*)(*p1), info->dataFormat); + smlDestroyTableInfo(info, (SSmlTableInfo*)(*p1)); p1 = (void**)taosHashIterate(info->childTables, p1); } taosHashCleanup(info->childTables); @@ -1357,7 +1377,9 @@ static void smlDestroyInfo(SSmlHandle* info){ // destroy info->pVgHash taosHashCleanup(info->pVgHash); taosHashCleanup(info->dumplicateKey); - + if(!info->dataFormat){ + taosArrayDestroy(info->colsContainer); + } taosMemoryFreeClear(info); } @@ -1682,8 +1704,7 @@ static int32_t smlConvertJSONString(SSmlKv *pVal, char* typeStr, cJSON *value) { return TSDB_CODE_TSC_INVALID_JSON_TYPE; } pVal->length = (int16_t)strlen(value->valuestring); - pVal->valueLen = pVal->length; - return smlJsonCreateSring(&pVal->value, value->valuestring, pVal->valueLen); + return smlJsonCreateSring(&pVal->value, value->valuestring, pVal->length); } static int32_t smlParseValueFromJSONObj(cJSON *root, SSmlKv *kv) { @@ -1754,7 +1775,7 @@ static int32_t smlParseValueFromJSON(cJSON *root, SSmlKv *kv) { * user configured parameter tsDefaultJSONStrType */ - char *tsDefaultJSONStrType = "binary"; //todo + char *tsDefaultJSONStrType = "nchar"; //todo smlConvertJSONString(kv, tsDefaultJSONStrType, root); break; } @@ -1994,14 +2015,18 @@ static int32_t smlParseInfluxLine(SSmlHandle* info, const char* sql) { SSmlSTableMeta** tableMeta = (SSmlSTableMeta**)taosHashGet(info->superTables, elements.measure, elements.measureLen); if(tableMeta){ // update meta - ret = smlUpdateMeta(*tableMeta, hasTable ? NULL : (*oneTable)->tags, cols, &info->msgBuf); + ret = smlUpdateMeta((*tableMeta)->colHash, (*tableMeta)->cols, cols, &info->msgBuf); + if(!hasTable && ret){ + ret = smlUpdateMeta((*tableMeta)->tagHash, (*tableMeta)->tags, (*oneTable)->tags, &info->msgBuf); + } if(!ret){ uError("SML:0x%"PRIx64" smlUpdateMeta failed", info->id); return TSDB_CODE_SML_INVALID_DATA; } }else{ SSmlSTableMeta *meta = smlBuildSTableMeta(); - smlInsertMeta(meta, (*oneTable)->tags, cols); + smlInsertMeta(meta->tagHash, meta->tags, (*oneTable)->tags); + smlInsertMeta(meta->colHash, meta->cols, cols); taosHashPut(info->superTables, elements.measure, elements.measureLen, &meta, POINTER_BYTES); } @@ -2026,15 +2051,15 @@ static int32_t smlParseTelnetLine(SSmlHandle* info, void *data) { } if(info->protocol == TSDB_SML_TELNET_PROTOCOL){ - smlParseTelnetString(info, (const char*)data, tinfo, cols); + ret = smlParseTelnetString(info, (const char*)data, tinfo, cols); }else if(info->protocol == TSDB_SML_JSON_PROTOCOL){ - smlParseJSONString(info, (cJSON *)data, tinfo, cols); + ret = smlParseJSONString(info, (cJSON *)data, tinfo, cols); }else{ ASSERT(0); } if(ret != TSDB_CODE_SUCCESS){ uError("SML:0x%"PRIx64" smlParseTelnetLine failed", info->id); - smlDestroyTableInfo(tinfo, true); + smlDestroyTableInfo(info, tinfo); taosArrayDestroy(cols); return ret; } @@ -2057,20 +2082,24 @@ static int32_t smlParseTelnetLine(SSmlHandle* info, void *data) { oneTable = &tinfo; hasTable = false; }else{ - smlDestroyTableInfo(tinfo, true); + smlDestroyTableInfo(info, tinfo); } taosArrayPush((*oneTable)->cols, &cols); SSmlSTableMeta** tableMeta = (SSmlSTableMeta** )taosHashGet(info->superTables, (*oneTable)->sTableName, (*oneTable)->sTableNameLen); if(tableMeta){ // update meta - ret = smlUpdateMeta(*tableMeta, hasTable ? NULL : (*oneTable)->tags, cols, &info->msgBuf); + ret = smlUpdateMeta((*tableMeta)->colHash, (*tableMeta)->cols, cols, &info->msgBuf); + if(!hasTable && ret){ + ret = smlUpdateMeta((*tableMeta)->tagHash, (*tableMeta)->tags, (*oneTable)->tags, &info->msgBuf); + } if(!ret){ uError("SML:0x%"PRIx64" smlUpdateMeta failed", info->id); return TSDB_CODE_SML_INVALID_DATA; } }else{ SSmlSTableMeta *meta = smlBuildSTableMeta(); - smlInsertMeta(meta, (*oneTable)->tags, cols); + smlInsertMeta(meta->tagHash, meta->tags, (*oneTable)->tags); + smlInsertMeta(meta->colHash, meta->cols, cols); taosHashPut(info->superTables, (*oneTable)->sTableName, (*oneTable)->sTableNameLen, &meta, POINTER_BYTES); } diff --git a/source/client/test/smlTest.cpp b/source/client/test/smlTest.cpp index f579489e62480c1247873c09b954debe63db67d2..b9870633dbb7cbae63c4f5a74555831d442d6f64 100644 --- a/source/client/test/smlTest.cpp +++ b/source/client/test/smlTest.cpp @@ -228,7 +228,7 @@ TEST(testCase, smlParseCols_tag_Test) { ASSERT_EQ(strncasecmp(kv->key, "cbin", 4), 0); ASSERT_EQ(kv->keyLen, 4); ASSERT_EQ(kv->type, TSDB_DATA_TYPE_NCHAR); - ASSERT_EQ(kv->valueLen, 17); + ASSERT_EQ(kv->length, 17); ASSERT_EQ(strncasecmp(kv->value, "\"passit", 7), 0); taosMemoryFree(kv); @@ -237,7 +237,7 @@ TEST(testCase, smlParseCols_tag_Test) { ASSERT_EQ(strncasecmp(kv->key, "cf64", 4), 0); ASSERT_EQ(kv->keyLen, 4); ASSERT_EQ(kv->type, TSDB_DATA_TYPE_NCHAR); - ASSERT_EQ(kv->valueLen, 7); + ASSERT_EQ(kv->length, 7); ASSERT_EQ(strncasecmp(kv->value, "4.31f64", 7), 0); taosMemoryFree(kv); @@ -259,7 +259,7 @@ TEST(testCase, smlParseCols_tag_Test) { ASSERT_EQ(strncasecmp(kv->key, TAG, strlen(TAG)), 0); ASSERT_EQ(kv->keyLen, strlen(TAG)); ASSERT_EQ(kv->type, TSDB_DATA_TYPE_NCHAR); - ASSERT_EQ(kv->valueLen, strlen(TAG)); + ASSERT_EQ(kv->length, strlen(TAG)); ASSERT_EQ(strncasecmp(kv->value, TAG, strlen(TAG)), 0); taosMemoryFree(kv); @@ -499,12 +499,14 @@ TEST(testCase, smlProcess_influx_Test) { TAOS_RES *res = taos_query(taos, "select * from t_6885c584b98481584ee13dac399e173d"); ASSERT_NE(res, nullptr); int fieldNum = taos_field_count(res); - ASSERT_EQ(fieldNum, 11); + ASSERT_EQ(fieldNum, 5); int rowNum = taos_affected_rows(res); ASSERT_EQ(rowNum, 2); for (int i = 0; i < rowNum; ++i) { TAOS_ROW rows = taos_fetch_row(res); } + taos_free_result(res); + smlDestroyInfo(info); } // different types @@ -530,245 +532,542 @@ TEST(testCase, smlParseLine_error_Test) { }; int ret = smlProcess(info, (char **)sql, sizeof(sql)/sizeof(sql[0])); ASSERT_NE(ret, 0); + destroyRequest(request); + smlDestroyInfo(info); +} + +TEST(testCase, smlGetTimestampLen_Test) { + uint8_t len = smlGetTimestampLen(0); + ASSERT_EQ(len, 1); + + len = smlGetTimestampLen(1); + ASSERT_EQ(len, 1); + + len = smlGetTimestampLen(10); + ASSERT_EQ(len, 2); + + len = smlGetTimestampLen(390); + ASSERT_EQ(len, 3); + + len = smlGetTimestampLen(-1); + ASSERT_EQ(len, 1); + + len = smlGetTimestampLen(-10); + ASSERT_EQ(len, 2); + + len = smlGetTimestampLen(-390); + ASSERT_EQ(len, 3); +} + +TEST(testCase, smlProcess_telnet_Test) { + TAOS *taos = taos_connect("localhost", "root", "taosdata", NULL, 0); + ASSERT_NE(taos, nullptr); + + TAOS_RES* pRes = taos_query(taos, "create database if not exists sml_db"); + taos_free_result(pRes); + + pRes = taos_query(taos, "use sml_db"); + taos_free_result(pRes); + + SRequestObj *request = (SRequestObj *)createRequest((STscObj*)taos, NULL, NULL, TSDB_SQL_INSERT); + ASSERT_NE(request, nullptr); + + SSmlHandle *info = smlBuildSmlInfo(taos, request, TSDB_SML_TELNET_PROTOCOL, TSDB_SML_TIMESTAMP_NANO_SECONDS, true); + ASSERT_NE(info, nullptr); + + const char *sql[5] = { + "sys.if.bytes.out 1479496100 1.3E0 host=web01 interface=eth0", + "sys.if.bytes.out 1479496101 1.3E1 interface=eth0 host=web01", + "sys.if.bytes.out 1479496102 1.3E3 network=tcp", + "sys.procs.running 1479496100 42 host=web01 ", + " sys.procs.running 1479496200 42 host=web01=4" + }; + int ret = smlProcess(info, (char**)sql, sizeof(sql)/sizeof(sql[0])); + ASSERT_EQ(ret, 0); + + TAOS_RES *res = taos_query(taos, "select * from t_8c30283b3c4131a071d1e16cf6d7094a"); + ASSERT_NE(res, nullptr); + int fieldNum = taos_field_count(res); + ASSERT_EQ(fieldNum, 2); + int rowNum = taos_affected_rows(res); + ASSERT_EQ(rowNum, 1); + for (int i = 0; i < rowNum; ++i) { + TAOS_ROW rows = taos_fetch_row(res); + } + taos_free_result(pRes); + + res = taos_query(taos, "select * from t_6931529054e5637ca92c78a1ad441961"); + ASSERT_NE(res, nullptr); + fieldNum = taos_field_count(res); + ASSERT_EQ(fieldNum, 2); + rowNum = taos_affected_rows(res); + ASSERT_EQ(rowNum, 2); + for (int i = 0; i < rowNum; ++i) { + TAOS_ROW rows = taos_fetch_row(res); + } + taos_free_result(pRes); + smlDestroyInfo(info); +} + +TEST(testCase, smlProcess_json1_Test) { + TAOS *taos = taos_connect("localhost", "root", "taosdata", NULL, 0); + ASSERT_NE(taos, nullptr); + + TAOS_RES *pRes = taos_query(taos, "create database if not exists sml_db"); + taos_free_result(pRes); + + pRes = taos_query(taos, "use sml_db"); + taos_free_result(pRes); + + SRequestObj *request = (SRequestObj *)createRequest((STscObj *)taos, NULL, NULL, TSDB_SQL_INSERT); + ASSERT_NE(request, nullptr); + + SSmlHandle *info = smlBuildSmlInfo(taos, request, TSDB_SML_JSON_PROTOCOL, TSDB_SML_TIMESTAMP_NANO_SECONDS, true); + ASSERT_NE(info, nullptr); + + const char *sql = + "[\n" + " {\n" + " \"metric\": \"sys.cpu.nice\",\n" + " \"timestamp\": 1346846400,\n" + " \"value\": 18,\n" + " \"tags\": {\n" + " \"host\": \"web01\",\n" + " \"dc\": \"lga\"\n" + " }\n" + " },\n" + " {\n" + " \"metric\": \"sys.cpu.nice\",\n" + " \"timestamp\": 1346846400,\n" + " \"value\": 9,\n" + " \"tags\": {\n" + " \"host\": \"web02\",\n" + " \"dc\": \"lga\"\n" + " }\n" + " }\n" + "]"; + int ret = smlProcess(info, (char **)(&sql), -1); + ASSERT_EQ(ret, 0); + + TAOS_RES *res = taos_query(taos, "select * from t_cb27a7198d637b4f1c6464bd73f756a7"); + ASSERT_NE(res, nullptr); + int fieldNum = taos_field_count(res); + ASSERT_EQ(fieldNum, 2); + // int rowNum = taos_affected_rows(res); + // ASSERT_EQ(rowNum, 1); + // for (int i = 0; i < rowNum; ++i) { + // TAOS_ROW rows = taos_fetch_row(res); + // } + taos_free_result(pRes); + smlDestroyInfo(info); +} + +TEST(testCase, smlProcess_json2_Test) { + TAOS *taos = taos_connect("localhost", "root", "taosdata", NULL, 0); + ASSERT_NE(taos, nullptr); + + TAOS_RES *pRes = taos_query(taos, "create database if not exists sml_db"); + taos_free_result(pRes); + + pRes = taos_query(taos, "use sml_db"); + taos_free_result(pRes); + + SRequestObj *request = (SRequestObj *)createRequest((STscObj *)taos, NULL, NULL, TSDB_SQL_INSERT); + ASSERT_NE(request, nullptr); + + SSmlHandle *info = smlBuildSmlInfo(taos, request, TSDB_SML_JSON_PROTOCOL, TSDB_SML_TIMESTAMP_NANO_SECONDS, true); + ASSERT_NE(info, nullptr); + const char *sql = + "{\n" + " \"metric\": \"meter_current0\",\n" + " \"timestamp\": {\n" + " \"value\" : 1346846400,\n" + " \"type\" : \"s\"\n" + " },\n" + " \"value\": {\n" + " \"value\" : 10.3,\n" + " \"type\" : \"i64\"\n" + " },\n" + " \"tags\": {\n" + " \"groupid\": { \n" + " \"value\" : 2,\n" + " \"type\" : \"bigint\"\n" + " },\n" + " \"location\": { \n" + " \"value\" : \"北京\",\n" + " \"type\" : \"binary\"\n" + " },\n" + " \"id\": \"d1001\"\n" + " }\n" + "}"; + int32_t ret = smlProcess(info, (char **)(&sql), -1); + ASSERT_EQ(ret, 0); + taos_free_result(pRes); + smlDestroyInfo(info); } - TEST(testCase, smlGetTimestampLen_Test) { - uint8_t len = smlGetTimestampLen(0); - ASSERT_EQ(len, 1); - - len = smlGetTimestampLen(1); - ASSERT_EQ(len, 1); - - len = smlGetTimestampLen(10); - ASSERT_EQ(len, 2); - - len = smlGetTimestampLen(390); - ASSERT_EQ(len, 3); - - len = smlGetTimestampLen(-1); - ASSERT_EQ(len, 1); - - len = smlGetTimestampLen(-10); - ASSERT_EQ(len, 2); - - len = smlGetTimestampLen(-390); - ASSERT_EQ(len, 3); - } - - TEST(testCase, smlProcess_telnet_Test) { - TAOS *taos = taos_connect("localhost", "root", "taosdata", NULL, 0); - ASSERT_NE(taos, nullptr); - - TAOS_RES* pRes = taos_query(taos, "create database if not exists sml_db"); - taos_free_result(pRes); - - pRes = taos_query(taos, "use sml_db"); - taos_free_result(pRes); - - SRequestObj *request = (SRequestObj *)createRequest((STscObj*)taos, NULL, NULL, TSDB_SQL_INSERT); - ASSERT_NE(request, nullptr); - - SSmlHandle *info = smlBuildSmlInfo(taos, request, TSDB_SML_TELNET_PROTOCOL, TSDB_SML_TIMESTAMP_NANO_SECONDS, true); - ASSERT_NE(info, nullptr); - - const char *sql[4] = { - "sys.if.bytes.out 1479496100 1.3E0 host=web01 interface=eth0", - "sys.if.bytes.out 1479496101 1.3E1 interface=eth0 host=web01 ", - "sys.if.bytes.out 1479496102 1.3E3 network=tcp", - "sys.procs.running 1479496100 42 host=web01" - }; - int ret = smlProcess(info, (char**)sql, sizeof(sql)/sizeof(sql[0])); - ASSERT_EQ(ret, 0); - - TAOS_RES *res = taos_query(taos, "select * from t_8c30283b3c4131a071d1e16cf6d7094a"); - ASSERT_NE(res, nullptr); - int fieldNum = taos_field_count(res); - ASSERT_EQ(fieldNum, 2); - int rowNum = taos_affected_rows(res); - ASSERT_EQ(rowNum, 1); - for (int i = 0; i < rowNum; ++i) { - TAOS_ROW rows = taos_fetch_row(res); - } - - res = taos_query(taos, "select * from t_6931529054e5637ca92c78a1ad441961"); - ASSERT_NE(res, nullptr); - fieldNum = taos_field_count(res); - ASSERT_EQ(fieldNum, 2); - rowNum = taos_affected_rows(res); - ASSERT_EQ(rowNum, 2); - for (int i = 0; i < rowNum; ++i) { - TAOS_ROW rows = taos_fetch_row(res); - } - } - - TEST(testCase, smlProcess_json_Test) { - TAOS *taos = taos_connect("localhost", "root", "taosdata", NULL, 0); - ASSERT_NE(taos, nullptr); - - TAOS_RES* pRes = taos_query(taos, "create database if not exists sml_db"); - taos_free_result(pRes); - - pRes = taos_query(taos, "use sml_db"); - taos_free_result(pRes); - - SRequestObj *request = (SRequestObj *)createRequest((STscObj*)taos, NULL, NULL, TSDB_SQL_INSERT); - ASSERT_NE(request, nullptr); - - SSmlHandle *info = smlBuildSmlInfo(taos, request, TSDB_SML_JSON_PROTOCOL, TSDB_SML_TIMESTAMP_NANO_SECONDS, true); - ASSERT_NE(info, nullptr); - - const char *sql = "[\n" - " {\n" - " \"metric\": \"sys.cpu.nice\",\n" - " \"timestamp\": 1346846400,\n" - " \"value\": 18,\n" - " \"tags\": {\n" - " \"host\": \"web01\",\n" - " \"dc\": \"lga\"\n" - " }\n" - " },\n" - " {\n" - " \"metric\": \"sys.cpu.nice\",\n" - " \"timestamp\": 1346846400,\n" - " \"value\": 9,\n" - " \"tags\": {\n" - " \"host\": \"web02\",\n" - " \"dc\": \"lga\"\n" - " }\n" - " }\n" - "]"; - int ret = smlProcess(info, (char**)(&sql), -1); - ASSERT_EQ(ret, 0); - - TAOS_RES *res = taos_query(taos, "select * from t_cb27a7198d637b4f1c6464bd73f756a7"); - ASSERT_NE(res, nullptr); - int fieldNum = taos_field_count(res); - ASSERT_EQ(fieldNum, 2); -// int rowNum = taos_affected_rows(res); -// ASSERT_EQ(rowNum, 1); -// for (int i = 0; i < rowNum; ++i) { -// TAOS_ROW rows = taos_fetch_row(res); -// } - - sql = "{\n" - " \"metric\": \"meter_current\",\n" - " \"timestamp\": {\n" - " \"value\" : 1346846400,\n" - " \"type\" : \"s\"\n" - " },\n" - " \"value\": {\n" - " \"value\" : 10.3,\n" - " \"type\" : \"i64\"\n" - " },\n" - " \"tags\": {\n" - " \"groupid\": { \n" - " \"value\" : 2,\n" - " \"type\" : \"bigint\"\n" - " },\n" - " \"location\": { \n" - " \"value\" : \"北京\",\n" - " \"type\" : \"binary\"\n" - " },\n" - " \"id\": \"d1001\"\n" - " }\n" - "}"; - ret = smlProcess(info, (char**)(&sql), -1); - ASSERT_EQ(ret, 0); - - sql = "{\n" - " \"metric\": \"meter_current\",\n" - " \"timestamp\": {\n" - " \"value\" : 1346846400,\n" - " \"type\" : \"s\"\n" - " },\n" - " \"value\": {\n" - " \"value\" : 10.3,\n" - " \"type\" : \"i64\"\n" - " },\n" - " \"tags\": {\n" - " \"t1\": { \n" - " \"value\" : 2,\n" - " \"type\" : \"bigint\"\n" - " },\n" - " \"t2\": { \n" - " \"value\" : 2,\n" - " \"type\" : \"int\"\n" - " },\n" - " \"t3\": { \n" - " \"value\" : 2,\n" - " \"type\" : \"i16\"\n" - " },\n" - " \"t4\": { \n" - " \"value\" : 2,\n" - " \"type\" : \"i8\"\n" - " },\n" - " \"t5\": { \n" - " \"value\" : 2,\n" - " \"type\" : \"f32\"\n" - " },\n" - " \"t6\": { \n" - " \"value\" : 2,\n" - " \"type\" : \"double\"\n" - " },\n" - " \"t7\": { \n" - " \"value\" : \"8323\",\n" - " \"type\" : \"binary\"\n" - " },\n" - " \"t8\": { \n" - " \"value\" : \"北京\",\n" - " \"type\" : \"binary\"\n" - " },\n" - " \"t9\": { \n" - " \"value\" : true,\n" - " \"type\" : \"bool\"\n" - " },\n" - " \"id\": \"d1001\"\n" - " }\n" - "}"; - ret = smlProcess(info, (char**)(&sql), -1); - ASSERT_EQ(ret, 0); - - sql = "{\n" - " \"metric\": \"meter_current\",\n" - " \"timestamp\": {\n" - " \"value\" : 1346846400000,\n" - " \"type\" : \"ms\"\n" - " },\n" - " \"value\": \"ni\",\n" - " \"tags\": {\n" - " \"t1\": { \n" - " \"value\" : 20,\n" - " \"type\" : \"i64\"\n" - " },\n" - " \"t2\": { \n" - " \"value\" : 25,\n" - " \"type\" : \"i32\"\n" - " },\n" - " \"t3\": { \n" - " \"value\" : 2,\n" - " \"type\" : \"smallint\"\n" - " },\n" - " \"t4\": { \n" - " \"value\" : 2,\n" - " \"type\" : \"tinyint\"\n" - " },\n" - " \"t5\": { \n" - " \"value\" : 2,\n" - " \"type\" : \"float\"\n" - " },\n" - " \"t6\": { \n" - " \"value\" : 0.2,\n" - " \"type\" : \"f64\"\n" - " },\n" - " \"t7\": \"nsj\",\n" - " \"t8\": { \n" - " \"value\" : \"北京\",\n" - " \"type\" : \"binary\"\n" - " },\n" - " \"t9\": false,\n" - " \"id\": \"d1001\"\n" - " }\n" - "}"; - ret = smlProcess(info, (char**)(&sql), -1); - ASSERT_EQ(ret, 0); - } +TEST(testCase, smlProcess_json3_Test) { + TAOS *taos = taos_connect("localhost", "root", "taosdata", NULL, 0); + ASSERT_NE(taos, nullptr); + + TAOS_RES *pRes = taos_query(taos, "create database if not exists sml_db"); + taos_free_result(pRes); + + pRes = taos_query(taos, "use sml_db"); + taos_free_result(pRes); + + SRequestObj *request = (SRequestObj *)createRequest((STscObj *)taos, NULL, NULL, TSDB_SQL_INSERT); + ASSERT_NE(request, nullptr); + + SSmlHandle *info = smlBuildSmlInfo(taos, request, TSDB_SML_JSON_PROTOCOL, TSDB_SML_TIMESTAMP_NANO_SECONDS, true); + ASSERT_NE(info, nullptr); + const char *sql = + "{\n" + " \"metric\": \"meter_current1\",\n" + " \"timestamp\": {\n" + " \"value\" : 1346846400,\n" + " \"type\" : \"s\"\n" + " },\n" + " \"value\": {\n" + " \"value\" : 10.3,\n" + " \"type\" : \"i64\"\n" + " },\n" + " \"tags\": {\n" + " \"t1\": { \n" + " \"value\" : 2,\n" + " \"type\" : \"bigint\"\n" + " },\n" + " \"t2\": { \n" + " \"value\" : 2,\n" + " \"type\" : \"int\"\n" + " },\n" + " \"t3\": { \n" + " \"value\" : 2,\n" + " \"type\" : \"i16\"\n" + " },\n" + " \"t4\": { \n" + " \"value\" : 2,\n" + " \"type\" : \"i8\"\n" + " },\n" + " \"t5\": { \n" + " \"value\" : 2,\n" + " \"type\" : \"f32\"\n" + " },\n" + " \"t6\": { \n" + " \"value\" : 2,\n" + " \"type\" : \"double\"\n" + " },\n" + " \"t7\": { \n" + " \"value\" : \"8323\",\n" + " \"type\" : \"binary\"\n" + " },\n" + " \"t8\": { \n" + " \"value\" : \"北京\",\n" + " \"type\" : \"nchar\"\n" + " },\n" + " \"t9\": { \n" + " \"value\" : true,\n" + " \"type\" : \"bool\"\n" + " },\n" + " \"id\": \"d1001\"\n" + " }\n" + "}"; + int32_t ret = smlProcess(info, (char **)(&sql), -1); + ASSERT_EQ(ret, 0); + taos_free_result(pRes); + smlDestroyInfo(info); +} + +TEST(testCase, smlProcess_json4_Test) { + TAOS *taos = taos_connect("localhost", "root", "taosdata", NULL, 0); + ASSERT_NE(taos, nullptr); + + TAOS_RES* pRes = taos_query(taos, "create database if not exists sml_db"); + taos_free_result(pRes); + + pRes = taos_query(taos, "use sml_db"); + taos_free_result(pRes); + + SRequestObj *request = (SRequestObj *)createRequest((STscObj*)taos, NULL, NULL, TSDB_SQL_INSERT); + ASSERT_NE(request, nullptr); + + SSmlHandle *info = smlBuildSmlInfo(taos, request, TSDB_SML_JSON_PROTOCOL, TSDB_SML_TIMESTAMP_NANO_SECONDS, true); + ASSERT_NE(info, nullptr); + const char *sql = "{\n" + " \"metric\": \"meter_current2\",\n" + " \"timestamp\": {\n" + " \"value\" : 1346846500000,\n" + " \"type\" : \"ms\"\n" + " },\n" + " \"value\": \"ni\",\n" + " \"tags\": {\n" + " \"t1\": { \n" + " \"value\" : 20,\n" + " \"type\" : \"i64\"\n" + " },\n" + " \"t2\": { \n" + " \"value\" : 25,\n" + " \"type\" : \"i32\"\n" + " },\n" + " \"t3\": { \n" + " \"value\" : 2,\n" + " \"type\" : \"smallint\"\n" + " },\n" + " \"t4\": { \n" + " \"value\" : 2,\n" + " \"type\" : \"tinyint\"\n" + " },\n" + " \"t5\": { \n" + " \"value\" : 2,\n" + " \"type\" : \"float\"\n" + " },\n" + " \"t6\": { \n" + " \"value\" : 0.2,\n" + " \"type\" : \"f64\"\n" + " },\n" + " \"t7\": \"nsj\",\n" + " \"t8\": { \n" + " \"value\" : \"北京\",\n" + " \"type\" : \"nchar\"\n" + " },\n" + " \"t9\": false,\n" + " \"id\": \"d1001\"\n" + " }\n" + "}"; + int32_t ret = smlProcess(info, (char**)(&sql), -1); + ASSERT_EQ(ret, 0); + taos_free_result(pRes); + smlDestroyInfo(info); +} + +TEST(testCase, smlParseTelnetLine_error_Test) { + TAOS *taos = taos_connect("localhost", "root", "taosdata", NULL, 0); + ASSERT_NE(taos, nullptr); + + TAOS_RES* pRes = taos_query(taos, "create database if not exists sml_db"); + taos_free_result(pRes); + + pRes = taos_query(taos, "use sml_db"); + taos_free_result(pRes); + + SRequestObj *request = (SRequestObj *)createRequest((STscObj*)taos, NULL, NULL, TSDB_SQL_INSERT); + ASSERT_NE(request, nullptr); + + SSmlHandle *info = smlBuildSmlInfo(taos, request, TSDB_SML_TELNET_PROTOCOL, TSDB_SML_TIMESTAMP_NANO_SECONDS, true); + ASSERT_NE(info, nullptr); + + int32_t ret = 0; + const char *sql[19] = { + "sys.procs.running 14794961040 42 host=web01", + "sys.procs.running 14791040 42 host=web01", + "sys.procs.running erere 42 host=web01", + "sys.procs.running 1.6e10 42 host=web01", + "sys.procs.running 1.47949610 42 host=web01", + "sys.procs.running 147949610i 42 host=web01", + "sys.procs.running -147949610 42 host=web01", + "", + " ", + "sys ", + "sys.procs.running 1479496100 42 ", + "sys.procs.running 1479496100 42 host= ", + "sys.procs.running 1479496100 42or host=web01", + "sys.procs.running 1479496100 true host=web01", + "sys.procs.running 1479496100 \"binary\" host=web01", + "sys.procs.running 1479496100 L\"rfr\" host=web01", + "sys.procs.running 1479496100 42 host=web01 cpu= ", + "sys.procs.running 1479496100 42 host=web01 host=w2", + "sys.procs.running 1479496100 42 host=web01 host", + }; + for(int i = 0; i < sizeof(sql)/sizeof(sql[0]); i++){ + ret = smlParseTelnetLine(info, (void*)sql[i]); + ASSERT_NE(ret, 0); + } + + destroyRequest(request); + smlDestroyInfo(info); +} + +TEST(testCase, smlParseTelnetLine_diff_type_Test) { + TAOS *taos = taos_connect("localhost", "root", "taosdata", NULL, 0); + ASSERT_NE(taos, nullptr); + + TAOS_RES* pRes = taos_query(taos, "create database if not exists sml_db"); + taos_free_result(pRes); + + pRes = taos_query(taos, "use sml_db"); + taos_free_result(pRes); + + SRequestObj *request = (SRequestObj *)createRequest((STscObj*)taos, NULL, NULL, TSDB_SQL_INSERT); + ASSERT_NE(request, nullptr); + + SSmlHandle *info = smlBuildSmlInfo(taos, request, TSDB_SML_TELNET_PROTOCOL, TSDB_SML_TIMESTAMP_NANO_SECONDS, true); + ASSERT_NE(info, nullptr); + + const char *sql[2] = { + "sys.procs.running 1479496104000 42 host=web01", + "sys.procs.running 1479496104000 42u8 host=web01" + }; + int32_t ret = smlProcess(info, (char**)sql, sizeof(sql)/sizeof(sql[0])); + ASSERT_NE(ret, 0); + + destroyRequest(request); + smlDestroyInfo(info); +} + +TEST(testCase, smlParseTelnetLine_json_error_Test) { + TAOS *taos = taos_connect("localhost", "root", "taosdata", NULL, 0); + ASSERT_NE(taos, nullptr); + + TAOS_RES* pRes = taos_query(taos, "create database if not exists sml_db"); + taos_free_result(pRes); + + pRes = taos_query(taos, "use sml_db"); + taos_free_result(pRes); + + SRequestObj *request = (SRequestObj *)createRequest((STscObj*)taos, NULL, NULL, TSDB_SQL_INSERT); + ASSERT_NE(request, nullptr); + + SSmlHandle *info = smlBuildSmlInfo(taos, request, TSDB_SML_TELNET_PROTOCOL, TSDB_SML_TIMESTAMP_NANO_SECONDS, true); + ASSERT_NE(info, nullptr); + + int32_t ret = 0; + const char *sql[] = { + "[\n" + " {\n" + " \"metric\": \"sys.cpu.nice\",\n" + " \"timestamp\": 13468464009999333322222223,\n" + " \"value\": 18,\n" + " \"tags\": {\n" + " \"host\": \"web01\",\n" + " \"dc\": \"lga\"\n" + " }\n" + " },\n" + "]", + "[\n" + " {\n" + " \"metric\": \"sys.cpu.nice\",\n" + " \"timestamp\": 1346846400i,\n" + " \"value\": 18,\n" + " \"tags\": {\n" + " \"host\": \"web01\",\n" + " \"dc\": \"lga\"\n" + " }\n" + " },\n" + "]", + "[\n" + " {\n" + " \"metric\": \"sys.cpu.nice\",\n" + " \"timestamp\": 1346846400,\n" + " \"value\": 18,\n" + " \"tags\": {\n" + " \"groupid\": { \n" + " \"value\" : 2,\n" + " \"type\" : \"nchar\"\n" + " },\n" + " \"location\": { \n" + " \"value\" : \"北京\",\n" + " \"type\" : \"binary\"\n" + " },\n" + " \"id\": \"d1001\"\n" + " }\n" + " },\n" + "]", + }; + for(int i = 0; i < sizeof(sql)/sizeof(sql[0]); i++){ + ret = smlParseTelnetLine(info, (void*)sql[i]); + ASSERT_NE(ret, 0); + } + + destroyRequest(request); + smlDestroyInfo(info); +} + +TEST(testCase, smlParseTelnetLine_diff_json_type1_Test) { + TAOS *taos = taos_connect("localhost", "root", "taosdata", NULL, 0); + ASSERT_NE(taos, nullptr); + + TAOS_RES* pRes = taos_query(taos, "create database if not exists sml_db"); + taos_free_result(pRes); + + pRes = taos_query(taos, "use sml_db"); + taos_free_result(pRes); + + SRequestObj *request = (SRequestObj *)createRequest((STscObj*)taos, NULL, NULL, TSDB_SQL_INSERT); + ASSERT_NE(request, nullptr); + + SSmlHandle *info = smlBuildSmlInfo(taos, request, TSDB_SML_TELNET_PROTOCOL, TSDB_SML_TIMESTAMP_NANO_SECONDS, true); + ASSERT_NE(info, nullptr); + + const char *sql[2] = { + "[\n" + " {\n" + " \"metric\": \"sys.cpu.nice\",\n" + " \"timestamp\": 1346846400,\n" + " \"value\": 18,\n" + " \"tags\": {\n" + " \"host\": \"lga\"\n" + " }\n" + " },\n" + "]", + "[\n" + " {\n" + " \"metric\": \"sys.cpu.nice\",\n" + " \"timestamp\": 1346846400,\n" + " \"value\": 18,\n" + " \"tags\": {\n" + " \"host\": 8\n" + " }\n" + " },\n" + "]", + }; + int32_t ret = smlProcess(info, (char**)sql, sizeof(sql)/sizeof(sql[0])); + ASSERT_NE(ret, 0); + + destroyRequest(request); + smlDestroyInfo(info); +} + +TEST(testCase, smlParseTelnetLine_diff_json_type2_Test) { + TAOS *taos = taos_connect("localhost", "root", "taosdata", NULL, 0); + ASSERT_NE(taos, nullptr); + + TAOS_RES* pRes = taos_query(taos, "create database if not exists sml_db"); + taos_free_result(pRes); + + pRes = taos_query(taos, "use sml_db"); + taos_free_result(pRes); + + SRequestObj *request = (SRequestObj *)createRequest((STscObj*)taos, NULL, NULL, TSDB_SQL_INSERT); + ASSERT_NE(request, nullptr); + + SSmlHandle *info = smlBuildSmlInfo(taos, request, TSDB_SML_TELNET_PROTOCOL, TSDB_SML_TIMESTAMP_NANO_SECONDS, true); + ASSERT_NE(info, nullptr); + + const char *sql[2] = { + "[\n" + " {\n" + " \"metric\": \"sys.cpu.nice\",\n" + " \"timestamp\": 1346846400,\n" + " \"value\": 18,\n" + " \"tags\": {\n" + " \"host\": \"lga\"\n" + " }\n" + " },\n" + "]", + "[\n" + " {\n" + " \"metric\": \"sys.cpu.nice\",\n" + " \"timestamp\": 1346846400,\n" + " \"value\": \"18\",\n" + " \"tags\": {\n" + " \"host\": \"fff\"\n" + " }\n" + " },\n" + "]", + }; + int32_t ret = smlProcess(info, (char**)sql, sizeof(sql)/sizeof(sql[0])); + ASSERT_NE(ret, 0); + + destroyRequest(request); + smlDestroyInfo(info); +} diff --git a/source/common/src/tname.c b/source/common/src/tname.c index 56fbfed8fff294ac482f5ffe25a00192f4bb9880..fa9b6e1e63628593aca1fb27ead10ec6a7bff7d1 100644 --- a/source/common/src/tname.c +++ b/source/common/src/tname.c @@ -317,7 +317,11 @@ void buildChildTableName(RandTableName* rName) { for (int j = 0; j < size; ++j) { SSmlKv* tagKv = taosArrayGetP(rName->tags, j); taosStringBuilderAppendStringLen(&sb, tagKv->key, tagKv->keyLen); - taosStringBuilderAppendStringLen(&sb, tagKv->value, tagKv->valueLen); + if(IS_VAR_DATA_TYPE(tagKv->type)){ + taosStringBuilderAppendStringLen(&sb, tagKv->value, tagKv->length); + }else{ + taosStringBuilderAppendStringLen(&sb, (char*)(&(tagKv->value)), tagKv->length); + } } size_t len = 0; char* keyJoined = taosStringBuilderGetResult(&sb, &len); diff --git a/source/libs/parser/src/parInsert.c b/source/libs/parser/src/parInsert.c index 228cb5a44bf722ed2875b7e482e4bd97c9b0c03f..81f55d80463115b501d1d48c40e09e826d90c433 100644 --- a/source/libs/parser/src/parInsert.c +++ b/source/libs/parser/src/parInsert.c @@ -758,7 +758,7 @@ static int32_t KvRowAppend(SMsgBuf* pMsgBuf, const void* value, int32_t len, voi int32_t output = 0; if (!taosMbsToUcs4(value, len, (TdUcs4*)varDataVal(pa->buf), pa->schema->bytes - VARSTR_HEADER_SIZE, &output)) { char buf[512] = {0}; - snprintf(buf, tListLen(buf), "%s", strerror(errno)); + snprintf(buf, tListLen(buf), " taosMbsToUcs4 error:%s", strerror(errno)); return buildSyntaxErrMsg(pMsgBuf, buf, value); } @@ -1668,7 +1668,11 @@ static int32_t smlBuildTagRow(SArray* cols, SKVRowBuilder* tagsBuilder, SParsedD SSchema* pTagSchema = &pSchema[tags->boundColumns[i] - 1]; // colId starts with 1 param.schema = pTagSchema; SSmlKv* kv = taosArrayGetP(cols, i); - KvRowAppend(msg, kv->value, kv->valueLen, ¶m); + if(IS_VAR_DATA_TYPE(kv->type)){ + KvRowAppend(msg, kv->value, kv->length, ¶m); + }else{ + KvRowAppend(msg, &(kv->value), kv->length, ¶m); + } } *row = tdGetKVRowFromBuilder(tagsBuilder); @@ -1766,14 +1770,16 @@ int32_t smlBindData(void *handle, SArray *tags, SArray *colsSchema, SArray *cols if (!kv || kv->length == 0) { MemRowAppend(&pBuf, NULL, 0, ¶m); } else { - int32_t colLen = pColSchema->bytes; - if (IS_VAR_DATA_TYPE(pColSchema->type)) { - colLen = kv->length; - } else if (pColSchema->type == TSDB_DATA_TYPE_TIMESTAMP) { + int32_t colLen = kv->length; + if (pColSchema->type == TSDB_DATA_TYPE_TIMESTAMP) { kv->i = convertTimePrecision(kv->i, TSDB_TIME_PRECISION_NANO, pTableMeta->tableInfo.precision); } - MemRowAppend(&pBuf, &(kv->value), colLen, ¶m); + if(IS_VAR_DATA_TYPE(kv->type)){ + MemRowAppend(&pBuf, kv->value, colLen, ¶m); + }else{ + MemRowAppend(&pBuf, &(kv->value), colLen, ¶m); + } } if (PRIMARYKEY_TIMESTAMP_COL_ID == pColSchema->colId) {