Merge pull request #10287 from taosdata/feature/3.0_wxy

TD-13495 planner refactoring
This commit is contained in:
xiao-yu-wang 2022-02-16 18:38:40 +08:00 committed by GitHub
commit ce824cdaa4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 527 additions and 97 deletions

View File

@ -105,7 +105,6 @@ typedef struct SFuncExecEnv {
int32_t calcMemSize; int32_t calcMemSize;
} SFuncExecEnv; } SFuncExecEnv;
typedef void* FuncMgtHandle;
typedef bool (*FExecGetEnv)(SFunctionNode* pFunc, SFuncExecEnv* pEnv); typedef bool (*FExecGetEnv)(SFunctionNode* pFunc, SFuncExecEnv* pEnv);
typedef bool (*FExecInit)(struct SqlFunctionCtx *pCtx, struct SResultRowEntryInfo* pResultCellInfo); typedef bool (*FExecInit)(struct SqlFunctionCtx *pCtx, struct SResultRowEntryInfo* pResultCellInfo);
typedef void (*FExecProcess)(struct SqlFunctionCtx *pCtx); typedef void (*FExecProcess)(struct SqlFunctionCtx *pCtx);
@ -120,9 +119,7 @@ typedef struct SFuncExecFuncs {
int32_t fmFuncMgtInit(); int32_t fmFuncMgtInit();
int32_t fmGetHandle(FuncMgtHandle* pHandle); int32_t fmGetFuncInfo(const char* pFuncName, int32_t* pFuncId, int32_t* pFuncType);
int32_t fmGetFuncInfo(FuncMgtHandle handle, const char* pFuncName, int32_t* pFuncId, int32_t* pFuncType);
int32_t fmGetFuncResultType(SFunctionNode* pFunc); int32_t fmGetFuncResultType(SFunctionNode* pFunc);
@ -136,7 +133,7 @@ bool fmIsTimeorderFunc(int32_t funcId);
int32_t fmFuncScanType(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 #ifdef __cplusplus
} }

View File

@ -49,7 +49,6 @@ typedef enum ENodeType {
QUERY_NODE_VALUE, QUERY_NODE_VALUE,
QUERY_NODE_OPERATOR, QUERY_NODE_OPERATOR,
QUERY_NODE_LOGIC_CONDITION, QUERY_NODE_LOGIC_CONDITION,
QUERY_NODE_IS_NULL_CONDITION,
QUERY_NODE_FUNCTION, QUERY_NODE_FUNCTION,
QUERY_NODE_REAL_TABLE, QUERY_NODE_REAL_TABLE,
QUERY_NODE_TEMP_TABLE, QUERY_NODE_TEMP_TABLE,
@ -62,6 +61,7 @@ typedef enum ENodeType {
QUERY_NODE_INTERVAL_WINDOW, QUERY_NODE_INTERVAL_WINDOW,
QUERY_NODE_NODE_LIST, QUERY_NODE_NODE_LIST,
QUERY_NODE_FILL, QUERY_NODE_FILL,
QUERY_NODE_COLUMN_REF,
// Only be used in parser module. // Only be used in parser module.
QUERY_NODE_RAW_EXPR, QUERY_NODE_RAW_EXPR,
@ -69,7 +69,11 @@ typedef enum ENodeType {
// Statement nodes are used in parser and planner module. // Statement nodes are used in parser and planner module.
QUERY_NODE_SET_OPERATOR, QUERY_NODE_SET_OPERATOR,
QUERY_NODE_SELECT_STMT, 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; } ENodeType;
/** /**
@ -121,7 +125,8 @@ void nodesRewriteListPostOrder(SNodeList* pList, FNodeRewriter rewriter, void* p
bool nodesEqualNode(const SNode* a, const SNode* b); 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 nodesNodeToString(const SNode* pNode, char** pStr, int32_t* pLen);
int32_t nodesStringToNode(const char* pStr, SNode** pNode); int32_t nodesStringToNode(const char* pStr, SNode** pNode);

View File

@ -37,7 +37,7 @@ typedef struct SDataType {
} SDataType; } SDataType;
typedef struct SExprNode { typedef struct SExprNode {
ENodeType nodeType; ENodeType type;
SDataType resType; SDataType resType;
char aliasName[TSDB_COL_NAME_LEN]; char aliasName[TSDB_COL_NAME_LEN];
SNodeList* pAssociationList; SNodeList* pAssociationList;
@ -59,6 +59,11 @@ typedef struct SColumnNode {
SNode* pProjectRef; SNode* pProjectRef;
} SColumnNode; } SColumnNode;
typedef struct SColumnRef {
ENodeType type;
int32_t slotId;
} SColumnRef;
typedef struct SValueNode { typedef struct SValueNode {
SExprNode node; // QUERY_NODE_VALUE SExprNode node; // QUERY_NODE_VALUE
char* literal; char* literal;
@ -80,6 +85,10 @@ typedef enum EOperatorType {
OP_TYPE_DIV, OP_TYPE_DIV,
OP_TYPE_MOD, OP_TYPE_MOD,
// bit operator
OP_TYPE_BIT_AND,
OP_TYPE_BIT_OR,
// comparison operator // comparison operator
OP_TYPE_GREATER_THAN, OP_TYPE_GREATER_THAN,
OP_TYPE_GREATER_EQUAL, OP_TYPE_GREATER_EQUAL,
@ -93,6 +102,8 @@ typedef enum EOperatorType {
OP_TYPE_NOT_LIKE, OP_TYPE_NOT_LIKE,
OP_TYPE_MATCH, OP_TYPE_MATCH,
OP_TYPE_NMATCH, OP_TYPE_NMATCH,
OP_TYPE_IS_NULL,
OP_TYPE_IS_NOT_NULL,
// json operator // json operator
OP_TYPE_JSON_GET_VALUE, OP_TYPE_JSON_GET_VALUE,
@ -118,12 +129,6 @@ typedef struct SLogicConditionNode {
SNodeList* pParameterList; SNodeList* pParameterList;
} SLogicConditionNode; } SLogicConditionNode;
typedef struct SIsNullCondNode {
SExprNode node; // QUERY_NODE_IS_NULL_CONDITION
SNode* pExpr;
bool isNull;
} SIsNullCondNode;
typedef struct SNodeListNode { typedef struct SNodeListNode {
ENodeType type; // QUERY_NODE_NODE_LIST ENodeType type; // QUERY_NODE_NODE_LIST
SNodeList* pNodeList; SNodeList* pNodeList;
@ -138,7 +143,7 @@ typedef struct SFunctionNode {
} SFunctionNode; } SFunctionNode;
typedef struct STableNode { typedef struct STableNode {
ENodeType type; SExprNode node;
char dbName[TSDB_DB_NAME_LEN]; char dbName[TSDB_DB_NAME_LEN];
char tableName[TSDB_TABLE_NAME_LEN]; char tableName[TSDB_TABLE_NAME_LEN];
char tableAlias[TSDB_TABLE_NAME_LEN]; char tableAlias[TSDB_TABLE_NAME_LEN];

View File

@ -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_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_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_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 #ifdef __cplusplus
} }

View File

@ -40,14 +40,8 @@ int32_t fmFuncMgtInit() {
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
int32_t fmGetHandle(FuncMgtHandle* pHandle) { int32_t fmGetFuncInfo(const char* pFuncName, int32_t* pFuncId, int32_t* pFuncType) {
*pHandle = &gFunMgtService; void* pVal = taosHashGet(gFunMgtService.pFuncNameHashTable, pFuncName, strlen(pFuncName));
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));
if (NULL == pVal) { if (NULL == pVal) {
return TSDB_CODE_FAILED; return TSDB_CODE_FAILED;
} }
@ -66,6 +60,17 @@ int32_t fmGetFuncResultType(SFunctionNode* pFunc) {
return funcMgtBuiltins[pFunc->funcId].checkFunc(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) { bool fmIsAggFunc(int32_t funcId) {
if (funcId < 0 || funcId >= funcMgtBuiltinsNum) { if (funcId < 0 || funcId >= funcMgtBuiltinsNum) {
return false; return false;

View File

@ -13,8 +13,179 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * 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;
} }

View File

@ -21,7 +21,6 @@ int32_t nodesNodeToString(const SNode* pNode, char** pStr, int32_t* pLen) {
case QUERY_NODE_VALUE: case QUERY_NODE_VALUE:
case QUERY_NODE_OPERATOR: case QUERY_NODE_OPERATOR:
case QUERY_NODE_LOGIC_CONDITION: case QUERY_NODE_LOGIC_CONDITION:
case QUERY_NODE_IS_NULL_CONDITION:
case QUERY_NODE_FUNCTION: case QUERY_NODE_FUNCTION:
case QUERY_NODE_REAL_TABLE: case QUERY_NODE_REAL_TABLE:
case QUERY_NODE_TEMP_TABLE: case QUERY_NODE_TEMP_TABLE:

View File

@ -89,12 +89,6 @@ static bool logicConditionNodeEqual(const SLogicConditionNode* a, const SLogicCo
return true; 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) { static bool functionNodeEqual(const SFunctionNode* a, const SFunctionNode* b) {
COMPARE_SCALAR_FIELD(funcId); COMPARE_SCALAR_FIELD(funcId);
COMPARE_NODE_LIST_FIELD(pParameterList); 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); return operatorNodeEqual((const SOperatorNode*)a, (const SOperatorNode*)b);
case QUERY_NODE_LOGIC_CONDITION: case QUERY_NODE_LOGIC_CONDITION:
return logicConditionNodeEqual((const SLogicConditionNode*)a, (const SLogicConditionNode*)b); 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: case QUERY_NODE_FUNCTION:
return functionNodeEqual((const SFunctionNode*)a, (const SFunctionNode*)b); return functionNodeEqual((const SFunctionNode*)a, (const SFunctionNode*)b);
case QUERY_NODE_REAL_TABLE: case QUERY_NODE_REAL_TABLE:

View File

@ -53,9 +53,6 @@ static EDealRes walkNode(SNode* pNode, ETraversalOrder order, FNodeWalker walker
case QUERY_NODE_LOGIC_CONDITION: case QUERY_NODE_LOGIC_CONDITION:
res = walkList(((SLogicConditionNode*)pNode)->pParameterList, order, walker, pContext); res = walkList(((SLogicConditionNode*)pNode)->pParameterList, order, walker, pContext);
break; break;
case QUERY_NODE_IS_NULL_CONDITION:
res = walkNode(((SIsNullCondNode*)pNode)->pExpr, order, walker, pContext);
break;
case QUERY_NODE_FUNCTION: case QUERY_NODE_FUNCTION:
res = walkList(((SFunctionNode*)pNode)->pParameterList, order, walker, pContext); res = walkList(((SFunctionNode*)pNode)->pParameterList, order, walker, pContext);
break; break;
@ -179,9 +176,6 @@ static EDealRes rewriteNode(SNode** pRawNode, ETraversalOrder order, FNodeRewrit
case QUERY_NODE_LOGIC_CONDITION: case QUERY_NODE_LOGIC_CONDITION:
res = rewriteList(((SLogicConditionNode*)pNode)->pParameterList, order, rewriter, pContext); res = rewriteList(((SLogicConditionNode*)pNode)->pParameterList, order, rewriter, pContext);
break; break;
case QUERY_NODE_IS_NULL_CONDITION:
res = rewriteNode(&(((SIsNullCondNode*)pNode)->pExpr), order, rewriter, pContext);
break;
case QUERY_NODE_FUNCTION: case QUERY_NODE_FUNCTION:
res = rewriteList(((SFunctionNode*)pNode)->pParameterList, order, rewriter, pContext); res = rewriteList(((SFunctionNode*)pNode)->pParameterList, order, rewriter, pContext);
break; break;

View File

@ -36,8 +36,6 @@ SNode* nodesMakeNode(ENodeType type) {
return makeNode(type, sizeof(SOperatorNode)); return makeNode(type, sizeof(SOperatorNode));
case QUERY_NODE_LOGIC_CONDITION: case QUERY_NODE_LOGIC_CONDITION:
return makeNode(type, sizeof(SLogicConditionNode)); return makeNode(type, sizeof(SLogicConditionNode));
case QUERY_NODE_IS_NULL_CONDITION:
return makeNode(type, sizeof(SIsNullCondNode));
case QUERY_NODE_FUNCTION: case QUERY_NODE_FUNCTION:
return makeNode(type, sizeof(SFunctionNode)); return makeNode(type, sizeof(SFunctionNode));
case QUERY_NODE_REAL_TABLE: case QUERY_NODE_REAL_TABLE:

View File

@ -43,7 +43,6 @@ SNode* createLogicConditionNode(SAstCreateContext* pCxt, ELogicConditionType typ
SNode* createOperatorNode(SAstCreateContext* pCxt, EOperatorType type, SNode* pLeft, SNode* pRight); SNode* createOperatorNode(SAstCreateContext* pCxt, EOperatorType type, SNode* pLeft, SNode* pRight);
SNode* createBetweenAnd(SAstCreateContext* pCxt, SNode* pExpr, 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* 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* createFunctionNode(SAstCreateContext* pCxt, const SToken* pFuncName, SNodeList* pParameterList);
SNode* createNodeListNode(SAstCreateContext* pCxt, SNodeList* pList); SNode* createNodeListNode(SAstCreateContext* pCxt, SNodeList* pList);
SNode* createRealTableNode(SAstCreateContext* pCxt, const SToken* pDbName, const SToken* pTableName, const SToken* pTableAlias); SNode* createRealTableNode(SAstCreateContext* pCxt, const SToken* pDbName, const SToken* pTableName, const SToken* pTableAlias);

View File

@ -192,12 +192,12 @@ predicate(A) ::= expression(B) NOT BETWEEN expression(C) AND expression(D).
predicate(A) ::= expression(B) IS NULL(C). { predicate(A) ::= expression(B) IS NULL(C). {
PARSER_TRACE; PARSER_TRACE;
SToken s = getTokenFromRawExprNode(pCxt, B); 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). { predicate(A) ::= expression(B) IS NOT NULL(C). {
PARSER_TRACE; PARSER_TRACE;
SToken s = getTokenFromRawExprNode(pCxt, B); 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). { predicate(A) ::= expression(B) in_op(C) in_predicate_value(D). {
PARSER_TRACE; PARSER_TRACE;

View File

@ -13,9 +13,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "querynodes.h"
#include "parser.h"
#ifndef _TD_AST_CREATE_FUNCS_H_ #ifndef _TD_AST_CREATE_FUNCS_H_
#define _TD_AST_CREATE_FUNCS_H_ #define _TD_AST_CREATE_FUNCS_H_
@ -23,9 +20,19 @@
extern "C" { extern "C" {
#endif #endif
#include "querynodes.h"
#include "parser.h"
typedef enum EStmtType {
STMT_TYPE_CMD = 1,
STMT_TYPE_QUERY
} EStmtType;
typedef struct SQuery { typedef struct SQuery {
EStmtType stmtType;
SNode* pRoot; SNode* pRoot;
// todo reslut meta int32_t numOfResCols;
SSchema* pResSchema;
} SQuery; } SQuery;
int32_t doParse(SParseContext* pParseCxt, SQuery* pQuery); int32_t doParse(SParseContext* pParseCxt, SQuery* pQuery);

View File

@ -84,6 +84,10 @@ SNode* releaseRawExprNode(SAstCreateContext* pCxt, SNode* pNode) {
} }
SToken getTokenFromRawExprNode(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; SRawExprNode* target = (SRawExprNode*)pNode;
SToken t = { .type = 0, .z = target->p, .n = target->n}; SToken t = { .type = 0, .z = target->p, .n = target->n};
return t; 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)); 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) { SNode* createFunctionNode(SAstCreateContext* pCxt, const SToken* pFuncName, SNodeList* pParameterList) {
SFunctionNode* func = (SFunctionNode*)nodesMakeNode(QUERY_NODE_FUNCTION); SFunctionNode* func = (SFunctionNode*)nodesMakeNode(QUERY_NODE_FUNCTION);
CHECK_OUT_OF_MEM(func); CHECK_OUT_OF_MEM(func);
@ -292,7 +288,11 @@ SNode* createGroupingSetNode(SAstCreateContext* pCxt, SNode* pNode) {
} }
SNode* setProjectionAlias(SAstCreateContext* pCxt, SNode* pNode, const SToken* pAlias) { 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; return pNode;
} }

View File

@ -1717,7 +1717,7 @@ static YYACTIONTYPE yy_reduce(
{ {
PARSER_TRACE; PARSER_TRACE;
SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy56); 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; yymsp[-2].minor.yy56 = yylhsminor.yy56;
break; break;
@ -1725,7 +1725,7 @@ static YYACTIONTYPE yy_reduce(
{ {
PARSER_TRACE; PARSER_TRACE;
SToken s = getTokenFromRawExprNode(pCxt, yymsp[-3].minor.yy56); 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; yymsp[-3].minor.yy56 = yylhsminor.yy56;
break; break;

View File

@ -174,6 +174,19 @@ static uint32_t getToken(const char* z, uint32_t* tokenId) {
return n; 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) { int32_t doParse(SParseContext* pParseCxt, SQuery* pQuery) {
SAstCreateContext cxt; SAstCreateContext cxt;
createAstCreateContext(pParseCxt, &cxt); createAstCreateContext(pParseCxt, &cxt);
@ -181,15 +194,12 @@ int32_t doParse(SParseContext* pParseCxt, SQuery* pQuery) {
int32_t i = 0; int32_t i = 0;
while (1) { while (1) {
SToken t0 = {0}; SToken t0 = {0};
// printf("===========================\n");
if (cxt.pQueryCxt->pSql[i] == 0) { if (cxt.pQueryCxt->pSql[i] == 0) {
NewParse(pParser, 0, t0, &cxt); NewParse(pParser, 0, t0, &cxt);
goto abort_parse; goto abort_parse;
} }
// printf("input: [%s]\n", cxt.pQueryCxt->pSql + i);
t0.n = getToken((char *)&cxt.pQueryCxt->pSql[i], &t0.type); t0.n = getToken((char *)&cxt.pQueryCxt->pSql[i], &t0.type);
t0.z = (char *)(cxt.pQueryCxt->pSql + i); t0.z = (char *)(cxt.pQueryCxt->pSql + i);
// printf("token : %d %d [%s]\n", t0.type, t0.n, t0.z);
i += t0.n; i += t0.n;
switch (t0.type) { switch (t0.type) {
@ -201,14 +211,12 @@ int32_t doParse(SParseContext* pParseCxt, SQuery* pQuery) {
NewParse(pParser, 0, t0, &cxt); NewParse(pParser, 0, t0, &cxt);
goto abort_parse; goto abort_parse;
} }
case TK_QUESTION: case TK_QUESTION:
case TK_ILLEGAL: { case TK_ILLEGAL: {
snprintf(cxt.pQueryCxt->pMsg, cxt.pQueryCxt->msgLen, "unrecognized token: \"%s\"", t0.z); snprintf(cxt.pQueryCxt->pMsg, cxt.pQueryCxt->msgLen, "unrecognized token: \"%s\"", t0.z);
cxt.valid = false; cxt.valid = false;
goto abort_parse; goto abort_parse;
} }
case TK_HEX: case TK_HEX:
case TK_OCT: case TK_OCT:
case TK_BIN: { case TK_BIN: {
@ -216,7 +224,6 @@ int32_t doParse(SParseContext* pParseCxt, SQuery* pQuery) {
cxt.valid = false; cxt.valid = false;
goto abort_parse; goto abort_parse;
} }
default: default:
NewParse(pParser, t0.type, t0, &cxt); NewParse(pParser, t0.type, t0, &cxt);
// NewParseTrace(stdout, ""); // NewParseTrace(stdout, "");
@ -227,9 +234,9 @@ int32_t doParse(SParseContext* pParseCxt, SQuery* pQuery) {
} }
abort_parse: abort_parse:
// printf("doParse completed.\n");
NewParseFree(pParser, free); NewParseFree(pParser, free);
destroyAstCreateContext(&cxt); destroyAstCreateContext(&cxt);
pQuery->stmtType = getStmtType(cxt.pRootNode);
pQuery->pRoot = cxt.pRootNode; pQuery->pRoot = cxt.pRootNode;
return cxt.valid ? TSDB_CODE_SUCCESS : TSDB_CODE_FAILED; return cxt.valid ? TSDB_CODE_SUCCESS : TSDB_CODE_FAILED;
} }
@ -255,7 +262,6 @@ static bool beforeHaving(ESqlClause clause) {
typedef struct STranslateContext { typedef struct STranslateContext {
SParseContext* pParseCxt; SParseContext* pParseCxt;
FuncMgtHandle fmgt;
int32_t errCode; int32_t errCode;
SMsgBuf msgBuf; SMsgBuf msgBuf;
SArray* pNsLevel; // element is SArray*, the element of this subarray is STableNode* 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"; return "Not SELECTed expression";
case TSDB_CODE_PAR_NOT_SINGLE_GROUP: case TSDB_CODE_PAR_NOT_SINGLE_GROUP:
return "Not a single-group group function"; return "Not a single-group group function";
case TSDB_CODE_PAR_OUT_OF_MEMORY:
return "Out of memory";
default: default:
return "Unknown error"; return "Unknown error";
} }
@ -376,12 +384,15 @@ static void setColumnInfoByExpr(const STableNode* pTable, SExprNode* pExpr, SCol
pCol->node.resType = pExpr->resType; 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)) { if (QUERY_NODE_REAL_TABLE == nodeType(pTable)) {
const STableMeta* pMeta = ((SRealTableNode*)pTable)->pMeta; const STableMeta* pMeta = ((SRealTableNode*)pTable)->pMeta;
int32_t nums = pMeta->tableInfo.numOfTags + pMeta->tableInfo.numOfColumns; int32_t nums = pMeta->tableInfo.numOfTags + pMeta->tableInfo.numOfColumns;
for (int32_t i = 0; i < nums; ++i) { for (int32_t i = 0; i < nums; ++i) {
SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN); 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); setColumnInfoBySchema(pTable, pMeta->schema + i, pCol);
nodesListAppend(pList, (SNode*)pCol); nodesListAppend(pList, (SNode*)pCol);
} }
@ -390,10 +401,14 @@ static int32_t createColumnNodeByTable(const STableNode* pTable, SNodeList* pLis
SNode* pNode; SNode* pNode;
FOREACH(pNode, pProjectList) { FOREACH(pNode, pProjectList) {
SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN); SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN);
if (NULL == pCol) {
return generateSyntaxErrMsg(pCxt, TSDB_CODE_PAR_OUT_OF_MEMORY);
}
setColumnInfoByExpr(pTable, (SExprNode*)pNode, pCol); setColumnInfoByExpr(pTable, (SExprNode*)pNode, pCol);
nodesListAppend(pList, (SNode*)pCol); nodesListAppend(pList, (SNode*)pCol);
} }
} }
return TSDB_CODE_SUCCESS;
} }
static bool findAndSetColumn(SColumnNode* pCol, const STableNode* pTable) { 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_UTINYINT:
case TSDB_DATA_TYPE_USMALLINT: case TSDB_DATA_TYPE_USMALLINT:
case TSDB_DATA_TYPE_UINT: case TSDB_DATA_TYPE_UINT:
case TSDB_DATA_TYPE_UBIGINT:{ case TSDB_DATA_TYPE_UBIGINT: {
char* endPtr = NULL; char* endPtr = NULL;
pVal->datum.u = strtoull(pVal->literal, &endPtr, 10); pVal->datum.u = strtoull(pVal->literal, &endPtr, 10);
break; break;
@ -556,12 +571,20 @@ static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) {
case TSDB_DATA_TYPE_VARBINARY: { case TSDB_DATA_TYPE_VARBINARY: {
int32_t n = strlen(pVal->literal); int32_t n = strlen(pVal->literal);
pVal->datum.p = calloc(1, n); 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); trimStringCopy(pVal->literal, n, pVal->datum.p);
break; break;
} }
case TSDB_DATA_TYPE_TIMESTAMP: { case TSDB_DATA_TYPE_TIMESTAMP: {
int32_t n = strlen(pVal->literal); int32_t n = strlen(pVal->literal);
char* tmp = calloc(1, n); 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); int32_t len = trimStringCopy(pVal->literal, n, tmp);
if (taosParseTime(tmp, &pVal->datum.i, len, pVal->node.resType.precision, tsDaylight) != TSDB_CODE_SUCCESS) { if (taosParseTime(tmp, &pVal->datum.i, len, pVal->node.resType.precision, tsDaylight) != TSDB_CODE_SUCCESS) {
tfree(tmp); tfree(tmp);
@ -608,7 +631,7 @@ static EDealRes translateOperator(STranslateContext* pCxt, SOperatorNode* pOp) {
} }
static EDealRes translateFunction(STranslateContext* pCxt, SFunctionNode* pFunc) { 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); generateSyntaxErrMsg(pCxt, TSDB_CODE_PAR_INVALID_FUNTION, pFunc->functionName);
return DEAL_RES_ERROR; return DEAL_RES_ERROR;
} }
@ -806,9 +829,15 @@ static int32_t translateStar(STranslateContext* pCxt, SSelectStmt* pSelect, bool
SArray* pTables = taosArrayGetP(pCxt->pNsLevel, pCxt->currLevel); SArray* pTables = taosArrayGetP(pCxt->pNsLevel, pCxt->currLevel);
size_t nums = taosArrayGetSize(pTables); size_t nums = taosArrayGetSize(pTables);
pSelect->pProjectionList = nodesMakeList(); pSelect->pProjectionList = nodesMakeList();
if (NULL == pSelect->pProjectionList) {
return generateSyntaxErrMsg(pCxt, TSDB_CODE_PAR_OUT_OF_MEMORY);
}
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);
createColumnNodeByTable(pTable, pSelect->pProjectionList); int32_t code = createColumnNodeByTable(pCxt, pTable, pSelect->pProjectionList);
if (TSDB_CODE_SUCCESS != code) {
return code;
}
} }
*pIsSelectStar = true; *pIsSelectStar = true;
} else { } else {
@ -848,7 +877,7 @@ static int32_t getPositionValue(const SValueNode* pVal) {
return -1; 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; *pOther = false;
SNode* pNode; SNode* pNode;
FOREACH(pNode, pOrderByList) { FOREACH(pNode, pOrderByList) {
@ -856,18 +885,20 @@ static bool translateOrderByPosition(STranslateContext* pCxt, SNodeList* pProjec
if (QUERY_NODE_VALUE == nodeType(pExpr)) { if (QUERY_NODE_VALUE == nodeType(pExpr)) {
SValueNode* pVal = (SValueNode*)pExpr; SValueNode* pVal = (SValueNode*)pExpr;
if (!translateValue(pCxt, pVal)) { if (!translateValue(pCxt, pVal)) {
return false; return pCxt->errCode;
} }
int32_t pos = getPositionValue((SValueNode*)pExpr); int32_t pos = getPositionValue(pVal);
if (pos < 0) { if (pos < 0) {
ERASE_NODE(pOrderByList); ERASE_NODE(pOrderByList);
nodesDestroyNode(pNode); nodesDestroyNode(pNode);
continue; continue;
} else if (0 == pos || pos > LIST_LENGTH(pProjectionList)) { } else if (0 == pos || pos > LIST_LENGTH(pProjectionList)) {
generateSyntaxErrMsg(pCxt, TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT); return generateSyntaxErrMsg(pCxt, TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT);
return false;
} else { } else {
SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN); 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); setColumnInfoByExpr(NULL, (SExprNode*)nodesListGetNode(pProjectionList, pos - 1), pCol);
((SOrderByExprNode*)pNode)->pExpr = (SNode*)pCol; ((SOrderByExprNode*)pNode)->pExpr = (SNode*)pCol;
nodesDestroyNode(pExpr); nodesDestroyNode(pExpr);
@ -876,19 +907,20 @@ static bool translateOrderByPosition(STranslateContext* pCxt, SNodeList* pProjec
*pOther = true; *pOther = true;
} }
} }
return true; return TSDB_CODE_SUCCESS;
} }
static int32_t translateOrderBy(STranslateContext* pCxt, SSelectStmt* pSelect) { static int32_t translateOrderBy(STranslateContext* pCxt, SSelectStmt* pSelect) {
bool other; bool other;
if (!translateOrderByPosition(pCxt, pSelect->pProjectionList, pSelect->pOrderByList, &other)) { int32_t code = translateOrderByPosition(pCxt, pSelect->pProjectionList, pSelect->pOrderByList, &other);
return pCxt->errCode; if (TSDB_CODE_SUCCESS != code) {
return code;
} }
if (!other) { if (!other) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
pCxt->currClause = SQL_CLAUSE_ORDER_BY; pCxt->currClause = SQL_CLAUSE_ORDER_BY;
int32_t code = translateExprList(pCxt, pSelect->pOrderByList); code = translateExprList(pCxt, pSelect->pOrderByList);
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
code = checkExprListForGroupBy(pCxt, pSelect->pOrderByList); code = checkExprListForGroupBy(pCxt, pSelect->pOrderByList);
} }
@ -945,12 +977,6 @@ static int32_t translateFrom(STranslateContext* pCxt, SNode* pTable) {
return translateTable(pCxt, pTable); return translateTable(pCxt, pTable);
} }
// typedef struct SSelectStmt {
// bool isDistinct;
// SNode* pLimit;
// SNode* pSlimit;
// } SSelectStmt;
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->pFromTable); int32_t code = translateFrom(pCxt, pSelect->pFromTable);
@ -1004,6 +1030,26 @@ static int32_t translateSubquery(STranslateContext* pCxt, SNode* pNode) {
return code; 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) { int32_t doTranslate(SParseContext* pParseCxt, SQuery* pQuery) {
STranslateContext cxt = { STranslateContext cxt = {
.pParseCxt = pParseCxt, .pParseCxt = pParseCxt,
@ -1014,12 +1060,11 @@ int32_t doTranslate(SParseContext* pParseCxt, SQuery* pQuery) {
.currClause = 0 .currClause = 0
}; };
int32_t code = fmFuncMgtInit(); int32_t code = fmFuncMgtInit();
if (TSDB_CODE_SUCCESS != code) { if (TSDB_CODE_SUCCESS == code) {
return code; code = translateQuery(&cxt, pQuery->pRoot);
} }
code = fmGetHandle(&cxt.fmgt); if (TSDB_CODE_SUCCESS == code && STMT_TYPE_QUERY == pQuery->stmtType) {
if (TSDB_CODE_SUCCESS != code) { code = setReslutSchema(&cxt, pQuery);
return code;
} }
return translateQuery(&cxt, pQuery->pRoot); return code;
} }

View File

@ -8,7 +8,7 @@ target_include_directories(
target_link_libraries( target_link_libraries(
planner planner
PRIVATE os util catalog cjson parser function qcom PRIVATE os util nodes catalog cjson parser function qcom
PUBLIC transport PUBLIC transport
) )

View File

@ -20,6 +20,33 @@
extern "C" { extern "C" {
#endif #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 #ifdef __cplusplus
} }
#endif #endif

View File

@ -13,7 +13,192 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * 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);
// } 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;
}