*** src/backend/parser/gram.y.orig	Sun Jul 30 21:16:37 2006
--- src/backend/parser/gram.y	Mon Jul 31 20:15:46 2006
***************
*** 173,179 ****
  		DropOwnedStmt ReassignOwnedStmt
  
  %type <node>	select_no_parens select_with_parens select_clause
! 				simple_select
  
  %type <node>	alter_column_default opclass_item alter_using
  %type <ival>	add_drop
--- 173,179 ----
  		DropOwnedStmt ReassignOwnedStmt
  
  %type <node>	select_no_parens select_with_parens select_clause
! 				simple_select values_clause
  
  %type <node>	alter_column_default opclass_item alter_using
  %type <ival>	add_drop
***************
*** 238,244 ****
  				qualified_name_list any_name any_name_list
  				any_operator expr_list attrs
  				target_list update_target_list insert_column_list
! 				insert_target_list def_list indirection opt_indirection
  				group_clause TriggerFuncArgs select_limit
  				opt_select_limit opclass_item_list
  				transaction_mode_list_or_empty
--- 238,244 ----
  				qualified_name_list any_name any_name_list
  				any_operator expr_list attrs
  				target_list update_target_list insert_column_list
! 				values_list def_list indirection opt_indirection
  				group_clause TriggerFuncArgs select_limit
  				opt_select_limit opclass_item_list
  				transaction_mode_list_or_empty
***************
*** 299,305 ****
  %type <list>	when_clause_list
  %type <ival>	sub_type
  %type <list>	OptCreateAs CreateAsList
! %type <node>	CreateAsElement
  %type <value>	NumericOnly FloatOnly IntegerOnly
  %type <alias>	alias_clause
  %type <sortby>	sortby
--- 299,305 ----
  %type <list>	when_clause_list
  %type <ival>	sub_type
  %type <list>	OptCreateAs CreateAsList
! %type <node>	CreateAsElement values_item
  %type <value>	NumericOnly FloatOnly IntegerOnly
  %type <alias>	alias_clause
  %type <sortby>	sortby
***************
*** 308,314 ****
  %type <jexpr>	joined_table
  %type <range>	relation_expr
  %type <range>	relation_expr_opt_alias
! %type <target>	target_el insert_target_el update_target_el insert_column_item
  
  %type <typnam>	Typename SimpleTypename ConstTypename
  				GenericType Numeric opt_float
--- 308,314 ----
  %type <jexpr>	joined_table
  %type <range>	relation_expr
  %type <range>	relation_expr_opt_alias
! %type <target>	target_el update_target_el insert_column_item
  
  %type <typnam>	Typename SimpleTypename ConstTypename
  				GenericType Numeric opt_float
***************
*** 5342,5381 ****
  		;
  
  insert_rest:
! 			VALUES '(' insert_target_list ')'
! 				{
! 					$$ = makeNode(InsertStmt);
! 					$$->cols = NIL;
! 					$$->targetList = $3;
! 					$$->selectStmt = NULL;
! 				}
! 			| DEFAULT VALUES
! 				{
! 					$$ = makeNode(InsertStmt);
! 					$$->cols = NIL;
! 					$$->targetList = NIL;
! 					$$->selectStmt = NULL;
! 				}
! 			| SelectStmt
  				{
  					$$ = makeNode(InsertStmt);
  					$$->cols = NIL;
- 					$$->targetList = NIL;
  					$$->selectStmt = $1;
  				}
! 			| '(' insert_column_list ')' VALUES '(' insert_target_list ')'
  				{
  					$$ = makeNode(InsertStmt);
  					$$->cols = $2;
! 					$$->targetList = $6;
! 					$$->selectStmt = NULL;
  				}
! 			| '(' insert_column_list ')' SelectStmt
  				{
  					$$ = makeNode(InsertStmt);
! 					$$->cols = $2;
! 					$$->targetList = NIL;
! 					$$->selectStmt = $4;
  				}
  		;
  
--- 5342,5364 ----
  		;
  
  insert_rest:
! 			SelectStmt
  				{
  					$$ = makeNode(InsertStmt);
  					$$->cols = NIL;
  					$$->selectStmt = $1;
  				}
! 			| '(' insert_column_list ')' SelectStmt
  				{
  					$$ = makeNode(InsertStmt);
  					$$->cols = $2;
! 					$$->selectStmt = $4;
  				}
! 			| DEFAULT VALUES
  				{
  					$$ = makeNode(InsertStmt);
! 					$$->cols = NIL;
! 					$$->selectStmt = NULL;
  				}
  		;
  
***************
*** 5629,5634 ****
--- 5612,5618 ----
  					n->havingClause = $8;
  					$$ = (Node *)n;
  				}
+ 			| values_clause							{ $$ = $1; }
  			| select_clause UNION opt_all select_clause
  				{
  					$$ = makeSetOp(SETOP_UNION, $3, $1, $4);
***************
*** 5848,5853 ****
--- 5832,5863 ----
  			| /* EMPTY */							{ $$ = NIL; }
  		;
  
+ 
+ values_clause:
+ 			VALUES '(' values_list ')'
+ 				{
+ 					SelectStmt *n = makeNode(SelectStmt);
+ 					n->valuesLists = list_make1($3);
+ 					$$ = (Node *) n;
+ 				}
+ 			| values_clause ',' '(' values_list ')'
+ 				{
+ 					SelectStmt *n = (SelectStmt *) $1;
+ 					n->valuesLists = lappend(n->valuesLists, $4);
+ 					$$ = (Node *) n;
+ 				}
+ 		;
+ 
+ values_list: values_item							{ $$ = list_make1($1); }
+ 			| values_list ',' values_item			{ $$ = lappend($1, $3); }
+ 		;
+ 
+ values_item:
+ 			a_expr					{ $$ = (Node *) $1; }
+ 			| DEFAULT				{ $$ = (Node *) makeNode(SetToDefault); }
+ 		;
+ 
+ 
  /*****************************************************************************
   *
   *	clauses common to all Optimizable Stmts:
***************
*** 8176,8205 ****
  
  		;
  
- insert_target_list:
- 			insert_target_el						{ $$ = list_make1($1); }
- 			| insert_target_list ',' insert_target_el { $$ = lappend($1, $3); }
- 		;
- 
- insert_target_el:
- 			a_expr
- 				{
- 					$$ = makeNode(ResTarget);
- 					$$->name = NULL;
- 					$$->indirection = NIL;
- 					$$->val = (Node *)$1;
- 					$$->location = @1;
- 				}
- 			| DEFAULT
- 				{
- 					$$ = makeNode(ResTarget);
- 					$$->name = NULL;
- 					$$->indirection = NIL;
- 					$$->val = (Node *) makeNode(SetToDefault);
- 					$$->location = @1;
- 				}
- 		;
- 
  
  /*****************************************************************************
   *
--- 8186,8191 ----
***************
*** 8656,8662 ****
  			| VACUUM
  			| VALID
  			| VALIDATOR
- 			| VALUES
  			| VARYING
  			| VIEW
  			| VOLATILE
--- 8642,8647 ----
***************
*** 8715,8720 ****
--- 8700,8706 ----
  			| TIMESTAMP
  			| TREAT
  			| TRIM
+ 			| VALUES
  			| VARCHAR
  		;
  
*** src/include/nodes/parsenodes.h.orig	Sun Jul 30 21:16:38 2006
--- src/include/nodes/parsenodes.h	Mon Jul 31 20:13:59 2006
***************
*** 517,523 ****
  	RTE_SUBQUERY,				/* subquery in FROM */
  	RTE_JOIN,					/* join */
  	RTE_SPECIAL,				/* special rule relation (NEW or OLD) */
! 	RTE_FUNCTION				/* function in FROM */
  } RTEKind;
  
  typedef struct RangeTblEntry
--- 517,524 ----
  	RTE_SUBQUERY,				/* subquery in FROM */
  	RTE_JOIN,					/* join */
  	RTE_SPECIAL,				/* special rule relation (NEW or OLD) */
! 	RTE_FUNCTION,				/* function in FROM */
! 	RTE_VALUES					/* VALUES (<exprlist>), (<exprlist>), ... */
  } RTEKind;
  
  typedef struct RangeTblEntry
***************
*** 554,559 ****
--- 555,565 ----
  	List	   *funccoltypmods;	/* integer list of column typmods */
  
  	/*
+ 	 * Fields valid for a values RTE (else NIL):
+ 	 */
+ 	List	   *values_lists;	/* list of expression lists */
+ 
+ 	/*
  	 * Fields valid for a join RTE (else NULL/zero):
  	 *
  	 * joinaliasvars is a list of Vars or COALESCE expressions corresponding
***************
*** 630,635 ****
--- 636,645 ----
  
  /* ----------------------
   *		Insert Statement
+  *
+  * The source expression is represented by SelectStmt for both the
+  * SELECT and VALUES cases.  If selectStmt is NULL, then the query
+  * is INSERT ... DEFAULT VALUES.
   * ----------------------
   */
  typedef struct InsertStmt
***************
*** 637,650 ****
  	NodeTag		type;
  	RangeVar   *relation;		/* relation to insert into */
  	List	   *cols;			/* optional: names of the target columns */
! 
! 	/*
! 	 * An INSERT statement has *either* VALUES or SELECT, never both. If
! 	 * VALUES, a targetList is supplied (empty for DEFAULT VALUES). If SELECT,
! 	 * a complete SelectStmt (or set-operation tree) is supplied.
! 	 */
! 	List	   *targetList;		/* the target list (of ResTarget) */
! 	Node	   *selectStmt;		/* the source SELECT */
  } InsertStmt;
  
  /* ----------------------
--- 647,653 ----
  	NodeTag		type;
  	RangeVar   *relation;		/* relation to insert into */
  	List	   *cols;			/* optional: names of the target columns */
! 	Node	   *selectStmt;		/* the source SELECT/VALUES, or NULL */
  } InsertStmt;
  
  /* ----------------------
***************
*** 676,684 ****
   *		Select Statement
   *
   * A "simple" SELECT is represented in the output of gram.y by a single
!  * SelectStmt node.  A SELECT construct containing set operators (UNION,
!  * INTERSECT, EXCEPT) is represented by a tree of SelectStmt nodes, in
!  * which the leaf nodes are component SELECTs and the internal nodes
   * represent UNION, INTERSECT, or EXCEPT operators.  Using the same node
   * type for both leaf and internal nodes allows gram.y to stick ORDER BY,
   * LIMIT, etc, clause values into a SELECT statement without worrying
--- 679,687 ----
   *		Select Statement
   *
   * A "simple" SELECT is represented in the output of gram.y by a single
!  * SelectStmt node; so is a VALUES construct.  A query containing set
!  * operators (UNION, INTERSECT, EXCEPT) is represented by a tree of SelectStmt
!  * nodes, in which the leaf nodes are component SELECTs and the internal nodes
   * represent UNION, INTERSECT, or EXCEPT operators.  Using the same node
   * type for both leaf and internal nodes allows gram.y to stick ORDER BY,
   * LIMIT, etc, clause values into a SELECT statement without worrying
***************
*** 715,720 ****
--- 718,733 ----
  	Node	   *whereClause;	/* WHERE qualification */
  	List	   *groupClause;	/* GROUP BY clauses */
  	Node	   *havingClause;	/* HAVING conditional-expression */
+ 
+ 	/*
+ 	 * In a "leaf" node representing a VALUES list, the above fields are all
+ 	 * null, and instead we have this field set.  Note that the elements of
+ 	 * the sublists are just expressions, without ResTarget decoration.
+ 	 * Also note that a list element can be DEFAULT (represented as a
+ 	 * SetToDefault node), regardless of the context of the VALUES list.
+ 	 * It's up to parse analysis to reject that where not valid.
+ 	 */
+ 	List	   *valuesLists;	/* untransformed list of expression lists */
  
  	/*
  	 * These fields are used in both "leaf" SelectStmts and upper-level
