diff --git a/source/libs/parser/src/parAstCreater.c b/source/libs/parser/src/parAstCreater.c index a418dc63b4..12062e0d4a 100644 --- a/source/libs/parser/src/parAstCreater.c +++ b/source/libs/parser/src/parAstCreater.c @@ -276,11 +276,9 @@ SNode* releaseRawExprNode(SAstCreateContext* pCxt, SNode* pNode) { strcpy(pExpr->aliasName, ((SColumnNode*)pExpr)->colName); strcpy(pExpr->userAlias, ((SColumnNode*)pExpr)->colName); } else if (pRawExpr->isPseudoColumn) { - int32_t len = TMIN(sizeof(pExpr->aliasName) - 1, pRawExpr->n); - strncpy(pExpr->userAlias, pRawExpr->p, len); - pExpr->userAlias[len] = '\0'; - strncpy(pExpr->aliasName, pRawExpr->p, len); - pExpr->aliasName[len] = '\0'; + // all pseudo column are translate to function with same name + strcpy(pExpr->userAlias, ((SFunctionNode*)pExpr)->functionName); + strcpy(pExpr->aliasName, ((SFunctionNode*)pExpr)->functionName); } else { int32_t len = TMIN(sizeof(pExpr->aliasName) - 1, pRawExpr->n); diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index 090d83d88f..42ab2f7a2f 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -1942,6 +1942,22 @@ static int32_t replacePsedudoColumnFuncWithColumn(STranslateContext* pCxt, SNode return TSDB_CODE_OUT_OF_MEMORY; } SExprNode* pOldExpr = (SExprNode*)(*ppNode); + //rewrite a.tbname == tbname(a) + if (nodeType(*ppNode) == QUERY_NODE_FUNCTION && ((SFunctionNode*)(*ppNode))->funcType == FUNCTION_TYPE_TBNAME) { + SFunctionNode* pFunc = (SFunctionNode*)(*ppNode); + if (0 != LIST_LENGTH(pFunc->pParameterList)) { + SValueNode* pVal = (SValueNode*)nodesListGetNode(pFunc->pParameterList, 0); + pCol->node.resType = pOldExpr->resType; + strcpy(pCol->tableAlias, pVal->literal); + strcpy(pCol->colName, pFunc->functionName); + strcpy(pCol->node.aliasName, pCol->colName); + strcpy(pCol->node.userAlias, pCol->colName); + nodesDestroyNode(*ppNode); + *ppNode = (SNode*)pCol; + + return TSDB_CODE_SUCCESS; + } + } pCol->node.resType = pOldExpr->resType; strcpy(pCol->node.aliasName, pOldExpr->aliasName); strcpy(pCol->node.userAlias, pOldExpr->userAlias); @@ -1953,6 +1969,19 @@ static int32_t replacePsedudoColumnFuncWithColumn(STranslateContext* pCxt, SNode return TSDB_CODE_SUCCESS; } +static int32_t rewriteToColumnAndRetranslate(STranslateContext* pCxt, SNode** ppNode, int32_t errCode) { + int32_t code = replacePsedudoColumnFuncWithColumn(pCxt, ppNode); + if (code != TSDB_CODE_SUCCESS) { + return code; + } + translateColumn(pCxt, (SColumnNode**)ppNode); + if (pCxt->errCode != TSDB_CODE_SUCCESS) { + return generateSyntaxErrMsg(&pCxt->msgBuf, errCode); + } else { + return TSDB_CODE_SUCCESS; + } +} + static int32_t translateWindowPseudoColumnFunc(STranslateContext* pCxt, SNode** ppNode, bool* pRewriteToColumn) { SFunctionNode* pFunc = (SFunctionNode*)(*ppNode); if (!fmIsWindowPseudoColumnFunc(pFunc->funcId)) { @@ -1967,16 +1996,7 @@ static int32_t translateWindowPseudoColumnFunc(STranslateContext* pCxt, SNode** } if (NULL == ((SSelectStmt*)pCxt->pCurrStmt)->pWindow) { *pRewriteToColumn = true; - int32_t code = replacePsedudoColumnFuncWithColumn(pCxt, ppNode); - if (code != TSDB_CODE_SUCCESS) { - return code; - } - translateColumn(pCxt, (SColumnNode**)ppNode); - if (pCxt->errCode != TSDB_CODE_SUCCESS) { - return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_WINDOW_PC); - } else { - return TSDB_CODE_SUCCESS; - } + return rewriteToColumnAndRetranslate(pCxt, ppNode, TSDB_CODE_PAR_INVALID_WINDOW_PC); } return TSDB_CODE_SUCCESS; } @@ -1992,23 +2012,18 @@ static int32_t translateScanPseudoColumnFunc(STranslateContext* pCxt, SNode** pp } if (QUERY_NODE_REAL_TABLE != nodeType(((SSelectStmt*)pCxt->pCurrStmt)->pFromTable)) { *pRewriteToColumn = true; - int32_t code = replacePsedudoColumnFuncWithColumn(pCxt, ppNode); - if (code != TSDB_CODE_SUCCESS) { - return code; - } - translateColumn(pCxt, (SColumnNode**)ppNode); - if (pCxt->errCode != TSDB_CODE_SUCCESS) { - return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TBNAME); - } else { - return TSDB_CODE_SUCCESS; - } + return rewriteToColumnAndRetranslate(pCxt, ppNode, TSDB_CODE_PAR_INVALID_TBNAME); } } else { SValueNode* pVal = (SValueNode*)nodesListGetNode(pFunc->pParameterList, 0); STableNode* pTable = NULL; pCxt->errCode = findTable(pCxt, pVal->literal, &pTable); - if (TSDB_CODE_SUCCESS != pCxt->errCode || (NULL == pTable || QUERY_NODE_REAL_TABLE != nodeType(pTable))) { + if (TSDB_CODE_SUCCESS != pCxt->errCode || (NULL == pTable)) { return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TBNAME); + } + if (nodeType(pTable) != QUERY_NODE_REAL_TABLE) { + *pRewriteToColumn = true; + return rewriteToColumnAndRetranslate(pCxt, ppNode, TSDB_CODE_PAR_INVALID_TBNAME); } } return TSDB_CODE_SUCCESS; diff --git a/tests/develop-test/2-query/pseudo_column.py b/tests/develop-test/2-query/pseudo_column.py index 4a97be6612..1d94df4cff 100644 --- a/tests/develop-test/2-query/pseudo_column.py +++ b/tests/develop-test/2-query/pseudo_column.py @@ -55,7 +55,7 @@ class TDTestCase: tdSql.checkData(2, 0, 'ct2') tdSql.checkData(2, 0, 'ct2') - tdSql.query('select `st.tbname` from (select st.tbname from st) order by `st.tbname`') + tdSql.query('select tbname from (select st.tbname from st) order by tbname') tdSql.checkCols(1) tdSql.checkRows(4) tdSql.checkData(0, 0, 'ct1') @@ -63,6 +63,14 @@ class TDTestCase: tdSql.checkData(2, 0, 'ct2') tdSql.checkData(2, 0, 'ct2') + tdSql.query('select * from (select tbname, avg(f) from st partition by tbname) a partition by a.tbname order by a.tbname'); + tdSql.checkRows(2) + tdSql.checkCols(2) + tdSql.checkData(0, 0, 'ct1'); + tdSql.checkData(0, 1, 6.0); + tdSql.checkData(1, 0, 'ct2'); + tdSql.checkData(1, 1, 12.0); + tdSql.error('select tbname from (select * from st)') tdSql.error('select st.tbname from (select st.tbname from st)') tdSql.error('select `st.tbname` from (select st.tbname from st) order by tbname')