1111 *
1212 *
1313 * IDENTIFICATION
14- * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.564 2006/09/0303:19:44 momjian Exp $
14+ * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.565 2006/09/0322:37:05 tgl Exp $
1515 *
1616 * HISTORY
1717 * AUTHORDATEMAJOR EVENT
@@ -236,9 +236,9 @@ static void doNegateFloat(Value *v);
236236name_list from_clause from_list opt_array_bounds
237237qualified_name_list any_name any_name_list
238238any_operator expr_list attrs
239- target_list update_col_list update_target_list
240- update_value_list set_opt insert_column_list
241- values_list def_list indirection opt_indirection
239+ target_list insert_column_list set_target_list
240+ set_clause_list set_clause multiple_set_clause
241+ ctext_expr_list ctext_row def_list indirection opt_indirection
242242group_clause TriggerFuncArgs select_limit
243243opt_select_limit opclass_item_list
244244transaction_mode_list_or_empty
@@ -299,7 +299,7 @@ static void doNegateFloat(Value *v);
299299%type <list> when_clause_list
300300%type <ival> sub_type
301301%type <list> OptCreateAs CreateAsList
302- %type <node> CreateAsElement values_item
302+ %type <node> CreateAsElement ctext_expr
303303%type <value> NumericOnly FloatOnly IntegerOnly
304304%type <alias> alias_clause
305305%type <sortby> sortby
@@ -308,8 +308,7 @@ static void doNegateFloat(Value *v);
308308%type <jexpr> joined_table
309309%type <range> relation_expr
310310%type <range> relation_expr_opt_alias
311- %type <target> target_el update_target_el update_col_list_el insert_column_item
312- %type <list> update_target_lists_list update_target_lists_el
311+ %type <target> target_el single_set_clause set_target insert_column_item
313312
314313%type <typnam> Typename SimpleTypename ConstTypename
315314GenericType Numeric opt_float
@@ -5488,7 +5487,7 @@ opt_nowait:NOWAIT{ $$ = TRUE; }
54885487 *****************************************************************************/
54895488
54905489UpdateStmt: UPDATE relation_expr_opt_alias
5491- SETset_opt
5490+ SETset_clause_list
54925491from_clause
54935492where_clause
54945493returning_clause
@@ -5503,9 +5502,65 @@ UpdateStmt: UPDATE relation_expr_opt_alias
55035502}
55045503;
55055504
5506- set_opt:
5507- update_target_list{$$ =$1 ; }
5508- | update_target_lists_list{$$ =$1 ; }
5505+ set_clause_list:
5506+ set_clause{$$ =$1 ; }
5507+ | set_clause_list' ,' set_clause{$$ = list_concat($1 ,$3 ); }
5508+ ;
5509+
5510+ set_clause:
5511+ single_set_clause{$$ = list_make1($1 ); }
5512+ | multiple_set_clause{$$ =$1 ; }
5513+ ;
5514+
5515+ single_set_clause:
5516+ set_target' =' ctext_expr
5517+ {
5518+ $$ =$1 ;
5519+ $$ ->val = (Node *)$3 ;
5520+ }
5521+ ;
5522+
5523+ multiple_set_clause:
5524+ ' (' set_target_list' )' ' =' ctext_row
5525+ {
5526+ ListCell *col_cell;
5527+ ListCell *val_cell;
5528+
5529+ /*
5530+ * Break the ctext_row apart, merge individual expressions
5531+ * into the destination ResTargets. XXX this approach
5532+ * cannot work for general row expressions as sources.
5533+ */
5534+ if (list_length($2 ) != list_length($5 ))
5535+ ereport (ERROR,
5536+ (errcode(ERRCODE_SYNTAX_ERROR),
5537+ errmsg(" number of columns does not match number of values" )));
5538+ forboth (col_cell, $2 , val_cell, $5 )
5539+ {
5540+ ResTarget *res_col = (ResTarget *)lfirst (col_cell);
5541+ Node *res_val = (Node *)lfirst (val_cell);
5542+
5543+ res_col->val = res_val;
5544+ }
5545+
5546+ $$ =$2 ;
5547+ }
5548+ ;
5549+
5550+ set_target:
5551+ ColId opt_indirection
5552+ {
5553+ $$ = makeNode(ResTarget);
5554+ $$ ->name =$1 ;
5555+ $$ ->indirection =$2 ;
5556+ $$ ->val =NULL ;/* upper production sets this*/
5557+ $$ ->location =@1 ;
5558+ }
5559+ ;
5560+
5561+ set_target_list:
5562+ set_target{$$ = list_make1($1 ); }
5563+ | set_target_list' ,' set_target{$$ = lappend($1 ,$3 ); }
55095564;
55105565
55115566
@@ -5887,83 +5942,20 @@ locked_rels_list:
58875942
58885943
58895944values_clause:
5890- VALUES' ( ' values_list ' ) '
5945+ VALUESctext_row
58915946{
58925947SelectStmt *n = makeNode(SelectStmt);
5893- n->valuesLists = list_make1($3 );
5948+ n->valuesLists = list_make1($2 );
58945949$$ = (Node *) n;
58955950}
5896- | values_clause' ,' ' ( ' values_list ' ) '
5951+ | values_clause' ,' ctext_row
58975952{
58985953SelectStmt *n = (SelectStmt *)$1 ;
5899- n->valuesLists = lappend(n->valuesLists,$4 );
5954+ n->valuesLists = lappend(n->valuesLists,$3 );
59005955$$ = (Node *) n;
59015956}
59025957;
59035958
5904- values_list: values_item{$$ = list_make1($1 ); }
5905- | values_list' ,' values_item{$$ = lappend($1 ,$3 ); }
5906- ;
5907-
5908- values_item:
5909- a_expr{$$ = (Node *)$1 ; }
5910- | DEFAULT{$$ = (Node *) makeNode(SetToDefault); }
5911- ;
5912-
5913- update_target_lists_list:
5914- update_target_lists_el {$$ =$1 ; }
5915- | update_target_lists_list' ,' update_target_lists_el {$$ = list_concat($1 ,$3 ); }
5916- ;
5917-
5918- update_target_lists_el:
5919- ' (' update_col_list' )' ' =' ' (' update_value_list' )'
5920- {
5921- ListCell *col_cell;
5922- ListCell *val_cell;
5923-
5924- if (list_length($2 ) != list_length($6 ))
5925- {
5926- ereport (ERROR,
5927- (errcode(ERRCODE_SYNTAX_ERROR),
5928- errmsg(" number of columns does not match to number of values" )));
5929- }
5930-
5931- for (col_cell = list_head($2 ), val_cell = list_head($6 );
5932- col_cell !=NULL && val_cell !=NULL ;
5933- col_cell = lnext(col_cell), val_cell = lnext(val_cell))
5934- {
5935- /* merge update_value_list with update_col_list*/
5936- ResTarget *res_col = (ResTarget *) lfirst(col_cell);
5937- Node *res_val = (Node *) lfirst(val_cell);
5938-
5939- res_col->val = res_val;
5940- }
5941-
5942- $$ =$2 ;
5943- }
5944- ;
5945-
5946- update_col_list:
5947- update_col_list_el {$$ = list_make1($1 ); }
5948- | update_col_list' ,' update_col_list_el {$$ = lappend($1 ,$3 ); }
5949- ;
5950-
5951- update_col_list_el:
5952- ColId opt_indirection
5953- {
5954- $$ = makeNode(ResTarget);
5955- $$ ->name =$1 ;
5956- $$ ->indirection =$2 ;
5957- $$ ->val =NULL ;
5958- $$ ->location =@1 ;
5959- }
5960- ;
5961-
5962- update_value_list:
5963- values_item {$$ = list_make1($1 ); }
5964- | update_value_list' ,' values_item {$$ = lappend($1 ,$3 ); }
5965- ;
5966-
59675959
59685960/* ****************************************************************************
59695961 *
@@ -8232,10 +8224,35 @@ opt_asymmetric: ASYMMETRIC
82328224|/* EMPTY*/
82338225;
82348226
8227+ /*
8228+ * The SQL spec defines "contextually typed value expressions" and
8229+ * "contextually typed row value constructors", which for our purposes
8230+ * are the same as "a_expr" and "row" except that DEFAULT can appear at
8231+ * the top level.
8232+ */
8233+
8234+ ctext_expr:
8235+ a_expr{$$ = (Node *)$1 ; }
8236+ | DEFAULT{$$ = (Node *) makeNode(SetToDefault); }
8237+ ;
8238+
8239+ ctext_expr_list:
8240+ ctext_expr{$$ = list_make1($1 ); }
8241+ | ctext_expr_list' ,' ctext_expr{$$ = lappend($1 ,$3 ); }
8242+ ;
8243+
8244+ /*
8245+ * We should allow ROW '(' ctext_expr_list ')' too, but that seems to require
8246+ * making VALUES a fully reserved word, which will probably break more apps
8247+ * than allowing the noise-word is worth.
8248+ */
8249+ ctext_row:' (' ctext_expr_list' )' {$$ =$2 ; }
8250+ ;
8251+
82358252
82368253/* ****************************************************************************
82378254 *
8238- *targetlists for SELECT, UPDATE, INSERT
8255+ *targetlist for SELECT
82398256 *
82408257 *****************************************************************************/
82418258
@@ -8275,31 +8292,6 @@ target_el:a_expr AS ColLabel
82758292}
82768293;
82778294
8278- update_target_list:
8279- update_target_el {$$ = list_make1($1 ); }
8280- | update_target_list' ,' update_target_el {$$ = lappend($1 ,$3 ); }
8281- ;
8282-
8283- update_target_el:
8284- ColId opt_indirection' =' a_expr
8285- {
8286- $$ = makeNode(ResTarget);
8287- $$ ->name =$1 ;
8288- $$ ->indirection =$2 ;
8289- $$ ->val = (Node *)$4 ;
8290- $$ ->location =@1 ;
8291- }
8292- | ColId opt_indirection' =' DEFAULT
8293- {
8294- $$ = makeNode(ResTarget);
8295- $$ ->name =$1 ;
8296- $$ ->indirection =$2 ;
8297- $$ ->val = (Node *) makeNode(SetToDefault);
8298- $$ ->location =@1 ;
8299- }
8300-
8301- ;
8302-
83038295
83048296/* ****************************************************************************
83058297 *