enh: translate cols in clauses
This commit is contained in:
parent
44f6859d65
commit
e16b96db72
|
@ -461,7 +461,7 @@ This document details the server error codes that may be encountered when using
|
||||||
| 0x80002687 | Invalid using cols function | Illegal using cols function | Check and correct the SQL statement |
|
| 0x80002687 | Invalid using cols function | Illegal using cols function | Check and correct the SQL statement |
|
||||||
| 0x80002688 | Cols function's first param must be a select function | The first parameter of the cols function should be a selection function | Check and correct the SQL statement |
|
| 0x80002688 | Cols function's first param must be a select function | The first parameter of the cols function should be a selection function | Check and correct the SQL statement |
|
||||||
| 0x80002689 | Invalid using cols function with multiple output columns | Illegal using the cols function for multiple column output | Check and correct the SQL statement |
|
| 0x80002689 | Invalid using cols function with multiple output columns | Illegal using the cols function for multiple column output | Check and correct the SQL statement |
|
||||||
| 0x80002690 | Invalid using alias for cols function | Illegal cols function alias | Check and correct the SQL statement |
|
| 0x8000268A | Invalid using alias for cols function | Illegal cols function alias | Check and correct the SQL statement |
|
||||||
| 0x800026FF | Parser internal error | Internal error in parser | Preserve the scene and logs, report issue on GitHub |
|
| 0x800026FF | Parser internal error | Internal error in parser | Preserve the scene and logs, report issue on GitHub |
|
||||||
| 0x80002700 | Planner internal error | Internal error in planner | Preserve the scene and logs, report issue on GitHub |
|
| 0x80002700 | Planner internal error | Internal error in planner | Preserve the scene and logs, report issue on GitHub |
|
||||||
| 0x80002701 | Expect ts equal | JOIN condition validation failed | Preserve the scene and logs, report issue on GitHub |
|
| 0x80002701 | Expect ts equal | JOIN condition validation failed | Preserve the scene and logs, report issue on GitHub |
|
||||||
|
|
|
@ -478,7 +478,7 @@ description: TDengine 服务端的错误码列表和详细说明
|
||||||
| 0x80002687 | Invalid using cols function | cols函数使用错误 | 检查并修正SQL语句 |
|
| 0x80002687 | Invalid using cols function | cols函数使用错误 | 检查并修正SQL语句 |
|
||||||
| 0x80002688 | Cols function's first param must be a select function | cols函数第一个参数应该为选择函数 | 检查并修正SQL语句 |
|
| 0x80002688 | Cols function's first param must be a select function | cols函数第一个参数应该为选择函数 | 检查并修正SQL语句 |
|
||||||
| 0x80002689 | Invalid using cols function with multiple output columns | 多列输出的 cols 函数使用错误 | 检查并修正SQL语句 |
|
| 0x80002689 | Invalid using cols function with multiple output columns | 多列输出的 cols 函数使用错误 | 检查并修正SQL语句 |
|
||||||
| 0x80002690 | Invalid using alias for cols function | cols 函数输出列重命名错误 | 检查并修正SQL语句 |
|
| 0x8000268A | Invalid using alias for cols function | cols 函数输出列重命名错误 | 检查并修正SQL语句 |
|
||||||
| 0x800026FF | Parser internal error | 解析器内部错误 | 保留现场和日志,github上报issue |
|
| 0x800026FF | Parser internal error | 解析器内部错误 | 保留现场和日志,github上报issue |
|
||||||
| 0x80002700 | Planner internal error | 计划期内部错误 | 保留现场和日志,github上报issue |
|
| 0x80002700 | Planner internal error | 计划期内部错误 | 保留现场和日志,github上报issue |
|
||||||
| 0x80002701 | Expect ts equal | JOIN条件校验失败 | 保留现场和日志,github上报issue |
|
| 0x80002701 | Expect ts equal | JOIN条件校验失败 | 保留现场和日志,github上报issue |
|
||||||
|
|
|
@ -5460,9 +5460,83 @@ static int32_t translateClausePosition(STranslateContext* pCxt, SNodeList* pProj
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t rewriteColsFunction(STranslateContext* pCxt, SNodeList** nodeList, SNodeList** selectFuncList);
|
||||||
|
static int32_t translateSelectColsFunction(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||||
|
SNodeList* selectFuncList = NULL;
|
||||||
|
int32_t code = rewriteColsFunction(pCxt, &pSelect->pProjectionList, &selectFuncList);
|
||||||
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
|
goto _end;
|
||||||
|
}
|
||||||
|
if (selectFuncList != NULL) {
|
||||||
|
code = nodesListAppendList(pSelect->pProjectionList, selectFuncList);
|
||||||
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
|
goto _end;
|
||||||
|
}
|
||||||
|
selectFuncList = NULL;
|
||||||
|
}
|
||||||
|
_end:
|
||||||
|
if (selectFuncList) {
|
||||||
|
nodesDestroyList(selectFuncList);
|
||||||
|
}
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t getBindedExprList(STranslateContext* pCxt, SNodeList* projectionList, SNodeList** selectFuncList) {
|
||||||
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
for (int32_t i = 0; i < LIST_LENGTH(projectionList); ++i) {
|
||||||
|
SNode* pNode = nodesListGetNode(projectionList, i);
|
||||||
|
if (((SExprNode*)pNode)->bindTupleFuncIdx > 0) {
|
||||||
|
if (NULL == *selectFuncList) {
|
||||||
|
code = nodesMakeList(selectFuncList);
|
||||||
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
code = nodesListStrictAppend(*selectFuncList, pNode);
|
||||||
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t translateOrderbyColsFunction(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||||
|
SNodeList* selectFuncList = NULL;
|
||||||
|
int32_t code = getBindedExprList(pCxt, pSelect->pProjectionList, &selectFuncList);
|
||||||
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
|
goto _end;
|
||||||
|
}
|
||||||
|
int len = LIST_LENGTH(selectFuncList);
|
||||||
|
code = rewriteColsFunction(pCxt, &pSelect->pOrderByList, &selectFuncList);
|
||||||
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
|
goto _end;
|
||||||
|
}
|
||||||
|
if(LIST_LENGTH(selectFuncList) - len > 0) {
|
||||||
|
for (int i = len; i < LIST_LENGTH(selectFuncList); ++i) {
|
||||||
|
SNode* pNode = nodesListGetNode(selectFuncList, i);
|
||||||
|
int32_t code = nodesListStrictAppend(pSelect->pProjectionList, pNode);
|
||||||
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nodesClearList(selectFuncList);
|
||||||
|
return code;
|
||||||
|
_end:
|
||||||
|
if (selectFuncList) {
|
||||||
|
nodesDestroyList(selectFuncList);
|
||||||
|
}
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t translateOrderBy(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
static int32_t translateOrderBy(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||||
bool other;
|
bool other;
|
||||||
int32_t code = translateClausePosition(pCxt, pSelect->pProjectionList, pSelect->pOrderByList, &other);
|
int32_t code = translateOrderbyColsFunction(pCxt, pSelect);
|
||||||
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
code = translateClausePosition(pCxt, pSelect->pProjectionList, pSelect->pOrderByList, &other);
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
if (0 == LIST_LENGTH(pSelect->pOrderByList)) {
|
if (0 == LIST_LENGTH(pSelect->pOrderByList)) {
|
||||||
NODES_DESTORY_LIST(pSelect->pOrderByList);
|
NODES_DESTORY_LIST(pSelect->pOrderByList);
|
||||||
|
@ -5681,7 +5755,11 @@ static int32_t translatePartitionByList(STranslateContext* pCxt, SSelectStmt* pS
|
||||||
|
|
||||||
static int32_t translateSelectList(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
static int32_t translateSelectList(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||||
pCxt->currClause = SQL_CLAUSE_SELECT;
|
pCxt->currClause = SQL_CLAUSE_SELECT;
|
||||||
int32_t code = translateExprList(pCxt, pSelect->pProjectionList);
|
int32_t code = translateSelectColsFunction(pCxt, pSelect);
|
||||||
|
code = translateOrderbyColsFunction(pCxt, pSelect);
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = translateExprList(pCxt, pSelect->pProjectionList);
|
||||||
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = translateStar(pCxt, pSelect);
|
code = translateStar(pCxt, pSelect);
|
||||||
}
|
}
|
||||||
|
@ -7432,7 +7510,7 @@ static int32_t checkMultColsFuncParam(SNodeList* pParameterList) {
|
||||||
SNode* pNode = NULL;
|
SNode* pNode = NULL;
|
||||||
FOREACH(pNode, pParameterList) {
|
FOREACH(pNode, pParameterList) {
|
||||||
if (index == 0) { // the first parameter is select function
|
if (index == 0) { // the first parameter is select function
|
||||||
if (QUERY_NODE_FUNCTION != nodeType(pNode)) {
|
if (QUERY_NODE_FUNCTION != nodeType(pNode) || isColsFuncByName((SFunctionNode*)pNode)) {
|
||||||
return TSDB_CODE_PAR_INVALID_COLS_FUNCTION;
|
return TSDB_CODE_PAR_INVALID_COLS_FUNCTION;
|
||||||
}
|
}
|
||||||
SFunctionNode* pFunc = (SFunctionNode*)pNode;
|
SFunctionNode* pFunc = (SFunctionNode*)pNode;
|
||||||
|
@ -7474,7 +7552,7 @@ static EDealRes rewriteSingleColsFunc(SNode** pNode, void* pContext) {
|
||||||
}
|
}
|
||||||
SNode* pSelectFunc = nodesListGetNode(pFunc->pParameterList, 0);
|
SNode* pSelectFunc = nodesListGetNode(pFunc->pParameterList, 0);
|
||||||
SNode* pExpr = nodesListGetNode(pFunc->pParameterList, 1);
|
SNode* pExpr = nodesListGetNode(pFunc->pParameterList, 1);
|
||||||
if (nodeType(pSelectFunc) != QUERY_NODE_FUNCTION) {
|
if (nodeType(pSelectFunc) != QUERY_NODE_FUNCTION || isColsFuncByName((SFunctionNode*)pSelectFunc)) {
|
||||||
pCxt->status = TSDB_CODE_PAR_INVALID_COLS_SELECTFUNC;
|
pCxt->status = TSDB_CODE_PAR_INVALID_COLS_SELECTFUNC;
|
||||||
parserError("%s Invalid cols function, the first parameter must be a select function", __func__);
|
parserError("%s Invalid cols function, the first parameter must be a select function", __func__);
|
||||||
return DEAL_RES_ERROR;
|
return DEAL_RES_ERROR;
|
||||||
|
@ -7625,46 +7703,10 @@ static int32_t rewriteColsFunction(STranslateContext* pCxt, SNodeList** nodeList
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t translateColsFunction(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
|
||||||
if (pSelect->pFromTable && QUERY_NODE_TEMP_TABLE == nodeType(pSelect->pFromTable)) {
|
|
||||||
SNode* pSubquery = ((STempTableNode*)pSelect->pFromTable)->pSubquery;
|
|
||||||
if (QUERY_NODE_SELECT_STMT == nodeType(pSubquery)) {
|
|
||||||
SSelectStmt* pSubSelect = (SSelectStmt*)pSubquery;
|
|
||||||
int32_t code = translateColsFunction(pCxt, pSubSelect);
|
|
||||||
if (TSDB_CODE_SUCCESS != code) {
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SNodeList* selectFuncList = NULL;
|
|
||||||
int32_t code = rewriteColsFunction(pCxt, &pSelect->pProjectionList, &selectFuncList);
|
|
||||||
if (code == TSDB_CODE_SUCCESS) {
|
|
||||||
code = rewriteColsFunction(pCxt, &pSelect->pOrderByList, &selectFuncList);
|
|
||||||
}
|
|
||||||
if (TSDB_CODE_SUCCESS != code) {
|
|
||||||
goto _end;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (selectFuncList != NULL) {
|
|
||||||
nodesListAppendList(pSelect->pProjectionList, selectFuncList);
|
|
||||||
selectFuncList = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
_end:
|
|
||||||
if (selectFuncList) {
|
|
||||||
nodesDestroyList(selectFuncList);
|
|
||||||
}
|
|
||||||
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t translateSelectFrom(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
static int32_t translateSelectFrom(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||||
pCxt->pCurrStmt = (SNode*)pSelect;
|
pCxt->pCurrStmt = (SNode*)pSelect;
|
||||||
pCxt->dual = false;
|
pCxt->dual = false;
|
||||||
int32_t code = translateColsFunction(pCxt, pSelect);
|
int32_t code = translateFrom(pCxt, &pSelect->pFromTable);
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
|
||||||
code = translateFrom(pCxt, &pSelect->pFromTable);
|
|
||||||
}
|
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
pSelect->precision = ((STableNode*)pSelect->pFromTable)->precision;
|
pSelect->precision = ((STableNode*)pSelect->pFromTable)->precision;
|
||||||
code = translateWhere(pCxt, pSelect);
|
code = translateWhere(pCxt, pSelect);
|
||||||
|
|
Loading…
Reference in New Issue