Index: doc/src/sgml/ref/update.sgml
===================================================================
RCS file: /home/rbt/work/postgresql/cvs/pgsql-server/doc/src/sgml/ref/update.sgml,v
retrieving revision 1.21
diff -c -r1.21 update.sgml
*** doc/src/sgml/ref/update.sgml	26 Apr 2003 23:56:51 -0000	1.21
--- doc/src/sgml/ref/update.sgml	10 Jun 2003 01:59:00 -0000
***************
*** 16,22 ****
  
   <refsynopsisdiv>
  <synopsis>
! UPDATE [ ONLY ] <replaceable class="PARAMETER">table</replaceable> SET <replaceable class="PARAMETER">column</replaceable> = <replaceable class="PARAMETER">expression</replaceable> [, ...]
      [ FROM <replaceable class="PARAMETER">fromlist</replaceable> ]
      [ WHERE <replaceable class="PARAMETER">condition</replaceable> ]
  </synopsis>
--- 16,22 ----
  
   <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>
***************
*** 73,78 ****
--- 73,87 ----
      <listitem>
       <para>
        An expression or value to assign to the column.
+      </para>
+     </listitem>
+    </varlistentry>
+ 
+    <varlistentry>
+     <term><literal>DEFAULT</literal></term>
+     <listitem>
+      <para>
+       This column will be filled with its default value.
       </para>
      </listitem>
     </varlistentry>
Index: src/backend/nodes/copyfuncs.c
===================================================================
RCS file: /home/rbt/work/postgresql/cvs/pgsql-server/src/backend/nodes/copyfuncs.c,v
retrieving revision 1.252
diff -c -r1.252 copyfuncs.c
*** src/backend/nodes/copyfuncs.c	6 Jun 2003 15:04:02 -0000	1.252
--- src/backend/nodes/copyfuncs.c	9 Jun 2003 14:03:54 -0000
***************
*** 1653,1662 ****
  	return newnode;
  }
  
! static InsertDefault *
! _copyInsertDefault(InsertDefault *from)
  {
! 	InsertDefault *newnode = makeNode(InsertDefault);
  
  	return newnode;
  }
--- 1653,1662 ----
  	return newnode;
  }
  
! static SetToDefault *
! _copySetToDefault(SetToDefault *from)
  {
! 	SetToDefault *newnode = makeNode(SetToDefault);
  
  	return newnode;
  }
***************
*** 2920,2927 ****
  		case T_FuncWithArgs:
  			retval = _copyFuncWithArgs(from);
  			break;
! 		case T_InsertDefault:
! 			retval = _copyInsertDefault(from);
  			break;
  
  		default:
--- 2920,2927 ----
  		case T_FuncWithArgs:
  			retval = _copyFuncWithArgs(from);
  			break;
! 		case T_SetToDefault:
! 			retval = _copySetToDefault(from);
  			break;
  
  		default:
Index: src/backend/nodes/equalfuncs.c
===================================================================
RCS file: /home/rbt/work/postgresql/cvs/pgsql-server/src/backend/nodes/equalfuncs.c,v
retrieving revision 1.195
diff -c -r1.195 equalfuncs.c
*** src/backend/nodes/equalfuncs.c	6 Jun 2003 15:04:02 -0000	1.195
--- src/backend/nodes/equalfuncs.c	9 Jun 2003 14:04:00 -0000
***************
*** 720,726 ****
  }
  
  static bool
! _equalInsertDefault(InsertDefault *a, InsertDefault *b)
  {
  	return true;
  }
--- 720,726 ----
  }
  
  static bool
! _equalSetToDefault(SetToDefault *a, SetToDefault *b)
  {
  	return true;
  }
***************
*** 2035,2042 ****
  		case T_FuncWithArgs:
  			retval = _equalFuncWithArgs(a, b);
  			break;
! 		case T_InsertDefault:
! 			retval = _equalInsertDefault(a, b);
  			break;
  
  		default:
--- 2035,2042 ----
  		case T_FuncWithArgs:
  			retval = _equalFuncWithArgs(a, b);
  			break;
! 		case T_SetToDefault:
! 			retval = _equalSetToDefault(a, b);
  			break;
  
  		default:
Index: src/backend/parser/analyze.c
===================================================================
RCS file: /home/rbt/work/postgresql/cvs/pgsql-server/src/backend/parser/analyze.c,v
retrieving revision 1.273
diff -c -r1.273 analyze.c
*** src/backend/parser/analyze.c	6 Jun 2003 15:04:02 -0000	1.273
--- src/backend/parser/analyze.c	10 Jun 2003 01:38:53 -0000
***************
*** 656,678 ****
  		col = (ResTarget *) lfirst(icolumns);
  		Assert(IsA(col, ResTarget));
  
! 		/*
! 		 * When the value is to be set to the column default we can simply
! 		 * drop the TLE now and handle it later on using methods for missing
! 		 * columns.
! 		 */
! 		if (IsA(tle, InsertDefault))
! 		{
! 			qry->targetList = lremove(tle, qry->targetList);
! 			/* Note: the stmt->cols list is not adjusted to match */
! 		}
! 		else
! 		{
! 			/* Normal case */
! 			Assert(!tle->resdom->resjunk);
! 			updateTargetListEntry(pstate, tle, col->name, lfirsti(attnos),
! 								  col->indirection);
! 		}
  
  		icolumns = lnext(icolumns);
  		attnos = lnext(attnos);
--- 656,664 ----
  		col = (ResTarget *) lfirst(icolumns);
  		Assert(IsA(col, ResTarget));
  
! 		Assert(!tle->resdom->resjunk);
! 		updateTargetListEntry(pstate, tle, col->name, lfirsti(attnos),
! 							  col->indirection);
  
  		icolumns = lnext(icolumns);
  		attnos = lnext(attnos);
***************
*** 2298,2307 ****
--- 2284,2295 ----
  		if (origTargetList == NIL)
  			elog(ERROR, "UPDATE target count mismatch --- internal error");
  		origTarget = (ResTarget *) lfirst(origTargetList);
+ 
  		updateTargetListEntry(pstate, tle, origTarget->name,
  							  attnameAttNum(pstate->p_target_relation,
  											origTarget->name, true),
  							  origTarget->indirection);
+ 
  		origTargetList = lnext(origTargetList);
  	}
  	if (origTargetList != NIL)
Index: src/backend/parser/gram.y
===================================================================
RCS file: /home/rbt/work/postgresql/cvs/pgsql-server/src/backend/parser/gram.y,v
retrieving revision 2.416
diff -c -r2.416 gram.y
*** src/backend/parser/gram.y	29 May 2003 20:40:36 -0000	2.416
--- src/backend/parser/gram.y	9 Jun 2003 14:08:53 -0000
***************
*** 6893,6898 ****
--- 6893,6907 ----
  					$$->indirection = $2;
  					$$->val = (Node *)$4;
  				}
+ 			| ColId opt_indirection '=' DEFAULT
+ 				{
+ 					SetToDefault *def = makeNode(SetToDefault);
+ 					$$ = makeNode(ResTarget);
+ 					$$->name = $1;
+ 					$$->indirection = NULL;
+ 					$$->val = (Node *)def;
+ 				}
+ 
  		;
  
  insert_target_list:
***************
*** 6904,6910 ****
  			target_el								{ $$ = $1; }
  			| DEFAULT
  				{
! 					InsertDefault *def = makeNode(InsertDefault);
  					$$ = makeNode(ResTarget);
  					$$->name = NULL;
  					$$->indirection = NULL;
--- 6913,6919 ----
  			target_el								{ $$ = $1; }
  			| DEFAULT
  				{
! 					SetToDefault *def = makeNode(SetToDefault);
  					$$ = makeNode(ResTarget);
  					$$->name = NULL;
  					$$->indirection = NULL;
Index: src/backend/parser/parse_target.c
===================================================================
RCS file: /home/rbt/work/postgresql/cvs/pgsql-server/src/backend/parser/parse_target.c,v
retrieving revision 1.102
diff -c -r1.102 parse_target.c
*** src/backend/parser/parse_target.c	31 May 2003 19:03:34 -0000	1.102
--- src/backend/parser/parse_target.c	10 Jun 2003 02:15:43 -0000
***************
*** 177,195 ****
  														false));
  			}
  		}
! 		else if (IsA(res->val, InsertDefault))
  		{
- 			InsertDefault *newnode = makeNode(InsertDefault);
- 
  			/*
! 			 * If this is a DEFAULT element, we make a junk entry which
! 			 * will get dropped on return to transformInsertStmt().
  			 */
! 			p_target = lappend(p_target, newnode);
  		}
  		else
  		{
! 			/* Everything else but ColumnRef and InsertDefault */
  			p_target = lappend(p_target,
  							   transformTargetEntry(pstate,
  													res->val,
--- 177,200 ----
  														false));
  			}
  		}
! 		else if (IsA(res->val, SetToDefault))
  		{
  			/*
! 			 * If this is a DEFAULT element, we make a standard entry using
! 			 * the default for the target expression.  rewriteTargetList will
! 			 * substitute the columns default for this expression.
  			 */
! 			p_target = lappend(p_target,
! 							   makeTargetEntry(makeResdom((AttrNumber) pstate->p_next_resno++,
! 														  UNKNOWNOID,
! 														  -1,
! 														  res->name,
! 														  false),
! 											   (Expr *) res->val));
  		}
  		else
  		{
! 			/* Everything else but ColumnRef and SetToDefault */
  			p_target = lappend(p_target,
  							   transformTargetEntry(pstate,
  													res->val,
***************
*** 321,329 ****
  					  int attrno,
  					  List *indirection)
  {
! 	Oid			type_id = exprType((Node *) tle->expr);	/* type of value provided */
  	Oid			attrtype;		/* type of target column */
  	int32		attrtypmod;
  	Resdom	   *resnode = tle->resdom;
  	Relation	rd = pstate->p_target_relation;
  
--- 326,335 ----
  					  int attrno,
  					  List *indirection)
  {
! 	Oid			type_id; 		/* type of value provided */
  	Oid			attrtype;		/* type of target column */
  	int32		attrtypmod;
+ 	bool		isDefault = false;
  	Resdom	   *resnode = tle->resdom;
  	Relation	rd = pstate->p_target_relation;
  
***************
*** 333,338 ****
--- 339,355 ----
  	attrtype = attnumTypeId(rd, attrno);
  	attrtypmod = rd->rd_att->attrs[attrno - 1]->atttypmod;
  
+ 	/* The type of the default column is equivalent to that of the column */
+ 	if (tle->expr != NULL && IsA(tle->expr, SetToDefault))
+ 	{
+ 		type_id = attrtype;
+ 		isDefault = true;
+ 	}
+ 
+ 	/* Otherwise the expression holds the type */
+ 	else
+ 		type_id = exprType((Node *) tle->expr);
+ 
  	/*
  	 * If there are subscripts on the target column, prepare an array
  	 * assignment expression.  This will generate an array value that the
***************
*** 383,389 ****
  		 * coercion.  But accept InvalidOid, which indicates the source is
  		 * a NULL constant.  (XXX is that still true?)
  		 */
! 		if (type_id != InvalidOid)
  		{
  			tle->expr = (Expr *)
  				coerce_to_target_type(pstate,
--- 400,406 ----
  		 * coercion.  But accept InvalidOid, which indicates the source is
  		 * a NULL constant.  (XXX is that still true?)
  		 */
! 		if (!isDefault && type_id != InvalidOid)
  		{
  			tle->expr = (Expr *)
  				coerce_to_target_type(pstate,
Index: src/backend/rewrite/rewriteHandler.c
===================================================================
RCS file: /home/rbt/work/postgresql/cvs/pgsql-server/src/backend/rewrite/rewriteHandler.c,v
retrieving revision 1.120
diff -c -r1.120 rewriteHandler.c
*** src/backend/rewrite/rewriteHandler.c	2 May 2003 20:54:35 -0000	1.120
--- src/backend/rewrite/rewriteHandler.c	10 Jun 2003 02:19:15 -0000
***************
*** 307,313 ****
  			{
  				Assert(strcmp(resdom->resname,
  							  NameStr(att_tup->attname)) == 0);
! 				new_tle = process_matched_tle(old_tle, new_tle);
  				/* keep scanning to detect multiple assignments to attr */
  			}
  		}
--- 307,331 ----
  			{
  				Assert(strcmp(resdom->resname,
  							  NameStr(att_tup->attname)) == 0);
! 
! 				if (old_tle->expr != NULL && IsA(old_tle->expr, SetToDefault))
! 				{
! 					/* Set to the default value of the column, as requested */
! 					Node	   *new_expr;
! 
! 					new_expr = build_column_default(target_relation, attrno);
! 
! 					new_tle = makeTargetEntry(makeResdom(attrno,
! 														 att_tup->atttypid,
! 														 att_tup->atttypmod,
! 											  pstrdup(NameStr(att_tup->attname)),
! 														 false),
! 											  (Expr *) new_expr);
! 				}
! 				else
! 					/* Normal Case */
! 					new_tle = process_matched_tle(old_tle, new_tle);
! 
  				/* keep scanning to detect multiple assignments to attr */
  			}
  		}
Index: src/include/nodes/nodes.h
===================================================================
RCS file: /home/rbt/work/postgresql/cvs/pgsql-server/src/include/nodes/nodes.h,v
retrieving revision 1.140
diff -c -r1.140 nodes.h
*** src/include/nodes/nodes.h	8 Apr 2003 23:20:04 -0000	1.140
--- src/include/nodes/nodes.h	9 Jun 2003 03:01:10 -0000
***************
*** 277,283 ****
  	T_PrivGrantee,
  	T_FuncWithArgs,
  	T_PrivTarget,
! 	T_InsertDefault,
  	T_CreateOpClassItem,
  	T_CompositeTypeStmt,
  
--- 277,283 ----
  	T_PrivGrantee,
  	T_FuncWithArgs,
  	T_PrivTarget,
! 	T_SetToDefault,
  	T_CreateOpClassItem,
  	T_CompositeTypeStmt,
  
Index: src/include/nodes/parsenodes.h
===================================================================
RCS file: /home/rbt/work/postgresql/cvs/pgsql-server/src/include/nodes/parsenodes.h,v
retrieving revision 1.238
diff -c -r1.238 parsenodes.h
*** src/include/nodes/parsenodes.h	28 May 2003 16:04:02 -0000	1.238
--- src/include/nodes/parsenodes.h	9 Jun 2003 13:59:49 -0000
***************
*** 279,288 ****
  /*
   * Empty node used as a marker for Default Columns
   */
! typedef struct InsertDefault
  {
  	NodeTag		type;
! } InsertDefault;
  
  /*
   * SortGroupBy - for ORDER BY clause
--- 279,288 ----
  /*
   * Empty node used as a marker for Default Columns
   */
! typedef struct SetToDefault
  {
  	NodeTag		type;
! } SetToDefault;
  
  /*
   * SortGroupBy - for ORDER BY clause
