diff --git a/documentation20/cn/08.connector/docs.md b/documentation20/cn/08.connector/docs.md index 2295de6f9bba359d691af5e92c2bb8026beaf5a1..b4543111b22008467ba749018fa2c19321f4f18e 100644 --- a/documentation20/cn/08.connector/docs.md +++ b/documentation20/cn/08.connector/docs.md @@ -573,6 +573,14 @@ cd C:\TDengine\connector\python python -m pip install . ``` +**PyPI** + +从2.1.1版本开始,用户可以从[PyPI](https://pypi.org/project/taospy/)安装: + +```sh +pip install taospy +``` + * 如果机器上没有pip命令,用户可将src/connector/python下的taos文件夹拷贝到应用程序的目录使用。 对于windows 客户端,安装TDengine windows 客户端后,将C:\TDengine\driver\taos.dll拷贝到C:\windows\system32目录下即可。 @@ -608,6 +616,22 @@ python3 PythonChecker.py -host ### Python连接器的使用 +#### PEP-249 兼容API + +您可以像其他数据库一样,使用类似 [PEP-249](https://www.python.org/dev/peps/pep-0249/) 数据库API规范风格的API: + +```python +import taos + +conn = taos.connect() +cursor = conn.cursor() + +cursor.execute("show databases") +results = cursor.fetchall() +for row in results: + print(row) +``` + #### 代码示例 * 导入TDengine客户端模块 @@ -663,6 +687,44 @@ for data in c1: print("ts=%s, temperature=%d, humidity=%f" %(data[0], data[1],data[2])) ``` +* 从v2.1.0版本开始, 我们提供另外一种API:`connection.query` + + ```python + import taos + + conn = taos.connect() + conn.execute("create database if not exists pytest") + + result = conn.query("show databases") + num_of_fields = result.field_count + for field in result.fields: + print(field) + for row in result: + print(row) + conn.execute("drop database pytest") + ``` + + `query` 方法会返回一个 `TaosResult` 类对象,并提供了以下有用的属性或方法: + + 属性: + + - `fields`: `TaosFields` 集合类,提供返回数据的列信息。 + - `field_count`: 返回数据的列数. + - `affected_rows`: 插入数据的行数. + - `row_count`: 查询数据结果数. + - `precision`: 当前数据库的时间精度. + + 方法: + + - `fetch_all()`: 类似于 `cursor.fetchall()` 返回同样的集合数据 + - `fetch_all_into_dict()`: v2.1.1 新添加的API,将上面的数据转换成字典类型返回 + - `blocks_iter()` `rows_iter()`: 根据底层API提供的两种不同迭代器。 + - `fetch_rows_a`: 异步API + - `errno`: 错误码 + - `errstr`: 错误信息 + - `close`: 关闭结果对象,一般不需要直接调用 + + * 创建订阅 ```python diff --git a/documentation20/en/08.connector/docs.md b/documentation20/en/08.connector/docs.md index 57efd27dcc1b90775c7f2bfc6fbcbca57dc503ff..806bebd77738bd4251607237e3f88c589baa4741 100644 --- a/documentation20/en/08.connector/docs.md +++ b/documentation20/en/08.connector/docs.md @@ -419,19 +419,47 @@ or `pip3 install src/connector/python/` +You can install the `taospy` connector from [PyPI](https://pypi.org/project/taospy/): + +```sh +pip install taospy +``` + #### Windows -With Windows TDengine client installed, copy the file "C:\TDengine\driver\taos.dll" to the "C:\ windows\ system32" directory and enter the Windows cmd command line interface: +With Windows TDengine client installed, copy the file "C:\TDengine\driver\taos.dll" to the "C:\Windows\system32" directory and enter the Windows *cmd* command line interface: ```cmd cd C:\TDengine\connector\python python -m pip install . ``` +Or install from PyPI: + +```cmd +pip install taospy +``` + - If there is no `pip` command on the machine, the user can copy the taos folder under src/connector/python to the application directory for use. For Windows client, after installing the TDengine Windows client, copy C:\ TDengine\driver\taos.dll to the C:\ windows\ system32 directory. ### How to use +#### PEP-249 Python Database API + +Definitely you can use the [PEP-249](https://www.python.org/dev/peps/pep-0249/) database API like other type of databases: + +```python +import taos + +conn = taos.connect() +cursor = conn.cursor() + +cursor.execute("show databases") +results = cursor.fetchall() +for row in results: + print(row) +``` + #### Code sample - Import the TDengine client module @@ -488,6 +516,44 @@ for data in c1: print("ts=%s, temperature=%d, humidity=%f" %(data[0], data[1],data[2])) ``` +- Since v2.1.0, python connector provides a new API for query: + +```python +import taos + +conn = taos.connect() +conn.execute("create database if not exists pytest") + +result = conn.query("show databases") +num_of_fields = result.field_count +for field in result.fields: + print(field) +for row in result: + print(row) +conn.execute("drop database pytest") +``` + +The `query` method returns `TaosResult` class. It provides high level APIs for convenient use: + +Properties: + +- `fields`: the `TaosFields` object contains the column metadata, given the collection of each column field metadata by iterator. +- `field_count`: column number of result. +- `affected_rows`: the rows completed for insert. +- `row_count`: the rows number for select. +- `precision`: the result precision. + +Functions: + +- `fetch_all()`: get all data as tuple array. +- `fetch_all_into_dict()`: get all data as dict array, added since v2.1.1 +- `blocks_iter()`: provides iterator by C `taos_fetch_blocks` API +- `rows_iter()`: provides iterator by C `taos_fetch_row` API +- `fetch_rows_a`: fetch rows by async API in taosc. +- `errno`: error code if failed. +- `errstr`: error string if failed. +- `close`: close result, you do not need to call it directly, result will auto closed out of scope. + - Create subscription ```python @@ -510,6 +576,7 @@ for d in data: sub.close() ``` + - Close connection ```python diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 28515f6c63c98f741d84aa11f92b9ca9f7ad3691..47af7568642d0badccda51a28c09d321cf782571 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -1,5 +1,5 @@ name: tdengine -base: core18 +base: core20 version: '2.3.0.0' icon: snap/gui/t-dengine.svg summary: an open-source big data platform designed and optimized for IoT. @@ -39,14 +39,17 @@ parts: - taoswrapper.sh tdengine: + plugin: cmake source: . source-type: local - plugin: cmake build-packages: - gcc - g++ - make - cmake + cmake-parameters: + - -DCMAKE_BUILD_TYPE=Release + - -DBUILD_HTTP=true override-build: | snapcraftctl build if [ ! -d $SNAPCRAFT_STAGE/usr ]; then diff --git a/src/client/inc/tscParseLine.h b/src/client/inc/tscParseLine.h index 4cbb66aa4b9b58c2e696672efeccad29514803de..74ba9ab3d9c5251e1cf8ab4e8549c8da0353ea49 100644 --- a/src/client/inc/tscParseLine.h +++ b/src/client/inc/tscParseLine.h @@ -67,6 +67,7 @@ typedef struct { int32_t affectedRows; } SSmlLinesInfo; +void addEscapeCharToString(char *str, int32_t len); int tscSmlInsert(TAOS* taos, TAOS_SML_DATA_POINT* points, int numPoint, SSmlLinesInfo* info); bool checkDuplicateKey(char *key, SHashObj *pHash, SSmlLinesInfo* info); bool isValidInteger(char *str); diff --git a/src/client/inc/tscUtil.h b/src/client/inc/tscUtil.h index 11ae6ae2704050850e7d79f8ee8c36ce207158e6..e2b151ea6ab417ef18746d0a35ce3c7818b504b7 100644 --- a/src/client/inc/tscUtil.h +++ b/src/client/inc/tscUtil.h @@ -251,6 +251,7 @@ void tscColumnListCopyAll(SArray* dst, const SArray* src); void convertQueryResult(SSqlRes* pRes, SQueryInfo* pQueryInfo, uint64_t objId, bool convertNchar); void tscDequoteAndTrimToken(SStrToken* pToken); +void tscRmEscapeAndTrimToken(SStrToken* pToken); int32_t tscValidateName(SStrToken* pToken, bool escapeEnabled, bool *dbIncluded); void tscIncStreamExecutionCount(void* pStream); diff --git a/src/client/src/tscParseInsert.c b/src/client/src/tscParseInsert.c index da03ed40f02c667c474f3c10a648cb1808667835..dbc7503535d79604c3ca908ce748075d41e2eb00 100644 --- a/src/client/src/tscParseInsert.c +++ b/src/client/src/tscParseInsert.c @@ -1251,10 +1251,18 @@ static int32_t parseBoundColumns(SInsertStatementParam *pInsertParam, SParsedDat sToken = tStrGetToken(str, &index, false); str += index; + char tmpTokenBuf[TSDB_MAX_BYTES_PER_ROW] = {0}; // used for deleting Escape character backstick(`) + strncpy(tmpTokenBuf, sToken.z, sToken.n); + sToken.z = tmpTokenBuf; + if (TK_STRING == sToken.type) { tscDequoteAndTrimToken(&sToken); } + if (TK_ID == sToken.type) { + tscRmEscapeAndTrimToken(&sToken); + } + if (sToken.type == TK_RP) { if (end != NULL) { // set the end position *end = str; diff --git a/src/client/src/tscParseLineProtocol.c b/src/client/src/tscParseLineProtocol.c index 6354ba9e9fe60758dc5b8ddafa618033a4d0ffa1..64b15d0dd85c5acc83eee9d18fe191817383d9ef 100644 --- a/src/client/src/tscParseLineProtocol.c +++ b/src/client/src/tscParseLineProtocol.c @@ -499,6 +499,7 @@ static int32_t fillDbSchema(STableMeta* tableMeta, char* tableName, SSmlSTableSc for (int i=0; itableInfo.numOfColumns; ++i) { SSchema field; tstrncpy(field.name, tableMeta->schema[i].name, strlen(tableMeta->schema[i].name)+1); + addEscapeCharToString(field.name, (int16_t)strlen(field.name)); field.type = tableMeta->schema[i].type; field.bytes = tableMeta->schema[i].bytes; taosArrayPush(schema->fields, &field); @@ -510,6 +511,7 @@ static int32_t fillDbSchema(STableMeta* tableMeta, char* tableName, SSmlSTableSc int j = i + tableMeta->tableInfo.numOfColumns; SSchema field; tstrncpy(field.name, tableMeta->schema[j].name, strlen(tableMeta->schema[j].name)+1); + addEscapeCharToString(field.name, (int16_t)strlen(field.name)); field.type = tableMeta->schema[j].type; field.bytes = tableMeta->schema[j].bytes; taosArrayPush(schema->tags, &field); @@ -1175,6 +1177,15 @@ static void escapeSpecialCharacter(uint8_t field, const char **pos) { *pos = cur; } +void addEscapeCharToString(char *str, int32_t len) { + if (str == NULL) { + return; + } + memmove(str + 1, str, len); + str[0] = str[len + 1] = TS_ESCAPE_CHAR; + str[len + 2] = '\0'; +} + bool isValidInteger(char *str) { char *c = str; if (*c != '+' && *c != '-' && !isdigit(*c)) { @@ -1435,58 +1446,65 @@ static bool isNchar(char *pVal, uint16_t len) { return false; } -static bool isTimeStamp(char *pVal, uint16_t len, SMLTimeStampType *tsType, SSmlLinesInfo* info) { +static int32_t isTimeStamp(char *pVal, uint16_t len, SMLTimeStampType *tsType, SSmlLinesInfo* info) { if (len == 0) { - return true; + return TSDB_CODE_SUCCESS; } if ((len == 1) && pVal[0] == '0') { *tsType = SML_TIME_STAMP_NOW; - return true; + return TSDB_CODE_SUCCESS; } - //Default no appendix - if (isdigit(pVal[len - 1]) && isdigit(pVal[len - 2])) { - if (info->protocol == TSDB_SML_LINE_PROTOCOL) { - if (info->tsType != SML_TIME_STAMP_NOT_CONFIGURED) { - *tsType = info->tsType; - } else { - *tsType = SML_TIME_STAMP_NANO_SECONDS; - } - } else if (info->protocol == TSDB_SML_TELNET_PROTOCOL) { - if (len == SML_TIMESTAMP_SECOND_DIGITS) { - *tsType = SML_TIME_STAMP_SECONDS; - } else if (len == SML_TIMESTAMP_MILLI_SECOND_DIGITS) { - *tsType = SML_TIME_STAMP_MILLI_SECONDS; - } else { - return TSDB_CODE_TSC_INVALID_TIME_STAMP; - } + for (int i = 0; i < len; ++i) { + if(!isdigit(pVal[i])) { + return TSDB_CODE_TSC_INVALID_TIME_STAMP; } - return true; } - if (pVal[len - 1] == 's') { - switch (pVal[len - 2]) { - case 'm': - *tsType = SML_TIME_STAMP_MILLI_SECONDS; - break; - case 'u': - *tsType = SML_TIME_STAMP_MICRO_SECONDS; - break; - case 'n': - *tsType = SML_TIME_STAMP_NANO_SECONDS; - break; - default: - if (isdigit(pVal[len - 2])) { - *tsType = SML_TIME_STAMP_SECONDS; - break; - } else { - return false; - } + /* For InfluxDB line protocol use user passed timestamp precision + * For OpenTSDB protocols only 10 digit(seconds) or 13 digits(milliseconds) + * precision allowed + */ + if (info->protocol == TSDB_SML_LINE_PROTOCOL) { + if (info->tsType != SML_TIME_STAMP_NOT_CONFIGURED) { + *tsType = info->tsType; + } else { + *tsType = SML_TIME_STAMP_NANO_SECONDS; + } + } else if (info->protocol == TSDB_SML_TELNET_PROTOCOL) { + if (len == SML_TIMESTAMP_SECOND_DIGITS) { + *tsType = SML_TIME_STAMP_SECONDS; + } else if (len == SML_TIMESTAMP_MILLI_SECOND_DIGITS) { + *tsType = SML_TIME_STAMP_MILLI_SECONDS; + } else { + return TSDB_CODE_TSC_INVALID_TIME_STAMP; } - //printf("Type is timestamp(%s)\n", pVal); - return true; } - return false; + return TSDB_CODE_SUCCESS; + + //if (pVal[len - 1] == 's') { + // switch (pVal[len - 2]) { + // case 'm': + // *tsType = SML_TIME_STAMP_MILLI_SECONDS; + // break; + // case 'u': + // *tsType = SML_TIME_STAMP_MICRO_SECONDS; + // break; + // case 'n': + // *tsType = SML_TIME_STAMP_NANO_SECONDS; + // break; + // default: + // if (isdigit(pVal[len - 2])) { + // *tsType = SML_TIME_STAMP_SECONDS; + // break; + // } else { + // return false; + // } + // } + // //printf("Type is timestamp(%s)\n", pVal); + // return true; + //} + //return false; } static bool convertStrToNumber(TAOS_SML_KV *pVal, char *str, SSmlLinesInfo* info) { @@ -1750,14 +1768,6 @@ bool convertSmlValueType(TAOS_SML_KV *pVal, char *value, static int32_t getTimeStampValue(char *value, uint16_t len, SMLTimeStampType type, int64_t *ts, SSmlLinesInfo* info) { - if (len >= 2) { - for (int i = 0; i < len - 2; ++i) { - if(!isdigit(value[i])) { - return TSDB_CODE_TSC_INVALID_TIME_STAMP; - } - } - } - //No appendix or no timestamp given (len = 0) if (len != 0 && type != SML_TIME_STAMP_NOW) { *ts = (int64_t)strtoll(value, NULL, 10); @@ -1806,13 +1816,13 @@ int32_t convertSmlTimeStamp(TAOS_SML_KV *pVal, char *value, SMLTimeStampType type; int64_t tsVal; - strntolower_s(value, value, len); - if (!isTimeStamp(value, len, &type, info)) { - return TSDB_CODE_TSC_INVALID_TIME_STAMP; + ret = isTimeStamp(value, len, &type, info); + if (ret != TSDB_CODE_SUCCESS) { + return ret; } ret = getTimeStampValue(value, len, type, &tsVal, info); - if (ret) { + if (ret != TSDB_CODE_SUCCESS) { return ret; } tscDebug("SML:0x%"PRIx64"Timestamp after conversion:%"PRId64, info->id, tsVal); @@ -1884,15 +1894,10 @@ bool checkDuplicateKey(char *key, SHashObj *pHash, SSmlLinesInfo* info) { static int32_t parseSmlKey(TAOS_SML_KV *pKV, const char **index, SHashObj *pHash, SSmlLinesInfo* info) { const char *cur = *index; char key[TSDB_COL_NAME_LEN + 1]; // +1 to avoid key[len] over write - uint16_t len = 0; + int16_t len = 0; - //key field cannot start with digit - if (isdigit(*cur)) { - tscError("SML:0x%"PRIx64" Tag key cannot start with digit", info->id); - return TSDB_CODE_TSC_LINE_SYNTAX_ERROR; - } while (*cur != '\0') { - if (len >= TSDB_COL_NAME_LEN - 1) { + if (len > TSDB_COL_NAME_LEN - 1) { tscError("SML:0x%"PRIx64" Key field cannot exceeds %d characters", info->id, TSDB_COL_NAME_LEN - 1); return TSDB_CODE_TSC_INVALID_COLUMN_LENGTH; } @@ -1919,9 +1924,11 @@ static int32_t parseSmlKey(TAOS_SML_KV *pKV, const char **index, SHashObj *pHash return TSDB_CODE_TSC_LINE_SYNTAX_ERROR; } - pKV->key = calloc(len + 1, 1); + pKV->key = calloc(len + TS_ESCAPE_CHAR_SIZE + 1, 1); memcpy(pKV->key, key, len + 1); - //tscDebug("SML:0x%"PRIx64" Key:%s|len:%d", info->id, pKV->key, len); + strntolower_s(pKV->key, pKV->key, (int32_t)len); + addEscapeCharToString(pKV->key, len); + tscDebug("SML:0x%"PRIx64" Key:%s|len:%d", info->id, pKV->key, len); *index = cur + 1; return TSDB_CODE_SUCCESS; } @@ -1932,7 +1939,7 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **index, const char *start, *cur; int32_t ret = TSDB_CODE_SUCCESS; char *value = NULL; - uint16_t len = 0; + int16_t len = 0; bool searchQuote = false; start = cur = *index; @@ -2013,21 +2020,15 @@ error: static int32_t parseSmlMeasurement(TAOS_SML_DATA_POINT *pSml, const char **index, uint8_t *has_tags, SSmlLinesInfo* info) { const char *cur = *index; - uint16_t len = 0; + int16_t len = 0; - pSml->stableName = calloc(TSDB_TABLE_NAME_LEN + 1, 1); // +1 to avoid 1772 line over write + pSml->stableName = calloc(TSDB_TABLE_NAME_LEN + TS_ESCAPE_CHAR_SIZE, 1); if (pSml->stableName == NULL){ return TSDB_CODE_TSC_OUT_OF_MEMORY; } - if (isdigit(*cur)) { - tscError("SML:0x%"PRIx64" Measurement field cannnot start with digit", info->id); - free(pSml->stableName); - pSml->stableName = NULL; - return TSDB_CODE_TSC_LINE_SYNTAX_ERROR; - } while (*cur != '\0') { - if (len >= TSDB_TABLE_NAME_LEN - 1) { + if (len > TSDB_TABLE_NAME_LEN - 1) { tscError("SML:0x%"PRIx64" Measurement field cannot exceeds %d characters", info->id, TSDB_TABLE_NAME_LEN - 1); free(pSml->stableName); pSml->stableName = NULL; @@ -2061,7 +2062,7 @@ static int32_t parseSmlMeasurement(TAOS_SML_DATA_POINT *pSml, const char **index pSml->stableName = NULL; return TSDB_CODE_TSC_LINE_SYNTAX_ERROR; } - pSml->stableName[len] = '\0'; + addEscapeCharToString(pSml->stableName, len); *index = cur + 1; tscDebug("SML:0x%"PRIx64" Stable name in measurement:%s|len:%d", info->id, pSml->stableName, len); @@ -2117,17 +2118,11 @@ static int32_t parseSmlKvPairs(TAOS_SML_KV **pKVs, int *num_kvs, tscError("SML:0x%"PRIx64" Unable to parse value", info->id); goto error; } - if (!isField && (strcasecmp(pkv->key, "ID") == 0)) { - ret = isValidChildTableName(pkv->value, pkv->length, info); - if (ret) { - free(pkv->key); - free(pkv->value); - goto error; - } - smlData->childTableName = malloc( pkv->length + 1); + if (!isField && (strcasecmp(pkv->key, "`ID`") == 0)) { + smlData->childTableName = malloc(pkv->length + TS_ESCAPE_CHAR_SIZE + 1); memcpy(smlData->childTableName, pkv->value, pkv->length); strntolower_s(smlData->childTableName, smlData->childTableName, (int32_t)pkv->length); - smlData->childTableName[pkv->length] = '\0'; + addEscapeCharToString(smlData->childTableName, (int32_t)pkv->length); free(pkv->key); free(pkv->value); } else { @@ -2373,6 +2368,7 @@ static SSqlObj* createSmlQueryObj(TAOS* taos, int32_t affected_rows, int32_t cod } pNew->signature = pNew; pNew->pTscObj = taos; + pNew->fp = NULL; tsem_init(&pNew->rspSem, 0, 0); registerSqlObj(pNew); diff --git a/src/client/src/tscParseOpenTSDB.c b/src/client/src/tscParseOpenTSDB.c index e06f6df5f7cbb66c3a1979941dc556c15d5a8c9e..717638f8407c47c3fc621a3dbd037f9b05dae553 100644 --- a/src/client/src/tscParseOpenTSDB.c +++ b/src/client/src/tscParseOpenTSDB.c @@ -37,18 +37,20 @@ static int32_t parseTelnetMetric(TAOS_SML_DATA_POINT *pSml, const char **index, const char *cur = *index; uint16_t len = 0; - pSml->stableName = tcalloc(TSDB_TABLE_NAME_LEN, 1); + pSml->stableName = tcalloc(TSDB_TABLE_NAME_LEN + TS_ESCAPE_CHAR_SIZE, 1); if (pSml->stableName == NULL) { return TSDB_CODE_TSC_OUT_OF_MEMORY; } + /* if (isdigit(*cur)) { tscError("OTD:0x%"PRIx64" Metric cannot start with digit", info->id); tfree(pSml->stableName); return TSDB_CODE_TSC_LINE_SYNTAX_ERROR; } + */ while (*cur != '\0') { - if (len >= TSDB_TABLE_NAME_LEN - 1) { + if (len > TSDB_TABLE_NAME_LEN - 1) { tscError("OTD:0x%"PRIx64" Metric cannot exceeds %d characters", info->id, TSDB_TABLE_NAME_LEN - 1); tfree(pSml->stableName); return TSDB_CODE_TSC_INVALID_TABLE_ID_LENGTH; @@ -63,7 +65,7 @@ static int32_t parseTelnetMetric(TAOS_SML_DATA_POINT *pSml, const char **index, } } - pSml->stableName[len] = *cur; + pSml->stableName[len] = tolower(*cur); cur++; len++; @@ -73,7 +75,7 @@ static int32_t parseTelnetMetric(TAOS_SML_DATA_POINT *pSml, const char **index, return TSDB_CODE_TSC_LINE_SYNTAX_ERROR; } - pSml->stableName[len] = '\0'; + addEscapeCharToString(pSml->stableName, len); *index = cur + 1; tscDebug("OTD:0x%"PRIx64" Stable name in metric:%s|len:%d", info->id, pSml->stableName, len); @@ -207,12 +209,12 @@ static int32_t parseTelnetTagKey(TAOS_SML_KV *pKV, const char **index, SHashObj uint16_t len = 0; //key field cannot start with digit - if (isdigit(*cur)) { - tscError("OTD:0x%"PRIx64" Tag key cannot start with digit", info->id); - return TSDB_CODE_TSC_LINE_SYNTAX_ERROR; - } + //if (isdigit(*cur)) { + // tscError("OTD:0x%"PRIx64" Tag key cannot start with digit", info->id); + // return TSDB_CODE_TSC_LINE_SYNTAX_ERROR; + //} while (*cur != '\0') { - if (len >= TSDB_COL_NAME_LEN - 1) { + if (len > TSDB_COL_NAME_LEN - 1) { tscError("OTD:0x%"PRIx64" Tag key cannot exceeds %d characters", info->id, TSDB_COL_NAME_LEN - 1); return TSDB_CODE_TSC_INVALID_COLUMN_LENGTH; } @@ -236,8 +238,10 @@ static int32_t parseTelnetTagKey(TAOS_SML_KV *pKV, const char **index, SHashObj return TSDB_CODE_TSC_DUP_TAG_NAMES; } - pKV->key = tcalloc(len + 1, 1); + pKV->key = tcalloc(len + TS_ESCAPE_CHAR_SIZE + 1, 1); memcpy(pKV->key, key, len + 1); + strntolower_s(pKV->key, pKV->key, (int32_t)len); + addEscapeCharToString(pKV->key, len); //tscDebug("OTD:0x%"PRIx64" Key:%s|len:%d", info->id, pKV->key, len); *index = cur + 1; return TSDB_CODE_SUCCESS; @@ -312,15 +316,12 @@ static int32_t parseTelnetTagKvs(TAOS_SML_KV **pKVs, int *num_kvs, tscError("OTD:0x%"PRIx64" Unable to parse value", info->id); return ret; } - if ((strcasecmp(pkv->key, "ID") == 0)) { - ret = isValidChildTableName(pkv->value, pkv->length, info); - if (ret) { - return ret; - } - *childTableName = malloc(pkv->length + 1); + if ((strcasecmp(pkv->key, "`ID`") == 0)) { + *childTableName = tcalloc(pkv->length + TS_ESCAPE_CHAR_SIZE + 1, 1); memcpy(*childTableName, pkv->value, pkv->length); (*childTableName)[pkv->length] = '\0'; strntolower_s(*childTableName, *childTableName, (int32_t)pkv->length); + addEscapeCharToString(*childTableName, pkv->length); tfree(pkv->key); tfree(pkv->value); } else { @@ -493,19 +494,22 @@ static int32_t parseMetricFromJSON(cJSON *root, TAOS_SML_DATA_POINT* pSml, SSmlL return TSDB_CODE_TSC_INVALID_TABLE_ID_LENGTH; } - pSml->stableName = tcalloc(stableLen + 1, sizeof(char)); + pSml->stableName = tcalloc(stableLen + TS_ESCAPE_CHAR_SIZE + 1, sizeof(char)); if (pSml->stableName == NULL){ return TSDB_CODE_TSC_OUT_OF_MEMORY; } + /* if (isdigit(metric->valuestring[0])) { tscError("OTD:0x%"PRIx64" Metric cannot start with digit in JSON", info->id); tfree(pSml->stableName); return TSDB_CODE_TSC_INVALID_JSON; } + */ tstrncpy(pSml->stableName, metric->valuestring, stableLen + 1); strntolower_s(pSml->stableName, pSml->stableName, (int32_t)stableLen); + addEscapeCharToString(pSml->stableName, stableLen); return TSDB_CODE_SUCCESS; @@ -896,13 +900,10 @@ static int32_t parseTagsFromJSON(cJSON *root, TAOS_SML_KV **pKVs, int *num_kvs, return TSDB_CODE_TSC_INVALID_JSON; } size_t idLen = strlen(id->valuestring); - ret = isValidChildTableName(id->valuestring, (int16_t)idLen, info); - if (ret != TSDB_CODE_SUCCESS) { - return ret; - } - *childTableName = tcalloc(idLen + 1, sizeof(char)); + *childTableName = tcalloc(idLen + TS_ESCAPE_CHAR_SIZE + 1, sizeof(char)); memcpy(*childTableName, id->valuestring, idLen); strntolower_s(*childTableName, *childTableName, (int32_t)idLen); + addEscapeCharToString(*childTableName, idLen); //check duplicate IDs cJSON_DeleteItemFromObject(tags, "ID"); @@ -936,8 +937,10 @@ static int32_t parseTagsFromJSON(cJSON *root, TAOS_SML_KV **pKVs, int *num_kvs, tscError("OTD:0x%"PRIx64" Tag key cannot exceeds %d characters in JSON", info->id, TSDB_COL_NAME_LEN - 1); return TSDB_CODE_TSC_INVALID_COLUMN_LENGTH; } - pkv->key = tcalloc(keyLen + 1, sizeof(char)); + pkv->key = tcalloc(keyLen + TS_ESCAPE_CHAR_SIZE + 1, sizeof(char)); strncpy(pkv->key, tag->string, keyLen); + strntolower_s(pkv->key, pkv->key, (int32_t)keyLen); + addEscapeCharToString(pkv->key, keyLen); //value ret = parseValueFromJSON(tag, pkv, info); if (ret != TSDB_CODE_SUCCESS) { diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index b728f537156cc6a4dbb34bc43ffb2b37a39c62d4..e96e7e5b232a500f5780688cab8a82ab6545e624 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -3174,6 +3174,14 @@ static int16_t doGetColumnIndex(SQueryInfo* pQueryInfo, int32_t index, SStrToken int16_t columnIndex = COLUMN_INDEX_INITIAL_VAL; + char tmpTokenBuf[TSDB_MAX_BYTES_PER_ROW] = {0}; // create tmp buf to avoid alter orginal sqlstr + strncpy(tmpTokenBuf, pToken->z, pToken->n); + pToken->z = tmpTokenBuf; + + if (pToken->type == TK_ID) { + tscRmEscapeAndTrimToken(pToken); + } + for (int16_t i = 0; i < numOfCols; ++i) { if (pToken->n != strlen(pSchema[i].name)) { continue; @@ -6313,6 +6321,13 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { SColumnIndex columnIndex = COLUMN_INDEX_INITIALIZER; SStrToken name = {.type = TK_STRING, .z = pItem->name, .n = (uint32_t)strlen(pItem->name)}; + //handle Escape character backstick + if (name.z[0] == TS_ESCAPE_CHAR && name.z[name.n - 1] == TS_ESCAPE_CHAR) { + memmove(name.z, name.z + 1, name.n); + name.z[name.n - TS_ESCAPE_CHAR_SIZE] = '\0'; + name.n -= TS_ESCAPE_CHAR_SIZE; + } + if (getColumnIndexByName(&name, pQueryInfo, &columnIndex, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(pMsg, msg17); } @@ -6646,6 +6661,9 @@ int32_t validateColumnName(char* name) { } return validateColumnName(token.z); + } else if (token.type == TK_ID) { + strRmquoteEscape(name, token.n); + return TSDB_CODE_SUCCESS; } else { if (isNumber(&token)) { return TSDB_CODE_TSC_INVALID_OPERATION; @@ -7711,7 +7729,7 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) { SCreatedTableInfo* pCreateTableInfo = taosArrayGet(pCreateTable->childTableInfo, j); SStrToken* pToken = &pCreateTableInfo->stableName; - + bool dbIncluded = false; char buf[TSDB_TABLE_FNAME_LEN]; SStrToken sTblToken; @@ -7771,10 +7789,19 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) { for (int32_t i = 0; i < nameSize; ++i) { SStrToken* sToken = taosArrayGet(pNameList, i); + + char tmpTokenBuf[TSDB_MAX_BYTES_PER_ROW] = {0}; // create tmp buf to avoid alter orginal sqlstr + strncpy(tmpTokenBuf, sToken->z, sToken->n); + sToken->z = tmpTokenBuf; + if (TK_STRING == sToken->type) { tscDequoteAndTrimToken(sToken); } + if (TK_ID == sToken->type) { + tscRmEscapeAndTrimToken(sToken); + } + tVariantListItem* pItem = taosArrayGet(pValList, i); findColumnIndex = false; diff --git a/src/client/src/tscSql.c b/src/client/src/tscSql.c index caddde3f088c8ea65743070563a093921c3d2b2d..bb3bddeefd798366fe205eb67b55b3b4a7301df4 100644 --- a/src/client/src/tscSql.c +++ b/src/client/src/tscSql.c @@ -629,6 +629,10 @@ static bool hasAdditionalErrorInfo(int32_t code, SSqlCmd *pCmd) { return false; } + if (pCmd->payload == NULL) { + return false; + } + size_t len = strlen(pCmd->payload); char *z = NULL; diff --git a/src/connector/python/examples/insert-lines.py b/src/connector/python/examples/insert-lines.py index 755050dfb52b180567dd80e87b63508fc4101172..1d20af7e9bcac23deb70c1dbd058bb86dd5585a5 100644 --- a/src/connector/python/examples/insert-lines.py +++ b/src/connector/python/examples/insert-lines.py @@ -1,4 +1,5 @@ import taos +from taos import SmlProtocol, SmlPrecision conn = taos.connect() dbname = "pytest_line" @@ -9,10 +10,10 @@ conn.select_db(dbname) lines = [ 'st,t1=3i64,t2=4f64,t3="t3" c1=3i64,c3=L"pass",c2=false,c4=4f64 1626006833639000000', ] -conn.schemaless_insert(lines, 0, "ns") +conn.schemaless_insert(lines, taos.SmlProtocol.LINE_PROTOCOL, taos.SmlPrecision.NOT_CONFIGURED) print("inserted") -conn.schemaless_insert(lines, 0, "ns") +conn.schemaless_insert(lines, taos.SmlProtocol.LINE_PROTOCOL, taos.SmlPrecision.NOT_CONFIGURED) result = conn.query("show tables") for row in result: diff --git a/src/connector/python/pyproject.toml b/src/connector/python/pyproject.toml index a8099199563a0e5957a7d69e75bab65cca6d17db..da61cccf49429251d49f2cba495e24e146244c85 100644 --- a/src/connector/python/pyproject.toml +++ b/src/connector/python/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "taos" -version = "2.1.0" +version = "2.1.1" description = "TDengine connector for python" authors = ["Taosdata Inc. "] license = "AGPL-3.0" diff --git a/src/connector/python/setup.py b/src/connector/python/setup.py index b7e10001737bc40c04173ea4a65e95248965ffda..8f1dfafe4762e4a55a6d3e7c645c945a67a10f68 100644 --- a/src/connector/python/setup.py +++ b/src/connector/python/setup.py @@ -5,7 +5,7 @@ with open("README.md", "r") as fh: setuptools.setup( name="taos", - version="2.1.0", + version="2.1.1", author="Taosdata Inc.", author_email="support@taosdata.com", description="TDengine python client package", diff --git a/src/connector/python/taos/__init__.py b/src/connector/python/taos/__init__.py index ebbad68c5a8a148a601fb5ec48f9658a1920ed62..2520984e78fad236227d9cf55c29ace92878d3bf 100644 --- a/src/connector/python/taos/__init__.py +++ b/src/connector/python/taos/__init__.py @@ -440,6 +440,7 @@ from .cursor import * from .result import * from .statement import * from .subscription import * +from .schemaless import * try: import importlib.metadata @@ -468,6 +469,8 @@ __all__ = [ "TaosRow", "TaosStmt", "PrecisionEnum", + "SmlPrecision", + "SmlProtocol" ] def connect(*args, **kwargs): diff --git a/src/connector/python/taos/cinterface.py b/src/connector/python/taos/cinterface.py index 1223b4544899dd83d3f1ea1a519def035de8ebcf..4365c7eabc509f95525078378ff76d46a884c075 100644 --- a/src/connector/python/taos/cinterface.py +++ b/src/connector/python/taos/cinterface.py @@ -12,6 +12,7 @@ except: from .error import * from .bind import * from .field import * +from .schemaless import * # stream callback @@ -64,6 +65,8 @@ _libtaos.taos_consume.restype = ctypes.c_void_p _libtaos.taos_fetch_lengths.restype = ctypes.POINTER(ctypes.c_int) _libtaos.taos_free_result.restype = None _libtaos.taos_query.restype = ctypes.POINTER(ctypes.c_void_p) +_libtaos.taos_schemaless_insert.restype = ctypes.c_void_p + try: _libtaos.taos_stmt_errstr.restype = c_char_p except AttributeError: @@ -808,30 +811,27 @@ def taos_stmt_use_result(stmt): return result try: - _libtaos.taos_insert_lines.restype = c_int - _libtaos.taos_insert_lines.argstype = c_void_p, c_void_p, c_int + _libtaos.taos_schemaless_insert.restype = c_void_p + _libtaos.taos_schemaless_insert.argstype = c_void_p, c_void_p, c_int, c_int, c_int except AttributeError: - print("WARNING: libtaos(%s) does not support insert_lines" % taos_get_client_info()) - - - + print("WARNING: libtaos(%s) does not support taos_schemaless_insert" % taos_get_client_info()) def taos_schemaless_insert(connection, lines, protocol, precision): - # type: (c_void_p, list[str] | tuple(str)) -> None + # type: (c_void_p, list[str] | tuple(str), SmlProtocol, SmlPrecision) -> int num_of_lines = len(lines) lines = (c_char_p(line.encode("utf-8")) for line in lines) lines_type = ctypes.c_char_p * num_of_lines p_lines = lines_type(*lines) res = c_void_p(_libtaos.taos_schemaless_insert(connection, p_lines, num_of_lines, protocol, precision)) errno = taos_errno(res) + affected_rows = taos_affected_rows(res) if errno != 0: errstr = taos_errstr(res) taos_free_result(res) - print("schemaless_insert error affected rows: {}".format(taos_affected_rows(res))) - raise SchemalessError(errstr, errno) + raise SchemalessError(errstr, errno, affected_rows) taos_free_result(res) - return errno + return affected_rows class CTaosInterface(object): def __init__(self, config=None): diff --git a/src/connector/python/taos/connection.py b/src/connector/python/taos/connection.py index dfac42f244d19267124c5ea790d4503e28fd5a78..dc8225ab33c84930214eb8f0d8ba47f6f31a5adf 100644 --- a/src/connector/python/taos/connection.py +++ b/src/connector/python/taos/connection.py @@ -72,10 +72,9 @@ class TaosConnection(object): taos_select_db(self._conn, database) def execute(self, sql): - # type: (str) -> None + # type: (str) -> int """Simplely execute sql ignoring the results""" - res = taos_query(self._conn, sql) - taos_free_result(res) + return self.query(sql).affected_rows def query(self, sql): # type: (str) -> TaosResult @@ -118,7 +117,7 @@ class TaosConnection(object): return TaosStream(stream) def schemaless_insert(self, lines, protocol, precision): - # type: (list[str]) -> None + # type: (list[str], SmlProtocol, SmlPrecision) -> int """ 1.Line protocol and schemaless support @@ -171,6 +170,7 @@ class TaosConnection(object): conn.schemaless_insert(lines, 2, None) """ + print(lines, protocol, precision) return taos_schemaless_insert(self._conn, lines, protocol, precision) diff --git a/src/connector/python/taos/error.py b/src/connector/python/taos/error.py index 723f6f1a2db1249a3773538b4bfa6d51595a005d..122466fe3c448ec551fb910c402ad14bb6c93336 100644 --- a/src/connector/python/taos/error.py +++ b/src/connector/python/taos/error.py @@ -83,7 +83,16 @@ class ResultError(DatabaseError): class SchemalessError(DatabaseError): """taos_schemaless_insert errors.""" - pass + def __init__(self, msg=None, errno=0xffff, affected_rows=0): + DatabaseError.__init__(self, msg, errno) + self.affected_rows = affected_rows + + def __str__(self): + return self._full_msg + "(affected rows: %d)" % self.affected_rows + + # @property + # def affected_rows(self): + # return self.affected_rows class StatementError(DatabaseError): diff --git a/src/connector/python/taos/result.py b/src/connector/python/taos/result.py index 81151733615d1b7fdc3318b6e53888ae39d32b14..c9feb4d6502515cc6e3e2d4be688f2e7fcd895b2 100644 --- a/src/connector/python/taos/result.py +++ b/src/connector/python/taos/result.py @@ -123,6 +123,12 @@ class TaosResult(object): for i in range(len(self._fields)): buffer[i].extend(block[i]) return list(map(tuple, zip(*buffer))) + + def fetch_all_into_dict(self): + """Fetch all rows and convert it to dict""" + names = [field.name for field in self.fields] + rows = self.fetch_all() + return list(dict(zip(names, row)) for row in rows) def fetch_rows_a(self, callback, param): taos_fetch_rows_a(self._result, callback, param) @@ -228,6 +234,12 @@ class TaosRow: blocks[i] = CONVERT_FUNC[fields[i].type](data, 1, field_lens[i], precision)[0] return tuple(blocks) + def as_dict(self): + values = self.as_tuple() + names = self._result.fields + dict(zip(names, values)) + + class TaosBlocks: """TDengine result blocks iterator""" diff --git a/src/connector/python/taos/schemaless.py b/src/connector/python/taos/schemaless.py new file mode 100644 index 0000000000000000000000000000000000000000..35967412f78a63e67d63f0e58bbf903f21fb275a --- /dev/null +++ b/src/connector/python/taos/schemaless.py @@ -0,0 +1,17 @@ + +class SmlPrecision: + """Schemaless timestamp precision constants""" + NOT_CONFIGURED = 0 # C.TSDB_SML_TIMESTAMP_NOT_CONFIGURED + HOURS = 1 + MINUTES = 2 + SECONDS = 3 + MILLI_SECONDS = 4 + MICRO_SECONDS = 5 + NANO_SECONDS = 6 + +class SmlProtocol: + """Schemaless protocol constants""" + UNKNOWN_PROTOCOL = 0 + LINE_PROTOCOL = 1 + TELNET_PROTOCOL = 2 + JSON_PROTOCOL = 3 \ No newline at end of file diff --git a/src/connector/python/tests/test_lines.py b/src/connector/python/tests/test_lines.py index 93bab039abfa2a1e6fea7947ed926dc804ec5d6f..51d23b8e891d398b404086fdb2ff2910dcc1eb0a 100644 --- a/src/connector/python/tests/test_lines.py +++ b/src/connector/python/tests/test_lines.py @@ -1,4 +1,4 @@ -from taos.error import OperationalError +from taos.error import OperationalError, SchemalessError from taos import connect, new_bind_params, PrecisionEnum from taos import * @@ -13,32 +13,95 @@ def conn(): return connect() +def test_schemaless_insert_update_2(conn): + # type: (TaosConnection) -> None + + dbname = "test_schemaless_insert_update_2" + try: + conn.execute("drop database if exists %s" % dbname) + conn.execute("create database if not exists %s update 2 precision 'ns'" % dbname) + conn.select_db(dbname) + + lines = [ + 'st,t1=4i64,t3="t4",t2=5f64,t4=5f64 c1=3i64,c3=L"passitagin, abc",c2=true,c4=5f64,c5=5f64,c6=7u64 1626006933640000000', + ] + res = conn.schemaless_insert(lines, 1, 0) + print("affected rows: ", res) + assert(res == 1) + + result = conn.query("select * from st") + [before] = result.fetch_all_into_dict() + assert(before["c3"] == "passitagin, abc") + + lines = [ + 'st,t1=4i64,t3="t4",t2=5f64,t4=5f64 c1=3i64,c3=L"passitagin",c2=true,c4=5f64,c5=5f64,c6=7u64 1626006933640000000', + ] + res = conn.schemaless_insert(lines, 1, 0) + result = conn.query("select * from st") + [after] = result.fetch_all_into_dict() + assert(after["c3"] == "passitagin") + + conn.execute("drop database if exists %s" % dbname) + conn.close() + + except Exception as err: + conn.execute("drop database if exists %s" % dbname) + conn.close() + print(err) + raise err + def test_schemaless_insert(conn): # type: (TaosConnection) -> None dbname = "pytest_taos_schemaless_insert" try: conn.execute("drop database if exists %s" % dbname) - conn.execute("create database if not exists %s precision 'us'" % dbname) + conn.execute("create database if not exists %s update 2 precision 'ns'" % dbname) conn.select_db(dbname) lines = [ 'st,t1=3i64,t2=4f64,t3="t3" c1=3i64,c3=L"passit",c2=false,c4=4f64 1626006833639000000', - 'st,t1=4i64,t3="t4",t2=5f64,t4=5f64 c1=3i64,c3=L"passitagin",c2=true,c4=5f64,c5=5f64,c6=7u64 1626006933640000000', + 'st,t1=4i64,t3="t4",t2=5f64,t4=5f64 c1=3i64,c3=L"passitagin, abc",c2=true,c4=5f64,c5=5f64,c6=7u64 1626006933640000000', 'stf,t1=4i64,t3="t4",t2=5f64,t4=5f64 c1=3i64,c3=L"passitagin_stf",c2=false,c5=5f64,c6=7u64 1626006933641000000', ] - conn.schemaless_insert(lines, 0, "ns") + res = conn.schemaless_insert(lines, 1, 0) + print("affected rows: ", res) + assert(res == 3) lines = [ 'stf,t1=5i64,t3="t4",t2=5f64,t4=5f64 c1=3i64,c3=L"passitagin_stf",c2=false,c5=5f64,c6=7u64 1626006933641000000', ] - conn.schemaless_insert(lines, 0, "ns") + res = conn.schemaless_insert(lines, 1, 0) + print("affected rows: ", res) + assert(res == 1) + result = conn.query("select * from st") + + dict2 = result.fetch_all_into_dict() + print(dict2) + result.row_count + all = result.rows_iter() + for row in all: + print(row) + result.close() + assert(result.row_count == 2) + + # error test + lines = [ + ',t1=3i64,t2=4f64,t3="t3" c1=3i64,c3=L"passit",c2=false,c4=4f64 1626006833639000000', + ] + try: + res = conn.schemaless_insert(lines, 1, 0) + print(res) + # assert(False) + except SchemalessError as err: + pass + result = conn.query("select * from st") + result.row_count all = result.rows_iter() for row in all: print(row) result.close() - print(result.row_count) conn.execute("drop database if exists %s" % dbname) conn.close() @@ -52,3 +115,4 @@ def test_schemaless_insert(conn): if __name__ == "__main__": test_schemaless_insert(connect()) + test_schemaless_insert_update_2(connect()) diff --git a/src/connector/python/tests/test_stmt.py b/src/connector/python/tests/test_stmt.py index 938ba10eb3d2377a63f7972deb99dbd47f7de1b2..3368ecb6a9336a4295790f2cd55314ac9bb6290e 100644 --- a/src/connector/python/tests/test_stmt.py +++ b/src/connector/python/tests/test_stmt.py @@ -1,3 +1,4 @@ +# encoding:UTF-8 from taos import * from ctypes import * diff --git a/src/inc/taosdef.h b/src/inc/taosdef.h index d7848937b137c2e458c567099e3df0e386eb92fa..78fb2ac01c1d8cd01d8d704a384891125f8bb00e 100644 --- a/src/inc/taosdef.h +++ b/src/inc/taosdef.h @@ -99,6 +99,7 @@ extern const int32_t TYPE_BYTES[15]; #define TS_PATH_DELIMITER "." #define TS_ESCAPE_CHAR '`' +#define TS_ESCAPE_CHAR_SIZE 2 #define TSDB_TIME_PRECISION_MILLI 0 #define TSDB_TIME_PRECISION_MICRO 1 diff --git a/src/kit/taosdemo/taosdemo.c b/src/kit/taosdemo/taosdemo.c index e1103fa7ab64f90eee93212ebbb53ea34f179161..902d2adcb33f5828343037afb042c9aff7627630 100644 --- a/src/kit/taosdemo/taosdemo.c +++ b/src/kit/taosdemo/taosdemo.c @@ -3482,8 +3482,14 @@ static int postProceSql(char *host, uint16_t port, 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'}; - snprintf(userpass_buf, INPUT_BUF_LEN, "%s:%s", - g_Dbs.user, g_Dbs.password); + if (g_args.test_mode == INSERT_TEST) { + snprintf(userpass_buf, INPUT_BUF_LEN, "%s:%s", + g_Dbs.user, g_Dbs.password); + } else { + snprintf(userpass_buf, INPUT_BUF_LEN, "%s:%s", + g_queryInfo.user, g_queryInfo.password); + } + size_t userpass_buf_len = strlen(userpass_buf); size_t encoded_len = 4 * ((userpass_buf_len +2) / 3); diff --git a/src/util/src/ttokenizer.c b/src/util/src/ttokenizer.c index 99ade6db1a76fdac48e441a2c1a9a2a3d388f812..8414b6292c43f674d62a61338ca271273922a209 100644 --- a/src/util/src/ttokenizer.c +++ b/src/util/src/ttokenizer.c @@ -628,7 +628,7 @@ SStrToken tStrGetToken(char* str, int32_t* i, bool isPrevOptr) { t0.n = 0; return t0; } - + t = str[++(*i)]; } diff --git a/src/util/src/tutil.c b/src/util/src/tutil.c index 35ec90cb2efbb270c8b007f9bdb347333a87fded..31556b83d06224d285db29650eba82c4d3acab5e 100644 --- a/src/util/src/tutil.c +++ b/src/util/src/tutil.c @@ -53,13 +53,13 @@ int32_t strdequote(char *z) { } -int32_t strRmquote(char *z, int32_t len){ +int32_t strRmquote(char *z, int32_t len){ // delete escape character: \\, \', \" char delim = z[0]; if (delim != '\'' && delim != '\"') { return len; } - + int32_t cnt = 0; int32_t j = 0; for (uint32_t k = 1; k < len - 1; ++k) { @@ -74,23 +74,24 @@ int32_t strRmquote(char *z, int32_t len){ continue; } } - + z[j] = z[k]; j++; } - + z[j] = 0; - + return len - 2 - cnt; } int32_t strRmquoteEscape(char *z, int32_t len) { if (len <= 0) return len; - + if (z[0] == '\'' || z[0] == '\"') { return strRmquote(z, len); } else if (len > 1 && z[0] == TS_ESCAPE_CHAR && z[len - 1] == TS_ESCAPE_CHAR) { memmove(z, z + 1, len - 2); + z[len - 2] = '\0'; return len - 2; } diff --git a/tests/examples/c/apitest.c b/tests/examples/c/apitest.c index 2510035e9217f4907ac8fdd3d11d7fc123a2bfa6..2c197887e7d7f1e6397213641a02ee8b37a84190 100644 --- a/tests/examples/c/apitest.c +++ b/tests/examples/c/apitest.c @@ -15,7 +15,7 @@ static void prepare_data(TAOS* taos) { result = taos_query(taos, "drop database if exists test;"); taos_free_result(result); usleep(100000); - result = taos_query(taos, "create database test precision 'us';"); + result = taos_query(taos, "create database test precision 'ns';"); taos_free_result(result); usleep(100000); taos_select_db(taos, "test"); @@ -293,7 +293,7 @@ void verify_schema_less(TAOS* taos) { result = taos_query(taos, "drop database if exists test;"); taos_free_result(result); usleep(100000); - result = taos_query(taos, "create database test precision 'us' update 1;"); + result = taos_query(taos, "create database test precision 'ns' update 1 keep 36500;"); taos_free_result(result); usleep(100000); @@ -401,6 +401,21 @@ void verify_schema_less(TAOS* taos) { } taos_free_result(result); + //Test timestamp precision + char* lines7[] = { + "stts,t1=10i64,t2=4f64,t3=\"t3\" c1=3i64,c3=L\"passit\",c2=false,c4=4f64 1", + }; + + for (int precision = TSDB_SML_TIMESTAMP_HOURS; precision <= TSDB_SML_TIMESTAMP_NANO_SECONDS; ++precision) { + result = taos_schemaless_insert(taos, lines7, 1, TSDB_SML_LINE_PROTOCOL, precision); + code = taos_errno(result); + if (code != TSDB_CODE_SUCCESS) { + affected_rows = taos_affected_rows(result); + printf("\033[31m [lines7_%d]taos_schemaless_insert failed, code: %d,%s, affected rows:%d \033[0m\n", precision, code, taos_errstr(result), affected_rows); + } + taos_free_result(result); + } + } int main(int argc, char* argv[]) { diff --git a/tests/examples/c/epoll.c b/tests/examples/c/epoll.c index 0fb8754de666d7067ef3dcbf9b7797592ca5b61b..05df33ffe6f0c08dd5608bb3ba30a21623f2ae45 100644 --- a/tests/examples/c/epoll.c +++ b/tests/examples/c/epoll.c @@ -92,7 +92,7 @@ static void null_event(ep_t *ep, struct epoll_event *ev, fde_t *client); fprintf(stderr, "" fmt "\n", ##__VA_ARGS__); \ } \ fprintf(stderr, "usage:\n"); \ - fprintf(stderr, " %s -l : specify listenning port\n", arg0); \ + fprintf(stderr, " %s -l : specify listening port\n", arg0); \ } while (0) int main(int argc, char *argv[]) { @@ -256,7 +256,7 @@ static int open_listen(unsigned short port) { E("getsockname() failed"); } A(len == sizeof(si), "internal logic error"); - D("listenning at: %d", ntohs(si.sin_port)); + D("listening at: %d", ntohs(si.sin_port)); return skt; } while (0); close(skt); diff --git a/tests/pytest/functions/queryTestCases.py b/tests/pytest/functions/queryTestCases.py index b254908c42ec8f267fa947b5c759101b16b066a9..e5213d9f7253d1a82e84584c87b66291daf01f25 100644 --- a/tests/pytest/functions/queryTestCases.py +++ b/tests/pytest/functions/queryTestCases.py @@ -418,10 +418,14 @@ class TDTestCase: tdSql.execute("use db") tdSql.execute("create stable db.stb1 (ts timestamp, c1 int) tags(t1 int)") + nowtime = int(round(time.time() * 1000)) for i in range(1000): tdSql.execute(f"create table db.t1{i} using db.stb1 tags({i})") + sql = f"insert into db.t1{i} values" for j in range(260): - tdSql.execute(f"insert into db.t1{i} values (now-100d, {i+j})") + sql += f"({nowtime-1000*i-j}, {i+j})" + # tdSql.execute(f"insert into db.t1{i} values (now-100d, {i+j})") + tdSql.execute(sql) # tdDnodes.stop(dnode_index) # tdDnodes.start(dnode_index) @@ -465,7 +469,7 @@ class TDTestCase: # tdSql.execute("insert into db.t1 values ('2021-07-01 08:00:04.000', 1001.51, 1001.52, 1001.53, 1001.54)") # for i in range(1000000): - for i in range(1000000): + for i in range(10000): random1 = random.uniform(1000,1001) random2 = random.uniform(1000,1001) random3 = random.uniform(1000,1001) diff --git a/tests/pytest/insert/insertJSONPayload.py b/tests/pytest/insert/insertJSONPayload.py index 41d60cd1520e09b94c90083f8b6a361df4556444..81d4b47ef15cb03311943d3d53c2efe25a3b0312 100644 --- a/tests/pytest/insert/insertJSONPayload.py +++ b/tests/pytest/insert/insertJSONPayload.py @@ -36,7 +36,7 @@ class TDTestCase: print("============= step0 : test metric ================") payload = [''' { - "metric": "`.stb.0.`", + "metric": ".stb.0.", "timestamp": 1626006833610, "value": 10, "tags": { @@ -664,6 +664,183 @@ class TDTestCase: tdSql.checkData(9, 1, "BINARY") tdSql.checkData(10, 1, "NCHAR") + ### special characters ### + + payload = [''' + { + "metric": "1234", + "timestamp": 1626006833, + "value": 1, + "tags": { + "id": "123", + "456": true, + "int": false, + "double": 1, + "into": 1, + "from": 2, + "!@#$.%^&*()": "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>" + } + } + '''] + code = self._conn.schemaless_insert(payload, TDSmlProtocolType.JSON.value, TDSmlTimestampType.NOT_CONFIGURED.value) + print("schemaless_insert result {}".format(code)) + + tdSql.query("describe `1234`") + tdSql.checkRows(8) + + tdSql.query("select * from `123`") + tdSql.checkRows(1) + + payload = [''' + { + "metric": "int", + "timestamp": 1626006833, + "value": 1, + "tags": { + "id": "and", + "456": true, + "int": false, + "double": 1, + "into": 1, + "from": 2, + "!@#$.%^&*()": "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>" + } + } + '''] + code = self._conn.schemaless_insert(payload, TDSmlProtocolType.JSON.value, TDSmlTimestampType.NOT_CONFIGURED.value) + print("schemaless_insert result {}".format(code)) + + tdSql.query("describe `int`") + tdSql.checkRows(8) + + tdSql.query("select * from `and`") + tdSql.checkRows(1) + + payload = [''' + { + "metric": "double", + "timestamp": 1626006833, + "value": 1, + "tags": { + "id": "for", + "456": true, + "int": false, + "double": 1, + "into": 1, + "from": 2, + "!@#$.%^&*()": "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>" + } + } + '''] + code = self._conn.schemaless_insert(payload, TDSmlProtocolType.JSON.value, TDSmlTimestampType.NOT_CONFIGURED.value) + print("schemaless_insert result {}".format(code)) + + tdSql.query("describe `double`") + tdSql.checkRows(8) + + tdSql.query("select * from `for`") + tdSql.checkRows(1) + + payload = [''' + { + "metric": "from", + "timestamp": 1626006833, + "value": 1, + "tags": { + "id": "!@#.^&", + "456": true, + "int": false, + "double": 1, + "into": 1, + "from": 2, + "!@#$.%^&*()": "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>" + } + } + '''] + code = self._conn.schemaless_insert(payload, TDSmlProtocolType.JSON.value, TDSmlTimestampType.NOT_CONFIGURED.value) + print("schemaless_insert result {}".format(code)) + + tdSql.query("describe `from`") + tdSql.checkRows(8) + + tdSql.query("select * from `!@#.^&`") + tdSql.checkRows(1) + + payload = [''' + { + "metric": "!@#$.%^&*()", + "timestamp": 1626006833, + "value": 1, + "tags": { + "id": "none", + "456": true, + "int": false, + "double": 1, + "into": 1, + "from": 2, + "!@#$.%^&*()": "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>" + } + } + '''] + code = self._conn.schemaless_insert(payload, TDSmlProtocolType.JSON.value, TDSmlTimestampType.NOT_CONFIGURED.value) + print("schemaless_insert result {}".format(code)) + + tdSql.query("describe `!@#$.%^&*()`") + tdSql.checkRows(8) + + tdSql.query("select * from `none`") + tdSql.checkRows(1) + + payload = [''' + { + "metric": "STABLE", + "timestamp": { + "value": 1626006833, + "type": "s" + }, + "value": { + "value": "hello", + "type": "nchar" + }, + "tags": { + "id": "KEY", + "456": { + "value": true, + "type": "bool" + }, + "int": { + "value": 127, + "type": "tinyint" + }, + "double":{ + "value": 32767, + "type": "smallint" + }, + "into": { + "value": 2147483647, + "type": "int" + }, + "INSERT": { + "value": 9.2233720368547758e+18, + "type": "bigint" + }, + "!@#$.%^&*()": { + "value": 11.12345, + "type": "float" + } + } + } + '''] + + code = self._conn.schemaless_insert(payload, TDSmlProtocolType.JSON.value, TDSmlTimestampType.NOT_CONFIGURED.value) + print("schemaless_insert result {}".format(code)) + + tdSql.query("describe `stable`") + tdSql.checkRows(8) + + tdSql.query("select * from `key`") + tdSql.checkRows(1) + def stop(self): tdSql.close() diff --git a/tests/pytest/insert/insertTelnetLines.py b/tests/pytest/insert/insertTelnetLines.py index 0ecf93b5a459d2aac2a656543e946173f8309759..a48351f6c0b162be83f6aca44a87ff9f55b498c8 100644 --- a/tests/pytest/insert/insertTelnetLines.py +++ b/tests/pytest/insert/insertTelnetLines.py @@ -35,7 +35,7 @@ class TDTestCase: "stb0_0 1626006833639000000ns 4i8 host=\"host0\" interface=\"eth0\"", "stb0_1 1626006833639000000ns 4i8 host=\"host0\" interface=\"eth0\"", "stb0_2 1626006833639000000ns 4i8 host=\"host0\" interface=\"eth0\"", - "`.stb0.3.` 1626006833639000000ns 4i8 host=\"host0\" interface=\"eth0\"", + ".stb0.3. 1626006833639000000ns 4i8 host=\"host0\" interface=\"eth0\"", ] code = self._conn.schemaless_insert(lines0, TDSmlProtocolType.TELNET.value, TDSmlTimestampType.NOT_CONFIGURED.value) @@ -59,28 +59,24 @@ class TDTestCase: ### timestamp ### print("============= step2 : test timestamp ================") lines1 = [ - "stb1 1626006833s 1i8 host=\"host0\"", - "stb1 1626006833639000000ns 2i8 host=\"host0\"", - "stb1 1626006833640000us 3i8 host=\"host0\"", - "stb1 1626006833641 4i8 host=\"host0\"", - "stb1 1626006834 5i8 host=\"host0\"", - "stb1 1626006833651ms 6i8 host=\"host0\"", - "stb1 0 7i8 host=\"host0\"", + "stb1 1626006833641 1i8 host=\"host0\"", + "stb1 1626006834 2i8 host=\"host0\"", + "stb1 0 3i8 host=\"host0\"", ] code = self._conn.schemaless_insert(lines1, TDSmlProtocolType.TELNET.value, TDSmlTimestampType.NOT_CONFIGURED.value) print("schemaless_insert result {}".format(code)) tdSql.query("select * from stb1") - tdSql.checkRows(7) + tdSql.checkRows(3) ### metric value ### print("============= step3 : test metric value ================") #tinyint lines2_0 = [ - "stb2_0 1626006833651ms -127i8 host=\"host0\"", - "stb2_0 1626006833652ms 127i8 host=\"host0\"" + "stb2_0 1626006833651 -127i8 host=\"host0\"", + "stb2_0 1626006833652 127i8 host=\"host0\"" ] code = self._conn.schemaless_insert(lines2_0, TDSmlProtocolType.TELNET.value, TDSmlTimestampType.NOT_CONFIGURED.value) print("schemaless_insert result {}".format(code)) @@ -94,8 +90,8 @@ class TDTestCase: #smallint lines2_1 = [ - "stb2_1 1626006833651ms -32767i16 host=\"host0\"", - "stb2_1 1626006833652ms 32767i16 host=\"host0\"" + "stb2_1 1626006833651 -32767i16 host=\"host0\"", + "stb2_1 1626006833652 32767i16 host=\"host0\"" ] code = self._conn.schemaless_insert(lines2_1, TDSmlProtocolType.TELNET.value, TDSmlTimestampType.NOT_CONFIGURED.value) print("schemaless_insert result {}".format(code)) @@ -109,8 +105,8 @@ class TDTestCase: #int lines2_2 = [ - "stb2_2 1626006833651ms -2147483647i32 host=\"host0\"", - "stb2_2 1626006833652ms 2147483647i32 host=\"host0\"" + "stb2_2 1626006833651 -2147483647i32 host=\"host0\"", + "stb2_2 1626006833652 2147483647i32 host=\"host0\"" ] code = self._conn.schemaless_insert(lines2_2, TDSmlProtocolType.TELNET.value, TDSmlTimestampType.NOT_CONFIGURED.value) @@ -125,8 +121,8 @@ class TDTestCase: #bigint lines2_3 = [ - "stb2_3 1626006833651ms -9223372036854775807i64 host=\"host0\"", - "stb2_3 1626006833652ms 9223372036854775807i64 host=\"host0\"" + "stb2_3 1626006833651 -9223372036854775807i64 host=\"host0\"", + "stb2_3 1626006833652 9223372036854775807i64 host=\"host0\"" ] code = self._conn.schemaless_insert(lines2_3, TDSmlProtocolType.TELNET.value, TDSmlTimestampType.NOT_CONFIGURED.value) @@ -141,16 +137,16 @@ class TDTestCase: #float lines2_4 = [ - "stb2_4 1626006833610ms 3f32 host=\"host0\"", - "stb2_4 1626006833620ms -3f32 host=\"host0\"", - "stb2_4 1626006833630ms 3.4f32 host=\"host0\"", - "stb2_4 1626006833640ms -3.4f32 host=\"host0\"", - "stb2_4 1626006833650ms 3.4E10f32 host=\"host0\"", - "stb2_4 1626006833660ms -3.4e10f32 host=\"host0\"", - "stb2_4 1626006833670ms 3.4E+2f32 host=\"host0\"", - "stb2_4 1626006833680ms -3.4e-2f32 host=\"host0\"", - "stb2_4 1626006833700ms 3.4E38f32 host=\"host0\"", - "stb2_4 1626006833710ms -3.4E38f32 host=\"host0\"" + "stb2_4 1626006833610 3f32 host=\"host0\"", + "stb2_4 1626006833620 -3f32 host=\"host0\"", + "stb2_4 1626006833630 3.4f32 host=\"host0\"", + "stb2_4 1626006833640 -3.4f32 host=\"host0\"", + "stb2_4 1626006833650 3.4E10f32 host=\"host0\"", + "stb2_4 1626006833660 -3.4e10f32 host=\"host0\"", + "stb2_4 1626006833670 3.4E+2f32 host=\"host0\"", + "stb2_4 1626006833680 -3.4e-2f32 host=\"host0\"", + "stb2_4 1626006833700 3.4E38f32 host=\"host0\"", + "stb2_4 1626006833710 -3.4E38f32 host=\"host0\"" ] code = self._conn.schemaless_insert(lines2_4, TDSmlProtocolType.TELNET.value, TDSmlTimestampType.NOT_CONFIGURED.value) @@ -165,17 +161,17 @@ class TDTestCase: #double lines2_5 = [ - "stb2_5 1626006833610ms 3f64 host=\"host0\"", - "stb2_5 1626006833620ms -3f64 host=\"host0\"", - "stb2_5 1626006833630ms 3.4f64 host=\"host0\"", - "stb2_5 1626006833640ms -3.4f64 host=\"host0\"", - "stb2_5 1626006833650ms 3.4E10f64 host=\"host0\"", - "stb2_5 1626006833660ms -3.4e10f64 host=\"host0\"", - "stb2_5 1626006833670ms 3.4E+2f64 host=\"host0\"", - "stb2_5 1626006833680ms -3.4e-2f64 host=\"host0\"", - "stb2_5 1626006833690ms 1.7E308f64 host=\"host0\"", - "stb2_5 1626006833700ms -1.7E308f64 host=\"host0\"", - "stb2_5 1626006833710ms 3 host=\"host0\"" + "stb2_5 1626006833610 3f64 host=\"host0\"", + "stb2_5 1626006833620 -3f64 host=\"host0\"", + "stb2_5 1626006833630 3.4f64 host=\"host0\"", + "stb2_5 1626006833640 -3.4f64 host=\"host0\"", + "stb2_5 1626006833650 3.4E10f64 host=\"host0\"", + "stb2_5 1626006833660 -3.4e10f64 host=\"host0\"", + "stb2_5 1626006833670 3.4E+2f64 host=\"host0\"", + "stb2_5 1626006833680 -3.4e-2f64 host=\"host0\"", + "stb2_5 1626006833690 1.7E308f64 host=\"host0\"", + "stb2_5 1626006833700 -1.7E308f64 host=\"host0\"", + "stb2_5 1626006833710 3 host=\"host0\"" ] code = self._conn.schemaless_insert(lines2_5, TDSmlProtocolType.TELNET.value, TDSmlTimestampType.NOT_CONFIGURED.value) @@ -190,16 +186,16 @@ class TDTestCase: #bool lines2_6 = [ - "stb2_6 1626006833610ms t host=\"host0\"", - "stb2_6 1626006833620ms T host=\"host0\"", - "stb2_6 1626006833630ms true host=\"host0\"", - "stb2_6 1626006833640ms True host=\"host0\"", - "stb2_6 1626006833650ms TRUE host=\"host0\"", - "stb2_6 1626006833660ms f host=\"host0\"", - "stb2_6 1626006833670ms F host=\"host0\"", - "stb2_6 1626006833680ms false host=\"host0\"", - "stb2_6 1626006833690ms False host=\"host0\"", - "stb2_6 1626006833700ms FALSE host=\"host0\"" + "stb2_6 1626006833610 t host=\"host0\"", + "stb2_6 1626006833620 T host=\"host0\"", + "stb2_6 1626006833630 true host=\"host0\"", + "stb2_6 1626006833640 True host=\"host0\"", + "stb2_6 1626006833650 TRUE host=\"host0\"", + "stb2_6 1626006833660 f host=\"host0\"", + "stb2_6 1626006833670 F host=\"host0\"", + "stb2_6 1626006833680 false host=\"host0\"", + "stb2_6 1626006833690 False host=\"host0\"", + "stb2_6 1626006833700 FALSE host=\"host0\"" ] code = self._conn.schemaless_insert(lines2_6, TDSmlProtocolType.TELNET.value, TDSmlTimestampType.NOT_CONFIGURED.value) @@ -214,9 +210,9 @@ class TDTestCase: #binary lines2_7 = [ - "stb2_7 1626006833610ms \" binary_val .!@#$%^&* \" host=\"host0\"", - "stb2_7 1626006833620ms \"binary_val.:;,./?|+-=\" host=\"host0\"", - "stb2_7 1626006833630ms \"binary_val.()[]{}<>\" host=\"host0\"" + "stb2_7 1626006833610 \" binary_val .!@#$%^&* \" host=\"host0\"", + "stb2_7 1626006833620 \"binary_val.:;,./?|+-=\" host=\"host0\"", + "stb2_7 1626006833630 \"binary_val.()[]{}<>\" host=\"host0\"" ] code = self._conn.schemaless_insert(lines2_7, TDSmlProtocolType.TELNET.value, TDSmlTimestampType.NOT_CONFIGURED.value) @@ -231,8 +227,8 @@ class TDTestCase: #nchar lines2_8 = [ - "stb2_8 1626006833610ms L\" nchar_val 数值一 \" host=\"host0\"", - "stb2_8 1626006833620ms L\"nchar_val数值二\" host=\"host0\"" + "stb2_8 1626006833610 L\" nchar_val 数值一 \" host=\"host0\"", + "stb2_8 1626006833620 L\"nchar_val数值二\" host=\"host0\"" ] code = self._conn.schemaless_insert(lines2_8, TDSmlProtocolType.TELNET.value, TDSmlTimestampType.NOT_CONFIGURED.value) @@ -249,8 +245,8 @@ class TDTestCase: print("============= step3 : test tags ================") #tag value types lines3_0 = [ - "stb3_0 1626006833610ms 1 t1=127i8 t2=32767i16 t3=2147483647i32 t4=9223372036854775807i64 t5=3.4E38f32 t6=1.7E308f64 t7=true t8=\"binary_val_1\" t9=L\"标签值1\"", - "stb3_0 1626006833610ms 2 t1=-127i8 t2=-32767i16 t3=-2147483647i32 t4=-9223372036854775807i64 t5=-3.4E38f32 t6=-1.7E308f64 t7=false t8=\"binary_val_2\" t9=L\"标签值2\"" + "stb3_0 1626006833610 1 t1=127i8 t2=32767i16 t3=2147483647i32 t4=9223372036854775807i64 t5=3.4E38f32 t6=1.7E308f64 t7=true t8=\"binary_val_1\" t9=L\"标签值1\"", + "stb3_0 1626006833610 2 t1=-127i8 t2=-32767i16 t3=-2147483647i32 t4=-9223372036854775807i64 t5=-3.4E38f32 t6=-1.7E308f64 t7=false t8=\"binary_val_2\" t9=L\"标签值2\"" ] code = self._conn.schemaless_insert(lines3_0, TDSmlProtocolType.TELNET.value, TDSmlTimestampType.NOT_CONFIGURED.value) @@ -292,9 +288,9 @@ class TDTestCase: #tag ID as child table name lines3_1 = [ - "stb3_1 1626006833610ms 1 id=child_table1 host=host1", - "stb3_1 1626006833610ms 2 host=host2 iD=child_table2", - "stb3_1 1626006833610ms 3 ID=child_table3 host=host3" + "stb3_1 1626006833610 1 id=child_table1 host=host1", + "stb3_1 1626006833610 2 host=host2 iD=child_table2", + "stb3_1 1626006833610 3 ID=child_table3 host=host3" ] code = self._conn.schemaless_insert(lines3_1, TDSmlProtocolType.TELNET.value, TDSmlTimestampType.NOT_CONFIGURED.value) @@ -308,6 +304,56 @@ class TDTestCase: tdSql.checkData(0, 0, "child_table1") + ### special characters and keywords ### + print("============= step4 : test special characters and keywords ================") + lines4_1 = [ + "1234 1626006833610ms 1 id=123 456=true int=true double=false into=1 from=2 !@#$.%^&*()=false", + "int 1626006833610ms 2 id=and 456=true int=true double=false into=1 from=2 !@#$.%^&*()=false", + "double 1626006833610ms 2 id=for 456=true int=true double=false into=1 from=2 !@#$.%^&*()=false", + "from 1626006833610ms 2 id=!@#.^& 456=true int=true double=false into=1 from=2 !@#$.%^&*()=false", + "!@#$.%^&*() 1626006833610ms 2 id=none 456=true int=true double=false into=1 from=2 !@#$.%^&*()=false", + "STABLE 1626006833610ms 2 id=KEY 456=true int=true double=false TAG=1 FROM=2 COLUMN=false", + ] + + code = self._conn.schemaless_insert(lines4_1, TDSmlProtocolType.TELNET.value, TDSmlTimestampType.NOT_CONFIGURED.value) + print("schemaless_insert result {}".format(code)) + + tdSql.query('describe `1234`') + tdSql.checkRows(8) + + tdSql.query('describe `int`') + tdSql.checkRows(8) + + tdSql.query('describe `double`') + tdSql.checkRows(8) + + tdSql.query('describe `from`') + tdSql.checkRows(8) + + tdSql.query('describe `!@#$.%^&*()`') + tdSql.checkRows(8) + + tdSql.query('describe `stable`') + tdSql.checkRows(8) + + tdSql.query('select * from `123`') + tdSql.checkRows(1) + + tdSql.query('select * from `and`') + tdSql.checkRows(1) + + tdSql.query('select * from `for`') + tdSql.checkRows(1) + + tdSql.query('select * from `!@#.^&`') + tdSql.checkRows(1) + + tdSql.query('select * from `none`') + tdSql.checkRows(1) + + tdSql.query('select * from `key`') + tdSql.checkRows(1) + def stop(self): tdSql.close() tdLog.success("%s successfully executed" % __file__) diff --git a/tests/pytest/insert/line_insert.py b/tests/pytest/insert/line_insert.py index 334ccd4e6ec8c6058afe2f115fda61bda6428a14..ff26483aeb323ebd309ba7a41e91ac860af9d222 100644 --- a/tests/pytest/insert/line_insert.py +++ b/tests/pytest/insert/line_insert.py @@ -85,6 +85,53 @@ class TDTestCase: tdSql.query('select tbname, * from childtable') tdSql.checkRows(1) + + ###Special Character and keyss + self._conn.schemaless_insert([ + "1234,id=3456,abc=4i64,def=3i64 123=3i64,int=2i64,bool=false,into=5f64,column=7u64,!@#$.%^&*()=false 1626006933641", + "int,id=and,123=4i64,smallint=5f64,double=5f64,of=3i64,key=L\"passitagin_stf\",!@#$.%^&*()=false abc=false 1626006933654", + "double,id=for,123=4i64,smallint=5f64,double=5f64,of=3i64,key=L\"passitagin_stf\",!@#$.%^&*()=false abc=false 1626006933664", + "from,id=!@#$.%^,123=4i64,smallint=5f64,double=5f64,of=3i64,key=L\"passitagin_stf\",!@#$.%^&*()=false abc=false 1626006933674", + "!@#$.%^&*(),id=none,123=4i64,smallint=5f64,double=5f64,of=3i64,key=L\"passitagin_stf\",!@#$.%^&*()=false abc=false 1626006933684", + "STABLE,id=CREATE,123=4i64,smallint=5f64,DOUBLE=5f64,of=3i64,key=L\"passitagin_stf\",!@#$.%^&*()=false SELECT=false 1626006933684", + ], TDSmlProtocolType.LINE.value, TDSmlTimestampType.MILLI_SECOND.value) + tdSql.execute('reset query cache') + + tdSql.query('describe `1234`') + tdSql.checkRows(9) + + tdSql.query('describe `int`') + tdSql.checkRows(8) + + tdSql.query('describe `double`') + tdSql.checkRows(8) + + tdSql.query('describe `from`') + tdSql.checkRows(8) + + tdSql.query('describe `!@#$.%^&*()`') + tdSql.checkRows(8) + + tdSql.query('describe `stable`') + tdSql.checkRows(8) + + tdSql.query('select * from `3456`') + tdSql.checkRows(1) + + tdSql.query('select * from `and`') + tdSql.checkRows(1) + + tdSql.query('select * from `for`') + tdSql.checkRows(1) + + tdSql.query('select * from `!@#$.%^`') + tdSql.checkRows(1) + + tdSql.query('select * from `none`') + tdSql.checkRows(1) + + tdSql.query('select * from `create`') + tdSql.checkRows(1) def stop(self): tdSql.close() tdLog.success("%s successfully executed" % __file__) diff --git a/tests/pytest/tools/taosdemoAllTest/TD-3453/query-interrupt.json b/tests/pytest/tools/taosdemoAllTest/TD-3453/query-interrupt.json index 5e53bd7e7d10edea9bdbc56ef9ab737dbb34684e..c2e4920097cd1b3581c9893c9677c3cf1f14b7ed 100644 --- a/tests/pytest/tools/taosdemoAllTest/TD-3453/query-interrupt.json +++ b/tests/pytest/tools/taosdemoAllTest/TD-3453/query-interrupt.json @@ -22,7 +22,7 @@ "cache": 50, "blocks": 8, "precision": "ms", - "keep": 365, + "keep": 36500, "minRows": 100, "maxRows": 4096, "comp":2, @@ -36,7 +36,7 @@ "name": "stb0", "child_table_exists":"no", "childtable_count": 60, - "childtable_prefix": "stb00_", + "childtable_prefix": "stb00_", "auto_create_table": "no", "batch_create_tbl_num": 20, "data_source": "rand", diff --git a/tests/pytest/tools/taosdemoAllTest/taosdemoInsertMSDB.json b/tests/pytest/tools/taosdemoAllTest/taosdemoInsertMSDB.json index 49ab6f3a4367b4cebd840bb24b43a5d190c0d464..fd458a88d1a434c22958d5086949009cdd6080bf 100644 --- a/tests/pytest/tools/taosdemoAllTest/taosdemoInsertMSDB.json +++ b/tests/pytest/tools/taosdemoAllTest/taosdemoInsertMSDB.json @@ -22,7 +22,7 @@ "cache": 50, "blocks": 8, "precision": "ms", - "keep": 36, + "keep": 36500, "minRows": 100, "maxRows": 4096, "comp":2, diff --git a/tests/pytest/tools/taosdemoAllTest/taosdemoInsertNanoDB.json b/tests/pytest/tools/taosdemoAllTest/taosdemoInsertNanoDB.json index 9a35df917dcbb2600852e8172da0be3ffacb0d15..99233bdd738d068664241efda40d96c5a6fc7090 100644 --- a/tests/pytest/tools/taosdemoAllTest/taosdemoInsertNanoDB.json +++ b/tests/pytest/tools/taosdemoAllTest/taosdemoInsertNanoDB.json @@ -22,7 +22,7 @@ "cache": 50, "blocks": 8, "precision": "ns", - "keep": 36, + "keep": 36500, "minRows": 100, "maxRows": 4096, "comp":2, diff --git a/tests/pytest/tools/taosdemoAllTest/taosdemoInsertUSDB.json b/tests/pytest/tools/taosdemoAllTest/taosdemoInsertUSDB.json index 631179dbaebfff29de6b38831b78fede989369d4..14bb9e9be07d9bd61dc089af0bb34acd523155d9 100644 --- a/tests/pytest/tools/taosdemoAllTest/taosdemoInsertUSDB.json +++ b/tests/pytest/tools/taosdemoAllTest/taosdemoInsertUSDB.json @@ -22,7 +22,7 @@ "cache": 50, "blocks": 8, "precision": "us", - "keep": 36, + "keep": 36500, "minRows": 100, "maxRows": 4096, "comp":2, diff --git a/tests/pytest/tools/taosdemoAllTest/taosdemoTestNanoDatabase.json b/tests/pytest/tools/taosdemoAllTest/taosdemoTestNanoDatabase.json index 246f1c35f29973fc20602284b37ae68de23f70c1..e6c4b3205a77e20714067733bfa6f6c4053f087c 100644 --- a/tests/pytest/tools/taosdemoAllTest/taosdemoTestNanoDatabase.json +++ b/tests/pytest/tools/taosdemoAllTest/taosdemoTestNanoDatabase.json @@ -22,7 +22,7 @@ "cache": 50, "blocks": 8, "precision": "ns", - "keep": 36, + "keep": 36500, "minRows": 100, "maxRows": 4096, "comp":2, diff --git a/tests/pytest/tools/taosdemoAllTest/taosdemoTestNanoDatabaseInsertForSub.json b/tests/pytest/tools/taosdemoAllTest/taosdemoTestNanoDatabaseInsertForSub.json index 0726f3905de2b254b49be51a7973d34b5eb6757e..a19132b1da9c99b8fe3792a1c2d475fd4f18ef91 100644 --- a/tests/pytest/tools/taosdemoAllTest/taosdemoTestNanoDatabaseInsertForSub.json +++ b/tests/pytest/tools/taosdemoAllTest/taosdemoTestNanoDatabaseInsertForSub.json @@ -22,7 +22,7 @@ "cache": 50, "blocks": 8, "precision": "ns", - "keep": 36, + "keep": 36500, "minRows": 100, "maxRows": 4096, "comp":2, diff --git a/tests/pytest/tools/taosdemoAllTest/taosdemoTestNanoDatabaseNow.json b/tests/pytest/tools/taosdemoAllTest/taosdemoTestNanoDatabaseNow.json index f36b1f9b4c1b83707b9482428d4303a5418ad2c3..3b4c43d5d05ee1a1b26ee4016b1c38aade592b56 100644 --- a/tests/pytest/tools/taosdemoAllTest/taosdemoTestNanoDatabaseNow.json +++ b/tests/pytest/tools/taosdemoAllTest/taosdemoTestNanoDatabaseNow.json @@ -22,7 +22,7 @@ "cache": 50, "blocks": 8, "precision": "ns", - "keep": 36, + "keep": 36500, "minRows": 100, "maxRows": 4096, "comp":2, diff --git a/tests/pytest/tools/taosdemoAllTest/taosdemoTestNanoDatabasecsv.json b/tests/pytest/tools/taosdemoAllTest/taosdemoTestNanoDatabasecsv.json index 867619ed8c1497e76077f96d257dd09a489d9eb7..7fb90727ef6fa38da73639ebe11125924b9ed507 100644 --- a/tests/pytest/tools/taosdemoAllTest/taosdemoTestNanoDatabasecsv.json +++ b/tests/pytest/tools/taosdemoAllTest/taosdemoTestNanoDatabasecsv.json @@ -22,7 +22,7 @@ "cache": 50, "blocks": 8, "precision": "ns", - "keep": 36, + "keep": 36500, "minRows": 100, "maxRows": 4096, "comp":2, diff --git a/tests/pytest/tools/taosdemoAllTest/taosdemoTestQueryWithJson.py b/tests/pytest/tools/taosdemoAllTest/taosdemoTestQueryWithJson.py index 6021c9136ad235f3e9d07bb4f6654fdac54989e5..3a3152ecde3c4eca09d8b8583cf90bbfdc0cc31d 100644 --- a/tests/pytest/tools/taosdemoAllTest/taosdemoTestQueryWithJson.py +++ b/tests/pytest/tools/taosdemoAllTest/taosdemoTestQueryWithJson.py @@ -20,14 +20,16 @@ from util.dnodes import * import time from datetime import datetime import ast +import re # from assertpy import assert_that import subprocess + class TDTestCase: def init(self, conn, logSql): tdLog.debug("start to execute %s" % __file__) tdSql.init(conn.cursor(), logSql) - + def getBuildPath(self): selfPath = os.path.dirname(os.path.realpath(__file__)) @@ -40,52 +42,54 @@ class TDTestCase: if ("taosd" in files): rootRealPath = os.path.dirname(os.path.realpath(root)) if ("packaging" not in rootRealPath): - buildPath = root[:len(root)-len("/build/bin")] + buildPath = root[:len(root) - len("/build/bin")] break return buildPath # 获取taosc接口查询的结果文件中的内容,返回每行数据,并断言数据的第一列内容。 - def assertfileDataTaosc(self,filename,expectResult): + def assertfileDataTaosc(self, filename, expectResult): self.filename = filename self.expectResult = expectResult - with open("%s" % filename, 'r+') as f1: + with open("%s" % filename, 'r+') as f1: for line in f1.readlines(): queryResult = line.strip().split()[0] - self.assertCheck(filename,queryResult,expectResult) + self.assertCheck(filename, queryResult, expectResult) # 获取restful接口查询的结果文件中的关键内容,目前的关键内容找到第一个key就跳出循,所以就只有一个数据。后续再修改多个结果文件。 - def getfileDataRestful(self,filename): + def getfileDataRestful(self, filename): self.filename = filename - with open("%s" % filename, 'r+') as f1: + with open("%s" % filename, 'r+') as f1: for line in f1.readlines(): contents = line.strip() if contents.find("data") != -1: + pattern = re.compile("{.*}") + contents = pattern.search(contents).group() contentsDict = ast.literal_eval(contents) # 字符串转换为字典 queryResult = contentsDict['data'][0][0] break return queryResult # 获取taosc接口查询次数 - def queryTimesTaosc(self,filename): + def queryTimesTaosc(self, filename): self.filename = filename - command = 'cat %s |wc -l'% filename - times = int(subprocess.getstatusoutput(command)[1]) + command = 'cat %s |wc -l' % filename + times = int(subprocess.getstatusoutput(command)[1]) return times # 获取restful接口查询次数 - def queryTimesRestful(self,filename): + def queryTimesRestful(self, filename): self.filename = filename - command = 'cat %s |grep "200 OK" |wc -l'% filename - times = int(subprocess.getstatusoutput(command)[1]) + command = 'cat %s |grep "200 OK" |wc -l' % filename + times = int(subprocess.getstatusoutput(command)[1]) return times # 定义断言结果是否正确。不正确返回错误结果,正确即通过。 - def assertCheck(self,filename,queryResult,expectResult): + def assertCheck(self, filename, queryResult, expectResult): self.filename = filename self.queryResult = queryResult self.expectResult = expectResult args0 = (filename, queryResult, expectResult) - assert queryResult == expectResult , "Queryfile:%s ,result is %s != expect: %s" % args0 + assert queryResult == expectResult, "Queryfile:%s ,result is %s != expect: %s" % args0 def run(self): buildPath = self.getBuildPath() @@ -93,109 +97,144 @@ class TDTestCase: tdLog.exit("taosd not found!") else: tdLog.info("taosd found in %s" % buildPath) - binPath = buildPath+ "/build/bin/" - + binPath = buildPath + "/build/bin/" + # delete useless files - os.system("rm -rf ./query_res*") + os.system("rm -rf ./query_res*") os.system("rm -rf ./all_query*") - - # taosc query: query specified table and query super table - os.system("%staosdemo -f tools/taosdemoAllTest/queryInsertdata.json" % binPath) - os.system("%staosdemo -f tools/taosdemoAllTest/queryTaosc.json" % binPath) + + # taosc query: query specified table and query super table + os.system( + "%staosdemo -f tools/taosdemoAllTest/queryInsertdata.json" % + binPath) + os.system( + "%staosdemo -f tools/taosdemoAllTest/queryTaosc.json" % + binPath) os.system("cat query_res0.txt* > all_query_res0_taosc.txt") os.system("cat query_res1.txt* > all_query_res1_taosc.txt") os.system("cat query_res2.txt* > all_query_res2_taosc.txt") - - # correct Times testcases + + # correct Times testcases queryTimes0Taosc = self.queryTimesTaosc("all_query_res0_taosc.txt") - self.assertCheck("all_query_res0_taosc.txt",queryTimes0Taosc,6) + self.assertCheck("all_query_res0_taosc.txt", queryTimes0Taosc, 6) queryTimes1Taosc = self.queryTimesTaosc("all_query_res1_taosc.txt") - self.assertCheck("all_query_res1_taosc.txt",queryTimes1Taosc,6) + self.assertCheck("all_query_res1_taosc.txt", queryTimes1Taosc, 6) queryTimes2Taosc = self.queryTimesTaosc("all_query_res2_taosc.txt") - self.assertCheck("all_query_res2_taosc.txt",queryTimes2Taosc,20) - + self.assertCheck("all_query_res2_taosc.txt", queryTimes2Taosc, 20) + # correct data testcase - self.assertfileDataTaosc("all_query_res0_taosc.txt","1604160000099") - self.assertfileDataTaosc("all_query_res1_taosc.txt","100") - self.assertfileDataTaosc("all_query_res2_taosc.txt","1604160000199") - + self.assertfileDataTaosc("all_query_res0_taosc.txt", "1604160000099") + self.assertfileDataTaosc("all_query_res1_taosc.txt", "100") + self.assertfileDataTaosc("all_query_res2_taosc.txt", "1604160000199") + # delete useless files - os.system("rm -rf ./query_res*") + os.system("rm -rf ./query_res*") os.system("rm -rf ./all_query*") - # use restful api to query - os.system("%staosdemo -f tools/taosdemoAllTest/queryInsertrestdata.json" % binPath) - os.system("%staosdemo -f tools/taosdemoAllTest/queryRestful.json" % binPath) + os.system( + "%staosdemo -f tools/taosdemoAllTest/queryInsertrestdata.json" % + binPath) + os.system( + "%staosdemo -f tools/taosdemoAllTest/queryRestful.json" % + binPath) os.system("cat query_res0.txt* > all_query_res0_rest.txt") os.system("cat query_res1.txt* > all_query_res1_rest.txt") os.system("cat query_res2.txt* > all_query_res2_rest.txt") - - # correct Times testcases + + # correct Times testcases queryTimes0Restful = self.queryTimesRestful("all_query_res0_rest.txt") - self.assertCheck("all_query_res0_rest.txt",queryTimes0Restful,6) + self.assertCheck("all_query_res0_rest.txt", queryTimes0Restful, 6) queryTimes1Restful = self.queryTimesRestful("all_query_res1_rest.txt") - self.assertCheck("all_query_res1_rest.txt",queryTimes1Restful,6) - + self.assertCheck("all_query_res1_rest.txt", queryTimes1Restful, 6) + queryTimes2Restful = self.queryTimesRestful("all_query_res2_rest.txt") - self.assertCheck("all_query_res2_rest.txt",queryTimes2Restful,4) + self.assertCheck("all_query_res2_rest.txt", queryTimes2Restful, 4) # correct data testcase data0 = self.getfileDataRestful("all_query_res0_rest.txt") - self.assertCheck('all_query_res0_rest.txt',data0,"2020-11-01 00:00:00.009") + self.assertCheck( + 'all_query_res0_rest.txt', + data0, + "2020-11-01 00:00:00.009") data1 = self.getfileDataRestful("all_query_res1_rest.txt") - self.assertCheck('all_query_res1_rest.txt',data1,10) + self.assertCheck('all_query_res1_rest.txt', data1, 10) data2 = self.getfileDataRestful("all_query_res2_rest.txt") - self.assertCheck('all_query_res2_rest.txt',data2,"2020-11-01 00:00:00.004") - - + self.assertCheck( + 'all_query_res2_rest.txt', + data2, + "2020-11-01 00:00:00.004") + # query times less than or equal to 100 - os.system("%staosdemo -f tools/taosdemoAllTest/queryInsertdata.json" % binPath) - os.system("%staosdemo -f tools/taosdemoAllTest/querySpeciMutisql100.json" % binPath) - os.system("%staosdemo -f tools/taosdemoAllTest/querySuperMutisql100.json" % binPath) - - #query result print QPS - os.system("%staosdemo -f tools/taosdemoAllTest/queryInsertdata.json" % binPath) - os.system("%staosdemo -f tools/taosdemoAllTest/queryQps.json" % binPath) - + os.system( + "%staosdemo -f tools/taosdemoAllTest/queryInsertdata.json" % + binPath) + os.system( + "%staosdemo -f tools/taosdemoAllTest/querySpeciMutisql100.json" % + binPath) + os.system( + "%staosdemo -f tools/taosdemoAllTest/querySuperMutisql100.json" % + binPath) + + # query result print QPS + os.system( + "%staosdemo -f tools/taosdemoAllTest/queryInsertdata.json" % + binPath) + os.system( + "%staosdemo -f tools/taosdemoAllTest/queryQps.json" % + binPath) + # use illegal or out of range parameters query json file - os.system("%staosdemo -f tools/taosdemoAllTest/queryInsertdata.json" % binPath) - exceptcode = os.system("%staosdemo -f tools/taosdemoAllTest/queryTimes0.json" % binPath) + os.system( + "%staosdemo -f tools/taosdemoAllTest/queryInsertdata.json" % + binPath) + exceptcode = os.system( + "%staosdemo -f tools/taosdemoAllTest/queryTimes0.json" % + binPath) assert exceptcode != 0 - exceptcode0 = os.system("%staosdemo -f tools/taosdemoAllTest/queryTimesless0.json" % binPath) + exceptcode0 = os.system( + "%staosdemo -f tools/taosdemoAllTest/queryTimesless0.json" % + binPath) assert exceptcode0 != 0 - exceptcode1 = os.system("%staosdemo -f tools/taosdemoAllTest/queryConcurrentless0.json" % binPath) + exceptcode1 = os.system( + "%staosdemo -f tools/taosdemoAllTest/queryConcurrentless0.json" % + binPath) assert exceptcode1 != 0 - exceptcode2 = os.system("%staosdemo -f tools/taosdemoAllTest/queryConcurrent0.json" % binPath) + exceptcode2 = os.system( + "%staosdemo -f tools/taosdemoAllTest/queryConcurrent0.json" % + binPath) assert exceptcode2 != 0 - exceptcode3 = os.system("%staosdemo -f tools/taosdemoAllTest/querrThreadsless0.json" % binPath) + exceptcode3 = os.system( + "%staosdemo -f tools/taosdemoAllTest/querrThreadsless0.json" % + binPath) assert exceptcode3 != 0 - exceptcode4 = os.system("%staosdemo -f tools/taosdemoAllTest/querrThreads0.json" % binPath) + exceptcode4 = os.system( + "%staosdemo -f tools/taosdemoAllTest/querrThreads0.json" % + binPath) assert exceptcode4 != 0 # delete useless files os.system("rm -rf ./insert_res.txt") - os.system("rm -rf tools/taosdemoAllTest/*.py.sql") - os.system("rm -rf ./querySystemInfo*") - os.system("rm -rf ./query_res*") - os.system("rm -rf ./all_query*") + os.system("rm -rf tools/taosdemoAllTest/*.py.sql") + os.system("rm -rf ./querySystemInfo*") + os.system("rm -rf ./query_res*") +# os.system("rm -rf ./all_query*") os.system("rm -rf ./test_query_res0.txt") - - def stop(self): tdSql.close() tdLog.success("%s successfully executed" % __file__) + tdCases.addWindows(__file__, TDTestCase()) tdCases.addLinux(__file__, TDTestCase()) diff --git a/tests/pytest/tools/taosdemoAllTest/taosdemoTestSupportNanoInsert.py b/tests/pytest/tools/taosdemoAllTest/taosdemoTestSupportNanoInsert.py index c3fdff00ec15fc1ca0d55f86d430c5cbf86ad168..d8c68af0f9b43443744d7d799db6f5ee1e1dacaa 100644 --- a/tests/pytest/tools/taosdemoAllTest/taosdemoTestSupportNanoInsert.py +++ b/tests/pytest/tools/taosdemoAllTest/taosdemoTestSupportNanoInsert.py @@ -36,7 +36,7 @@ class TDTestCase: if ("taosd" in files): rootRealPath = os.path.dirname(os.path.realpath(root)) if ("packaging" not in rootRealPath): - buildPath = root[:len(root)-len("/build/bin")] + buildPath = root[:len(root) - len("/build/bin")] break return buildPath @@ -46,14 +46,15 @@ class TDTestCase: tdLog.exit("taosd not found!") else: tdLog.info("taosd found in %s" % buildPath) - binPath = buildPath+ "/build/bin/" + binPath = buildPath + "/build/bin/" - # insert: create one or mutiple tables per sql and insert multiple rows per sql # insert data from a special timestamp # check stable stb0 - os.system("%staosdemo -f tools/taosdemoAllTest/taosdemoTestNanoDatabase.json -y " % binPath) + os.system( + "%staosdemo -f tools/taosdemoAllTest/taosdemoTestNanoDatabase.json -y " % + binPath) tdSql.execute("use nsdb") tdSql.query("show stables") tdSql.checkData(0, 4, 100) @@ -64,9 +65,9 @@ class TDTestCase: tdSql.query("select count(*) from stb0") tdSql.checkData(0, 0, 10000) tdSql.query("describe stb0") - tdSql.checkDataType(9, 1,"TIMESTAMP") + tdSql.checkDataType(9, 1, "TIMESTAMP") tdSql.query("select last(ts) from stb0") - tdSql.checkData(0, 0,"2021-07-01 00:00:00.990000000") + tdSql.checkData(0, 0, "2021-07-01 00:00:00.990000000") # check stable stb1 which is insert with disord @@ -78,16 +79,18 @@ class TDTestCase: tdSql.checkData(0, 0, 10000) # check c8 is an nano timestamp tdSql.query("describe stb1") - tdSql.checkDataType(9, 1,"TIMESTAMP") + tdSql.checkDataType(9, 1, "TIMESTAMP") # check insert timestamp_step is nano_second tdSql.query("select last(ts) from stb1") - tdSql.checkData(0, 0,"2021-07-01 00:00:00.990000000") - + tdSql.checkData(0, 0, "2021-07-01 00:00:00.990000000") + # insert data from now time # check stable stb0 - os.system("%staosdemo -f tools/taosdemoAllTest/taosdemoTestNanoDatabaseNow.json -y " % binPath) - + os.system( + "%staosdemo -f tools/taosdemoAllTest/taosdemoTestNanoDatabaseNow.json -y " % + binPath) + tdSql.execute("use nsdb2") tdSql.query("show stables") tdSql.checkData(0, 4, 100) @@ -99,11 +102,14 @@ class TDTestCase: tdSql.checkData(0, 0, 10000) # check c8 is an nano timestamp tdSql.query("describe stb0") - tdSql.checkDataType(9,1,"TIMESTAMP") + tdSql.checkDataType(9, 1, "TIMESTAMP") + + # insert by csv files and timetamp is long int , strings in ts and + # cols - # insert by csv files and timetamp is long int , strings in ts and cols - - os.system("%staosdemo -f tools/taosdemoAllTest/taosdemoTestNanoDatabasecsv.json -y " % binPath) + os.system( + "%staosdemo -f tools/taosdemoAllTest/taosdemoTestNanoDatabasecsv.json -y " % + binPath) tdSql.execute("use nsdbcsv") tdSql.query("show stables") tdSql.checkData(0, 4, 100) @@ -111,29 +117,36 @@ class TDTestCase: tdSql.checkData(0, 0, 10000) tdSql.query("describe stb0") tdSql.checkDataType(3, 1, "TIMESTAMP") - tdSql.query("select count(*) from stb0 where ts > \"2021-07-01 00:00:00.490000000\"") + tdSql.query( + "select count(*) from stb0 where ts > \"2021-07-01 00:00:00.490000000\"") tdSql.checkData(0, 0, 5000) tdSql.query("select count(*) from stb0 where ts < 1626918583000000000") tdSql.checkData(0, 0, 10000) - + os.system("rm -rf ./insert_res.txt") os.system("rm -rf tools/taosdemoAllTest/taosdemoTestSupportNano*.py.sql") - # taosdemo test insert with command and parameter , detals show taosdemo --help - os.system("%staosdemo -u root -ptaosdata -P 6030 -a 1 -m pre -n 10 -T 20 -t 60 -o res.txt -y " % binPath) + # taosdemo test insert with command and parameter , detals show + # taosdemo --help + os.system( + "%staosdemo -u root -ptaosdata -P 6030 -a 1 -m pre -n 10 -T 20 -t 60 -o res.txt -y " % + binPath) tdSql.query("select count(*) from test.meters") tdSql.checkData(0, 0, 600) # check taosdemo -s - sqls_ls = ['drop database if exists nsdbsql;','create database nsdbsql precision "ns" keep 36 days 6 update 1;', - 'use nsdbsql;','CREATE STABLE meters (ts timestamp, current float, voltage int, phase float) TAGS (location binary(64), groupdId int);', - 'CREATE TABLE d1001 USING meters TAGS ("Beijing.Chaoyang", 2);', - 'INSERT INTO d1001 USING METERS TAGS ("Beijng.Chaoyang", 2) VALUES (now, 10.2, 219, 0.32);', - 'INSERT INTO d1001 USING METERS TAGS ("Beijng.Chaoyang", 2) VALUES (now, 85, 32, 0.76);'] + sqls_ls = [ + 'drop database if exists nsdbsql;', + 'create database nsdbsql precision "ns" keep 36500 days 6 update 1;', + 'use nsdbsql;', + 'CREATE STABLE meters (ts timestamp, current float, voltage int, phase float) TAGS (location binary(64), groupdId int);', + 'CREATE TABLE d1001 USING meters TAGS ("Beijing.Chaoyang", 2);', + 'INSERT INTO d1001 USING METERS TAGS ("Beijng.Chaoyang", 2) VALUES (now, 10.2, 219, 0.32);', + 'INSERT INTO d1001 USING METERS TAGS ("Beijng.Chaoyang", 2) VALUES (now, 85, 32, 0.76);'] - with open("./taosdemoTestNanoCreateDB.sql",mode ="a" ) as sql_files: + with open("./taosdemoTestNanoCreateDB.sql", mode="a") as sql_files: for sql in sqls_ls: - sql_files.write(sql+"\n") + sql_files.write(sql + "\n") sql_files.close() sleep(10) @@ -141,11 +154,10 @@ class TDTestCase: os.system("%staosdemo -s taosdemoTestNanoCreateDB.sql -y " % binPath) tdSql.query("select count(*) from nsdbsql.meters") tdSql.checkData(0, 0, 2) - + os.system("rm -rf ./res.txt") os.system("rm -rf ./*.py.sql") os.system("rm -rf ./taosdemoTestNanoCreateDB.sql") - def stop(self): tdSql.close() diff --git a/tests/script/api/openTSDBTest.c b/tests/script/api/openTSDBTest.c index 70048e17fcaf6d609274d561b8d206490c53dd96..8b70a324ea55c905c9a8bdaf67de9c258f9d57d7 100644 --- a/tests/script/api/openTSDBTest.c +++ b/tests/script/api/openTSDBTest.c @@ -22,9 +22,9 @@ void verify_telnet_insert(TAOS* taos) { /* metric */ char* lines0[] = { - "stb0_0 1626006833639000000ns 4i8 host=\"host0\" interface=\"eth0\"", - "stb0_1 1626006833639000000ns 4i8 host=\"host0\" interface=\"eth0\"", - "stb0_2 1626006833639000000ns 4i8 host=\"host0\" interface=\"eth0\"", + "stb0_0 1626006833639 4i8 host=\"host0\" interface=\"eth0\"", + "stb0_1 1626006833639 4i8 host=\"host0\" interface=\"eth0\"", + "stb0_2 1626006833639 4i8 host=\"host0\" interface=\"eth0\"", }; result = taos_schemaless_insert(taos, lines0, 3, TSDB_SML_TELNET_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); code = taos_errno(result); @@ -35,15 +35,11 @@ void verify_telnet_insert(TAOS* taos) { /* timestamp */ char* lines1[] = { - "stb1 1626006833s 1i8 host=\"host0\"", - "stb1 1626006833639000000ns 2i8 host=\"host0\"", - "stb1 1626006833640000us 3i8 host=\"host0\"", - "stb1 1626006833641 4i8 host=\"host0\"", - "stb1 1626006832 5i8 host=\"host0\"", - "stb1 1626006833651ms 6i8 host=\"host0\"", - "stb1 0 7i8 host=\"host0\"", + "stb1 1626006833641 1i8 host=\"host0\"", + "stb1 1626006832 2i8 host=\"host0\"", + "stb1 0 3i8 host=\"host0\"", }; - result = taos_schemaless_insert(taos, lines1, 7, TSDB_SML_TELNET_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); + result = taos_schemaless_insert(taos, lines1, 3, TSDB_SML_TELNET_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); code = taos_errno(result); if (code) { printf("lines1 code: %d, %s.\n", code, tstrerror(code)); @@ -53,8 +49,8 @@ void verify_telnet_insert(TAOS* taos) { /* metric value */ //tinyint char* lines2_0[] = { - "stb2_0 1626006833651ms -127i8 host=\"host0\"", - "stb2_0 1626006833652ms 127i8 host=\"host0\"" + "stb2_0 1626006833651 -127i8 host=\"host0\"", + "stb2_0 1626006833652 127i8 host=\"host0\"" }; result = taos_schemaless_insert(taos, lines2_0, 2, TSDB_SML_TELNET_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); code = taos_errno(result); @@ -65,8 +61,8 @@ void verify_telnet_insert(TAOS* taos) { //smallint char* lines2_1[] = { - "stb2_1 1626006833651ms -32767i16 host=\"host0\"", - "stb2_1 1626006833652ms 32767i16 host=\"host0\"" + "stb2_1 1626006833651 -32767i16 host=\"host0\"", + "stb2_1 1626006833652 32767i16 host=\"host0\"" }; result = taos_schemaless_insert(taos, lines2_1, 2, TSDB_SML_TELNET_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); code = taos_errno(result); @@ -77,8 +73,8 @@ void verify_telnet_insert(TAOS* taos) { //int char* lines2_2[] = { - "stb2_2 1626006833651ms -2147483647i32 host=\"host0\"", - "stb2_2 1626006833652ms 2147483647i32 host=\"host0\"" + "stb2_2 1626006833651 -2147483647i32 host=\"host0\"", + "stb2_2 1626006833652 2147483647i32 host=\"host0\"" }; result = taos_schemaless_insert(taos, lines2_2, 2, TSDB_SML_TELNET_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); code = taos_errno(result); @@ -89,8 +85,8 @@ void verify_telnet_insert(TAOS* taos) { //bigint char* lines2_3[] = { - "stb2_3 1626006833651ms -9223372036854775807i64 host=\"host0\"", - "stb2_3 1626006833652ms 9223372036854775807i64 host=\"host0\"" + "stb2_3 1626006833651 -9223372036854775807i64 host=\"host0\"", + "stb2_3 1626006833652 9223372036854775807i64 host=\"host0\"" }; result = taos_schemaless_insert(taos, lines2_3, 2, TSDB_SML_TELNET_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); code = taos_errno(result); @@ -101,16 +97,16 @@ void verify_telnet_insert(TAOS* taos) { //float char* lines2_4[] = { - "stb2_4 1626006833610ms 3f32 host=\"host0\"", - "stb2_4 1626006833620ms -3f32 host=\"host0\"", - "stb2_4 1626006833630ms 3.4f32 host=\"host0\"", - "stb2_4 1626006833640ms -3.4f32 host=\"host0\"", - "stb2_4 1626006833650ms 3.4E10f32 host=\"host0\"", - "stb2_4 1626006833660ms -3.4e10f32 host=\"host0\"", - "stb2_4 1626006833670ms 3.4E+2f32 host=\"host0\"", - "stb2_4 1626006833680ms -3.4e-2f32 host=\"host0\"", - "stb2_4 1626006833700ms 3.4E38f32 host=\"host0\"", - "stb2_4 1626006833710ms -3.4E38f32 host=\"host0\"" + "stb2_4 1626006833610 3f32 host=\"host0\"", + "stb2_4 1626006833620 -3f32 host=\"host0\"", + "stb2_4 1626006833630 3.4f32 host=\"host0\"", + "stb2_4 1626006833640 -3.4f32 host=\"host0\"", + "stb2_4 1626006833650 3.4E10f32 host=\"host0\"", + "stb2_4 1626006833660 -3.4e10f32 host=\"host0\"", + "stb2_4 1626006833670 3.4E+2f32 host=\"host0\"", + "stb2_4 1626006833680 -3.4e-2f32 host=\"host0\"", + "stb2_4 1626006833700 3.4E38f32 host=\"host0\"", + "stb2_4 1626006833710 -3.4E38f32 host=\"host0\"" }; result = taos_schemaless_insert(taos, lines2_4, 10, TSDB_SML_TELNET_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); code = taos_errno(result); @@ -121,17 +117,17 @@ void verify_telnet_insert(TAOS* taos) { //double char* lines2_5[] = { - "stb2_5 1626006833610ms 3f64 host=\"host0\"", - "stb2_5 1626006833620ms -3f64 host=\"host0\"", - "stb2_5 1626006833630ms 3.4f64 host=\"host0\"", - "stb2_5 1626006833640ms -3.4f64 host=\"host0\"", - "stb2_5 1626006833650ms 3.4E10f64 host=\"host0\"", - "stb2_5 1626006833660ms -3.4e10f64 host=\"host0\"", - "stb2_5 1626006833670ms 3.4E+2f64 host=\"host0\"", - "stb2_5 1626006833680ms -3.4e-2f64 host=\"host0\"", - "stb2_5 1626006833690ms 1.7E308f64 host=\"host0\"", - "stb2_5 1626006833700ms -1.7E308f64 host=\"host0\"", - "stb2_5 1626006833710ms 3.15 host=\"host0\"" + "stb2_5 1626006833610 3f64 host=\"host0\"", + "stb2_5 1626006833620 -3f64 host=\"host0\"", + "stb2_5 1626006833630 3.4f64 host=\"host0\"", + "stb2_5 1626006833640 -3.4f64 host=\"host0\"", + "stb2_5 1626006833650 3.4E10f64 host=\"host0\"", + "stb2_5 1626006833660 -3.4e10f64 host=\"host0\"", + "stb2_5 1626006833670 3.4E+2f64 host=\"host0\"", + "stb2_5 1626006833680 -3.4e-2f64 host=\"host0\"", + "stb2_5 1626006833690 1.7E308f64 host=\"host0\"", + "stb2_5 1626006833700 -1.7E308f64 host=\"host0\"", + "stb2_5 1626006833710 3.15 host=\"host0\"" }; result = taos_schemaless_insert(taos, lines2_5, 11, TSDB_SML_TELNET_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); code = taos_errno(result); @@ -142,16 +138,16 @@ void verify_telnet_insert(TAOS* taos) { //bool char* lines2_6[] = { - "stb2_6 1626006833610ms t host=\"host0\"", - "stb2_6 1626006833620ms T host=\"host0\"", - "stb2_6 1626006833630ms true host=\"host0\"", - "stb2_6 1626006833640ms True host=\"host0\"", - "stb2_6 1626006833650ms TRUE host=\"host0\"", - "stb2_6 1626006833660ms f host=\"host0\"", - "stb2_6 1626006833670ms F host=\"host0\"", - "stb2_6 1626006833680ms false host=\"host0\"", - "stb2_6 1626006833690ms False host=\"host0\"", - "stb2_6 1626006833700ms FALSE host=\"host0\"" + "stb2_6 1626006833610 t host=\"host0\"", + "stb2_6 1626006833620 T host=\"host0\"", + "stb2_6 1626006833630 true host=\"host0\"", + "stb2_6 1626006833640 True host=\"host0\"", + "stb2_6 1626006833650 TRUE host=\"host0\"", + "stb2_6 1626006833660 f host=\"host0\"", + "stb2_6 1626006833670 F host=\"host0\"", + "stb2_6 1626006833680 false host=\"host0\"", + "stb2_6 1626006833690 False host=\"host0\"", + "stb2_6 1626006833700 FALSE host=\"host0\"" }; result = taos_schemaless_insert(taos, lines2_6, 10, TSDB_SML_TELNET_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); code = taos_errno(result); @@ -162,9 +158,9 @@ void verify_telnet_insert(TAOS* taos) { //binary char* lines2_7[] = { - "stb2_7 1626006833610ms \"binary_val.!@#$%^&*\" host=\"host0\"", - "stb2_7 1626006833620ms \"binary_val.:;,./?|+-=\" host=\"host0\"", - "stb2_7 1626006833630ms \"binary_val.()[]{}<>\" host=\"host0\"" + "stb2_7 1626006833610 \"binary_val.!@#$%^&*\" host=\"host0\"", + "stb2_7 1626006833620 \"binary_val.:;,./?|+-=\" host=\"host0\"", + "stb2_7 1626006833630 \"binary_val.()[]{}<>\" host=\"host0\"" }; result = taos_schemaless_insert(taos, lines2_7, 3, TSDB_SML_TELNET_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); code = taos_errno(result); @@ -175,8 +171,8 @@ void verify_telnet_insert(TAOS* taos) { //nchar char* lines2_8[] = { - "stb2_8 1626006833610ms L\"nchar_val数值一\" host=\"host0\"", - "stb2_8 1626006833620ms L\"nchar_val数值二\" host=\"host0\"" + "stb2_8 1626006833610 L\"nchar_val数值一\" host=\"host0\"", + "stb2_8 1626006833620 L\"nchar_val数值二\" host=\"host0\"" }; result = taos_schemaless_insert(taos, lines2_8, 2, TSDB_SML_TELNET_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); code = taos_errno(result); @@ -188,8 +184,8 @@ void verify_telnet_insert(TAOS* taos) { /* tags */ //tag value types char* lines3_0[] = { - "stb3_0 1626006833610ms 1 t1=127i8 t2=32767i16 t3=2147483647i32 t4=9223372036854775807i64 t5=3.4E38f32 t6=1.7E308f64 t7=true t8=\"binary_val_1\" t9=L\"标签值1\"", - "stb3_0 1626006833610ms 2 t1=-127i8 t2=-32767i16 t3=-2147483647i32 t4=-9223372036854775807i64 t5=-3.4E38f32 t6=-1.7E308f64 t7=false t8=\"binary_val_2\" t9=L\"标签值2\"" + "stb3_0 1626006833610 1 t1=127i8 t2=32767i16 t3=2147483647i32 t4=9223372036854775807i64 t5=3.4E38f32 t6=1.7E308f64 t7=true t8=\"binary_val_1\" t9=L\"标签值1\"", + "stb3_0 1626006833610 2 t1=-127i8 t2=-32767i16 t3=-2147483647i32 t4=-9223372036854775807i64 t5=-3.4E38f32 t6=-1.7E308f64 t7=false t8=\"binary_val_2\" t9=L\"标签值2\"" }; result = taos_schemaless_insert(taos, lines3_0, 2, TSDB_SML_TELNET_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); code = taos_errno(result); @@ -200,9 +196,9 @@ void verify_telnet_insert(TAOS* taos) { //tag ID as child table name char* lines3_1[] = { - "stb3_1 1626006833610ms 1 id=child_table1 host=host1", - "stb3_1 1626006833610ms 2 host=host2 iD=child_table2", - "stb3_1 1626006833610ms 3 ID=child_table3 host=host3" + "stb3_1 1626006833610 1 id=child_table1 host=host1", + "stb3_1 1626006833610 2 host=host2 iD=child_table2", + "stb3_1 1626006833610 3 ID=child_table3 host=host3" }; result = taos_schemaless_insert(taos, lines3_1, 3, TSDB_SML_TELNET_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); code = taos_errno(result); diff --git a/tests/script/fullGeneralSuite.sim b/tests/script/fullGeneralSuite.sim index ec72827c9697cbb30a5845ff5f2a2f809ada4164..ebc054777940430e9cdb78b55b496dda873f2143 100644 --- a/tests/script/fullGeneralSuite.sim +++ b/tests/script/fullGeneralSuite.sim @@ -228,4 +228,6 @@ run general/db/show_create_table.sim run general/parser/like.sim run general/parser/regex.sim run general/parser/tbname_escape.sim +run general/parser/columnName_escape.sim +run general/parser/tagName_escape.sim run general/parser/interp_blocks.sim diff --git a/tests/script/general/parser/columnName_escape.sim b/tests/script/general/parser/columnName_escape.sim new file mode 100644 index 0000000000000000000000000000000000000000..dd3278d0dc98fa5378b7aed122dc39f6717372d5 --- /dev/null +++ b/tests/script/general/parser/columnName_escape.sim @@ -0,0 +1,426 @@ +system sh/stop_dnodes.sh + + +system sh/deploy.sh -n dnode1 -i 1 +system sh/cfg.sh -n dnode1 -c walLevel -v 1 +system sh/exec.sh -n dnode1 -s start + +sleep 100 +sql connect +print ======================== dnode1 start + +sql create database colesc; + +sql use colesc; + +print ======================= test create table/stable + + +sql create table tb0 (ts timestamp, `123` int, `123 456` int, `123.abc` int) +sql create table tb1 (ts timestamp, `!%^&*()` int) +sql create table tb2 (ts timestamp, `int` int, `bool` int, `double` int, `INTO` int, `COLUMN` int) + +sql create table stb0 (ts timestamp, `123` int, `123 456` int, `123.abc` int) tags (t1 int) +sql create table stb1 (ts timestamp, `!%^&*()` int) tags (t2 int) +sql create table stb2 (ts timestamp, `int` int, `bool` int, `double` int, `INTO` int, `COLUMN` int) tags (t3 int) + +sql create table ctb0 using stb0 tags (1) +sql create table ctb1 using stb1 tags (1) +sql create table ctb2 using stb2 tags (1) + +##check table +sql describe tb0; +if $rows != 4 then + return -1 +endi +if $data10 != @123@ then + return -1 +endi +if $data20 != @123 456@ then + return -1 +endi +if $data30 != @123.abc@ then + return -1 +endi + +sql describe tb1; +if $rows != 2 then + return -1 +endi +if $data10 != @!%^&*()@ then + return -1 +endi + +sql describe tb2; +if $rows != 6 then + return -1 +endi +if $data10 != @int@ then + return -1 +endi +if $data20 != @bool@ then + return -1 +endi +if $data30 != @double@ then + return -1 +endi +if $data40 != @INTO@ then + return -1 +endi +if $data50 != @COLUMN@ then + return -1 +endi +##check stable +sql describe stb0; +if $rows != 5 then + return -1 +endi +if $data10 != @123@ then + return -1 +endi +if $data20 != @123 456@ then + return -1 +endi +if $data30 != @123.abc@ then + return -1 +endi + +sql describe stb1; +if $rows != 3 then + return -1 +endi +if $data10 != @!%^&*()@ then + return -1 +endi + +sql describe stb2; +if $rows != 7 then + return -1 +endi +if $data10 != @int@ then + return -1 +endi +if $data20 != @bool@ then + return -1 +endi +if $data30 != @double@ then + return -1 +endi +if $data40 != @INTO@ then + return -1 +endi +if $data50 != @COLUMN@ then + return -1 +endi + + +print ======================= test Alter columns for table/stable + +##Add column +sql_error alter table tb0 add column `123` int +sql_error alter table tb0 add column `123 456` int +sql_error alter table tb0 add column `123.abc` int + +sql_error alter table ctb0 add column `1234` + +sql alter table tb0 add column `!%^&*()` int +sql alter table tb0 add column `int` int +sql alter table tb0 add column `bool` int +sql alter table tb0 add column `double` int +sql alter table tb0 add column `INTO` nchar(10) +sql alter table tb0 add column `COLUMN` binary(10) + +sql alter table stb0 add column `!%^&*()` int +sql alter table stb0 add column `int` int +sql alter table stb0 add column `bool` int +sql alter table stb0 add column `double` int +sql alter table stb0 add column `INTO` nchar(10) +sql alter table stb0 add column `COLUMN` binary(10) + + +##check table +sql describe tb0; +if $rows != 10 then + return -1 +endi +if $data40 != @!%^&*()@ then + return -1 +endi +if $data50 != @int@ then + return -1 +endi +if $data60 != @bool@ then + return -1 +endi +if $data70 != @double@ then + return -1 +endi +if $data80 != @INTO@ then + return -1 +endi +if $data90 != @COLUMN@ then + return -1 +endi + +#check stable +sql describe stb0; +if $rows != 11 then + return -1 +endi +if $data40 != @!%^&*()@ then + return -1 +endi +if $data50 != @int@ then + return -1 +endi +if $data60 != @bool@ then + return -1 +endi +if $data70 != @double@ then + return -1 +endi +if $data80 != @INTO@ then + return -1 +endi +if $data90 != @COLUMN@ then + return -1 +endi + +##Drop column + +sql_error alter table ctb0 drop column `123` +sql_error alter table ctb0 drop column `123 456` +sql_error alter table ctb0 drop column `123.abc` + +sql alter table tb0 drop column `!%^&*()` +sql alter table tb0 drop column `int` +sql alter table tb0 drop column `bool` +sql alter table tb0 drop column `double` +sql alter table tb0 drop column `INTO` +sql alter table tb0 drop column `COLUMN` + +sql alter table stb0 drop column `!%^&*()` +sql alter table stb0 drop column `int` +sql alter table stb0 drop column `bool` +sql alter table stb0 drop column `double` +sql alter table stb0 drop column `INTO` +sql alter table stb0 drop column `COLUMN` + +##check table +sql describe tb0; +if $rows != 4 then + return -1 +endi +if $data10 != @123@ then + return -1 +endi +if $data20 != @123 456@ then + return -1 +endi +if $data30 != @123.abc@ then + return -1 +endi + +##check stable +sql describe stb0; +if $rows != 5 then + return -1 +endi +if $data10 != @123@ then + return -1 +endi +if $data20 != @123 456@ then + return -1 +endi +if $data30 != @123.abc@ then + return -1 +endi + +##Modify column for binary/nchar length + +sql alter table tb0 add column `INTO` nchar(10) +sql alter table tb0 add column `COLUMN` binary(10) + +sql alter table stb0 add column `INTO` nchar(10) +sql alter table stb0 add column `COLUMN` binary(10) + +sql alter table tb0 modify column `INTO` nchar(15) +sql alter table tb0 modify column `COLUMN` binary(15) + +sql alter table stb0 modify column `INTO` nchar(15) +sql alter table stb0 modify column `COLUMN` binary(15) + +sql describe tb0; +if $rows != 6 then + return -1 +endi +if $data42 != @15@ then + return -1 +endi +if $data52 != @15@ then + return -1 +endi + +sql describe stb0; +if $rows != 7 then + return -1 +endi +if $data42 != @15@ then + return -1 +endi +if $data52 != @15@ then + return -1 +endi + +print ======================= test insert columns for table/stable + +sql insert into tb0 (ts, `123`, `123 456`, `123.abc`) values (now, 1, 1, 1) +sql insert into tb1 (ts, `!%^&*()`) values (now, 1) +sql insert into tb2 (ts, `int`, `bool`, `double`, `INTO`, `COLUMN`) values (now, 1, 1, 1, 1, 1) + +sql insert into ctb0 (ts, `123`, `123 456`, `123.abc`) values (now, 1, 1, 1) +sql insert into ctb1 (ts, `!%^&*()`) values (now, 1) +sql insert into ctb2 (ts, `int`, `bool`, `double`, `INTO`, `COLUMN`) values (now, 1, 1, 1, 1, 1) + +sql select * from tb0; +if $rows != 1 then + return -1 +endi + +sql select * from tb1; +if $rows != 1 then + return -1 +endi + +sql select * from tb2; +if $rows != 1 then + return -1 +endi + +sql select * from ctb0; +if $rows != 1 then + return -1 +endi + +sql select * from ctb1; +if $rows != 1 then + return -1 +endi + +sql select * from ctb2; +if $rows != 1 then + return -1 +endi + +print ======================= test select columns for table/stable + +sql select `123`,`123 456`,`123.abc` from tb0; + +if $rows != 1 then + return -1 +endi + +if $data00 != 1 then + return -1 +endi + +if $data01 != 1 then + return -1 +endi + +if $data02 != 1 then + return -1 +endi + +sql select `!%^&*()` from tb1; + +if $rows != 1 then + return -1 +endi + +if $data00 != 1 then + return -1 +endi + +sql select `int`,`bool`,`double`,`INTO`,`COLUMN` from tb2; + +if $rows != 1 then + return -1 +endi + +if $data00 != 1 then + return -1 +endi + +if $data01 != 1 then + return -1 +endi + +if $data02 != 1 then + return -1 +endi + +if $data03 != 1 then + return -1 +endi + +if $data04 != 1 then + return -1 +endi + + +sql select `123`,`123 456`,`123.abc` from stb0; + +if $rows != 1 then + return -1 +endi + +if $data00 != 1 then + return -1 +endi + +if $data01 != 1 then + return -1 +endi + +if $data02 != 1 then + return -1 +endi + +sql select `!%^&*()` from stb1; + +if $rows != 1 then + return -1 +endi + +if $data00 != 1 then + return -1 +endi + +sql select `int`,`bool`,`double`,`INTO`,`COLUMN` from stb2; + +if $rows != 1 then + return -1 +endi + +if $data00 != 1 then + return -1 +endi + +if $data01 != 1 then + return -1 +endi + +if $data02 != 1 then + return -1 +endi + +if $data03 != 1 then + return -1 +endi + +if $data04 != 1 then + return -1 +endi + +system sh/exec.sh -n dnode1 -s stop -x SIGINT diff --git a/tests/script/general/parser/tagName_escape.sim b/tests/script/general/parser/tagName_escape.sim new file mode 100644 index 0000000000000000000000000000000000000000..9b04dc2899af0dc4489f8f5621bbd2db3a79789b --- /dev/null +++ b/tests/script/general/parser/tagName_escape.sim @@ -0,0 +1,186 @@ +system sh/stop_dnodes.sh + + +system sh/deploy.sh -n dnode1 -i 1 +system sh/cfg.sh -n dnode1 -c walLevel -v 1 +system sh/exec.sh -n dnode1 -s start + +sleep 100 +sql connect +print ======================== dnode1 start + +sql create database tagesc; + +sql use tagesc; + +print ======================= test create table/stable + +sql create stable stb0 (ts timestamp, c0 int) tags (`123` int, `123 456` int, `123.abc` int) +sql create stable stb1 (ts timestamp, c1 int) tags (`!%^&*()` int) +sql create stable stb2 (ts timestamp, c2 int) tags (`int` int, `bool` int, `double` int, `INTO` int, `COLUMN` int) + +sql create table ctb0 using stb0 (`123`, `123 456`, `123.abc`) tags (1, 1, 1) +sql create table ctb1 using stb1 (`!%^&*()`) tags (1) +sql create table ctb2 using stb2 (`int`, `bool`, `double`, `INTO`, `COLUMN`) tags (1, 1, 1, 1, 1) + +##check table +sql describe ctb0; +if $rows != 5 then + return -1 +endi +if $data20 != @123@ then + return -1 +endi +if $data30 != @123 456@ then + return -1 +endi +if $data40 != @123.abc@ then + return -1 +endi + +sql describe ctb1; +if $rows != 3 then + return -1 +endi +if $data20 != @!%^&*()@ then + return -1 +endi + +sql describe ctb2; +if $rows != 7 then + return -1 +endi +if $data20 != @int@ then + return -1 +endi +if $data30 != @bool@ then + return -1 +endi +if $data40 != @double@ then + return -1 +endi +if $data50 != @INTO@ then + return -1 +endi +if $data60 != @COLUMN@ then + return -1 +endi + +print ======================= test Alter tags for stable + +##ADD TAG +sql_error alter stable stb0 add tag `123` int +sql_error alter stable stb0 add tag `123 456` int +sql_error alter stable stb0 add tag `123.abc` int + +sql alter stable stb0 add tag `!%^&*()` int +sql alter stable stb0 add tag `int` int +sql alter stable stb0 add tag `bool` int +sql alter stable stb0 add tag `double` int +sql alter stable stb0 add tag `INTO` int +sql alter stable stb0 add tag `COLUMN` int + + +sql describe stb0; +if $rows != 11 then + return -1 +endi +if $data50 != @!%^&*()@ then + return -1 +endi +if $data60 != @int@ then + return -1 +endi +if $data70 != @bool@ then + return -1 +endi +if $data80 != @double@ then + return -1 +endi +if $data90 != @INTO@ then + return -1 +endi + + +##DROP TAG +sql alter stable stb0 drop tag `!%^&*()` +sql alter stable stb0 drop tag `int` +sql alter stable stb0 drop tag `bool` +sql alter stable stb0 drop tag `double` +sql alter stable stb0 drop tag `INTO` +sql alter stable stb0 drop tag `COLUMN` + + +sql describe stb0; +if $rows != 5 then + return -1 +endi +if $data20 != @123@ then + return -1 +endi +if $data30 != @123 456@ then + return -1 +endi +if $data40 != @123.abc@ then + return -1 +endi + + +##CHANGE TAG + +sql alter stable stb0 change tag `123` `321` +sql alter stable stb0 change tag `123 456` `456 123` +#sql alter stable stb0 change tag `123.abc` `abc.123` +#change tag has bug when using dot in tagname + +sql describe stb0; +if $rows != 5 then + return -1 +endi +if $data20 != @321@ then + return -1 +endi +if $data30 != @456 123@ then + return -1 +endi + +##SET TAG + +sql insert into ctb0 values (now, 1) +sql insert into ctb1 values (now, 1) +sql insert into ctb2 values (now, 1) + +sql alter table ctb0 set tag `321`=2 +sql alter table ctb0 set tag `456 123`=2 +#sql alter table ctb0 set tag `abc.123`=2 +#change tag has bug when using dot in tagname + +print ======================= test insert specific tags automatically create table + +sql alter table ctb0 set tag `321`=2 +sql alter table ctb0 set tag `321`=2 +sql insert into ctb0_0 using stb0 (`321`, `456 123`, `123.abc`) tags (1, 1, 1) values (now + 10s, 5) +sql insert into ctb1_0 using stb1 (`!%^&*()`) tags (1) values (now + 10s, 5) +sql insert into ctb2_0 using stb2 (`int`, `bool`, `double`, `INTO`, `COLUMN`) tags (1, 1, 1, 1, 1) values (now + 10s, 5) +sql insert into ctb2_1 using stb2 (`int`, `bool`, `INTO`, `COLUMN`) tags (1, 1, 1, 1) values (now + 10s, 5) + +sql select * from stb0; +if $rows != 2 then + return -1 +endi + +sql select * from stb1; +if $rows != 2 then + return -1 +endi + +sql select * from stb2; +if $rows != 3 then + return -1 +endi + +if $data24 != NULL then + return -1 +endi + +system sh/exec.sh -n dnode1 -s stop -x SIGINT