feat:[TS-5137] Support group/partition by position and alias.

This commit is contained in:
sima 2024-07-05 17:11:55 +08:00
parent 0205291bcf
commit 04d525d429
12 changed files with 336 additions and 38 deletions

View File

@ -60,6 +60,7 @@ typedef struct SExprNode {
bool orderAlias;
bool asAlias;
bool asParam;
bool asPosition;
} SExprNode;
typedef enum EColumnType {

View File

@ -229,6 +229,9 @@ static void checkParamIsFunc(SFunctionNode* pFunc) {
if (nodeType(pPara) == QUERY_NODE_COLUMN) {
((SColumnNode*)pPara)->node.asParam = true;
}
if (nodeType(pPara) == QUERY_NODE_VALUE) {
((SValueNode*)pPara)->node.asParam = true;
}
}
}

168
source/libs/parser/src/parTranslater.c Normal file → Executable file
View File

@ -1450,6 +1450,8 @@ static EDealRes translateColumnWithoutPrefix(STranslateContext* pCxt, SColumnNod
return DEAL_RES_CONTINUE;
}
static int32_t getFuncInfo(STranslateContext* pCxt, SFunctionNode* pFunc);
static EDealRes translateColumnUseAlias(STranslateContext* pCxt, SColumnNode** pCol, bool* pFound) {
SNodeList* pProjectionList = getProjectListFromCurrStmt(pCxt->pCurrStmt);
SNode* pNode;
@ -1470,6 +1472,25 @@ static EDealRes translateColumnUseAlias(STranslateContext* pCxt, SColumnNode** p
}
}
if (*pFound) {
if (QUERY_NODE_FUNCTION == nodeType(pFoundNode) && (SQL_CLAUSE_GROUP_BY == pCxt->currClause || SQL_CLAUSE_PARTITION_BY == pCxt->currClause)) {
pCxt->errCode = getFuncInfo(pCxt, (SFunctionNode*)pFoundNode);
if (TSDB_CODE_SUCCESS == pCxt->errCode) {
if (fmIsVectorFunc(((SFunctionNode*)pFoundNode)->funcId)) {
pCxt->errCode = TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION;
return DEAL_RES_ERROR;
} else if (fmIsPseudoColumnFunc(((SFunctionNode*)pFoundNode)->funcId)) {
if ('\0' != (*pCol)->tableAlias[0]) {
return translateColumnWithPrefix(pCxt, pCol);
} else {
return translateColumnWithoutPrefix(pCxt, pCol);
}
} else {
/* Do nothing and replace old node with found node. */
}
} else {
return DEAL_RES_ERROR;
}
}
SNode* pNew = NULL;
int32_t code = nodesCloneNode(pFoundNode, &pNew);
if (NULL == pNew) {
@ -1478,6 +1499,13 @@ static EDealRes translateColumnUseAlias(STranslateContext* pCxt, SColumnNode** p
}
nodesDestroyNode(*(SNode**)pCol);
*(SNode**)pCol = (SNode*)pNew;
if (QUERY_NODE_COLUMN == nodeType(pFoundNode)) {
if ('\0' != (*pCol)->tableAlias[0]) {
return translateColumnWithPrefix(pCxt, pCol);
} else {
return translateColumnWithoutPrefix(pCxt, pCol);
}
}
}
return DEAL_RES_CONTINUE;
}
@ -1716,6 +1744,12 @@ int32_t biCheckCreateTableTbnameCol(STranslateContext* pCxt, SCreateTableStmt* p
return TSDB_CODE_SUCCESS;
}
static bool clauseSupportAlias(ESqlClause clause) {
return SQL_CLAUSE_GROUP_BY == clause ||
SQL_CLAUSE_PARTITION_BY == clause ||
SQL_CLAUSE_ORDER_BY == clause;
}
static EDealRes translateColumn(STranslateContext* pCxt, SColumnNode** pCol) {
if (NULL == pCxt->pCurrStmt ||
(isSelectStmt(pCxt->pCurrStmt) && NULL == ((SSelectStmt*)pCxt->pCurrStmt)->pFromTable)) {
@ -1742,7 +1776,8 @@ static EDealRes translateColumn(STranslateContext* pCxt, SColumnNode** pCol) {
res = translateColumnWithPrefix(pCxt, pCol);
} else {
bool found = false;
if (SQL_CLAUSE_ORDER_BY == pCxt->currClause && !(*pCol)->node.asParam) {
if ((clauseSupportAlias(pCxt->currClause)) &&
!(*pCol)->node.asParam) {
res = translateColumnUseAlias(pCxt, pCol, &found);
}
if (DEAL_RES_ERROR != res && !found) {
@ -1752,7 +1787,9 @@ static EDealRes translateColumn(STranslateContext* pCxt, SColumnNode** pCol) {
res = translateColumnWithoutPrefix(pCxt, pCol);
}
}
if (SQL_CLAUSE_ORDER_BY == pCxt->currClause && !(*pCol)->node.asParam && res != DEAL_RES_CONTINUE &&
if (clauseSupportAlias(pCxt->currClause) &&
!(*pCol)->node.asParam &&
res != DEAL_RES_CONTINUE &&
res != DEAL_RES_END) {
res = translateColumnUseAlias(pCxt, pCol, &found);
}
@ -2954,6 +2991,13 @@ static EDealRes translateFunction(STranslateContext* pCxt, SFunctionNode** pFunc
}
pCxt->errCode = getFuncInfo(pCxt, *pFunc);
if (TSDB_CODE_SUCCESS == pCxt->errCode) {
if ((SQL_CLAUSE_GROUP_BY == pCxt->currClause ||
SQL_CLAUSE_PARTITION_BY == pCxt->currClause) &&
fmIsVectorFunc((*pFunc)->funcId)) {
pCxt->errCode = TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION;
}
}
if (TSDB_CODE_SUCCESS == pCxt->errCode) {
pCxt->errCode = translateFunctionImpl(pCxt, pFunc);
}
@ -4940,7 +4984,7 @@ static int32_t getPositionValue(const SValueNode* pVal) {
case TSDB_DATA_TYPE_GEOMETRY:
return -1;
case TSDB_DATA_TYPE_BOOL:
return (pVal->datum.b ? 1 : 0);
return -1;
case TSDB_DATA_TYPE_TINYINT:
case TSDB_DATA_TYPE_SMALLINT:
case TSDB_DATA_TYPE_INT:
@ -4948,7 +4992,7 @@ static int32_t getPositionValue(const SValueNode* pVal) {
return pVal->datum.i;
case TSDB_DATA_TYPE_FLOAT:
case TSDB_DATA_TYPE_DOUBLE:
return pVal->datum.d;
return -1;
case TSDB_DATA_TYPE_UTINYINT:
case TSDB_DATA_TYPE_USMALLINT:
case TSDB_DATA_TYPE_UINT:
@ -4960,25 +5004,36 @@ static int32_t getPositionValue(const SValueNode* pVal) {
return -1;
}
static int32_t translateOrderByPosition(STranslateContext* pCxt, SNodeList* pProjectionList, SNodeList* pOrderByList,
static int32_t translateClausePosition(STranslateContext* pCxt, SNodeList* pProjectionList, SNodeList* pClauseList,
bool* pOther) {
*pOther = false;
SNode* pNode = NULL;
WHERE_EACH(pNode, pOrderByList) {
SNode* pExpr = ((SOrderByExprNode*)pNode)->pExpr;
WHERE_EACH(pNode, pClauseList) {
SNode* pExpr = NULL;
switch (pNode->type) {
case QUERY_NODE_GROUPING_SET:
pExpr = getGroupByNode(pNode);
break;
case QUERY_NODE_ORDER_BY_EXPR:
pExpr = ((SOrderByExprNode*)pNode)->pExpr;
break;
default:
pExpr = pNode;
break;
}
if (QUERY_NODE_VALUE == nodeType(pExpr)) {
SValueNode* pVal = (SValueNode*)pExpr;
pVal->node.asPosition = false;
if (DEAL_RES_ERROR == translateValue(pCxt, pVal)) {
return pCxt->errCode;
}
int32_t pos = getPositionValue(pVal);
if (pos < 0) {
ERASE_NODE(pOrderByList);
continue;
pVal->node.asPosition = false;
} else if (0 == pos || pos > LIST_LENGTH(pProjectionList)) {
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT);
} else {
// No longer using SColumnRefNode, processing in replaceOrderByAliasImpl function
pVal->node.asPosition = true;
}
} else {
*pOther = true;
@ -4990,7 +5045,7 @@ static int32_t translateOrderByPosition(STranslateContext* pCxt, SNodeList* pPro
static int32_t translateOrderBy(STranslateContext* pCxt, SSelectStmt* pSelect) {
bool other;
int32_t code = translateOrderByPosition(pCxt, pSelect->pProjectionList, pSelect->pOrderByList, &other);
int32_t code = translateClausePosition(pCxt, pSelect->pProjectionList, pSelect->pOrderByList, &other);
if (TSDB_CODE_SUCCESS == code) {
if (0 == LIST_LENGTH(pSelect->pOrderByList)) {
NODES_DESTORY_LIST(pSelect->pOrderByList);
@ -5121,6 +5176,68 @@ static int32_t translateProjectionList(STranslateContext* pCxt, SSelectStmt* pSe
}
}
typedef struct SReplaceGroupByAliasCxt {
STranslateContext* pTranslateCxt;
SNodeList* pProjectionList;
} SReplaceGroupByAliasCxt;
static EDealRes replaceGroupByAliasImpl(SNode** pNode, void* pContext) {
SReplaceGroupByAliasCxt* pCxt = pContext;
SNodeList* pProjectionList = pCxt->pProjectionList;
SNode* pProject = NULL;
if (QUERY_NODE_VALUE == nodeType(*pNode)) {
STranslateContext* pTransCxt = pCxt->pTranslateCxt;
SValueNode* pVal = (SValueNode*) *pNode;
if (DEAL_RES_ERROR == translateValue(pTransCxt, pVal)) {
return DEAL_RES_CONTINUE;
}
if (!pVal->node.asPosition) {
return DEAL_RES_CONTINUE;
}
int32_t pos = getPositionValue(pVal);
if (0 < pos && pos <= LIST_LENGTH(pProjectionList)) {
SNode* pNew = NULL;
int32_t code = nodesCloneNode(nodesListGetNode(pProjectionList, pos - 1), (SNode**)&pNew);
if (TSDB_CODE_SUCCESS != code) {
pCxt->pTranslateCxt->errCode = code;
return DEAL_RES_ERROR;
}
nodesDestroyNode(*pNode);
*pNode = pNew;
return DEAL_RES_CONTINUE;
} else {
return DEAL_RES_CONTINUE;
}
} else if (QUERY_NODE_COLUMN == nodeType(*pNode)) {
STranslateContext* pTransCxt = pCxt->pTranslateCxt;
return translateColumn(pTransCxt, (SColumnNode**)pNode);
}
return DEAL_RES_CONTINUE;
}
static int32_t replaceGroupByAlias(STranslateContext* pCxt, SSelectStmt* pSelect) {
if (NULL == pSelect->pGroupByList) {
return TSDB_CODE_SUCCESS;
}
SReplaceGroupByAliasCxt cxt = {
.pTranslateCxt = pCxt, .pProjectionList = pSelect->pProjectionList};
nodesRewriteExprsPostOrder(pSelect->pGroupByList, replaceGroupByAliasImpl, &cxt);
return pCxt->errCode;
}
static int32_t replacePartitionByAlias(STranslateContext* pCxt, SSelectStmt* pSelect) {
if (NULL == pSelect->pPartitionByList) {
return TSDB_CODE_SUCCESS;
}
SReplaceGroupByAliasCxt cxt = {
.pTranslateCxt = pCxt, .pProjectionList = pSelect->pProjectionList};
nodesRewriteExprsPostOrder(pSelect->pPartitionByList, replaceGroupByAliasImpl, &cxt);
return pCxt->errCode;
}
static int32_t translateSelectList(STranslateContext* pCxt, SSelectStmt* pSelect) {
pCxt->currClause = SQL_CLAUSE_SELECT;
int32_t code = translateExprList(pCxt, pSelect->pProjectionList);
@ -5172,9 +5289,21 @@ static int32_t translateGroupBy(STranslateContext* pCxt, SSelectStmt* pSelect) {
if (NULL != pSelect->pWindow) {
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_GROUPBY_WINDOW_COEXIST);
}
bool other;
int32_t code = translateClausePosition(pCxt, pSelect->pProjectionList, pSelect->pGroupByList, &other);
if (TSDB_CODE_SUCCESS == code) {
if (0 == LIST_LENGTH(pSelect->pGroupByList)) {
NODES_DESTORY_LIST(pSelect->pGroupByList);
return TSDB_CODE_SUCCESS;
}
code = replaceGroupByAlias(pCxt, pSelect);
}
if (TSDB_CODE_SUCCESS == code) {
pCxt->currClause = SQL_CLAUSE_GROUP_BY;
pSelect->timeLineResMode = TIME_LINE_NONE;
return translateExprList(pCxt, pSelect->pGroupByList);
code = translateExprList(pCxt, pSelect->pGroupByList);
}
return code;
}
static int32_t getTimeRange(SNode** pPrimaryKeyCond, STimeWindow* pTimeRange, bool* pIsStrict) {
@ -5781,7 +5910,8 @@ static int32_t translatePartitionBy(STranslateContext* pCxt, SSelectStmt* pSelec
int32_t code = TSDB_CODE_SUCCESS;
if (pSelect->pPartitionByList) {
code = removeConstantValueFromList(&pSelect->pPartitionByList);
bool other;
code = translateClausePosition(pCxt, pSelect->pProjectionList, pSelect->pPartitionByList, &other);
}
if (TSDB_CODE_SUCCESS == code && pSelect->pPartitionByList) {
@ -5791,9 +5921,11 @@ static int32_t translatePartitionBy(STranslateContext* pCxt, SSelectStmt* pSelec
(QUERY_NODE_FUNCTION == nodeType(pPar) && FUNCTION_TYPE_TBNAME == ((SFunctionNode*)pPar)->funcType))) {
pSelect->timeLineResMode = TIME_LINE_MULTI;
}
code = replacePartitionByAlias(pCxt, pSelect);
if (TSDB_CODE_SUCCESS == code) {
code = translateExprList(pCxt, pSelect->pPartitionByList);
}
}
if (TSDB_CODE_SUCCESS == code) {
code = translateExprList(pCxt, pSelect->pTags);
}
@ -6519,7 +6651,11 @@ static int32_t translateSelectFrom(STranslateContext* pCxt, SSelectStmt* pSelect
code = removeConstantValueFromList(&pSelect->pPartitionByList);
}
}
if (TSDB_CODE_SUCCESS == code) {
if (pSelect->pGroupByList) {
code = removeConstantValueFromList(&pSelect->pGroupByList);
}
}
return code;
}
@ -6606,7 +6742,7 @@ static int32_t translateSetOperOrderBy(STranslateContext* pCxt, SSetOperator* pS
}
bool other;
int32_t code = translateOrderByPosition(pCxt, pSetOperator->pProjectionList, pSetOperator->pOrderByList, &other);
int32_t code = translateClausePosition(pCxt, pSetOperator->pProjectionList, pSetOperator->pOrderByList, &other);
/*
if (TSDB_CODE_SUCCESS == code) {
if (other) {

View File

@ -44,7 +44,7 @@ static char* getSyntaxErrFormat(int32_t errCode) {
case TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION:
return "There mustn't be aggregation";
case TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT:
return "ORDER BY item must be the number of a SELECT-list expression";
return "ORDER BY / GROUP BY item must be the number of a SELECT-list expression";
case TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION:
return "Not a GROUP BY expression";
case TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION:

View File

@ -595,7 +595,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_PAR_TABLE_NOT_EXIST, "Table does not exist
TAOS_DEFINE_ERROR(TSDB_CODE_PAR_AMBIGUOUS_COLUMN, "Column ambiguously defined")
TAOS_DEFINE_ERROR(TSDB_CODE_PAR_WRONG_VALUE_TYPE, "Invalid value type")
TAOS_DEFINE_ERROR(TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION, "There mustn't be aggregation")
TAOS_DEFINE_ERROR(TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT, "ORDER BY item must be the number of a SELECT-list expression")
TAOS_DEFINE_ERROR(TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT, "ORDER BY / GROUP BY item must be the number of a SELECT-list expression")
TAOS_DEFINE_ERROR(TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION, "Not a GROUP BY expression")
TAOS_DEFINE_ERROR(TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION, "Not SELECTed expression")
TAOS_DEFINE_ERROR(TSDB_CODE_PAR_NOT_SINGLE_GROUP, "Not a single-group group function")

View File

@ -144,8 +144,8 @@ class TDTestCase:
tdSql.query(f"select distinct c1, c2 from (select c2, c1 from {dbname}.stb1 where c1 > 2 order by ts)")
tdSql.query(f"select distinct c1, c2 from (select c2, c1 from {dbname}.t1 where c1 > 2 order by ts)")
tdSql.error(f"select distinct c1, c2 from (select c2, c1 from {dbname}.stb1 where c1 > 2 group by c1)")
tdSql.query(f"select distinct c1, c2 from (select max(c1) c1, max(c2) c2 from {dbname}.stb1 group by c1)")
tdSql.query(f"select distinct c1, c2 from (select max(c1) c1, max(c2) c2 from {dbname}.t1 group by c1)")
tdSql.query(f"select distinct c1, c2 from (select max(c1) c1, max(c2) c2 from {dbname}.stb1 group by stb1.c1)")
tdSql.query(f"select distinct c1, c2 from (select max(c1) c1, max(c2) c2 from {dbname}.t1 group by t1.c1)")
tdSql.query(f"select distinct c1, c2 from (select max(c1) c1, max(c2) c2 from {dbname}.stb1 )")
tdSql.checkRows(1)
tdSql.query(f"select distinct c1, c2 from (select max(c1) c1, max(c2) c2 from {dbname}.t1 )")
@ -245,7 +245,7 @@ class TDTestCase:
tdSql.query(f"select distinct t1 from (select t0, t1 from {dbname}.stb1 where t0 > 2 ) where t1 < 3")
tdSql.checkRows(1)
tdSql.error(f"select distinct t1, t0 from (select t1 from {dbname}.stb1 where t0 > 2 ) where t1 < 3")
tdSql.query(f"select distinct t1, t0 from (select max(t1) t1, max(t0) t0 from {dbname}.stb1 group by t1)")
tdSql.query(f"select distinct t1, t0 from (select max(t1) t1, max(t0) t0 from {dbname}.stb1 group by stb1.t1)")
tdSql.query(f"select distinct t1, t0 from (select max(t1) t1, max(t0) t0 from {dbname}.stb1)")
tdSql.query(f"select distinct t1, t0 from (select t1,t0 from {dbname}.stb1 where t0 > 2 ) where t1 < 3")
tdSql.checkRows(1)

View File

@ -77,7 +77,7 @@ class TDTestCase:
)
query_condition.extend(
(
1010,
1010.1,
''' "test1234!@#$%^&*():'><?/.,][}{" ''',
"null"
)

View File

@ -97,6 +97,157 @@ class TDTestCase:
tdSql.query(f"select t2, t3, c1, count(*) from {self.dbname}.{self.stable} {keyword} by t2, t3, c1 ")
tdSql.checkRows(nonempty_tb_num * self.row_nums)
def test_groupby_position(self, keyword, check_num, nonempty_tb_num):
####### by tbname
tdSql.query(f"select tbname, count(*) from {self.dbname}.{self.stable} {keyword} by 1 ")
tdSql.checkRows(check_num)
tdSql.query(f"select tbname from {self.dbname}.{self.stable} {keyword} by 1 order by count(*)")
tdSql.checkRows(check_num)
# last
tdSql.query(f"select tbname from {self.dbname}.{self.stable} {keyword} by 1 having count(*)>=0")
tdSql.checkRows(check_num)
# having filter out empty
tdSql.query(f"select tbname, count(*) from {self.dbname}.{self.stable} {keyword} by 1 having count(*) <= 0")
tdSql.checkRows(check_num - nonempty_tb_num)
####### by tag
tdSql.query(f"select t2, count(*), count(1), count(c1) from {self.dbname}.{self.stable} {keyword} by 1 ")
tdSql.checkRows(check_num)
tdSql.query(f"select t2, count(*) from {self.dbname}.{self.stable} {keyword} by 1 having count(*) <= 0")
tdSql.checkRows(check_num - nonempty_tb_num)
# where
tdSql.query(f"select t2, count(*) from {self.dbname}.{self.stable} where ts < now {keyword} by 1 ")
tdSql.checkRows(check_num)
tdSql.query(f"select t2, count(*) from {self.dbname}.{self.stable} where ts > 1737146000000 {keyword} by 1 ")
tdSql.checkRows(check_num)
tdSql.query(f"select t2, count(*) from {self.dbname}.{self.stable} where c1 = 1 {keyword} by 1 ")
tdSql.checkRows(check_num)
####### by col
tdSql.query(f"select c1, count(*), count(1), count(c1) from {self.dbname}.{self.stable} {keyword} by 1 ")
num = 0
if nonempty_tb_num > 0:
num = self.row_nums
tdSql.checkRows(num)
tdSql.query(f"select ts, count(*) from {self.dbname}.{self.stable} {keyword} by 1 ")
tdSql.checkRows(nonempty_tb_num * self.row_nums)
# col + tag
tdSql.query(f"select t2, c1, count(*) from {self.dbname}.{self.stable} {keyword} by 1, 2 ")
tdSql.checkRows(nonempty_tb_num * self.row_nums)
tdSql.query(f"select t2, c1, count(*) from {self.dbname}.{self.stable} {keyword} by 1, c1 ")
tdSql.checkRows(nonempty_tb_num * self.row_nums)
tdSql.query(f"select t2, c1, count(*) from {self.dbname}.{self.stable} {keyword} by t2, 2 ")
tdSql.checkRows(nonempty_tb_num * self.row_nums)
tdSql.query(f"select t2, t3, c1, count(*) from {self.dbname}.{self.stable} {keyword} by 1, 2, 3 ")
tdSql.checkRows(nonempty_tb_num * self.row_nums)
tdSql.query(f"select t2, t3, c1, count(*) from {self.dbname}.{self.stable} {keyword} by t2, 2, 3 ")
tdSql.checkRows(nonempty_tb_num * self.row_nums)
tdSql.query(f"select t2, t3, c1, count(*) from {self.dbname}.{self.stable} {keyword} by 1, t3, 3 ")
tdSql.checkRows(nonempty_tb_num * self.row_nums)
tdSql.query(f"select sum(t0.sumc2) from (select c1, sum(c2) as sumc2 from {self.dbname}.{self.stable} {keyword} by 1) t0")
num = 0
if nonempty_tb_num > 0:
num = 1
tdSql.checkRows(num)
tdSql.query(f"select abs(c1), count(*) from {self.dbname}.{self.stable} {keyword} by 1")
num = 0
if nonempty_tb_num > 0:
num = self.row_nums
tdSql.checkRows(num)
####### error case
tdSql.error(f"select c1, count(*) from {self.dbname}.{self.stable} {keyword} by 10")
tdSql.error(f"select c1, count(*) from {self.dbname}.{self.stable} {keyword} by 0")
tdSql.error(f"select c1, c2, count(*) from {self.dbname}.{self.stable} {keyword} by 0, 1")
tdSql.error(f"select c1, count(*) from {self.dbname}.{self.stable} {keyword} by 1.2")
tdSql.error(f"select c1, c2, c3, count(*) from {self.dbname}.{self.stable} {keyword} by 1, 2.2, 3")
tdSql.error(f"select c1, c2, count(*) from {self.dbname}.{self.stable} {keyword} by 1")
tdSql.error(f"select c1, avg(c2), count(*) from {self.dbname}.{self.stable} {keyword} by 1, 2")
def test_groupby_alias(self, keyword, check_num, nonempty_tb_num):
tdSql.query(f"select t1 as t1_alias, count(*) from {self.dbname}.{self.stable} {keyword} by t1_alias ")
tdSql.checkRows(check_num)
tdSql.query(f"select t1 as t1_alias from {self.dbname}.{self.stable} {keyword} by t1_alias order by count(*)")
tdSql.checkRows(check_num)
# last
tdSql.query(f"select t1 as t1_alias from {self.dbname}.{self.stable} {keyword} by t1_alias having count(*)>=0")
tdSql.checkRows(check_num)
# having filter out empty
tdSql.query(f"select t1 as t1_alias, count(*) from {self.dbname}.{self.stable} {keyword} by t1_alias having count(*) <= 0")
tdSql.checkRows(check_num - nonempty_tb_num)
####### by tag
tdSql.query(f"select t2 as t2_alias, count(*), count(1), count(c1) from {self.dbname}.{self.stable} {keyword} by t2_alias ")
tdSql.checkRows(check_num)
tdSql.query(f"select t2 as t2_alias, count(*) from {self.dbname}.{self.stable} {keyword} by t2_alias having count(*) <= 0")
tdSql.checkRows(check_num - nonempty_tb_num)
# where
tdSql.query(f"select t2 as t2_alias, count(*) from {self.dbname}.{self.stable} where ts < now {keyword} by t2_alias ")
tdSql.checkRows(check_num)
tdSql.query(f"select t2 as t2_alias, count(*) from {self.dbname}.{self.stable} where ts > 1737146000000 {keyword} by t2_alias ")
tdSql.checkRows(check_num)
tdSql.query(f"select t2 as t2_alias, count(*) from {self.dbname}.{self.stable} where c1 = 1 {keyword} by t2_alias ")
tdSql.checkRows(check_num)
####### by col
tdSql.query(f"select c1 as c1_alias, count(*), count(1), count(c1) from {self.dbname}.{self.stable} {keyword} by c1_alias ")
num = 0
if nonempty_tb_num > 0:
num = self.row_nums
tdSql.checkRows(num)
tdSql.query(f"select ts as ts_alias, count(*) from {self.dbname}.{self.stable} {keyword} by ts_alias ")
tdSql.checkRows(nonempty_tb_num * self.row_nums)
# col + tag
tdSql.query(f"select t2 as t2_alias, c1 as c1_alias, count(*) from {self.dbname}.{self.stable} {keyword} by 1, 2 ")
tdSql.checkRows(nonempty_tb_num * self.row_nums)
tdSql.query(f"select t2 as t2_alias, c1 as c1_alias, count(*) from {self.dbname}.{self.stable} {keyword} by 1, c1 ")
tdSql.checkRows(nonempty_tb_num * self.row_nums)
tdSql.query(f"select t2 as t2_alias, c1 as c1_alias, count(*) from {self.dbname}.{self.stable} {keyword} by t2, 2 ")
tdSql.checkRows(nonempty_tb_num * self.row_nums)
tdSql.query(f"select t2 as t2_alias, t3 as t3_alias, c1 as c1_alias, count(*) from {self.dbname}.{self.stable} {keyword} by t2_alias, t3_alias, 3 ")
tdSql.checkRows(nonempty_tb_num * self.row_nums)
tdSql.query(f"select t2 as t2_alias, t3 as t3_alias, c1 as c1_alias, count(*) from {self.dbname}.{self.stable} {keyword} by t2, t3_alias, c1_alias ")
tdSql.checkRows(nonempty_tb_num * self.row_nums)
tdSql.query(f"select t2 as t2_alias, t3 as t3_alias, c1 as c1_alias, count(*) from {self.dbname}.{self.stable} {keyword} by t2_alias, t3, c1_alias ")
tdSql.checkRows(nonempty_tb_num * self.row_nums)
tdSql.query(f"select sum(t0.sumc2) from (select c1 as c1_alias, sum(c2) as sumc2 from {self.dbname}.{self.stable} {keyword} by c1_alias) t0")
num = 0
if nonempty_tb_num > 0:
num = 1
tdSql.checkRows(num)
tdSql.query(f"select abs(c1) as abs_alias, count(*) from {self.dbname}.{self.stable} {keyword} by abs_alias")
num = 0
if nonempty_tb_num > 0:
num = self.row_nums
tdSql.checkRows(num)
####### error case
tdSql.error(f"select c1, avg(c2) as avg_alias, count(*) from {self.dbname}.{self.stable} {keyword} by 1, avg_alias")
def test_groupby_sub_table(self):
for i in range(self.tb_nums):
tbname = f"{self.dbname}.sub_{self.stable}_{i}"
@ -276,6 +427,10 @@ class TDTestCase:
# empty table only
self.test_groupby('group', self.tb_nums, 0)
self.test_groupby('partition', self.tb_nums, 0)
self.test_groupby_position('group', self.tb_nums, 0)
self.test_groupby_position('partition', self.tb_nums, 0)
self.test_groupby_alias('group', self.tb_nums, 0)
self.test_groupby_alias('partition', self.tb_nums, 0)
self.test_innerSelect(self.tb_nums)
self.test_multi_group_key(self.tb_nums, 0)
self.test_multi_agg(self.tb_nums, 0)
@ -287,6 +442,10 @@ class TDTestCase:
self.test_groupby('group', self.tb_nums, nonempty_tb_num)
self.test_groupby('partition', self.tb_nums, nonempty_tb_num)
self.test_groupby_position('group', self.tb_nums, nonempty_tb_num)
self.test_groupby_position('partition', self.tb_nums, nonempty_tb_num)
self.test_groupby_alias('group', self.tb_nums, nonempty_tb_num)
self.test_groupby_alias('partition', self.tb_nums, nonempty_tb_num)
self.test_groupby_sub_table()
self.test_innerSelect(self.tb_nums)
self.test_multi_group_key(self.tb_nums, nonempty_tb_num)

View File

@ -77,7 +77,7 @@ class TDTestCase:
)
query_condition.extend(
(
1010,
1010.1,
''' "test1234!@#$%^&*():'><?/.,][}{" ''',
"null"
)

View File

@ -75,7 +75,7 @@ class TDTestCase:
)
query_condition.extend(
(
1010,
1010.1,
)
)

View File

@ -42,8 +42,7 @@ class TDTestCase:
sum_condition.extend( f"{num_col} + {num_col_2}" for num_col_2 in NUM_COL )
sum_condition.extend( f"{num_col} + {un_num_col} " for un_num_col in UN_NUM_COL )
sum_condition.append(1)
sum_condition.append(1.1)
return sum_condition
def __where_condition(self, col):

View File

@ -20,32 +20,32 @@ class TDTestCase:
tdSql.execute("insert into td_28068.ct4 using td_28068.st (branch, scenario) tags ('3.1', 'scenario2') values (1717122950000, 'query1', 9,10);")
def run(self):
tdSql.query('select last(ts) as ts, last(branch) as branch, last(scenario) as scenario, last(test_case) as test_case from td_28068.st group by branch, scenario order by last(branch);')
tdSql.query('select last(ts) as ts, last(branch) as branch, last(scenario) as scenario, last(test_case) as test_case from td_28068.st group by st.branch, st.scenario order by last(branch);')
tdSql.checkRows(4)
tdSql.query('select last(ts) as ts, last(branch) as branch1, last(scenario) as scenario, last(test_case) as test_case from td_28068.st group by branch, scenario order by last(branch), last(scenario); ')
tdSql.query('select last(ts) as ts, last(branch) as branch1, last(scenario) as scenario, last(test_case) as test_case from td_28068.st group by st.branch, st.scenario order by last(branch), last(scenario); ')
tdSql.checkRows(4)
tdSql.query('select last(ts) as ts, last(branch) as branch1, last(scenario) as scenario, last(test_case) as test_case from td_28068.st group by branch, scenario order by last(branch); ')
tdSql.query('select last(ts) as ts, last(branch) as branch1, last(scenario) as scenario, last(test_case) as test_case from td_28068.st group by st.branch, st.scenario order by last(branch); ')
tdSql.checkRows(4)
tdSql.query('select last(ts) as ts, last(branch) as branch1, last(scenario) as scenario, last(test_case) from td_28068.st group by branch, scenario order by last(branch), last(test_case);')
tdSql.query('select last(ts) as ts, last(branch) as branch1, last(scenario) as scenario, last(test_case) from td_28068.st group by st.branch, st.scenario order by last(branch), last(test_case);')
tdSql.checkRows(4)
tdSql.query('select last(ts) as ts, last(branch) as branch1, last(scenario) as scenario1, last(test_case) as test_case from td_28068.st group by branch, scenario order by last(branch), last(scenario);')
tdSql.query('select last(ts) as ts, last(branch) as branch1, last(scenario) as scenario1, last(test_case) as test_case from td_28068.st group by st.branch, st.scenario order by last(branch), last(scenario);')
tdSql.checkRows(4)
tdSql.query('select last(ts) as ts, last(branch) as branch1, last(scenario) as scenario1, last(test_case) as test_case from td_28068.st group by branch, scenario order by branch1, scenario1;')
tdSql.query('select last(ts) as ts, last(branch) as branch1, last(scenario) as scenario1, last(test_case) as test_case from td_28068.st group by st.branch, st.scenario order by branch1, scenario1;')
tdSql.checkRows(4)
tdSql.query('select last(ts) as ts, last(branch) as branch1, last(scenario) as scenario1, last(test_case) as test_case from td_28068.st group by tbname; ')
tdSql.checkRows(4)
tdSql.query('select last(ts) as ts, last(branch) as branch1, last(scenario) as scenario1, last(test_case) as test_case from td_28068.st group by branch, scenario order by test_case;')
tdSql.query('select last(ts) as ts, last(branch) as branch1, last(scenario) as scenario1, last(test_case) as test_case from td_28068.st group by st.branch, st.scenario order by test_case;')
tdSql.checkRows(4)
tdSql.query('select last(ts) as ts, last(branch) as branch1, last(scenario) as scenario1, last(test_case) as test_case1 from td_28068.st group by branch, scenario order by last(test_case);')
tdSql.query('select last(ts) as ts, last(branch) as branch1, last(scenario) as scenario1, last(test_case) as test_case1 from td_28068.st group by st.branch, st.scenario order by last(test_case);')
tdSql.checkRows(4)
tdSql.query('select time_cost, num, time_cost + num as final_cost from td_28068.st partition by branch; ')
tdSql.query('select time_cost, num, time_cost + num as final_cost from td_28068.st partition by st.branch; ')
tdSql.checkRows(8)
tdSql.query('select count(*) from td_28068.st partition by branch order by branch; ')