PostgreSQL 的 语法分析的理解(五)
接上文,从 simple_select 中的 target_list ,再看target_list部分的内容:
/***************************************************************************** * * target list for SELECT * *****************************************************************************/ target_list: target_el { $$ = list_make1($1); } | target_list ',' target_el { $$ = lappend($1, $3); } ; target_el: a_expr AS ColLabel { $$ = makeNode(ResTarget); $$->name = $3; $$->indirection = NIL; $$->val = (Node *)$1; $$->location = @1; } /* * We support omitting AS only for column labels that aren't * any known keyword. There is an ambiguity against postfix * operators: is "a ! b" an infix expression, or a postfix * expression and a column label? We prefer to resolve this * as an infix expression, which we accomplish by assigning * IDENT a precedence higher than POSTFIXOP. */ | a_expr IDENT { $$ = makeNode(ResTarget); $$->name = $2; $$->indirection = NIL; $$->val = (Node *)$1; $$->location = @1; } | a_expr { $$ = makeNode(ResTarget); $$->name = NULL; $$->indirection = NIL; $$->val = (Node *)$1; $$->location = @1; } | '*' { ColumnRef *n = makeNode(ColumnRef); n->fields = list_make1(makeNode(A_Star)); n->location = @1; $$ = makeNode(ResTarget); $$->name = NULL; $$->indirection = NIL; $$->val = (Node *)n; $$->location = @1; } ;
从上面可以看出:
target_list 是一个递归表达式:
target_list: target_el
| target_list ',' target_el
而具体 target_el又分为以下几种:
a_expr AS ColLabel
a_expr INDENT
a_expr
'*'
这个 target_list 就是指我们平时 select col1,col2,col3 ... from table 中的各个列的组合。