mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	Add UPDATE tab SET ROW (col, ...) = (val, ...) for updating
multiple columns Susanne Ebrecht
This commit is contained in:
		@@ -1,5 +1,5 @@
 | 
				
			|||||||
<!--
 | 
					<!--
 | 
				
			||||||
$PostgreSQL: pgsql/doc/src/sgml/ref/update.sgml,v 1.38 2006/08/12 02:52:03 tgl Exp $
 | 
					$PostgreSQL: pgsql/doc/src/sgml/ref/update.sgml,v 1.39 2006/09/02 20:34:47 momjian Exp $
 | 
				
			||||||
PostgreSQL documentation
 | 
					PostgreSQL documentation
 | 
				
			||||||
-->
 | 
					-->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -21,7 +21,8 @@ PostgreSQL documentation
 | 
				
			|||||||
 <refsynopsisdiv>
 | 
					 <refsynopsisdiv>
 | 
				
			||||||
<synopsis>
 | 
					<synopsis>
 | 
				
			||||||
UPDATE [ ONLY ] <replaceable class="PARAMETER">table</replaceable> [ [ AS ] <replaceable class="parameter">alias</replaceable> ]
 | 
					UPDATE [ ONLY ] <replaceable class="PARAMETER">table</replaceable> [ [ AS ] <replaceable class="parameter">alias</replaceable> ]
 | 
				
			||||||
    SET <replaceable class="PARAMETER">column</replaceable> = { <replaceable class="PARAMETER">expression</replaceable> | DEFAULT } [, ...]
 | 
					    [ SET <replaceable class="PARAMETER">column</replaceable> = { <replaceable class="PARAMETER">expression</replaceable> | DEFAULT } [, ...] |
 | 
				
			||||||
 | 
					      SET ( <replaceable class="PARAMETER">column</replaceable> [, ...] ) = ( { <replaceable class="PARAMETER">expression</replaceable> | DEFAULT } [, ...] ) [, ...] ]
 | 
				
			||||||
    [ FROM <replaceable class="PARAMETER">fromlist</replaceable> ]
 | 
					    [ FROM <replaceable class="PARAMETER">fromlist</replaceable> ]
 | 
				
			||||||
    [ WHERE <replaceable class="PARAMETER">condition</replaceable> ]
 | 
					    [ WHERE <replaceable class="PARAMETER">condition</replaceable> ]
 | 
				
			||||||
    [ RETURNING * | <replaceable class="parameter">output_expression</replaceable> [ AS <replaceable class="parameter">output_name</replaceable> ] [, ...] ]
 | 
					    [ RETURNING * | <replaceable class="parameter">output_expression</replaceable> [ AS <replaceable class="parameter">output_name</replaceable> ] [, ...] ]
 | 
				
			||||||
@@ -250,6 +251,10 @@ UPDATE films SET kind = 'Dramatic' WHERE kind = 'Drama';
 | 
				
			|||||||
<programlisting>
 | 
					<programlisting>
 | 
				
			||||||
UPDATE weather SET temp_lo = temp_lo+1, temp_hi = temp_lo+15, prcp = DEFAULT
 | 
					UPDATE weather SET temp_lo = temp_lo+1, temp_hi = temp_lo+15, prcp = DEFAULT
 | 
				
			||||||
  WHERE city = 'San Francisco' AND date = '2003-07-03';
 | 
					  WHERE city = 'San Francisco' AND date = '2003-07-03';
 | 
				
			||||||
 | 
					</programlisting>
 | 
				
			||||||
 | 
					<programlisting>
 | 
				
			||||||
 | 
					UPDATE weather SET (temp_lo, temp_hi, prcp) = (temp_lo+1, temp_lo+15, DEFAULT)
 | 
				
			||||||
 | 
					  WHERE city = 'San Francisco' AND date = '2003-07-03';
 | 
				
			||||||
</programlisting>
 | 
					</programlisting>
 | 
				
			||||||
  </para>
 | 
					  </para>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,7 +11,7 @@
 | 
				
			|||||||
 *
 | 
					 *
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * IDENTIFICATION
 | 
					 * IDENTIFICATION
 | 
				
			||||||
 *	  $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.560 2006/09/02 18:17:17 momjian Exp $
 | 
					 *	  $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.561 2006/09/02 20:34:47 momjian Exp $
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * HISTORY
 | 
					 * HISTORY
 | 
				
			||||||
 *	  AUTHOR			DATE			MAJOR EVENT
 | 
					 *	  AUTHOR			DATE			MAJOR EVENT
 | 
				
			||||||
@@ -237,7 +237,8 @@ static void doNegateFloat(Value *v);
 | 
				
			|||||||
				name_list from_clause from_list opt_array_bounds
 | 
									name_list from_clause from_list opt_array_bounds
 | 
				
			||||||
				qualified_name_list any_name any_name_list
 | 
									qualified_name_list any_name any_name_list
 | 
				
			||||||
				any_operator expr_list attrs
 | 
									any_operator expr_list attrs
 | 
				
			||||||
				target_list update_target_list insert_column_list
 | 
									target_list update_col_list update_target_list
 | 
				
			||||||
 | 
									update_value_list insert_column_list
 | 
				
			||||||
				values_list def_list indirection opt_indirection
 | 
									values_list def_list indirection opt_indirection
 | 
				
			||||||
				group_clause TriggerFuncArgs select_limit
 | 
									group_clause TriggerFuncArgs select_limit
 | 
				
			||||||
				opt_select_limit opclass_item_list
 | 
									opt_select_limit opclass_item_list
 | 
				
			||||||
@@ -308,7 +309,8 @@ static void doNegateFloat(Value *v);
 | 
				
			|||||||
%type <jexpr>	joined_table
 | 
					%type <jexpr>	joined_table
 | 
				
			||||||
%type <range>	relation_expr
 | 
					%type <range>	relation_expr
 | 
				
			||||||
%type <range>	relation_expr_opt_alias
 | 
					%type <range>	relation_expr_opt_alias
 | 
				
			||||||
%type <target>	target_el update_target_el insert_column_item
 | 
					%type <target>	target_el update_target_el update_col_list_el insert_column_item
 | 
				
			||||||
 | 
					%type <list>	update_target_lists_list update_target_lists_el
 | 
				
			||||||
 | 
					
 | 
				
			||||||
%type <typnam>	Typename SimpleTypename ConstTypename
 | 
					%type <typnam>	Typename SimpleTypename ConstTypename
 | 
				
			||||||
				GenericType Numeric opt_float
 | 
									GenericType Numeric opt_float
 | 
				
			||||||
@@ -5537,6 +5539,20 @@ UpdateStmt: UPDATE relation_expr_opt_alias
 | 
				
			|||||||
					n->returningList = $7;
 | 
										n->returningList = $7;
 | 
				
			||||||
					$$ = (Node *)n;
 | 
										$$ = (Node *)n;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					            | UPDATE relation_expr_opt_alias
 | 
				
			||||||
 | 
								SET update_target_lists_list
 | 
				
			||||||
 | 
								from_clause
 | 
				
			||||||
 | 
								where_clause
 | 
				
			||||||
 | 
								returning_clause
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										UpdateStmt *n = makeNode(UpdateStmt);
 | 
				
			||||||
 | 
										n->relation = $2;
 | 
				
			||||||
 | 
										n->targetList = $4;
 | 
				
			||||||
 | 
										n->fromClause = $5;
 | 
				
			||||||
 | 
										n->whereClause = $6;
 | 
				
			||||||
 | 
										n->returningList = $7;
 | 
				
			||||||
 | 
										$$ = (Node *)n;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
		;
 | 
							;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -5941,6 +5957,60 @@ values_item:
 | 
				
			|||||||
			| DEFAULT				{ $$ = (Node *) makeNode(SetToDefault); }
 | 
								| DEFAULT				{ $$ = (Node *) makeNode(SetToDefault); }
 | 
				
			||||||
		;
 | 
							;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					update_target_lists_list:
 | 
				
			||||||
 | 
								update_target_lists_el { $$ = $1; }
 | 
				
			||||||
 | 
								| update_target_lists_list ',' update_target_lists_el { $$ = list_concat($1, $3); }
 | 
				
			||||||
 | 
							;
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
					update_target_lists_el:
 | 
				
			||||||
 | 
								'(' update_col_list ')' '=' '(' update_value_list ')'
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										ListCell *col_cell;
 | 
				
			||||||
 | 
										ListCell *val_cell;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										if (list_length($2) != list_length($6))
 | 
				
			||||||
 | 
										{
 | 
				
			||||||
 | 
											ereport(ERROR, 
 | 
				
			||||||
 | 
												(errcode(ERRCODE_SYNTAX_ERROR),
 | 
				
			||||||
 | 
												 errmsg("number of columns does not match to number of values")));
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										for (col_cell = list_head($2), val_cell = list_head($6);
 | 
				
			||||||
 | 
											 col_cell != NULL && val_cell != NULL;
 | 
				
			||||||
 | 
											 col_cell = lnext(col_cell), val_cell = lnext(val_cell))
 | 
				
			||||||
 | 
										{
 | 
				
			||||||
 | 
											/* merge update_value_list with update_col_list */
 | 
				
			||||||
 | 
											ResTarget *res_col = (ResTarget *) lfirst(col_cell);
 | 
				
			||||||
 | 
											ResTarget *res_val = (ResTarget *) lfirst(val_cell);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											res_col->val = (Node *)copyObject(res_val);
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									    
 | 
				
			||||||
 | 
										$$ = $2;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
							;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					update_col_list:
 | 
				
			||||||
 | 
								update_col_list_el { $$ = list_make1($1); }
 | 
				
			||||||
 | 
								| update_col_list ',' update_col_list_el { $$ = lappend($1, $3); }
 | 
				
			||||||
 | 
							;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					update_col_list_el:
 | 
				
			||||||
 | 
								ColId opt_indirection
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										$$ = makeNode(ResTarget);
 | 
				
			||||||
 | 
										$$->name = $1;
 | 
				
			||||||
 | 
										$$->indirection = $2;
 | 
				
			||||||
 | 
										$$->val = NULL;
 | 
				
			||||||
 | 
										$$->location = @1;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
							;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					update_value_list:
 | 
				
			||||||
 | 
								values_item { $$ = list_make1($1); }
 | 
				
			||||||
 | 
								| update_value_list ',' values_item { $$ = lappend($1, $3); }
 | 
				
			||||||
 | 
							;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*****************************************************************************
 | 
					/*****************************************************************************
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
@@ -8253,7 +8323,7 @@ target_el:	a_expr AS ColLabel
 | 
				
			|||||||
		;
 | 
							;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
update_target_list:
 | 
					update_target_list:
 | 
				
			||||||
			update_target_el						{ $$ = list_make1($1); }
 | 
								update_target_el			  { $$ = list_make1($1); }
 | 
				
			||||||
			| update_target_list ',' update_target_el { $$ = lappend($1,$3); }
 | 
								| update_target_list ',' update_target_el { $$ = lappend($1,$3); }
 | 
				
			||||||
		;
 | 
							;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user