TD-13197 SELECT statement syntax definition
This commit is contained in:
parent
09071e70eb
commit
45c4099e99
|
@ -207,36 +207,50 @@
|
|||
#define TK_INTO 189
|
||||
#define TK_VALUES 190
|
||||
|
||||
#define NEW_TK_UNION 1
|
||||
#define NEW_TK_ALL 2
|
||||
#define NEW_TK_MINUS 3
|
||||
#define NEW_TK_EXCEPT 4
|
||||
#define NEW_TK_INTERSECT 5
|
||||
#define NEW_TK_NK_PLUS 6
|
||||
#define NEW_TK_NK_MINUS 7
|
||||
#define NEW_TK_NK_STAR 8
|
||||
#define NEW_TK_NK_SLASH 9
|
||||
#define NEW_TK_SHOW 10
|
||||
#define NEW_TK_DATABASES 11
|
||||
#define NEW_TK_NK_ID 12
|
||||
#define NEW_TK_NK_LP 13
|
||||
#define NEW_TK_NK_RP 14
|
||||
#define NEW_TK_NK_COMMA 15
|
||||
#define NEW_TK_NK_LITERAL 16
|
||||
#define NEW_TK_NK_DOT 17
|
||||
#define NEW_TK_SELECT 18
|
||||
#define NEW_TK_DISTINCT 19
|
||||
#define NEW_TK_AS 20
|
||||
#define NEW_TK_FROM 21
|
||||
#define NEW_TK_WITH 22
|
||||
#define NEW_TK_RECURSIVE 23
|
||||
#define NEW_TK_ORDER 24
|
||||
#define NEW_TK_BY 25
|
||||
#define NEW_TK_ASC 26
|
||||
#define NEW_TK_DESC 27
|
||||
#define NEW_TK_NULLS 28
|
||||
#define NEW_TK_FIRST 29
|
||||
#define NEW_TK_LAST 30
|
||||
#define NEW_TK_OR 1
|
||||
#define NEW_TK_AND 2
|
||||
#define NEW_TK_NOT 3
|
||||
#define NEW_TK_UNION 4
|
||||
#define NEW_TK_ALL 5
|
||||
#define NEW_TK_MINUS 6
|
||||
#define NEW_TK_EXCEPT 7
|
||||
#define NEW_TK_INTERSECT 8
|
||||
#define NEW_TK_NK_PLUS 9
|
||||
#define NEW_TK_NK_MINUS 10
|
||||
#define NEW_TK_NK_STAR 11
|
||||
#define NEW_TK_NK_SLASH 12
|
||||
#define NEW_TK_SHOW 13
|
||||
#define NEW_TK_DATABASES 14
|
||||
#define NEW_TK_NK_INTEGER 15
|
||||
#define NEW_TK_NK_FLOAT 16
|
||||
#define NEW_TK_NK_STRING 17
|
||||
#define NEW_TK_NK_BOOL 18
|
||||
#define NEW_TK_NK_NOW 19
|
||||
#define NEW_TK_NK_ID 20
|
||||
#define NEW_TK_NK_QUESTION 21
|
||||
#define NEW_TK_NK_LP 22
|
||||
#define NEW_TK_NK_RP 23
|
||||
#define NEW_TK_NK_DOT 24
|
||||
#define NEW_TK_FROM 25
|
||||
#define NEW_TK_NK_COMMA 26
|
||||
#define NEW_TK_AS 27
|
||||
#define NEW_TK_JOIN 28
|
||||
#define NEW_TK_ON 29
|
||||
#define NEW_TK_INNER 30
|
||||
#define NEW_TK_SELECT 31
|
||||
#define NEW_TK_DISTINCT 32
|
||||
#define NEW_TK_ORDER 33
|
||||
#define NEW_TK_BY 34
|
||||
#define NEW_TK_SLIMIT 35
|
||||
#define NEW_TK_SOFFSET 36
|
||||
#define NEW_TK_LIMIT 37
|
||||
#define NEW_TK_OFFSET 38
|
||||
#define NEW_TK_NK_LR 39
|
||||
#define NEW_TK_ASC 40
|
||||
#define NEW_TK_DESC 41
|
||||
#define NEW_TK_NULLS 42
|
||||
#define NEW_TK_FIRST 43
|
||||
#define NEW_TK_LAST 44
|
||||
|
||||
#define TK_SPACE 300
|
||||
#define TK_COMMENT 301
|
||||
|
@ -247,6 +261,8 @@
|
|||
#define TK_FILE 306
|
||||
#define TK_QUESTION 307 // denoting the placeholder of "?",when invoking statement bind query
|
||||
|
||||
#define TK_NIL 65535
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -22,6 +22,19 @@ extern "C" {
|
|||
|
||||
#include "tdef.h"
|
||||
|
||||
#define nodeType(nodeptr) (((const SNode*)(nodeptr))->type)
|
||||
#define setNodeType(nodeptr, type) (((SNode*)(nodeptr))->type = (type))
|
||||
|
||||
#define LIST_LENGTH(l) (NULL != (l) ? (l)->length : 0)
|
||||
|
||||
#define FOREACH(node, list) \
|
||||
for (SListCell* cell = (NULL != (list) ? (list)->pHead : NULL); (NULL != cell ? (node = cell->pNode, true) : (node = NULL, false)); cell = cell->pNext)
|
||||
|
||||
#define FORBOTH(node1, list1, node2, list2) \
|
||||
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); \
|
||||
cell1 = cell1->pNext, cell2 = cell2->pNext)
|
||||
|
||||
typedef enum ENodeType {
|
||||
QUERY_NODE_COLUMN = 1,
|
||||
QUERY_NODE_VALUE,
|
||||
|
@ -52,9 +65,6 @@ typedef struct SNode {
|
|||
ENodeType type;
|
||||
} SNode;
|
||||
|
||||
#define nodeType(nodeptr) (((const SNode*)(nodeptr))->type)
|
||||
#define setNodeType(nodeptr, type) (((SNode*)(nodeptr))->type = (type))
|
||||
|
||||
typedef struct SListCell {
|
||||
SNode* pNode;
|
||||
struct SListCell* pNext;
|
||||
|
@ -62,19 +72,10 @@ typedef struct SListCell {
|
|||
|
||||
typedef struct SNodeList {
|
||||
int16_t length;
|
||||
SListCell* pHeader;
|
||||
SListCell* pHead;
|
||||
SListCell* pTail;
|
||||
} SNodeList;
|
||||
|
||||
#define LIST_LENGTH(l) (NULL != (l) ? (l)->length : 0)
|
||||
|
||||
#define FOREACH(node, list) \
|
||||
for (SListCell* cell = (NULL != (list) ? (list)->pHeader : NULL); (NULL != cell ? (node = cell->pNode, true) : (node = NULL, false)); cell = cell->pNext)
|
||||
|
||||
#define FORBOTH(node1, list1, node2, list2) \
|
||||
for (SListCell* cell1 = (NULL != (list1) ? (list1)->pHeader : NULL), *cell2 = (NULL != (list2) ? (list2)->pHeader : NULL); \
|
||||
(NULL == cell1 ? (node1 = NULL, false) : (node1 = cell1->pNode, true)), (NULL == cell2 ? (node2 = NULL, false) : (node2 = cell2->pNode, true)), (node1 != NULL && node2 != NULL); \
|
||||
cell1 = cell1->pNext, cell2 = cell2->pNext)
|
||||
|
||||
typedef struct SDataType {
|
||||
uint8_t type;
|
||||
uint8_t precision;
|
||||
|
@ -252,13 +253,14 @@ typedef struct SSelectStmt {
|
|||
bool isStar;
|
||||
SNodeList* pProjectionList; // SNode
|
||||
SNode* pFromTable;
|
||||
SNode* pWhereCond;
|
||||
SNode* pWhere;
|
||||
SNodeList* pPartitionByList; // SNode
|
||||
SNode* pWindowClause;
|
||||
SNode* pWindow;
|
||||
SNodeList* pGroupByList; // SGroupingSetNode
|
||||
SNode* pHaving;
|
||||
SNodeList* pOrderByList; // SOrderByExprNode
|
||||
SLimitNode limit;
|
||||
SLimitNode slimit;
|
||||
SLimitNode* pLimit;
|
||||
SLimitNode* pSlimit;
|
||||
} SSelectStmt;
|
||||
|
||||
typedef enum ESetOperatorType {
|
||||
|
@ -272,10 +274,17 @@ typedef struct SSetOperator {
|
|||
SNode* pRight;
|
||||
} SSetOperator;
|
||||
|
||||
SNode* nodesMakeNode(ENodeType type);
|
||||
void nodesDestroyNode(SNode* pNode);
|
||||
|
||||
SNodeList* nodesMakeList();
|
||||
SNodeList* nodesListAppend(SNodeList* pList, SNode* pNode);
|
||||
void nodesDestroyList(SNodeList* pList);
|
||||
|
||||
typedef bool (*FQueryNodeWalker)(SNode* pNode, void* pContext);
|
||||
|
||||
bool nodesWalkNode(SNode* pNode, FQueryNodeWalker walker, void* pContext);
|
||||
bool nodesWalkNodeList(SNodeList* pNodeList, FQueryNodeWalker walker, void* pContext);
|
||||
bool nodesWalkList(SNodeList* pList, FQueryNodeWalker walker, void* pContext);
|
||||
|
||||
bool nodesWalkStmt(SNode* pNode, FQueryNodeWalker walker, void* pContext);
|
||||
|
||||
|
@ -289,10 +298,6 @@ int32_t nodesStringToNode(const char* pStr, SNode** pNode);
|
|||
bool nodesIsTimeorderQuery(const SNode* pQuery);
|
||||
bool nodesIsTimelineQuery(const SNode* pQuery);
|
||||
|
||||
SNode* nodesMakeNode(ENodeType type);
|
||||
void nodesDestroyNode(SNode* pNode);
|
||||
void nodesDestroyNodeList(SNodeList* pList);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -23,17 +23,23 @@ extern "C" {
|
|||
#include "nodes.h"
|
||||
#include "parser.h"
|
||||
|
||||
typedef enum EResourceType {
|
||||
AST_CXT_RESOURCE_NODE = 1,
|
||||
AST_CXT_RESOURCE_NODE_LIST
|
||||
} EResourceType;
|
||||
|
||||
typedef struct SAstCreateContext {
|
||||
SParseContext* pQueryCxt;
|
||||
bool notSupport;
|
||||
bool valid;
|
||||
SNode* pRootNode;
|
||||
SHashObj* pResourceHash;
|
||||
} SAstCreateContext;
|
||||
|
||||
int32_t createAstCreateContext(const SParseContext* pQueryCxt, SAstCreateContext* pCxt);
|
||||
int32_t createAstCreateContext(SParseContext* pQueryCxt, SAstCreateContext* pCxt);
|
||||
int32_t destroyAstCreateContext(SAstCreateContext* pCxt);
|
||||
|
||||
void* acquireRaii(SAstCreateContext* pCxt, void* p);
|
||||
void* acquireRaii(SAstCreateContext* pCxt, EResourceType type, void* p);
|
||||
void* releaseRaii(SAstCreateContext* pCxt, void* p);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -25,20 +25,35 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
bool checkTableName(const SToken* pTableName);
|
||||
SNodeList* addNodeToList(SAstCreateContext* pCxt, SNodeList* pList, SNode* pNode);
|
||||
SNode* addOrderByList(SAstCreateContext* pCxt, SNode* pStmt, SNodeList* pOrderByList);
|
||||
SNode* addSlimit(SAstCreateContext* pCxt, SNode* pStmt, SNode* pSlimit);
|
||||
SNode* addLimit(SAstCreateContext* pCxt, SNode* pStmt, SNode* pLimit);
|
||||
SNode* createColumnNode(SAstCreateContext* pCxt, const SToken* pTableName, const SToken* pColumnName);
|
||||
SNode* createLimitNode(SAstCreateContext* pCxt, const SToken* pLimit, const SToken* pOffset);
|
||||
extern SToken nil_token;
|
||||
|
||||
SNodeList* createNodeList(SAstCreateContext* pCxt, SNode* pNode);
|
||||
SNodeList* addNodeToList(SAstCreateContext* pCxt, SNodeList* pList, SNode* pNode);
|
||||
|
||||
SNode* createColumnNode(SAstCreateContext* pCxt, const SToken* pTableName, const SToken* pColumnName);
|
||||
SNode* createValueNode(SAstCreateContext* pCxt, int32_t dataType, const SToken* pLiteral);
|
||||
SNode* addMinusSign(SAstCreateContext* pCxt, SNode* pNode);
|
||||
SNode* setProjectionAlias(SAstCreateContext* pCxt, SNode* pNode, const SToken* pAlias);
|
||||
SNode* createLogicConditionNode(SAstCreateContext* pCxt, ELogicConditionType type, SNode* pParam1, SNode* pParam2);
|
||||
SNode* createRealTableNode(SAstCreateContext* pCxt, const SToken* pDbName, const SToken* pTableName, const SToken* pTableAlias);
|
||||
SNode* createTempTableNode(SAstCreateContext* pCxt, SNode* pSubquery, const SToken* pTableAlias);
|
||||
SNode* createJoinTableNode(SAstCreateContext* pCxt, EJoinType type, SNode* pLeft, SNode* pRight, SNode* pJoinCond);
|
||||
SNode* createLimitNode(SAstCreateContext* pCxt, SNode* pLimit, SNode* pOffset);
|
||||
SNode* createOrderByExprNode(SAstCreateContext* pCxt, SNode* pExpr, EOrder order, ENullOrder nullOrder);
|
||||
SNode* createRealTableNode(SAstCreateContext* pCxt, const SToken* pDbName, const SToken* pTableName);
|
||||
|
||||
SNode* addWhereClause(SAstCreateContext* pCxt, SNode* pStmt, SNode* pWhere);
|
||||
SNode* addPartitionByClause(SAstCreateContext* pCxt, SNode* pStmt, SNodeList* pPartitionByList);
|
||||
SNode* addWindowClauseClause(SAstCreateContext* pCxt, SNode* pStmt, SNode* pWindow);
|
||||
SNode* addGroupByClause(SAstCreateContext* pCxt, SNode* pStmt, SNodeList* pGroupByList);
|
||||
SNode* addHavingClause(SAstCreateContext* pCxt, SNode* pStmt, SNode* pHaving);
|
||||
SNode* addOrderByClause(SAstCreateContext* pCxt, SNode* pStmt, SNodeList* pOrderByList);
|
||||
SNode* addSlimitClause(SAstCreateContext* pCxt, SNode* pStmt, SNode* pSlimit);
|
||||
SNode* addLimitClause(SAstCreateContext* pCxt, SNode* pStmt, SNode* pLimit);
|
||||
SNode* createSelectStmt(SAstCreateContext* pCxt, bool isDistinct, SNodeList* pProjectionList, SNode* pTable);
|
||||
SNode* createSetOperator(SAstCreateContext* pCxt, ESetOperatorType type, SNode* pLeft, SNode* pRight);
|
||||
|
||||
SNode* createShowStmt(SAstCreateContext* pCxt, EShowStmtType type);
|
||||
SNode* setProjectionAlias(SAstCreateContext* pCxt, SNode* pNode, const SToken* pAlias);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
%token_prefix NEW_TK_
|
||||
%token_type { SToken }
|
||||
%default_type { SNode* }
|
||||
%default_destructor { nodesDestroyNode($$); }
|
||||
%default_destructor { PARSER_DESTRUCTOR_TRACE; nodesDestroyNode($$); }
|
||||
|
||||
%extra_argument { SAstCreateContext* pCxt }
|
||||
|
||||
|
@ -22,7 +22,8 @@
|
|||
#include "ttokendef.h"
|
||||
#include "astCreateFuncs.h"
|
||||
|
||||
#define PARSER_TRACE printf("rule = %s\n", yyRuleName[yyruleno])
|
||||
#define PARSER_TRACE printf("lemon rule = %s\n", yyRuleName[yyruleno])
|
||||
#define PARSER_DESTRUCTOR_TRACE printf("lemon destroy token = %s\n", yyTokenName[yymajor])
|
||||
}
|
||||
|
||||
%syntax_error {
|
||||
|
@ -45,9 +46,9 @@
|
|||
|
||||
%parse_accept { printf("parsing complete!\n" );}
|
||||
|
||||
//%left OR.
|
||||
//%left AND.
|
||||
//%right NOT.
|
||||
%left OR.
|
||||
%left AND.
|
||||
%right NOT.
|
||||
%left UNION ALL MINUS EXCEPT INTERSECT.
|
||||
//%left EQ NE ISNULL NOTNULL IS LIKE MATCH NMATCH GLOB BETWEEN IN.
|
||||
//%left GT GE LT LE.
|
||||
|
@ -58,27 +59,226 @@
|
|||
//%left CONCAT.
|
||||
//%right UMINUS UPLUS BITNOT.
|
||||
|
||||
cmd ::= SHOW DATABASES. { PARSER_TRACE; createShowStmt(pCxt, SHOW_TYPE_DATABASE); }
|
||||
cmd ::= SHOW DATABASES. { PARSER_TRACE; createShowStmt(pCxt, SHOW_TYPE_DATABASE); }
|
||||
cmd ::= query_expression(A). { PARSER_TRACE; pCxt->pRootNode = A; }
|
||||
|
||||
cmd ::= query_expression(A). { PARSER_TRACE; pCxt->pRootNode = A; }
|
||||
/*5.4*********************************************** literal *********************************************************/
|
||||
unsigned_integer(A) ::= NK_INTEGER(B). { A = createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &B); }
|
||||
unsigned_approximate_numeric(A) ::= NK_FLOAT(B). { A = createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &B); }
|
||||
|
||||
signed_integer(A) ::= unsigned_integer(B). { A = B; }
|
||||
signed_integer(A) ::= NK_PLUS unsigned_integer(B). { A = B; }
|
||||
signed_integer(A) ::= NK_MINUS unsigned_integer(B). { A = addMinusSign(pCxt, B);}
|
||||
|
||||
unsigned_literal ::= unsigned_numeric_literal.
|
||||
unsigned_literal ::= general_literal.
|
||||
|
||||
unsigned_numeric_literal ::= unsigned_integer.
|
||||
unsigned_numeric_literal ::= unsigned_approximate_numeric.
|
||||
|
||||
general_literal ::= NK_STRING.
|
||||
general_literal ::= NK_BOOL.
|
||||
general_literal ::= NK_NOW.
|
||||
|
||||
/*5.4*********************************************** names and identifiers *********************************************************/
|
||||
%type db_name { SToken }
|
||||
%destructor db_name { PARSER_DESTRUCTOR_TRACE; }
|
||||
db_name(A) ::= NK_ID(B). { PARSER_TRACE; A = B; }
|
||||
|
||||
%type table_name { SToken }
|
||||
%destructor table_name { PARSER_DESTRUCTOR_TRACE; }
|
||||
table_name(A) ::= NK_ID(B). { PARSER_TRACE; A = B; }
|
||||
|
||||
%type column_name { SToken }
|
||||
%destructor column_name { PARSER_DESTRUCTOR_TRACE; }
|
||||
column_name(A) ::= NK_ID(B). { PARSER_TRACE; A = B; }
|
||||
|
||||
%type table_alias { SToken }
|
||||
%destructor table_alias { PARSER_DESTRUCTOR_TRACE; }
|
||||
table_alias(A) ::= NK_ID(B). { PARSER_TRACE; A = B; }
|
||||
|
||||
/*6.4*********************************************** value_specification *********************************************************/
|
||||
unsigned_value_specification ::= unsigned_literal.
|
||||
unsigned_value_specification ::= NK_QUESTION.
|
||||
|
||||
/*6.35 todo *********************************************** value_expression_primary *********************************************************/
|
||||
value_expression_primary ::= NK_LP value_expression NK_RP.
|
||||
value_expression_primary ::= nonparenthesized_value_expression_primary.
|
||||
|
||||
nonparenthesized_value_expression_primary ::= unsigned_value_specification.
|
||||
nonparenthesized_value_expression_primary ::= column_reference.
|
||||
//nonparenthesized_value_expression_primary ::= agg_function.
|
||||
nonparenthesized_value_expression_primary ::= subquery.
|
||||
//nonparenthesized_value_expression_primary ::= case_expression. // todo
|
||||
//nonparenthesized_value_expression_primary ::= cast_specification. // todo
|
||||
|
||||
column_reference(A) ::= column_name(B). { PARSER_TRACE; A = createColumnNode(pCxt, NULL, &B); }
|
||||
column_reference(A) ::= table_name(B) NK_DOT column_name(C). { PARSER_TRACE; A = createColumnNode(pCxt, &B, &C); }
|
||||
|
||||
/*6.35*********************************************** boolean_value_expression *********************************************************/
|
||||
boolean_value_expression(A) ::= boolean_primary(B). { PARSER_TRACE; A = B; }
|
||||
boolean_value_expression(A) ::= NOT boolean_primary(B). { PARSER_TRACE; A = createLogicConditionNode(pCxt, LOGIC_COND_TYPE_NOT, B, NULL); }
|
||||
boolean_value_expression(A) ::=
|
||||
boolean_value_expression(B) OR boolean_value_expression(C). { PARSER_TRACE; A = createLogicConditionNode(pCxt, LOGIC_COND_TYPE_OR, B, C); }
|
||||
boolean_value_expression(A) ::=
|
||||
boolean_value_expression(B) AND boolean_value_expression(C). { PARSER_TRACE; A = createLogicConditionNode(pCxt, LOGIC_COND_TYPE_AND, B, C); }
|
||||
|
||||
boolean_primary(A) ::= predicate(B). { PARSER_TRACE; A = B; }
|
||||
boolean_primary(A) ::= NK_LP boolean_value_expression(B) NK_RP. { PARSER_TRACE; A = B; }
|
||||
|
||||
/*7.5*********************************************** from_clause *********************************************************/
|
||||
from_clause(A) ::= FROM table_reference_list(B). { PARSER_TRACE; A = B; }
|
||||
|
||||
table_reference_list(A) ::= table_reference(B). { PARSER_TRACE; A = B; }
|
||||
table_reference_list(A) ::= table_reference_list(B) NK_COMMA table_reference(C). { PARSER_TRACE; A = createJoinTableNode(pCxt, JOIN_TYPE_INNER, B, C, NULL); }
|
||||
|
||||
/*7.6*********************************************** table_reference *****************************************************/
|
||||
table_reference(A) ::= table_primary(B). { PARSER_TRACE; A = B; }
|
||||
table_reference(A) ::= joined_table(B). { PARSER_TRACE; A = B; }
|
||||
|
||||
table_primary(A) ::= table_name(B) correlation_or_recognition_opt(C). { PARSER_TRACE; A = createRealTableNode(pCxt, NULL, &B, &C); }
|
||||
table_primary(A) ::=
|
||||
db_name(B) NK_DOT table_name(C) correlation_or_recognition_opt(D). { PARSER_TRACE; A = createRealTableNode(pCxt, &B, &C, &D); }
|
||||
table_primary(A) ::= subquery(B) correlation_or_recognition_opt(C). { PARSER_TRACE; A = createTempTableNode(pCxt, B, &C); }
|
||||
table_primary ::= parenthesized_joined_table.
|
||||
|
||||
%type correlation_or_recognition_opt { SToken }
|
||||
%destructor correlation_or_recognition_opt { PARSER_DESTRUCTOR_TRACE; }
|
||||
correlation_or_recognition_opt(A) ::= . { PARSER_TRACE; A = nil_token; }
|
||||
correlation_or_recognition_opt(A) ::= table_alias(B). { PARSER_TRACE; A = B; }
|
||||
correlation_or_recognition_opt(A) ::= AS table_alias(B). { PARSER_TRACE; A = B; }
|
||||
|
||||
parenthesized_joined_table(A) ::= NK_LP joined_table(B) NK_RP. { PARSER_TRACE; A = B; }
|
||||
parenthesized_joined_table(A) ::= NK_LP parenthesized_joined_table(B) NK_RP. { PARSER_TRACE; A = B; }
|
||||
|
||||
/*7.10*********************************************** joined_table ************************************************************/
|
||||
joined_table(A) ::=
|
||||
table_reference(B) join_type(C) JOIN table_reference(D) ON search_condition(E). { PARSER_TRACE; A = createJoinTableNode(pCxt, C, B, D, E); }
|
||||
|
||||
%type join_type { EJoinType }
|
||||
%destructor join_type { PARSER_DESTRUCTOR_TRACE; }
|
||||
join_type(A) ::= INNER. { PARSER_TRACE; A = JOIN_TYPE_INNER; }
|
||||
|
||||
/*7.15*********************************************** query_specification *************************************************/
|
||||
query_specification(A) ::=
|
||||
SELECT set_quantifier_opt(B) select_list(C) from_clause(D) where_clause_opt(E)
|
||||
partition_by_clause_opt(F) twindow_clause_opt(G)
|
||||
group_by_clause_opt(H) having_clause_opt(I). {
|
||||
PARSER_TRACE;
|
||||
A = createSelectStmt(pCxt, B, C, D);
|
||||
A = addWhereClause(pCxt, A, E);
|
||||
A = addPartitionByClause(pCxt, A, F);
|
||||
A = addWindowClauseClause(pCxt, A, G);
|
||||
A = addGroupByClause(pCxt, A, H);
|
||||
A = addHavingClause(pCxt, A, I);
|
||||
}
|
||||
|
||||
%type set_quantifier_opt { bool }
|
||||
%destructor set_quantifier_opt { PARSER_DESTRUCTOR_TRACE; }
|
||||
set_quantifier_opt(A) ::= . { PARSER_TRACE; A = false; }
|
||||
set_quantifier_opt(A) ::= DISTINCT. { PARSER_TRACE; A = true; }
|
||||
set_quantifier_opt(A) ::= ALL. { PARSER_TRACE; A = false; }
|
||||
|
||||
%type select_list { SNodeList* }
|
||||
%destructor select_list { PARSER_DESTRUCTOR_TRACE; nodesDestroyList($$); }
|
||||
select_list(A) ::= NK_STAR. { PARSER_TRACE; A = NULL; }
|
||||
select_list(A) ::= select_sublist(B). { PARSER_TRACE; A = B; }
|
||||
|
||||
%type select_sublist { SNodeList* }
|
||||
%destructor select_sublist { PARSER_DESTRUCTOR_TRACE; nodesDestroyList($$); }
|
||||
select_sublist(A) ::= select_item(B). { PARSER_TRACE; A = createNodeList(pCxt, B); }
|
||||
select_sublist(A) ::= select_sublist(B) NK_COMMA select_item(C). { PARSER_TRACE; A = addNodeToList(pCxt, B, C); }
|
||||
|
||||
select_item(A) ::= value_expression(B). { PARSER_TRACE; A = B; }
|
||||
select_item(A) ::= value_expression(B) NK_ID(C). { PARSER_TRACE; A = setProjectionAlias(pCxt, B, &C); }
|
||||
select_item(A) ::= value_expression(B) AS NK_ID(C). { PARSER_TRACE; A = setProjectionAlias(pCxt, B, &C); }
|
||||
select_item(A) ::= table_name(B) NK_DOT NK_STAR(C). { PARSER_TRACE; A = createColumnNode(pCxt, &B, &C); }
|
||||
|
||||
/*7.16*********************************************** query_expression ****************************************************/
|
||||
query_expression(A) ::=
|
||||
query_expression_body(B)
|
||||
order_by_clause_opt(C) slimit_clause_opt(D) limit_clause_opt(E). {
|
||||
PARSER_TRACE;
|
||||
A = addOrderByClause(pCxt, B, C);
|
||||
A = addSlimitClause(pCxt, A, D);
|
||||
A = addLimitClause(pCxt, A, E);
|
||||
}
|
||||
|
||||
query_expression_body(A) ::= query_primary(B). { PARSER_TRACE; A = B; }
|
||||
query_expression_body(A) ::=
|
||||
query_expression_body(B) UNION ALL query_expression_body(D). { PARSER_TRACE; A = createSetOperator(pCxt, SET_OP_TYPE_UNION_ALL, B, D); }
|
||||
|
||||
query_primary(A) ::= query_specification(B). { PARSER_TRACE; A = B; }
|
||||
query_primary(A) ::=
|
||||
NK_LP query_expression_body(B)
|
||||
order_by_clause_opt limit_clause_opt slimit_clause_opt NK_RP. { PARSER_TRACE; A = B;}
|
||||
|
||||
%type order_by_clause_opt { SNodeList* }
|
||||
%destructor order_by_clause_opt { PARSER_DESTRUCTOR_TRACE; nodesDestroyList($$); }
|
||||
order_by_clause_opt(A) ::= . { PARSER_TRACE; A = NULL; }
|
||||
order_by_clause_opt(A) ::= ORDER BY sort_specification_list(B). { PARSER_TRACE; A = B; }
|
||||
|
||||
slimit_clause_opt(A) ::= . { PARSER_TRACE; A = NULL; }
|
||||
slimit_clause_opt(A) ::= SLIMIT signed_integer(B). { PARSER_TRACE; A = createLimitNode(pCxt, B, 0); }
|
||||
slimit_clause_opt(A) ::= SLIMIT signed_integer(B) SOFFSET signed_integer(C). { PARSER_TRACE; A = createLimitNode(pCxt, B, C); }
|
||||
slimit_clause_opt(A) ::= SLIMIT signed_integer(C) NK_COMMA signed_integer(B). { PARSER_TRACE; A = createLimitNode(pCxt, B, C); }
|
||||
|
||||
limit_clause_opt(A) ::= . { PARSER_TRACE; A = NULL; }
|
||||
limit_clause_opt(A) ::= LIMIT signed_integer(B). { PARSER_TRACE; A = createLimitNode(pCxt, B, 0); }
|
||||
limit_clause_opt(A) ::= LIMIT signed_integer(B) OFFSET signed_integer(C). { PARSER_TRACE; A = createLimitNode(pCxt, B, C); }
|
||||
limit_clause_opt(A) ::= LIMIT signed_integer(C) NK_COMMA signed_integer(B). { PARSER_TRACE; A = createLimitNode(pCxt, B, C); }
|
||||
|
||||
/*7.18*********************************************** subquery ************************************************************/
|
||||
subquery(A) ::= NK_LR query_expression(B) NK_RP. { PARSER_TRACE; A = B; }
|
||||
|
||||
/*8.1*********************************************** predicate ************************************************************/
|
||||
predicate ::= .
|
||||
|
||||
/*8.21 todo *********************************************** search_condition ************************************************************/
|
||||
search_condition(A) ::= boolean_value_expression(B). { PARSER_TRACE; A = B; }
|
||||
|
||||
/*10.10*********************************************** sort_specification_list ************************************************************/
|
||||
%type sort_specification_list { SNodeList* }
|
||||
%destructor sort_specification_list { PARSER_DESTRUCTOR_TRACE; nodesDestroyList($$); }
|
||||
sort_specification_list(A) ::= sort_specification(B). { PARSER_TRACE; A = createNodeList(pCxt, B); }
|
||||
sort_specification_list(A) ::=
|
||||
sort_specification_list(B) NK_COMMA sort_specification(C). { PARSER_TRACE; A = addNodeToList(pCxt, B, C); }
|
||||
|
||||
sort_specification(A) ::=
|
||||
value_expression(B) ordering_specification_opt(C) null_ordering_opt(D). { PARSER_TRACE; A = createOrderByExprNode(pCxt, B, C, D); }
|
||||
|
||||
%type ordering_specification_opt EOrder
|
||||
%destructor ordering_specification_opt { PARSER_DESTRUCTOR_TRACE; }
|
||||
ordering_specification_opt(A) ::= . { PARSER_TRACE; A = ORDER_ASC; }
|
||||
ordering_specification_opt(A) ::= ASC. { PARSER_TRACE; A = ORDER_ASC; }
|
||||
ordering_specification_opt(A) ::= DESC. { PARSER_TRACE; A = ORDER_DESC; }
|
||||
|
||||
%type null_ordering_opt ENullOrder
|
||||
%destructor null_ordering_opt { PARSER_DESTRUCTOR_TRACE; }
|
||||
null_ordering_opt(A) ::= . { PARSER_TRACE; A = NULL_ORDER_DEFAULT; }
|
||||
null_ordering_opt(A) ::= NULLS FIRST. { PARSER_TRACE; A = NULL_ORDER_FIRST; }
|
||||
null_ordering_opt(A) ::= NULLS LAST. { PARSER_TRACE; A = NULL_ORDER_LAST; }
|
||||
|
||||
/************************************************ todo ************************************************************/
|
||||
|
||||
where_clause_opt ::= .
|
||||
|
||||
%type partition_by_clause_opt { SNodeList* }
|
||||
%destructor partition_by_clause_opt { PARSER_DESTRUCTOR_TRACE; nodesDestroyList($$); }
|
||||
partition_by_clause_opt ::=.
|
||||
|
||||
twindow_clause_opt ::= .
|
||||
|
||||
%type group_by_clause_opt { SNodeList* }
|
||||
%destructor group_by_clause_opt { PARSER_DESTRUCTOR_TRACE; nodesDestroyList($$); }
|
||||
group_by_clause_opt ::= .
|
||||
|
||||
having_clause_opt ::= .
|
||||
|
||||
//////////////////////// value_function /////////////////////////////////
|
||||
value_function ::= NK_ID NK_LP value_expression NK_RP.
|
||||
value_function ::= NK_ID NK_LP value_expression NK_COMMA value_expression NK_RP.
|
||||
|
||||
//////////////////////// value_expression_primary /////////////////////////////////
|
||||
value_expression_primary ::= NK_LP value_expression NK_RP.
|
||||
value_expression_primary ::= nonparenthesized_value_expression_primary.
|
||||
|
||||
nonparenthesized_value_expression_primary ::= literal.
|
||||
// ?
|
||||
nonparenthesized_value_expression_primary ::= column_reference.
|
||||
|
||||
literal ::= NK_LITERAL.
|
||||
|
||||
column_reference(A) ::= NK_ID(B). { PARSER_TRACE; A = createColumnNode(pCxt, NULL, &B); }
|
||||
column_reference(A) ::= table_name(B) NK_DOT NK_ID(C). { PARSER_TRACE; A = createColumnNode(pCxt, &B, &C); }
|
||||
|
||||
//////////////////////// value_expression /////////////////////////////////
|
||||
value_expression ::= common_value_expression.
|
||||
|
||||
|
@ -93,107 +293,4 @@ numeric_value_expression ::= numeric_value_expression NK_STAR numeric_value_expr
|
|||
numeric_value_expression ::= numeric_value_expression NK_SLASH numeric_value_expression.
|
||||
|
||||
numeric_primary ::= value_expression_primary.
|
||||
numeric_primary ::= value_function.
|
||||
|
||||
//////////////////////// query_specification /////////////////////////////////
|
||||
query_specification(A) ::= SELECT set_quantifier_opt(B) select_list(C) from_clause(D). { PARSER_TRACE; A = createSelectStmt(pCxt, B, C, D); }
|
||||
|
||||
%type set_quantifier_opt { bool }
|
||||
%destructor set_quantifier_opt {}
|
||||
set_quantifier_opt(A) ::= . { PARSER_TRACE; A = false; }
|
||||
set_quantifier_opt(A) ::= DISTINCT. { PARSER_TRACE; A = true; }
|
||||
set_quantifier_opt(A) ::= ALL. { PARSER_TRACE; A = false; }
|
||||
|
||||
%type select_list { SNodeList* }
|
||||
%destructor select_list { nodesDestroyNodeList($$); }
|
||||
select_list(A) ::= NK_STAR. { PARSER_TRACE; A = NULL; }
|
||||
select_list(A) ::= select_sublist(B). { PARSER_TRACE; A = B; }
|
||||
|
||||
%type select_sublist { SNodeList* }
|
||||
%destructor select_sublist { nodesDestroyNodeList($$); }
|
||||
select_sublist(A) ::= select_item(B). { PARSER_TRACE; A = createNodeList(pCxt, B); }
|
||||
select_sublist(A) ::= select_sublist(B) NK_COMMA select_item(C). { PARSER_TRACE; A = addNodeToList(pCxt, B, C); }
|
||||
|
||||
select_item(A) ::= value_expression(B). { PARSER_TRACE; A = B; }
|
||||
select_item(A) ::= value_expression(B) AS NK_ID(C). { PARSER_TRACE; A = setProjectionAlias(pCxt, B, &C); }
|
||||
select_item(A) ::= table_name(B) NK_DOT NK_STAR(C). { PARSER_TRACE; A = createColumnNode(pCxt, &B, &C); }
|
||||
|
||||
from_clause(A) ::= FROM table_reference_list(B). { PARSER_TRACE; A = B; }
|
||||
|
||||
//%type table_reference_list { SNodeList* }
|
||||
//%destructor table_reference_list { nodesDestroyNodeList($$); }
|
||||
table_reference_list(A) ::= table_reference(B). { PARSER_TRACE; A = B; }
|
||||
//table_reference_list(A) ::= table_reference_list(B) NK_COMMA table_reference(C). { PARSER_TRACE; A = createJoinTableNode(pCxt, B, C); }
|
||||
|
||||
//table_reference(A) ::= NK_ID(B). { PARSER_TRACE; A = createRealTableNode(pCxt, ); }
|
||||
table_reference(A) ::= table_factor(B). { PARSER_TRACE; A = B; }
|
||||
//table_reference ::= joined_table.
|
||||
|
||||
table_factor(A) ::= table_primary(B). { PARSER_TRACE; A = B; }
|
||||
|
||||
table_primary(A) ::= table_name(B). { PARSER_TRACE; A = createRealTableNode(pCxt, NULL, &B); }
|
||||
table_primary(A) ::= db_name(B) NK_DOT table_name(C). { PARSER_TRACE; A = createRealTableNode(pCxt, &B, &C); }
|
||||
table_primary ::= derived_table.
|
||||
|
||||
derived_table ::= table_subquery.
|
||||
|
||||
%type db_name { SToken }
|
||||
db_name(A) ::= NK_ID(B). { PARSER_TRACE; A = B; }
|
||||
%type table_name { SToken }
|
||||
table_name(A) ::= NK_ID(B). { PARSER_TRACE; A = B; }
|
||||
|
||||
//////////////////////// subquery /////////////////////////////////
|
||||
subquery ::= NK_LR query_expression NK_RP.
|
||||
|
||||
table_subquery ::= subquery.
|
||||
|
||||
// query_expression
|
||||
query_expression(A) ::= with_clause_opt query_expression_body(B) order_by_clause_opt(C) slimit_clause_opt(D) limit_clause_opt(E). {
|
||||
PARSER_TRACE;
|
||||
addOrderByList(pCxt, B, C);
|
||||
addSlimit(pCxt, B, D);
|
||||
addLimit(pCxt, B, E);
|
||||
A = B;
|
||||
}
|
||||
|
||||
// WITH AS
|
||||
with_clause_opt ::= . {}
|
||||
|
||||
query_expression_body(A) ::= query_primary(B). { PARSER_TRACE; A = B; }
|
||||
query_expression_body(A) ::= query_expression_body(B) UNION ALL query_expression_body(D). { PARSER_TRACE; A = createSetOperator(pCxt, SET_OP_TYPE_UNION_ALL, B, D); }
|
||||
|
||||
query_primary(A) ::= query_specification(B). { PARSER_TRACE; A = B; }
|
||||
query_primary(A) ::= NK_LP query_expression_body(B) order_by_clause_opt limit_clause_opt slimit_clause_opt NK_RP. { PARSER_TRACE; A = B;}
|
||||
|
||||
%type order_by_clause_opt { SNodeList* }
|
||||
%destructor order_by_clause_opt { nodesDestroyNodeList($$); }
|
||||
order_by_clause_opt(A) ::= . { PARSER_TRACE; A = NULL; }
|
||||
order_by_clause_opt(A) ::= ORDER BY sort_specification_list(B). { PARSER_TRACE; A = B; }
|
||||
|
||||
slimit_clause_opt(A) ::= . { A = NULL; }
|
||||
slimit_clause_opt(A) ::= SLIMIT NK_INTEGER(B) SOFFSET NK_INTEGER(C). { A = createLimitNode(pCxt, &B, &C); }
|
||||
slimit_clause_opt(A) ::= SLIMIT NK_INTEGER(C) NK_COMMA NK_INTEGER(B). { A = createLimitNode(pCxt, &B, &C); }
|
||||
|
||||
limit_clause_opt(A) ::= . { A = NULL; }
|
||||
limit_clause_opt(A) ::= LIMIT NK_INTEGER(B) OFFSET NK_INTEGER(C). { A = createLimitNode(pCxt, &B, &C); }
|
||||
limit_clause_opt(A) ::= LIMIT NK_INTEGER(C) NK_COMMA NK_INTEGER(B). { A = createLimitNode(pCxt, &B, &C); }
|
||||
|
||||
//////////////////////// sort_specification_list /////////////////////////////////
|
||||
%type sort_specification_list { SNodeList* }
|
||||
%destructor sort_specification_list { nodesDestroyNodeList($$); }
|
||||
sort_specification_list(A) ::= sort_specification(B). { PARSER_TRACE; A = createNodeList(pCxt, B); }
|
||||
sort_specification_list(A) ::= sort_specification_list(B) NK_COMMA sort_specification(C). { PARSER_TRACE; A = addNodeToList(pCxt, B, C); }
|
||||
|
||||
sort_specification(A) ::= value_expression(B) ordering_specification_opt(C) null_ordering_opt(D). { PARSER_TRACE; A = createOrderByExprNode(pCxt, B, C, D); }
|
||||
|
||||
%type ordering_specification_opt EOrder
|
||||
%destructor ordering_specification_opt {}
|
||||
ordering_specification_opt(A) ::= . { PARSER_TRACE; A = ORDER_ASC; }
|
||||
ordering_specification_opt(A) ::= ASC. { PARSER_TRACE; A = ORDER_ASC; }
|
||||
ordering_specification_opt(A) ::= DESC. { PARSER_TRACE; A = ORDER_DESC; }
|
||||
|
||||
%type null_ordering_opt ENullOrder
|
||||
%destructor null_ordering_opt {}
|
||||
null_ordering_opt(A) ::= . { PARSER_TRACE; A = NULL_ORDER_DEFAULT; }
|
||||
null_ordering_opt(A) ::= NULLS FIRST. { PARSER_TRACE; A = NULL_ORDER_FIRST; }
|
||||
null_ordering_opt(A) ::= NULLS LAST. { PARSER_TRACE; A = NULL_ORDER_LAST; }
|
||||
numeric_primary ::= value_function.
|
|
@ -16,10 +16,46 @@
|
|||
#include "ttoken.h"
|
||||
#include "astCreateContext.h"
|
||||
|
||||
void* acquireRaii(SAstCreateContext* pCxt, void* p) {
|
||||
typedef struct SResourceEntry {
|
||||
EResourceType type;
|
||||
void* res;
|
||||
} SResourceEntry;
|
||||
|
||||
int32_t createAstCreateContext(SParseContext* pQueryCxt, SAstCreateContext* pCxt) {
|
||||
pCxt->pQueryCxt = pQueryCxt;
|
||||
pCxt->notSupport = false;
|
||||
pCxt->valid = true;
|
||||
pCxt->pRootNode = NULL;
|
||||
pCxt->pResourceHash = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
||||
if (NULL == pCxt->pResourceHash) {
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t destroyAstCreateContext(SAstCreateContext* pCxt) {
|
||||
SResourceEntry* item = taosHashIterate(pCxt->pResourceHash, NULL);
|
||||
while (item) {
|
||||
switch (item->type) {
|
||||
case AST_CXT_RESOURCE_NODE:
|
||||
nodesDestroyNode(item->res);
|
||||
break;
|
||||
case AST_CXT_RESOURCE_NODE_LIST:
|
||||
nodesDestroyList(item->res);
|
||||
break;
|
||||
default:
|
||||
tfree(item->res);
|
||||
}
|
||||
item = taosHashIterate(pCxt->pResourceHash, item);
|
||||
}
|
||||
}
|
||||
|
||||
void* acquireRaii(SAstCreateContext* pCxt, EResourceType type, void* p) {
|
||||
if (NULL == p) {
|
||||
return NULL;
|
||||
}
|
||||
SResourceEntry entry = { .type = type, .res = p };
|
||||
taosHashPut(pCxt->pResourceHash, &p, POINTER_BYTES, &entry, sizeof(SResourceEntry));
|
||||
return p;
|
||||
}
|
||||
|
||||
|
@ -27,14 +63,6 @@ void* releaseRaii(SAstCreateContext* pCxt, void* p) {
|
|||
if (NULL == p) {
|
||||
return NULL;
|
||||
}
|
||||
taosHashRemove(pCxt->pResourceHash, &p, POINTER_BYTES);
|
||||
return p;
|
||||
}
|
||||
|
||||
int32_t createAstCreater(const SParseContext* pQueryCxt, SAstCreateContext* pCxt) {
|
||||
|
||||
}
|
||||
|
||||
int32_t destroyAstCreater(SAstCreateContext* pCxt) {
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -16,76 +16,216 @@
|
|||
|
||||
#include "astCreateFuncs.h"
|
||||
|
||||
#include "astCreateContext.h"
|
||||
#define CHECK_OUT_OF_MEM(p) \
|
||||
do { \
|
||||
if (NULL == (p)) { \
|
||||
pCxt->valid = false; \
|
||||
return NULL; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
bool checkTableName(const SToken* pTableName) {
|
||||
printf("%p : %d, %d, %s\n", pTableName, pTableName->type, pTableName->n, pTableName->z);
|
||||
return pTableName->n < TSDB_TABLE_NAME_LEN ? true : false;
|
||||
SToken nil_token = { .type = TK_NIL, .n = 0, .z = NULL };
|
||||
|
||||
static bool checkDbName(SAstCreateContext* pCxt, const SToken* pDbName) {
|
||||
if (NULL == pDbName) {
|
||||
return true;
|
||||
}
|
||||
pCxt->valid = pDbName->n < TSDB_DB_NAME_LEN ? true : false;
|
||||
return pCxt->valid;
|
||||
}
|
||||
|
||||
SNodeList* addNodeToList(SAstCreateContext* pCxt, SNodeList* pList, SNode* pNode) {
|
||||
|
||||
static bool checkTableName(SAstCreateContext* pCxt, const SToken* pTableName) {
|
||||
if (NULL == pTableName) {
|
||||
return true;
|
||||
}
|
||||
pCxt->valid = pTableName->n < TSDB_TABLE_NAME_LEN ? true : false;
|
||||
return pCxt->valid;
|
||||
}
|
||||
|
||||
SNode* addOrderByList(SAstCreateContext* pCxt, SNode* pStmt, SNodeList* pOrderByList) {
|
||||
|
||||
}
|
||||
|
||||
SNode* addSlimit(SAstCreateContext* pCxt, SNode* pStmt, SNode* pSlimit) {
|
||||
|
||||
}
|
||||
|
||||
SNode* addLimit(SAstCreateContext* pCxt, SNode* pStmt, SNode* pLimit) {
|
||||
|
||||
}
|
||||
|
||||
SNode* createColumnNode(SAstCreateContext* pCxt, const SToken* pTableName, const SToken* pColumnName) {
|
||||
|
||||
}
|
||||
|
||||
SNode* createLimitNode(SAstCreateContext* pCxt, const SToken* pLimit, const SToken* pOffset) {
|
||||
|
||||
static bool checkColumnName(SAstCreateContext* pCxt, const SToken* pColumnName) {
|
||||
if (NULL == pColumnName) {
|
||||
return true;
|
||||
}
|
||||
pCxt->valid = pColumnName->n < TSDB_COL_NAME_LEN ? true : false;
|
||||
return pCxt->valid;
|
||||
}
|
||||
|
||||
SNodeList* createNodeList(SAstCreateContext* pCxt, SNode* pNode) {
|
||||
SNodeList* list = nodesMakeList();
|
||||
CHECK_OUT_OF_MEM(list);
|
||||
return acquireRaii(pCxt, AST_CXT_RESOURCE_NODE_LIST, nodesListAppend(list, releaseRaii(pCxt, pNode)));
|
||||
}
|
||||
|
||||
SNodeList* addNodeToList(SAstCreateContext* pCxt, SNodeList* pList, SNode* pNode) {
|
||||
return nodesListAppend(pList, releaseRaii(pCxt, pNode));
|
||||
}
|
||||
|
||||
SNode* createColumnNode(SAstCreateContext* pCxt, const SToken* pTableName, const SToken* pColumnName) {
|
||||
if (!checkTableName(pCxt, pTableName) || !checkColumnName(pCxt, pColumnName)) {
|
||||
return NULL;
|
||||
}
|
||||
SColumnNode* col = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN);
|
||||
CHECK_OUT_OF_MEM(col);
|
||||
if (NULL != pTableName) {
|
||||
strncpy(col->tableName, pTableName->z, pTableName->n);
|
||||
}
|
||||
strncpy(col->colName, pColumnName->z, pColumnName->n);
|
||||
return acquireRaii(pCxt, AST_CXT_RESOURCE_NODE, col);
|
||||
}
|
||||
|
||||
SNode* createValueNode(SAstCreateContext* pCxt, int32_t dataType, const SToken* pLiteral) {
|
||||
SValueNode* val = (SValueNode*)nodesMakeNode(QUERY_NODE_VALUE);
|
||||
CHECK_OUT_OF_MEM(val);
|
||||
// strncpy(col->colName, pColumnName->z, pColumnName->n);
|
||||
return acquireRaii(pCxt, AST_CXT_RESOURCE_NODE, val);
|
||||
}
|
||||
|
||||
SNode* addMinusSign(SAstCreateContext* pCxt, SNode* pNode) {
|
||||
// todo
|
||||
}
|
||||
|
||||
SNode* createLogicConditionNode(SAstCreateContext* pCxt, ELogicConditionType type, SNode* pParam1, SNode* pParam2) {
|
||||
SLogicConditionNode* cond = (SLogicConditionNode*)nodesMakeNode(QUERY_NODE_LOGIC_CONDITION);
|
||||
CHECK_OUT_OF_MEM(cond);
|
||||
cond->condType = type;
|
||||
cond->pParameterList = nodesMakeList();
|
||||
nodesListAppend(cond->pParameterList, releaseRaii(pCxt, pParam1));
|
||||
nodesListAppend(cond->pParameterList, releaseRaii(pCxt, pParam2));
|
||||
return acquireRaii(pCxt, AST_CXT_RESOURCE_NODE, cond);
|
||||
}
|
||||
|
||||
SNode* createRealTableNode(SAstCreateContext* pCxt, const SToken* pDbName, const SToken* pTableName, const SToken* pTableAlias) {
|
||||
if (!checkDbName(pCxt, pDbName) || !checkTableName(pCxt, pTableName)) {
|
||||
return NULL;
|
||||
}
|
||||
SRealTableNode* realTable = (SRealTableNode*)nodesMakeNode(QUERY_NODE_REAL_TABLE);
|
||||
CHECK_OUT_OF_MEM(realTable);
|
||||
if (NULL != pDbName) {
|
||||
strncpy(realTable->dbName, pDbName->z, pDbName->n);
|
||||
}
|
||||
strncpy(realTable->table.tableName, pTableName->z, pTableName->n);
|
||||
return acquireRaii(pCxt, AST_CXT_RESOURCE_NODE, realTable);
|
||||
}
|
||||
|
||||
SNode* createTempTableNode(SAstCreateContext* pCxt, SNode* pSubquery, const SToken* pTableAlias) {
|
||||
STempTableNode* tempTable = (STempTableNode*)nodesMakeNode(QUERY_NODE_TEMP_TABLE);
|
||||
CHECK_OUT_OF_MEM(tempTable);
|
||||
tempTable->pSubquery = pSubquery;
|
||||
return acquireRaii(pCxt, AST_CXT_RESOURCE_NODE, tempTable);
|
||||
}
|
||||
|
||||
SNode* createJoinTableNode(SAstCreateContext* pCxt, EJoinType type, SNode* pLeft, SNode* pRight, SNode* pJoinCond) {
|
||||
SJoinTableNode* joinTable = (SJoinTableNode*)nodesMakeNode(QUERY_NODE_JOIN_TABLE);
|
||||
CHECK_OUT_OF_MEM(joinTable);
|
||||
joinTable->joinType = type;
|
||||
joinTable->pLeft = releaseRaii(pCxt, pLeft);
|
||||
joinTable->pRight = releaseRaii(pCxt, pRight);
|
||||
joinTable->pOnCond = pJoinCond;
|
||||
return acquireRaii(pCxt, AST_CXT_RESOURCE_NODE, joinTable);
|
||||
}
|
||||
|
||||
SNode* createLimitNode(SAstCreateContext* pCxt, SNode* pLimit, SNode* pOffset) {
|
||||
SLimitNode* limitNode = (SLimitNode*)nodesMakeNode(QUERY_NODE_LIMIT);
|
||||
CHECK_OUT_OF_MEM(limitNode);
|
||||
// limitNode->limit = limit;
|
||||
// limitNode->offset = offset;
|
||||
return acquireRaii(pCxt, AST_CXT_RESOURCE_NODE, limitNode);
|
||||
}
|
||||
|
||||
SNode* createOrderByExprNode(SAstCreateContext* pCxt, SNode* pExpr, EOrder order, ENullOrder nullOrder) {
|
||||
|
||||
SOrderByExprNode* orderByExpr = (SOrderByExprNode*)nodesMakeNode(QUERY_NODE_ORDER_BY_EXPR);
|
||||
CHECK_OUT_OF_MEM(orderByExpr);
|
||||
orderByExpr->pExpr = releaseRaii(pCxt, pExpr);
|
||||
orderByExpr->order = order;
|
||||
orderByExpr->nullOrder = nullOrder;
|
||||
return acquireRaii(pCxt, AST_CXT_RESOURCE_NODE, orderByExpr);
|
||||
}
|
||||
|
||||
SNode* createRealTableNode(SAstCreateContext* pCxt, const SToken* pDbName, const SToken* pTableName) {
|
||||
SRealTableNode* realTable = (SRealTableNode*)nodesMakeNode(QUERY_NODE_REAL_TABLE);
|
||||
if (NULL != pDbName) {
|
||||
printf("DbName %p : %d, %d, %s\n", pDbName, pDbName->type, pDbName->n, pDbName->z);
|
||||
strncpy(realTable->dbName, pDbName->z, pDbName->n);
|
||||
SNode* setProjectionAlias(SAstCreateContext* pCxt, SNode* pNode, const SToken* pAlias) {
|
||||
strncpy(((SExprNode*)pNode)->aliasName, pAlias->z, pAlias->n);
|
||||
return pNode;
|
||||
}
|
||||
|
||||
SNode* addWhereClause(SAstCreateContext* pCxt, SNode* pStmt, SNode* pWhere) {
|
||||
if (QUERY_NODE_SELECT_STMT == nodeType(pStmt)) {
|
||||
((SSelectStmt*)pStmt)->pWhere = releaseRaii(pCxt, pWhere);
|
||||
}
|
||||
printf("TableName %p : %d, %d, %s\n", pTableName, pTableName->type, pTableName->n, pTableName->z);
|
||||
strncpy(realTable->table.tableName, pTableName->z, pTableName->n);
|
||||
return acquireRaii(pCxt, realTable);
|
||||
return pStmt;
|
||||
}
|
||||
|
||||
SNode* addPartitionByClause(SAstCreateContext* pCxt, SNode* pStmt, SNodeList* pPartitionByList) {
|
||||
if (QUERY_NODE_SELECT_STMT == nodeType(pStmt)) {
|
||||
((SSelectStmt*)pStmt)->pPartitionByList = releaseRaii(pCxt, pPartitionByList);
|
||||
}
|
||||
return pStmt;
|
||||
}
|
||||
|
||||
SNode* addWindowClauseClause(SAstCreateContext* pCxt, SNode* pStmt, SNode* pWindow) {
|
||||
if (QUERY_NODE_SELECT_STMT == nodeType(pStmt)) {
|
||||
((SSelectStmt*)pStmt)->pWindow = releaseRaii(pCxt, pWindow);
|
||||
}
|
||||
return pStmt;
|
||||
}
|
||||
|
||||
SNode* addGroupByClause(SAstCreateContext* pCxt, SNode* pStmt, SNodeList* pGroupByList) {
|
||||
if (QUERY_NODE_SELECT_STMT == nodeType(pStmt)) {
|
||||
((SSelectStmt*)pStmt)->pGroupByList = releaseRaii(pCxt, pGroupByList);
|
||||
}
|
||||
return pStmt;
|
||||
}
|
||||
|
||||
SNode* addHavingClause(SAstCreateContext* pCxt, SNode* pStmt, SNode* pHaving) {
|
||||
if (QUERY_NODE_SELECT_STMT == nodeType(pStmt)) {
|
||||
((SSelectStmt*)pStmt)->pHaving = releaseRaii(pCxt, pHaving);
|
||||
}
|
||||
return pStmt;
|
||||
}
|
||||
|
||||
SNode* addOrderByClause(SAstCreateContext* pCxt, SNode* pStmt, SNodeList* pOrderByList) {
|
||||
if (QUERY_NODE_SELECT_STMT == nodeType(pStmt)) {
|
||||
((SSelectStmt*)pStmt)->pOrderByList = releaseRaii(pCxt, pOrderByList);
|
||||
}
|
||||
return pStmt;
|
||||
}
|
||||
|
||||
SNode* addSlimitClause(SAstCreateContext* pCxt, SNode* pStmt, SNode* pSlimit) {
|
||||
if (QUERY_NODE_SELECT_STMT == nodeType(pStmt)) {
|
||||
((SSelectStmt*)pStmt)->pSlimit = releaseRaii(pCxt, pSlimit);
|
||||
}
|
||||
return pStmt;
|
||||
}
|
||||
|
||||
SNode* addLimitClause(SAstCreateContext* pCxt, SNode* pStmt, SNode* pLimit) {
|
||||
if (QUERY_NODE_SELECT_STMT == nodeType(pStmt)) {
|
||||
((SSelectStmt*)pStmt)->pLimit = releaseRaii(pCxt, pLimit);
|
||||
}
|
||||
return pStmt;
|
||||
}
|
||||
|
||||
SNode* createSelectStmt(SAstCreateContext* pCxt, bool isDistinct, SNodeList* pProjectionList, SNode* pTable) {
|
||||
SSelectStmt* select = (SSelectStmt*)nodesMakeNode(QUERY_NODE_SELECT_STMT);
|
||||
CHECK_OUT_OF_MEM(select);
|
||||
select->isDistinct = isDistinct;
|
||||
if (NULL == pProjectionList) {
|
||||
select->isStar = true;
|
||||
}
|
||||
select->pProjectionList = releaseRaii(pCxt, pProjectionList);
|
||||
printf("pTable = %p, name = %s\n", pTable, ((SRealTableNode*)pTable)->table.tableName);
|
||||
select->pFromTable = releaseRaii(pCxt, pTable);
|
||||
return acquireRaii(pCxt, select);
|
||||
return acquireRaii(pCxt, AST_CXT_RESOURCE_NODE, select);
|
||||
}
|
||||
|
||||
SNode* createSetOperator(SAstCreateContext* pCxt, ESetOperatorType type, SNode* pLeft, SNode* pRight) {
|
||||
|
||||
SSetOperator* setOp = (SSetOperator*)nodesMakeNode(QUERY_NODE_SET_OPERATOR);
|
||||
CHECK_OUT_OF_MEM(setOp);
|
||||
setOp->opType = type;
|
||||
setOp->pLeft = releaseRaii(pCxt, pLeft);
|
||||
setOp->pRight = releaseRaii(pCxt, pRight);
|
||||
return acquireRaii(pCxt, AST_CXT_RESOURCE_NODE, setOp);
|
||||
}
|
||||
|
||||
SNode* createShowStmt(SAstCreateContext* pCxt, EShowStmtType type) {
|
||||
|
||||
}
|
||||
|
||||
SNode* setProjectionAlias(SAstCreateContext* pCxt, SNode* pNode, const SToken* pAlias) {
|
||||
|
||||
SShowStmt* show = (SShowStmt*)nodesMakeNode(QUERY_NODE_SHOW_STMT);
|
||||
CHECK_OUT_OF_MEM(show);
|
||||
show->showType = type;
|
||||
return acquireRaii(pCxt, AST_CXT_RESOURCE_NODE, show);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -80,7 +80,8 @@ uint32_t getToken(const char* z, uint32_t* tokenId) {
|
|||
}
|
||||
|
||||
int32_t doParse(SParseContext* pParseCxt, SQuery* pQuery) {
|
||||
SAstCreateContext cxt = { .pQueryCxt = pParseCxt, .valid = true, .pRootNode = NULL };
|
||||
SAstCreateContext cxt;
|
||||
createAstCreateContext(pParseCxt, &cxt);
|
||||
void *pParser = NewParseAlloc(malloc);
|
||||
int32_t i = 0;
|
||||
while (1) {
|
||||
|
@ -93,7 +94,7 @@ int32_t doParse(SParseContext* pParseCxt, SQuery* pQuery) {
|
|||
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 %p : %d %d [%s]\n", &t0, t0.type, t0.n, t0.z);
|
||||
printf("token : %d %d [%s]\n", t0.type, t0.n, t0.z);
|
||||
i += t0.n;
|
||||
|
||||
switch (t0.type) {
|
||||
|
@ -130,7 +131,9 @@ int32_t doParse(SParseContext* pParseCxt, SQuery* pQuery) {
|
|||
}
|
||||
|
||||
abort_parse:
|
||||
printf("doParse completed.\n");
|
||||
NewParseFree(pParser, free);
|
||||
destroyAstCreateContext(&cxt);
|
||||
pQuery->pRoot = cxt.pRootNode;
|
||||
return cxt.valid ? TSDB_CODE_SUCCESS : TSDB_CODE_FAILED;
|
||||
}
|
||||
|
|
|
@ -38,11 +38,11 @@ protected:
|
|||
|
||||
}
|
||||
|
||||
int32_t run() {
|
||||
bool run(int32_t expectCode = TSDB_CODE_SUCCESS) {
|
||||
int32_t code = doParse(&cxt_, &query_);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
cout << "code:" << tstrerror(code) << ", msg:" << errMagBuf_ << endl;
|
||||
return code;
|
||||
return (code == expectCode);
|
||||
}
|
||||
cout << nodeType(query_.pRoot) << endl;
|
||||
if (NULL != query_.pRoot && QUERY_NODE_SELECT_STMT == nodeType(query_.pRoot)) {
|
||||
|
@ -76,7 +76,7 @@ protected:
|
|||
// return code;
|
||||
// }
|
||||
// cout << "node tree:\n" << pStr << endl;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
return (code == expectCode);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -136,8 +136,24 @@ TEST_F(NewParserTest, selectStar) {
|
|||
setDatabase("root", "test");
|
||||
|
||||
bind("SELECT * FROM t1");
|
||||
ASSERT_EQ(run(), TSDB_CODE_SUCCESS);
|
||||
ASSERT_TRUE(run());
|
||||
|
||||
bind("SELECT * FROM test.t1");
|
||||
ASSERT_EQ(run(), TSDB_CODE_SUCCESS);
|
||||
ASSERT_TRUE(run());
|
||||
}
|
||||
|
||||
TEST_F(NewParserTest, syntaxError) {
|
||||
setDatabase("root", "test");
|
||||
|
||||
bind("SELECTT * FROM t1");
|
||||
ASSERT_TRUE(run(TSDB_CODE_FAILED));
|
||||
|
||||
bind("SELECT *");
|
||||
ASSERT_TRUE(run(TSDB_CODE_FAILED));
|
||||
|
||||
bind("SELECT *, * FROM test.t1");
|
||||
ASSERT_TRUE(run(TSDB_CODE_FAILED));
|
||||
|
||||
bind("SELECT * FROM test.t1 t WHER");
|
||||
ASSERT_TRUE(run(TSDB_CODE_FAILED));
|
||||
}
|
||||
|
|
|
@ -15,17 +15,13 @@
|
|||
|
||||
#include "nodes.h"
|
||||
#include "nodesShowStmts.h"
|
||||
|
||||
bool nodesIsTimeorderQuery(const SNode* pQuery) {
|
||||
|
||||
}
|
||||
|
||||
bool nodesIsTimelineQuery(const SNode* pQuery) {
|
||||
|
||||
}
|
||||
#include "taoserror.h"
|
||||
|
||||
static SNode* makeNode(ENodeType type, size_t size) {
|
||||
SNode* p = calloc(1, size);
|
||||
if (NULL == p) {
|
||||
return NULL;
|
||||
}
|
||||
setNodeType(p, type);
|
||||
return p;
|
||||
}
|
||||
|
@ -78,6 +74,37 @@ void nodesDestroyNode(SNode* pNode) {
|
|||
|
||||
}
|
||||
|
||||
void nodesDestroyNodeList(SNodeList* pList) {
|
||||
SNodeList* nodesMakeList() {
|
||||
SNodeList* p = calloc(1, sizeof(SNodeList));
|
||||
if (NULL == p) {
|
||||
return NULL;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
SNodeList* nodesListAppend(SNodeList* pList, SNode* pNode) {
|
||||
if (NULL == pList || NULL == pNode) {
|
||||
return NULL;
|
||||
}
|
||||
SListCell* p = calloc(1, sizeof(SListCell));
|
||||
if (NULL == p) {
|
||||
terrno = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
return pList;
|
||||
}
|
||||
p->pNode = pNode;
|
||||
pList->pTail->pNext = p;
|
||||
pList->pTail = p;
|
||||
return pList;
|
||||
}
|
||||
|
||||
void nodesDestroyList(SNodeList* pList) {
|
||||
|
||||
}
|
||||
|
||||
bool nodesIsTimeorderQuery(const SNode* pQuery) {
|
||||
|
||||
}
|
||||
|
||||
bool nodesIsTimelineQuery(const SNode* pQuery) {
|
||||
|
||||
}
|
Loading…
Reference in New Issue