From 6e985b443c69d8468e522fa5f2a1dd67253b7471 Mon Sep 17 00:00:00 2001 From: dapan1121 <89396746@qq.com> Date: Wed, 28 Apr 2021 10:53:10 +0800 Subject: [PATCH] fix bug --- src/client/inc/tscUtil.h | 3 ++- src/client/src/tscSQLParser.c | 12 +++++++++-- src/client/src/tscUtil.c | 31 +++++++++++++++++++++++++-- tests/script/general/parser/union.sim | 30 +++++++++++++++++++++++++- 4 files changed, 70 insertions(+), 6 deletions(-) diff --git a/src/client/inc/tscUtil.h b/src/client/inc/tscUtil.h index 0eda49b1f4..481a0a4d22 100644 --- a/src/client/inc/tscUtil.h +++ b/src/client/inc/tscUtil.h @@ -168,7 +168,8 @@ void tscFieldInfoClear(SFieldInfo* pFieldInfo); static FORCE_INLINE int32_t tscNumOfFields(SQueryInfo* pQueryInfo) { return pQueryInfo->fieldsInfo.numOfOutput; } -int32_t tscFieldInfoCompare(const SFieldInfo* pFieldInfo1, const SFieldInfo* pFieldInfo2); +int32_t tscFieldInfoCompare(const SFieldInfo* pFieldInfo1, const SFieldInfo* pFieldInfo2, int32_t *diffSize); +int32_t tscFieldInfoSetSize(const SFieldInfo* pFieldInfo1, const SFieldInfo* pFieldInfo2); void addExprParams(SSqlExpr* pExpr, char* argument, int32_t type, int32_t bytes); diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index 751c4bf39f..624a4996cd 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -642,17 +642,25 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) { // set the command/global limit parameters from the first subclause to the sqlcmd object SQueryInfo* pQueryInfo1 = tscGetQueryInfoDetail(pCmd, 0); pCmd->command = pQueryInfo1->command; - + int32_t diffSize = 0; + // if there is only one element, the limit of clause is the limit of global result. for (int32_t i = 1; i < pCmd->numOfClause; ++i) { SQueryInfo* pQueryInfo2 = tscGetQueryInfoDetail(pCmd, i); - int32_t ret = tscFieldInfoCompare(&pQueryInfo1->fieldsInfo, &pQueryInfo2->fieldsInfo); + int32_t ret = tscFieldInfoCompare(&pQueryInfo1->fieldsInfo, &pQueryInfo2->fieldsInfo, &diffSize); if (ret != 0) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); } } + if (diffSize) { + for (int32_t i = 1; i < pCmd->numOfClause; ++i) { + SQueryInfo* pQueryInfo2 = tscGetQueryInfoDetail(pCmd, i); + tscFieldInfoSetSize(&pQueryInfo1->fieldsInfo, &pQueryInfo2->fieldsInfo); + } + } + pCmd->parseFinished = 1; return TSDB_CODE_SUCCESS; // do not build query message here } diff --git a/src/client/src/tscUtil.c b/src/client/src/tscUtil.c index fa9e53b0a6..e8d7d5d03c 100644 --- a/src/client/src/tscUtil.c +++ b/src/client/src/tscUtil.c @@ -1098,7 +1098,7 @@ int16_t tscFieldInfoGetOffset(SQueryInfo* pQueryInfo, int32_t index) { return pInfo->pSqlExpr->offset; } -int32_t tscFieldInfoCompare(const SFieldInfo* pFieldInfo1, const SFieldInfo* pFieldInfo2) { +int32_t tscFieldInfoCompare(const SFieldInfo* pFieldInfo1, const SFieldInfo* pFieldInfo2, int32_t *diffSize) { assert(pFieldInfo1 != NULL && pFieldInfo2 != NULL); if (pFieldInfo1->numOfOutput != pFieldInfo2->numOfOutput) { @@ -1110,15 +1110,36 @@ int32_t tscFieldInfoCompare(const SFieldInfo* pFieldInfo1, const SFieldInfo* pFi TAOS_FIELD* pField2 = tscFieldInfoGetField((SFieldInfo*) pFieldInfo2, i); if (pField1->type != pField2->type || - pField1->bytes != pField2->bytes || strcasecmp(pField1->name, pField2->name) != 0) { return 1; } + + if (pField1->bytes != pField2->bytes) { + *diffSize = 1; + + if (pField2->bytes > pField1->bytes) { + pField1->bytes = pField2->bytes; + } + } + } + + return 0; +} + +int32_t tscFieldInfoSetSize(const SFieldInfo* pFieldInfo1, const SFieldInfo* pFieldInfo2) { + assert(pFieldInfo1 != NULL && pFieldInfo2 != NULL); + + for (int32_t i = 0; i < pFieldInfo1->numOfOutput; ++i) { + TAOS_FIELD* pField1 = tscFieldInfoGetField((SFieldInfo*) pFieldInfo1, i); + TAOS_FIELD* pField2 = tscFieldInfoGetField((SFieldInfo*) pFieldInfo2, i); + + pField2->bytes = pField1->bytes; } return 0; } + int32_t tscGetResRowLength(SArray* pExprList) { size_t num = taosArrayGetSize(pExprList); if (num == 0) { @@ -2682,7 +2703,13 @@ void tscTryQueryNextClause(SSqlObj* pSql, __async_cb_func_t fp) { //backup the total number of result first int64_t num = pRes->numOfTotal + pRes->numOfClauseTotal; + + + // DON't free final since it may be recoreded and used later in APP + TAOS_FIELD* finalBk = pRes->final; + pRes->final = NULL; tscFreeSqlResult(pSql); + pRes->final = finalBk; pRes->numOfTotal = num; diff --git a/tests/script/general/parser/union.sim b/tests/script/general/parser/union.sim index d50daea656..a02c626b7d 100644 --- a/tests/script/general/parser/union.sim +++ b/tests/script/general/parser/union.sim @@ -139,6 +139,34 @@ if $data10 != 1 then return -1 endi +sql select 'ab' as options from union_tb1 limit 1 union all select 'dd' as options from union_tb0 limit 1; +if $rows != 2 then + return -1 +endi + +if $data00 != @ab@ then + return -1 +endi + +if $data10 != @dd@ then + return -1 +endi + + +sql select 'ab' as options from union_tb1 limit 1 union all select '1234567' as options from union_tb0 limit 1; +if $rows != 2 then + return -1 +endi + +if $data00 != @ab@ then + return -1 +endi + +if $data10 != @1234567@ then + return -1 +endi + + # mixed order sql select ts, c1 from union_tb1 order by ts asc limit 10 union all select ts, c1 from union_tb0 order by ts desc limit 2 union all select ts, c1 from union_tb2 order by ts asc limit 10 if $rows != 22 then @@ -425,4 +453,4 @@ sql_error show tables union all show tables sql_error show stables union all show stables sql_error show databases union all show databases -system sh/exec.sh -n dnode1 -s stop -x SIGINT \ No newline at end of file +system sh/exec.sh -n dnode1 -s stop -x SIGINT -- GitLab