From 1c27c2123fcb2e88114709c0e55bfaab5084c9d9 Mon Sep 17 00:00:00 2001 From: slzhou Date: Wed, 20 Sep 2023 11:06:59 +0800 Subject: [PATCH 01/12] enhance: select `tbname` from (select tbname from d.st) --- include/libs/nodes/querynodes.h | 1 + source/libs/parser/inc/parAst.h | 1 + source/libs/parser/inc/sql.y | 2 +- source/libs/parser/src/parAstCreater.c | 15 ++ source/libs/parser/src/parTranslater.c | 3 +- source/libs/parser/src/sql.c | 233 +++++++++++++------------ 6 files changed, 138 insertions(+), 117 deletions(-) diff --git a/include/libs/nodes/querynodes.h b/include/libs/nodes/querynodes.h index 972421b1e7..58cc3c4a75 100644 --- a/include/libs/nodes/querynodes.h +++ b/include/libs/nodes/querynodes.h @@ -35,6 +35,7 @@ typedef struct SRawExprNode { char* p; uint32_t n; SNode* pNode; + bool isPseudoColumn; } SRawExprNode; typedef struct SDataType { diff --git a/source/libs/parser/inc/parAst.h b/source/libs/parser/inc/parAst.h index 47043fddb1..3024eea397 100644 --- a/source/libs/parser/inc/parAst.h +++ b/source/libs/parser/inc/parAst.h @@ -98,6 +98,7 @@ void initAstCreateContext(SParseContext* pParseCxt, SAstCreateContext* pCxt); SNode* createRawExprNode(SAstCreateContext* pCxt, const SToken* pToken, SNode* pNode); SNode* createRawExprNodeExt(SAstCreateContext* pCxt, const SToken* pStart, const SToken* pEnd, SNode* pNode); +SNode* setRawExprNodeIsPseudoColumn(SAstCreateContext* pCxt, SNode* pNode, bool isPseudoColumn); SNode* releaseRawExprNode(SAstCreateContext* pCxt, SNode* pNode); SToken getTokenFromRawExprNode(SAstCreateContext* pCxt, SNode* pNode); diff --git a/source/libs/parser/inc/sql.y b/source/libs/parser/inc/sql.y index 667b21893e..c7da1e0878 100755 --- a/source/libs/parser/inc/sql.y +++ b/source/libs/parser/inc/sql.y @@ -809,7 +809,7 @@ expr_or_subquery(A) ::= expression(B). //expr_or_subquery(A) ::= subquery(B). { A = createTempTableNode(pCxt, releaseRawExprNode(pCxt, B), NULL); } expression(A) ::= literal(B). { A = B; } -expression(A) ::= pseudo_column(B). { A = B; } +expression(A) ::= pseudo_column(B). { A = B; setRawExprNodeIsPseudoColumn(pCxt, A, true); } expression(A) ::= column_reference(B). { A = B; } expression(A) ::= function_expression(B). { A = B; } expression(A) ::= case_when_expression(B). { A = B; } diff --git a/source/libs/parser/src/parAstCreater.c b/source/libs/parser/src/parAstCreater.c index e0b135b4f9..9baacf2790 100644 --- a/source/libs/parser/src/parAstCreater.c +++ b/source/libs/parser/src/parAstCreater.c @@ -257,6 +257,15 @@ SNode* createRawExprNodeExt(SAstCreateContext* pCxt, const SToken* pStart, const return (SNode*)target; } +SNode* setRawExprNodeIsPseudoColumn(SAstCreateContext* pCxt, SNode* pNode, bool isPseudoColumn) { + CHECK_PARSER_STATUS(pCxt); + if (NULL == pNode || QUERY_NODE_RAW_EXPR != nodeType(pNode)) { + return pNode; + } + ((SRawExprNode*)pNode)->isPseudoColumn = isPseudoColumn; + return pNode; +} + SNode* releaseRawExprNode(SAstCreateContext* pCxt, SNode* pNode) { CHECK_PARSER_STATUS(pCxt); SRawExprNode* pRawExpr = (SRawExprNode*)pNode; @@ -266,6 +275,12 @@ SNode* releaseRawExprNode(SAstCreateContext* pCxt, SNode* pNode) { if (QUERY_NODE_COLUMN == nodeType(pExpr)) { 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'; } 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 c702400526..0fc57d3729 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -1576,8 +1576,7 @@ static int32_t translateScanPseudoColumnFunc(STranslateContext* pCxt, SFunctionN return TSDB_CODE_SUCCESS; } if (0 == LIST_LENGTH(pFunc->pParameterList)) { - if (!isSelectStmt(pCxt->pCurrStmt) || NULL == ((SSelectStmt*)pCxt->pCurrStmt)->pFromTable || - QUERY_NODE_REAL_TABLE != nodeType(((SSelectStmt*)pCxt->pCurrStmt)->pFromTable)) { + if (!isSelectStmt(pCxt->pCurrStmt) || NULL == ((SSelectStmt*)pCxt->pCurrStmt)->pFromTable) { return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TBNAME); } } else { diff --git a/source/libs/parser/src/sql.c b/source/libs/parser/src/sql.c index ff1d834791..b86edc8791 100644 --- a/source/libs/parser/src/sql.c +++ b/source/libs/parser/src/sql.c @@ -6814,7 +6814,6 @@ static YYACTIONTYPE yy_reduce( case 405: /* signed_literal ::= signed */ yytestcase(yyruleno==405); case 426: /* expr_or_subquery ::= expression */ yytestcase(yyruleno==426); case 427: /* expression ::= literal */ yytestcase(yyruleno==427); - case 428: /* expression ::= pseudo_column */ yytestcase(yyruleno==428); case 429: /* expression ::= column_reference */ yytestcase(yyruleno==429); case 430: /* expression ::= function_expression */ yytestcase(yyruleno==430); case 431: /* expression ::= case_when_expression */ yytestcase(yyruleno==431); @@ -6833,37 +6832,37 @@ static YYACTIONTYPE yy_reduce( case 597: /* query_or_subquery ::= query_expression */ yytestcase(yyruleno==597); #line 727 "sql.y" { yylhsminor.yy122 = yymsp[0].minor.yy122; } -#line 6836 "sql.c" +#line 6835 "sql.c" yymsp[0].minor.yy122 = yylhsminor.yy122; break; case 396: /* literal ::= NULL */ #line 728 "sql.y" { yylhsminor.yy122 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_NULL, &yymsp[0].minor.yy0)); } -#line 6842 "sql.c" +#line 6841 "sql.c" yymsp[0].minor.yy122 = yylhsminor.yy122; break; case 397: /* literal ::= NK_QUESTION */ #line 729 "sql.y" { yylhsminor.yy122 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createPlaceholderValueNode(pCxt, &yymsp[0].minor.yy0)); } -#line 6848 "sql.c" +#line 6847 "sql.c" yymsp[0].minor.yy122 = yylhsminor.yy122; break; case 398: /* duration_literal ::= NK_VARIABLE */ #line 731 "sql.y" { yylhsminor.yy122 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createDurationValueNode(pCxt, &yymsp[0].minor.yy0)); } -#line 6854 "sql.c" +#line 6853 "sql.c" yymsp[0].minor.yy122 = yylhsminor.yy122; break; case 399: /* signed ::= NK_INTEGER */ #line 733 "sql.y" { yylhsminor.yy122 = createValueNode(pCxt, TSDB_DATA_TYPE_UBIGINT, &yymsp[0].minor.yy0); } -#line 6860 "sql.c" +#line 6859 "sql.c" yymsp[0].minor.yy122 = yylhsminor.yy122; break; case 400: /* signed ::= NK_PLUS NK_INTEGER */ #line 734 "sql.y" { yymsp[-1].minor.yy122 = createValueNode(pCxt, TSDB_DATA_TYPE_UBIGINT, &yymsp[0].minor.yy0); } -#line 6866 "sql.c" +#line 6865 "sql.c" break; case 401: /* signed ::= NK_MINUS NK_INTEGER */ #line 735 "sql.y" @@ -6872,19 +6871,19 @@ static YYACTIONTYPE yy_reduce( t.n = (yymsp[0].minor.yy0.z + yymsp[0].minor.yy0.n) - yymsp[-1].minor.yy0.z; yylhsminor.yy122 = createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &t); } -#line 6875 "sql.c" +#line 6874 "sql.c" yymsp[-1].minor.yy122 = yylhsminor.yy122; break; case 402: /* signed ::= NK_FLOAT */ #line 740 "sql.y" { yylhsminor.yy122 = createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &yymsp[0].minor.yy0); } -#line 6881 "sql.c" +#line 6880 "sql.c" yymsp[0].minor.yy122 = yylhsminor.yy122; break; case 403: /* signed ::= NK_PLUS NK_FLOAT */ #line 741 "sql.y" { yymsp[-1].minor.yy122 = createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &yymsp[0].minor.yy0); } -#line 6887 "sql.c" +#line 6886 "sql.c" break; case 404: /* signed ::= NK_MINUS NK_FLOAT */ #line 742 "sql.y" @@ -6893,25 +6892,25 @@ static YYACTIONTYPE yy_reduce( t.n = (yymsp[0].minor.yy0.z + yymsp[0].minor.yy0.n) - yymsp[-1].minor.yy0.z; yylhsminor.yy122 = createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &t); } -#line 6896 "sql.c" +#line 6895 "sql.c" yymsp[-1].minor.yy122 = yylhsminor.yy122; break; case 406: /* signed_literal ::= NK_STRING */ #line 749 "sql.y" { yylhsminor.yy122 = createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0); } -#line 6902 "sql.c" +#line 6901 "sql.c" yymsp[0].minor.yy122 = yylhsminor.yy122; break; case 407: /* signed_literal ::= NK_BOOL */ #line 750 "sql.y" { yylhsminor.yy122 = createValueNode(pCxt, TSDB_DATA_TYPE_BOOL, &yymsp[0].minor.yy0); } -#line 6908 "sql.c" +#line 6907 "sql.c" yymsp[0].minor.yy122 = yylhsminor.yy122; break; case 408: /* signed_literal ::= TIMESTAMP NK_STRING */ #line 751 "sql.y" { yymsp[-1].minor.yy122 = createValueNode(pCxt, TSDB_DATA_TYPE_TIMESTAMP, &yymsp[0].minor.yy0); } -#line 6914 "sql.c" +#line 6913 "sql.c" break; case 409: /* signed_literal ::= duration_literal */ case 411: /* signed_literal ::= literal_func */ yytestcase(yyruleno==411); @@ -6923,19 +6922,25 @@ static YYACTIONTYPE yy_reduce( case 611: /* search_condition ::= common_expression */ yytestcase(yyruleno==611); #line 752 "sql.y" { yylhsminor.yy122 = releaseRawExprNode(pCxt, yymsp[0].minor.yy122); } -#line 6926 "sql.c" +#line 6925 "sql.c" yymsp[0].minor.yy122 = yylhsminor.yy122; break; case 410: /* signed_literal ::= NULL */ #line 753 "sql.y" { yylhsminor.yy122 = createValueNode(pCxt, TSDB_DATA_TYPE_NULL, &yymsp[0].minor.yy0); } -#line 6932 "sql.c" +#line 6931 "sql.c" yymsp[0].minor.yy122 = yylhsminor.yy122; break; case 412: /* signed_literal ::= NK_QUESTION */ #line 755 "sql.y" { yylhsminor.yy122 = createPlaceholderValueNode(pCxt, &yymsp[0].minor.yy0); } -#line 6938 "sql.c" +#line 6937 "sql.c" + yymsp[0].minor.yy122 = yylhsminor.yy122; + break; + case 428: /* expression ::= pseudo_column */ +#line 812 "sql.y" +{ yylhsminor.yy122 = yymsp[0].minor.yy122; setRawExprNodeIsPseudoColumn(pCxt, yylhsminor.yy122, true); } +#line 6943 "sql.c" yymsp[0].minor.yy122 = yylhsminor.yy122; break; case 432: /* expression ::= NK_LP expression NK_RP */ @@ -6943,7 +6948,7 @@ static YYACTIONTYPE yy_reduce( case 610: /* subquery ::= NK_LP subquery NK_RP */ yytestcase(yyruleno==610); #line 816 "sql.y" { yylhsminor.yy122 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, releaseRawExprNode(pCxt, yymsp[-1].minor.yy122)); } -#line 6946 "sql.c" +#line 6951 "sql.c" yymsp[-2].minor.yy122 = yylhsminor.yy122; break; case 433: /* expression ::= NK_PLUS expr_or_subquery */ @@ -6952,7 +6957,7 @@ static YYACTIONTYPE yy_reduce( SToken t = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy122); yylhsminor.yy122 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &t, releaseRawExprNode(pCxt, yymsp[0].minor.yy122)); } -#line 6955 "sql.c" +#line 6960 "sql.c" yymsp[-1].minor.yy122 = yylhsminor.yy122; break; case 434: /* expression ::= NK_MINUS expr_or_subquery */ @@ -6961,7 +6966,7 @@ static YYACTIONTYPE yy_reduce( SToken t = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy122); yylhsminor.yy122 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &t, createOperatorNode(pCxt, OP_TYPE_MINUS, releaseRawExprNode(pCxt, yymsp[0].minor.yy122), NULL)); } -#line 6964 "sql.c" +#line 6969 "sql.c" yymsp[-1].minor.yy122 = yylhsminor.yy122; break; case 435: /* expression ::= expr_or_subquery NK_PLUS expr_or_subquery */ @@ -6971,7 +6976,7 @@ static YYACTIONTYPE yy_reduce( SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy122); yylhsminor.yy122 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_ADD, releaseRawExprNode(pCxt, yymsp[-2].minor.yy122), releaseRawExprNode(pCxt, yymsp[0].minor.yy122))); } -#line 6974 "sql.c" +#line 6979 "sql.c" yymsp[-2].minor.yy122 = yylhsminor.yy122; break; case 436: /* expression ::= expr_or_subquery NK_MINUS expr_or_subquery */ @@ -6981,7 +6986,7 @@ static YYACTIONTYPE yy_reduce( SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy122); yylhsminor.yy122 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_SUB, releaseRawExprNode(pCxt, yymsp[-2].minor.yy122), releaseRawExprNode(pCxt, yymsp[0].minor.yy122))); } -#line 6984 "sql.c" +#line 6989 "sql.c" yymsp[-2].minor.yy122 = yylhsminor.yy122; break; case 437: /* expression ::= expr_or_subquery NK_STAR expr_or_subquery */ @@ -6991,7 +6996,7 @@ static YYACTIONTYPE yy_reduce( SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy122); yylhsminor.yy122 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_MULTI, releaseRawExprNode(pCxt, yymsp[-2].minor.yy122), releaseRawExprNode(pCxt, yymsp[0].minor.yy122))); } -#line 6994 "sql.c" +#line 6999 "sql.c" yymsp[-2].minor.yy122 = yylhsminor.yy122; break; case 438: /* expression ::= expr_or_subquery NK_SLASH expr_or_subquery */ @@ -7001,7 +7006,7 @@ static YYACTIONTYPE yy_reduce( SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy122); yylhsminor.yy122 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_DIV, releaseRawExprNode(pCxt, yymsp[-2].minor.yy122), releaseRawExprNode(pCxt, yymsp[0].minor.yy122))); } -#line 7004 "sql.c" +#line 7009 "sql.c" yymsp[-2].minor.yy122 = yylhsminor.yy122; break; case 439: /* expression ::= expr_or_subquery NK_REM expr_or_subquery */ @@ -7011,7 +7016,7 @@ static YYACTIONTYPE yy_reduce( SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy122); yylhsminor.yy122 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_REM, releaseRawExprNode(pCxt, yymsp[-2].minor.yy122), releaseRawExprNode(pCxt, yymsp[0].minor.yy122))); } -#line 7014 "sql.c" +#line 7019 "sql.c" yymsp[-2].minor.yy122 = yylhsminor.yy122; break; case 440: /* expression ::= column_reference NK_ARROW NK_STRING */ @@ -7020,7 +7025,7 @@ static YYACTIONTYPE yy_reduce( SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy122); yylhsminor.yy122 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createOperatorNode(pCxt, OP_TYPE_JSON_GET_VALUE, releaseRawExprNode(pCxt, yymsp[-2].minor.yy122), createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0))); } -#line 7023 "sql.c" +#line 7028 "sql.c" yymsp[-2].minor.yy122 = yylhsminor.yy122; break; case 441: /* expression ::= expr_or_subquery NK_BITAND expr_or_subquery */ @@ -7030,7 +7035,7 @@ static YYACTIONTYPE yy_reduce( SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy122); yylhsminor.yy122 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_BIT_AND, releaseRawExprNode(pCxt, yymsp[-2].minor.yy122), releaseRawExprNode(pCxt, yymsp[0].minor.yy122))); } -#line 7033 "sql.c" +#line 7038 "sql.c" yymsp[-2].minor.yy122 = yylhsminor.yy122; break; case 442: /* expression ::= expr_or_subquery NK_BITOR expr_or_subquery */ @@ -7040,19 +7045,19 @@ static YYACTIONTYPE yy_reduce( SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy122); yylhsminor.yy122 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_BIT_OR, releaseRawExprNode(pCxt, yymsp[-2].minor.yy122), releaseRawExprNode(pCxt, yymsp[0].minor.yy122))); } -#line 7043 "sql.c" +#line 7048 "sql.c" yymsp[-2].minor.yy122 = yylhsminor.yy122; break; case 445: /* column_reference ::= column_name */ #line 870 "sql.y" { yylhsminor.yy122 = createRawExprNode(pCxt, &yymsp[0].minor.yy203, createColumnNode(pCxt, NULL, &yymsp[0].minor.yy203)); } -#line 7049 "sql.c" +#line 7054 "sql.c" yymsp[0].minor.yy122 = yylhsminor.yy122; break; case 446: /* column_reference ::= table_name NK_DOT column_name */ #line 871 "sql.y" { yylhsminor.yy122 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy203, &yymsp[0].minor.yy203, createColumnNode(pCxt, &yymsp[-2].minor.yy203, &yymsp[0].minor.yy203)); } -#line 7055 "sql.c" +#line 7060 "sql.c" yymsp[-2].minor.yy122 = yylhsminor.yy122; break; case 447: /* pseudo_column ::= ROWTS */ @@ -7069,68 +7074,68 @@ static YYACTIONTYPE yy_reduce( case 464: /* literal_func ::= NOW */ yytestcase(yyruleno==464); #line 873 "sql.y" { yylhsminor.yy122 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[0].minor.yy0, NULL)); } -#line 7072 "sql.c" +#line 7077 "sql.c" yymsp[0].minor.yy122 = yylhsminor.yy122; break; case 449: /* pseudo_column ::= table_name NK_DOT TBNAME */ #line 875 "sql.y" { yylhsminor.yy122 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy203, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[0].minor.yy0, createNodeList(pCxt, createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[-2].minor.yy203)))); } -#line 7078 "sql.c" +#line 7083 "sql.c" yymsp[-2].minor.yy122 = yylhsminor.yy122; break; case 459: /* function_expression ::= function_name NK_LP expression_list NK_RP */ case 460: /* function_expression ::= star_func NK_LP star_func_para_list NK_RP */ yytestcase(yyruleno==460); #line 886 "sql.y" { yylhsminor.yy122 = createRawExprNodeExt(pCxt, &yymsp[-3].minor.yy203, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[-3].minor.yy203, yymsp[-1].minor.yy298)); } -#line 7085 "sql.c" +#line 7090 "sql.c" yymsp[-3].minor.yy122 = yylhsminor.yy122; break; case 461: /* function_expression ::= CAST NK_LP expr_or_subquery AS type_name NK_RP */ #line 889 "sql.y" { yylhsminor.yy122 = createRawExprNodeExt(pCxt, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0, createCastFunctionNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy122), yymsp[-1].minor.yy388)); } -#line 7091 "sql.c" +#line 7096 "sql.c" yymsp[-5].minor.yy122 = yylhsminor.yy122; break; case 463: /* literal_func ::= noarg_func NK_LP NK_RP */ #line 892 "sql.y" { yylhsminor.yy122 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy203, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[-2].minor.yy203, NULL)); } -#line 7097 "sql.c" +#line 7102 "sql.c" yymsp[-2].minor.yy122 = yylhsminor.yy122; break; case 478: /* star_func_para_list ::= NK_STAR */ #line 916 "sql.y" { yylhsminor.yy298 = createNodeList(pCxt, createColumnNode(pCxt, NULL, &yymsp[0].minor.yy0)); } -#line 7103 "sql.c" +#line 7108 "sql.c" yymsp[0].minor.yy298 = yylhsminor.yy298; break; case 483: /* star_func_para ::= table_name NK_DOT NK_STAR */ case 551: /* select_item ::= table_name NK_DOT NK_STAR */ yytestcase(yyruleno==551); #line 925 "sql.y" { yylhsminor.yy122 = createColumnNode(pCxt, &yymsp[-2].minor.yy203, &yymsp[0].minor.yy0); } -#line 7110 "sql.c" +#line 7115 "sql.c" yymsp[-2].minor.yy122 = yylhsminor.yy122; break; case 484: /* case_when_expression ::= CASE when_then_list case_when_else_opt END */ #line 928 "sql.y" { yylhsminor.yy122 = createRawExprNodeExt(pCxt, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0, createCaseWhenNode(pCxt, NULL, yymsp[-2].minor.yy298, yymsp[-1].minor.yy122)); } -#line 7116 "sql.c" +#line 7121 "sql.c" yymsp[-3].minor.yy122 = yylhsminor.yy122; break; case 485: /* case_when_expression ::= CASE common_expression when_then_list case_when_else_opt END */ #line 930 "sql.y" { yylhsminor.yy122 = createRawExprNodeExt(pCxt, &yymsp[-4].minor.yy0, &yymsp[0].minor.yy0, createCaseWhenNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy122), yymsp[-2].minor.yy298, yymsp[-1].minor.yy122)); } -#line 7122 "sql.c" +#line 7127 "sql.c" yymsp[-4].minor.yy122 = yylhsminor.yy122; break; case 488: /* when_then_expr ::= WHEN common_expression THEN common_expression */ #line 937 "sql.y" { yymsp[-3].minor.yy122 = createWhenThenNode(pCxt, releaseRawExprNode(pCxt, yymsp[-2].minor.yy122), releaseRawExprNode(pCxt, yymsp[0].minor.yy122)); } -#line 7128 "sql.c" +#line 7133 "sql.c" break; case 490: /* case_when_else_opt ::= ELSE common_expression */ #line 940 "sql.y" { yymsp[-1].minor.yy122 = releaseRawExprNode(pCxt, yymsp[0].minor.yy122); } -#line 7133 "sql.c" +#line 7138 "sql.c" break; case 491: /* predicate ::= expr_or_subquery compare_op expr_or_subquery */ case 496: /* predicate ::= expr_or_subquery in_op in_predicate_value */ yytestcase(yyruleno==496); @@ -7140,7 +7145,7 @@ static YYACTIONTYPE yy_reduce( SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy122); yylhsminor.yy122 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, yymsp[-1].minor.yy416, releaseRawExprNode(pCxt, yymsp[-2].minor.yy122), releaseRawExprNode(pCxt, yymsp[0].minor.yy122))); } -#line 7143 "sql.c" +#line 7148 "sql.c" yymsp[-2].minor.yy122 = yylhsminor.yy122; break; case 492: /* predicate ::= expr_or_subquery BETWEEN expr_or_subquery AND expr_or_subquery */ @@ -7150,7 +7155,7 @@ static YYACTIONTYPE yy_reduce( SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy122); yylhsminor.yy122 = createRawExprNodeExt(pCxt, &s, &e, createBetweenAnd(pCxt, releaseRawExprNode(pCxt, yymsp[-4].minor.yy122), releaseRawExprNode(pCxt, yymsp[-2].minor.yy122), releaseRawExprNode(pCxt, yymsp[0].minor.yy122))); } -#line 7153 "sql.c" +#line 7158 "sql.c" yymsp[-4].minor.yy122 = yylhsminor.yy122; break; case 493: /* predicate ::= expr_or_subquery NOT BETWEEN expr_or_subquery AND expr_or_subquery */ @@ -7160,7 +7165,7 @@ static YYACTIONTYPE yy_reduce( SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy122); yylhsminor.yy122 = createRawExprNodeExt(pCxt, &s, &e, createNotBetweenAnd(pCxt, releaseRawExprNode(pCxt, yymsp[-5].minor.yy122), releaseRawExprNode(pCxt, yymsp[-2].minor.yy122), releaseRawExprNode(pCxt, yymsp[0].minor.yy122))); } -#line 7163 "sql.c" +#line 7168 "sql.c" yymsp[-5].minor.yy122 = yylhsminor.yy122; break; case 494: /* predicate ::= expr_or_subquery IS NULL */ @@ -7169,7 +7174,7 @@ static YYACTIONTYPE yy_reduce( SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy122); yylhsminor.yy122 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createOperatorNode(pCxt, OP_TYPE_IS_NULL, releaseRawExprNode(pCxt, yymsp[-2].minor.yy122), NULL)); } -#line 7172 "sql.c" +#line 7177 "sql.c" yymsp[-2].minor.yy122 = yylhsminor.yy122; break; case 495: /* predicate ::= expr_or_subquery IS NOT NULL */ @@ -7178,78 +7183,78 @@ static YYACTIONTYPE yy_reduce( SToken s = getTokenFromRawExprNode(pCxt, yymsp[-3].minor.yy122); yylhsminor.yy122 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createOperatorNode(pCxt, OP_TYPE_IS_NOT_NULL, releaseRawExprNode(pCxt, yymsp[-3].minor.yy122), NULL)); } -#line 7181 "sql.c" +#line 7186 "sql.c" yymsp[-3].minor.yy122 = yylhsminor.yy122; break; case 497: /* compare_op ::= NK_LT */ #line 977 "sql.y" { yymsp[0].minor.yy416 = OP_TYPE_LOWER_THAN; } -#line 7187 "sql.c" +#line 7192 "sql.c" break; case 498: /* compare_op ::= NK_GT */ #line 978 "sql.y" { yymsp[0].minor.yy416 = OP_TYPE_GREATER_THAN; } -#line 7192 "sql.c" +#line 7197 "sql.c" break; case 499: /* compare_op ::= NK_LE */ #line 979 "sql.y" { yymsp[0].minor.yy416 = OP_TYPE_LOWER_EQUAL; } -#line 7197 "sql.c" +#line 7202 "sql.c" break; case 500: /* compare_op ::= NK_GE */ #line 980 "sql.y" { yymsp[0].minor.yy416 = OP_TYPE_GREATER_EQUAL; } -#line 7202 "sql.c" +#line 7207 "sql.c" break; case 501: /* compare_op ::= NK_NE */ #line 981 "sql.y" { yymsp[0].minor.yy416 = OP_TYPE_NOT_EQUAL; } -#line 7207 "sql.c" +#line 7212 "sql.c" break; case 502: /* compare_op ::= NK_EQ */ #line 982 "sql.y" { yymsp[0].minor.yy416 = OP_TYPE_EQUAL; } -#line 7212 "sql.c" +#line 7217 "sql.c" break; case 503: /* compare_op ::= LIKE */ #line 983 "sql.y" { yymsp[0].minor.yy416 = OP_TYPE_LIKE; } -#line 7217 "sql.c" +#line 7222 "sql.c" break; case 504: /* compare_op ::= NOT LIKE */ #line 984 "sql.y" { yymsp[-1].minor.yy416 = OP_TYPE_NOT_LIKE; } -#line 7222 "sql.c" +#line 7227 "sql.c" break; case 505: /* compare_op ::= MATCH */ #line 985 "sql.y" { yymsp[0].minor.yy416 = OP_TYPE_MATCH; } -#line 7227 "sql.c" +#line 7232 "sql.c" break; case 506: /* compare_op ::= NMATCH */ #line 986 "sql.y" { yymsp[0].minor.yy416 = OP_TYPE_NMATCH; } -#line 7232 "sql.c" +#line 7237 "sql.c" break; case 507: /* compare_op ::= CONTAINS */ #line 987 "sql.y" { yymsp[0].minor.yy416 = OP_TYPE_JSON_CONTAINS; } -#line 7237 "sql.c" +#line 7242 "sql.c" break; case 508: /* in_op ::= IN */ #line 991 "sql.y" { yymsp[0].minor.yy416 = OP_TYPE_IN; } -#line 7242 "sql.c" +#line 7247 "sql.c" break; case 509: /* in_op ::= NOT IN */ #line 992 "sql.y" { yymsp[-1].minor.yy416 = OP_TYPE_NOT_IN; } -#line 7247 "sql.c" +#line 7252 "sql.c" break; case 510: /* in_predicate_value ::= NK_LP literal_list NK_RP */ #line 994 "sql.y" { yylhsminor.yy122 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, createNodeListNode(pCxt, yymsp[-1].minor.yy298)); } -#line 7252 "sql.c" +#line 7257 "sql.c" yymsp[-2].minor.yy122 = yylhsminor.yy122; break; case 512: /* boolean_value_expression ::= NOT boolean_primary */ @@ -7258,7 +7263,7 @@ static YYACTIONTYPE yy_reduce( SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy122); yylhsminor.yy122 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &e, createLogicConditionNode(pCxt, LOGIC_COND_TYPE_NOT, releaseRawExprNode(pCxt, yymsp[0].minor.yy122), NULL)); } -#line 7261 "sql.c" +#line 7266 "sql.c" yymsp[-1].minor.yy122 = yylhsminor.yy122; break; case 513: /* boolean_value_expression ::= boolean_value_expression OR boolean_value_expression */ @@ -7268,7 +7273,7 @@ static YYACTIONTYPE yy_reduce( SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy122); yylhsminor.yy122 = createRawExprNodeExt(pCxt, &s, &e, createLogicConditionNode(pCxt, LOGIC_COND_TYPE_OR, releaseRawExprNode(pCxt, yymsp[-2].minor.yy122), releaseRawExprNode(pCxt, yymsp[0].minor.yy122))); } -#line 7271 "sql.c" +#line 7276 "sql.c" yymsp[-2].minor.yy122 = yylhsminor.yy122; break; case 514: /* boolean_value_expression ::= boolean_value_expression AND boolean_value_expression */ @@ -7278,64 +7283,64 @@ static YYACTIONTYPE yy_reduce( SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy122); yylhsminor.yy122 = createRawExprNodeExt(pCxt, &s, &e, createLogicConditionNode(pCxt, LOGIC_COND_TYPE_AND, releaseRawExprNode(pCxt, yymsp[-2].minor.yy122), releaseRawExprNode(pCxt, yymsp[0].minor.yy122))); } -#line 7281 "sql.c" +#line 7286 "sql.c" yymsp[-2].minor.yy122 = yylhsminor.yy122; break; case 522: /* table_reference_list ::= table_reference_list NK_COMMA table_reference */ #line 1027 "sql.y" { yylhsminor.yy122 = createJoinTableNode(pCxt, JOIN_TYPE_INNER, yymsp[-2].minor.yy122, yymsp[0].minor.yy122, NULL); } -#line 7287 "sql.c" +#line 7292 "sql.c" yymsp[-2].minor.yy122 = yylhsminor.yy122; break; case 525: /* table_primary ::= table_name alias_opt */ #line 1033 "sql.y" { yylhsminor.yy122 = createRealTableNode(pCxt, NULL, &yymsp[-1].minor.yy203, &yymsp[0].minor.yy203); } -#line 7293 "sql.c" +#line 7298 "sql.c" yymsp[-1].minor.yy122 = yylhsminor.yy122; break; case 526: /* table_primary ::= db_name NK_DOT table_name alias_opt */ #line 1034 "sql.y" { yylhsminor.yy122 = createRealTableNode(pCxt, &yymsp[-3].minor.yy203, &yymsp[-1].minor.yy203, &yymsp[0].minor.yy203); } -#line 7299 "sql.c" +#line 7304 "sql.c" yymsp[-3].minor.yy122 = yylhsminor.yy122; break; case 527: /* table_primary ::= subquery alias_opt */ #line 1035 "sql.y" { yylhsminor.yy122 = createTempTableNode(pCxt, releaseRawExprNode(pCxt, yymsp[-1].minor.yy122), &yymsp[0].minor.yy203); } -#line 7305 "sql.c" +#line 7310 "sql.c" yymsp[-1].minor.yy122 = yylhsminor.yy122; break; case 529: /* alias_opt ::= */ #line 1040 "sql.y" { yymsp[1].minor.yy203 = nil_token; } -#line 7311 "sql.c" +#line 7316 "sql.c" break; case 531: /* alias_opt ::= AS table_alias */ #line 1042 "sql.y" { yymsp[-1].minor.yy203 = yymsp[0].minor.yy203; } -#line 7316 "sql.c" +#line 7321 "sql.c" break; case 532: /* parenthesized_joined_table ::= NK_LP joined_table NK_RP */ case 533: /* parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP */ yytestcase(yyruleno==533); #line 1044 "sql.y" { yymsp[-2].minor.yy122 = yymsp[-1].minor.yy122; } -#line 7322 "sql.c" +#line 7327 "sql.c" break; case 534: /* joined_table ::= table_reference join_type JOIN table_reference ON search_condition */ #line 1049 "sql.y" { yylhsminor.yy122 = createJoinTableNode(pCxt, yymsp[-4].minor.yy498, yymsp[-5].minor.yy122, yymsp[-2].minor.yy122, yymsp[0].minor.yy122); } -#line 7327 "sql.c" +#line 7332 "sql.c" yymsp[-5].minor.yy122 = yylhsminor.yy122; break; case 535: /* join_type ::= */ #line 1053 "sql.y" { yymsp[1].minor.yy498 = JOIN_TYPE_INNER; } -#line 7333 "sql.c" +#line 7338 "sql.c" break; case 536: /* join_type ::= INNER */ #line 1054 "sql.y" { yymsp[0].minor.yy498 = JOIN_TYPE_INNER; } -#line 7338 "sql.c" +#line 7343 "sql.c" break; case 537: /* query_specification ::= SELECT hint_list set_quantifier_opt tag_mode_opt select_list from_clause_opt where_clause_opt partition_by_clause_opt range_opt every_opt fill_opt twindow_clause_opt group_by_clause_opt having_clause_opt */ #line 1060 "sql.y" @@ -7351,42 +7356,42 @@ static YYACTIONTYPE yy_reduce( yymsp[-13].minor.yy122 = addEveryClause(pCxt, yymsp[-13].minor.yy122, yymsp[-4].minor.yy122); yymsp[-13].minor.yy122 = addFillClause(pCxt, yymsp[-13].minor.yy122, yymsp[-3].minor.yy122); } -#line 7354 "sql.c" +#line 7359 "sql.c" break; case 538: /* hint_list ::= */ #line 1075 "sql.y" { yymsp[1].minor.yy298 = createHintNodeList(pCxt, NULL); } -#line 7359 "sql.c" +#line 7364 "sql.c" break; case 539: /* hint_list ::= NK_HINT */ #line 1076 "sql.y" { yylhsminor.yy298 = createHintNodeList(pCxt, &yymsp[0].minor.yy0); } -#line 7364 "sql.c" +#line 7369 "sql.c" yymsp[0].minor.yy298 = yylhsminor.yy298; break; case 544: /* set_quantifier_opt ::= ALL */ #line 1087 "sql.y" { yymsp[0].minor.yy983 = false; } -#line 7370 "sql.c" +#line 7375 "sql.c" break; case 547: /* select_item ::= NK_STAR */ #line 1094 "sql.y" { yylhsminor.yy122 = createColumnNode(pCxt, NULL, &yymsp[0].minor.yy0); } -#line 7375 "sql.c" +#line 7380 "sql.c" yymsp[0].minor.yy122 = yylhsminor.yy122; break; case 549: /* select_item ::= common_expression column_alias */ case 559: /* partition_item ::= expr_or_subquery column_alias */ yytestcase(yyruleno==559); #line 1096 "sql.y" { yylhsminor.yy122 = setProjectionAlias(pCxt, releaseRawExprNode(pCxt, yymsp[-1].minor.yy122), &yymsp[0].minor.yy203); } -#line 7382 "sql.c" +#line 7387 "sql.c" yymsp[-1].minor.yy122 = yylhsminor.yy122; break; case 550: /* select_item ::= common_expression AS column_alias */ case 560: /* partition_item ::= expr_or_subquery AS column_alias */ yytestcase(yyruleno==560); #line 1097 "sql.y" { yylhsminor.yy122 = setProjectionAlias(pCxt, releaseRawExprNode(pCxt, yymsp[-2].minor.yy122), &yymsp[0].minor.yy203); } -#line 7389 "sql.c" +#line 7394 "sql.c" yymsp[-2].minor.yy122 = yylhsminor.yy122; break; case 555: /* partition_by_clause_opt ::= PARTITION BY partition_list */ @@ -7394,99 +7399,99 @@ static YYACTIONTYPE yy_reduce( case 600: /* order_by_clause_opt ::= ORDER BY sort_specification_list */ yytestcase(yyruleno==600); #line 1106 "sql.y" { yymsp[-2].minor.yy298 = yymsp[0].minor.yy298; } -#line 7397 "sql.c" +#line 7402 "sql.c" break; case 562: /* twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA duration_literal NK_RP */ #line 1119 "sql.y" { yymsp[-5].minor.yy122 = createSessionWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy122), releaseRawExprNode(pCxt, yymsp[-1].minor.yy122)); } -#line 7402 "sql.c" +#line 7407 "sql.c" break; case 563: /* twindow_clause_opt ::= STATE_WINDOW NK_LP expr_or_subquery NK_RP */ #line 1120 "sql.y" { yymsp[-3].minor.yy122 = createStateWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-1].minor.yy122)); } -#line 7407 "sql.c" +#line 7412 "sql.c" break; case 564: /* twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt */ #line 1122 "sql.y" { yymsp[-5].minor.yy122 = createIntervalWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy122), NULL, yymsp[-1].minor.yy122, yymsp[0].minor.yy122); } -#line 7412 "sql.c" +#line 7417 "sql.c" break; case 565: /* twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt */ #line 1125 "sql.y" { yymsp[-7].minor.yy122 = createIntervalWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-5].minor.yy122), releaseRawExprNode(pCxt, yymsp[-3].minor.yy122), yymsp[-1].minor.yy122, yymsp[0].minor.yy122); } -#line 7417 "sql.c" +#line 7422 "sql.c" break; case 566: /* twindow_clause_opt ::= EVENT_WINDOW START WITH search_condition END WITH search_condition */ #line 1127 "sql.y" { yymsp[-6].minor.yy122 = createEventWindowNode(pCxt, yymsp[-3].minor.yy122, yymsp[0].minor.yy122); } -#line 7422 "sql.c" +#line 7427 "sql.c" break; case 570: /* fill_opt ::= FILL NK_LP fill_mode NK_RP */ #line 1133 "sql.y" { yymsp[-3].minor.yy122 = createFillNode(pCxt, yymsp[-1].minor.yy312, NULL); } -#line 7427 "sql.c" +#line 7432 "sql.c" break; case 571: /* fill_opt ::= FILL NK_LP VALUE NK_COMMA expression_list NK_RP */ #line 1134 "sql.y" { yymsp[-5].minor.yy122 = createFillNode(pCxt, FILL_MODE_VALUE, createNodeListNode(pCxt, yymsp[-1].minor.yy298)); } -#line 7432 "sql.c" +#line 7437 "sql.c" break; case 572: /* fill_opt ::= FILL NK_LP VALUE_F NK_COMMA expression_list NK_RP */ #line 1135 "sql.y" { yymsp[-5].minor.yy122 = createFillNode(pCxt, FILL_MODE_VALUE_F, createNodeListNode(pCxt, yymsp[-1].minor.yy298)); } -#line 7437 "sql.c" +#line 7442 "sql.c" break; case 573: /* fill_mode ::= NONE */ #line 1139 "sql.y" { yymsp[0].minor.yy312 = FILL_MODE_NONE; } -#line 7442 "sql.c" +#line 7447 "sql.c" break; case 574: /* fill_mode ::= PREV */ #line 1140 "sql.y" { yymsp[0].minor.yy312 = FILL_MODE_PREV; } -#line 7447 "sql.c" +#line 7452 "sql.c" break; case 575: /* fill_mode ::= NULL */ #line 1141 "sql.y" { yymsp[0].minor.yy312 = FILL_MODE_NULL; } -#line 7452 "sql.c" +#line 7457 "sql.c" break; case 576: /* fill_mode ::= NULL_F */ #line 1142 "sql.y" { yymsp[0].minor.yy312 = FILL_MODE_NULL_F; } -#line 7457 "sql.c" +#line 7462 "sql.c" break; case 577: /* fill_mode ::= LINEAR */ #line 1143 "sql.y" { yymsp[0].minor.yy312 = FILL_MODE_LINEAR; } -#line 7462 "sql.c" +#line 7467 "sql.c" break; case 578: /* fill_mode ::= NEXT */ #line 1144 "sql.y" { yymsp[0].minor.yy312 = FILL_MODE_NEXT; } -#line 7467 "sql.c" +#line 7472 "sql.c" break; case 581: /* group_by_list ::= expr_or_subquery */ #line 1153 "sql.y" { yylhsminor.yy298 = createNodeList(pCxt, createGroupingSetNode(pCxt, releaseRawExprNode(pCxt, yymsp[0].minor.yy122))); } -#line 7472 "sql.c" +#line 7477 "sql.c" yymsp[0].minor.yy298 = yylhsminor.yy298; break; case 582: /* group_by_list ::= group_by_list NK_COMMA expr_or_subquery */ #line 1154 "sql.y" { yylhsminor.yy298 = addNodeToList(pCxt, yymsp[-2].minor.yy298, createGroupingSetNode(pCxt, releaseRawExprNode(pCxt, yymsp[0].minor.yy122))); } -#line 7478 "sql.c" +#line 7483 "sql.c" yymsp[-2].minor.yy298 = yylhsminor.yy298; break; case 586: /* range_opt ::= RANGE NK_LP expr_or_subquery NK_COMMA expr_or_subquery NK_RP */ #line 1161 "sql.y" { yymsp[-5].minor.yy122 = createInterpTimeRange(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy122), releaseRawExprNode(pCxt, yymsp[-1].minor.yy122)); } -#line 7484 "sql.c" +#line 7489 "sql.c" break; case 587: /* range_opt ::= RANGE NK_LP expr_or_subquery NK_RP */ #line 1163 "sql.y" { yymsp[-3].minor.yy122 = createInterpTimePoint(pCxt, releaseRawExprNode(pCxt, yymsp[-1].minor.yy122)); } -#line 7489 "sql.c" +#line 7494 "sql.c" break; case 590: /* query_expression ::= query_simple order_by_clause_opt slimit_clause_opt limit_clause_opt */ #line 1170 "sql.y" @@ -7495,80 +7500,80 @@ static YYACTIONTYPE yy_reduce( yylhsminor.yy122 = addSlimitClause(pCxt, yylhsminor.yy122, yymsp[-1].minor.yy122); yylhsminor.yy122 = addLimitClause(pCxt, yylhsminor.yy122, yymsp[0].minor.yy122); } -#line 7498 "sql.c" +#line 7503 "sql.c" yymsp[-3].minor.yy122 = yylhsminor.yy122; break; case 593: /* union_query_expression ::= query_simple_or_subquery UNION ALL query_simple_or_subquery */ #line 1180 "sql.y" { yylhsminor.yy122 = createSetOperator(pCxt, SET_OP_TYPE_UNION_ALL, yymsp[-3].minor.yy122, yymsp[0].minor.yy122); } -#line 7504 "sql.c" +#line 7509 "sql.c" yymsp[-3].minor.yy122 = yylhsminor.yy122; break; case 594: /* union_query_expression ::= query_simple_or_subquery UNION query_simple_or_subquery */ #line 1182 "sql.y" { yylhsminor.yy122 = createSetOperator(pCxt, SET_OP_TYPE_UNION, yymsp[-2].minor.yy122, yymsp[0].minor.yy122); } -#line 7510 "sql.c" +#line 7515 "sql.c" yymsp[-2].minor.yy122 = yylhsminor.yy122; break; case 602: /* slimit_clause_opt ::= SLIMIT NK_INTEGER */ case 606: /* limit_clause_opt ::= LIMIT NK_INTEGER */ yytestcase(yyruleno==606); #line 1196 "sql.y" { yymsp[-1].minor.yy122 = createLimitNode(pCxt, &yymsp[0].minor.yy0, NULL); } -#line 7517 "sql.c" +#line 7522 "sql.c" break; case 603: /* slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER */ case 607: /* limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER */ yytestcase(yyruleno==607); #line 1197 "sql.y" { yymsp[-3].minor.yy122 = createLimitNode(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); } -#line 7523 "sql.c" +#line 7528 "sql.c" break; case 604: /* slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER */ case 608: /* limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER */ yytestcase(yyruleno==608); #line 1198 "sql.y" { yymsp[-3].minor.yy122 = createLimitNode(pCxt, &yymsp[0].minor.yy0, &yymsp[-2].minor.yy0); } -#line 7529 "sql.c" +#line 7534 "sql.c" break; case 609: /* subquery ::= NK_LP query_expression NK_RP */ #line 1206 "sql.y" { yylhsminor.yy122 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-1].minor.yy122); } -#line 7534 "sql.c" +#line 7539 "sql.c" yymsp[-2].minor.yy122 = yylhsminor.yy122; break; case 614: /* sort_specification ::= expr_or_subquery ordering_specification_opt null_ordering_opt */ #line 1220 "sql.y" { yylhsminor.yy122 = createOrderByExprNode(pCxt, releaseRawExprNode(pCxt, yymsp[-2].minor.yy122), yymsp[-1].minor.yy626, yymsp[0].minor.yy877); } -#line 7540 "sql.c" +#line 7545 "sql.c" yymsp[-2].minor.yy122 = yylhsminor.yy122; break; case 615: /* ordering_specification_opt ::= */ #line 1224 "sql.y" { yymsp[1].minor.yy626 = ORDER_ASC; } -#line 7546 "sql.c" +#line 7551 "sql.c" break; case 616: /* ordering_specification_opt ::= ASC */ #line 1225 "sql.y" { yymsp[0].minor.yy626 = ORDER_ASC; } -#line 7551 "sql.c" +#line 7556 "sql.c" break; case 617: /* ordering_specification_opt ::= DESC */ #line 1226 "sql.y" { yymsp[0].minor.yy626 = ORDER_DESC; } -#line 7556 "sql.c" +#line 7561 "sql.c" break; case 618: /* null_ordering_opt ::= */ #line 1230 "sql.y" { yymsp[1].minor.yy877 = NULL_ORDER_DEFAULT; } -#line 7561 "sql.c" +#line 7566 "sql.c" break; case 619: /* null_ordering_opt ::= NULLS FIRST */ #line 1231 "sql.y" { yymsp[-1].minor.yy877 = NULL_ORDER_FIRST; } -#line 7566 "sql.c" +#line 7571 "sql.c" break; case 620: /* null_ordering_opt ::= NULLS LAST */ #line 1232 "sql.y" { yymsp[-1].minor.yy877 = NULL_ORDER_LAST; } -#line 7571 "sql.c" +#line 7576 "sql.c" break; default: break; @@ -7641,7 +7646,7 @@ static void yy_syntax_error( } else if (TSDB_CODE_PAR_DB_NOT_SPECIFIED == pCxt->errCode && TK_NK_FLOAT == TOKEN.type) { pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_SYNTAX_ERROR, TOKEN.z); } -#line 7644 "sql.c" +#line 7649 "sql.c" /************ End %syntax_error code ******************************************/ ParseARG_STORE /* Suppress warning about unused %extra_argument variable */ ParseCTX_STORE From dce29b367b9ad35e6cc350dd0f49a25ddaf610d4 Mon Sep 17 00:00:00 2001 From: slzhou Date: Wed, 27 Sep 2023 13:46:14 +0800 Subject: [PATCH 02/12] fix: retore translater.c --- source/libs/parser/src/parTranslater.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index 81da234b06..959cd81e06 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -1555,7 +1555,8 @@ static int32_t translateScanPseudoColumnFunc(STranslateContext* pCxt, SFunctionN return TSDB_CODE_SUCCESS; } if (0 == LIST_LENGTH(pFunc->pParameterList)) { - if (!isSelectStmt(pCxt->pCurrStmt) || NULL == ((SSelectStmt*)pCxt->pCurrStmt)->pFromTable) { + if (!isSelectStmt(pCxt->pCurrStmt) || NULL == ((SSelectStmt*)pCxt->pCurrStmt)->pFromTable || + QUERY_NODE_REAL_TABLE != nodeType(((SSelectStmt*)pCxt->pCurrStmt)->pFromTable)) { return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TBNAME); } } else { From 1aad905558e7118df00d5f884ef013fe7489ebdb Mon Sep 17 00:00:00 2001 From: slzhou Date: Sun, 8 Oct 2023 15:55:01 +0800 Subject: [PATCH 03/12] fix: collection functions hash set distinct error --- source/libs/nodes/src/nodesUtilFuncs.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/source/libs/nodes/src/nodesUtilFuncs.c b/source/libs/nodes/src/nodesUtilFuncs.c index bf5b6c8080..c5a1bfa599 100644 --- a/source/libs/nodes/src/nodesUtilFuncs.c +++ b/source/libs/nodes/src/nodesUtilFuncs.c @@ -2033,7 +2033,6 @@ typedef struct SCollectFuncsCxt { char* tableAlias; FFuncClassifier classifier; SNodeList* pFuncs; - SHashObj* pFuncsSet; } SCollectFuncsCxt; static EDealRes collectFuncs(SNode* pNode, void* pContext) { @@ -2048,9 +2047,15 @@ static EDealRes collectFuncs(SNode* pNode, void* pContext) { } } SExprNode* pExpr = (SExprNode*)pNode; - if (NULL == taosHashGet(pCxt->pFuncsSet, &pExpr, sizeof(SExprNode*))) { + bool bFound = false; + SNode* pn = NULL; + FOREACH(pn, pCxt->pFuncs) { + if (nodesEqualNode(pn, pNode)) { + bFound = true; + } + } + if (!bFound) { pCxt->errCode = nodesListStrictAppend(pCxt->pFuncs, nodesCloneNode(pNode)); - taosHashPut(pCxt->pFuncsSet, &pExpr, POINTER_BYTES, &pExpr, POINTER_BYTES); } return (TSDB_CODE_SUCCESS == pCxt->errCode ? DEAL_RES_IGNORE_CHILD : DEAL_RES_ERROR); } @@ -2077,12 +2082,10 @@ int32_t nodesCollectFuncs(SSelectStmt* pSelect, ESqlClause clause, char* tableAl SCollectFuncsCxt cxt = {.errCode = TSDB_CODE_SUCCESS, .classifier = classifier, .tableAlias = tableAlias, - .pFuncs = (NULL == *pFuncs ? nodesMakeList() : *pFuncs), - .pFuncsSet = taosHashInit(4, funcNodeHash, false, false)}; - if (NULL == cxt.pFuncs || NULL == cxt.pFuncsSet) { + .pFuncs = (NULL == *pFuncs ? nodesMakeList() : *pFuncs)}; + if (NULL == cxt.pFuncs) { return TSDB_CODE_OUT_OF_MEMORY; } - taosHashSetEqualFp(cxt.pFuncsSet, funcNodeEqual); *pFuncs = NULL; nodesWalkSelectStmt(pSelect, clause, collectFuncs, &cxt); if (TSDB_CODE_SUCCESS == cxt.errCode) { @@ -2094,7 +2097,6 @@ int32_t nodesCollectFuncs(SSelectStmt* pSelect, ESqlClause clause, char* tableAl } else { nodesDestroyList(cxt.pFuncs); } - taosHashCleanup(cxt.pFuncsSet); return cxt.errCode; } From 6ad518d61de8f142e4160d4aff15b15d43bd0ce2 Mon Sep 17 00:00:00 2001 From: shenglian zhou Date: Mon, 9 Oct 2023 13:21:32 +0800 Subject: [PATCH 04/12] enhance: pseduo column coverted to column when necessary --- source/libs/parser/src/parTranslater.c | 96 ++++++++++++++++---------- 1 file changed, 59 insertions(+), 37 deletions(-) diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index 0fc57d3729..2a55a5fcd3 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -1571,25 +1571,6 @@ static int32_t translateAggFunc(STranslateContext* pCxt, SFunctionNode* pFunc) { return TSDB_CODE_SUCCESS; } -static int32_t translateScanPseudoColumnFunc(STranslateContext* pCxt, SFunctionNode* pFunc) { - if (!fmIsScanPseudoColumnFunc(pFunc->funcId)) { - return TSDB_CODE_SUCCESS; - } - if (0 == LIST_LENGTH(pFunc->pParameterList)) { - if (!isSelectStmt(pCxt->pCurrStmt) || NULL == ((SSelectStmt*)pCxt->pCurrStmt)->pFromTable) { - return generateSyntaxErrMsg(&pCxt->msgBuf, 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))) { - return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TBNAME); - } - } - return TSDB_CODE_SUCCESS; -} - static int32_t translateIndefiniteRowsFunc(STranslateContext* pCxt, SFunctionNode* pFunc) { if (!fmIsIndefiniteRowsFunc(pFunc->funcId)) { return TSDB_CODE_SUCCESS; @@ -1726,20 +1707,6 @@ static int32_t translateForbidFillFunc(STranslateContext* pCxt, SFunctionNode* p return TSDB_CODE_SUCCESS; } -static int32_t translateWindowPseudoColumnFunc(STranslateContext* pCxt, SFunctionNode* pFunc) { - if (!fmIsWindowPseudoColumnFunc(pFunc->funcId)) { - return TSDB_CODE_SUCCESS; - } - if (!isSelectStmt(pCxt->pCurrStmt) || NULL == ((SSelectStmt*)pCxt->pCurrStmt)->pWindow) { - return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_WINDOW_PC); - } - if (beforeWindow(pCxt->currClause)) { - return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_WINDOW_PC, "There mustn't be %s", - pFunc->functionName); - } - return TSDB_CODE_SUCCESS; -} - static int32_t translateForbidStreamFunc(STranslateContext* pCxt, SFunctionNode* pFunc) { if (!fmIsForbidStreamFunc(pFunc->funcId)) { return TSDB_CODE_SUCCESS; @@ -1978,10 +1945,65 @@ static int32_t rewriteSystemInfoFunc(STranslateContext* pCxt, SNode** pNode) { return TSDB_CODE_PAR_INTERNAL_ERROR; } -static int32_t translateNormalFunction(STranslateContext* pCxt, SFunctionNode* pFunc) { +static int32_t replacePsedudoColumnFuncWithColumn(STranslateContext* pCxt, SNode** ppNode) { + SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN); + if (pCol == NULL) { + return TSDB_CODE_OUT_OF_MEMORY; + } + SExprNode* pOldExpr = (SExprNode*)(*ppNode); + pCol->node.resType = pOldExpr->resType; + strcpy(pCol->node.aliasName, pOldExpr->aliasName); + strcpy(pCol->node.userAlias, pOldExpr->userAlias); + strcpy(pCol->colName, pOldExpr->aliasName); + + nodesDestroyNode(*ppNode); + *ppNode = (SNode*)pCol; + + return TSDB_CODE_SUCCESS; +} + +static int32_t translateWindowPseudoColumnFunc2(STranslateContext* pCxt, SNode** ppNode) { + SFunctionNode* pFunc = (SFunctionNode*)(*ppNode); + if (!isSelectStmt(pCxt->pCurrStmt)) { + return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_WINDOW_PC); + } + if (((SSelectStmt*)pCxt->pCurrStmt)->pWindow && beforeWindow(pCxt->currClause)) { + return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_WINDOW_PC, "There mustn't be %s", + pFunc->functionName); + } + if (NULL == ((SSelectStmt*)pCxt->pCurrStmt)->pWindow) { + replacePsedudoColumnFuncWithColumn(pCxt, ppNode); + return translateColumn(pCxt, (SColumnNode**)ppNode); + } + return TSDB_CODE_SUCCESS; +} + +static int32_t translateScanPseudoColumnFunc2(STranslateContext* pCxt, SNode** ppNode) { + SFunctionNode* pFunc = (SFunctionNode*)(*ppNode); + if (0 == LIST_LENGTH(pFunc->pParameterList)) { + if (!isSelectStmt(pCxt->pCurrStmt) || NULL == ((SSelectStmt*)pCxt->pCurrStmt)->pFromTable) { + return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TBNAME); + } + if (QUERY_NODE_REAL_TABLE != nodeType(((SSelectStmt*)pCxt->pCurrStmt)->pFromTable)) { + replacePsedudoColumnFuncWithColumn(pCxt, ppNode); + return translateColumn(pCxt, (SColumnNode**)ppNode); + } + } 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))) { + return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TBNAME); + } + } + return TSDB_CODE_SUCCESS; +} + +static int32_t translateNormalFunction(STranslateContext* pCxt, SNode** ppNode) { + SFunctionNode* pFunc = (SFunctionNode*)(*ppNode); int32_t code = translateAggFunc(pCxt, pFunc); if (TSDB_CODE_SUCCESS == code) { - code = translateScanPseudoColumnFunc(pCxt, pFunc); + code = translateScanPseudoColumnFunc2(pCxt, ppNode); } if (TSDB_CODE_SUCCESS == code) { code = translateIndefiniteRowsFunc(pCxt, pFunc); @@ -1990,7 +2012,7 @@ static int32_t translateNormalFunction(STranslateContext* pCxt, SFunctionNode* p code = translateForbidFillFunc(pCxt, pFunc); } if (TSDB_CODE_SUCCESS == code) { - code = translateWindowPseudoColumnFunc(pCxt, pFunc); + code = translateWindowPseudoColumnFunc2(pCxt, ppNode); } if (TSDB_CODE_SUCCESS == code) { code = translateForbidStreamFunc(pCxt, pFunc); @@ -2082,7 +2104,7 @@ static int32_t translateFunctionImpl(STranslateContext* pCxt, SFunctionNode** pF if (fmIsClientPseudoColumnFunc((*pFunc)->funcId)) { return rewriteClientPseudoColumnFunc(pCxt, (SNode**)pFunc); } - return translateNormalFunction(pCxt, *pFunc); + return translateNormalFunction(pCxt, (SNode**)pFunc); } static EDealRes translateFunction(STranslateContext* pCxt, SFunctionNode** pFunc) { From 56534a7b0d47b2601a960dee5a985f97b5222dc3 Mon Sep 17 00:00:00 2001 From: slzhou Date: Mon, 9 Oct 2023 16:22:44 +0800 Subject: [PATCH 05/12] enhance: scan and window pseudo column --- source/libs/parser/src/parTranslater.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index b341e4e5eb..0228a7fded 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -1934,6 +1934,9 @@ static int32_t replacePsedudoColumnFuncWithColumn(STranslateContext* pCxt, SNode static int32_t translateWindowPseudoColumnFunc2(STranslateContext* pCxt, SNode** ppNode) { SFunctionNode* pFunc = (SFunctionNode*)(*ppNode); + if (!fmIsWindowPseudoColumnFunc(pFunc->funcId)) { + return TSDB_CODE_SUCCESS; + } if (!isSelectStmt(pCxt->pCurrStmt)) { return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_WINDOW_PC); } @@ -1942,27 +1945,38 @@ static int32_t translateWindowPseudoColumnFunc2(STranslateContext* pCxt, SNode** pFunc->functionName); } if (NULL == ((SSelectStmt*)pCxt->pCurrStmt)->pWindow) { - replacePsedudoColumnFuncWithColumn(pCxt, ppNode); - return translateColumn(pCxt, (SColumnNode**)ppNode); + int32_t code = replacePsedudoColumnFuncWithColumn(pCxt, ppNode); + if (code != TSDB_CODE_SUCCESS) { + return code; + } + translateColumn(pCxt, (SColumnNode**)ppNode); + return pCxt->errCode; } return TSDB_CODE_SUCCESS; } static int32_t translateScanPseudoColumnFunc2(STranslateContext* pCxt, SNode** ppNode) { SFunctionNode* pFunc = (SFunctionNode*)(*ppNode); + if (!fmIsScanPseudoColumnFunc(pFunc->funcId)) { + return TSDB_CODE_SUCCESS; + } if (0 == LIST_LENGTH(pFunc->pParameterList)) { if (!isSelectStmt(pCxt->pCurrStmt) || NULL == ((SSelectStmt*)pCxt->pCurrStmt)->pFromTable) { return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TBNAME); } if (QUERY_NODE_REAL_TABLE != nodeType(((SSelectStmt*)pCxt->pCurrStmt)->pFromTable)) { - replacePsedudoColumnFuncWithColumn(pCxt, ppNode); - return translateColumn(pCxt, (SColumnNode**)ppNode); + int32_t code = replacePsedudoColumnFuncWithColumn(pCxt, ppNode); + if (code != TSDB_CODE_SUCCESS) { + return code; + } + translateColumn(pCxt, (SColumnNode**)ppNode); + return pCxt->errCode; } } 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 || QUERY_NODE_REAL_TABLE != nodeType(pTable))) { return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TBNAME); } } From 44c3bc99e09c939eac667ed295b90be3724eefe5 Mon Sep 17 00:00:00 2001 From: slzhou Date: Mon, 9 Oct 2023 16:56:21 +0800 Subject: [PATCH 06/12] feat: add interp pseudo column conversion to column --- source/libs/parser/src/parTranslater.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index 0228a7fded..4e0979ddaa 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -263,6 +263,8 @@ static int32_t createLastTsSelectStmt(char* pDb, char* pTable, STableMeta* pMet static int32_t setQuery(STranslateContext* pCxt, SQuery* pQuery); static int32_t setRefreshMate(STranslateContext* pCxt, SQuery* pQuery); +static int32_t replacePsedudoColumnFuncWithColumn(STranslateContext* pCxt, SNode** ppNode); + static bool afterGroupBy(ESqlClause clause) { return clause > SQL_CLAUSE_GROUP_BY; } static bool beforeHaving(ESqlClause clause) { return clause < SQL_CLAUSE_HAVING; } @@ -1619,7 +1621,8 @@ static int32_t translateInterpFunc(STranslateContext* pCxt, SFunctionNode* pFunc return TSDB_CODE_SUCCESS; } -static int32_t translateInterpPseudoColumnFunc(STranslateContext* pCxt, SFunctionNode* pFunc) { +static int32_t translateInterpPseudoColumnFunc(STranslateContext* pCxt, SNode** ppNode) { + SFunctionNode* pFunc = (SFunctionNode*)(*ppNode); if (!fmIsInterpPseudoColumnFunc(pFunc->funcId)) { return TSDB_CODE_SUCCESS; } @@ -1631,6 +1634,24 @@ static int32_t translateInterpPseudoColumnFunc(STranslateContext* pCxt, SFunctio return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_INTERP_CLAUSE, "%s is not allowed in where clause", pFunc->functionName); } + + SSelectStmt* pSelect = (SSelectStmt*)pCxt->pCurrStmt; + SNode* pNode = NULL; + bool bFound = false; + FOREACH(pNode, pSelect->pProjectionList) { + if (nodeType(pNode) == QUERY_NODE_FUNCTION && strcasecmp(((SFunctionNode*)pNode)->functionName, "interp") == 0) { + bFound = true; + break; + } + } + if (!bFound) { + int32_t code = replacePsedudoColumnFuncWithColumn(pCxt, ppNode); + if (code != TSDB_CODE_SUCCESS) { + return code; + } + translateColumn(pCxt, (SColumnNode**)ppNode); + return pCxt->errCode; + } return TSDB_CODE_SUCCESS; } @@ -2017,7 +2038,7 @@ static int32_t translateNormalFunction(STranslateContext* pCxt, SNode** ppNode) code = translateInterpFunc(pCxt, pFunc); } if (TSDB_CODE_SUCCESS == code) { - code = translateInterpPseudoColumnFunc(pCxt, pFunc); + code = translateInterpPseudoColumnFunc(pCxt, ppNode); } if (TSDB_CODE_SUCCESS == code) { code = translateTimelineFunc(pCxt, pFunc); From b8fe279a855edb5edabfe5608a970d19d42caf65 Mon Sep 17 00:00:00 2001 From: slzhou Date: Tue, 10 Oct 2023 07:44:29 +0800 Subject: [PATCH 07/12] fix: renanme function --- source/libs/parser/src/parTranslater.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index 4e0979ddaa..201111e425 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -1953,7 +1953,7 @@ static int32_t replacePsedudoColumnFuncWithColumn(STranslateContext* pCxt, SNode return TSDB_CODE_SUCCESS; } -static int32_t translateWindowPseudoColumnFunc2(STranslateContext* pCxt, SNode** ppNode) { +static int32_t translateWindowPseudoColumnFunc(STranslateContext* pCxt, SNode** ppNode) { SFunctionNode* pFunc = (SFunctionNode*)(*ppNode); if (!fmIsWindowPseudoColumnFunc(pFunc->funcId)) { return TSDB_CODE_SUCCESS; @@ -1976,7 +1976,7 @@ static int32_t translateWindowPseudoColumnFunc2(STranslateContext* pCxt, SNode** return TSDB_CODE_SUCCESS; } -static int32_t translateScanPseudoColumnFunc2(STranslateContext* pCxt, SNode** ppNode) { +static int32_t translateScanPseudoColumnFunc(STranslateContext* pCxt, SNode** ppNode) { SFunctionNode* pFunc = (SFunctionNode*)(*ppNode); if (!fmIsScanPseudoColumnFunc(pFunc->funcId)) { return TSDB_CODE_SUCCESS; @@ -2008,7 +2008,7 @@ static int32_t translateNormalFunction(STranslateContext* pCxt, SNode** ppNode) SFunctionNode* pFunc = (SFunctionNode*)(*ppNode); int32_t code = translateAggFunc(pCxt, pFunc); if (TSDB_CODE_SUCCESS == code) { - code = translateScanPseudoColumnFunc2(pCxt, ppNode); + code = translateScanPseudoColumnFunc(pCxt, ppNode); } if (TSDB_CODE_SUCCESS == code) { code = translateIndefiniteRowsFunc(pCxt, pFunc); @@ -2017,7 +2017,7 @@ static int32_t translateNormalFunction(STranslateContext* pCxt, SNode** ppNode) code = translateForbidFillFunc(pCxt, pFunc); } if (TSDB_CODE_SUCCESS == code) { - code = translateWindowPseudoColumnFunc2(pCxt, ppNode); + code = translateWindowPseudoColumnFunc(pCxt, ppNode); } if (TSDB_CODE_SUCCESS == code) { code = translateForbidStreamFunc(pCxt, pFunc); From da9d39bfe6ec09afa701325f975670421b5e2d12 Mon Sep 17 00:00:00 2001 From: slzhou Date: Tue, 10 Oct 2023 08:31:23 +0800 Subject: [PATCH 08/12] fix: cancel future pseudo column translation function processing when rewritten to column --- source/libs/parser/src/parTranslater.c | 27 ++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index 201111e425..e285c7a806 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -1621,7 +1621,7 @@ static int32_t translateInterpFunc(STranslateContext* pCxt, SFunctionNode* pFunc return TSDB_CODE_SUCCESS; } -static int32_t translateInterpPseudoColumnFunc(STranslateContext* pCxt, SNode** ppNode) { +static int32_t translateInterpPseudoColumnFunc(STranslateContext* pCxt, SNode** ppNode, bool* pRewriteToColumn) { SFunctionNode* pFunc = (SFunctionNode*)(*ppNode); if (!fmIsInterpPseudoColumnFunc(pFunc->funcId)) { return TSDB_CODE_SUCCESS; @@ -1645,6 +1645,7 @@ static int32_t translateInterpPseudoColumnFunc(STranslateContext* pCxt, SNode** } } if (!bFound) { + *pRewriteToColumn = true; int32_t code = replacePsedudoColumnFuncWithColumn(pCxt, ppNode); if (code != TSDB_CODE_SUCCESS) { return code; @@ -1953,7 +1954,7 @@ static int32_t replacePsedudoColumnFuncWithColumn(STranslateContext* pCxt, SNode return TSDB_CODE_SUCCESS; } -static int32_t translateWindowPseudoColumnFunc(STranslateContext* pCxt, SNode** ppNode) { +static int32_t translateWindowPseudoColumnFunc(STranslateContext* pCxt, SNode** ppNode, bool* pRewriteToColumn) { SFunctionNode* pFunc = (SFunctionNode*)(*ppNode); if (!fmIsWindowPseudoColumnFunc(pFunc->funcId)) { return TSDB_CODE_SUCCESS; @@ -1966,6 +1967,7 @@ static int32_t translateWindowPseudoColumnFunc(STranslateContext* pCxt, SNode** pFunc->functionName); } if (NULL == ((SSelectStmt*)pCxt->pCurrStmt)->pWindow) { + *pRewriteToColumn = true; int32_t code = replacePsedudoColumnFuncWithColumn(pCxt, ppNode); if (code != TSDB_CODE_SUCCESS) { return code; @@ -1976,7 +1978,7 @@ static int32_t translateWindowPseudoColumnFunc(STranslateContext* pCxt, SNode** return TSDB_CODE_SUCCESS; } -static int32_t translateScanPseudoColumnFunc(STranslateContext* pCxt, SNode** ppNode) { +static int32_t translateScanPseudoColumnFunc(STranslateContext* pCxt, SNode** ppNode, bool* pRewriteToColumn) { SFunctionNode* pFunc = (SFunctionNode*)(*ppNode); if (!fmIsScanPseudoColumnFunc(pFunc->funcId)) { return TSDB_CODE_SUCCESS; @@ -1986,6 +1988,7 @@ static int32_t translateScanPseudoColumnFunc(STranslateContext* pCxt, SNode** pp return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TBNAME); } 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; @@ -2008,7 +2011,11 @@ static int32_t translateNormalFunction(STranslateContext* pCxt, SNode** ppNode) SFunctionNode* pFunc = (SFunctionNode*)(*ppNode); int32_t code = translateAggFunc(pCxt, pFunc); if (TSDB_CODE_SUCCESS == code) { - code = translateScanPseudoColumnFunc(pCxt, ppNode); + bool bRewriteToColumn = false; + code = translateScanPseudoColumnFunc(pCxt, ppNode, &bRewriteToColumn); + if (bRewriteToColumn) { + return code; + } } if (TSDB_CODE_SUCCESS == code) { code = translateIndefiniteRowsFunc(pCxt, pFunc); @@ -2017,7 +2024,11 @@ static int32_t translateNormalFunction(STranslateContext* pCxt, SNode** ppNode) code = translateForbidFillFunc(pCxt, pFunc); } if (TSDB_CODE_SUCCESS == code) { - code = translateWindowPseudoColumnFunc(pCxt, ppNode); + bool bRewriteToColumn = false; + code = translateWindowPseudoColumnFunc(pCxt, ppNode, &bRewriteToColumn); + if (bRewriteToColumn) { + return code; + } } if (TSDB_CODE_SUCCESS == code) { code = translateForbidStreamFunc(pCxt, pFunc); @@ -2038,7 +2049,11 @@ static int32_t translateNormalFunction(STranslateContext* pCxt, SNode** ppNode) code = translateInterpFunc(pCxt, pFunc); } if (TSDB_CODE_SUCCESS == code) { - code = translateInterpPseudoColumnFunc(pCxt, ppNode); + bool bRewriteToColumn = false; + code = translateInterpPseudoColumnFunc(pCxt, ppNode, &bRewriteToColumn); + if (bRewriteToColumn) { + return code; + } } if (TSDB_CODE_SUCCESS == code) { code = translateTimelineFunc(pCxt, pFunc); From bc2cf345fade4301cba25785e98817d5cd0751fb Mon Sep 17 00:00:00 2001 From: slzhou Date: Tue, 10 Oct 2023 10:44:13 +0800 Subject: [PATCH 09/12] fix: change error code after replace column and translate --- source/libs/parser/src/parTranslater.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index e285c7a806..c1881e3d27 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -1973,7 +1973,11 @@ static int32_t translateWindowPseudoColumnFunc(STranslateContext* pCxt, SNode** return code; } translateColumn(pCxt, (SColumnNode**)ppNode); - return pCxt->errCode; + if (pCxt->errCode != TSDB_CODE_SUCCESS) { + return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_WINDOW_PC); + } else { + return TSDB_CODE_SUCCESS; + } } return TSDB_CODE_SUCCESS; } @@ -1994,7 +1998,11 @@ static int32_t translateScanPseudoColumnFunc(STranslateContext* pCxt, SNode** pp return code; } translateColumn(pCxt, (SColumnNode**)ppNode); - return pCxt->errCode; + if (pCxt->errCode != TSDB_CODE_SUCCESS) { + return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TBNAME); + } else { + return TSDB_CODE_SUCCESS; + } } } else { SValueNode* pVal = (SValueNode*)nodesListGetNode(pFunc->pParameterList, 0); From 1762a85127d8a16d6b34b51a4e64ca31981d421d Mon Sep 17 00:00:00 2001 From: slzhou Date: Tue, 10 Oct 2023 14:33:53 +0800 Subject: [PATCH 10/12] enhance: add test case --- tests/develop-test/2-query/pseudo_column.py | 81 +++++++++++++++++++++ tests/parallel_test/cases.task | 1 + 2 files changed, 82 insertions(+) create mode 100644 tests/develop-test/2-query/pseudo_column.py diff --git a/tests/develop-test/2-query/pseudo_column.py b/tests/develop-test/2-query/pseudo_column.py new file mode 100644 index 0000000000..9f6366a3c6 --- /dev/null +++ b/tests/develop-test/2-query/pseudo_column.py @@ -0,0 +1,81 @@ +import sys +from util.log import * +from util.cases import * +from util.sql import * +from util.dnodes import tdDnodes +from math import inf + +class TDTestCase: + def caseDescription(self): + ''' + case1: [TS-3904/TS-3005] pseudo column test case + ''' + return + + def init(self, conn, logSql, replicaVer=1): + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor(), True) + self._conn = conn + + def restartTaosd(self, index=1, dbname="db"): + tdDnodes.stop(index) + tdDnodes.startWithoutSleep(index) + tdSql.execute(f"use pseudo_col") + + def run(self): + print("running {}".format(__file__)) + tdSql.execute("drop database if exists pseudo_col") + tdSql.execute("create database if not exists pseudo_col") + tdSql.execute('use pseudo_col') + tdSql.execute('create table st(ts timestamp, f int) tags (t int)') + tdSql.execute("insert into ct1 using st tags(1) values('2023-10-10 14:10:00', 1)('2023-10-10 14:10:01', 11)") + tdSql.execute("insert into ct2 using st tags(2) values('2023-10-10 14:10:02', 2)('2023-10-10 14:10:03', 22)") + + tdSql.query('select tbname from (select tbname from st) order by tbname') + tdSql.checkCols(1) + tdSql.checkRows(4) + tdSql.checkData(0, 0, 'ct1') + tdSql.checkData(1, 0, 'ct1') + tdSql.checkData(2, 0, 'ct2') + tdSql.checkData(2, 0, 'ct2') + + tdSql.query('select `tbname` from (select tbname from st) order by tbname') + tdSql.checkCols(1) + tdSql.checkRows(4) + tdSql.checkData(0, 0, 'ct1') + tdSql.checkData(1, 0, 'ct1') + 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.checkCols(1) + tdSql.checkRows(4) + tdSql.checkData(0, 0, 'ct1') + tdSql.checkData(1, 0, 'ct1') + tdSql.checkData(2, 0, 'ct2') + tdSql.checkData(2, 0, 'ct2') + + 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') + + tdSql.query('select _wstart, _wend, _wduration, c from (select _wstart, _wend, _wduration, count(*) as c from st interval(1s)) order by _wstart') + tdSql.checkCols(4) + tdSql.checkRows(4) + tdSql.checkData(0, 1, '2023-10-10 14:10:01') + tdSql.checkData(0, 3, 1) + + tdSql.error('select _wstart, _wend, _wduration, c from (select count(*) as c from st) order by _wstart') + + tdSql.query("select _irowts, if2 from (select _irowts, interp(f) as if2 from st range('2023-10-10 14:10:00', '2023-10-10 14:10:10') every(1s) fill(value, 8))") + tdSql.checkRows(11) + tdSql.checkData(9, 1, 8); + tdSql.execute('drop database pseudo_col') + + tdSql.error("select _irowts, if2 from (select interp(f) as if2 from st range('2023-10-10 14:10:00', '2023-10-10 14:10:10') every(1s) fill(value, 8))") + def stop(self): + tdSql.close() + tdLog.success("%s successfully executed" % __file__) + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) diff --git a/tests/parallel_test/cases.task b/tests/parallel_test/cases.task index 36b8fded81..7afef03f0d 100644 --- a/tests/parallel_test/cases.task +++ b/tests/parallel_test/cases.task @@ -1263,6 +1263,7 @@ #develop test ,,n,develop-test,python3 ./test.py -f 2-query/table_count_scan.py +,,n,develop-test,python3 ./test.py -f 2-query/pseudo_column.py ,,n,develop-test,python3 ./test.py -f 2-query/show_create_db.py ,,n,develop-test,python3 ./test.py -f 5-taos-tools/taosbenchmark/auto_create_table_json.py ,,n,develop-test,python3 ./test.py -f 5-taos-tools/taosbenchmark/custom_col_tag.py From 1e1ed541fa83d900189e4c20b198c83eaf3e336c Mon Sep 17 00:00:00 2001 From: slzhou Date: Fri, 13 Oct 2023 08:11:15 +0800 Subject: [PATCH 11/12] fix: add more test case --- tests/develop-test/2-query/pseudo_column.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/develop-test/2-query/pseudo_column.py b/tests/develop-test/2-query/pseudo_column.py index 9f6366a3c6..4a97be6612 100644 --- a/tests/develop-test/2-query/pseudo_column.py +++ b/tests/develop-test/2-query/pseudo_column.py @@ -47,6 +47,14 @@ class TDTestCase: tdSql.checkData(2, 0, 'ct2') tdSql.checkData(2, 0, 'ct2') + tdSql.query('select `tbname` from (select tbname from st) order by tbname') + tdSql.checkCols(1) + tdSql.checkRows(4) + tdSql.checkData(0, 0, 'ct1') + tdSql.checkData(1, 0, 'ct1') + 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.checkCols(1) tdSql.checkRows(4) From d30c6f6bcc1e6a1102c57178a389b47b2976693c Mon Sep 17 00:00:00 2001 From: slzhou Date: Mon, 16 Oct 2023 13:56:15 +0800 Subject: [PATCH 12/12] fix: change tablename.tbname aliasname to tbname --- source/libs/parser/src/parAstCreater.c | 8 ++- source/libs/parser/src/parTranslater.c | 57 +++++++++++++-------- tests/develop-test/2-query/pseudo_column.py | 10 +++- 3 files changed, 48 insertions(+), 27 deletions(-) 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')