diff --git a/src/client/inc/tsclient.h b/src/client/inc/tsclient.h index 1740266518dd2c736feb47a5e9baa98cb66cbd94..2d7c3947019f9c2eb9540ebeec6ce7712f9d5541 100644 --- a/src/client/inc/tsclient.h +++ b/src/client/inc/tsclient.h @@ -367,7 +367,7 @@ typedef struct SSqlObj { int64_t svgroupRid; int64_t squeryLock; - + int32_t retryReason; // previous error code struct SSqlObj *prev, *next; int64_t self; } SSqlObj; diff --git a/src/client/src/tscAsync.c b/src/client/src/tscAsync.c index 87f6058cecefbfc1bb45fd4ccff584d8d0c10aba..432f4d94fddb50382f127041aa9eb729c7ab54f6 100644 --- a/src/client/src/tscAsync.c +++ b/src/client/src/tscAsync.c @@ -310,9 +310,50 @@ void tscAsyncResultOnError(SSqlObj* pSql) { taosScheduleTask(tscQhandle, &schedMsg); } +int tscSendMsgToServer(SSqlObj *pSql); +static int32_t updateMetaBeforeRetryQuery(SSqlObj* pSql, STableMetaInfo* pTableMetaInfo, SQueryInfo* pQueryInfo) { + // handle the invalid table error code for super table. + // update the pExpr info, colList info, number of table columns + // TODO Re-parse this sql and issue the corresponding subquery as an alternative for this case. + if (pSql->retryReason == TSDB_CODE_TDB_INVALID_TABLE_ID) { + int32_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); + int32_t numOfCols = tscGetNumOfColumns(pTableMetaInfo->pTableMeta); + int32_t numOfTags = tscGetNumOfTags(pTableMetaInfo->pTableMeta); + + SSchema *pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta); + for (int32_t i = 0; i < numOfExprs; ++i) { + SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, i); + pExpr->uid = pTableMetaInfo->pTableMeta->id.uid; + + if (pExpr->colInfo.colIndex >= 0) { + int32_t index = pExpr->colInfo.colIndex; + + if ((TSDB_COL_IS_NORMAL_COL(pExpr->colInfo.flag) && index >= numOfCols) || + (TSDB_COL_IS_TAG(pExpr->colInfo.flag) && (index < numOfCols || index >= (numOfCols + numOfTags)))) { + return pSql->retryReason; + } -int tscSendMsgToServer(SSqlObj *pSql); + if ((pSchema[pExpr->colInfo.colIndex].colId != pExpr->colInfo.colId) && + strcasecmp(pExpr->colInfo.name, pSchema[pExpr->colInfo.colIndex].name) != 0) { + return pSql->retryReason; + } + } + } + + // validate the table columns information + for (int32_t i = 0; i < taosArrayGetSize(pQueryInfo->colList); ++i) { + SColumn *pCol = taosArrayGetP(pQueryInfo->colList, i); + if (pCol->colIndex.columnIndex >= numOfCols) { + return pSql->retryReason; + } + } + } else { + // do nothing + } + + return TSDB_CODE_SUCCESS; +} void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) { SSqlObj* pSql = (SSqlObj*)taosAcquireRef(tscObjRef, (int64_t)param); @@ -339,7 +380,8 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) { if (TSDB_QUERY_HAS_TYPE(pQueryInfo->type, (TSDB_QUERY_TYPE_STABLE_SUBQUERY|TSDB_QUERY_TYPE_SUBQUERY|TSDB_QUERY_TYPE_TAG_FILTER_QUERY))) { tscDebug("%p update local table meta, continue to process sql and send the corresponding query", pSql); - STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); + STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); + code = tscGetTableMeta(pSql, pTableMetaInfo); assert(code == TSDB_CODE_TSC_ACTION_IN_PROGRESS || code == TSDB_CODE_SUCCESS); @@ -349,6 +391,10 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) { } assert((tscGetNumOfTags(pTableMetaInfo->pTableMeta) != 0)); + code = updateMetaBeforeRetryQuery(pSql, pTableMetaInfo, pQueryInfo); + if (code != TSDB_CODE_SUCCESS) { + goto _error; + } // tscProcessSql can add error into async res tscProcessSql(pSql); diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index 45ca470ce69bda06484feea2af2a9dec004e815f..31655a4b70f93d8322aee73537b3c74f1f171286 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -350,8 +350,8 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) { taosMsleep(duration); } + pSql->retryReason = rpcMsg->code; rpcMsg->code = tscRenewTableMeta(pSql, 0); - // if there is an error occurring, proceed to the following error handling procedure. if (rpcMsg->code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) { taosReleaseRef(tscObjRef, handle);