From 8a793af8ff0d62a93b8e2ee3b0bcf7377ca6c97e Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter_e@gmx.net>
Date: Sun, 14 Aug 2016 12:00:00 -0400
Subject: [PATCH 2/2] Use NEXT VALUE FOR for serial columns

In the expansion of the default value generated by serial columns, use
the NEXT VALUE FOR expression instead of the nextval function.  There is
no behavior change, but the expression becomes simpler and less ugly.
---
 doc/src/sgml/datatype.sgml                     |  4 ++--
 src/backend/parser/parse_utilcmd.c             | 30 ++++++++------------------
 src/test/regress/expected/replica_identity.out | 30 +++++++++++++-------------
 3 files changed, 26 insertions(+), 38 deletions(-)

diff --git a/doc/src/sgml/datatype.sgml b/doc/src/sgml/datatype.sgml
index 67d0c34..a99071b 100644
--- a/doc/src/sgml/datatype.sgml
+++ b/doc/src/sgml/datatype.sgml
@@ -850,7 +850,7 @@ <title>Serial Types</title>
 <programlisting>
 CREATE SEQUENCE <replaceable class="parameter">tablename</replaceable>_<replaceable class="parameter">colname</replaceable>_seq;
 CREATE TABLE <replaceable class="parameter">tablename</replaceable> (
-    <replaceable class="parameter">colname</replaceable> integer NOT NULL DEFAULT nextval('<replaceable class="parameter">tablename</replaceable>_<replaceable class="parameter">colname</replaceable>_seq')
+    <replaceable class="parameter">colname</replaceable> integer NOT NULL DEFAULT NEXT VALUE FOR <replaceable class="parameter">tablename</replaceable>_<replaceable class="parameter">colname</replaceable>_seq
 );
 ALTER SEQUENCE <replaceable class="parameter">tablename</replaceable>_<replaceable class="parameter">colname</replaceable>_seq OWNED BY <replaceable class="parameter">tablename</replaceable>.<replaceable class="parameter">colname</replaceable>;
 </programlisting>
@@ -874,7 +874,7 @@ <title>Serial Types</title>
         from the sequence is still "used up" even if a row containing that
         value is never successfully inserted into the table column.  This
         may happen, for example, if the inserting transaction rolls back.
-        See <literal>nextval()</literal> in <xref linkend="functions-sequence">
+        See <literal>NEXT VALUE FOR</literal> in <xref linkend="functions-sequence">
         for details.
       </para>
     </note>
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index e98fad0..bb088b5 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -411,10 +411,7 @@ transformColumnDefinition(CreateStmtContext *cxt, ColumnDef *column)
 		Oid			snamespaceid;
 		char	   *snamespace;
 		char	   *sname;
-		char	   *qstring;
-		A_Const    *snamenode;
-		TypeCast   *castnode;
-		FuncCall   *funccallnode;
+		NextValueClause *nvcnode;
 		CreateSeqStmt *seqstmt;
 		AlterSeqStmt *altseqstmt;
 		List	   *attnamelist;
@@ -491,27 +488,18 @@ transformColumnDefinition(CreateStmtContext *cxt, ColumnDef *column)
 		 * rather than shortcutting, so that we will detect any conflicting
 		 * constraints the user wrote (like a different DEFAULT).
 		 *
-		 * Create an expression tree representing the function call
-		 * nextval('sequencename').  We cannot reduce the raw tree to cooked
-		 * form until after the sequence is created, but there's no need to do
-		 * so.
+		 * Create an expression tree representing NEXT VALUE FOR
+		 * "sequencename".  We cannot reduce the raw tree to cooked form until
+		 * after the sequence is created, but there's no need to do so.
 		 */
-		qstring = quote_qualified_identifier(snamespace, sname);
-		snamenode = makeNode(A_Const);
-		snamenode->val.type = T_String;
-		snamenode->val.val.str = qstring;
-		snamenode->location = -1;
-		castnode = makeNode(TypeCast);
-		castnode->typeName = SystemTypeName("regclass");
-		castnode->arg = (Node *) snamenode;
-		castnode->location = -1;
-		funccallnode = makeFuncCall(SystemFuncName("nextval"),
-									list_make1(castnode),
-									-1);
+		nvcnode = makeNode(NextValueClause);
+		nvcnode->sequence = seqstmt->sequence;
+		nvcnode->location = -1;
+
 		constraint = makeNode(Constraint);
 		constraint->contype = CONSTR_DEFAULT;
 		constraint->location = -1;
-		constraint->raw_expr = (Node *) funccallnode;
+		constraint->raw_expr = (Node *) nvcnode;
 		constraint->cooked_expr = NULL;
 		column->constraints = lappend(column->constraints, constraint);
 
diff --git a/src/test/regress/expected/replica_identity.out b/src/test/regress/expected/replica_identity.out
index 39a60a5..2efb86f 100644
--- a/src/test/regress/expected/replica_identity.out
+++ b/src/test/regress/expected/replica_identity.out
@@ -77,10 +77,10 @@ SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass;
 (1 row)
 
 \d test_replica_identity
-                         Table "public.test_replica_identity"
- Column |  Type   |                             Modifiers                              
---------+---------+--------------------------------------------------------------------
- id     | integer | not null default nextval('test_replica_identity_id_seq'::regclass)
+                      Table "public.test_replica_identity"
+ Column |  Type   |                          Modifiers                           
+--------+---------+--------------------------------------------------------------
+ id     | integer | not null default NEXT VALUE FOR test_replica_identity_id_seq
  keya   | text    | not null
  keyb   | text    | not null
  nonkey | text    | 
@@ -110,10 +110,10 @@ SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass;
 (1 row)
 
 \d test_replica_identity
-                         Table "public.test_replica_identity"
- Column |  Type   |                             Modifiers                              
---------+---------+--------------------------------------------------------------------
- id     | integer | not null default nextval('test_replica_identity_id_seq'::regclass)
+                      Table "public.test_replica_identity"
+ Column |  Type   |                          Modifiers                           
+--------+---------+--------------------------------------------------------------
+ id     | integer | not null default NEXT VALUE FOR test_replica_identity_id_seq
  keya   | text    | not null
  keyb   | text    | not null
  nonkey | text    | 
@@ -159,13 +159,13 @@ SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass;
 (1 row)
 
 \d+ test_replica_identity
-                                             Table "public.test_replica_identity"
- Column |  Type   |                             Modifiers                              | Storage  | Stats target | Description 
---------+---------+--------------------------------------------------------------------+----------+--------------+-------------
- id     | integer | not null default nextval('test_replica_identity_id_seq'::regclass) | plain    |              | 
- keya   | text    | not null                                                           | extended |              | 
- keyb   | text    | not null                                                           | extended |              | 
- nonkey | text    |                                                                    | extended |              | 
+                                          Table "public.test_replica_identity"
+ Column |  Type   |                          Modifiers                           | Storage  | Stats target | Description 
+--------+---------+--------------------------------------------------------------+----------+--------------+-------------
+ id     | integer | not null default NEXT VALUE FOR test_replica_identity_id_seq | plain    |              | 
+ keya   | text    | not null                                                     | extended |              | 
+ keyb   | text    | not null                                                     | extended |              | 
+ nonkey | text    |                                                              | extended |              | 
 Indexes:
     "test_replica_identity_pkey" PRIMARY KEY, btree (id)
     "test_replica_identity_expr" UNIQUE, btree (keya, keyb, (3))
-- 
2.9.3

