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));
|
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) {
|
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);
|
||||||
}
|
}
|
||||||
|
@ -672,38 +676,6 @@ static int32_t rewriteCountStar(STranslateContext* pCxt, SFunctionNode* pCount)
|
||||||
return code;
|
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,
|
||||||
|
@ -727,9 +699,6 @@ static EDealRes translateFunction(STranslateContext* pCxt, SFunctionNode* pFunc)
|
||||||
pCxt->errCode = rewriteCountStar(pCxt, 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;
|
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;
|
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) {
|
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);
|
||||||
|
@ -1671,6 +1682,9 @@ 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 = rewriteTimelineFunc(pCxt, pSelect);
|
||||||
|
}
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -67,27 +67,29 @@ TEST_F(ParserSelectTest, condition) {
|
||||||
TEST_F(ParserSelectTest, pseudoColumn) {
|
TEST_F(ParserSelectTest, pseudoColumn) {
|
||||||
useDb("root", "test");
|
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) {
|
TEST_F(ParserSelectTest, multiResFunc) {
|
||||||
useDb("root", "test");
|
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) {
|
TEST_F(ParserSelectTest, timelineFunc) {
|
||||||
useDb("root", "test");
|
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");
|
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 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 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 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 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 stb1 where c1 > 3 slimit 1")
|
||||||
# tdSql.error("select distinct c1, c2 from t1 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} ")
|
# tdSql.query(f"select distinct c1, c2 from stb1 where c1 between {tbnum-2} and {tbnum} ")
|
||||||
|
|
Loading…
Reference in New Issue