diff --git a/src/client/inc/tsclient.h b/src/client/inc/tsclient.h index 4ed7894931..4847a34dd1 100644 --- a/src/client/inc/tsclient.h +++ b/src/client/inc/tsclient.h @@ -486,6 +486,7 @@ bool tscHasReachLimitation(SQueryInfo *pQueryInfo, SSqlRes *pRes); void tscSetBoundColumnInfo(SParsedDataColInfo *pColInfo, SSchema *pSchema, int32_t numOfCols); char *tscGetErrorMsgPayload(SSqlCmd *pCmd); +int32_t tscErrorMsgWithCode(int32_t code, char* dstBuffer, const char* errMsg, const char* sql); int32_t tscInvalidOperationMsg(char *msg, const char *additionalInfo, const char *sql); int32_t tscSQLSyntaxErrMsg(char* msg, const char* additionalInfo, const char* sql); diff --git a/src/client/src/tscParseLineProtocol.c b/src/client/src/tscParseLineProtocol.c index 25438ef940..ee63290a3e 100644 --- a/src/client/src/tscParseLineProtocol.c +++ b/src/client/src/tscParseLineProtocol.c @@ -371,7 +371,10 @@ static int32_t applySchemaAction(TAOS* taos, SSchemaAction* action, SSmlLinesInf buildColumnDescription(action->alterSTable.field, result+n, capacity-n, &outBytes); TAOS_RES* res = taos_query(taos, result); //TODO async doAsyncQuery code = taos_errno(res); - if (code == TSDB_CODE_MND_FIELD_ALREAY_EXIST) { + if (code != TSDB_CODE_SUCCESS) { + tscError("SML:0x%"PRIx64" apply schema action. error : %s", info->id, taos_errstr(res)); + } + if (code == TSDB_CODE_MND_FIELD_ALREAY_EXIST || code == TSDB_CODE_TSC_DUP_COL_NAMES) { TAOS_RES* res2 = taos_query(taos, "RESET QUERY CACHE"); code = taos_errno(res2); taos_free_result(res2); @@ -385,7 +388,10 @@ static int32_t applySchemaAction(TAOS* taos, SSchemaAction* action, SSmlLinesInf result+n, capacity-n, &outBytes); TAOS_RES* res = taos_query(taos, result); //TODO async doAsyncQuery code = taos_errno(res); - if (code == TSDB_CODE_MND_TAG_ALREAY_EXIST) { + if (code != TSDB_CODE_SUCCESS) { + tscError("SML:0x%"PRIx64" apply schema action. error : %s", info->id, taos_errstr(res)); + } + if (code == TSDB_CODE_MND_TAG_ALREAY_EXIST || code == TSDB_CODE_TSC_DUP_COL_NAMES) { TAOS_RES* res2 = taos_query(taos, "RESET QUERY CACHE"); code = taos_errno(res2); taos_free_result(res2); @@ -399,6 +405,9 @@ static int32_t applySchemaAction(TAOS* taos, SSchemaAction* action, SSmlLinesInf capacity-n, &outBytes); TAOS_RES* res = taos_query(taos, result); //TODO async doAsyncQuery code = taos_errno(res); + if (code != TSDB_CODE_SUCCESS) { + tscError("SML:0x%"PRIx64" apply schema action. error : %s", info->id, taos_errstr(res)); + } if (code == TSDB_CODE_MND_INVALID_COLUMN_LENGTH) { TAOS_RES* res2 = taos_query(taos, "RESET QUERY CACHE"); code = taos_errno(res2); @@ -413,6 +422,9 @@ static int32_t applySchemaAction(TAOS* taos, SSchemaAction* action, SSmlLinesInf capacity-n, &outBytes); TAOS_RES* res = taos_query(taos, result); //TODO async doAsyncQuery code = taos_errno(res); + if (code != TSDB_CODE_SUCCESS) { + tscError("SML:0x%"PRIx64" apply schema action. error : %s", info->id, taos_errstr(res)); + } if (code == TSDB_CODE_MND_INVALID_TAG_LENGTH) { TAOS_RES* res2 = taos_query(taos, "RESET QUERY CACHE"); code = taos_errno(res2); @@ -447,6 +459,9 @@ static int32_t applySchemaAction(TAOS* taos, SSchemaAction* action, SSmlLinesInf outBytes = snprintf(pos, freeBytes, ")"); TAOS_RES* res = taos_query(taos, result); code = taos_errno(res); + if (code != TSDB_CODE_SUCCESS) { + tscError("SML:0x%"PRIx64" apply schema action. error : %s", info->id, taos_errstr(res)); + } if (code == TSDB_CODE_MND_TABLE_ALREADY_EXIST) { TAOS_RES* res2 = taos_query(taos, "RESET QUERY CACHE"); code = taos_errno(res2); @@ -462,7 +477,7 @@ static int32_t applySchemaAction(TAOS* taos, SSchemaAction* action, SSmlLinesInf free(result); if (code != 0) { - tscError("SML:0x%"PRIx64 "apply schema action failure. %s", info->id, tstrerror(code)); + tscError("SML:0x%"PRIx64 " apply schema action failure. %s", info->id, tstrerror(code)); } return code; } diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index 612a3d4798..2699ad2eb6 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -307,6 +307,31 @@ static int32_t invalidOperationMsg(char* dstBuffer, const char* errMsg) { return tscInvalidOperationMsg(dstBuffer, errMsg, NULL); } +int32_t tscErrorMsgWithCode(int32_t code, char* dstBuffer, const char* errMsg, const char* sql) { + const char* msgFormat1 = "%s:%s"; + const char* msgFormat2 = "%s:\'%s\' (%s)"; + const char* msgFormat3 = "%s:\'%s\'"; + + const int32_t BACKWARD_CHAR_STEP = 0; + + if (sql == NULL) { + assert(errMsg != NULL); + sprintf(dstBuffer, msgFormat1, tstrerror(code), errMsg); + return code; + } + + char buf[64] = {0}; // only extract part of sql string + strncpy(buf, (sql - BACKWARD_CHAR_STEP), tListLen(buf) - 1); + + if (errMsg != NULL) { + sprintf(dstBuffer, msgFormat2, tstrerror(code), buf, errMsg); + } else { + sprintf(dstBuffer, msgFormat3, tstrerror(code), buf); // no additional information for invalid sql error + } + + return code; +} + static int convertTimestampStrToInt64(tVariant *pVar, int32_t precision) { int64_t time = 0; strdequote(pVar->pz); @@ -1393,7 +1418,6 @@ static bool validateTableColumnInfo(SArray* pFieldList, SSqlCmd* pCmd) { const char* msg = "illegal number of columns"; const char* msg1 = "first column must be timestamp"; const char* msg2 = "row length exceeds max length"; - const char* msg3 = "duplicated column names"; const char* msg4 = "invalid data type"; const char* msg5 = "invalid binary/nchar column length"; const char* msg6 = "invalid column name"; @@ -1442,7 +1466,7 @@ static bool validateTableColumnInfo(SArray* pFieldList, SSqlCmd* pCmd) { // field name must be unique if (has(pFieldList, i + 1, pField->name) == true) { - invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); + tscErrorMsgWithCode(TSDB_CODE_TSC_DUP_COL_NAMES, tscGetErrorMsgPayload(pCmd), pField->name, NULL); return false; } @@ -1464,8 +1488,6 @@ static bool validateTagParams(SArray* pTagsList, SArray* pFieldList, SSqlCmd* pC const char* msg1 = "invalid number of tag columns"; const char* msg2 = "tag length too long"; - const char* msg3 = "duplicated column names"; - //const char* msg4 = "timestamp not allowed in tags"; const char* msg5 = "invalid data type in tags"; const char* msg6 = "invalid tag name"; const char* msg7 = "invalid binary/nchar tag length"; @@ -1496,7 +1518,7 @@ static bool validateTagParams(SArray* pTagsList, SArray* pFieldList, SSqlCmd* pC } if (has(pTagsList, i + 1, p->name) == true) { - invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); + tscErrorMsgWithCode(TSDB_CODE_TSC_DUP_COL_NAMES, tscGetErrorMsgPayload(pCmd), p->name, NULL); return false; } } @@ -1523,7 +1545,7 @@ static bool validateTagParams(SArray* pTagsList, SArray* pFieldList, SSqlCmd* pC TAOS_FIELD* p = taosArrayGet(pTagsList, i); if (has(pFieldList, 0, p->name) == true) { - invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); + tscErrorMsgWithCode(TSDB_CODE_TSC_DUP_COL_NAMES, tscGetErrorMsgPayload(pCmd), p->name, NULL); return false; } } @@ -1535,8 +1557,6 @@ static bool validateTagParams(SArray* pTagsList, SArray* pFieldList, SSqlCmd* pC * tags name /column name is truncated in sql.y */ bool validateOneTags(SSqlCmd* pCmd, TAOS_FIELD* pTagField) { - //const char* msg1 = "timestamp not allowed in tags"; - const char* msg2 = "duplicated column names"; const char* msg3 = "tag length too long"; const char* msg4 = "invalid tag name"; const char* msg5 = "invalid binary/nchar tag length"; @@ -1605,7 +1625,7 @@ bool validateOneTags(SSqlCmd* pCmd, TAOS_FIELD* pTagField) { for (int32_t i = 0; i < numOfTags + numOfCols; ++i) { if (strncasecmp(pTagField->name, pSchema[i].name, sizeof(pTagField->name) - 1) == 0) { - invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); + tscErrorMsgWithCode(TSDB_CODE_TSC_DUP_COL_NAMES, tscGetErrorMsgPayload(pCmd), pTagField->name, NULL); return false; } } @@ -1615,7 +1635,6 @@ bool validateOneTags(SSqlCmd* pCmd, TAOS_FIELD* pTagField) { bool validateOneColumn(SSqlCmd* pCmd, TAOS_FIELD* pColField) { const char* msg1 = "too many columns"; - const char* msg2 = "duplicated column names"; const char* msg3 = "column length too long"; const char* msg4 = "invalid data type"; const char* msg5 = "invalid column name"; @@ -1665,7 +1684,7 @@ bool validateOneColumn(SSqlCmd* pCmd, TAOS_FIELD* pColField) { // field name must be unique for (int32_t i = 0; i < numOfTags + numOfCols; ++i) { if (strncasecmp(pColField->name, pSchema[i].name, sizeof(pColField->name) - 1) == 0) { - invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); + tscErrorMsgWithCode(TSDB_CODE_TSC_DUP_COL_NAMES, tscGetErrorMsgPayload(pCmd), pColField->name, NULL); return false; } } diff --git a/src/inc/taoserror.h b/src/inc/taoserror.h index b8ccada105..f54150d76b 100644 --- a/src/inc/taoserror.h +++ b/src/inc/taoserror.h @@ -103,6 +103,7 @@ int32_t* taosGetErrno(); #define TSDB_CODE_TSC_FILE_EMPTY TAOS_DEF_ERROR_CODE(0, 0x021A) //"File is empty") #define TSDB_CODE_TSC_LINE_SYNTAX_ERROR TAOS_DEF_ERROR_CODE(0, 0x021B) //"Syntax error in Line") #define TSDB_CODE_TSC_NO_META_CACHED TAOS_DEF_ERROR_CODE(0, 0x021C) //"No table meta cached") +#define TSDB_CODE_TSC_DUP_COL_NAMES TAOS_DEF_ERROR_CODE(0, 0x021D) //"duplicated column names") // mnode #define TSDB_CODE_MND_MSG_NOT_PROCESSED TAOS_DEF_ERROR_CODE(0, 0x0300) //"Message not processed") diff --git a/tests/pytest/insert/schemalessInsert.py b/tests/pytest/insert/schemalessInsert.py index 49c3223588..00e805d791 100644 --- a/tests/pytest/insert/schemalessInsert.py +++ b/tests/pytest/insert/schemalessInsert.py @@ -1261,52 +1261,52 @@ class TDTestCase: # self._conn.insert_lines([input_sql4]) def runAll(self): - self.initCheckCase() - self.boolTypeCheckCase() - self.symbolsCheckCase() - self.tsCheckCase() - self.idSeqCheckCase() - self.idUpperCheckCase() - self.noIdCheckCase() - self.maxColTagCheckCase() - self.idIllegalNameCheckCase() - self.idStartWithNumCheckCase() - self.nowTsCheckCase() - self.dateFormatTsCheckCase() - self.illegalTsCheckCase() - self.tagValueLengthCheckCase() - self.colValueLengthCheckCase() - self.tagColIllegalValueCheckCase() - self.duplicateIdTagColInsertCheckCase() - self.noIdStbExistCheckCase() - self.duplicateInsertExistCheckCase() - self.tagColBinaryNcharLengthCheckCase() - self.tagColAddDupIDCheckCase() - self.tagColAddCheckCase() - self.tagMd5Check() - self.tagColBinaryMaxLengthCheckCase() - # self.tagColNcharMaxLengthCheckCase() - self.batchInsertCheckCase() - self.multiInsertCheckCase(1000) - self.batchErrorInsertCheckCase() - # MultiThreads - self.stbInsertMultiThreadCheckCase() - self.sStbStbDdataInsertMultiThreadCheckCase() - self.sStbStbDdataAtcInsertMultiThreadCheckCase() - self.sStbStbDdataMtcInsertMultiThreadCheckCase() - self.sStbDtbDdataInsertMultiThreadCheckCase() + # self.initCheckCase() + # self.boolTypeCheckCase() + # self.symbolsCheckCase() + # self.tsCheckCase() + # self.idSeqCheckCase() + # self.idUpperCheckCase() + # self.noIdCheckCase() + # self.maxColTagCheckCase() + # self.idIllegalNameCheckCase() + # self.idStartWithNumCheckCase() + # self.nowTsCheckCase() + # self.dateFormatTsCheckCase() + # self.illegalTsCheckCase() + # self.tagValueLengthCheckCase() + # self.colValueLengthCheckCase() + # self.tagColIllegalValueCheckCase() + # self.duplicateIdTagColInsertCheckCase() + # self.noIdStbExistCheckCase() + # self.duplicateInsertExistCheckCase() + # self.tagColBinaryNcharLengthCheckCase() + # self.tagColAddDupIDCheckCase() + # self.tagColAddCheckCase() + # self.tagMd5Check() + # self.tagColBinaryMaxLengthCheckCase() + # # self.tagColNcharMaxLengthCheckCase() + # self.batchInsertCheckCase() + # self.multiInsertCheckCase(1000) + # self.batchErrorInsertCheckCase() + # # MultiThreads + # self.stbInsertMultiThreadCheckCase() + # self.sStbStbDdataInsertMultiThreadCheckCase() + # self.sStbStbDdataAtcInsertMultiThreadCheckCase() + # self.sStbStbDdataMtcInsertMultiThreadCheckCase() + # self.sStbDtbDdataInsertMultiThreadCheckCase() # # ! concurrency conflict - # self.sStbDtbDdataAcMtInsertMultiThreadCheckCase() + self.sStbDtbDdataAcMtInsertMultiThreadCheckCase() # self.sStbDtbDdataAtMcInsertMultiThreadCheckCase() - self.sStbStbDdataDtsInsertMultiThreadCheckCase() + # self.sStbStbDdataDtsInsertMultiThreadCheckCase() # # ! concurrency conflict # self.sStbStbDdataDtsAcMtInsertMultiThreadCheckCase() # self.sStbStbDdataDtsAtMcInsertMultiThreadCheckCase() - self.sStbDtbDdataDtsInsertMultiThreadCheckCase() + # self.sStbDtbDdataDtsInsertMultiThreadCheckCase() # ! concurrency conflict # self.sStbDtbDdataDtsAcMtInsertMultiThreadCheckCase()