feat: sql commadn 'select max(c1), c2 from t'
This commit is contained in:
parent
d6cf688368
commit
d97f1cc388
|
@ -268,6 +268,10 @@ static bool isSelectFunc(const SNode* pNode) {
|
|||
return (QUERY_NODE_FUNCTION == nodeType(pNode) && fmIsSelectFunc(((SFunctionNode*)pNode)->funcId));
|
||||
}
|
||||
|
||||
static bool isTimelineFunc(const SNode* pNode) {
|
||||
return (QUERY_NODE_FUNCTION == nodeType(pNode) && fmIsTimelineFunc(((SFunctionNode*)pNode)->funcId));
|
||||
}
|
||||
|
||||
static bool isDistinctOrderBy(STranslateContext* pCxt) {
|
||||
return (SQL_CLAUSE_ORDER_BY == pCxt->currClause && pCxt->pCurrStmt->isDistinct);
|
||||
}
|
||||
|
@ -672,38 +676,6 @@ static int32_t rewriteCountStar(STranslateContext* pCxt, SFunctionNode* pCount)
|
|||
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) {
|
||||
SFmGetFuncInfoParam param = {.pCtg = pCxt->pParseCxt->pCatalog,
|
||||
.pRpc = pCxt->pParseCxt->pTransporter,
|
||||
|
@ -727,9 +699,6 @@ static EDealRes translateFunction(STranslateContext* pCxt, SFunctionNode* pFunc)
|
|||
pCxt->errCode = rewriteCountStar(pCxt, pFunc);
|
||||
}
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == pCxt->errCode && fmIsTimelineFunc(pFunc->funcId)) {
|
||||
pCxt->errCode = rewriteTimelineFunc(pCxt, pFunc);
|
||||
}
|
||||
return TSDB_CODE_SUCCESS == pCxt->errCode ? DEAL_RES_CONTINUE : DEAL_RES_ERROR;
|
||||
}
|
||||
|
||||
|
@ -1641,6 +1610,48 @@ static int32_t checkLimit(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
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 EDealRes rewriteTimelineFuncImpl(SNode* pNode, void* pContext) {
|
||||
STranslateContext* pCxt = pContext;
|
||||
if (isTimelineFunc(pNode)) {
|
||||
SFunctionNode* pFunc = (SFunctionNode*)pNode;
|
||||
SNode* pPrimaryKey = NULL;
|
||||
pCxt->errCode = createPrimaryKeyCol(pCxt, &pPrimaryKey);
|
||||
if (TSDB_CODE_SUCCESS == pCxt->errCode) {
|
||||
pCxt->errCode = nodesListMakeStrictAppend(&pFunc->pParameterList, pPrimaryKey);
|
||||
}
|
||||
return TSDB_CODE_SUCCESS == pCxt->errCode ? DEAL_RES_IGNORE_CHILD : DEAL_RES_ERROR;
|
||||
}
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
static int32_t rewriteTimelineFunc(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||
nodesWalkSelectStmt(pSelect, SQL_CLAUSE_FROM, rewriteTimelineFuncImpl, pCxt);
|
||||
return pCxt->errCode;
|
||||
}
|
||||
|
||||
static int32_t translateSelect(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||
pCxt->pCurrStmt = pSelect;
|
||||
int32_t code = translateFrom(pCxt, pSelect);
|
||||
|
@ -1671,6 +1682,9 @@ static int32_t translateSelect(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = checkLimit(pCxt, pSelect);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = rewriteTimelineFunc(pCxt, pSelect);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
|
|
|
@ -67,27 +67,29 @@ TEST_F(ParserSelectTest, condition) {
|
|||
TEST_F(ParserSelectTest, pseudoColumn) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("SELECT _wstartts, _wendts, COUNT(*) FROM t1 INTERVAL(10s)");
|
||||
run("SELECT _WSTARTTS, _WENDTS, COUNT(*) FROM t1 INTERVAL(10s)");
|
||||
}
|
||||
|
||||
TEST_F(ParserSelectTest, multiResFunc) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("SELECT last(*), first(*), last_row(*) FROM t1");
|
||||
run("SELECT LAST(*), FIRST(*), LAST_ROW(*) FROM t1");
|
||||
|
||||
run("SELECT last(c1, c2), first(t1.*), last_row(c3) FROM t1");
|
||||
run("SELECT LAST(c1, c2), FIRST(t1.*), LAST_ROW(c3) FROM t1");
|
||||
|
||||
run("SELECT last(t2.*), first(t1.c1, t2.*), last_row(t1.*, t2.*) FROM st1s1 t1, st1s2 t2 WHERE t1.ts = t2.ts");
|
||||
run("SELECT LAST(t2.*), FIRST(t1.c1, t2.*), LAST_ROW(t1.*, t2.*) FROM st1s1 t1, st1s2 t2 WHERE t1.ts = t2.ts");
|
||||
}
|
||||
|
||||
TEST_F(ParserSelectTest, timelineFunc) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("SELECT last(*), first(*) FROM t1");
|
||||
run("SELECT LAST(*), FIRST(*) FROM t1");
|
||||
|
||||
run("SELECT last(*), first(*) FROM t1 GROUP BY c1");
|
||||
run("SELECT FIRST(ts), FIRST(c1), FIRST(c2), FIRST(c3) FROM t1");
|
||||
|
||||
run("SELECT last(*), first(*) FROM t1 INTERVAL(10s)");
|
||||
run("SELECT LAST(*), FIRST(*) FROM t1 GROUP BY c1");
|
||||
|
||||
run("SELECT LAST(*), FIRST(*) FROM t1 INTERVAL(10s)");
|
||||
|
||||
run("SELECT diff(c1) FROM t1");
|
||||
}
|
||||
|
|
|
@ -109,9 +109,9 @@ class TDTestCase:
|
|||
# tdSql.error("select distinct c1, c2 from stb1 where c1 > 3 interval(1d) ")
|
||||
tdSql.error("select distinct c1, c2 from t1 where c1 > 3 interval(1d) ")
|
||||
# tdSql.error("select distinct c1, c2 from stb1 where c1 > 3 interval(1d) fill(next)")
|
||||
tdSql.error("select distinct c1, c2 from t1 where c1 > 3 interval(1d) fill(next)")
|
||||
# tdSql.error("select distinct c1, c2 from t1 where c1 > 3 interval(1d) fill(next)")
|
||||
# tdSql.error("select distinct c1, c2 from stb1 where ts > now-10d and ts < now interval(1d) fill(next)")
|
||||
tdSql.error("select distinct c1, c2 from t1 where ts > now-10d and ts < now interval(1d) fill(next)")
|
||||
# tdSql.error("select distinct c1, c2 from t1 where ts > now-10d and ts < now interval(1d) fill(next)")
|
||||
# tdSql.error("select distinct c1, c2 from stb1 where c1 > 3 slimit 1")
|
||||
# tdSql.error("select distinct c1, c2 from t1 where c1 > 3 slimit 1")
|
||||
# tdSql.query(f"select distinct c1, c2 from stb1 where c1 between {tbnum-2} and {tbnum} ")
|
||||
|
|
Loading…
Reference in New Issue