From 4e2ed952ec89c106d9b565bf8cc1eea3518da629 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Wed, 29 Jul 2020 18:51:27 +0800 Subject: [PATCH] [td-225] fix bugs in join query. --- src/client/inc/tsclient.h | 2 +- src/client/src/tscSubquery.c | 10 ++- src/client/src/tscUtil.c | 140 ++++++++++++++++++----------------- 3 files changed, 79 insertions(+), 73 deletions(-) diff --git a/src/client/inc/tsclient.h b/src/client/inc/tsclient.h index dbbb6be128..e3e1d44514 100644 --- a/src/client/inc/tsclient.h +++ b/src/client/inc/tsclient.h @@ -106,7 +106,7 @@ typedef struct SColumnIndex { typedef struct SFieldSupInfo { bool visible; SExprInfo *pArithExprInfo; - SSqlExpr * pSqlExpr; + SSqlExpr *pSqlExpr; } SFieldSupInfo; typedef struct SFieldInfo { diff --git a/src/client/src/tscSubquery.c b/src/client/src/tscSubquery.c index c396c81310..c7e7d1323b 100644 --- a/src/client/src/tscSubquery.c +++ b/src/client/src/tscSubquery.c @@ -1026,9 +1026,11 @@ void tscSetupOutputColumnIndex(SSqlObj* pSql) { } SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); - pRes->pColumnIndex = calloc(1, sizeof(SColumnIndex) * pQueryInfo->fieldsInfo.numOfOutput); - for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) { + int32_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); + pRes->pColumnIndex = calloc(1, sizeof(SColumnIndex) * numOfExprs); + + for (int32_t i = 0; i < numOfExprs; ++i) { SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); int32_t tableIndexOfSub = -1; @@ -1045,8 +1047,8 @@ void tscSetupOutputColumnIndex(SSqlObj* pSql) { SSqlCmd* pSubCmd = &pSql->pSubs[tableIndexOfSub]->cmd; SQueryInfo* pSubQueryInfo = tscGetQueryInfoDetail(pSubCmd, 0); - size_t numOfExprs = taosArrayGetSize(pSubQueryInfo->exprList); - for (int32_t k = 0; k < numOfExprs; ++k) { + size_t numOfSubExpr = taosArrayGetSize(pSubQueryInfo->exprList); + for (int32_t k = 0; k < numOfSubExpr; ++k) { SSqlExpr* pSubExpr = tscSqlExprGet(pSubQueryInfo, k); if (pExpr->functionId == pSubExpr->functionId && pExpr->colInfo.colId == pSubExpr->colInfo.colId) { pRes->pColumnIndex[i] = (SColumnIndex){.tableIndex = tableIndexOfSub, .columnIndex = k}; diff --git a/src/client/src/tscUtil.c b/src/client/src/tscUtil.c index bd1fd9905a..32a82a080f 100644 --- a/src/client/src/tscUtil.c +++ b/src/client/src/tscUtil.c @@ -1673,6 +1673,77 @@ SSqlObj* createSimpleSubObj(SSqlObj* pSql, void (*fp)(), void* param, int32_t cm return pNew; } +// current sql function is not direct output result, so create a dummy output field +static void doSetNewFieldInfo(SQueryInfo* pNewQueryInfo, SSqlExpr* pExpr) { + TAOS_FIELD f = {.type = pExpr->resType, .bytes = pExpr->resBytes}; + tstrncpy(f.name, pExpr->aliasName, sizeof(f.name)); + + SFieldSupInfo* pInfo1 = tscFieldInfoAppend(&pNewQueryInfo->fieldsInfo, &f); + + pInfo1->pSqlExpr = pExpr; + pInfo1->visible = false; +} + +static void doSetSqlExprAndResultFieldInfo(SQueryInfo* pQueryInfo, SQueryInfo* pNewQueryInfo, int64_t uid) { + int32_t numOfOutput = tscSqlExprNumOfExprs(pNewQueryInfo); + if (numOfOutput == 0) { + return; + } + + size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); + SFieldInfo* pFieldInfo = &pQueryInfo->fieldsInfo; + + // set the field info in pNewQueryInfo object + for (int32_t i = 0; i < numOfExprs; ++i) { + SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); + + if (pExpr->uid == uid) { + if (i < pFieldInfo->numOfOutput) { + SFieldSupInfo* pInfo = tscFieldInfoGetSupp(pFieldInfo, i); + + if (pInfo->pSqlExpr != NULL) { + TAOS_FIELD* p = tscFieldInfoGetField(pFieldInfo, i); + assert(strcmp(p->name, pExpr->aliasName) == 0); + + SFieldSupInfo* pInfo1 = tscFieldInfoAppend(&pNewQueryInfo->fieldsInfo, p); + *pInfo1 = *pInfo; + } else { + assert(pInfo->pArithExprInfo != NULL); + doSetNewFieldInfo(pNewQueryInfo, pExpr); + } + } else { // it is a arithmetic column, does not have actual field for sqlExpr, so build it + doSetNewFieldInfo(pNewQueryInfo, pExpr); + } + } + } + + // make sure the the sqlExpr for each fields is correct + numOfExprs = tscSqlExprNumOfExprs(pNewQueryInfo); + + // update the pSqlExpr pointer in SFieldSupInfo according the field name + // make sure the pSqlExpr point to the correct SqlExpr in pNewQueryInfo, not SqlExpr in pQueryInfo + for (int32_t f = 0; f < pNewQueryInfo->fieldsInfo.numOfOutput; ++f) { + TAOS_FIELD* field = tscFieldInfoGetField(&pNewQueryInfo->fieldsInfo, f); + + bool matched = false; + for (int32_t k1 = 0; k1 < numOfExprs; ++k1) { + SSqlExpr* pExpr1 = tscSqlExprGet(pNewQueryInfo, k1); + + if (strcmp(field->name, pExpr1->aliasName) == 0) { // establish link according to the result field name + SFieldSupInfo* pInfo = tscFieldInfoGetSupp(&pNewQueryInfo->fieldsInfo, f); + pInfo->pSqlExpr = pExpr1; + + matched = true; + break; + } + } + + assert(matched); + } + + tscFieldInfoUpdateOffset(pNewQueryInfo); +} + SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, void (*fp)(), void* param, int32_t cmd, SSqlObj* pPrevSql) { SSqlCmd* pCmd = &pSql->cmd; SSqlObj* pNew = (SSqlObj*)calloc(1, sizeof(SSqlObj)); @@ -1766,74 +1837,7 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, void (*fp)(), void uint64_t uid = pTableMetaInfo->pTableMeta->id.uid; tscSqlExprCopy(pNewQueryInfo->exprList, pQueryInfo->exprList, uid, true); - int32_t numOfOutput = tscSqlExprNumOfExprs(pNewQueryInfo); - - if (numOfOutput > 0) { // todo refactor to extract method - size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); - SFieldInfo* pFieldInfo = &pQueryInfo->fieldsInfo; - - for (int32_t i = 0; i < numOfExprs; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); - - if (pExpr->uid == uid) { - if (i < pFieldInfo->numOfOutput) { - SFieldSupInfo* pInfo = tscFieldInfoGetSupp(pFieldInfo, i); - if (pInfo->pSqlExpr != NULL) { - TAOS_FIELD* p = tscFieldInfoGetField(pFieldInfo, i); - assert(strcmp(p->name, pExpr->aliasName) == 0); - - SFieldSupInfo* pInfo1 = tscFieldInfoAppend(&pNewQueryInfo->fieldsInfo, p); - *pInfo1 = *pInfo; - } else { - // current sql function is not direct output result, so create a dummy output field - assert(pInfo->pArithExprInfo != NULL); - - TAOS_FIELD f = {.type = pExpr->resType, .bytes = pExpr->resBytes}; - tstrncpy(f.name, pExpr->aliasName, sizeof(f.name)); - - SFieldSupInfo* pInfo1 = tscFieldInfoAppend(&pNewQueryInfo->fieldsInfo, &f); - - pInfo1->pSqlExpr = pExpr; - pInfo1->visible = false; - } - } else { - // current sql function is not direct output result, so create a dummy output field - TAOS_FIELD f = {.type = pExpr->resType, .bytes = pExpr->resBytes}; - tstrncpy(f.name, pExpr->aliasName, sizeof(f.name)); - - SFieldSupInfo* pInfo1 = tscFieldInfoAppend(&pNewQueryInfo->fieldsInfo, &f); - - pInfo1->pSqlExpr = pExpr; - pInfo1->visible = false; - } - } - } - - // make sure the the sqlExpr for each fields is correct - // todo handle the agg arithmetic expression - numOfExprs = tscSqlExprNumOfExprs(pNewQueryInfo); - - for(int32_t f = 0; f < pNewQueryInfo->fieldsInfo.numOfOutput; ++f) { - TAOS_FIELD* field = tscFieldInfoGetField(&pNewQueryInfo->fieldsInfo, f); - bool matched = false; - - for(int32_t k1 = 0; k1 < numOfExprs; ++k1) { - SSqlExpr* pExpr1 = tscSqlExprGet(pNewQueryInfo, k1); - - if (strcmp(field->name, pExpr1->aliasName) == 0) { // establish link according to the result field name - SFieldSupInfo* pInfo = tscFieldInfoGetSupp(&pNewQueryInfo->fieldsInfo, f); - pInfo->pSqlExpr = pExpr1; - - matched = true; - break; - } - } - - assert(matched); - } - - tscFieldInfoUpdateOffset(pNewQueryInfo); - } + doSetSqlExprAndResultFieldInfo(pQueryInfo, pNewQueryInfo, uid); pNew->fp = fp; pNew->fetchFp = fp; -- GitLab