diff --git a/include/util/taoserror.h b/include/util/taoserror.h index 1c48a466144cc282d6883f1f92d44d704ccb3a36..28c1174dfd0897b9a00a98d6cf77d06038c42630 100644 --- a/include/util/taoserror.h +++ b/include/util/taoserror.h @@ -557,6 +557,7 @@ int32_t* taosGetErrno(); #define TSDB_CODE_PAR_INVALID_SMA_INDEX TAOS_DEF_ERROR_CODE(0, 0x2660) #define TSDB_CODE_PAR_INVALID_SELECTED_EXPR TAOS_DEF_ERROR_CODE(0, 0x2661) #define TSDB_CODE_PAR_GET_META_ERROR TAOS_DEF_ERROR_CODE(0, 0x2662) +#define TSDB_CODE_PAR_NOT_UNIQUE_TABLE_ALIAS TAOS_DEF_ERROR_CODE(0, 0x2663) #define TSDB_CODE_PAR_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x26FF) //planner diff --git a/source/libs/executor/src/joinoperator.c b/source/libs/executor/src/joinoperator.c index 17b81cdb827fe11b5de3e27233fd0add211aa32d..4134ce5dbfdd8a661082b2887fdbef5972e86341 100644 --- a/source/libs/executor/src/joinoperator.c +++ b/source/libs/executor/src/joinoperator.c @@ -323,8 +323,6 @@ static void doMergeJoinImpl(struct SOperatorInfo* pOperator, SSDataBlock* pRes) } if (leftTs == rightTs) { - mergeJoinJoinLeftRight(pOperator, pRes, nrows, pJoinInfo->pLeft, pJoinInfo->leftPos, pJoinInfo->pRight, - pJoinInfo->rightPos); mergeJoinJoinDownstreamTsRanges(pOperator, leftTs, pRes, &nrows); } else if (asc && leftTs < rightTs || !asc && leftTs > rightTs) { pJoinInfo->leftPos += 1; diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index 1930adcfa41bf0516d9af027e4767cefba091c37..47ce6ceec061472f50427f62d7a40c748be5ae5a 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -61,16 +61,42 @@ static bool beforeHaving(ESqlClause clause) { return clause < SQL_CLAUSE_HAVING; static bool afterHaving(ESqlClause clause) { return clause > SQL_CLAUSE_HAVING; } +static bool hasSameTableAlias(SArray* pTables) { + if (taosArrayGetSize(pTables) < 2) { + return false; + } + STableNode* pTable0 = taosArrayGetP(pTables, 0); + for (int32_t i = 1; i < taosArrayGetSize(pTables); ++i) { + STableNode* pTable = taosArrayGetP(pTables, i); + if (0 == strcmp(pTable0->tableAlias, pTable->tableAlias)) { + return true; + } + } + return false; +} + static int32_t addNamespace(STranslateContext* pCxt, void* pTable) { size_t currTotalLevel = taosArrayGetSize(pCxt->pNsLevel); if (currTotalLevel > pCxt->currLevel) { SArray* pTables = taosArrayGetP(pCxt->pNsLevel, pCxt->currLevel); taosArrayPush(pTables, &pTable); + if (hasSameTableAlias(pTables)) { + return generateSyntaxErrMsgExt(&pCxt->msgBuf, + TSDB_CODE_PAR_NOT_UNIQUE_TABLE_ALIAS, + "Not unique table/alias: '%s'", + ((STableNode*)pTable)->tableAlias); + } } else { do { SArray* pTables = taosArrayInit(TARRAY_MIN_SIZE, POINTER_BYTES); if (pCxt->currLevel == currTotalLevel) { taosArrayPush(pTables, &pTable); + if (hasSameTableAlias(pTables)) { + return generateSyntaxErrMsgExt(&pCxt->msgBuf, + TSDB_CODE_PAR_NOT_UNIQUE_TABLE_ALIAS, + "Not unique table/alias: '%s'", + ((STableNode*)pTable)->tableAlias); + } } taosArrayPush(pCxt->pNsLevel, &pTables); ++currTotalLevel; diff --git a/source/libs/scalar/src/filter.c b/source/libs/scalar/src/filter.c index a18fc73494216e49642cc5de4c2ec46dee20f83c..04328fda9ca22532045f9e8dabbab07e0bcec2af 100644 --- a/source/libs/scalar/src/filter.c +++ b/source/libs/scalar/src/filter.c @@ -3929,6 +3929,26 @@ static EConditionType classifyCondition(SNode* pNode) { : (cxt.hasTagIndexCol ? COND_TYPE_TAG_INDEX : COND_TYPE_TAG))); } +static bool isCondColumnsFromMultiTable(SNode* pCond) { + SNodeList* pCondCols = nodesMakeList(); + int32_t code = nodesCollectColumnsFromNode(pCond, NULL, COLLECT_COL_TYPE_ALL, &pCondCols); + if (code == TSDB_CODE_SUCCESS) { + if (LIST_LENGTH(pCondCols) >= 2) { + SColumnNode* pFirstCol = (SColumnNode*)nodesListGetNode(pCondCols, 0); + SNode* pColNode = NULL; + FOREACH(pColNode, pCondCols) { + if (strcmp(((SColumnNode*)pColNode)->dbName, pFirstCol->dbName) != 0 || + strcmp(((SColumnNode*)pColNode)->tableAlias, pFirstCol->tableAlias) != 0) { + nodesDestroyList(pCondCols); + return true; + } + } + } + nodesDestroyList(pCondCols); + } + return false; +} + static int32_t partitionLogicCond(SNode** pCondition, SNode** pPrimaryKeyCond, SNode** pTagIndexCond, SNode** pTagCond, SNode** pOtherCond) { SLogicConditionNode* pLogicCond = (SLogicConditionNode*)(*pCondition); @@ -3941,31 +3961,37 @@ static int32_t partitionLogicCond(SNode** pCondition, SNode** pPrimaryKeyCond, S SNodeList* pOtherConds = NULL; SNode* pCond = NULL; FOREACH(pCond, pLogicCond->pParameterList) { - switch (classifyCondition(pCond)) { - case COND_TYPE_PRIMARY_KEY: - if (NULL != pPrimaryKeyCond) { - code = nodesListMakeAppend(&pPrimaryKeyConds, nodesCloneNode(pCond)); - } - break; - case COND_TYPE_TAG_INDEX: - if (NULL != pTagIndexCond) { - code = nodesListMakeAppend(&pTagIndexConds, nodesCloneNode(pCond)); - } - if (NULL != pTagCond) { - code = nodesListMakeAppend(&pTagConds, nodesCloneNode(pCond)); - } - break; - case COND_TYPE_TAG: - if (NULL != pTagCond) { - code = nodesListMakeAppend(&pTagConds, nodesCloneNode(pCond)); - } - break; - case COND_TYPE_NORMAL: - default: - if (NULL != pOtherCond) { - code = nodesListMakeAppend(&pOtherConds, nodesCloneNode(pCond)); - } - break; + if (isCondColumnsFromMultiTable(pCond)) { + if (NULL != pOtherCond) { + code = nodesListMakeAppend(&pOtherConds, nodesCloneNode(pCond)); + } + } else { + switch (classifyCondition(pCond)) { + case COND_TYPE_PRIMARY_KEY: + if (NULL != pPrimaryKeyCond) { + code = nodesListMakeAppend(&pPrimaryKeyConds, nodesCloneNode(pCond)); + } + break; + case COND_TYPE_TAG_INDEX: + if (NULL != pTagIndexCond) { + code = nodesListMakeAppend(&pTagIndexConds, nodesCloneNode(pCond)); + } + if (NULL != pTagCond) { + code = nodesListMakeAppend(&pTagConds, nodesCloneNode(pCond)); + } + break; + case COND_TYPE_TAG: + if (NULL != pTagCond) { + code = nodesListMakeAppend(&pTagConds, nodesCloneNode(pCond)); + } + break; + case COND_TYPE_NORMAL: + default: + if (NULL != pOtherCond) { + code = nodesListMakeAppend(&pOtherConds, nodesCloneNode(pCond)); + } + break; + } } if (TSDB_CODE_SUCCESS != code) { break; @@ -4026,43 +4052,50 @@ int32_t filterPartitionCond(SNode** pCondition, SNode** pPrimaryKeyCond, SNode** } bool needOutput = false; - switch (classifyCondition(*pCondition)) { - case COND_TYPE_PRIMARY_KEY: - if (NULL != pPrimaryKeyCond) { - *pPrimaryKeyCond = *pCondition; - needOutput = true; - } - break; - case COND_TYPE_TAG_INDEX: - if (NULL != pTagIndexCond) { - *pTagIndexCond = *pCondition; - needOutput = true; - } - if (NULL != pTagCond) { - SNode* pTempCond = *pCondition; + if (isCondColumnsFromMultiTable(*pCondition)) { + if (NULL != pOtherCond) { + *pOtherCond = *pCondition; + needOutput = true; + } + } else { + switch (classifyCondition(*pCondition)) { + case COND_TYPE_PRIMARY_KEY: + if (NULL != pPrimaryKeyCond) { + *pPrimaryKeyCond = *pCondition; + needOutput = true; + } + break; + case COND_TYPE_TAG_INDEX: if (NULL != pTagIndexCond) { - pTempCond = nodesCloneNode(*pCondition); - if (NULL == pTempCond) { - return TSDB_CODE_OUT_OF_MEMORY; + *pTagIndexCond = *pCondition; + needOutput = true; + } + if (NULL != pTagCond) { + SNode *pTempCond = *pCondition; + if (NULL != pTagIndexCond) { + pTempCond = nodesCloneNode(*pCondition); + if (NULL == pTempCond) { + return TSDB_CODE_OUT_OF_MEMORY; + } } + *pTagCond = pTempCond; + needOutput = true; } - *pTagCond = pTempCond; - needOutput = true; - } - break; - case COND_TYPE_TAG: - if (NULL != pTagCond) { - *pTagCond = *pCondition; - needOutput = true; - } - break; - case COND_TYPE_NORMAL: - default: - if (NULL != pOtherCond) { - *pOtherCond = *pCondition; - needOutput = true; - } - break; + break; + case COND_TYPE_TAG: + if (NULL != pTagCond) { + *pTagCond = *pCondition; + needOutput = true; + } + break; + case COND_TYPE_NORMAL: + default: + if (NULL != pOtherCond) { + *pOtherCond = *pCondition; + needOutput = true; + } + break; + } } if (needOutput) { *pCondition = NULL; diff --git a/source/util/src/terror.c b/source/util/src/terror.c index 3835260335c08f009b813eb272c516b6f3f5aabc..51dfa1ce1372d2ba8c3424c2be22c93286a00582 100644 --- a/source/util/src/terror.c +++ b/source/util/src/terror.c @@ -561,6 +561,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_PAR_ONLY_SUPPORT_SINGLE_TABLE, "Only support single TAOS_DEFINE_ERROR(TSDB_CODE_PAR_INVALID_SMA_INDEX, "Invalid sma index") TAOS_DEFINE_ERROR(TSDB_CODE_PAR_INVALID_SELECTED_EXPR, "Invalid SELECTed expression") TAOS_DEFINE_ERROR(TSDB_CODE_PAR_GET_META_ERROR, "Fail to get table info") +TAOS_DEFINE_ERROR(TSDB_CODE_PAR_NOT_UNIQUE_TABLE_ALIAS, "Not unique table/alias") TAOS_DEFINE_ERROR(TSDB_CODE_PAR_INTERNAL_ERROR, "Parser internal error") //planner diff --git a/tests/script/jenkins/basic.txt b/tests/script/jenkins/basic.txt index 755c8d537d32a7642547193955f884e3365b4daf..910b99ace3d098923bbe539b3f19eb35d8b5f6eb 100644 --- a/tests/script/jenkins/basic.txt +++ b/tests/script/jenkins/basic.txt @@ -133,7 +133,7 @@ ./test.sh -f tsim/parser/join_manyblocks.sim # TD-18018 ./test.sh -f tsim/parser/join_multitables.sim ./test.sh -f tsim/parser/join_multivnode.sim -# TD-17707 ./test.sh -f tsim/parser/join.sim +./test.sh -f tsim/parser/join.sim ./test.sh -f tsim/parser/last_cache.sim ./test.sh -f tsim/parser/last_groupby.sim ./test.sh -f tsim/parser/lastrow.sim diff --git a/tests/script/tsim/parser/join.sim b/tests/script/tsim/parser/join.sim index 0f41ebd1780d8922a1b2111830645f21514eff74..8ad5946a5452520e6d9ef42fba904c1e4aac2160 100644 --- a/tests/script/tsim/parser/join.sim +++ b/tests/script/tsim/parser/join.sim @@ -320,7 +320,7 @@ sql_error select count(join_tb1.c3), last(join_tb1.c3) from $tb1 , $tb2 where jo sql_error select count(join_tb3.*) from $tb1 , $tb2 where join_tb1.ts = join_tb0.ts and join_tb1.ts <= 100002 and join_tb0.c7 = true; sql_error select first(join_tb1.*) from $tb1 , $tb2 where join_tb1.ts = join_tb0.ts and join_tb1.ts <= 100002 or join_tb0.c7 = true; sql_error select join_tb3.* from $tb1 , $tb2 where join_tb1.ts = join_tb0.ts and join_tb1.ts <= 100002 and join_tb0.c7 = true; -sql_error select join_tb1.* from $tb1 , $tb2 where join_tb1.ts = join_tb0.ts and join_tb1.ts = join_tb0.c1; +sql select join_tb1.* from $tb1 , $tb2 where join_tb1.ts = join_tb0.ts and join_tb1.ts = join_tb0.c1; sql_error select join_tb1.* from $tb1 , $tb2 where join_tb1.ts = join_tb0.c1; sql_error select join_tb1.* from $tb1 , $tb2 where join_tb1.c7 = join_tb0.c1; sql_error select join_tb1.* from $tb1 , $tb2 where join_tb1.ts > join_tb0.ts; @@ -407,32 +407,32 @@ if $data00 != 396.000000000 then endi # first/last -sql select count(join_mt0.c1), sum(join_mt1.c2), first(join_mt0.c5), last(join_mt1.c7) from join_mt0, join_mt1 where join_mt0.t1=join_mt1.t1 and join_mt0.ts=join_mt1.ts and join_mt0.t1=1 interval(10a) order by join_mt0.ts asc; +sql select count(join_mt0.c1), sum(join_mt1.c2), first(join_mt0.c5), last(join_mt1.c7) from join_mt0, join_mt1 where join_mt0.t1=join_mt1.t1 and join_mt0.ts=join_mt1.ts and join_mt0.t1=1 interval(10a) order by _wstart asc; $val = 100 if $rows != $val then print $rows return -1 endi - +print $data00 $data01 $data02 $val = 10 -if $data01 != $val then +if $data00 != $val then return -1 endi $val = 45.000000000 -print $data02 -if $data02 != $val then +print $data01 +if $data01 != $val then return -1 endi $val = 0 -if $data03 != 0 then +if $data02 != 0 then return -1 endi # order by first/last -sql select count(join_mt0.c1), sum(join_mt1.c2), first(join_mt0.c5), last(join_mt1.c7) from join_mt0, join_mt1 where join_mt0.t1=join_mt1.t1 and join_mt0.ts=join_mt1.ts and join_mt0.t1=1 interval(10a) order by join_mt0.ts desc; +sql select count(join_mt0.c1), sum(join_mt1.c2), first(join_mt0.c5), last(join_mt1.c7) from join_mt0, join_mt1 where join_mt0.t1=join_mt1.t1 and join_mt0.ts=join_mt1.ts and join_mt0.t1=1 interval(10a) order by _wstart desc; $val = 100 if $rows != $val then @@ -453,13 +453,13 @@ print =================>"group by not supported" #======================limit offset=================================== # tag values not int -sql_error select count(*) from join_mt0, join_mt1 where join_mt0.ts=join_mt1.ts and join_mt0.t2=join_mt1.t2; +sql select count(*) from join_mt0, join_mt1 where join_mt0.ts=join_mt1.ts and join_mt0.t2=join_mt1.t2; # tag type not identical -sql_error select count(*) from join_mt0, join_mt1 where join_mt1.t2 = join_mt0.t1 and join_mt1.ts=join_mt0.ts; +sql select count(*) from join_mt0, join_mt1 where join_mt1.t2 = join_mt0.t1 and join_mt1.ts=join_mt0.ts; # table/super table join -sql_error select count(join_mt0.c1) from join_mt0, join_tb1 where join_mt0.ts=join_tb1.ts +sql select count(join_mt0.c1) from join_mt0, join_tb1 where join_mt0.ts=join_tb1.ts # multi-condition @@ -471,7 +471,7 @@ sql_error select count(join_mt0.c1), count(join_mt0.c2) from join_mt0, join_mt0 sql_error select sum(join_mt1.c2) from join_mt0, join_mt1 where join_mt0.t1=join_mt1.t1; # missing tag equals -sql_error select count(join_mt1.c3) from join_mt0, join_mt1 where join_mt0.ts=join_mt1.ts; +sql select count(join_mt1.c3) from join_mt0, join_mt1 where join_mt0.ts=join_mt1.ts; # tag values are identical error sql create table m1(ts timestamp, k int) tags(a int); @@ -486,7 +486,7 @@ sql insert into tm2 using m1 tags(1) values(1000000, 1)(2000000, 2); sql insert into um1 using m2 tags(1) values(1000001, 10)(2000000, 20); sql insert into um2 using m2 tags(9) values(1000001, 10)(2000000, 20); -sql_error select count(*) from m1,m2 where m1.a=m2.a and m1.ts=m2.ts; +sql select count(*) from m1,m2 where m1.a=m2.a and m1.ts=m2.ts; print ====> empty table/empty super-table join test, add for no result join test sql create database ux1;