提交 e070ad2b 编写于 作者: X Xiaoyu Wang

TD-13495 planner refactoring

上级 33123636
......@@ -105,7 +105,6 @@ typedef struct SFuncExecEnv {
int32_t calcMemSize;
} SFuncExecEnv;
typedef void* FuncMgtHandle;
typedef bool (*FExecGetEnv)(SFunctionNode* pFunc, SFuncExecEnv* pEnv);
typedef bool (*FExecInit)(struct SqlFunctionCtx *pCtx, struct SResultRowEntryInfo* pResultCellInfo);
typedef void (*FExecProcess)(struct SqlFunctionCtx *pCtx);
......@@ -120,9 +119,7 @@ typedef struct SFuncExecFuncs {
int32_t fmFuncMgtInit();
int32_t fmGetHandle(FuncMgtHandle* pHandle);
int32_t fmGetFuncInfo(FuncMgtHandle handle, const char* pFuncName, int32_t* pFuncId, int32_t* pFuncType);
int32_t fmGetFuncInfo(const char* pFuncName, int32_t* pFuncId, int32_t* pFuncType);
int32_t fmGetFuncResultType(SFunctionNode* pFunc);
......@@ -136,7 +133,7 @@ bool fmIsTimeorderFunc(int32_t funcId);
int32_t fmFuncScanType(int32_t funcId);
int32_t fmGetFuncExecFuncs(FuncMgtHandle handle, int32_t funcId, SFuncExecFuncs* pFpSet);
int32_t fmGetFuncExecFuncs(int32_t funcId, SFuncExecFuncs* pFpSet);
#ifdef __cplusplus
}
......
......@@ -49,7 +49,6 @@ typedef enum ENodeType {
QUERY_NODE_VALUE,
QUERY_NODE_OPERATOR,
QUERY_NODE_LOGIC_CONDITION,
QUERY_NODE_IS_NULL_CONDITION,
QUERY_NODE_FUNCTION,
QUERY_NODE_REAL_TABLE,
QUERY_NODE_TEMP_TABLE,
......@@ -62,6 +61,7 @@ typedef enum ENodeType {
QUERY_NODE_INTERVAL_WINDOW,
QUERY_NODE_NODE_LIST,
QUERY_NODE_FILL,
QUERY_NODE_COLUMN_REF,
// Only be used in parser module.
QUERY_NODE_RAW_EXPR,
......@@ -69,7 +69,11 @@ typedef enum ENodeType {
// Statement nodes are used in parser and planner module.
QUERY_NODE_SET_OPERATOR,
QUERY_NODE_SELECT_STMT,
QUERY_NODE_SHOW_STMT
QUERY_NODE_SHOW_STMT,
QUERY_NODE_LOGIC_PLAN_SCAN,
QUERY_NODE_LOGIC_PLAN_FILTER,
QUERY_NODE_LOGIC_PLAN_AGG
} ENodeType;
/**
......@@ -121,7 +125,8 @@ void nodesRewriteListPostOrder(SNodeList* pList, FNodeRewriter rewriter, void* p
bool nodesEqualNode(const SNode* a, const SNode* b);
void nodesCloneNode(const SNode* pNode);
SNode* nodesCloneNode(const SNode* pNode);
SNodeList* nodesCloneList(const SNodeList* pList);
int32_t nodesNodeToString(const SNode* pNode, char** pStr, int32_t* pLen);
int32_t nodesStringToNode(const char* pStr, SNode** pNode);
......
......@@ -37,7 +37,7 @@ typedef struct SDataType {
} SDataType;
typedef struct SExprNode {
ENodeType nodeType;
ENodeType type;
SDataType resType;
char aliasName[TSDB_COL_NAME_LEN];
SNodeList* pAssociationList;
......@@ -59,6 +59,11 @@ typedef struct SColumnNode {
SNode* pProjectRef;
} SColumnNode;
typedef struct SColumnRef {
ENodeType type;
int32_t slotId;
} SColumnRef;
typedef struct SValueNode {
SExprNode node; // QUERY_NODE_VALUE
char* literal;
......@@ -93,6 +98,8 @@ typedef enum EOperatorType {
OP_TYPE_NOT_LIKE,
OP_TYPE_MATCH,
OP_TYPE_NMATCH,
OP_TYPE_IS_NULL,
OP_TYPE_IS_NOT_NULL,
// json operator
OP_TYPE_JSON_GET_VALUE,
......@@ -118,12 +125,6 @@ typedef struct SLogicConditionNode {
SNodeList* pParameterList;
} SLogicConditionNode;
typedef struct SIsNullCondNode {
SExprNode node; // QUERY_NODE_IS_NULL_CONDITION
SNode* pExpr;
bool isNull;
} SIsNullCondNode;
typedef struct SNodeListNode {
ENodeType type; // QUERY_NODE_NODE_LIST
SNodeList* pNodeList;
......@@ -138,7 +139,7 @@ typedef struct SFunctionNode {
} SFunctionNode;
typedef struct STableNode {
ENodeType type;
SExprNode node;
char dbName[TSDB_DB_NAME_LEN];
char tableName[TSDB_TABLE_NAME_LEN];
char tableAlias[TSDB_TABLE_NAME_LEN];
......
......@@ -459,6 +459,7 @@ int32_t* taosGetErrno();
#define TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION TAOS_DEF_ERROR_CODE(0, 0x260A) //Not a GROUP BY expression
#define TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION TAOS_DEF_ERROR_CODE(0, 0x260B) //Not SELECTed expression
#define TSDB_CODE_PAR_NOT_SINGLE_GROUP TAOS_DEF_ERROR_CODE(0, 0x260C) //Not a single-group group function
#define TSDB_CODE_PAR_OUT_OF_MEMORY TAOS_DEF_ERROR_CODE(0, 0x260D) //Out of memory
#ifdef __cplusplus
}
......
......@@ -40,14 +40,8 @@ int32_t fmFuncMgtInit() {
return TSDB_CODE_SUCCESS;
}
int32_t fmGetHandle(FuncMgtHandle* pHandle) {
*pHandle = &gFunMgtService;
return TSDB_CODE_SUCCESS;
}
int32_t fmGetFuncInfo(FuncMgtHandle handle, const char* pFuncName, int32_t* pFuncId, int32_t* pFuncType) {
SFuncMgtService* pService = (SFuncMgtService*)handle;
void* pVal = taosHashGet(pService->pFuncNameHashTable, pFuncName, strlen(pFuncName));
int32_t fmGetFuncInfo(const char* pFuncName, int32_t* pFuncId, int32_t* pFuncType) {
void* pVal = taosHashGet(gFunMgtService.pFuncNameHashTable, pFuncName, strlen(pFuncName));
if (NULL == pVal) {
return TSDB_CODE_FAILED;
}
......@@ -66,6 +60,17 @@ int32_t fmGetFuncResultType(SFunctionNode* pFunc) {
return funcMgtBuiltins[pFunc->funcId].checkFunc(pFunc);
}
int32_t fmGetFuncExecFuncs(int32_t funcId, SFuncExecFuncs* pFpSet) {
if (funcId < 0 || funcId >= funcMgtBuiltinsNum) {
return TSDB_CODE_FAILED;
}
pFpSet->getEnv = funcMgtBuiltins[funcId].getEnvFunc;
pFpSet->init = funcMgtBuiltins[funcId].initFunc;
pFpSet->process = funcMgtBuiltins[funcId].processFunc;
pFpSet->finalize = funcMgtBuiltins[funcId].finalizeFunc;
return TSDB_CODE_SUCCESS;
}
bool fmIsAggFunc(int32_t funcId) {
if (funcId < 0 || funcId >= funcMgtBuiltinsNum) {
return false;
......
......@@ -13,8 +13,179 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "nodes.h"
#include "querynodes.h"
#include "taos.h"
void nodesCloneNode(const SNode* pNode) {
#define COPY_SCALAR_FIELD(fldname) \
do { \
(pDst)->fldname = (pSrc)->fldname; \
} while (0)
#define COPY_CHAR_ARRAY_FIELD(fldname) \
do { \
strcpy((pDst)->fldname, (pSrc)->fldname); \
} while (0)
#define COPY_CHAR_POINT_FIELD(fldname) \
do { \
(pDst)->fldname = strdup((pSrc)->fldname); \
} while (0)
#define COPY_NODE_FIELD(fldname) \
do { \
(pDst)->fldname = nodesCloneNode((pSrc)->fldname); \
if (NULL == (pDst)->fldname) { \
nodesDestroyNode((SNode*)(pDst)); \
return NULL; \
} \
} while (0)
#define COPY_NODE_LIST_FIELD(fldname) \
do { \
(pDst)->fldname = nodesCloneList((pSrc)->fldname); \
if (NULL == (pDst)->fldname) { \
nodesDestroyNode((SNode*)(pDst)); \
return NULL; \
} \
} while (0)
static void dataTypeCopy(const SDataType* pSrc, SDataType* pDst) {
COPY_SCALAR_FIELD(type);
COPY_SCALAR_FIELD(precision);
COPY_SCALAR_FIELD(scale);
COPY_SCALAR_FIELD(bytes);
}
static void exprNodeCopy(const SExprNode* pSrc, SExprNode* pDst) {
COPY_SCALAR_FIELD(type);
dataTypeCopy(&pSrc->resType, &pDst->resType);
COPY_CHAR_ARRAY_FIELD(aliasName);
// COPY_NODE_LIST_FIELD(pAssociationList);
}
static SNode* columnNodeCopy(const SColumnNode* pSrc, SColumnNode* pDst) {
exprNodeCopy((const SExprNode*)&pSrc, (SExprNode*)&pDst);
COPY_SCALAR_FIELD(colId);
COPY_SCALAR_FIELD(colType);
COPY_CHAR_ARRAY_FIELD(dbName);
COPY_CHAR_ARRAY_FIELD(tableName);
COPY_CHAR_ARRAY_FIELD(tableAlias);
COPY_CHAR_ARRAY_FIELD(colName);
// COPY_NODE_FIELD(pProjectRef);
return (SNode*)pDst;
}
static SNode* valueNodeCopy(const SValueNode* pSrc, SValueNode* pDst) {
exprNodeCopy((const SExprNode*)&pSrc, (SExprNode*)&pDst);
COPY_CHAR_POINT_FIELD(literal);
COPY_SCALAR_FIELD(isDuration);
switch (pSrc->node.resType.type) {
case TSDB_DATA_TYPE_NULL:
break;
case TSDB_DATA_TYPE_BOOL:
COPY_SCALAR_FIELD(datum.b);
break;
case TSDB_DATA_TYPE_TINYINT:
case TSDB_DATA_TYPE_SMALLINT:
case TSDB_DATA_TYPE_INT:
case TSDB_DATA_TYPE_BIGINT:
case TSDB_DATA_TYPE_TIMESTAMP:
COPY_SCALAR_FIELD(datum.i);
break;
case TSDB_DATA_TYPE_UTINYINT:
case TSDB_DATA_TYPE_USMALLINT:
case TSDB_DATA_TYPE_UINT:
case TSDB_DATA_TYPE_UBIGINT:
COPY_SCALAR_FIELD(datum.u);
break;
case TSDB_DATA_TYPE_FLOAT:
case TSDB_DATA_TYPE_DOUBLE:
COPY_SCALAR_FIELD(datum.d);
break;
case TSDB_DATA_TYPE_BINARY:
case TSDB_DATA_TYPE_NCHAR:
case TSDB_DATA_TYPE_VARCHAR:
case TSDB_DATA_TYPE_VARBINARY:
COPY_CHAR_POINT_FIELD(datum.p);
break;
case TSDB_DATA_TYPE_JSON:
case TSDB_DATA_TYPE_DECIMAL:
case TSDB_DATA_TYPE_BLOB:
// todo
default:
break;
}
return (SNode*)pDst;
}
static SNode* operatorNodeCopy(const SOperatorNode* pSrc, SOperatorNode* pDst) {
exprNodeCopy((const SExprNode*)&pSrc, (SExprNode*)&pDst);
COPY_SCALAR_FIELD(opType);
COPY_NODE_FIELD(pLeft);
COPY_NODE_FIELD(pRight);
return (SNode*)pDst;
}
static SNode* logicConditionNodeCopy(const SLogicConditionNode* pSrc, SLogicConditionNode* pDst) {
exprNodeCopy((const SExprNode*)&pSrc, (SExprNode*)&pDst);
COPY_SCALAR_FIELD(condType);
COPY_NODE_LIST_FIELD(pParameterList);
return (SNode*)pDst;
}
static SNode* functionNodeCopy(const SFunctionNode* pSrc, SFunctionNode* pDst) {
exprNodeCopy((const SExprNode*)&pSrc, (SExprNode*)&pDst);
COPY_CHAR_ARRAY_FIELD(functionName);
COPY_SCALAR_FIELD(funcId);
COPY_SCALAR_FIELD(funcType);
COPY_NODE_LIST_FIELD(pParameterList);
return (SNode*)pDst;
}
SNode* nodesCloneNode(const SNode* pNode) {
if (NULL == pNode) {
return NULL;
}
SNode* pDst = nodesMakeNode(nodeType(pNode));
if (NULL == pDst) {
return NULL;
}
switch (nodeType(pNode)) {
case QUERY_NODE_COLUMN:
return columnNodeCopy((const SColumnNode*)pNode, (SColumnNode*)pDst);
case QUERY_NODE_VALUE:
return valueNodeCopy((const SValueNode*)pNode, (SValueNode*)pDst);
case QUERY_NODE_OPERATOR:
return operatorNodeCopy((const SOperatorNode*)pNode, (SOperatorNode*)pDst);
case QUERY_NODE_LOGIC_CONDITION:
return logicConditionNodeCopy((const SLogicConditionNode*)pNode, (SLogicConditionNode*)pDst);
case QUERY_NODE_FUNCTION:
return functionNodeCopy((const SFunctionNode*)pNode, (SFunctionNode*)pDst);
case QUERY_NODE_REAL_TABLE:
case QUERY_NODE_TEMP_TABLE:
case QUERY_NODE_JOIN_TABLE:
case QUERY_NODE_GROUPING_SET:
case QUERY_NODE_ORDER_BY_EXPR:
case QUERY_NODE_LIMIT:
default:
break;
}
return pDst;
}
SNodeList* nodesCloneList(const SNodeList* pList) {
SNodeList* pDst = nodesMakeList();
if (NULL == pDst) {
return NULL;
}
SNode* pNode;
FOREACH(pNode, pList) {
SNode* pNewNode = nodesCloneNode(pNode);
if (NULL == pNewNode) {
nodesDestroyList(pDst);
return NULL;
}
nodesListAppend(pDst, pNewNode);
}
return pDst;
}
......@@ -21,7 +21,6 @@ int32_t nodesNodeToString(const SNode* pNode, char** pStr, int32_t* pLen) {
case QUERY_NODE_VALUE:
case QUERY_NODE_OPERATOR:
case QUERY_NODE_LOGIC_CONDITION:
case QUERY_NODE_IS_NULL_CONDITION:
case QUERY_NODE_FUNCTION:
case QUERY_NODE_REAL_TABLE:
case QUERY_NODE_TEMP_TABLE:
......
......@@ -89,12 +89,6 @@ static bool logicConditionNodeEqual(const SLogicConditionNode* a, const SLogicCo
return true;
}
static bool isNullConditionNodeEqual(const SIsNullCondNode* a, const SIsNullCondNode* b) {
COMPARE_NODE_FIELD(pExpr);
COMPARE_SCALAR_FIELD(isNull);
return true;
}
static bool functionNodeEqual(const SFunctionNode* a, const SFunctionNode* b) {
COMPARE_SCALAR_FIELD(funcId);
COMPARE_NODE_LIST_FIELD(pParameterList);
......@@ -123,8 +117,6 @@ bool nodesEqualNode(const SNode* a, const SNode* b) {
return operatorNodeEqual((const SOperatorNode*)a, (const SOperatorNode*)b);
case QUERY_NODE_LOGIC_CONDITION:
return logicConditionNodeEqual((const SLogicConditionNode*)a, (const SLogicConditionNode*)b);
case QUERY_NODE_IS_NULL_CONDITION:
return isNullConditionNodeEqual((const SIsNullCondNode*)a, (const SIsNullCondNode*)b);
case QUERY_NODE_FUNCTION:
return functionNodeEqual((const SFunctionNode*)a, (const SFunctionNode*)b);
case QUERY_NODE_REAL_TABLE:
......
......@@ -53,9 +53,6 @@ static EDealRes walkNode(SNode* pNode, ETraversalOrder order, FNodeWalker walker
case QUERY_NODE_LOGIC_CONDITION:
res = walkList(((SLogicConditionNode*)pNode)->pParameterList, order, walker, pContext);
break;
case QUERY_NODE_IS_NULL_CONDITION:
res = walkNode(((SIsNullCondNode*)pNode)->pExpr, order, walker, pContext);
break;
case QUERY_NODE_FUNCTION:
res = walkList(((SFunctionNode*)pNode)->pParameterList, order, walker, pContext);
break;
......@@ -179,9 +176,6 @@ static EDealRes rewriteNode(SNode** pRawNode, ETraversalOrder order, FNodeRewrit
case QUERY_NODE_LOGIC_CONDITION:
res = rewriteList(((SLogicConditionNode*)pNode)->pParameterList, order, rewriter, pContext);
break;
case QUERY_NODE_IS_NULL_CONDITION:
res = rewriteNode(&(((SIsNullCondNode*)pNode)->pExpr), order, rewriter, pContext);
break;
case QUERY_NODE_FUNCTION:
res = rewriteList(((SFunctionNode*)pNode)->pParameterList, order, rewriter, pContext);
break;
......
......@@ -36,8 +36,6 @@ SNode* nodesMakeNode(ENodeType type) {
return makeNode(type, sizeof(SOperatorNode));
case QUERY_NODE_LOGIC_CONDITION:
return makeNode(type, sizeof(SLogicConditionNode));
case QUERY_NODE_IS_NULL_CONDITION:
return makeNode(type, sizeof(SIsNullCondNode));
case QUERY_NODE_FUNCTION:
return makeNode(type, sizeof(SFunctionNode));
case QUERY_NODE_REAL_TABLE:
......
......@@ -43,7 +43,6 @@ SNode* createLogicConditionNode(SAstCreateContext* pCxt, ELogicConditionType typ
SNode* createOperatorNode(SAstCreateContext* pCxt, EOperatorType type, SNode* pLeft, SNode* pRight);
SNode* createBetweenAnd(SAstCreateContext* pCxt, SNode* pExpr, SNode* pLeft, SNode* pRight);
SNode* createNotBetweenAnd(SAstCreateContext* pCxt, SNode* pExpr, SNode* pLeft, SNode* pRight);
SNode* createIsNullCondNode(SAstCreateContext* pCxt, SNode* pExpr, bool isNull);
SNode* createFunctionNode(SAstCreateContext* pCxt, const SToken* pFuncName, SNodeList* pParameterList);
SNode* createNodeListNode(SAstCreateContext* pCxt, SNodeList* pList);
SNode* createRealTableNode(SAstCreateContext* pCxt, const SToken* pDbName, const SToken* pTableName, const SToken* pTableAlias);
......
......@@ -192,12 +192,12 @@ predicate(A) ::= expression(B) NOT BETWEEN expression(C) AND expression(D).
predicate(A) ::= expression(B) IS NULL(C). {
PARSER_TRACE;
SToken s = getTokenFromRawExprNode(pCxt, B);
A = createRawExprNodeExt(pCxt, &s, &C, createIsNullCondNode(pCxt, releaseRawExprNode(pCxt, B), true));
A = createRawExprNodeExt(pCxt, &s, &C, createOperatorNode(pCxt, OP_TYPE_IS_NULL, releaseRawExprNode(pCxt, B), NULL));
}
predicate(A) ::= expression(B) IS NOT NULL(C). {
PARSER_TRACE;
SToken s = getTokenFromRawExprNode(pCxt, B);
A = createRawExprNodeExt(pCxt, &s, &C, createIsNullCondNode(pCxt, releaseRawExprNode(pCxt, B), false));
A = createRawExprNodeExt(pCxt, &s, &C, createOperatorNode(pCxt, OP_TYPE_IS_NOT_NULL, releaseRawExprNode(pCxt, B), NULL));
}
predicate(A) ::= expression(B) in_op(C) in_predicate_value(D). {
PARSER_TRACE;
......
......@@ -13,9 +13,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "querynodes.h"
#include "parser.h"
#ifndef _TD_AST_CREATE_FUNCS_H_
#define _TD_AST_CREATE_FUNCS_H_
......@@ -23,9 +20,19 @@
extern "C" {
#endif
#include "querynodes.h"
#include "parser.h"
typedef enum EStmtType {
STMT_TYPE_CMD = 1,
STMT_TYPE_QUERY
} EStmtType;
typedef struct SQuery {
EStmtType stmtType;
SNode* pRoot;
// todo reslut meta
int32_t numOfResCols;
SSchema* pResSchema;
} SQuery;
int32_t doParse(SParseContext* pParseCxt, SQuery* pQuery);
......
......@@ -84,6 +84,10 @@ SNode* releaseRawExprNode(SAstCreateContext* pCxt, SNode* pNode) {
}
SToken getTokenFromRawExprNode(SAstCreateContext* pCxt, SNode* pNode) {
if (NULL == pNode || QUERY_NODE_RAW_EXPR != nodeType(pNode)) {
pCxt->valid = false;
return nil_token;
}
SRawExprNode* target = (SRawExprNode*)pNode;
SToken t = { .type = 0, .z = target->p, .n = target->n};
return t;
......@@ -166,14 +170,6 @@ SNode* createNotBetweenAnd(SAstCreateContext* pCxt, SNode* pExpr, SNode* pLeft,
createOperatorNode(pCxt, OP_TYPE_LOWER_THAN, pExpr, pLeft), createOperatorNode(pCxt, OP_TYPE_GREATER_THAN, pExpr, pRight));
}
SNode* createIsNullCondNode(SAstCreateContext* pCxt, SNode* pExpr, bool isNull) {
SIsNullCondNode* cond = (SIsNullCondNode*)nodesMakeNode(QUERY_NODE_IS_NULL_CONDITION);
CHECK_OUT_OF_MEM(cond);
cond->pExpr = pExpr;
cond->isNull = isNull;
return (SNode*)cond;
}
SNode* createFunctionNode(SAstCreateContext* pCxt, const SToken* pFuncName, SNodeList* pParameterList) {
SFunctionNode* func = (SFunctionNode*)nodesMakeNode(QUERY_NODE_FUNCTION);
CHECK_OUT_OF_MEM(func);
......@@ -292,7 +288,11 @@ SNode* createGroupingSetNode(SAstCreateContext* pCxt, SNode* pNode) {
}
SNode* setProjectionAlias(SAstCreateContext* pCxt, SNode* pNode, const SToken* pAlias) {
strncpy(((SExprNode*)pNode)->aliasName, pAlias->z, pAlias->n);
if (NULL == pNode || !pCxt->valid) {
return pNode;
}
uint32_t maxLen = sizeof(((SExprNode*)pNode)->aliasName);
strncpy(((SExprNode*)pNode)->aliasName, pAlias->z, pAlias->n > maxLen ? maxLen : pAlias->n);
return pNode;
}
......
......@@ -1717,7 +1717,7 @@ static YYACTIONTYPE yy_reduce(
{
PARSER_TRACE;
SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy56);
yylhsminor.yy56 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createIsNullCondNode(pCxt, releaseRawExprNode(pCxt, yymsp[-2].minor.yy56), true));
yylhsminor.yy56 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createOperatorNode(pCxt, OP_TYPE_IS_NULL, releaseRawExprNode(pCxt, yymsp[-2].minor.yy56), NULL));
}
yymsp[-2].minor.yy56 = yylhsminor.yy56;
break;
......@@ -1725,7 +1725,7 @@ static YYACTIONTYPE yy_reduce(
{
PARSER_TRACE;
SToken s = getTokenFromRawExprNode(pCxt, yymsp[-3].minor.yy56);
yylhsminor.yy56 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createIsNullCondNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy56), false));
yylhsminor.yy56 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createOperatorNode(pCxt, OP_TYPE_IS_NOT_NULL, releaseRawExprNode(pCxt, yymsp[-3].minor.yy56), NULL));
}
yymsp[-3].minor.yy56 = yylhsminor.yy56;
break;
......
......@@ -174,6 +174,19 @@ static uint32_t getToken(const char* z, uint32_t* tokenId) {
return n;
}
static EStmtType getStmtType(const SNode* pRootNode) {
if (NULL == pRootNode) {
return STMT_TYPE_CMD;
}
switch (nodeType(pRootNode)) {
case QUERY_NODE_SELECT_STMT:
return STMT_TYPE_QUERY;
default:
break;
}
return STMT_TYPE_CMD;
}
int32_t doParse(SParseContext* pParseCxt, SQuery* pQuery) {
SAstCreateContext cxt;
createAstCreateContext(pParseCxt, &cxt);
......@@ -181,15 +194,12 @@ int32_t doParse(SParseContext* pParseCxt, SQuery* pQuery) {
int32_t i = 0;
while (1) {
SToken t0 = {0};
// printf("===========================\n");
if (cxt.pQueryCxt->pSql[i] == 0) {
NewParse(pParser, 0, t0, &cxt);
goto abort_parse;
}
// printf("input: [%s]\n", cxt.pQueryCxt->pSql + i);
t0.n = getToken((char *)&cxt.pQueryCxt->pSql[i], &t0.type);
t0.z = (char *)(cxt.pQueryCxt->pSql + i);
// printf("token : %d %d [%s]\n", t0.type, t0.n, t0.z);
i += t0.n;
switch (t0.type) {
......@@ -201,14 +211,12 @@ int32_t doParse(SParseContext* pParseCxt, SQuery* pQuery) {
NewParse(pParser, 0, t0, &cxt);
goto abort_parse;
}
case TK_QUESTION:
case TK_ILLEGAL: {
snprintf(cxt.pQueryCxt->pMsg, cxt.pQueryCxt->msgLen, "unrecognized token: \"%s\"", t0.z);
cxt.valid = false;
goto abort_parse;
}
case TK_HEX:
case TK_OCT:
case TK_BIN: {
......@@ -216,7 +224,6 @@ int32_t doParse(SParseContext* pParseCxt, SQuery* pQuery) {
cxt.valid = false;
goto abort_parse;
}
default:
NewParse(pParser, t0.type, t0, &cxt);
// NewParseTrace(stdout, "");
......@@ -227,9 +234,9 @@ int32_t doParse(SParseContext* pParseCxt, SQuery* pQuery) {
}
abort_parse:
// printf("doParse completed.\n");
NewParseFree(pParser, free);
destroyAstCreateContext(&cxt);
pQuery->stmtType = getStmtType(cxt.pRootNode);
pQuery->pRoot = cxt.pRootNode;
return cxt.valid ? TSDB_CODE_SUCCESS : TSDB_CODE_FAILED;
}
......@@ -255,7 +262,6 @@ static bool beforeHaving(ESqlClause clause) {
typedef struct STranslateContext {
SParseContext* pParseCxt;
FuncMgtHandle fmgt;
int32_t errCode;
SMsgBuf msgBuf;
SArray* pNsLevel; // element is SArray*, the element of this subarray is STableNode*
......@@ -292,6 +298,8 @@ static char* getSyntaxErrFormat(int32_t errCode) {
return "Not SELECTed expression";
case TSDB_CODE_PAR_NOT_SINGLE_GROUP:
return "Not a single-group group function";
case TSDB_CODE_PAR_OUT_OF_MEMORY:
return "Out of memory";
default:
return "Unknown error";
}
......@@ -376,12 +384,15 @@ static void setColumnInfoByExpr(const STableNode* pTable, SExprNode* pExpr, SCol
pCol->node.resType = pExpr->resType;
}
static int32_t createColumnNodeByTable(const STableNode* pTable, SNodeList* pList) {
static int32_t createColumnNodeByTable(STranslateContext* pCxt, const STableNode* pTable, SNodeList* pList) {
if (QUERY_NODE_REAL_TABLE == nodeType(pTable)) {
const STableMeta* pMeta = ((SRealTableNode*)pTable)->pMeta;
int32_t nums = pMeta->tableInfo.numOfTags + pMeta->tableInfo.numOfColumns;
for (int32_t i = 0; i < nums; ++i) {
SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN);
if (NULL == pCol) {
return generateSyntaxErrMsg(pCxt, TSDB_CODE_PAR_OUT_OF_MEMORY);
}
setColumnInfoBySchema(pTable, pMeta->schema + i, pCol);
nodesListAppend(pList, (SNode*)pCol);
}
......@@ -390,10 +401,14 @@ static int32_t createColumnNodeByTable(const STableNode* pTable, SNodeList* pLis
SNode* pNode;
FOREACH(pNode, pProjectList) {
SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN);
if (NULL == pCol) {
return generateSyntaxErrMsg(pCxt, TSDB_CODE_PAR_OUT_OF_MEMORY);
}
setColumnInfoByExpr(pTable, (SExprNode*)pNode, pCol);
nodesListAppend(pList, (SNode*)pCol);
}
}
return TSDB_CODE_SUCCESS;
}
static bool findAndSetColumn(SColumnNode* pCol, const STableNode* pTable) {
......@@ -539,7 +554,7 @@ static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) {
case TSDB_DATA_TYPE_UTINYINT:
case TSDB_DATA_TYPE_USMALLINT:
case TSDB_DATA_TYPE_UINT:
case TSDB_DATA_TYPE_UBIGINT:{
case TSDB_DATA_TYPE_UBIGINT: {
char* endPtr = NULL;
pVal->datum.u = strtoull(pVal->literal, &endPtr, 10);
break;
......@@ -556,12 +571,20 @@ static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) {
case TSDB_DATA_TYPE_VARBINARY: {
int32_t n = strlen(pVal->literal);
pVal->datum.p = calloc(1, n);
if (NULL == pVal->datum.p) {
generateSyntaxErrMsg(pCxt, TSDB_CODE_PAR_OUT_OF_MEMORY);
return DEAL_RES_ERROR;
}
trimStringCopy(pVal->literal, n, pVal->datum.p);
break;
}
case TSDB_DATA_TYPE_TIMESTAMP: {
int32_t n = strlen(pVal->literal);
char* tmp = calloc(1, n);
if (NULL == tmp) {
generateSyntaxErrMsg(pCxt, TSDB_CODE_PAR_OUT_OF_MEMORY);
return DEAL_RES_ERROR;
}
int32_t len = trimStringCopy(pVal->literal, n, tmp);
if (taosParseTime(tmp, &pVal->datum.i, len, pVal->node.resType.precision, tsDaylight) != TSDB_CODE_SUCCESS) {
tfree(tmp);
......@@ -608,7 +631,7 @@ static EDealRes translateOperator(STranslateContext* pCxt, SOperatorNode* pOp) {
}
static EDealRes translateFunction(STranslateContext* pCxt, SFunctionNode* pFunc) {
if (TSDB_CODE_SUCCESS != fmGetFuncInfo(pCxt->fmgt, pFunc->functionName, &pFunc->funcId, &pFunc->funcType)) {
if (TSDB_CODE_SUCCESS != fmGetFuncInfo(pFunc->functionName, &pFunc->funcId, &pFunc->funcType)) {
generateSyntaxErrMsg(pCxt, TSDB_CODE_PAR_INVALID_FUNTION, pFunc->functionName);
return DEAL_RES_ERROR;
}
......@@ -806,9 +829,15 @@ static int32_t translateStar(STranslateContext* pCxt, SSelectStmt* pSelect, bool
SArray* pTables = taosArrayGetP(pCxt->pNsLevel, pCxt->currLevel);
size_t nums = taosArrayGetSize(pTables);
pSelect->pProjectionList = nodesMakeList();
if (NULL == pSelect->pProjectionList) {
return generateSyntaxErrMsg(pCxt, TSDB_CODE_PAR_OUT_OF_MEMORY);
}
for (size_t i = 0; i < nums; ++i) {
STableNode* pTable = taosArrayGetP(pTables, i);
createColumnNodeByTable(pTable, pSelect->pProjectionList);
int32_t code = createColumnNodeByTable(pCxt, pTable, pSelect->pProjectionList);
if (TSDB_CODE_SUCCESS != code) {
return code;
}
}
*pIsSelectStar = true;
} else {
......@@ -848,7 +877,7 @@ static int32_t getPositionValue(const SValueNode* pVal) {
return -1;
}
static bool translateOrderByPosition(STranslateContext* pCxt, SNodeList* pProjectionList, SNodeList* pOrderByList, bool* pOther) {
static int32_t translateOrderByPosition(STranslateContext* pCxt, SNodeList* pProjectionList, SNodeList* pOrderByList, bool* pOther) {
*pOther = false;
SNode* pNode;
FOREACH(pNode, pOrderByList) {
......@@ -856,18 +885,20 @@ static bool translateOrderByPosition(STranslateContext* pCxt, SNodeList* pProjec
if (QUERY_NODE_VALUE == nodeType(pExpr)) {
SValueNode* pVal = (SValueNode*)pExpr;
if (!translateValue(pCxt, pVal)) {
return false;
return pCxt->errCode;
}
int32_t pos = getPositionValue((SValueNode*)pExpr);
int32_t pos = getPositionValue(pVal);
if (pos < 0) {
ERASE_NODE(pOrderByList);
nodesDestroyNode(pNode);
continue;
} else if (0 == pos || pos > LIST_LENGTH(pProjectionList)) {
generateSyntaxErrMsg(pCxt, TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT);
return false;
return generateSyntaxErrMsg(pCxt, TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT);
} else {
SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN);
if (NULL == pCol) {
return generateSyntaxErrMsg(pCxt, TSDB_CODE_PAR_OUT_OF_MEMORY);
}
setColumnInfoByExpr(NULL, (SExprNode*)nodesListGetNode(pProjectionList, pos - 1), pCol);
((SOrderByExprNode*)pNode)->pExpr = (SNode*)pCol;
nodesDestroyNode(pExpr);
......@@ -876,19 +907,20 @@ static bool translateOrderByPosition(STranslateContext* pCxt, SNodeList* pProjec
*pOther = true;
}
}
return true;
return TSDB_CODE_SUCCESS;
}
static int32_t translateOrderBy(STranslateContext* pCxt, SSelectStmt* pSelect) {
bool other;
if (!translateOrderByPosition(pCxt, pSelect->pProjectionList, pSelect->pOrderByList, &other)) {
return pCxt->errCode;
int32_t code = translateOrderByPosition(pCxt, pSelect->pProjectionList, pSelect->pOrderByList, &other);
if (TSDB_CODE_SUCCESS != code) {
return code;
}
if (!other) {
return TSDB_CODE_SUCCESS;
}
pCxt->currClause = SQL_CLAUSE_ORDER_BY;
int32_t code = translateExprList(pCxt, pSelect->pOrderByList);
code = translateExprList(pCxt, pSelect->pOrderByList);
if (TSDB_CODE_SUCCESS == code) {
code = checkExprListForGroupBy(pCxt, pSelect->pOrderByList);
}
......@@ -945,12 +977,6 @@ static int32_t translateFrom(STranslateContext* pCxt, SNode* pTable) {
return translateTable(pCxt, pTable);
}
// typedef struct SSelectStmt {
// bool isDistinct;
// SNode* pLimit;
// SNode* pSlimit;
// } SSelectStmt;
static int32_t translateSelect(STranslateContext* pCxt, SSelectStmt* pSelect) {
pCxt->pCurrStmt = pSelect;
int32_t code = translateFrom(pCxt, pSelect->pFromTable);
......@@ -1004,6 +1030,26 @@ static int32_t translateSubquery(STranslateContext* pCxt, SNode* pNode) {
return code;
}
int32_t setReslutSchema(STranslateContext* pCxt, SQuery* pQuery) {
if (QUERY_NODE_SELECT_STMT == nodeType(pQuery->pRoot)) {
SSelectStmt* pSelect = (SSelectStmt*)pQuery->pRoot;
pQuery->numOfResCols = LIST_LENGTH(pSelect->pProjectionList);
pQuery->pResSchema = calloc(pQuery->numOfResCols, sizeof(SSchema));
if (NULL == pQuery->pResSchema) {
return generateSyntaxErrMsg(pCxt, TSDB_CODE_PAR_OUT_OF_MEMORY);
}
SNode* pNode;
int32_t index = 0;
FOREACH(pNode, pSelect->pProjectionList) {
SExprNode* pExpr = (SExprNode*)pNode;
pQuery->pResSchema[index].type = pExpr->resType.type;
pQuery->pResSchema[index].bytes = pExpr->resType.bytes;
strcpy(pQuery->pResSchema[index].name, pExpr->aliasName);
}
}
return TSDB_CODE_SUCCESS;
}
int32_t doTranslate(SParseContext* pParseCxt, SQuery* pQuery) {
STranslateContext cxt = {
.pParseCxt = pParseCxt,
......@@ -1014,12 +1060,11 @@ int32_t doTranslate(SParseContext* pParseCxt, SQuery* pQuery) {
.currClause = 0
};
int32_t code = fmFuncMgtInit();
if (TSDB_CODE_SUCCESS != code) {
return code;
if (TSDB_CODE_SUCCESS == code) {
code = translateQuery(&cxt, pQuery->pRoot);
}
code = fmGetHandle(&cxt.fmgt);
if (TSDB_CODE_SUCCESS != code) {
return code;
if (TSDB_CODE_SUCCESS == code && STMT_TYPE_QUERY == pQuery->stmtType) {
code = setReslutSchema(&cxt, pQuery);
}
return translateQuery(&cxt, pQuery->pRoot);
return code;
}
......@@ -8,7 +8,7 @@ target_include_directories(
target_link_libraries(
planner
PRIVATE os util catalog cjson parser function qcom
PRIVATE os util nodes catalog cjson parser function qcom
PUBLIC transport
)
......
......@@ -20,6 +20,33 @@
extern "C" {
#endif
#include "querynodes.h"
#include "planner.h"
typedef struct SLogicNode {
ENodeType type;
SNodeList* pTargets;
SNode* pConditions;
SNodeList* pChildren;
struct SLogicNode* pParent;
} SLogicNode;
typedef struct SScanLogicNode {
SLogicNode node;
SNodeList* pScanCols;
struct STableMeta* pMeta;
} SScanLogicNode;
typedef struct SFilterLogicNode {
SLogicNode node;
} SFilterLogicNode;
typedef struct SAggLogicNode {
SLogicNode node;
SNodeList* pGroupKeys;
SNodeList* pAggFuncs;
} SAggLogicNode;
#ifdef __cplusplus
}
#endif
......
......@@ -13,7 +13,192 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "plannerImpl.h"
#include "functionMgt.h"
// int32_t getPlan(SNode* pRoot, SQueryPlanNode** pQueryPlan) {
static SLogicNode* createQueryLogicNode(SNode* pStmt);
// }
\ No newline at end of file
typedef struct SCollectColumnsCxt {
SNodeList* pCols;
SHashObj* pColIdHash;
} SCollectColumnsCxt;
static EDealRes doCollectColumns(SNode* pNode, void* pContext) {
if (QUERY_NODE_COLUMN == nodeType(pNode)) {
SCollectColumnsCxt* pCxt = (SCollectColumnsCxt*)pContext;
int16_t colId = ((SColumnNode*)pNode)->colId;
if (colId > 0) {
if (NULL == taosHashGet(pCxt->pColIdHash, &colId, sizeof(colId))) {
taosHashPut(pCxt->pColIdHash, &colId, sizeof(colId), NULL, 0);
nodesListAppend(pCxt->pCols, pNode);
}
}
}
return DEAL_RES_CONTINUE;
}
static SNodeList* collectColumns(SSelectStmt* pSelect) {
SCollectColumnsCxt cxt = { .pCols = nodesMakeList(), .pColIdHash = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, HASH_NO_LOCK) };
if (NULL == cxt.pCols || NULL == cxt.pColIdHash) {
return NULL;
}
nodesWalkNode(pSelect->pFromTable, doCollectColumns, &cxt);
nodesWalkNode(pSelect->pWhere, doCollectColumns, &cxt);
nodesWalkList(pSelect->pPartitionByList, doCollectColumns, &cxt);
nodesWalkNode(pSelect->pWindow, doCollectColumns, &cxt);
nodesWalkList(pSelect->pGroupByList, doCollectColumns, &cxt);
nodesWalkNode(pSelect->pHaving, doCollectColumns, &cxt);
nodesWalkList(pSelect->pProjectionList, doCollectColumns, &cxt);
nodesWalkList(pSelect->pOrderByList, doCollectColumns, &cxt);
taosHashCleanup(cxt.pColIdHash);
return cxt.pCols;
}
typedef struct SCollectAggFuncsCxt {
SNodeList* pAggFuncs;
} SCollectAggFuncsCxt;
static EDealRes doCollectAggFuncs(SNode* pNode, void* pContext) {
if (QUERY_NODE_FUNCTION == nodeType(pNode) && fmIsAggFunc(((SFunctionNode*)pNode)->funcId)) {
SCollectAggFuncsCxt* pCxt = (SCollectAggFuncsCxt*)pContext;
nodesListAppend(pCxt->pAggFuncs, pNode);
return DEAL_RES_IGNORE_CHILD;
}
return DEAL_RES_CONTINUE;
}
static SNodeList* collectAggFuncs(SSelectStmt* pSelect) {
SCollectAggFuncsCxt cxt = { .pAggFuncs = nodesMakeList() };
if (NULL == cxt.pAggFuncs) {
return NULL;
}
nodesWalkNode(pSelect->pHaving, doCollectAggFuncs, &cxt);
nodesWalkList(pSelect->pProjectionList, doCollectAggFuncs, &cxt);
if (!pSelect->isDistinct) {
nodesWalkList(pSelect->pOrderByList, doCollectAggFuncs, &cxt);
}
return cxt.pAggFuncs;
}
typedef struct SRewriteExprCxt {
SNodeList* pTargets;
} SRewriteExprCxt;
static EDealRes doRewriteExpr(SNode** pNode, void* pContext) {
SRewriteExprCxt* pCxt = (SRewriteExprCxt*)pContext;
SNode* pTarget;
int32_t index = 0;
FOREACH(pTarget, pCxt->pTargets) {
if (nodesEqualNode(pTarget, *pNode)) {
nodesDestroyNode(*pNode);
*pNode = nodesMakeNode(QUERY_NODE_COLUMN_REF);
((SColumnRef*)*pNode)->slotId = index;
return DEAL_RES_IGNORE_CHILD;
}
++index;
}
return DEAL_RES_CONTINUE;
}
static int32_t rewriteExpr(SNodeList* pTargets, SSelectStmt* pSelect) {
SRewriteExprCxt cxt = { .pTargets = pTargets };
nodesRewriteNode(&(pSelect->pFromTable), doRewriteExpr, &cxt);
nodesRewriteNode(&(pSelect->pWhere), doRewriteExpr, &cxt);
nodesRewriteList(pSelect->pPartitionByList, doRewriteExpr, &cxt);
nodesRewriteNode(&(pSelect->pWindow), doRewriteExpr, &cxt);
nodesRewriteList(pSelect->pGroupByList, doRewriteExpr, &cxt);
nodesRewriteNode(&(pSelect->pHaving), doRewriteExpr, &cxt);
nodesRewriteList(pSelect->pProjectionList, doRewriteExpr, &cxt);
nodesRewriteList(pSelect->pOrderByList, doRewriteExpr, &cxt);
return TSDB_CODE_SUCCESS;
}
static SLogicNode* pushLogicNode(SLogicNode* pRoot, SLogicNode* pNode) {
if (NULL == pRoot) {
return pNode;
}
if (NULL == pNode) {
return pRoot;
}
pRoot->pParent = pNode;
if (NULL == pNode->pChildren) {
pNode->pChildren = nodesMakeList();
}
nodesListAppend(pNode->pChildren, (SNode*)pRoot);
return pNode;
}
static SNodeList* createScanTargets(SNodeList* pCols) {
}
static SLogicNode* createScanLogicNode(SSelectStmt* pSelect, SRealTableNode* pRealTable) {
SScanLogicNode* pScan = (SScanLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_SCAN);
SNodeList* pCols = collectColumns(pSelect);
pScan->pScanCols = nodesCloneList(pCols);
//
rewriteExpr(pScan->pScanCols, pSelect);
pScan->node.pTargets = createScanTargets(pCols);
pScan->pMeta = pRealTable->pMeta;
return (SLogicNode*)pScan;
}
static SLogicNode* createSubqueryLogicNode(SSelectStmt* pSelect, STempTableNode* pTable) {
return createQueryLogicNode(pTable->pSubquery);
}
static SLogicNode* createLogicNodeByTable(SSelectStmt* pSelect, SNode* pTable) {
switch (nodeType(pTable)) {
case QUERY_NODE_REAL_TABLE:
return createScanLogicNode(pSelect, (SRealTableNode*)pTable);
case QUERY_NODE_TEMP_TABLE:
return createSubqueryLogicNode(pSelect, (STempTableNode*)pTable);
case QUERY_NODE_JOIN_TABLE:
default:
break;
}
return NULL;
}
static SLogicNode* createFilterLogicNode(SNode* pWhere) {
if (NULL == pWhere) {
return NULL;
}
SFilterLogicNode* pFilter = (SFilterLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_FILTER);
pFilter->node.pConditions = nodesCloneNode(pWhere);
return (SLogicNode*)pFilter;
}
static SLogicNode* createAggLogicNode(SSelectStmt* pSelect, SNodeList* pGroupByList, SNode* pHaving) {
SNodeList* pAggFuncs = collectAggFuncs(pSelect);
if (NULL == pAggFuncs && NULL == pGroupByList) {
return NULL;
}
SAggLogicNode* pAgg = (SAggLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_AGG);
pAgg->pGroupKeys = nodesCloneList(pGroupByList);
pAgg->pAggFuncs = nodesCloneList(pAggFuncs);
pAgg->node.pConditions = nodesCloneNode(pHaving);
return (SLogicNode*)pAgg;
}
static SLogicNode* createSelectLogicNode(SSelectStmt* pSelect) {
SLogicNode* pRoot = createLogicNodeByTable(pSelect, pSelect->pFromTable);
pRoot = pushLogicNode(pRoot, createFilterLogicNode(pSelect->pWhere));
pRoot = pushLogicNode(pRoot, createAggLogicNode(pSelect, pSelect->pGroupByList, pSelect->pHaving));
// pRoot = pushLogicNode(pRoot, createProjectLogicNode(pSelect, pSelect->pProjectionList));
return pRoot;
}
static SLogicNode* createQueryLogicNode(SNode* pStmt) {
switch (nodeType(pStmt)) {
case QUERY_NODE_SELECT_STMT:
return createSelectLogicNode((SSelectStmt*)pStmt);
default:
break;
}
}
int32_t createLogicPlan(SNode* pNode, SLogicNode** pLogicNode) {
*pLogicNode = createQueryLogicNode(pNode);
return TSDB_CODE_SUCCESS;
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册