Merge pull request #15711 from taosdata/feature/3.0_wxy
fix: timeline function validity check
This commit is contained in:
commit
e9fc948097
|
@ -114,6 +114,7 @@ typedef struct SAggLogicNode {
|
|||
SNodeList* pAggFuncs;
|
||||
bool hasLastRow;
|
||||
bool hasTimeLineFunc;
|
||||
bool onlyHasKeepOrderFunc;
|
||||
} SAggLogicNode;
|
||||
|
||||
typedef struct SProjectLogicNode {
|
||||
|
|
|
@ -269,6 +269,7 @@ typedef struct SSelectStmt {
|
|||
bool hasInterpFunc;
|
||||
bool hasLastRowFunc;
|
||||
bool hasTimeLineFunc;
|
||||
bool onlyHasKeepOrderFunc;
|
||||
bool groupSort;
|
||||
} SSelectStmt;
|
||||
|
||||
|
|
|
@ -2246,7 +2246,8 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
{
|
||||
.name = "derivative",
|
||||
.type = FUNCTION_TYPE_DERIVATIVE,
|
||||
.classification = FUNC_MGT_INDEFINITE_ROWS_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC | FUNC_MGT_CUMULATIVE_FUNC | FUNC_MGT_FORBID_STREAM_FUNC,
|
||||
.classification = FUNC_MGT_INDEFINITE_ROWS_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC |
|
||||
FUNC_MGT_KEEP_ORDER_FUNC | FUNC_MGT_CUMULATIVE_FUNC | FUNC_MGT_FORBID_STREAM_FUNC,
|
||||
.translateFunc = translateDerivative,
|
||||
.getEnvFunc = getDerivativeFuncEnv,
|
||||
.initFunc = derivativeFuncSetup,
|
||||
|
@ -2453,7 +2454,8 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
{
|
||||
.name = "diff",
|
||||
.type = FUNCTION_TYPE_DIFF,
|
||||
.classification = FUNC_MGT_INDEFINITE_ROWS_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_FORBID_STREAM_FUNC | FUNC_MGT_CUMULATIVE_FUNC,
|
||||
.classification = FUNC_MGT_INDEFINITE_ROWS_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_KEEP_ORDER_FUNC |
|
||||
FUNC_MGT_FORBID_STREAM_FUNC | FUNC_MGT_CUMULATIVE_FUNC,
|
||||
.translateFunc = translateDiff,
|
||||
.getEnvFunc = getDiffFuncEnv,
|
||||
.initFunc = diffFunctionSetup,
|
||||
|
@ -2487,7 +2489,8 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
{
|
||||
.name = "csum",
|
||||
.type = FUNCTION_TYPE_CSUM,
|
||||
.classification = FUNC_MGT_INDEFINITE_ROWS_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_FORBID_STREAM_FUNC | FUNC_MGT_CUMULATIVE_FUNC,
|
||||
.classification = FUNC_MGT_INDEFINITE_ROWS_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_TIMELINE_FUNC |
|
||||
FUNC_MGT_FORBID_STREAM_FUNC | FUNC_MGT_CUMULATIVE_FUNC | FUNC_MGT_KEEP_ORDER_FUNC,
|
||||
.translateFunc = translateCsum,
|
||||
.getEnvFunc = getCsumFuncEnv,
|
||||
.initFunc = functionSetup,
|
||||
|
@ -2856,7 +2859,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
{
|
||||
.name = "tbname",
|
||||
.type = FUNCTION_TYPE_TBNAME,
|
||||
.classification = FUNC_MGT_PSEUDO_COLUMN_FUNC | FUNC_MGT_SCAN_PC_FUNC,
|
||||
.classification = FUNC_MGT_PSEUDO_COLUMN_FUNC | FUNC_MGT_SCAN_PC_FUNC | FUNC_MGT_KEEP_ORDER_FUNC,
|
||||
.translateFunc = translateTbnameColumn,
|
||||
.getEnvFunc = NULL,
|
||||
.initFunc = NULL,
|
||||
|
@ -2896,7 +2899,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
{
|
||||
.name = "_wstart",
|
||||
.type = FUNCTION_TYPE_WSTART,
|
||||
.classification = FUNC_MGT_PSEUDO_COLUMN_FUNC | FUNC_MGT_WINDOW_PC_FUNC,
|
||||
.classification = FUNC_MGT_PSEUDO_COLUMN_FUNC | FUNC_MGT_WINDOW_PC_FUNC | FUNC_MGT_KEEP_ORDER_FUNC,
|
||||
.translateFunc = translateTimePseudoColumn,
|
||||
.getEnvFunc = getTimePseudoFuncEnv,
|
||||
.initFunc = NULL,
|
||||
|
@ -2906,7 +2909,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
{
|
||||
.name = "_wend",
|
||||
.type = FUNCTION_TYPE_WEND,
|
||||
.classification = FUNC_MGT_PSEUDO_COLUMN_FUNC | FUNC_MGT_WINDOW_PC_FUNC,
|
||||
.classification = FUNC_MGT_PSEUDO_COLUMN_FUNC | FUNC_MGT_WINDOW_PC_FUNC | FUNC_MGT_KEEP_ORDER_FUNC,
|
||||
.translateFunc = translateTimePseudoColumn,
|
||||
.getEnvFunc = getTimePseudoFuncEnv,
|
||||
.initFunc = NULL,
|
||||
|
@ -2916,7 +2919,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
{
|
||||
.name = "_wduration",
|
||||
.type = FUNCTION_TYPE_WDURATION,
|
||||
.classification = FUNC_MGT_PSEUDO_COLUMN_FUNC | FUNC_MGT_WINDOW_PC_FUNC,
|
||||
.classification = FUNC_MGT_PSEUDO_COLUMN_FUNC | FUNC_MGT_WINDOW_PC_FUNC | FUNC_MGT_KEEP_ORDER_FUNC,
|
||||
.translateFunc = translateWduration,
|
||||
.getEnvFunc = getTimePseudoFuncEnv,
|
||||
.initFunc = NULL,
|
||||
|
@ -2964,7 +2967,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
{
|
||||
.name = "_group_key",
|
||||
.type = FUNCTION_TYPE_GROUP_KEY,
|
||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC,
|
||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_KEEP_ORDER_FUNC,
|
||||
.translateFunc = translateGroupKey,
|
||||
.getEnvFunc = getGroupKeyFuncEnv,
|
||||
.initFunc = functionSetup,
|
||||
|
|
|
@ -82,7 +82,9 @@ static bool columnNodeEqual(const SColumnNode* a, const SColumnNode* b) {
|
|||
COMPARE_STRING_FIELD(dbName);
|
||||
COMPARE_STRING_FIELD(tableName);
|
||||
COMPARE_STRING_FIELD(colName);
|
||||
COMPARE_STRING_FIELD(tableAlias);
|
||||
if (0 == a->tableId) {
|
||||
COMPARE_STRING_FIELD(tableAlias);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -767,6 +767,7 @@ SNode* createSelectStmt(SAstCreateContext* pCxt, bool isDistinct, SNodeList* pPr
|
|||
select->pFromTable = pTable;
|
||||
sprintf(select->stmtName, "%p", select);
|
||||
select->isTimeLineResult = true;
|
||||
select->onlyHasKeepOrderFunc = true;
|
||||
select->timeRange = TSWINDOW_INITIALIZER;
|
||||
return (SNode*)select;
|
||||
}
|
||||
|
|
|
@ -1171,6 +1171,44 @@ static int32_t translateMultiRowsFunc(STranslateContext* pCxt, SFunctionNode* pF
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t translateInterpFunc(STranslateContext* pCxt, SFunctionNode* pFunc) {
|
||||
if (!fmIsInterpFunc(pFunc->funcId)) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
if (!isSelectStmt(pCxt->pCurrStmt) || SQL_CLAUSE_SELECT != pCxt->currClause) {
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC);
|
||||
}
|
||||
SSelectStmt* pSelect = (SSelectStmt*)pCxt->pCurrStmt;
|
||||
if (pSelect->hasAggFuncs || pSelect->hasMultiRowsFunc || pSelect->hasIndefiniteRowsFunc) {
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC);
|
||||
}
|
||||
if (NULL != pSelect->pWindow || NULL != pSelect->pGroupByList) {
|
||||
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC,
|
||||
"%s function is not supported in window query or group query", pFunc->functionName);
|
||||
}
|
||||
if (hasInvalidFuncNesting(pFunc->pParameterList)) {
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_AGG_FUNC_NESTING);
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t translateTimelineFunc(STranslateContext* pCxt, SFunctionNode* pFunc) {
|
||||
if (!fmIsTimelineFunc(pFunc->funcId)) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
if (!isSelectStmt(pCxt->pCurrStmt)) {
|
||||
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC,
|
||||
"%s function must be used in select statements", pFunc->functionName);
|
||||
}
|
||||
SSelectStmt* pSelect = (SSelectStmt*)pCxt->pCurrStmt;
|
||||
if (QUERY_NODE_TEMP_TABLE == nodeType(pSelect->pFromTable) &&
|
||||
!isTimeLineQuery(((STempTableNode*)pSelect->pFromTable)->pSubquery)) {
|
||||
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC,
|
||||
"%s function requires valid time series input", pFunc->functionName);
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static bool hasFillClause(SNode* pCurrStmt) {
|
||||
if (!isSelectStmt(pCurrStmt)) {
|
||||
return false;
|
||||
|
@ -1291,6 +1329,7 @@ static void setFuncClassification(SNode* pCurrStmt, SFunctionNode* pFunc) {
|
|||
pSelect->hasInterpFunc = pSelect->hasInterpFunc ? true : (FUNCTION_TYPE_INTERP == pFunc->funcType);
|
||||
pSelect->hasLastRowFunc = pSelect->hasLastRowFunc ? true : (FUNCTION_TYPE_LAST_ROW == pFunc->funcType);
|
||||
pSelect->hasTimeLineFunc = pSelect->hasTimeLineFunc ? true : fmIsTimelineFunc(pFunc->funcId);
|
||||
pSelect->onlyHasKeepOrderFunc = pSelect->onlyHasKeepOrderFunc ? fmIsKeepOrderFunc(pFunc->funcId) : false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1409,6 +1448,12 @@ static int32_t translateNoramlFunction(STranslateContext* pCxt, SFunctionNode* p
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = translateMultiRowsFunc(pCxt, pFunc);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = translateInterpFunc(pCxt, pFunc);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = translateTimelineFunc(pCxt, pFunc);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
setFuncClassification(pCxt->pCurrStmt, pFunc);
|
||||
}
|
||||
|
@ -1685,6 +1730,9 @@ static int32_t checkAggColCoexist(STranslateContext* pCxt, SSelectStmt* pSelect)
|
|||
(!pSelect->hasAggFuncs && !pSelect->hasIndefiniteRowsFunc && !pSelect->hasInterpFunc)) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
if (!pSelect->onlyHasKeepOrderFunc) {
|
||||
pSelect->isTimeLineResult = false;
|
||||
}
|
||||
CheckAggColCoexistCxt cxt = {.pTranslateCxt = pCxt, .existCol = false};
|
||||
nodesRewriteExprs(pSelect->pProjectionList, doCheckAggColCoexist, &cxt);
|
||||
if (!pSelect->isDistinct) {
|
||||
|
@ -2181,9 +2229,9 @@ static int32_t translateOrderBy(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
|||
}
|
||||
pCxt->currClause = SQL_CLAUSE_ORDER_BY;
|
||||
code = translateExprList(pCxt, pSelect->pOrderByList);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = checkExprListForGroupBy(pCxt, pSelect, pSelect->pOrderByList);
|
||||
}
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = checkExprListForGroupBy(pCxt, pSelect, pSelect->pOrderByList);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
@ -2264,15 +2312,15 @@ static int32_t translateHaving(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
|||
}
|
||||
|
||||
static int32_t translateGroupBy(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||
if (NULL != pSelect->pGroupByList && NULL != pSelect->pWindow) {
|
||||
if (NULL == pSelect->pGroupByList) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
if (NULL != pSelect->pWindow) {
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_GROUPBY_WINDOW_COEXIST);
|
||||
}
|
||||
if (NULL != pSelect->pGroupByList) {
|
||||
pCxt->currClause = SQL_CLAUSE_GROUP_BY;
|
||||
pSelect->isTimeLineResult = false;
|
||||
return translateExprList(pCxt, pSelect->pGroupByList);
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
pCxt->currClause = SQL_CLAUSE_GROUP_BY;
|
||||
pSelect->isTimeLineResult = false;
|
||||
return translateExprList(pCxt, pSelect->pGroupByList);
|
||||
}
|
||||
|
||||
static int32_t getTimeRange(SNode** pPrimaryKeyCond, STimeWindow* pTimeRange, bool* pIsStrict) {
|
||||
|
@ -2495,6 +2543,7 @@ static int32_t translateWindow(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
|||
if (NULL == pSelect->pWindow) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
pSelect->isTimeLineResult = true;
|
||||
pCxt->currClause = SQL_CLAUSE_WINDOW;
|
||||
int32_t code = translateExpr(pCxt, &pSelect->pWindow);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
|
@ -2561,12 +2610,13 @@ static int32_t translateInterp(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
|||
return code;
|
||||
}
|
||||
|
||||
static int32_t translatePartitionBy(STranslateContext* pCxt, SNodeList* pPartitionByList) {
|
||||
if (NULL == pPartitionByList) {
|
||||
static int32_t translatePartitionBy(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||
if (NULL == pSelect->pPartitionByList) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
pSelect->isTimeLineResult = false;
|
||||
pCxt->currClause = SQL_CLAUSE_PARTITION_BY;
|
||||
return translateExprList(pCxt, pPartitionByList);
|
||||
return translateExprList(pCxt, pSelect->pPartitionByList);
|
||||
}
|
||||
|
||||
static int32_t translateWhere(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||
|
@ -2669,11 +2719,36 @@ static EDealRes replaceOrderByAliasImpl(SNode** pNode, void* pContext) {
|
|||
}
|
||||
|
||||
static int32_t replaceOrderByAlias(STranslateContext* pCxt, SNodeList* pProjectionList, SNodeList* pOrderByList) {
|
||||
if (NULL == pOrderByList) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
SReplaceOrderByAliasCxt cxt = {.pTranslateCxt = pCxt, .pProjectionList = pProjectionList};
|
||||
nodesRewriteExprsPostOrder(pOrderByList, replaceOrderByAliasImpl, &cxt);
|
||||
return pCxt->errCode;
|
||||
}
|
||||
|
||||
static void resetResultTimeline(SSelectStmt* pSelect) {
|
||||
if (NULL == pSelect->pOrderByList) {
|
||||
return;
|
||||
}
|
||||
SNode* pOrder = ((SOrderByExprNode*)nodesListGetNode(pSelect->pOrderByList, 0))->pExpr;
|
||||
if ((QUERY_NODE_TEMP_TABLE == nodeType(pSelect->pFromTable) &&
|
||||
isPrimaryKey((STempTableNode*)pSelect->pFromTable, pOrder)) ||
|
||||
(QUERY_NODE_TEMP_TABLE != nodeType(pSelect->pFromTable) && isPrimaryKeyImpl(pOrder))) {
|
||||
pSelect->isTimeLineResult = true;
|
||||
} else {
|
||||
pSelect->isTimeLineResult = false;
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t replaceOrderByAliasForSelect(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||
int32_t code = replaceOrderByAlias(pCxt, pSelect->pProjectionList, pSelect->pOrderByList);
|
||||
if (TSDB_CODE_SUCCESS == pCxt->errCode) {
|
||||
resetResultTimeline(pSelect);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t translateSelectWithoutFrom(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||
pCxt->pCurrStmt = (SNode*)pSelect;
|
||||
pCxt->currClause = SQL_CLAUSE_SELECT;
|
||||
|
@ -2688,7 +2763,7 @@ static int32_t translateSelectFrom(STranslateContext* pCxt, SSelectStmt* pSelect
|
|||
code = translateWhere(pCxt, pSelect);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = translatePartitionBy(pCxt, pSelect->pPartitionByList);
|
||||
code = translatePartitionBy(pCxt, pSelect);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = translateWindow(pCxt, pSelect);
|
||||
|
@ -2721,7 +2796,7 @@ static int32_t translateSelectFrom(STranslateContext* pCxt, SSelectStmt* pSelect
|
|||
code = appendTsForImplicitTsFunc(pCxt, pSelect);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = replaceOrderByAlias(pCxt, pSelect->pProjectionList, pSelect->pOrderByList);
|
||||
code = replaceOrderByAliasForSelect(pCxt, pSelect);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
|
|
@ -316,7 +316,8 @@ TEST_F(ParserSelectTest, subquery) {
|
|||
|
||||
run("SELECT SUM(a) FROM (SELECT MAX(c1) a, ts FROM st1s1 PARTITION BY TBNAME INTERVAL(1m)) INTERVAL(1n)");
|
||||
|
||||
run("SELECT SUM(a) FROM (SELECT MAX(c1) a, _wstart FROM st1s1 PARTITION BY TBNAME INTERVAL(1m)) INTERVAL(1n)");
|
||||
run("SELECT SUM(a) FROM (SELECT MAX(c1) a, _wstart FROM st1s1 PARTITION BY TBNAME INTERVAL(1m) ORDER BY _WSTART) "
|
||||
"INTERVAL(1n)");
|
||||
|
||||
run("SELECT _C0 FROM (SELECT _ROWTS, ts FROM st1s1)");
|
||||
|
||||
|
|
|
@ -480,6 +480,7 @@ static int32_t createAggLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect,
|
|||
|
||||
pAgg->hasLastRow = pSelect->hasLastRowFunc;
|
||||
pAgg->hasTimeLineFunc = pSelect->hasTimeLineFunc;
|
||||
pAgg->onlyHasKeepOrderFunc = pSelect->onlyHasKeepOrderFunc;
|
||||
pAgg->node.groupAction = GROUP_ACTION_SET;
|
||||
pAgg->node.requireDataOrder = pAgg->hasTimeLineFunc ? DATA_ORDER_LEVEL_IN_GROUP : DATA_ORDER_LEVEL_NONE;
|
||||
pAgg->node.resultDataOrder = DATA_ORDER_LEVEL_NONE;
|
||||
|
|
|
@ -146,19 +146,9 @@ static int32_t adjustJoinDataRequirement(SJoinLogicNode* pJoin, EDataOrderLevel
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static bool isKeepOrderAggFunc(SNodeList* pFuncs) {
|
||||
SNode* pFunc = NULL;
|
||||
FOREACH(pFunc, pFuncs) {
|
||||
if (!fmIsKeepOrderFunc(((SFunctionNode*)pFunc)->funcId)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static int32_t adjustAggDataRequirement(SAggLogicNode* pAgg, EDataOrderLevel requirement) {
|
||||
// The sort level of agg with group by output data can only be DATA_ORDER_LEVEL_NONE
|
||||
if (requirement > DATA_ORDER_LEVEL_NONE && (NULL != pAgg->pGroupKeys || !isKeepOrderAggFunc(pAgg->pAggFuncs))) {
|
||||
if (requirement > DATA_ORDER_LEVEL_NONE && (NULL != pAgg->pGroupKeys || !pAgg->onlyHasKeepOrderFunc)) {
|
||||
planError(
|
||||
"The output of aggregate cannot meet the requirements(%s) of the upper operator. "
|
||||
"Illegal statement, should be intercepted in parser",
|
||||
|
|
|
@ -162,9 +162,9 @@ class TDTestCase:
|
|||
self.checkcsum(**case6)
|
||||
|
||||
# case7~8: nested query
|
||||
case7 = {"table_expr": "(select c1 from db.stb1 order by tbname ,ts )"}
|
||||
case7 = {"table_expr": "(select c1 from db.stb1 order by ts, tbname )"}
|
||||
self.checkcsum(**case7)
|
||||
case8 = {"table_expr": "(select csum(c1) c1 from db.t1 partition by tbname)"}
|
||||
case8 = {"table_expr": "(select csum(c1) c1 from db.t1)"}
|
||||
self.checkcsum(**case8)
|
||||
|
||||
# case9~10: mix with tbname/ts/tag/col not support , must partition by alias ,such as select tbname ,csum(c1) partition by tbname
|
||||
|
|
Loading…
Reference in New Issue