feat: sql command 'select max(c1), c2 from t'
This commit is contained in:
parent
408929ec4b
commit
f99c01e66e
|
@ -624,6 +624,70 @@ static EDealRes haveAggFunction(SNode* pNode, void* pContext) {
|
||||||
return DEAL_RES_CONTINUE;
|
return DEAL_RES_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t findTable(STranslateContext* pCxt, const char* pTableAlias, STableNode** pOutput) {
|
||||||
|
SArray* pTables = taosArrayGetP(pCxt->pNsLevel, pCxt->currLevel);
|
||||||
|
size_t nums = taosArrayGetSize(pTables);
|
||||||
|
for (size_t i = 0; i < nums; ++i) {
|
||||||
|
STableNode* pTable = taosArrayGetP(pTables, i);
|
||||||
|
if (NULL == pTableAlias || 0 == strcmp(pTable->tableAlias, pTableAlias)) {
|
||||||
|
*pOutput = pTable;
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_TABLE_NOT_EXIST, pTableAlias);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isCountStar(SFunctionNode* pFunc) {
|
||||||
|
if (FUNCTION_TYPE_COUNT != pFunc->funcType || 1 != LIST_LENGTH(pFunc->pParameterList)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
SNode* pPara = nodesListGetNode(pFunc->pParameterList, 0);
|
||||||
|
return (QUERY_NODE_COLUMN == nodeType(pPara) && 0 == strcmp(((SColumnNode*)pPara)->colName, "*"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// count(*) is rewritten as count(ts) for scannning optimization
|
||||||
|
static int32_t rewriteCountStar(STranslateContext* pCxt, SFunctionNode* pCount) {
|
||||||
|
SColumnNode* pCol = nodesListGetNode(pCount->pParameterList, 0);
|
||||||
|
STableNode* pTable = NULL;
|
||||||
|
int32_t code = findTable(pCxt, ('\0' == pCol->tableAlias[0] ? NULL : pCol->tableAlias), &pTable);
|
||||||
|
if (TSDB_CODE_SUCCESS == code && QUERY_NODE_REAL_TABLE == nodeType(pTable)) {
|
||||||
|
setColumnInfoBySchema((SRealTableNode*)pTable, ((SRealTableNode*)pTable)->pMeta->schema, false, pCol);
|
||||||
|
}
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t createPrimaryKeyColByTable(STranslateContext* pCxt, STableNode* pTable, SNode** pPrimaryKey) {
|
||||||
|
SColumnNode* pCol = nodesMakeNode(QUERY_NODE_COLUMN);
|
||||||
|
if (NULL == pCol) {
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
if (QUERY_NODE_REAL_TABLE == nodeType(pTable)) {
|
||||||
|
setColumnInfoBySchema((SRealTableNode*)pTable, ((SRealTableNode*)pTable)->pMeta->schema, false, pCol);
|
||||||
|
} else {
|
||||||
|
// todo
|
||||||
|
}
|
||||||
|
*pPrimaryKey = (SNode*)pCol;
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t createPrimaryKeyCol(STranslateContext* pCxt, SNode** pPrimaryKey) {
|
||||||
|
STableNode* pTable = NULL;
|
||||||
|
int32_t code = findTable(pCxt, NULL, &pTable);
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = createPrimaryKeyColByTable(pCxt, pTable, pPrimaryKey);
|
||||||
|
}
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t rewriteTimelineFunc(STranslateContext* pCxt, SFunctionNode* pFunc) {
|
||||||
|
SNode* pPrimaryKey = NULL;
|
||||||
|
int32_t code = createPrimaryKeyCol(pCxt, &pPrimaryKey);
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = nodesListMakeStrictAppend(&pFunc->pParameterList, pPrimaryKey);
|
||||||
|
}
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
static EDealRes translateFunction(STranslateContext* pCxt, SFunctionNode* pFunc) {
|
static EDealRes translateFunction(STranslateContext* pCxt, SFunctionNode* pFunc) {
|
||||||
SFmGetFuncInfoParam param = {.pCtg = pCxt->pParseCxt->pCatalog,
|
SFmGetFuncInfoParam param = {.pCtg = pCxt->pParseCxt->pCatalog,
|
||||||
.pRpc = pCxt->pParseCxt->pTransporter,
|
.pRpc = pCxt->pParseCxt->pTransporter,
|
||||||
|
@ -631,10 +695,7 @@ static EDealRes translateFunction(STranslateContext* pCxt, SFunctionNode* pFunc)
|
||||||
.pErrBuf = pCxt->msgBuf.buf,
|
.pErrBuf = pCxt->msgBuf.buf,
|
||||||
.errBufLen = pCxt->msgBuf.len};
|
.errBufLen = pCxt->msgBuf.len};
|
||||||
pCxt->errCode = fmGetFuncInfo(¶m, pFunc);
|
pCxt->errCode = fmGetFuncInfo(¶m, pFunc);
|
||||||
if (TSDB_CODE_SUCCESS != pCxt->errCode) {
|
if (TSDB_CODE_SUCCESS == pCxt->errCode && fmIsAggFunc(pFunc->funcId)) {
|
||||||
return DEAL_RES_ERROR;
|
|
||||||
}
|
|
||||||
if (fmIsAggFunc(pFunc->funcId)) {
|
|
||||||
if (beforeHaving(pCxt->currClause)) {
|
if (beforeHaving(pCxt->currClause)) {
|
||||||
return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION);
|
return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION);
|
||||||
}
|
}
|
||||||
|
@ -643,11 +704,17 @@ static EDealRes translateFunction(STranslateContext* pCxt, SFunctionNode* pFunc)
|
||||||
if (haveAggFunc) {
|
if (haveAggFunc) {
|
||||||
return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_AGG_FUNC_NESTING);
|
return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_AGG_FUNC_NESTING);
|
||||||
}
|
}
|
||||||
|
|
||||||
pCxt->pCurrStmt->hasAggFuncs = true;
|
pCxt->pCurrStmt->hasAggFuncs = true;
|
||||||
pCxt->pCurrStmt->isTimeOrderQuery = false;
|
pCxt->pCurrStmt->isTimeOrderQuery = false;
|
||||||
|
if (isCountStar(pFunc)) {
|
||||||
|
pCxt->errCode = rewriteCountStar(pCxt, pFunc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == pCxt->errCode && fmIsTimelineFunc(pFunc->funcId)) {
|
||||||
return DEAL_RES_CONTINUE;
|
pCxt->errCode = rewriteTimelineFunc(pCxt, pFunc);
|
||||||
|
}
|
||||||
|
return TSDB_CODE_SUCCESS == pCxt->errCode ? DEAL_RES_CONTINUE : DEAL_RES_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static EDealRes translateExprSubquery(STranslateContext* pCxt, SNode* pNode) {
|
static EDealRes translateExprSubquery(STranslateContext* pCxt, SNode* pNode) {
|
||||||
|
@ -691,7 +758,13 @@ static int32_t translateExprList(STranslateContext* pCxt, SNodeList* pList) {
|
||||||
return pCxt->errCode;
|
return pCxt->errCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isAliasColumn(SColumnNode* pCol) { return ('\0' == pCol->tableAlias[0]); }
|
static bool isAliasColumn(const SNode* pNode) {
|
||||||
|
return (QUERY_NODE_COLUMN == nodeType(pNode) && ('\0' == ((SColumnNode*)pNode)->tableAlias[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isAggFunc(const SNode* pNode) {
|
||||||
|
return (QUERY_NODE_FUNCTION == nodeType(pNode) && fmIsAggFunc(((SFunctionNode*)pNode)->funcId));
|
||||||
|
}
|
||||||
|
|
||||||
static bool isDistinctOrderBy(STranslateContext* pCxt) {
|
static bool isDistinctOrderBy(STranslateContext* pCxt) {
|
||||||
return (SQL_CLAUSE_ORDER_BY == pCxt->currClause && pCxt->pCurrStmt->isDistinct);
|
return (SQL_CLAUSE_ORDER_BY == pCxt->currClause && pCxt->pCurrStmt->isDistinct);
|
||||||
|
@ -720,11 +793,10 @@ static int32_t getGroupByErrorCode(STranslateContext* pCxt) {
|
||||||
|
|
||||||
static EDealRes doCheckExprForGroupBy(SNode* pNode, void* pContext) {
|
static EDealRes doCheckExprForGroupBy(SNode* pNode, void* pContext) {
|
||||||
STranslateContext* pCxt = (STranslateContext*)pContext;
|
STranslateContext* pCxt = (STranslateContext*)pContext;
|
||||||
if (!nodesIsExprNode(pNode) || (QUERY_NODE_COLUMN == nodeType(pNode) && isAliasColumn((SColumnNode*)pNode))) {
|
if (!nodesIsExprNode(pNode) || isAliasColumn(pNode)) {
|
||||||
return DEAL_RES_CONTINUE;
|
return DEAL_RES_CONTINUE;
|
||||||
}
|
}
|
||||||
if (QUERY_NODE_FUNCTION == nodeType(pNode) && fmIsAggFunc(((SFunctionNode*)pNode)->funcId) &&
|
if (isAggFunc(pNode) && !isDistinctOrderBy(pCxt)) {
|
||||||
!isDistinctOrderBy(pCxt)) {
|
|
||||||
return DEAL_RES_IGNORE_CHILD;
|
return DEAL_RES_IGNORE_CHILD;
|
||||||
}
|
}
|
||||||
SNode* pGroupNode;
|
SNode* pGroupNode;
|
||||||
|
@ -733,9 +805,7 @@ static EDealRes doCheckExprForGroupBy(SNode* pNode, void* pContext) {
|
||||||
return DEAL_RES_IGNORE_CHILD;
|
return DEAL_RES_IGNORE_CHILD;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (QUERY_NODE_COLUMN == nodeType(pNode) ||
|
if (QUERY_NODE_COLUMN == nodeType(pNode) || (isAggFunc(pNode) && isDistinctOrderBy(pCxt))) {
|
||||||
(QUERY_NODE_FUNCTION == nodeType(pNode) && fmIsAggFunc(((SFunctionNode*)pNode)->funcId) &&
|
|
||||||
isDistinctOrderBy(pCxt))) {
|
|
||||||
return generateDealNodeErrMsg(pCxt, getGroupByErrorCode(pCxt));
|
return generateDealNodeErrMsg(pCxt, getGroupByErrorCode(pCxt));
|
||||||
}
|
}
|
||||||
return DEAL_RES_CONTINUE;
|
return DEAL_RES_CONTINUE;
|
||||||
|
@ -990,19 +1060,6 @@ static SNode* createMultiResFunc(SFunctionNode* pSrcFunc, SExprNode* pExpr) {
|
||||||
return (SNode*)pFunc;
|
return (SNode*)pFunc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t findTable(STranslateContext* pCxt, const char* pTableAlias, STableNode** pOutput) {
|
|
||||||
SArray* pTables = taosArrayGetP(pCxt->pNsLevel, pCxt->currLevel);
|
|
||||||
size_t nums = taosArrayGetSize(pTables);
|
|
||||||
for (size_t i = 0; i < nums; ++i) {
|
|
||||||
STableNode* pTable = taosArrayGetP(pTables, i);
|
|
||||||
if (NULL == pTableAlias || 0 == strcmp(pTable->tableAlias, pTableAlias)) {
|
|
||||||
*pOutput = pTable;
|
|
||||||
return TSDB_CODE_SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_TABLE_NOT_EXIST, pTableAlias);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t createTableAllCols(STranslateContext* pCxt, SColumnNode* pCol, SNodeList** pOutput) {
|
static int32_t createTableAllCols(STranslateContext* pCxt, SColumnNode* pCol, SNodeList** pOutput) {
|
||||||
STableNode* pTable = NULL;
|
STableNode* pTable = NULL;
|
||||||
int32_t code = findTable(pCxt, pCol->tableAlias, &pTable);
|
int32_t code = findTable(pCxt, pCol->tableAlias, &pTable);
|
||||||
|
@ -1511,78 +1568,6 @@ static int32_t checkLimit(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isCountStar(SFunctionNode* pFunc) {
|
|
||||||
if (1 != LIST_LENGTH(pFunc->pParameterList)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
SNode* pPara = nodesListGetNode(pFunc->pParameterList, 0);
|
|
||||||
return (QUERY_NODE_COLUMN == nodeType(pPara) && 0 == strcmp(((SColumnNode*)pPara)->colName, "*"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// count(*) is rewritten as count(ts) for scannning optimization
|
|
||||||
static int32_t rewriteCountStar(STranslateContext* pCxt, SFunctionNode* pCount) {
|
|
||||||
SColumnNode* pCol = nodesListGetNode(pCount->pParameterList, 0);
|
|
||||||
STableNode* pTable = NULL;
|
|
||||||
int32_t code = findTable(pCxt, ('\0' == pCol->tableAlias[0] ? NULL : pCol->tableAlias), &pTable);
|
|
||||||
if (TSDB_CODE_SUCCESS == code && QUERY_NODE_REAL_TABLE == nodeType(pTable)) {
|
|
||||||
setColumnInfoBySchema((SRealTableNode*)pTable, ((SRealTableNode*)pTable)->pMeta->schema, false, pCol);
|
|
||||||
}
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t createPrimaryKeyColByTable(STranslateContext* pCxt, STableNode* pTable, SNode** pPrimaryKey) {
|
|
||||||
SColumnNode* pCol = nodesMakeNode(QUERY_NODE_COLUMN);
|
|
||||||
if (NULL == pCol) {
|
|
||||||
return TSDB_CODE_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
if (QUERY_NODE_REAL_TABLE == nodeType(pTable)) {
|
|
||||||
setColumnInfoBySchema((SRealTableNode*)pTable, ((SRealTableNode*)pTable)->pMeta->schema, false, pCol);
|
|
||||||
} else {
|
|
||||||
// todo
|
|
||||||
}
|
|
||||||
*pPrimaryKey = (SNode*)pCol;
|
|
||||||
return TSDB_CODE_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t createPrimaryKeyCol(STranslateContext* pCxt, SNode** pPrimaryKey) {
|
|
||||||
STableNode* pTable = NULL;
|
|
||||||
int32_t code = findTable(pCxt, NULL, &pTable);
|
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
|
||||||
code = createPrimaryKeyColByTable(pCxt, pTable, pPrimaryKey);
|
|
||||||
}
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t rewriteTimelineFunc(STranslateContext* pCxt, SFunctionNode* pFunc) {
|
|
||||||
SNode* pPrimaryKey = NULL;
|
|
||||||
int32_t code = createPrimaryKeyCol(pCxt, &pPrimaryKey);
|
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
|
||||||
code = nodesListMakeStrictAppend(&pFunc->pParameterList, pPrimaryKey);
|
|
||||||
}
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
EDealRes rewriteFuncForSelectImpl(SNode* pNode, void* pContext) {
|
|
||||||
if (QUERY_NODE_FUNCTION == nodeType(pNode)) {
|
|
||||||
STranslateContext* pCxt = pContext;
|
|
||||||
SFunctionNode* pFunc = (SFunctionNode*)pNode;
|
|
||||||
if (isCountStar(pFunc)) {
|
|
||||||
pCxt->errCode = rewriteCountStar(pCxt, pFunc);
|
|
||||||
} else if (fmIsTimelineFunc(pFunc->funcId)) {
|
|
||||||
pCxt->errCode = rewriteTimelineFunc(pCxt, pFunc);
|
|
||||||
}
|
|
||||||
if (TSDB_CODE_SUCCESS != pCxt->errCode) {
|
|
||||||
return DEAL_RES_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return DEAL_RES_CONTINUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t rewriteFuncForSelect(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
|
||||||
nodesWalkSelectStmt(pSelect, SQL_CLAUSE_FROM, rewriteFuncForSelectImpl, pCxt);
|
|
||||||
return pCxt->errCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t translateSelect(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
static int32_t translateSelect(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||||
pCxt->pCurrStmt = pSelect;
|
pCxt->pCurrStmt = pSelect;
|
||||||
int32_t code = translateFrom(pCxt, pSelect);
|
int32_t code = translateFrom(pCxt, pSelect);
|
||||||
|
@ -1613,9 +1598,6 @@ static int32_t translateSelect(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = checkLimit(pCxt, pSelect);
|
code = checkLimit(pCxt, pSelect);
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
|
||||||
code = rewriteFuncForSelect(pCxt, pSelect);
|
|
||||||
}
|
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,31 +85,45 @@ TEST_F(ParserSelectTest, timelineFunc) {
|
||||||
|
|
||||||
run("SELECT last(*), first(*) FROM t1");
|
run("SELECT last(*), first(*) FROM t1");
|
||||||
|
|
||||||
run("SELECT last(*), first(*) FROM t1 group by c1");
|
run("SELECT last(*), first(*) FROM t1 GROUP BY c1");
|
||||||
|
|
||||||
run("SELECT last(*), first(*) FROM t1 INTERVAL(10s)");
|
run("SELECT last(*), first(*) FROM t1 INTERVAL(10s)");
|
||||||
|
|
||||||
run("SELECT diff(c1) FROM t1");
|
run("SELECT diff(c1) FROM t1");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserSelectTest, selectFunc) {
|
||||||
|
useDb("root", "test");
|
||||||
|
// select function
|
||||||
|
run("SELECT MAX(c1), MIN(c1) FROM t1");
|
||||||
|
// select function for GROUP BY clause
|
||||||
|
run("SELECT MAX(c1), MIN(c1) FROM t1 GROUP BY c1");
|
||||||
|
// select function for INTERVAL clause
|
||||||
|
run("SELECT MAX(c1), MIN(c1) FROM t1 INTERVAL(10s)");
|
||||||
|
// select function along with the columns of select row
|
||||||
|
run("SELECT MAX(c1), c2 FROM t1");
|
||||||
|
run("SELECT MAX(c1), * FROM t1");
|
||||||
|
run("SELECT MAX(c1), t1.* FROM t1");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(ParserSelectTest, clause) {
|
TEST_F(ParserSelectTest, clause) {
|
||||||
useDb("root", "test");
|
useDb("root", "test");
|
||||||
|
|
||||||
// group by clause
|
// GROUP BY clause
|
||||||
run("SELECT COUNT(*) cnt FROM t1 WHERE c1 > 0");
|
run("SELECT COUNT(*) cnt FROM t1 WHERE c1 > 0");
|
||||||
|
|
||||||
run("SELECT COUNT(*), c2 cnt FROM t1 WHERE c1 > 0 group by c2");
|
run("SELECT COUNT(*), c2 cnt FROM t1 WHERE c1 > 0 GROUP BY c2");
|
||||||
|
|
||||||
run("SELECT COUNT(*) cnt FROM t1 WHERE c1 > 0 group by c2 having COUNT(c1) > 10");
|
run("SELECT COUNT(*) cnt FROM t1 WHERE c1 > 0 GROUP BY c2 having COUNT(c1) > 10");
|
||||||
|
|
||||||
run("SELECT COUNT(*), c1, c2 + 10, c1 + c2 cnt FROM t1 WHERE c1 > 0 group by c2, c1");
|
run("SELECT COUNT(*), c1, c2 + 10, c1 + c2 cnt FROM t1 WHERE c1 > 0 GROUP BY c2, c1");
|
||||||
|
|
||||||
run("SELECT COUNT(*), c1 + 10, c2 cnt FROM t1 WHERE c1 > 0 group by c1 + 10, c2");
|
run("SELECT COUNT(*), c1 + 10, c2 cnt FROM t1 WHERE c1 > 0 GROUP BY c1 + 10, c2");
|
||||||
|
|
||||||
// order by clause
|
// order by clause
|
||||||
run("SELECT COUNT(*) cnt FROM t1 WHERE c1 > 0 group by c2 order by cnt");
|
run("SELECT COUNT(*) cnt FROM t1 WHERE c1 > 0 GROUP BY c2 order by cnt");
|
||||||
|
|
||||||
run("SELECT COUNT(*) cnt FROM t1 WHERE c1 > 0 group by c2 order by 1");
|
run("SELECT COUNT(*) cnt FROM t1 WHERE c1 > 0 GROUP BY c2 order by 1");
|
||||||
|
|
||||||
// distinct clause
|
// distinct clause
|
||||||
// run("SELECT distinct c1, c2 FROM t1 WHERE c1 > 0 order by c1");
|
// run("SELECT distinct c1, c2 FROM t1 WHERE c1 > 0 order by c1");
|
||||||
|
@ -118,7 +132,7 @@ TEST_F(ParserSelectTest, clause) {
|
||||||
|
|
||||||
// run("SELECT distinct c1 + 10 cc1, c2 cc2 FROM t1 WHERE c1 > 0 order by cc1, c2");
|
// run("SELECT distinct c1 + 10 cc1, c2 cc2 FROM t1 WHERE c1 > 0 order by cc1, c2");
|
||||||
|
|
||||||
// run("SELECT distinct COUNT(c2) FROM t1 WHERE c1 > 0 group by c1 order by COUNT(c2)");
|
// run("SELECT distinct COUNT(c2) FROM t1 WHERE c1 > 0 GROUP BY c1 order by COUNT(c2)");
|
||||||
}
|
}
|
||||||
|
|
||||||
// INTERVAL(interval_val [, interval_offset]) [SLIDING (sliding_val)] [FILL(fill_mod_and_val)]
|
// INTERVAL(interval_val [, interval_offset]) [SLIDING (sliding_val)] [FILL(fill_mod_and_val)]
|
||||||
|
@ -137,6 +151,12 @@ TEST_F(ParserSelectTest, interval) {
|
||||||
"INTERVAL(10s) FILL(NONE)");
|
"INTERVAL(10s) FILL(NONE)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserSelectTest, intervalSemanticCheck) {
|
||||||
|
useDb("root", "test");
|
||||||
|
|
||||||
|
run("SELECT c1 FROM t1 INTERVAL(10s)");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(ParserSelectTest, semanticError) {
|
TEST_F(ParserSelectTest, semanticError) {
|
||||||
useDb("root", "test");
|
useDb("root", "test");
|
||||||
|
|
||||||
|
@ -164,7 +184,7 @@ TEST_F(ParserSelectTest, semanticError) {
|
||||||
|
|
||||||
run("SELECT c2 FROM t1 WHERE COUNT(*) > 0", TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION, PARSER_STAGE_TRANSLATE);
|
run("SELECT c2 FROM t1 WHERE COUNT(*) > 0", TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION, PARSER_STAGE_TRANSLATE);
|
||||||
|
|
||||||
run("SELECT c2 FROM t1 group by COUNT(*)", TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION, PARSER_STAGE_TRANSLATE);
|
run("SELECT c2 FROM t1 GROUP BY COUNT(*)", TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION, PARSER_STAGE_TRANSLATE);
|
||||||
|
|
||||||
// TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT
|
// TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT
|
||||||
run("SELECT c2 FROM t1 order by 0", TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT, PARSER_STAGE_TRANSLATE);
|
run("SELECT c2 FROM t1 order by 0", TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT, PARSER_STAGE_TRANSLATE);
|
||||||
|
@ -174,13 +194,13 @@ TEST_F(ParserSelectTest, semanticError) {
|
||||||
// TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION
|
// TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION
|
||||||
run("SELECT COUNT(*) cnt FROM t1 having c1 > 0", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION, PARSER_STAGE_TRANSLATE);
|
run("SELECT COUNT(*) cnt FROM t1 having c1 > 0", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION, PARSER_STAGE_TRANSLATE);
|
||||||
|
|
||||||
run("SELECT COUNT(*) cnt FROM t1 group by c2 having c1 > 0", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION,
|
run("SELECT COUNT(*) cnt FROM t1 GROUP BY c2 having c1 > 0", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION,
|
||||||
PARSER_STAGE_TRANSLATE);
|
PARSER_STAGE_TRANSLATE);
|
||||||
|
|
||||||
run("SELECT COUNT(*), c1 cnt FROM t1 group by c2 having c2 > 0", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION,
|
run("SELECT COUNT(*), c1 cnt FROM t1 GROUP BY c2 having c2 > 0", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION,
|
||||||
PARSER_STAGE_TRANSLATE);
|
PARSER_STAGE_TRANSLATE);
|
||||||
|
|
||||||
run("SELECT COUNT(*) cnt FROM t1 group by c2 having c2 > 0 order by c1", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION,
|
run("SELECT COUNT(*) cnt FROM t1 GROUP BY c2 having c2 > 0 order by c1", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION,
|
||||||
PARSER_STAGE_TRANSLATE);
|
PARSER_STAGE_TRANSLATE);
|
||||||
|
|
||||||
// TSDB_CODE_PAR_NOT_SINGLE_GROUP
|
// TSDB_CODE_PAR_NOT_SINGLE_GROUP
|
||||||
|
|
Loading…
Reference in New Issue