*** ./doc/src/sgml/keywords.sgml.orig	2005-10-12 18:45:29.000000000 +0900
--- ./doc/src/sgml/keywords.sgml	2005-12-01 21:55:52.000000000 +0900
***************
*** 3581,3587 ****
     </row>
     <row>
      <entry><token>SET</token></entry>
!     <entry>non-reserved</entry>
      <entry>reserved</entry>
      <entry>reserved</entry>
      <entry>reserved</entry>
--- 3581,3587 ----
     </row>
     <row>
      <entry><token>SET</token></entry>
!     <entry>reserved</entry>
      <entry>reserved</entry>
      <entry>reserved</entry>
      <entry>reserved</entry>
*** ./doc/src/sgml/ref/delete.sgml.orig	2005-11-02 06:09:50.000000000 +0900
--- ./doc/src/sgml/ref/delete.sgml	2005-12-01 21:55:52.000000000 +0900
***************
*** 20,26 ****
  
   <refsynopsisdiv>
  <synopsis>
! DELETE FROM [ ONLY ] <replaceable class="PARAMETER">table</replaceable>
      [ USING <replaceable class="PARAMETER">usinglist</replaceable> ]
      [ WHERE <replaceable class="PARAMETER">condition</replaceable> ]
  </synopsis>
--- 20,26 ----
  
   <refsynopsisdiv>
  <synopsis>
! DELETE FROM [ ONLY ] <replaceable class="PARAMETER">table</replaceable> [ [ AS ] <replaceable class="parameter">alias</replaceable> ]
      [ USING <replaceable class="PARAMETER">usinglist</replaceable> ]
      [ WHERE <replaceable class="PARAMETER">condition</replaceable> ]
  </synopsis>
***************
*** 92,97 ****
--- 92,110 ----
     </varlistentry>
  
     <varlistentry>
+     <term><replaceable class="parameter">alias</replaceable></term>
+     <listitem>
+      <para>
+       A substitute name for the target table. When an alias is
+       provided, it completely hides the actual name of the table.
+       for example given <literal>DELETE foo AS f</>, the remainder
+       of the SQL must refer to this table as <literal>f</> not
+       <literal>foo</>.
+      </para>
+     </listitem>
+    </varlistentry>
+ 
+    <varlistentry>
      <term><replaceable class="PARAMETER">usinglist</replaceable></term>
      <listitem>
       <para>
*** ./doc/src/sgml/ref/update.sgml.orig	2005-10-13 08:19:22.000000000 +0900
--- ./doc/src/sgml/ref/update.sgml	2005-12-01 21:55:52.000000000 +0900
***************
*** 20,26 ****
  
   <refsynopsisdiv>
  <synopsis>
! UPDATE [ ONLY ] <replaceable class="PARAMETER">table</replaceable> SET <replaceable class="PARAMETER">column</replaceable> = { <replaceable class="PARAMETER">expression</replaceable> | DEFAULT } [, ...]
      [ FROM <replaceable class="PARAMETER">fromlist</replaceable> ]
      [ WHERE <replaceable class="PARAMETER">condition</replaceable> ]
  </synopsis>
--- 20,27 ----
  
   <refsynopsisdiv>
  <synopsis>
! 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 } [, ...]
      [ FROM <replaceable class="PARAMETER">fromlist</replaceable> ]
      [ WHERE <replaceable class="PARAMETER">condition</replaceable> ]
  </synopsis>
***************
*** 74,79 ****
--- 75,93 ----
     </varlistentry>
  
     <varlistentry>
+     <term><replaceable class="parameter">alias</replaceable></term>
+     <listitem>
+      <para>
+       A substitute name for the target table. When an alias is
+       provided, it completely hides the actual name of the table.
+       for example given <literal>UPDATE foo AS f</>, the remainder
+       of the SQL must refer to this table as <literal>f</> not
+       <literal>foo</>.
+      </para>
+     </listitem>
+    </varlistentry>
+ 
+    <varlistentry>
      <term><replaceable class="PARAMETER">column</replaceable></term>
      <listitem>
       <para>
*** ./src/backend/parser/analyze.c.orig	2005-11-23 03:17:15.000000000 +0900
--- ./src/backend/parser/analyze.c	2005-12-01 21:55:52.000000000 +0900
***************
*** 2325,2330 ****
--- 2325,2363 ----
  	 */
  	transformFromClause(pstate, stmt->fromClause);
  
+ 	/*
+ 	 * Processing when column identifier in SET clause is specified like
+ 	 * 'AAA.BBB': 'AAA' is table or composite column.
+ 	 *
+ 	 * Eat up a first element of column identifier when the first element
+ 	 * is a name or an alias for target table. And, make the second element
+ 	 * a column name.
+ 	 *
+ 	 * Example:
+ 	 *  update tbl as t set t.col = 1;
+ 	 *   => 't' is eaten up, and 'col' becomes a column name.
+ 	 */
+ 	foreach(tl, stmt->targetList)
+ 	{
+ 		ResTarget  *res = (ResTarget *)lfirst(tl);
+ 		char	   *relname = stmt->relation->relname;
+ 
+ 		if(stmt->relation->alias != NULL)
+ 			relname = stmt->relation->alias->aliasname;
+ 
+ 		if (res->indirection != NULL && strcmp(relname, res->name) == 0)
+ 		{
+ 			ListCell   *ind_cell = list_head(res->indirection);
+ 			Node	   *n = lfirst(ind_cell);
+ 
+ 			if (IsA(n, String))
+ 			{
+ 				res->name = pstrdup(strVal(n));
+ 				res->indirection = list_delete_first(res->indirection);
+ 			}
+ 		}
+ 	}
+ 
  	qry->targetList = transformTargetList(pstate, stmt->targetList);
  
  	qual = transformWhereClause(pstate, stmt->whereClause, "WHERE");
*** ./src/backend/parser/gram.y.orig	2005-11-23 00:24:17.000000000 +0900
--- ./src/backend/parser/gram.y	2005-12-01 21:55:52.000000000 +0900
***************
*** 291,296 ****
--- 291,297 ----
  %type <node>	table_ref
  %type <jexpr>	joined_table
  %type <range>	relation_expr
+ %type <range>	update_or_delete_relation_expr
  %type <target>	target_el insert_target_el update_target_el insert_column_item
  
  %type <typnam>	Typename SimpleTypename ConstTypename
***************
*** 5137,5143 ****
   *
   *****************************************************************************/
  
! DeleteStmt: DELETE_P FROM relation_expr using_clause where_clause
  				{
  					DeleteStmt *n = makeNode(DeleteStmt);
  					n->relation = $3;
--- 5138,5145 ----
   *
   *****************************************************************************/
  
! DeleteStmt: DELETE_P FROM update_or_delete_relation_expr
! 			using_clause where_clause
  				{
  					DeleteStmt *n = makeNode(DeleteStmt);
  					n->relation = $3;
***************
*** 5189,5195 ****
   *
   *****************************************************************************/
  
! UpdateStmt: UPDATE relation_expr
  			SET update_target_list
  			from_clause
  			where_clause
--- 5191,5197 ----
   *
   *****************************************************************************/
  
! UpdateStmt: UPDATE update_or_delete_relation_expr
  			SET update_target_list
  			from_clause
  			where_clause
***************
*** 5867,5872 ****
--- 5869,5895 ----
  		;
  
  
+ update_or_delete_relation_expr:		relation_expr
+ 				{
+ 					$$ = $1;
+ 				}
+ 			| relation_expr AS ColId
+ 				{
+ 					Alias *alias = makeNode(Alias);
+ 					alias->aliasname = $3;
+ 					$1->alias = alias;
+ 					$$ = $1;
+ 				}
+ 			| relation_expr ColId
+ 				{
+ 					Alias *alias = makeNode(Alias);
+ 					alias->aliasname = $2;
+ 					$1->alias = alias;
+ 					$$ = $1;
+ 				}
+ 		;
+ 
+ 
  func_table: func_expr								{ $$ = $1; }
  		;
  
***************
*** 8298,8304 ****
  			| SEQUENCE
  			| SERIALIZABLE
  			| SESSION
- 			| SET
  			| SHARE
  			| SHOW
  			| SIMPLE
--- 8321,8326 ----
***************
*** 8494,8499 ****
--- 8516,8522 ----
  			| REFERENCES
  			| SELECT
  			| SESSION_USER
+ 			| SET
  			| SOME
  			| SYMMETRIC
  			| TABLE
*** ./src/backend/parser/parse_clause.c.orig	2005-11-23 03:17:16.000000000 +0900
--- ./src/backend/parser/parse_clause.c	2005-12-01 21:55:52.000000000 +0900
***************
*** 160,166 ****
  	 * Now build an RTE.
  	 */
  	rte = addRangeTableEntryForRelation(pstate, pstate->p_target_relation,
! 										NULL, inh, false);
  	pstate->p_target_rangetblentry = rte;
  
  	/* assume new rte is at end */
--- 160,166 ----
  	 * Now build an RTE.
  	 */
  	rte = addRangeTableEntryForRelation(pstate, pstate->p_target_relation,
! 										relation->alias, inh, false);
  	pstate->p_target_rangetblentry = rte;
  
  	/* assume new rte is at end */
*** ./src/test/regress/expected/update.out.orig	2005-12-01 22:27:46.000000000 +0900
--- ./src/test/regress/expected/update.out	2005-12-01 22:31:13.000000000 +0900
***************
*** 22,25 ****
--- 22,41 ----
   10 |  
  (2 rows)
  
+ UPDATE update_test as a SET a.b = 20 where a.a = 10;
+ SELECT * FROM update_test;
+  a  | b  
+ ----+----
+  10 | 20
+  10 | 20
+ (2 rows)
+ 
+ UPDATE update_test a SET a.b = 30 where a.a = 10;
+ SELECT * FROM update_test;
+  a  | b  
+ ----+----
+  10 | 30
+  10 | 30
+ (2 rows)
+ 
  DROP TABLE update_test;
*** ./src/test/regress/sql/update.sql.orig	2005-12-01 22:26:01.000000000 +0900
--- ./src/test/regress/sql/update.sql	2005-12-01 22:29:33.000000000 +0900
***************
*** 16,19 ****
--- 16,27 ----
  
  SELECT * FROM update_test;
  
+ UPDATE update_test as a SET a.b = 20 where a.a = 10;
+ 
+ SELECT * FROM update_test;
+ 
+ UPDATE update_test a SET a.b = 30 where a.a = 10;
+ 
+ SELECT * FROM update_test;
+ 
  DROP TABLE update_test;
