feat:[TS-5137] Support group/partition by position and alias.
This commit is contained in:
parent
0205291bcf
commit
04d525d429
|
@ -60,6 +60,7 @@ typedef struct SExprNode {
|
|||
bool orderAlias;
|
||||
bool asAlias;
|
||||
bool asParam;
|
||||
bool asPosition;
|
||||
} SExprNode;
|
||||
|
||||
typedef enum EColumnType {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -77,7 +77,7 @@ class TDTestCase:
|
|||
)
|
||||
query_condition.extend(
|
||||
(
|
||||
1010,
|
||||
1010.1,
|
||||
''' "test1234!@#$%^&*():'><?/.,][}{" ''',
|
||||
"null"
|
||||
)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -77,7 +77,7 @@ class TDTestCase:
|
|||
)
|
||||
query_condition.extend(
|
||||
(
|
||||
1010,
|
||||
1010.1,
|
||||
''' "test1234!@#$%^&*():'><?/.,][}{" ''',
|
||||
"null"
|
||||
)
|
||||
|
|
|
@ -75,7 +75,7 @@ class TDTestCase:
|
|||
)
|
||||
query_condition.extend(
|
||||
(
|
||||
1010,
|
||||
1010.1,
|
||||
)
|
||||
)
|
||||
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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; ')
|
||||
|
|
Loading…
Reference in New Issue