diff --git a/src/client/src/tscParseInsert.c b/src/client/src/tscParseInsert.c index 5401e500bdbb1773c4938041a54e548f942b8f61..65555dba136480f92f90fdef6ba1fc9f61af088c 100644 --- a/src/client/src/tscParseInsert.c +++ b/src/client/src/tscParseInsert.c @@ -305,10 +305,8 @@ int32_t tsParseOneColumnData(SSchema *pSchema, SSQLToken *pToken, char *payload, case TSDB_DATA_TYPE_BINARY: // binary data cannot be null-terminated char string, otherwise the last char of the string is lost if (pToken->type == TK_NULL) { - *(int16_t*) payload = sizeof(int8_t); - payload += VARSTR_HEADER_SIZE; - - *payload = TSDB_DATA_BINARY_NULL; + varDataSetLen(payload, sizeof(int8_t)); + *(uint8_t*) varDataVal(payload) = TSDB_DATA_BINARY_NULL; } else { // too long values will return invalid sql, not be truncated automatically if (pToken->n + VARSTR_HEADER_SIZE > pSchema->bytes) { //todo refactor return tscInvalidSQLErrMsg(msg, "string data overflow", pToken->z); @@ -321,22 +319,18 @@ int32_t tsParseOneColumnData(SSchema *pSchema, SSQLToken *pToken, char *payload, case TSDB_DATA_TYPE_NCHAR: if (pToken->type == TK_NULL) { - *(int16_t*) payload = sizeof(int32_t); - payload += VARSTR_HEADER_SIZE; - - *(uint32_t*) payload = TSDB_DATA_NCHAR_NULL; + varDataSetLen(payload, sizeof(int32_t)); + *(uint32_t*) varDataVal(payload) = TSDB_DATA_NCHAR_NULL; } else { // if the converted output len is over than pColumnModel->bytes, return error: 'Argument list too long' - size_t wcharLength = 0; - if (!taosMbsToUcs4(pToken->z, pToken->n, payload + VARSTR_HEADER_SIZE, pSchema->bytes - VARSTR_HEADER_SIZE, - &wcharLength)) { - + size_t output = 0; + if (!taosMbsToUcs4(pToken->z, pToken->n, varDataVal(payload), pSchema->bytes - VARSTR_HEADER_SIZE, &output)) { char buf[512] = {0}; snprintf(buf, tListLen(buf), "%s", strerror(errno)); return tscInvalidSQLErrMsg(msg, buf, pToken->z); } - *(uint16_t*) payload = (uint16_t) (wcharLength); + varDataSetLen(payload, output); } break; @@ -480,10 +474,19 @@ int tsParseOneRowData(char **str, STableDataBlocks *pDataBlocks, SSchema schema[ char *ptr = payload; for (int32_t i = 0; i < spd->numOfCols; ++i) { + if (!spd->hasVal[i]) { // current column do not have any value to insert, set it to null - setNull(ptr, schema[i].type, schema[i].bytes); + if (schema[i].type == TSDB_DATA_TYPE_BINARY) { + varDataSetLen(ptr, sizeof(int8_t)); + *(uint8_t*) varDataVal(ptr) = TSDB_DATA_BINARY_NULL; + } else if (schema[i].type == TSDB_DATA_TYPE_NCHAR) { + varDataSetLen(ptr, sizeof(int32_t)); + *(uint32_t*) varDataVal(ptr) = TSDB_DATA_NCHAR_NULL; + } else { + setNull(ptr, schema[i].type, schema[i].bytes); + } } - + ptr += schema[i].bytes; } @@ -1288,6 +1291,7 @@ int tsParseInsertSql(SSqlObj *pSql) { pCmd->count = 0; pCmd->command = TSDB_SQL_INSERT; + pSql->res.numOfRows = 0; SQueryInfo *pQueryInfo = NULL; tscGetQueryInfoDetailSafely(pCmd, pCmd->clauseIndex, &pQueryInfo); @@ -1300,7 +1304,6 @@ int tsParseInsertSql(SSqlObj *pSql) { return tscInvalidSQLErrMsg(pCmd->payload, "keyword INTO is expected", sToken.z); } - pSql->res.numOfRows = 0; return doParseInsertSql(pSql, pSql->sqlstr + index); } diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index f6e4c66a5a7b808f607cdd13137b316721e76d33..79916c499141e7a775739e983d3ad7f8ef40eebc 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -2419,7 +2419,7 @@ static int32_t getTableMetaFromMgmt(SSqlObj *pSql, STableMetaInfo *pTableMetaInf strncpy(pNewMeterMetaInfo->name, pTableMetaInfo->name, tListLen(pNewMeterMetaInfo->name)); memcpy(pNew->cmd.payload, pSql->cmd.payload, TSDB_DEFAULT_PAYLOAD_SIZE); // tag information if table does not exists. - tscTrace("%p new pSqlObj:%p to get tableMeta", pSql, pNew); + tscTrace("%p new pSqlObj:%p to get tableMeta, auto create:%d", pSql, pNew, pNew->cmd.autoCreated); pNew->fp = tscTableMetaCallBack; pNew->param = pSql; diff --git a/src/client/src/tscSubquery.c b/src/client/src/tscSubquery.c index 7682287f945d89513e57190401664c90b918ad46..be4d13bd9711abc3acc2320fa9549de76d8e5427 100644 --- a/src/client/src/tscSubquery.c +++ b/src/client/src/tscSubquery.c @@ -2024,7 +2024,6 @@ void **doSetResultRowData(SSqlObj *pSql, bool finalResult) { tExprTreeCalcTraverse(pRes->pArithSup->pArithExpr->pExpr, 1, pRes->buffer[i], pRes->pArithSup, TSDB_ORDER_ASC, getArithemicInputSrc); pRes->tsrow[i] = pRes->buffer[i]; -// free(sas); //todo optimization } } diff --git a/src/client/src/tscUtil.c b/src/client/src/tscUtil.c index 727c7741f3183382bdc6321171b9677495f58ecd..0b1130508245354523835acece4d77b9ea1f4243 100644 --- a/src/client/src/tscUtil.c +++ b/src/client/src/tscUtil.c @@ -357,6 +357,7 @@ void tscResetSqlCmdObj(SSqlCmd* pCmd) { pCmd->curSql = NULL; pCmd->msgType = 0; pCmd->parseFinished = 0; + pCmd->autoCreated = 0; taosHashCleanup(pCmd->pTableList); pCmd->pTableList = NULL; diff --git a/src/common/inc/tdataformat.h b/src/common/inc/tdataformat.h index 794d45da6fb587b073cbc50b729862eb4c48de7e..ec52bcd2ae34acf04806727fddf5a24dfcb260ef 100644 --- a/src/common/inc/tdataformat.h +++ b/src/common/inc/tdataformat.h @@ -28,16 +28,16 @@ extern "C" { #define STR_TO_VARSTR(x, str) do {VarDataLenT __len = strlen(str); \ *(VarDataLenT*)(x) = __len; \ - strncpy((char*)(x) + VARSTR_HEADER_SIZE, (str), __len);} while(0); + strncpy(varDataVal(x), (str), __len);} while(0); #define STR_WITH_MAXSIZE_TO_VARSTR(x, str, _maxs) do {\ - char* _e = stpncpy((char*)(x) + VARSTR_HEADER_SIZE, (str), (_maxs));\ - *(VarDataLenT*)(x) = (_e - (x) - VARSTR_HEADER_SIZE);\ + char* _e = stpncpy(varDataVal(x), (str), (_maxs));\ + varDataSetLen(x, (_e - (x) - VARSTR_HEADER_SIZE));\ } while(0) #define STR_WITH_SIZE_TO_VARSTR(x, str, _size) do {\ *(VarDataLenT*)(x) = (_size); \ - strncpy((char*)(x) + VARSTR_HEADER_SIZE, (str), (_size));\ + strncpy(varDataVal(x), (str), (_size));\ } while(0); // ----------------- TSDB COLUMN DEFINITION diff --git a/src/inc/taosdef.h b/src/inc/taosdef.h index 5523f2e0f964423949062e7015b9385c0e6decec..09136fa6ce37ac9df0a69757e1580703a9d4f889 100644 --- a/src/inc/taosdef.h +++ b/src/inc/taosdef.h @@ -40,9 +40,10 @@ typedef int16_t VarDataLenT; #define varDataLen(v) ((VarDataLenT *)(v))[0] #define varDataTLen(v) (sizeof(VarDataLenT) + varDataLen(v)) -#define varDataVal(v) ((void *)((char *)v + sizeof(VarDataLenT))) +#define varDataVal(v) ((void *)((char *)v + VARSTR_HEADER_SIZE)) #define varDataCopy(dst, v) memcpy((dst), (void*) (v), varDataTLen(v)) #define varDataLenByData(v) (*(VarDataLenT *)(((char*)(v)) - VARSTR_HEADER_SIZE)) +#define varDataSetLen(v, _len) (((VarDataLenT *)(v))[0] = (VarDataLenT) (_len)) // this data type is internally used only in 'in' query to hold the values #define TSDB_DATA_TYPE_ARRAY (TSDB_DATA_TYPE_NCHAR + 1) diff --git a/src/query/src/qtokenizer.c b/src/query/src/qtokenizer.c index 2b568cfd5afe535ca9a2fda2c4412f5448370c4d..22cffafdaa21bb100f87c041834a9a20a1253efd 100644 --- a/src/query/src/qtokenizer.c +++ b/src/query/src/qtokenizer.c @@ -268,11 +268,13 @@ int tSQLKeywordCode(const char* z, int n) { pthread_once(&keywordsHashTableInit, doInitKeywordsTable); char key[512] = {0}; - assert(tListLen(key) >= n); + if (n > tListLen(key)) { // too long token, can not be any other token type + return TK_ID; + } for (int32_t j = 0; j < n; ++j) { if (z[j] >= 'a' && z[j] <= 'z') { - key[j] = (char)(z[j] & 0xDF); // touppercase and set the null-terminated + key[j] = (char)(z[j] & 0xDF); // to uppercase and set the null-terminated } else { key[j] = z[j]; } diff --git a/tests/script/general/parser/create_mt.sim b/tests/script/general/parser/create_mt.sim index 275393f4ac95766f0512577a01a4011dae8805ad..f87033b71e835dd446259a17852113509577468c 100644 --- a/tests/script/general/parser/create_mt.sim +++ b/tests/script/general/parser/create_mt.sim @@ -172,8 +172,8 @@ sql create table $tb using $mt tags (-1) # -x ng_tag_v # return -1 #ng_tag_v: -sql describe $tb -if $data23 != -1 then +sql select tg from $tb +if $data00 != -1 then return -1 endi sql drop table $tb @@ -182,9 +182,9 @@ sql drop table $tb print create_mt.sim unmatched_tag_types sql reset query cache sql create table $tb using $mt tags ('123') -sql describe $tb -#print data23 = $data23 -if $data23 != 123 then +sql select tg from $tb +print data00 = $data00 +if $data00 != 123 then return -1 endi sql drop table $tb @@ -194,14 +194,14 @@ sql_error create table $tb using $mt tags ('abc') sql drop table if exists $tb sql reset query cache sql create table $tb using $mt tags (1e1) -sql describe $tb -if $data23 != 10 then +sql select tg from $tb +if $data00 != 10 then return -1 endi sql drop table $tb sql create table $tb using $mt tags ('1e1') -sql describe $tb -if $data23 != 10 then +sql select tg from $tb +if $data00 != 10 then return -1 endi sql_error create table $tb using $mt tags (2147483649) @@ -234,13 +234,13 @@ $mt2 = mt2 #if $data20 != $mt2 then # return -1 #endi -#sql describe $mt1 +#sql select tg from $mt1 ##print expected $CN_char ##print returned $data10 #if $data10 != $CN_char then # return -1 #endi -#sql describe $mt2 +#sql select tg from $mt2 ##print expected: $CN_char ##print returned: $data20 #if $data20 != $CN_char then diff --git a/tests/script/general/parser/create_tb.sim b/tests/script/general/parser/create_tb.sim index a3a18697a2a13b2cde3f63ad6916ab023d95e01e..c098da226d1254ff22caa1c2e753897076be3232 100644 --- a/tests/script/general/parser/create_tb.sim +++ b/tests/script/general/parser/create_tb.sim @@ -172,7 +172,7 @@ print ========== create_tb.sim case7: table_name_length_exceeds_limit $tbname32 = _32_aaaabbbbccccddddaaaabbbbcccc $tbname64 = _64_aaaabbbbccccddddaaaabbbbccccddddaaaabbbbccccddddaaaabbbbcccc $tbname63 = _63_aaaabbbbccccddddaaaabbbbccccddddaaaabbbbccccddddaaaabbbbccc -$tbname65 = _65_aaaabbbbccccddddaaaabbbbccccddddaaaabbbbccccddddaaaabbbbcccca +$tbname65 = _65_aaaabbbbccccddddaaaabbbbccccddddaaaabbbbccccddddaaaabbbbcccca1111111111111111111111111111111111aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa sql create table $tbname32 (ts timestamp, col int) sql insert into $tbname32 values (now, 1) sql create table $tbname64 (ts timestamp, col int)