diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index ae279a8b8b84d54bd1084f668f5594addfbdf11c..f7746debef80db87290550e5865528937b1201a1 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -358,19 +358,28 @@ static int32_t handlePassword(SSqlCmd* pCmd, SStrToken* pPwd) { // validate the out put field type for "UNION ALL" subclause static int32_t normalizeVarDataTypeLength(SSqlCmd* pCmd) { const char* msg1 = "columns in select clause not identical"; + const char* msg2 = "too many select clause siblings, at most 100 allowed"; + int32_t siblings = 0; int32_t diffSize = 0; // if there is only one element, the limit of clause is the limit of global result. SQueryInfo* pQueryInfo1 = pCmd->pQueryInfo; SQueryInfo* pSibling = pQueryInfo1->sibling; + // pQueryInfo1 itself + ++siblings; + while(pSibling != NULL) { int32_t ret = tscFieldInfoCompare(&pQueryInfo1->fieldsInfo, &pSibling->fieldsInfo, &diffSize); if (ret != 0) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } + if (++siblings > 100) { + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); + } + pSibling = pSibling->sibling; } diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index 5fbe756b3bd63b0b22bda703ff5b02d4daf82052..dd0975de78dfdc231908130c6a2193d0cbc9f2bf 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -980,7 +980,11 @@ static int32_t serializeSqlExpr(SSqlExpr* pExpr, STableMetaInfo* pTableMetaInfo, return TSDB_CODE_TSC_INVALID_OPERATION; } - assert(pExpr->resColId < 0); + if (pExpr->resColId >= 0) { + tscError("result column id underflowed: %d", pExpr->resColId); + return TSDB_CODE_TSC_RES_TOO_MANY; + } + SSqlExpr* pSqlExpr = (SSqlExpr *)(*pMsg); SColIndex* pIndex = &pSqlExpr->colInfo; diff --git a/src/inc/taoserror.h b/src/inc/taoserror.h index 0f31b99ac070da2e3c1de0ec8638a7b398bc63a0..43ed20fe14af7c5f60c580dc08ff8456e7903e65 100644 --- a/src/inc/taoserror.h +++ b/src/inc/taoserror.h @@ -107,6 +107,7 @@ int32_t* taosGetErrno(); #define TSDB_CODE_TSC_DUP_COL_NAMES TAOS_DEF_ERROR_CODE(0, 0x021D) //"duplicated column names") #define TSDB_CODE_TSC_INVALID_TAG_LENGTH TAOS_DEF_ERROR_CODE(0, 0x021E) //"Invalid tag length") #define TSDB_CODE_TSC_INVALID_COLUMN_LENGTH TAOS_DEF_ERROR_CODE(0, 0x021F) //"Invalid column length") +#define TSDB_CODE_TSC_RES_TOO_MANY TAOS_DEF_ERROR_CODE(0, 0x0227) //"Result set too large to be output") // mnode #define TSDB_CODE_MND_MSG_NOT_PROCESSED TAOS_DEF_ERROR_CODE(0, 0x0300) //"Message not processed") diff --git a/src/util/src/terror.c b/src/util/src/terror.c index 0b9a76004b3e445abe1bbffe593d8061803d1b1b..d1ecc2188bec5c4a5b1af36a67cf177dd6d935ec 100644 --- a/src/util/src/terror.c +++ b/src/util/src/terror.c @@ -112,9 +112,10 @@ TAOS_DEFINE_ERROR(TSDB_CODE_TSC_EXCEED_SQL_LIMIT, "SQL statement too lon TAOS_DEFINE_ERROR(TSDB_CODE_TSC_FILE_EMPTY, "File is empty") TAOS_DEFINE_ERROR(TSDB_CODE_TSC_LINE_SYNTAX_ERROR, "Syntax error in Line") TAOS_DEFINE_ERROR(TSDB_CODE_TSC_NO_META_CACHED, "No table meta cached") -TAOS_DEFINE_ERROR(TSDB_CODE_TSC_DUP_COL_NAMES, "duplicated column names") -TAOS_DEFINE_ERROR(TSDB_CODE_TSC_INVALID_TAG_LENGTH, "Invalid tag length") -TAOS_DEFINE_ERROR(TSDB_CODE_TSC_INVALID_COLUMN_LENGTH, "Invalid column length") +TAOS_DEFINE_ERROR(TSDB_CODE_TSC_DUP_COL_NAMES, "duplicated column names") +TAOS_DEFINE_ERROR(TSDB_CODE_TSC_INVALID_TAG_LENGTH, "Invalid tag length") +TAOS_DEFINE_ERROR(TSDB_CODE_TSC_INVALID_COLUMN_LENGTH, "Invalid column length") +TAOS_DEFINE_ERROR(TSDB_CODE_TSC_RES_TOO_MANY, "Result set too large to be output") // mnode TAOS_DEFINE_ERROR(TSDB_CODE_MND_MSG_NOT_PROCESSED, "Message not processed") diff --git a/tests/pytest/query/unionAllTest.py b/tests/pytest/query/unionAllTest.py index d1e1bf4d3e11191be2875c464150793936acd065..9a7aedc763db05ebb11da33dc65fa74b2ba8daa3 100644 --- a/tests/pytest/query/unionAllTest.py +++ b/tests/pytest/query/unionAllTest.py @@ -103,10 +103,27 @@ class TDTestCase: select count(*) as count, loc from st where ts between 1600000000000 and 1600000000010 group by loc''') tdSql.checkRows(6) + # https://jira.taosdata.com:18080/browse/TS-715 + tdLog.info("test case for TS-715") + sql = "" + + tdSql.execute("create table st2(ts timestamp, c1 int, c2 int, c3 int) tags(loc nchar(20))") + + for i in range(101): + if i == 0: + sql = "select last(*) from sub0 " + else: + sql += f"union all select last(*) from sub{i} " + + tdSql.execute("create table sub%d using st2 tags('nchar%d')" % (i, i)) + tdSql.execute("insert into sub%d values(%d, %d, %d, %d)" % (i, self.ts + i, i, i, i)) + + tdSql.error(sql) + def stop(self): tdSql.close() tdLog.success("%s successfully executed" % __file__) tdCases.addWindows(__file__, TDTestCase()) -tdCases.addLinux(__file__, TDTestCase()) \ No newline at end of file +tdCases.addLinux(__file__, TDTestCase())