📄 gram.y
字号:
n->whereClause = $10; n->instead = $12; n->actions = $13; $$ = (Node *)n; } ;RuleActionList: NOTHING { $$ = NIL; } | SelectStmt { $$ = lcons($1, NIL); } | RuleActionStmt { $$ = lcons($1, NIL); } | '[' RuleActionBlock ']' { $$ = $2; } | '(' RuleActionBlock ')' { $$ = $2; } ;RuleActionBlock: RuleActionMulti { $$ = $1; } | RuleActionStmt { $$ = lcons($1, NIL); } ;RuleActionMulti: RuleActionMulti RuleActionStmt { $$ = lappend($1, $2); } | RuleActionMulti RuleActionStmt ';' { $$ = lappend($1, $2); } | RuleActionStmt ';' { $$ = lcons($1, NIL); } ;RuleActionStmt: InsertStmt | UpdateStmt | DeleteStmt | NotifyStmt ;event_object: relation_name '.' attr_name { $$ = makeNode(Attr); $$->relname = $1; $$->paramNo = NULL; $$->attrs = lcons(makeString($3), NIL); $$->indirection = NIL; } | relation_name { $$ = makeNode(Attr); $$->relname = $1; $$->paramNo = NULL; $$->attrs = NIL; $$->indirection = NIL; } ;/* change me to select, update, etc. some day */event: SELECT { $$ = CMD_SELECT; } | UPDATE { $$ = CMD_UPDATE; } | DELETE { $$ = CMD_DELETE; } | INSERT { $$ = CMD_INSERT; } ;opt_instead: INSTEAD { $$ = TRUE; } | /*EMPTY*/ { $$ = FALSE; } ;/***************************************************************************** * * QUERY: * NOTIFY <relation_name> can appear both in rule bodies and * as a query-level command * *****************************************************************************/NotifyStmt: NOTIFY relation_name { NotifyStmt *n = makeNode(NotifyStmt); n->relname = $2; $$ = (Node *)n; } ;ListenStmt: LISTEN relation_name { ListenStmt *n = makeNode(ListenStmt); n->relname = $2; $$ = (Node *)n; };UnlistenStmt: UNLISTEN relation_name { UnlistenStmt *n = makeNode(UnlistenStmt); n->relname = $2; $$ = (Node *)n; } | UNLISTEN '*' { UnlistenStmt *n = makeNode(UnlistenStmt); n->relname = "*"; $$ = (Node *)n; };/***************************************************************************** * * Transactions: * * abort transaction * (ABORT) * begin transaction * (BEGIN) * end transaction * (END) * *****************************************************************************/TransactionStmt: ABORT_TRANS opt_trans { TransactionStmt *n = makeNode(TransactionStmt); n->command = ABORT_TRANS; $$ = (Node *)n; } | BEGIN_TRANS opt_trans { TransactionStmt *n = makeNode(TransactionStmt); n->command = BEGIN_TRANS; $$ = (Node *)n; } | COMMIT opt_trans { TransactionStmt *n = makeNode(TransactionStmt); n->command = END_TRANS; $$ = (Node *)n; } | END_TRANS opt_trans { TransactionStmt *n = makeNode(TransactionStmt); n->command = END_TRANS; $$ = (Node *)n; } | ROLLBACK opt_trans { TransactionStmt *n = makeNode(TransactionStmt); n->command = ABORT_TRANS; $$ = (Node *)n; } ;opt_trans: WORK { $$ = TRUE; } | TRANSACTION { $$ = TRUE; } | /*EMPTY*/ { $$ = TRUE; } ;/***************************************************************************** * * QUERY: * define view <viewname> '('target-list ')' [where <quals> ] * *****************************************************************************/ViewStmt: CREATE VIEW name AS SelectStmt { ViewStmt *n = makeNode(ViewStmt); n->viewname = $3; n->query = (Query *)$5; if (((SelectStmt *)n->query)->sortClause != NULL) elog(ERROR,"Order by and Distinct on views is not implemented."); if (((SelectStmt *)n->query)->unionClause != NULL) elog(ERROR,"Views on unions not implemented."); if (((SelectStmt *)n->query)->forUpdate != NULL) elog(ERROR, "SELECT FOR UPDATE is not allowed in CREATE VIEW"); $$ = (Node *)n; } ;/***************************************************************************** * * QUERY: * load "filename" * *****************************************************************************/LoadStmt: LOAD file_name { LoadStmt *n = makeNode(LoadStmt); n->filename = $2; $$ = (Node *)n; } ;/***************************************************************************** * * QUERY: * createdb dbname * *****************************************************************************/CreatedbStmt: CREATE DATABASE database_name WITH opt_database1 opt_database2 { CreatedbStmt *n = makeNode(CreatedbStmt); if ($5 == NULL && $6 == NULL) { elog(ERROR, "CREATE DATABASE WITH requires at least an option"); } n->dbname = $3; n->dbpath = $5;#ifdef MULTIBYTE if ($6 != NULL) { n->encoding = pg_char_to_encoding($6); if (n->encoding < 0) { elog(ERROR, "invalid encoding name %s", $6); } } else { n->encoding = GetTemplateEncoding(); }#else if ($6 != NULL) elog(ERROR, "WITH ENCODING is not supported"); n->encoding = 0;#endif $$ = (Node *)n; } | CREATE DATABASE database_name { CreatedbStmt *n = makeNode(CreatedbStmt); n->dbname = $3; n->dbpath = NULL;#ifdef MULTIBYTE n->encoding = GetTemplateEncoding();#else n->encoding = 0;#endif $$ = (Node *)n; } ;opt_database1: LOCATION '=' location { $$ = $3; } | /*EMPTY*/ { $$ = NULL; } ;opt_database2: ENCODING '=' encoding { $$ = $3; } | /*EMPTY*/ { $$ = NULL; } ;location: Sconst { $$ = $1; } | DEFAULT { $$ = NULL; } | /*EMPTY*/ { $$ = NULL; } ;encoding: Sconst { $$ = $1; } | DEFAULT { $$ = NULL; } | /*EMPTY*/ { $$ = NULL; } ;/***************************************************************************** * * QUERY: * destroydb dbname * *****************************************************************************/DestroydbStmt: DROP DATABASE database_name { DestroydbStmt *n = makeNode(DestroydbStmt); n->dbname = $3; $$ = (Node *)n; } ;/***************************************************************************** * * QUERY: * cluster <index_name> on <relation_name> * *****************************************************************************/ClusterStmt: CLUSTER index_name ON relation_name { ClusterStmt *n = makeNode(ClusterStmt); n->relname = $4; n->indexname = $2; $$ = (Node*)n; } ;/***************************************************************************** * * QUERY: * vacuum * *****************************************************************************/VacuumStmt: VACUUM opt_verbose opt_analyze { VacuumStmt *n = makeNode(VacuumStmt); n->verbose = $2; n->analyze = $3; n->vacrel = NULL; n->va_spec = NIL; $$ = (Node *)n; } | VACUUM opt_verbose opt_analyze relation_name opt_va_list { VacuumStmt *n = makeNode(VacuumStmt); n->verbose = $2; n->analyze = $3; n->vacrel = $4; n->va_spec = $5; if ( $5 != NIL && !$4 ) elog(ERROR,"parser: syntax error at or near \"(\""); $$ = (Node *)n; } ;opt_verbose: VERBOSE { $$ = TRUE; } | /*EMPTY*/ { $$ = FALSE; } ;opt_analyze: ANALYZE { $$ = TRUE; } | /*EMPTY*/ { $$ = FALSE; } ;opt_va_list: '(' va_list ')' { $$ = $2; } | /*EMPTY*/ { $$ = NIL; } ;va_list: name { $$=lcons($1,NIL); } | va_list ',' name { $$=lappend($1,$3); } ;/***************************************************************************** * * QUERY: * EXPLAIN query * *****************************************************************************/ExplainStmt: EXPLAIN opt_verbose OptimizableStmt { ExplainStmt *n = makeNode(ExplainStmt); n->verbose = $2; n->query = (Query*)$3; $$ = (Node *)n; } ;/***************************************************************************** * * * Optimizable Stmts: * * * * one of the five queries processed by the planner * * * * [ultimately] produces query-trees as specified * * in the query-spec document in ~postgres/ref * * * *****************************************************************************/OptimizableStmt: SelectStmt | CursorStmt | UpdateStmt | InsertStmt | NotifyStmt | DeleteStmt /* by default all are $$=$1 */ ;/***************************************************************************** * * QUERY: * INSERT STATEMENTS * *****************************************************************************//***S*I***//* This rule used 'opt_column_list' between 'relation_name' and 'insert_rest' * originally. When the second rule of 'insert_rest' was changed to use * the new 'SelectStmt' rule (for INTERSECT and EXCEPT) it produced a shift/reduce * conflict. So I just changed the rules 'InsertStmt' and 'insert_rest' to accept * the same statements without any shift/reduce conflicts */InsertStmt: INSERT INTO relation_name insert_rest { $4->relname = $3; $$ = (Node *)$4; } ;insert_rest: VALUES '(' res_target_list2 ')' { $$ = makeNode(InsertStmt); $$->cols = NULL; $$->unique = NULL; $$->targetList = $3; $$->fromClause = NIL; $$->whereClause = NULL; $$->groupClause = NIL; $$->havingClause = NULL; $$->unionClause = NIL; } | DEFAULT VALUES { $$ = makeNode(InsertStmt); $$->unique = NULL; $$->targetList = NIL; $$->fromClause = NIL; $$->whereClause = NULL; $$->groupClause = NIL; $$->havingClause = NULL; $$->unionClause = NIL; /***S*I***/ $$->intersectClause = NIL; } /***S*I***/ /* We want the full power of SelectStatements including INTERSECT and EXCEPT * for insertion */ | SelectStmt { SelectStmt *n; n = (SelectStmt *)$1; $$ = makeNode(InsertStmt); $$->cols = NULL; $$->unique = n->unique; $$->targetList = n->targetList; $$->fromClause = n->fromClause; $$->whereClause = n->whereClause; $$->groupClause = n->groupClause; $$->havingClause = n->havingClause; $$->unionClause = n->unionClause; $$->intersectClause = n->intersectClause; $$->forUpdate = n->forUpdate; } | '(' columnList ')' VALUES '(' res_target_list2 ')' { $$ = makeNode(InsertStmt); $$->cols = $2; $$->unique = NULL; $$->targetList = $6; $$->fromClause = NIL; $$->whereClause = NULL; $$->groupClause = NIL; $$->havingClause = NULL; $$->unionClause = NIL; /***S*I***/ $$->intersectClause = NIL; } | '(' columnList ')' SelectStmt { SelectStmt *n; n = (SelectStmt *)$4; $$ = makeNode(InsertStmt); $$->cols = $2; $$->unique = n->unique; $$->targetList = n->targetList; $$->fromClause = n->fromClause; $$->whereClause = n->whereClause; $$->groupClause = n->groupClause; $$->havingClause = n->havingClause; $$->unionClause = n->unionClause; $$->intersectClause = n->intersectClause; } ;opt_column_list: '(' columnList ')' { $$ = $2; } | /*EMPTY*/ { $$ = NIL; } ;columnList: columnList ',' columnElem { $$ = lappend($1, $3); } | columnElem { $$ = lcons($1, NIL); } ;columnElem: ColId opt_indirection { Ident *id = makeNode(Ident); id->name = $1; id->indirection = $2; $$ = (Node *)id; } ;/***************************************************************************** * * QUERY: * DELETE STATEMENTS * *****************************************************************************/DeleteStmt: DELETE FROM relation_name where_clause { DeleteStmt *n = makeNode(DeleteStmt); n->relname = $3; n->whereClause = $4; $$ = (Node *)n; } ;LockStmt: LOCK_P opt_table relation_name opt_lock { LockStmt *n = makeNode(LockStmt); n->relname = $3; n->mode = $4; $$ = (Node *)n; } ;opt_lock: IN lock_type MODE { $$ = $2; } | /*EMPTY*/ { $$ = AccessEx
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -