提交 8ef6b184 编写于 作者: X Xiaoyu Wang

first(*)/last(*) rewrite

上级 fdbab777
...@@ -30,11 +30,19 @@ extern "C" { ...@@ -30,11 +30,19 @@ extern "C" {
#define FOREACH(node, list) \ #define FOREACH(node, list) \
for (SListCell* cell = (NULL != (list) ? (list)->pHead : NULL); (NULL != cell ? (node = cell->pNode, true) : (node = NULL, false)); cell = cell->pNext) for (SListCell* cell = (NULL != (list) ? (list)->pHead : NULL); (NULL != cell ? (node = cell->pNode, true) : (node = NULL, false)); cell = cell->pNext)
// only be use in FOREACH
#define ERASE_NODE(list) cell = nodesListErase(list, cell);
#define REPLACE_NODE(newNode) cell->pNode = (SNode*)(newNode) #define REPLACE_NODE(newNode) cell->pNode = (SNode*)(newNode)
#define INSERT_LIST(target, src) nodesListInsertList((target), cell, src)
#define WHERE_EACH(node, list) \
SListCell* cell = (NULL != (list) ? (list)->pHead : NULL); \
while (NULL != cell ? (node = cell->pNode, true) : (node = NULL, false))
#define WHERE_NEXT cell = cell->pNext
// only be use in WHERE_EACH
#define ERASE_NODE(list) cell = nodesListErase((list), cell)
#define FORBOTH(node1, list1, node2, list2) \ #define FORBOTH(node1, list1, node2, list2) \
for (SListCell* cell1 = (NULL != (list1) ? (list1)->pHead : NULL), *cell2 = (NULL != (list2) ? (list2)->pHead : NULL); \ for (SListCell* cell1 = (NULL != (list1) ? (list1)->pHead : NULL), *cell2 = (NULL != (list2) ? (list2)->pHead : NULL); \
(NULL == cell1 ? (node1 = NULL, false) : (node1 = cell1->pNode, true)), (NULL == cell2 ? (node2 = NULL, false) : (node2 = cell2->pNode, true)), (node1 != NULL && node2 != NULL); \ (NULL == cell1 ? (node1 = NULL, false) : (node1 = cell1->pNode, true)), (NULL == cell2 ? (node2 = NULL, false) : (node2 = cell2->pNode, true)), (node1 != NULL && node2 != NULL); \
...@@ -202,7 +210,9 @@ int32_t nodesListStrictAppend(SNodeList* pList, SNodeptr pNode); ...@@ -202,7 +210,9 @@ int32_t nodesListStrictAppend(SNodeList* pList, SNodeptr pNode);
int32_t nodesListMakeAppend(SNodeList** pList, SNodeptr pNode); int32_t nodesListMakeAppend(SNodeList** pList, SNodeptr pNode);
int32_t nodesListAppendList(SNodeList* pTarget, SNodeList* pSrc); int32_t nodesListAppendList(SNodeList* pTarget, SNodeList* pSrc);
int32_t nodesListStrictAppendList(SNodeList* pTarget, SNodeList* pSrc); int32_t nodesListStrictAppendList(SNodeList* pTarget, SNodeList* pSrc);
int32_t nodesListPushFront(SNodeList* pList, SNodeptr pNode);
SListCell* nodesListErase(SNodeList* pList, SListCell* pCell); SListCell* nodesListErase(SNodeList* pList, SListCell* pCell);
void nodesListInsertList(SNodeList* pTarget, SListCell* pPos, SNodeList* pSrc);
SNodeptr nodesListGetNode(SNodeList* pList, int32_t index); SNodeptr nodesListGetNode(SNodeList* pList, int32_t index);
void nodesDestroyList(SNodeList* pList); void nodesDestroyList(SNodeList* pList);
// Only clear the linked list structure, without releasing the elements inside // Only clear the linked list structure, without releasing the elements inside
......
...@@ -644,7 +644,7 @@ SNodeList* nodesMakeList() { ...@@ -644,7 +644,7 @@ SNodeList* nodesMakeList() {
int32_t nodesListAppend(SNodeList* pList, SNodeptr pNode) { int32_t nodesListAppend(SNodeList* pList, SNodeptr pNode) {
if (NULL == pList || NULL == pNode) { if (NULL == pList || NULL == pNode) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_FAILED;
} }
SListCell* p = taosMemoryCalloc(1, sizeof(SListCell)); SListCell* p = taosMemoryCalloc(1, sizeof(SListCell));
if (NULL == p) { if (NULL == p) {
...@@ -688,7 +688,7 @@ int32_t nodesListMakeAppend(SNodeList** pList, SNodeptr pNode) { ...@@ -688,7 +688,7 @@ int32_t nodesListMakeAppend(SNodeList** pList, SNodeptr pNode) {
int32_t nodesListAppendList(SNodeList* pTarget, SNodeList* pSrc) { int32_t nodesListAppendList(SNodeList* pTarget, SNodeList* pSrc) {
if (NULL == pTarget || NULL == pSrc) { if (NULL == pTarget || NULL == pSrc) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_FAILED;
} }
if (NULL == pTarget->pHead) { if (NULL == pTarget->pHead) {
...@@ -717,11 +717,34 @@ int32_t nodesListStrictAppendList(SNodeList* pTarget, SNodeList* pSrc) { ...@@ -717,11 +717,34 @@ int32_t nodesListStrictAppendList(SNodeList* pTarget, SNodeList* pSrc) {
return code; return code;
} }
int32_t nodesListPushFront(SNodeList* pList, SNodeptr pNode) {
if (NULL == pList || NULL == pNode) {
return TSDB_CODE_FAILED;
}
SListCell* p = taosMemoryCalloc(1, sizeof(SListCell));
if (NULL == p) {
terrno = TSDB_CODE_OUT_OF_MEMORY;
return TSDB_CODE_OUT_OF_MEMORY;
}
p->pNode = pNode;
if (NULL != pList->pHead) {
pList->pHead->pPrev = p;
p->pNext = pList->pHead;
}
pList->pHead = p;
++(pList->length);
return TSDB_CODE_SUCCESS;
}
SListCell* nodesListErase(SNodeList* pList, SListCell* pCell) { SListCell* nodesListErase(SNodeList* pList, SListCell* pCell) {
if (NULL == pCell->pPrev) { if (NULL == pCell->pPrev) {
pList->pHead = pCell->pNext; pList->pHead = pCell->pNext;
} else { } else {
pCell->pPrev->pNext = pCell->pNext; pCell->pPrev->pNext = pCell->pNext;
}
if (NULL == pCell->pNext) {
pList->pTail = pCell->pPrev;
} else {
pCell->pNext->pPrev = pCell->pPrev; pCell->pNext->pPrev = pCell->pPrev;
} }
SListCell* pNext = pCell->pNext; SListCell* pNext = pCell->pNext;
...@@ -731,6 +754,24 @@ SListCell* nodesListErase(SNodeList* pList, SListCell* pCell) { ...@@ -731,6 +754,24 @@ SListCell* nodesListErase(SNodeList* pList, SListCell* pCell) {
return pNext; return pNext;
} }
void nodesListInsertList(SNodeList* pTarget, SListCell* pPos, SNodeList* pSrc) {
if (NULL == pTarget || NULL == pPos || NULL == pSrc) {
return;
}
if (NULL == pPos->pPrev) {
pTarget->pHead = pSrc->pHead;
} else {
pPos->pPrev->pNext = pSrc->pHead;
}
pSrc->pHead->pPrev = pPos->pPrev;
pSrc->pTail->pNext = pPos;
pPos->pPrev = pSrc->pTail;
pTarget->length += pSrc->length;
taosMemoryFreeClear(pSrc);
}
SNodeptr nodesListGetNode(SNodeList* pList, int32_t index) { SNodeptr nodesListGetNode(SNodeList* pList, int32_t index) {
SNode* node; SNode* node;
FOREACH(node, pList) { FOREACH(node, pList) {
......
...@@ -743,24 +743,99 @@ static int32_t translateTable(STranslateContext* pCxt, SNode* pTable) { ...@@ -743,24 +743,99 @@ static int32_t translateTable(STranslateContext* pCxt, SNode* pTable) {
return code; return code;
} }
static int32_t translateStar(STranslateContext* pCxt, SSelectStmt* pSelect, bool* pIsSelectStar) { static int32_t createAllColumns(STranslateContext* pCxt, SNodeList** pCols) {
if (NULL == pSelect->pProjectionList) { // select * ... *pCols = nodesMakeList();
SArray* pTables = taosArrayGetP(pCxt->pNsLevel, pCxt->currLevel); if (NULL == *pCols) {
size_t nums = taosArrayGetSize(pTables); return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_OUT_OF_MEMORY);
pSelect->pProjectionList = nodesMakeList(); }
if (NULL == pSelect->pProjectionList) { SArray* pTables = taosArrayGetP(pCxt->pNsLevel, pCxt->currLevel);
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_OUT_OF_MEMORY); size_t nums = taosArrayGetSize(pTables);
} for (size_t i = 0; i < nums; ++i) {
for (size_t i = 0; i < nums; ++i) { STableNode* pTable = taosArrayGetP(pTables, i);
STableNode* pTable = taosArrayGetP(pTables, i); int32_t code = createColumnNodeByTable(pCxt, pTable, *pCols);
int32_t code = createColumnNodeByTable(pCxt, pTable, pSelect->pProjectionList); if (TSDB_CODE_SUCCESS != code) {
if (TSDB_CODE_SUCCESS != code) { return code;
return code; }
} }
return TSDB_CODE_SUCCESS;
}
static bool isFirstLastFunc(SFunctionNode* pFunc) {
return (FUNCTION_TYPE_FIRST == pFunc->funcType || FUNCTION_TYPE_LAST == pFunc->funcType);
}
static bool isFirstLastStar(SNode* pNode) {
if (QUERY_NODE_FUNCTION != nodeType(pNode) || !isFirstLastFunc((SFunctionNode*)pNode)) {
return false;
}
SNodeList* pParameterList = ((SFunctionNode*)pNode)->pParameterList;
if (LIST_LENGTH(pParameterList) != 1) {
return false;
}
SNode* pParam = nodesListGetNode(pParameterList, 0);
return (QUERY_NODE_COLUMN == nodeType(pParam) ? 0 == strcmp(((SColumnNode*)pParam)->colName, "*") : false);
}
static SNode* createFirstLastFunc(SFunctionNode* pSrcFunc, SColumnNode* pCol) {
SFunctionNode* pFunc = nodesMakeNode(QUERY_NODE_FUNCTION);
if (NULL == pFunc) {
return NULL;
}
pFunc->pParameterList = nodesMakeList();
if (NULL == pFunc->pParameterList || TSDB_CODE_SUCCESS != nodesListAppend(pFunc->pParameterList, pCol)) {
nodesDestroyNode(pFunc);
return NULL;
}
pFunc->node.resType = pCol->node.resType;
pFunc->funcId = pSrcFunc->funcId;
pFunc->funcType = pSrcFunc->funcType;
strcpy(pFunc->functionName, pSrcFunc->functionName);
snprintf(pFunc->node.aliasName, sizeof(pFunc->node.aliasName), (FUNCTION_TYPE_FIRST == pSrcFunc->funcType ? "first(%s)" : "last(%s)"), pCol->colName);
return (SNode*)pFunc;
}
static int32_t createFirstLastAllCols(STranslateContext* pCxt, SFunctionNode* pSrcFunc, SNodeList** pOutput) {
SNodeList* pCols = NULL;
if (TSDB_CODE_SUCCESS != createAllColumns(pCxt, &pCols)) {
return TSDB_CODE_OUT_OF_MEMORY;
}
SNodeList* pFuncs = nodesMakeList();
if (NULL == pFuncs) {
return TSDB_CODE_OUT_OF_MEMORY;
}
SNode* pCol = NULL;
FOREACH(pCol, pCols) {
if (TSDB_CODE_SUCCESS != nodesListStrictAppend(pFuncs, createFirstLastFunc(pSrcFunc, (SColumnNode*)pCol))) {
nodesDestroyNode(pFuncs);
return TSDB_CODE_OUT_OF_MEMORY;
} }
*pIsSelectStar = true; }
*pOutput = pFuncs;
return TSDB_CODE_SUCCESS;
}
static int32_t translateStar(STranslateContext* pCxt, SSelectStmt* pSelect) {
if (NULL == pSelect->pProjectionList) { // select * ...
return createAllColumns(pCxt, &pSelect->pProjectionList);
} else { } else {
// todo : t.* // todo : t.*
SNode* pNode = NULL;
WHERE_EACH(pNode, pSelect->pProjectionList) {
if (isFirstLastStar(pNode)) {
SNodeList* pFuncs = NULL;
if (TSDB_CODE_SUCCESS != createFirstLastAllCols(pCxt, (SFunctionNode*)pNode, &pFuncs)) {
return TSDB_CODE_OUT_OF_MEMORY;
}
INSERT_LIST(pSelect->pProjectionList, pFuncs);
ERASE_NODE(pSelect->pProjectionList);
continue;
}
WHERE_NEXT;
}
} }
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
...@@ -797,8 +872,8 @@ static int32_t getPositionValue(const SValueNode* pVal) { ...@@ -797,8 +872,8 @@ static int32_t getPositionValue(const SValueNode* pVal) {
static int32_t translateOrderByPosition(STranslateContext* pCxt, SNodeList* pProjectionList, SNodeList* pOrderByList, bool* pOther) { static int32_t translateOrderByPosition(STranslateContext* pCxt, SNodeList* pProjectionList, SNodeList* pOrderByList, bool* pOther) {
*pOther = false; *pOther = false;
SNode* pNode; SNode* pNode = NULL;
FOREACH(pNode, pOrderByList) { WHERE_EACH(pNode, pOrderByList) {
SNode* pExpr = ((SOrderByExprNode*)pNode)->pExpr; SNode* pExpr = ((SOrderByExprNode*)pNode)->pExpr;
if (QUERY_NODE_VALUE == nodeType(pExpr)) { if (QUERY_NODE_VALUE == nodeType(pExpr)) {
SValueNode* pVal = (SValueNode*)pExpr; SValueNode* pVal = (SValueNode*)pExpr;
...@@ -823,6 +898,7 @@ static int32_t translateOrderByPosition(STranslateContext* pCxt, SNodeList* pPro ...@@ -823,6 +898,7 @@ static int32_t translateOrderByPosition(STranslateContext* pCxt, SNodeList* pPro
} else { } else {
*pOther = true; *pOther = true;
} }
WHERE_NEXT;
} }
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
...@@ -845,11 +921,10 @@ static int32_t translateOrderBy(STranslateContext* pCxt, SSelectStmt* pSelect) { ...@@ -845,11 +921,10 @@ static int32_t translateOrderBy(STranslateContext* pCxt, SSelectStmt* pSelect) {
} }
static int32_t translateSelectList(STranslateContext* pCxt, SSelectStmt* pSelect) { static int32_t translateSelectList(STranslateContext* pCxt, SSelectStmt* pSelect) {
bool isSelectStar = false; pCxt->currClause = SQL_CLAUSE_SELECT;
int32_t code = translateStar(pCxt, pSelect, &isSelectStar); int32_t code = translateExprList(pCxt, pSelect->pProjectionList);
if (TSDB_CODE_SUCCESS == code && !isSelectStar) { if (TSDB_CODE_SUCCESS == code) {
pCxt->currClause = SQL_CLAUSE_SELECT; code = translateStar(pCxt, pSelect);
code = translateExprList(pCxt, pSelect->pProjectionList);
} }
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
code = checkExprListForGroupBy(pCxt, pSelect->pProjectionList); code = checkExprListForGroupBy(pCxt, pSelect->pProjectionList);
...@@ -1829,10 +1904,13 @@ static int32_t getSmaIndexBuildAst(STranslateContext* pCxt, SCreateIndexStmt* pS ...@@ -1829,10 +1904,13 @@ static int32_t getSmaIndexBuildAst(STranslateContext* pCxt, SCreateIndexStmt* pS
pSelect->pFromTable = (SNode*)pTable; pSelect->pFromTable = (SNode*)pTable;
pSelect->pProjectionList = nodesCloneList(pStmt->pOptions->pFuncs); pSelect->pProjectionList = nodesCloneList(pStmt->pOptions->pFuncs);
if (NULL == pTable) { SFunctionNode* pFunc = nodesMakeNode(QUERY_NODE_FUNCTION);
if (NULL == pSelect->pProjectionList || NULL == pFunc) {
nodesDestroyNode(pSelect); nodesDestroyNode(pSelect);
return TSDB_CODE_OUT_OF_MEMORY; return TSDB_CODE_OUT_OF_MEMORY;
} }
strcpy(pFunc->functionName, "_wstartts");
nodesListPushFront(pSelect->pProjectionList, pFunc);
SNode* pProject = NULL; SNode* pProject = NULL;
FOREACH(pProject, pSelect->pProjectionList) { FOREACH(pProject, pSelect->pProjectionList) {
sprintf(((SExprNode*)pProject)->aliasName, "#sma_%p", pProject); sprintf(((SExprNode*)pProject)->aliasName, "#sma_%p", pProject);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册