Index: src/backend/catalog/dependency.c
===================================================================
RCS file: /home/rbt/work/postgresql/cvs/pgsql-server/src/backend/catalog/dependency.c,v
retrieving revision 1.34
diff -c -r1.34 dependency.c
*** src/backend/catalog/dependency.c	29 Nov 2003 19:51:42 -0000	1.34
--- src/backend/catalog/dependency.c	30 Nov 2003 15:54:36 -0000
***************
*** 1123,1128 ****
--- 1123,1137 ----
  		context->rtables = lnext(context->rtables);
  		return result;
  	}
+ 	if (IsA(node, SequenceOp))
+ 	{
+ 		SequenceOp *sop = (SequenceOp *) node;
+ 
+ 		add_object_address(OCLASS_CLASS, sop->seqId, 0,
+ 						   &context->addrs);
+ 
+ 		return false;
+ 	}
  	return expression_tree_walker(node, find_expr_references_walker,
  								  (void *) context);
  }
Index: src/backend/commands/sequence.c
===================================================================
RCS file: /home/rbt/work/postgresql/cvs/pgsql-server/src/backend/commands/sequence.c,v
retrieving revision 1.109
diff -c -r1.109 sequence.c
*** src/backend/commands/sequence.c	6 Apr 2004 16:39:30 -0000	1.109
--- src/backend/commands/sequence.c	19 Apr 2004 20:20:33 -0000
***************
*** 23,28 ****
--- 23,29 ----
  #include "miscadmin.h"
  #include "utils/acl.h"
  #include "utils/builtins.h"
+ #include "utils/lsyscache.h"
  
  /*
   * We don't want to log each fetching of a value from a sequence,
***************
*** 67,74 ****
  static SeqTable seqtab = NULL;	/* Head of list of SeqTable items */
  
  
! static void init_sequence(RangeVar *relation,
! 			  SeqTable *p_elm, Relation *p_rel);
  static Form_pg_sequence read_info(SeqTable elm, Relation rel, Buffer *buf);
  static void init_params(List *options, Form_pg_sequence new, bool isInit);
  static void do_setval(RangeVar *sequence, int64 next, bool iscalled);
--- 68,75 ----
  static SeqTable seqtab = NULL;	/* Head of list of SeqTable items */
  
  
! static void init_sequence(Oid relId,
! 						  SeqTable *p_elm, Relation *p_rel);
  static Form_pg_sequence read_info(SeqTable elm, Relation rel, Buffer *buf);
  static void init_params(List *options, Form_pg_sequence new, bool isInit);
  static void do_setval(RangeVar *sequence, int64 next, bool iscalled);
***************
*** 304,310 ****
  	FormData_pg_sequence new;
  
  	/* open and AccessShareLock sequence */
! 	init_sequence(stmt->sequence, &elm, &seqrel);
  
  	/* allow ALTER to sequence owner only */
  	if (!pg_class_ownercheck(elm->relid, GetUserId()))
--- 305,311 ----
  	FormData_pg_sequence new;
  
  	/* open and AccessShareLock sequence */
! 	init_sequence(RangeVarGetRelid(stmt->sequence, false), &elm, &seqrel);
  
  	/* allow ALTER to sequence owner only */
  	if (!pg_class_ownercheck(elm->relid, GetUserId()))
***************
*** 371,376 ****
--- 372,390 ----
  {
  	text	   *seqin = PG_GETARG_TEXT_P(0);
  	RangeVar   *sequence;
+ 	int64		result;
+ 
+ 	sequence = makeRangeVarFromNameList(textToQualifiedNameList(seqin,
+ 															 "nextval"));
+ 
+ 	result = do_nextval(RangeVarGetRelid(sequence, false));
+ 
+ 	PG_RETURN_INT64(result);
+ }
+ 
+ int64
+ do_nextval(Oid seqId)
+ {
  	SeqTable	elm;
  	Relation	seqrel;
  	Buffer		buf;
***************
*** 388,404 ****
  				rescnt = 0;
  	bool		logit = false;
  
- 	sequence = makeRangeVarFromNameList(textToQualifiedNameList(seqin,
- 															 "nextval"));
- 
  	/* open and AccessShareLock sequence */
! 	init_sequence(sequence, &elm, &seqrel);
  
  	if (pg_class_aclcheck(elm->relid, GetUserId(), ACL_UPDATE) != ACLCHECK_OK)
  		ereport(ERROR,
  				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
  				 errmsg("permission denied for sequence %s",
! 						sequence->relname)));
  
  	if (elm->last != elm->cached)		/* some numbers were cached */
  	{
--- 402,415 ----
  				rescnt = 0;
  	bool		logit = false;
  
  	/* open and AccessShareLock sequence */
! 	init_sequence(seqId, &elm, &seqrel);
  
  	if (pg_class_aclcheck(elm->relid, GetUserId(), ACL_UPDATE) != ACLCHECK_OK)
  		ereport(ERROR,
  				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
  				 errmsg("permission denied for sequence %s",
! 						get_rel_name(seqId))));
  
  	if (elm->last != elm->cached)		/* some numbers were cached */
  	{
***************
*** 475,481 ****
  					ereport(ERROR,
  					  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
  					   errmsg("nextval: reached maximum value of sequence \"%s\" (%s)",
! 							  sequence->relname, buf)));
  				}
  				next = minv;
  			}
--- 486,492 ----
  					ereport(ERROR,
  					  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
  					   errmsg("nextval: reached maximum value of sequence \"%s\" (%s)",
! 							  get_rel_name(seqId), buf)));
  				}
  				next = minv;
  			}
***************
*** 498,504 ****
  					ereport(ERROR,
  					  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
  					   errmsg("nextval: reached minimum value of sequence \"%s\" (%s)",
! 							  sequence->relname, buf)));
  				}
  				next = maxv;
  			}
--- 509,515 ----
  					ereport(ERROR,
  					  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
  					   errmsg("nextval: reached minimum value of sequence \"%s\" (%s)",
! 							  get_rel_name(seqId), buf)));
  				}
  				next = maxv;
  			}
***************
*** 568,608 ****
  
  	relation_close(seqrel, NoLock);
  
! 	PG_RETURN_INT64(result);
  }
  
  Datum
  currval(PG_FUNCTION_ARGS)
  {
  	text	   *seqin = PG_GETARG_TEXT_P(0);
  	RangeVar   *sequence;
- 	SeqTable	elm;
- 	Relation	seqrel;
  	int64		result;
  
  	sequence = makeRangeVarFromNameList(textToQualifiedNameList(seqin,
  															 "currval"));
  
  	/* open and AccessShareLock sequence */
! 	init_sequence(sequence, &elm, &seqrel);
  
  	if (pg_class_aclcheck(elm->relid, GetUserId(), ACL_SELECT) != ACLCHECK_OK)
  		ereport(ERROR,
  				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
  				 errmsg("permission denied for sequence %s",
! 						sequence->relname)));
  
  	if (elm->increment == 0)	/* nextval/read_info were not called */
  		ereport(ERROR,
  				(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
  				 errmsg("currval of sequence \"%s\" is not yet defined in this session",
! 						sequence->relname)));
  
  	result = elm->last;
  
  	relation_close(seqrel, NoLock);
  
! 	PG_RETURN_INT64(result);
  }
  
  /*
--- 579,630 ----
  
  	relation_close(seqrel, NoLock);
  
! 	return(result);
  }
  
+ 
  Datum
  currval(PG_FUNCTION_ARGS)
  {
  	text	   *seqin = PG_GETARG_TEXT_P(0);
  	RangeVar   *sequence;
  	int64		result;
  
  	sequence = makeRangeVarFromNameList(textToQualifiedNameList(seqin,
  															 "currval"));
  
+ 	result = do_currval(RangeVarGetRelid(sequence, false));
+ 
+ 	PG_RETURN_INT64(result);
+ }
+ 
+ int64
+ do_currval(Oid seqId)
+ {
+ 	SeqTable	elm;
+ 	Relation	seqrel;
+ 	int64		result;
+ 
  	/* open and AccessShareLock sequence */
! 	init_sequence(seqId, &elm, &seqrel);
  
  	if (pg_class_aclcheck(elm->relid, GetUserId(), ACL_SELECT) != ACLCHECK_OK)
  		ereport(ERROR,
  				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
  				 errmsg("permission denied for sequence %s",
! 						get_rel_name(seqId))));
  
  	if (elm->increment == 0)	/* nextval/read_info were not called */
  		ereport(ERROR,
  				(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
  				 errmsg("currval of sequence \"%s\" is not yet defined in this session",
! 						get_rel_name(seqId))));
  
  	result = elm->last;
  
  	relation_close(seqrel, NoLock);
  
! 	return result;
  }
  
  /*
***************
*** 627,633 ****
  	Form_pg_sequence seq;
  
  	/* open and AccessShareLock sequence */
! 	init_sequence(sequence, &elm, &seqrel);
  
  	if (pg_class_aclcheck(elm->relid, GetUserId(), ACL_UPDATE) != ACLCHECK_OK)
  		ereport(ERROR,
--- 649,655 ----
  	Form_pg_sequence seq;
  
  	/* open and AccessShareLock sequence */
! 	init_sequence(RangeVarGetRelid(sequence, false), &elm, &seqrel);
  
  	if (pg_class_aclcheck(elm->relid, GetUserId(), ACL_UPDATE) != ACLCHECK_OK)
  		ereport(ERROR,
***************
*** 750,758 ****
   * output parameters.
   */
  static void
! init_sequence(RangeVar *relation, SeqTable *p_elm, Relation *p_rel)
  {
- 	Oid			relid = RangeVarGetRelid(relation, false);
  	TransactionId thisxid = GetCurrentTransactionId();
  	SeqTable	elm;
  	Relation	seqrel;
--- 772,779 ----
   * output parameters.
   */
  static void
! init_sequence(Oid relid, SeqTable *p_elm, Relation *p_rel)
  {
  	TransactionId thisxid = GetCurrentTransactionId();
  	SeqTable	elm;
  	Relation	seqrel;
***************
*** 777,783 ****
  		ereport(ERROR,
  				(errcode(ERRCODE_WRONG_OBJECT_TYPE),
  				 errmsg("\"%s\" is not a sequence",
! 						relation->relname)));
  
  	/*
  	 * Allocate new seqtable entry if we didn't find one.
--- 798,804 ----
  		ereport(ERROR,
  				(errcode(ERRCODE_WRONG_OBJECT_TYPE),
  				 errmsg("\"%s\" is not a sequence",
! 						get_rel_name(relid))));
  
  	/*
  	 * Allocate new seqtable entry if we didn't find one.
Index: src/backend/executor/execQual.c
===================================================================
RCS file: /home/rbt/work/postgresql/cvs/pgsql-server/src/backend/executor/execQual.c,v
retrieving revision 1.158
diff -c -r1.158 execQual.c
*** src/backend/executor/execQual.c	1 Apr 2004 21:28:44 -0000	1.158
--- src/backend/executor/execQual.c	20 Apr 2004 13:13:57 -0000
***************
*** 38,43 ****
--- 38,44 ----
  
  #include "access/heapam.h"
  #include "catalog/pg_type.h"
+ #include "commands/sequence.h"
  #include "commands/typecmds.h"
  #include "executor/execdebug.h"
  #include "executor/functions.h"
***************
*** 2420,2425 ****
--- 2421,2453 ----
  	return econtext->domainValue_datum;
  }
  
+ /*
+  * ExecEvalSequenceOp
+  *
+  * Return the next value of the sequence
+  */
+ static Datum
+ ExecEvalSequenceOp(ExprState *exprstate,
+ 				   ExprContext *econtext,
+ 				   bool *isNull, ExprDoneCond *isDone)
+ {
+ 	SequenceOp *sop = (SequenceOp *) exprstate->expr;
+ 	int64	result;
+ 
+ 	/* There is always a value or an error */
+ 	*isNull = false;
+ 	if (isDone)
+ 		*isDone = ExprSingleResult;
+ 
+ 	/* Call out for the work */
+ 	if (sop->next)
+ 		result = do_nextval(sop->seqId);
+ 	else
+ 		result = do_currval(sop->seqId);
+ 
+ 	return Int64GetDatum(result);
+ }
+ 
  /* ----------------------------------------------------------------
   *		ExecEvalFieldSelect
   *
***************
*** 2501,2507 ****
  	return ExecEvalExpr(exprstate->arg, econtext, isNull, isDone);
  }
  
- 
  /*
   * ExecEvalExprSwitchContext
   *
--- 2529,2534 ----
***************
*** 2587,2592 ****
--- 2614,2623 ----
  		case T_CaseTestExpr:
  			state = (ExprState *) makeNode(ExprState);
  			state->evalfunc = ExecEvalCaseTestExpr;
+ 			break;
+ 		case T_SequenceOp:
+ 			state = (ExprState *) makeNode(ExprState);
+ 			state->evalfunc = ExecEvalSequenceOp;
  			break;
  		case T_Aggref:
  			{
Index: src/backend/nodes/copyfuncs.c
===================================================================
RCS file: /home/rbt/work/postgresql/cvs/pgsql-server/src/backend/nodes/copyfuncs.c,v
retrieving revision 1.279
diff -c -r1.279 copyfuncs.c
*** src/backend/nodes/copyfuncs.c	17 Mar 2004 20:48:42 -0000	1.279
--- src/backend/nodes/copyfuncs.c	20 Apr 2004 22:51:34 -0000
***************
*** 2479,2484 ****
--- 2479,2495 ----
  	return newnode;
  }
  
+ static SequenceOp *
+ _copySequenceOp(SequenceOp *from)
+ {
+ 	SequenceOp *newnode = makeNode(SequenceOp);
+ 
+ 	COPY_SCALAR_FIELD(seqId);
+ 	COPY_SCALAR_FIELD(next);
+ 	COPY_NODE_FIELD(sequence);
+ 
+ 	return newnode;
+ }
  
  /* ****************************************************************
   *					pg_list.h copy functions
***************
*** 3034,3039 ****
--- 3045,3053 ----
  			break;
  		case T_FuncWithArgs:
  			retval = _copyFuncWithArgs(from);
+ 			break;
+ 		case T_SequenceOp:
+ 			retval = _copySequenceOp(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.218
diff -c -r1.218 equalfuncs.c
*** src/backend/nodes/equalfuncs.c	17 Mar 2004 20:48:42 -0000	1.218
--- src/backend/nodes/equalfuncs.c	19 Apr 2004 20:20:43 -0000
***************
*** 1616,1621 ****
--- 1616,1629 ----
  	return true;
  }
  
+ static bool
+ _equalSequenceOp(SequenceOp *a, SequenceOp *b)
+ {
+ 	COMPARE_NODE_FIELD(sequence);
+ 
+ 	return true;
+ }
+ 
  
  /*
   * Stuff from pg_list.h
***************
*** 2108,2113 ****
--- 2116,2124 ----
  			break;
  		case T_FuncWithArgs:
  			retval = _equalFuncWithArgs(a, b);
+ 			break;
+ 		case T_SequenceOp:
+ 			retval = _equalSequenceOp(a, b);
  			break;
  
  		default:
Index: src/backend/nodes/outfuncs.c
===================================================================
RCS file: /home/rbt/work/postgresql/cvs/pgsql-server/src/backend/nodes/outfuncs.c,v
retrieving revision 1.233
diff -c -r1.233 outfuncs.c
*** src/backend/nodes/outfuncs.c	17 Mar 2004 20:48:42 -0000	1.233
--- src/backend/nodes/outfuncs.c	20 Apr 2004 12:29:43 -0000
***************
*** 1550,1555 ****
--- 1550,1563 ----
  	WRITE_BOOL_FIELD(skip_validation);
  }
  
+ static void
+ _outSequenceOp(StringInfo str, SequenceOp *node)
+ {
+ 	WRITE_NODE_TYPE("SEQUENCEOP");
+ 
+ 	WRITE_BOOL_FIELD(next);
+ 	WRITE_OID_FIELD(seqId);
+ }
  
  /*
   * _outNode -
***************
*** 1858,1863 ****
--- 1866,1874 ----
  				break;
  			case T_FuncCall:
  				_outFuncCall(str, obj);
+ 				break;
+ 			case T_SequenceOp:
+ 				_outSequenceOp(str, obj);
  				break;
  
  			default:
Index: src/backend/nodes/readfuncs.c
===================================================================
RCS file: /home/rbt/work/postgresql/cvs/pgsql-server/src/backend/nodes/readfuncs.c,v
retrieving revision 1.166
diff -c -r1.166 readfuncs.c
*** src/backend/nodes/readfuncs.c	17 Mar 2004 20:48:42 -0000	1.166
--- src/backend/nodes/readfuncs.c	20 Apr 2004 12:30:08 -0000
***************
*** 959,964 ****
--- 959,974 ----
  	READ_DONE();
  }
  
+ static SequenceOp *
+ _readSequenceOp(void)
+ {
+ 	READ_LOCALS(SequenceOp);
+ 
+ 	READ_BOOL_FIELD(next);
+ 	READ_OID_FIELD(seqId);
+ 
+ 	READ_DONE();
+ }
  
  /*
   * parseNodeString
***************
*** 1064,1069 ****
--- 1074,1081 ----
  		return_value = _readNotifyStmt();
  	else if (MATCH("DECLARECURSOR", 13))
  		return_value = _readDeclareCursorStmt();
+ 	else if (MATCH("SEQUENCEOP", 10))
+ 		return_value = _readSequenceOp();
  	else
  	{
  		elog(ERROR, "badly formatted node string \"%.32s\"...", token);
Index: src/backend/optimizer/util/clauses.c
===================================================================
RCS file: /home/rbt/work/postgresql/cvs/pgsql-server/src/backend/optimizer/util/clauses.c,v
retrieving revision 1.169
diff -c -r1.169 clauses.c
*** src/backend/optimizer/util/clauses.c	2 Apr 2004 23:14:08 -0000	1.169
--- src/backend/optimizer/util/clauses.c	19 Apr 2004 20:26:28 -0000
***************
*** 2360,2365 ****
--- 2360,2366 ----
  		case T_CaseTestExpr:
  		case T_SetToDefault:
  		case T_RangeTblRef:
+ 		case T_SequenceOp:
  			/* primitive node types with no subnodes */
  			break;
  		case T_Aggref:
***************
*** 3021,3026 ****
--- 3022,3035 ----
  				return (Node *) newnode;
  			}
  			break;
+ 		case T_SequenceOp:
+ 			{
+ 				SequenceOp *sop = (SequenceOp *) node;
+ 				SequenceOp *newnode;
+ 
+ 				FLATCOPY(newnode, sop, SequenceOp);
+ 				return (Node *) newnode;
+ 			}
  		default:
  			elog(ERROR, "unrecognized node type: %d",
  				 (int) nodeTag(node));
Index: src/backend/parser/analyze.c
===================================================================
RCS file: /home/rbt/work/postgresql/cvs/pgsql-server/src/backend/parser/analyze.c,v
retrieving revision 1.298
diff -c -r1.298 analyze.c
*** src/backend/parser/analyze.c	2 Apr 2004 21:05:32 -0000	1.298
--- src/backend/parser/analyze.c	19 Apr 2004 20:20:49 -0000
***************
*** 971,979 ****
  	{
  		char	   *sname;
  		char	   *snamespace;
! 		char	   *qstring;
! 		A_Const    *snamenode;
! 		FuncCall   *funccallnode;
  		CreateSeqStmt *seqstmt;
  
  		/*
--- 971,977 ----
  	{
  		char	   *sname;
  		char	   *snamespace;
! 		SequenceOp  *sop;
  		CreateSeqStmt *seqstmt;
  
  		/*
***************
*** 1010,1032 ****
  		 * conflicting constraints the user wrote (like a different
  		 * DEFAULT).
  		 *
! 		 * Create an expression tree representing the function call
! 		 * nextval('"sequencename"')
  		 */
! 		qstring = quote_qualified_identifier(snamespace, sname);
! 		snamenode = makeNode(A_Const);
! 		snamenode->val.type = T_String;
! 		snamenode->val.val.str = qstring;
! 		funccallnode = makeNode(FuncCall);
! 		funccallnode->funcname = SystemFuncName("nextval");
! 		funccallnode->args = makeList1(snamenode);
! 		funccallnode->agg_star = false;
! 		funccallnode->agg_distinct = false;
  
  		constraint = makeNode(Constraint);
  		constraint->contype = CONSTR_DEFAULT;
  		constraint->name = sname;
! 		constraint->raw_expr = (Node *) funccallnode;
  		constraint->cooked_expr = NULL;
  		constraint->keys = NIL;
  		column->constraints = lappend(column->constraints, constraint);
--- 1008,1023 ----
  		 * conflicting constraints the user wrote (like a different
  		 * DEFAULT).
  		 *
! 		 * Create an expression tree representing NEXT VALUE FOR <sequencename>
  		 */
! 		sop = makeNode(SequenceOp);
! 		sop->sequence = makeRangeVar(snamespace, sname);
! 		sop->next = true;
  
  		constraint = makeNode(Constraint);
  		constraint->contype = CONSTR_DEFAULT;
  		constraint->name = sname;
! 		constraint->raw_expr = (Node *) sop;
  		constraint->cooked_expr = NULL;
  		constraint->keys = NIL;
  		column->constraints = lappend(column->constraints, constraint);
Index: src/backend/parser/gram.y
===================================================================
RCS file: /home/rbt/work/postgresql/cvs/pgsql-server/src/backend/parser/gram.y,v
retrieving revision 2.451
diff -c -r2.451 gram.y
*** src/backend/parser/gram.y	19 Apr 2004 17:22:30 -0000	2.451
--- src/backend/parser/gram.y	20 Apr 2004 14:46:22 -0000
***************
*** 343,349 ****
  	CHARACTER CHARACTERISTICS CHECK CHECKPOINT CLASS CLOSE
  	CLUSTER COALESCE COLLATE COLUMN COMMENT COMMIT
  	COMMITTED CONSTRAINT CONSTRAINTS CONVERSION_P CONVERT COPY CREATE CREATEDB
! 	CREATEUSER CROSS CSV CURRENT_DATE CURRENT_TIME
  	CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE
  
  	DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS
--- 343,349 ----
  	CHARACTER CHARACTERISTICS CHECK CHECKPOINT CLASS CLOSE
  	CLUSTER COALESCE COLLATE COLUMN COMMENT COMMIT
  	COMMITTED CONSTRAINT CONSTRAINTS CONVERSION_P CONVERT COPY CREATE CREATEDB
! 	CREATEUSER CROSS CSV CURRENT CURRENT_DATE CURRENT_TIME
  	CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE
  
  	DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS
***************
*** 6798,6803 ****
--- 6798,6838 ----
  				}
  			| ARRAY array_expr
  				{	$$ = $2;	}
+ 			/*
+ 			 * In order to prevent VALUE from becoming a reserved
+ 			 * keyword, we treat it as an IDENT whos value
+ 			 * must be value.
+ 			 *
+ 			 * This prevents breakages of applications using VALUE as
+ 			 * a column name.
+ 			 *
+ 			 * SQL92 and above state that VALUE is a reserved keyword.
+ 			 */
+ 			| NEXT IDENT FOR qualified_name
+ 				{
+ 					SequenceOp *n = makeNode(SequenceOp);
+ 
+ 					if (strcmp($2, "value") != 0)
+ 						elog(ERROR, "parse error at or near \"%s\"", $2);
+ 
+ 					n->sequence = $4;
+ 					n->next = true;
+ 
+ 					$$ = (Node *)n;
+ 				}
+ 			| CURRENT IDENT FOR qualified_name
+ 				{
+ 					SequenceOp *n = makeNode(SequenceOp);
+ 
+ 					if (strcmp($2, "value") != 0)
+ 						elog(ERROR, "parse error at or near \"%s\"", $2);
+ 
+ 					n->sequence = $4;
+ 					n->next = false;
+ 
+ 					$$ = (Node *)n;
+ 				}
+ 
  		;
  
  /*
***************
*** 7443,7448 ****
--- 7478,7484 ----
  			| CREATEDB
  			| CREATEUSER
  			| CSV
+ 			| CURRENT
  			| CURSOR
  			| CYCLE
  			| DATABASE
Index: src/backend/parser/keywords.c
===================================================================
RCS file: /home/rbt/work/postgresql/cvs/pgsql-server/src/backend/parser/keywords.c,v
retrieving revision 1.148
diff -c -r1.148 keywords.c
*** src/backend/parser/keywords.c	19 Apr 2004 17:22:31 -0000	1.148
--- src/backend/parser/keywords.c	19 Apr 2004 20:38:39 -0000
***************
*** 91,96 ****
--- 91,97 ----
  	{"createuser", CREATEUSER},
  	{"cross", CROSS},
  	{"csv", CSV},
+ 	{"current", CURRENT},
  	{"current_date", CURRENT_DATE},
  	{"current_time", CURRENT_TIME},
  	{"current_timestamp", CURRENT_TIMESTAMP},
Index: src/backend/parser/parse_expr.c
===================================================================
RCS file: /home/rbt/work/postgresql/cvs/pgsql-server/src/backend/parser/parse_expr.c,v
retrieving revision 1.169
diff -c -r1.169 parse_expr.c
*** src/backend/parser/parse_expr.c	18 Apr 2004 18:12:58 -0000	1.169
--- src/backend/parser/parse_expr.c	19 Apr 2004 20:43:27 -0000
***************
*** 15,20 ****
--- 15,21 ----
  
  #include "postgres.h"
  
+ #include "catalog/namespace.h"
  #include "catalog/pg_operator.h"
  #include "catalog/pg_proc.h"
  #include "commands/dbcommands.h"
***************
*** 875,880 ****
--- 876,890 ----
  				result = expr;
  				break;
  			}
+ 		case T_SequenceOp:
+ 			{
+ 				SequenceOp *sop = (SequenceOp *) expr;
+ 
+ 				sop->seqId = RangeVarGetRelid(sop->sequence, false);
+ 
+ 				result = expr;
+ 				break;
+ 			}
  
  			/*********************************************
  			 * Quietly accept node types that may be presented when we are
***************
*** 1360,1365 ****
--- 1370,1378 ----
  			break;
  		case T_SetToDefault:
  			type = ((SetToDefault *) expr)->typeId;
+ 			break;
+ 		case T_SequenceOp:
+ 			type = INT8OID;
  			break;
  		default:
  			elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
Index: src/backend/utils/adt/ruleutils.c
===================================================================
RCS file: /home/rbt/work/postgresql/cvs/pgsql-server/src/backend/utils/adt/ruleutils.c,v
retrieving revision 1.163
diff -c -r1.163 ruleutils.c
*** src/backend/utils/adt/ruleutils.c	17 Mar 2004 20:48:42 -0000	1.163
--- src/backend/utils/adt/ruleutils.c	19 Apr 2004 20:21:21 -0000
***************
*** 2616,2622 ****
  				default:
  					return false;
  			}
- 
  		default:
  			break;
  	}
--- 2616,2621 ----
***************
*** 3222,3227 ****
--- 3221,3240 ----
  		case T_SetToDefault:
  			appendStringInfo(buf, "DEFAULT");
  			break;
+ 
+ 		case T_SequenceOp:
+ 			{
+ 				SequenceOp *sop = (SequenceOp *) node;
+ 
+ 				appendStringInfo(buf, "%s VALUE FOR",
+ 								 sop->next ? "NEXT" : "CURRENT");
+ 				appendStringInfo(buf, " %s.%s",
+ 								 quote_identifier(
+ 									get_namespace_name(
+ 										get_rel_namespace(sop->seqId))),
+ 								 quote_identifier(get_rel_name(sop->seqId)));
+ 				break;
+ 			}
  
  		default:
  			elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
Index: src/include/commands/sequence.h
===================================================================
RCS file: /home/rbt/work/postgresql/cvs/pgsql-server/src/include/commands/sequence.h,v
retrieving revision 1.28
diff -c -r1.28 sequence.h
*** src/include/commands/sequence.h	29 Nov 2003 22:40:59 -0000	1.28
--- src/include/commands/sequence.h	1 Dec 2003 01:59:01 -0000
***************
*** 81,87 ****
--- 81,89 ----
  } xl_seq_rec;
  
  extern Datum nextval(PG_FUNCTION_ARGS);
+ extern int64 do_nextval(Oid seqId);
  extern Datum currval(PG_FUNCTION_ARGS);
+ extern int64 do_currval(Oid seqId);
  extern Datum setval(PG_FUNCTION_ARGS);
  extern Datum setval_and_iscalled(PG_FUNCTION_ARGS);
  
Index: src/include/nodes/execnodes.h
===================================================================
RCS file: /home/rbt/work/postgresql/cvs/pgsql-server/src/include/nodes/execnodes.h,v
retrieving revision 1.115
diff -c -r1.115 execnodes.h
*** src/include/nodes/execnodes.h	1 Apr 2004 21:28:46 -0000	1.115
--- src/include/nodes/execnodes.h	20 Apr 2004 12:24:59 -0000
***************
*** 632,638 ****
  	ExprState	xprstate;
  	ExprState  *arg;			/* input expression */
  	/* Cached list of constraints that need to be checked */
! 	List	   *constraints;	/* list of DomainConstraintState nodes */
  } CoerceToDomainState;
  
  /*
--- 632,638 ----
  	ExprState	xprstate;
  	ExprState  *arg;			/* input expression */
  	/* Cached list of constraints that need to be checked */
!  	List	   *constraints;	/* list of DomainConstraintState nodes */
  } CoerceToDomainState;
  
  /*
Index: src/include/nodes/nodes.h
===================================================================
RCS file: /home/rbt/work/postgresql/cvs/pgsql-server/src/include/nodes/nodes.h,v
retrieving revision 1.152
diff -c -r1.152 nodes.h
*** src/include/nodes/nodes.h	1 Apr 2004 21:28:46 -0000	1.152
--- src/include/nodes/nodes.h	19 Apr 2004 20:22:03 -0000
***************
*** 121,126 ****
--- 121,127 ----
  	T_BooleanTest,
  	T_CoerceToDomain,
  	T_CoerceToDomainValue,
+ 	T_SequenceOp,
  	T_SetToDefault,
  	T_TargetEntry,
  	T_RangeTblRef,
Index: src/include/nodes/primnodes.h
===================================================================
RCS file: /home/rbt/work/postgresql/cvs/pgsql-server/src/include/nodes/primnodes.h,v
retrieving revision 1.97
diff -c -r1.97 primnodes.h
*** src/include/nodes/primnodes.h	1 Apr 2004 21:28:46 -0000	1.97
--- src/include/nodes/primnodes.h	19 Apr 2004 20:22:04 -0000
***************
*** 760,765 ****
--- 760,775 ----
  	Expr	   *expr;			/* expression to evaluate */
  } TargetEntry;
  
+ /*
+  * Sequence Operation
+  */
+ typedef struct SequenceOp
+ {
+ 	NodeTag		type;
+ 	bool		next;		/* CURRENT VALUE if false, NEXT VALUE if true */
+ 	RangeVar   *sequence;
+ 	Oid			seqId;
+ } SequenceOp;
  
  /* ----------------------------------------------------------------
   *					node types for join trees
Index: src/test/regress/expected/sequence.out
===================================================================
RCS file: /home/rbt/work/postgresql/cvs/pgsql-server/src/test/regress/expected/sequence.out,v
retrieving revision 1.5
diff -c -r1.5 sequence.out
*** src/test/regress/expected/sequence.out	21 Nov 2003 22:32:49 -0000	1.5
--- src/test/regress/expected/sequence.out	1 Dec 2003 18:51:47 -0000
***************
*** 59,67 ****
        16
  (1 row)
  
! SELECT nextval('sequence_test2');
!  nextval 
! ---------
        20
  (1 row)
  
--- 59,73 ----
        16
  (1 row)
  
! SELECT NEXT VALUE FOR sequence_test2;
!  ?column? 
! ----------
!        20
! (1 row)
! 
! SELECT CURRENT VALUE FOR sequence_test2;
!  ?column? 
! ----------
        20
  (1 row)
  
***************
*** 69,74 ****
--- 75,92 ----
   nextval 
  ---------
         5
+ (1 row)
+ 
+ SELECT CURRENT VALUE FOR sequence_test2;
+  ?column? 
+ ----------
+         5
+ (1 row)
+ 
+ SELECT NEXT VALUE FOR sequence_test2;
+  ?column? 
+ ----------
+         9
  (1 row)
  
  -- Test comments
Index: src/test/regress/sql/sequence.sql
===================================================================
RCS file: /home/rbt/work/postgresql/cvs/pgsql-server/src/test/regress/sql/sequence.sql,v
retrieving revision 1.2
diff -c -r1.2 sequence.sql
*** src/test/regress/sql/sequence.sql	21 Nov 2003 22:32:49 -0000	1.2
--- src/test/regress/sql/sequence.sql	23 Nov 2003 17:29:02 -0000
***************
*** 34,41 ****
  ALTER SEQUENCE sequence_test2 RESTART WITH 16
  	 INCREMENT BY 4 MAXVALUE 22 MINVALUE 5 CYCLE;
  SELECT nextval('sequence_test2');
  SELECT nextval('sequence_test2');
! SELECT nextval('sequence_test2');
  
  -- Test comments
  COMMENT ON SEQUENCE asdf IS 'won''t work';
--- 34,44 ----
  ALTER SEQUENCE sequence_test2 RESTART WITH 16
  	 INCREMENT BY 4 MAXVALUE 22 MINVALUE 5 CYCLE;
  SELECT nextval('sequence_test2');
+ SELECT NEXT VALUE FOR sequence_test2;
+ SELECT CURRENT VALUE FOR sequence_test2;
  SELECT nextval('sequence_test2');
! SELECT CURRENT VALUE FOR sequence_test2;
! SELECT NEXT VALUE FOR sequence_test2;
  
  -- Test comments
  COMMENT ON SEQUENCE asdf IS 'won''t work';
