diff -dcrpN pgsql.orig/doc/src/sgml/catalogs.sgml pgsql/doc/src/sgml/catalogs.sgml
*** pgsql.orig/doc/src/sgml/catalogs.sgml	2007-04-04 10:10:45.000000000 +0200
--- pgsql/doc/src/sgml/catalogs.sgml	2007-04-04 12:57:20.000000000 +0200
***************
*** 974,979 ****
--- 974,998 ----
        </entry>
       </row>
  
+      <row>
+       <entry><structfield>attidentity</structfield></entry>
+       <entry><type>bool</type></entry>
+       <entry></entry>
+       <entry>
+        This column is an IDENTITY column.
+       </entry>
+      </row>
+ 
+      <row>
+       <entry><structfield>attgenerated</structfield></entry>
+       <entry><type>bool</type></entry>
+       <entry></entry>
+       <entry>
+        This column is defined as GENERATED ALWAYS and the
+        default value is always enforced.
+       </entry>
+      </row>
+ 
      </tbody>
     </tgroup>
    </table>
diff -dcrpN pgsql.orig/doc/src/sgml/datatype.sgml pgsql/doc/src/sgml/datatype.sgml
*** pgsql.orig/doc/src/sgml/datatype.sgml	2007-04-04 10:10:47.000000000 +0200
--- pgsql/doc/src/sgml/datatype.sgml	2007-04-04 12:57:20.000000000 +0200
*************** ALTER SEQUENCE <replaceable class="param
*** 805,810 ****
--- 805,924 ----
       will force removal of the column default expression.
      </para>
     </sect2>
+ 
+    <sect2 id="datatype-identity">
+     <title>Identity Columns</title>
+ 
+     <indexterm zone="datatype-identity">
+      <primary>identity</primary>
+     </indexterm>
+ 
+     <indexterm>
+      <primary>sequence</primary>
+      <secondary>and identity column</secondary>
+     </indexterm>
+ 
+     <para>
+      <type>Identity</type> columns are similar to the
+      pseudo data types <type>serial</type> and
+      <type>bigserial</type> but also have different properties.
+     </para>
+ 
+     <para>
+      <type>Identity</type> is not a type, but a type
+      modifier. As such,  an <type>identity</type> column isn't
+      limited to numeric types. Every type that has an implicit
+      cast from <type>int8</type> can be used as an
+      <type>identity</type> column.
+ 
+ <programlisting>
+ CREATE TABLE <replaceable class="parameter">tablename</replaceable> (
+     <replaceable class="parameter">colname</replaceable> <type>coltype</type>
+         GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY
+ );
+ </programlisting>
+ 
+      In the above example <type>coltype</type> can be e.g. float,
+      decimal or text.
+     </para>
+ 
+     <para>
+      Sequence generation options can also be specified at table creation:
+ 
+ <programlisting>
+ CREATE TABLE <replaceable class="parameter">tablename</replaceable> (
+     <replaceable class="parameter">colname</replaceable> <type>coltype</type>
+         GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [( <replaceable>sequence_options</replaceable> )]
+ );
+ </programlisting>
+ 
+      The optional <replaceable>sequence_options</replaceable>
+      are the same sequence options that can be used to
+      <command>CREATE</command> or <command>ALTER</command> a sequence.
+     </para>
+ 
+     <para>
+      For an <type>identity</type> column, either
+      <literal>GENERATED ALWAYS</literal> or
+      <literal>GENERATED BY DEFAULT</literal> can be specified.
+      The behaviour for <literal>GENERATED BY DEFAULT</literal>
+      is similar to the <type>serial</type> pseudo-type, e.g.
+      the sequence next value generation can be suppressed
+      at <command>INSERT</command> by providing an explicit value.
+      With <literal>GENERATED ALWAYS</literal>, the sequence
+      generation cannot be suppressed, the explicitly provided
+      value is ignored.
+     </para>
+ 
+     <para>
+      There can be only one <type>identity</type> column
+      in a table at any time.
+     </para>
+ 
+     <para>
+      The <type>identity</type> column in PostgreSQL conforms
+      to the SQL:2003 standard.
+     </para>
+    </sect2>
+ 
+    <sect2 id="datatype-generated">
+     <title>Generated Columns</title>
+ 
+     <indexterm zone="datatype-generated">
+      <primary>generated</primary>
+     </indexterm>
+ 
+     <para>
+      <type>Generated</type> is not a type, but a type
+      modifier. <type>Generated</type> columns are columns
+      with enforced <literal>DEFAULT</literal> values.
+      This kind of columns can be used to keep a "static" value
+      in the table whose value may depend on other columns of
+      the same row. The expression is not limited to constants
+      as with the DEFAULT clause, instead it may use the same
+      range of expressions as the CHECK clause.
+ 
+ <programlisting>
+ CREATE TABLE <replaceable class="parameter">tablename</replaceable> (
+     <replaceable class="parameter">colname</replaceable> <type>coltype</type>
+         GENERATED ALWAYS AS ( <replaceable>expression</replaceable> )
+ );
+ </programlisting>
+     </para>
+ 
+     <para>
+      The value of the <type>generated</type> column is
+      computed after all other (regular) columns are assigned
+      with their values but before the <type>identity</type>
+      column's next serial value is computed. A <type>generated</type>
+      column cannot reference other <type>generated</type> columns.
+     </para>
+ 
+     <para>
+      The <type>generated</type> column in PostgreSQL conforms
+      to the SQL:2003 standard.
+     </para>
+    </sect2>
    </sect1>
  
    <sect1 id="datatype-money">
diff -dcrpN pgsql.orig/doc/src/sgml/ref/alter_table.sgml pgsql/doc/src/sgml/ref/alter_table.sgml
*** pgsql.orig/doc/src/sgml/ref/alter_table.sgml	2007-03-23 12:16:52.000000000 +0100
--- pgsql/doc/src/sgml/ref/alter_table.sgml	2007-04-04 12:57:20.000000000 +0200
*************** where <replaceable class="PARAMETER">act
*** 36,41 ****
--- 36,43 ----
      ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> TYPE <replaceable class="PARAMETER">type</replaceable> [ USING <replaceable class="PARAMETER">expression</replaceable> ]
      ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> SET DEFAULT <replaceable class="PARAMETER">expression</replaceable>
      ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> DROP DEFAULT
+     ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> SET GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY
+     ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> DROP IDENTITY
      ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> { SET | DROP } NOT NULL
      ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> SET STATISTICS <replaceable class="PARAMETER">integer</replaceable>
      ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }
*************** where <replaceable class="PARAMETER">act
*** 124,129 ****
--- 126,152 ----
     </varlistentry>
  
     <varlistentry>
+     <term><literal>SET</literal>/<literal>GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY</literal></term>
+     <listitem>
+      <para>
+       This form "upgrades" a column that has an associated
+       sequence to an IDENTITY column. See also
+       <command>ALTER SEQUENCE ... OWNED BY</command>
+      </para>
+     </listitem>
+    </varlistentry>
+ 
+    <varlistentry>
+     <term><literal>SET</literal>/<literal>DROP IDENTITY</literal></term>
+     <listitem>
+      <para>
+       This form downgrades an IDENTITY to a regular column.
+       The column still keeps the OWNED sequence and its DEFAULT.
+      </para>
+     </listitem>
+    </varlistentry>
+ 
+    <varlistentry>
      <term><literal>SET</literal>/<literal>DROP NOT NULL</literal></term>
      <listitem>
       <para>
*************** where <replaceable class="PARAMETER">act
*** 385,390 ****
--- 408,420 ----
        (or an index, sequence, or view) or the name of an individual column in
        a table. There is no effect on the stored data.
       </para>
+ 
+      <para>
+       If the renamed column is <type>SERIAL</type> or it's an
+       <type>identity</type> column, the underlying sequence is
+       also renamed so it always tries to keep the
+       <replaceable class="PARAMETER">tablename_columnname</replaceable>_seq form.
+      </para>
      </listitem>
     </varlistentry>
  
*************** ALTER TABLE table ALTER COLUMN anycol TY
*** 688,694 ****
      drop the default with <literal>DROP DEFAULT</>, perform the <literal>ALTER
      TYPE</>, and then use <literal>SET DEFAULT</> to add a suitable new
      default.  Similar considerations apply to indexes and constraints involving
!     the column.
     </para>
  
     <para>
--- 718,725 ----
      drop the default with <literal>DROP DEFAULT</>, perform the <literal>ALTER
      TYPE</>, and then use <literal>SET DEFAULT</> to add a suitable new
      default.  Similar considerations apply to indexes and constraints involving
!     the column. Note that both SET DEFAULT and DROP DEFAULT are forbidden
!     on IDENTITY and GENERATED ALWAYS columns.
     </para>
  
     <para>
diff -dcrpN pgsql.orig/doc/src/sgml/ref/copy.sgml pgsql/doc/src/sgml/ref/copy.sgml
*** pgsql.orig/doc/src/sgml/ref/copy.sgml	2007-02-09 07:23:11.000000000 +0100
--- pgsql/doc/src/sgml/ref/copy.sgml	2007-04-04 12:57:20.000000000 +0200
*************** PostgreSQL documentation
*** 22,27 ****
--- 22,28 ----
   <refsynopsisdiv>
  <synopsis>
  COPY <replaceable class="parameter">tablename</replaceable> [ ( <replaceable class="parameter">column</replaceable> [, ...] ) ]
+     [ OVERRIDING { SYSTEM | USER } VALUE ]
      FROM { '<replaceable class="parameter">filename</replaceable>' | STDIN }
      [ [ WITH ] 
            [ BINARY ]
*************** COPY { <replaceable class="parameter">ta
*** 116,121 ****
--- 117,134 ----
     </varlistentry>
  
     <varlistentry>
+     <term><literal>OVERRIDING { SYSTEM | USER } VALUE</literal></term>
+     <listitem>
+      <para>   
+       Specifies that values override enforced default values
+       for GENERATED ALWAYS columns. Only effective for
+       <literal>COPY</literal> <replaceable class="parameter">tablename</replaceable> <literal>FROM</literal>
+       Only allowed for the owner of the table.
+      </para>
+     </listitem>
+    </varlistentry>
+ 
+    <varlistentry>
      <term><replaceable class="parameter">filename</replaceable></term>
      <listitem>
       <para>
diff -dcrpN pgsql.orig/doc/src/sgml/ref/create_table.sgml pgsql/doc/src/sgml/ref/create_table.sgml
*** pgsql.orig/doc/src/sgml/ref/create_table.sgml	2007-02-09 07:23:12.000000000 +0100
--- pgsql/doc/src/sgml/ref/create_table.sgml	2007-04-04 12:57:20.000000000 +0200
*************** PostgreSQL documentation
*** 21,27 ****
   <refsynopsisdiv>
  <synopsis>
  CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable class="PARAMETER">table_name</replaceable> ( [
!   { <replaceable class="PARAMETER">column_name</replaceable> <replaceable class="PARAMETER">data_type</replaceable> [ DEFAULT <replaceable>default_expr</> ] [ <replaceable class="PARAMETER">column_constraint</replaceable> [ ... ] ]
      | <replaceable>table_constraint</replaceable>
      | LIKE <replaceable>parent_table</replaceable> [ { INCLUDING | EXCLUDING } { DEFAULTS | CONSTRAINTS } ] ... }
      [, ... ]
--- 21,29 ----
   <refsynopsisdiv>
  <synopsis>
  CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable class="PARAMETER">table_name</replaceable> ( [
!   { <replaceable class="PARAMETER">column_name</replaceable> <replaceable class="PARAMETER">data_type</replaceable>
!     | [ DEFAULT <replaceable>default_expr</> | GENERATED ALWAYS AS (<replaceable>default_expr</replaceable> ) | GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( <replaceable>sequence_options</replaceable> ) ] ]
!     | [ <replaceable class="PARAMETER">column_constraint</replaceable> [ ... ] ]
      | <replaceable>table_constraint</replaceable>
      | LIKE <replaceable>parent_table</replaceable> [ { INCLUDING | EXCLUDING } { DEFAULTS | CONSTRAINTS } ] ... }
      [, ... ]
*************** and <replaceable class="PARAMETER">table
*** 186,191 ****
--- 188,236 ----
     </varlistentry>
  
     <varlistentry>
+     <term><literal>GENERATED ALWAYS AS (
+     <replaceable>default_expr</replaceable> ) </literal></term>
+     <listitem>   
+      <para>
+       This creates a GENERATED column. It's similar
+       to the <literal>DEFAULT</> clause, with the following
+       exceptions. In an <literal>INSERT</literal> operation the default value
+       will be enforced even when an expression is specified.
+       This can be overridden by specifying <literal>OVERRIDING SYSTEM VALUE</literal>
+       but it's only allowed for the table owner.
+       In an <literal>UPDATE</literal> statement, only
+       <literal>SET<literal> <replaceable>colname</replaceable> = <literal>DEFAULT</literal>
+       is allowed for such columns.
+      </para>
+     </listitem>
+    </varlistentry>
+ 
+    <varlistentry>
+     <term><literal>GENERATED { ALWAYS BY DEFAULT } AS IDENTITY [ (
+     <replaceable>sequence_options</replaceable> ) ]</literal></term>
+     <listitem>
+      <para>   
+       This clause creates an identity column, whose default value
+       will be generated by an automatically created sequence.
+       For the <literal>SERIAL</> pseudo-type this is implicit.
+       However, any type that has implicit cast from bigint
+       can be specified for the column.
+      </para>
+ 
+      <para>
+       With <literal>GENERATED ALWAYS AS IDENTITY</literal>, the default value
+       will always be enforced in an <literal>INSERT</literal> operation.
+       <literal>OVERRIDING SYSTEM VALUE</literal> works the same just as with <literal>GENERATED</literal> columns.
+       However, any occurence of such columns in an <literal>UPDATE</literal> statement is forbidden.
+       With this feature, one can approximate the autoincrementer type
+       that other DBMSs provide, e.g.:
+       <literal>INSERT INTO table (id, ... ) VALUES (0, ...);</literal>
+       will insert a new column with the next sequence value instead of 0.
+      </para>
+     </listitem>
+    </varlistentry>
+ 
+    <varlistentry>
      <term><literal>INHERITS ( <replaceable>parent_table</replaceable> [, ... ] )</literal></term>
      <listitem>
       <para>
diff -dcrpN pgsql.orig/doc/src/sgml/ref/insert.sgml pgsql/doc/src/sgml/ref/insert.sgml
*** pgsql.orig/doc/src/sgml/ref/insert.sgml	2007-02-09 07:23:12.000000000 +0100
--- pgsql/doc/src/sgml/ref/insert.sgml	2007-04-04 12:57:20.000000000 +0200
*************** PostgreSQL documentation
*** 21,26 ****
--- 21,27 ----
   <refsynopsisdiv>
  <synopsis>
  INSERT INTO <replaceable class="PARAMETER">table</replaceable> [ ( <replaceable class="PARAMETER">column</replaceable> [, ...] ) ]
+     [ OVERRIDING { SYSTEM | USER } VALUE ]
      { DEFAULT VALUES | VALUES ( { <replaceable class="PARAMETER">expression</replaceable> | DEFAULT } [, ...] ) [, ...] | <replaceable class="PARAMETER">query</replaceable> }
      [ RETURNING * | <replaceable class="parameter">output_expression</replaceable> [ AS <replaceable class="parameter">output_name</replaceable> ] [, ...] ]
  </synopsis>
*************** INSERT INTO <replaceable class="PARAMETE
*** 102,107 ****
--- 103,124 ----
     </varlistentry>
  
     <varlistentry>
+     <term><literal>OVERRIDING { SYSTEM | USER } VALUE</literal></term>
+     <listitem>
+      <para>   
+       The <literal>OVERRIDING SYSTEM VALUE</literal> clause can be used
+       to override default values for columns that were defined as
+       <literal>GENERATED ALWAYS</literal>. Omitting the <literal>OVERRIDING</literal> clause or
+       specifying <literal>OVERRIDING USER VALUE</literal> enforces the default value
+       for such columns. Only effective for the table owner and
+       the database superuser. It has no effect on regular columns
+       with or without <literal>DEFAULT</literal> values or
+       on <literal>GENERATED BY DEFAULT AS IDENTITY</literal> columns.
+      </para>
+     </listitem>
+    </varlistentry>
+ 
+    <varlistentry>
      <term><literal>DEFAULT VALUES</literal></term>
      <listitem>
       <para>
diff -dcrpN pgsql.orig/doc/src/sgml/ref/update.sgml pgsql/doc/src/sgml/ref/update.sgml
*** pgsql.orig/doc/src/sgml/ref/update.sgml	2007-02-09 07:23:14.000000000 +0100
--- pgsql/doc/src/sgml/ref/update.sgml	2007-04-04 12:57:20.000000000 +0200
*************** UPDATE accounts SET (contact_last_name, 
*** 340,344 ****
--- 340,351 ----
     <literal>FROM</>.  Be careful when porting applications that use this
     extension.
    </para>
+ 
+   <para>
+    UPDATE always fails for GENERATED ALWAYS AS IDENTITY columns
+    and fails for GENERATED ALWAYS AS ( expr ) columns when
+    other than the <literal>DEFAULT</literal> literal appears as
+    the expression on the right side of the assignment.
+   </para>
   </refsect1>
  </refentry>
diff -dcrpN pgsql.orig/src/backend/access/common/tupdesc.c pgsql/src/backend/access/common/tupdesc.c
*** pgsql.orig/src/backend/access/common/tupdesc.c	2007-01-10 19:58:07.000000000 +0100
--- pgsql/src/backend/access/common/tupdesc.c	2007-04-04 14:09:07.000000000 +0200
*************** CreateTupleDescCopy(TupleDesc tupdesc)
*** 142,147 ****
--- 142,149 ----
  		memcpy(desc->attrs[i], tupdesc->attrs[i], ATTRIBUTE_TUPLE_SIZE);
  		desc->attrs[i]->attnotnull = false;
  		desc->attrs[i]->atthasdef = false;
+ 		desc->attrs[i]->attidentity = false;
+ 		desc->attrs[i]->attgenerated = false;
  	}
  
  	desc->tdtypeid = tupdesc->tdtypeid;
*************** equalTupleDescs(TupleDesc tupdesc1, Tupl
*** 356,361 ****
--- 358,367 ----
  			return false;
  		if (attr1->attinhcount != attr2->attinhcount)
  			return false;
+ 		if (attr1->attidentity != attr2->attidentity)
+ 			return false;
+ 		if (attr1->attgenerated != attr2->attgenerated)
+ 			return false;
  	}
  
  	if (tupdesc1->constr != NULL)
*************** TupleDescInitEntry(TupleDesc desc,
*** 471,476 ****
--- 477,484 ----
  	att->attisdropped = false;
  	att->attislocal = true;
  	att->attinhcount = 0;
+ 	att->attidentity = false;
+ 	att->attgenerated = false;
  
  	tuple = SearchSysCache(TYPEOID,
  						   ObjectIdGetDatum(oidtypeid),
*************** BuildDescForRelation(List *schema)
*** 564,569 ****
--- 572,579 ----
  			attrdef[ndef].adbin = pstrdup(entry->cooked_default);
  			ndef++;
  			desc->attrs[attnum - 1]->atthasdef = true;
+ 			desc->attrs[attnum - 1]->attidentity = entry->is_identity;
+ 			desc->attrs[attnum - 1]->attgenerated = entry->is_generated;
  		}
  
  		desc->attrs[attnum - 1]->attislocal = entry->is_local;
diff -dcrpN pgsql.orig/src/backend/catalog/heap.c pgsql/src/backend/catalog/heap.c
*** pgsql.orig/src/backend/catalog/heap.c	2007-04-04 10:11:07.000000000 +0200
--- pgsql/src/backend/catalog/heap.c	2007-04-04 12:57:20.000000000 +0200
*************** RemoveAttrDefaultById(Oid attrdefId)
*** 1199,1204 ****
--- 1199,1206 ----
  			 myattnum, myrelid);
  
  	((Form_pg_attribute) GETSTRUCT(tuple))->atthasdef = false;
+ 	((Form_pg_attribute) GETSTRUCT(tuple))->attidentity = false;
+ 	((Form_pg_attribute) GETSTRUCT(tuple))->attgenerated = false;
  
  	simple_heap_update(attr_rel, &tuple->t_self, tuple);
  
*************** heap_drop_with_catalog(Oid relid)
*** 1292,1298 ****
   * The expression must be presented as a nodeToString() string.
   */
  void
! StoreAttrDefault(Relation rel, AttrNumber attnum, char *adbin)
  {
  	Node	   *expr;
  	char	   *adsrc;
--- 1294,1300 ----
   * The expression must be presented as a nodeToString() string.
   */
  void
! StoreAttrDefault(Relation rel, AttrNumber attnum, char *adbin, bool attidentity, bool attgenerated)
  {
  	Node	   *expr;
  	char	   *adsrc;
*************** StoreAttrDefault(Relation rel, AttrNumbe
*** 1306,1311 ****
--- 1308,1314 ----
  	Oid			attrdefOid;
  	ObjectAddress colobject,
  				defobject;
+ 	List	   *rtable;
  
  	/*
  	 * Need to construct source equivalent of given node-string.
*************** StoreAttrDefault(Relation rel, AttrNumbe
*** 1365,1370 ****
--- 1368,1375 ----
  	if (!attStruct->atthasdef)
  	{
  		attStruct->atthasdef = true;
+ 		attStruct->attidentity = attidentity;
+ 		attStruct->attgenerated = attgenerated;
  		simple_heap_update(attrrel, &atttup->t_self, atttup);
  		/* keep catalog indexes current */
  		CatalogUpdateIndexes(attrrel, atttup);
*************** StoreAttrDefault(Relation rel, AttrNumbe
*** 1385,1391 ****
  	/*
  	 * Record dependencies on objects used in the expression, too.
  	 */
! 	recordDependencyOnExpr(&defobject, expr, NIL, DEPENDENCY_NORMAL);
  }
  
  /*
--- 1390,1412 ----
  	/*
  	 * Record dependencies on objects used in the expression, too.
  	 */
! 	if (!attidentity && attgenerated)
! 	{
! 		ParseState *pstate;
! 		RangeTblEntry	*rte;
! 
! 		pstate = make_parsestate(NULL);
! 		rte = addRangeTableEntryForRelation(pstate,
! 										rel,
! 										NULL,
! 										false,
! 										true);
! 		addRTEtoQuery(pstate, rte, true, true, true);
! 		rtable = list_make1(rte);
! 	}
! 	else
! 		rtable = NIL;
! 	recordDependencyOnExpr(&defobject, expr, rtable, DEPENDENCY_NORMAL);
  }
  
  /*
*************** StoreConstraints(Relation rel, TupleDesc
*** 1504,1510 ****
  
  	for (i = 0; i < constr->num_defval; i++)
  		StoreAttrDefault(rel, constr->defval[i].adnum,
! 						 constr->defval[i].adbin);
  
  	for (i = 0; i < constr->num_check; i++)
  		StoreRelCheck(rel, constr->check[i].ccname,
--- 1525,1533 ----
  
  	for (i = 0; i < constr->num_defval; i++)
  		StoreAttrDefault(rel, constr->defval[i].adnum,
! 						 constr->defval[i].adbin,
! 						 rel->rd_att->attrs[constr->defval[i].adnum - 1]->attidentity,
! 						 rel->rd_att->attrs[constr->defval[i].adnum - 1]->attgenerated);
  
  	for (i = 0; i < constr->num_check; i++)
  		StoreRelCheck(rel, constr->check[i].ccname,
*************** AddRelationRawConstraints(Relation rel,
*** 1554,1559 ****
--- 1577,1584 ----
  	ListCell   *cell;
  	Node	   *expr;
  	CookedConstraint *cooked;
+ 	int			varno;
+ 	int			sublevels_up;
  
  	/*
  	 * Get info about existing constraints.
*************** AddRelationRawConstraints(Relation rel,
*** 1584,1601 ****
  	{
  		RawColumnDefault *colDef = (RawColumnDefault *) lfirst(cell);
  		Form_pg_attribute atp = rel->rd_att->attrs[colDef->attnum - 1];
  
  		expr = cookDefault(pstate, colDef->raw_default,
  						   atp->atttypid, atp->atttypmod,
! 						   NameStr(atp->attname));
  
! 		StoreAttrDefault(rel, colDef->attnum, nodeToString(expr));
  
  		cooked = (CookedConstraint *) palloc(sizeof(CookedConstraint));
  		cooked->contype = CONSTR_DEFAULT;
  		cooked->name = NULL;
  		cooked->attnum = colDef->attnum;
  		cooked->expr = expr;
  		cookedConstraints = lappend(cookedConstraints, cooked);
  	}
  
--- 1609,1659 ----
  	{
  		RawColumnDefault *colDef = (RawColumnDefault *) lfirst(cell);
  		Form_pg_attribute atp = rel->rd_att->attrs[colDef->attnum - 1];
+ 		int		attnum;
  
  		expr = cookDefault(pstate, colDef->raw_default,
  						   atp->atttypid, atp->atttypmod,
! 						   NameStr(atp->attname),
! 						   !colDef->is_identity && colDef->is_generated);
  
! 		varno = RTERangeTablePosn(pstate, rte, &sublevels_up);
! 
! 		if (!colDef->is_identity && colDef->is_generated)
! 		{
! 			varno = RTERangeTablePosn(pstate, rte, &sublevels_up);
! 
! 			for (attnum = 1; attnum <= tupleDesc->natts; attnum++)
! 			{
! 				if (tupleDesc->attrs[attnum - 1]->attisdropped)
! 					continue;
! 				if (tupleDesc->attrs[attnum - 1]->attgenerated &&
! 					!tupleDesc->attrs[attnum - 1]->attidentity)
! 				{
! 					Node *var;
! 
! 					var = scanRTEForColumn(pstate,
! 								rte,
! 								NameStr(tupleDesc->attrs[attnum - 1]->attname),
! 								-1);
! 					if (contain_var_reference(expr, varno, ((Var *)var)->varattno, sublevels_up))
! 						ereport(ERROR,
! 							(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
! 							 errmsg("GENERATED column \"%s\" of table \"%s\" cannot be referenced by GENERATED column \"%s\"",
! 								get_attname(RelationGetRelid(rel), attnum),
! 								RelationGetRelationName(rel),
! 								get_attname(RelationGetRelid(rel), colDef->attnum))));
! 				}
! 			}
! 		}
! 
! 		StoreAttrDefault(rel, colDef->attnum, nodeToString(expr), colDef->is_identity, colDef->is_generated);
  
  		cooked = (CookedConstraint *) palloc(sizeof(CookedConstraint));
  		cooked->contype = CONSTR_DEFAULT;
  		cooked->name = NULL;
  		cooked->attnum = colDef->attnum;
  		cooked->expr = expr;
+ 		cooked->is_generated = colDef->is_generated;
  		cookedConstraints = lappend(cookedConstraints, cooked);
  	}
  
*************** cookDefault(ParseState *pstate,
*** 1799,1805 ****
  			Node *raw_default,
  			Oid atttypid,
  			int32 atttypmod,
! 			char *attname)
  {
  	Node	   *expr;
  
--- 1857,1864 ----
  			Node *raw_default,
  			Oid atttypid,
  			int32 atttypmod,
! 			char *attname,
! 			bool is_generated)
  {
  	Node	   *expr;
  
*************** cookDefault(ParseState *pstate,
*** 1813,1819 ****
  	/*
  	 * Make sure default expr does not refer to any vars.
  	 */
! 	if (contain_var_clause(expr))
  		ereport(ERROR,
  				(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
  			  errmsg("cannot use column references in default expression")));
--- 1872,1878 ----
  	/*
  	 * Make sure default expr does not refer to any vars.
  	 */
! 	if (!is_generated && contain_var_clause(expr))
  		ereport(ERROR,
  				(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
  			  errmsg("cannot use column references in default expression")));
diff -dcrpN pgsql.orig/src/backend/catalog/index.c pgsql/src/backend/catalog/index.c
*** pgsql.orig/src/backend/catalog/index.c	2007-03-30 09:33:53.000000000 +0200
--- pgsql/src/backend/catalog/index.c	2007-04-04 12:57:20.000000000 +0200
*************** ConstructTupleDescriptor(Relation heapRe
*** 166,171 ****
--- 166,173 ----
  			to->atthasdef = false;
  			to->attislocal = true;
  			to->attinhcount = 0;
+ 			to->attidentity = false;
+ 			to->attgenerated = false;
  		}
  		else
  		{
diff -dcrpN pgsql.orig/src/backend/commands/copy.c pgsql/src/backend/commands/copy.c
*** pgsql.orig/src/backend/commands/copy.c	2007-03-30 09:33:54.000000000 +0200
--- pgsql/src/backend/commands/copy.c	2007-04-04 14:20:49.000000000 +0200
***************
*** 40,45 ****
--- 40,46 ----
  #include "utils/builtins.h"
  #include "utils/lsyscache.h"
  #include "utils/memutils.h"
+ #include "utils/rel.h"
  
  
  #define ISOCTAL(c) (((c) >= '0') && ((c) <= '7'))
*************** typedef struct CopyStateData
*** 103,108 ****
--- 104,110 ----
  	QueryDesc  *queryDesc;		/* executable query to copy from */
  	List	   *attnumlist;		/* integer list of attnums to copy */
  	char	   *filename;		/* filename, or NULL for STDIN/STDOUT */
+ 	bool		overriding;		/* OVERRIDING SYSTEM VALUE */
  	bool		binary;			/* binary format? */
  	bool		oids;			/* include OIDs? */
  	bool		csv_mode;		/* Comma Separated Value format? */
*************** DoCopy(const CopyStmt *stmt, const char 
*** 1124,1129 ****
--- 1126,1132 ----
  
  	cstate->copy_dest = COPY_FILE;		/* default */
  	cstate->filename = stmt->filename;
+ 	cstate->overriding = stmt->overriding;	/* OVERRIDING SYSTEM VALUE */
  
  	if (is_from)
  		CopyFrom(cstate);		/* copy from file to database */
*************** CopyFrom(CopyState cstate)
*** 1626,1631 ****
--- 1629,1635 ----
  	Oid			in_func_oid;
  	Datum	   *values;
  	char	   *nulls;
+ 	char	   *replace;
  	int			nfields;
  	char	  **field_strings;
  	bool		done = false;
*************** CopyFrom(CopyState cstate)
*** 1642,1647 ****
--- 1646,1652 ----
  	CommandId	mycid = GetCurrentCommandId();
  	bool		use_wal = true;		/* by default, use WAL logging */
  	bool		use_fsm = true;		/* by default, use FSM for free space */
+ 	bool		hasgenerated;
  
  	Assert(cstate->rel);
  
*************** CopyFrom(CopyState cstate)
*** 1765,1770 ****
--- 1770,1776 ----
  	slot = MakeSingleTupleTableSlot(tupDesc);
  
  	econtext = GetPerTupleExprContext(estate);
+ 	econtext->ecxt_scantuple = slot;
  
  	/*
  	 * Pick up the required catalog information for each attribute in the
*************** CopyFrom(CopyState cstate)
*** 1777,1782 ****
--- 1783,1789 ----
  	defmap = (int *) palloc(num_phys_attrs * sizeof(int));
  	defexprs = (ExprState **) palloc(num_phys_attrs * sizeof(ExprState *));
  
+ 	hasgenerated = false;
  	for (attnum = 1; attnum <= num_phys_attrs; attnum++)
  	{
  		/* We don't need info for dropped attributes */
*************** CopyFrom(CopyState cstate)
*** 1793,1799 ****
  		fmgr_info(in_func_oid, &in_functions[attnum - 1]);
  
  		/* Get default info if needed */
! 		if (!list_member_int(cstate->attnumlist, attnum))
  		{
  			/* attribute is NOT to be copied from input */
  			/* use default value if one exists */
--- 1800,1808 ----
  		fmgr_info(in_func_oid, &in_functions[attnum - 1]);
  
  		/* Get default info if needed */
! 		if (!list_member_int(cstate->attnumlist, attnum) ||
! 			attr[attnum - 1]->attidentity ||
! 			attr[attnum - 1]->attgenerated)
  		{
  			/* attribute is NOT to be copied from input */
  			/* use default value if one exists */
*************** CopyFrom(CopyState cstate)
*** 1806,1811 ****
--- 1815,1823 ----
  				defmap[num_defaults] = attnum - 1;
  				num_defaults++;
  			}
+ 
+ 			hasgenerated |= attr[attnum - 1]->attgenerated &&
+ 					!attr[attnum - 1]->attidentity;
  		}
  	}
  
*************** CopyFrom(CopyState cstate)
*** 1870,1875 ****
--- 1882,1888 ----
  
  	values = (Datum *) palloc(num_phys_attrs * sizeof(Datum));
  	nulls = (char *) palloc(num_phys_attrs * sizeof(char));
+ 	replace = (char *) palloc(num_phys_attrs * sizeof(char));
  
  	/* create workspace for CopyReadAttributes results */
  	nfields = file_has_oids ? (attr_count + 1) : attr_count;
*************** CopyFrom(CopyState cstate)
*** 2060,2069 ****
  		/*
  		 * Now compute and insert any defaults available for the columns not
  		 * provided by the input data.	Anything not processed here or above
! 		 * will remain NULL.
  		 */
  		for (i = 0; i < num_defaults; i++)
  		{
  			values[defmap[i]] = ExecEvalExpr(defexprs[i], econtext,
  											 &isnull, NULL);
  			if (!isnull)
--- 2073,2091 ----
  		/*
  		 * Now compute and insert any defaults available for the columns not
  		 * provided by the input data.	Anything not processed here or above
! 		 * will remain NULL. Skip GENERATED fields until the next phase.
! 		 * Skip the IDENTITY field if the stream contains non-NULL value
! 		 * and we got OVERRIDING SYSTEM VALUE.
  		 */
  		for (i = 0; i < num_defaults; i++)
  		{
+ 			if (attr[defmap[i]]->attgenerated &&
+ 				!attr[defmap[i]]->attidentity)
+ 				continue;
+ 			if (attr[defmap[i]]->attidentity &&
+ 				nulls[defmap[i]] == ' ' &&
+ 				cstate->overriding)
+ 				continue;
  			values[defmap[i]] = ExecEvalExpr(defexprs[i], econtext,
  											 &isnull, NULL);
  			if (!isnull)
*************** CopyFrom(CopyState cstate)
*** 2073,2078 ****
--- 2095,2127 ----
  		/* And now we can form the input tuple. */
  		tuple = heap_formtuple(tupDesc, values, nulls);
  
+ 		/*
+ 		 * Generate DEFAULTs for GENERATED columns after all regular columns.
+ 		 */
+ 		if (hasgenerated)
+ 		{
+ 			ExecStoreTuple(tuple, slot, InvalidBuffer, false);
+ 			MemSet(replace, ' ', num_phys_attrs * sizeof(char));
+ 			for (i = 0; i < num_defaults; i++)
+ 			{
+ 				if (attr[defmap[i]]->attgenerated &&
+ 					!attr[defmap[i]]->attidentity &&
+ 					(!cstate->overriding || nulls[defmap[i]] == 'n'))
+ 				{
+ 					values[defmap[i]] = ExecEvalExpr(defexprs[i], econtext,
+ 											 &isnull, NULL);
+ 					if (!isnull)
+ 						nulls[defmap[i]] = ' ';
+ 					replace[defmap[i]] = 'r';
+ 				}
+ 			}
+ 			tuple = heap_modifytuple(tuple,
+ 							tupDesc,
+ 							values,
+ 							nulls,
+ 							replace);
+ 		}
+ 
  		if (cstate->oids && file_has_oids)
  			HeapTupleSetOid(tuple, loaded_oid);
  
*************** CopyFrom(CopyState cstate)
*** 2138,2143 ****
--- 2187,2193 ----
  
  	pfree(values);
  	pfree(nulls);
+ 	pfree(replace);
  	pfree(field_strings);
  
  	pfree(in_functions);
diff -dcrpN pgsql.orig/src/backend/commands/sequence.c pgsql/src/backend/commands/sequence.c
*** pgsql.orig/src/backend/commands/sequence.c	2007-02-09 07:23:21.000000000 +0100
--- pgsql/src/backend/commands/sequence.c	2007-04-04 14:24:03.000000000 +0200
*************** DefineSequence(CreateSeqStmt *seq)
*** 129,134 ****
--- 129,136 ----
  		coldef->raw_default = NULL;
  		coldef->cooked_default = NULL;
  		coldef->constraints = NIL;
+ 		coldef->is_identity = false;
+ 		coldef->is_generated = false;
  
  		null[i - 1] = ' ';
  
diff -dcrpN pgsql.orig/src/backend/commands/tablecmds.c pgsql/src/backend/commands/tablecmds.c
*** pgsql.orig/src/backend/commands/tablecmds.c	2007-03-23 12:17:08.000000000 +0100
--- pgsql/src/backend/commands/tablecmds.c	2007-04-04 12:57:20.000000000 +0200
***************
*** 34,39 ****
--- 34,40 ----
  #include "catalog/toasting.h"
  #include "commands/cluster.h"
  #include "commands/defrem.h"
+ #include "commands/sequence.h"
  #include "commands/tablecmds.h"
  #include "commands/tablespace.h"
  #include "commands/trigger.h"
***************
*** 44,49 ****
--- 45,51 ----
  #include "optimizer/clauses.h"
  #include "optimizer/plancat.h"
  #include "optimizer/prep.h"
+ #include "optimizer/var.h"
  #include "parser/analyze.h"
  #include "parser/gramparse.h"
  #include "parser/parse_clause.h"
*************** static void StoreCatalogInheritance1(Oid
*** 174,179 ****
--- 176,182 ----
  						 int16 seqNumber, Relation inhRelation);
  static int	findAttrByName(const char *attributeName, List *schema);
  static void setRelhassubclassInRelation(Oid relationId, bool relhassubclass);
+ static void renameseqfor(Oid tableOid, const char *newrelname, const char *oldattname, const char *newattname);
  static void AlterIndexNamespaces(Relation classRel, Relation rel,
  					 Oid oldNspOid, Oid newNspOid);
  static void AlterSeqNamespaces(Relation classRel, Relation rel,
*************** static void ATExecEnableDisableRule(Rela
*** 259,264 ****
--- 262,269 ----
  						   char fires_when);
  static void ATExecAddInherit(Relation rel, RangeVar *parent);
  static void ATExecDropInherit(Relation rel, RangeVar *parent);
+ static void ATExecAlterSeq(Relation rel, char *column, List *seq_opts);
+ static void ATExecIdentity(Relation rel, char *column, bool is_identity, bool is_generated);
  static void copy_relation_data(Relation rel, SMgrRelation dst);
  
  
*************** DefineRelation(CreateStmt *stmt, char re
*** 287,292 ****
--- 292,298 ----
  	Datum		reloptions;
  	ListCell   *listptr;
  	AttrNumber	attnum;
+ 	int		identity_count;
  
  	/*
  	 * Truncate relname to appropriate length (probably a waste of time, as
*************** DefineRelation(CreateStmt *stmt, char re
*** 366,371 ****
--- 372,392 ----
  							 stmt->relation->istemp,
  							 &inheritOids, &old_constraints, &parentOidCount);
  
+ 	identity_count = 0;
+ 	foreach(listptr, schema)
+ 	{
+ 		ColumnDef  *colDef = lfirst(listptr);
+ 
+ 		if (colDef->is_identity)
+ 		{
+ 			identity_count++;
+ 			if (identity_count > 1)
+ 				ereport(ERROR,
+ 						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ 						 errmsg("multiple IDENTITY columns are not allowed")));
+ 		}
+ 	}
+ 
  	/*
  	 * Create a relation descriptor from the relation schema and create the
  	 * relation.  Note that in this stage only inherited (pre-cooked) defaults
*************** DefineRelation(CreateStmt *stmt, char re
*** 480,485 ****
--- 501,508 ----
  			rawEnt = (RawColumnDefault *) palloc(sizeof(RawColumnDefault));
  			rawEnt->attnum = attnum;
  			rawEnt->raw_default = colDef->raw_default;
+ 			rawEnt->is_identity = colDef->is_identity;
+ 			rawEnt->is_generated = colDef->is_generated;
  			rawDefaults = lappend(rawDefaults, rawEnt);
  		}
  	}
*************** MergeAttributes(List *schema, List *supe
*** 931,936 ****
--- 954,961 ----
  				def->raw_default = NULL;
  				def->cooked_default = NULL;
  				def->constraints = NIL;
+ 				def->is_identity = false;
+ 				def->is_generated = false;
  				inhSchema = lappend(inhSchema, def);
  				newattno[parent_attno - 1] = ++child_attno;
  			}
*************** MergeAttributes(List *schema, List *supe
*** 975,980 ****
--- 1000,1007 ----
  					def->cooked_default = bogus_marker;
  					have_bogus_defaults = true;
  				}
+ 				def->is_identity = attribute->attidentity;
+ 				def->is_generated = attribute->attgenerated;
  			}
  		}
  
*************** MergeAttributes(List *schema, List *supe
*** 1065,1070 ****
--- 1092,1099 ----
  				{
  					def->raw_default = newdef->raw_default;
  					def->cooked_default = newdef->cooked_default;
+ 					def->is_identity = newdef->is_identity;
+ 					def->is_generated = newdef->is_generated;
  				}
  			}
  			else
*************** setRelhassubclassInRelation(Oid relation
*** 1409,1414 ****
--- 1438,1471 ----
  }
  
  
+ static void renameseqfor(Oid tableOid, const char *newrelname, const char *oldattname, const char *newattname)
+ {
+ 	int		attnum;
+ 	Oid		sequenceId;
+ 
+ 	if (!newrelname)
+ 		newrelname = get_rel_name(tableOid);
+ 	attnum = get_attnum(tableOid, oldattname);
+ 	if (attnum == InvalidAttrNumber)
+ 		return;
+ 
+ 	sequenceId = get_relid_att_serial_sequence(tableOid, attnum);
+ 
+ 	if (OidIsValid(sequenceId))
+ 	{
+ 		char		*sname;
+ 
+ 		sname = ChooseRelationName(newrelname,
+ 							newattname,
+ 							"seq",
+ 							get_rel_namespace(sequenceId));
+ 		renamerel(sequenceId, sname);
+ 		ereport(NOTICE,
+ 				(errmsg("supporting sequence for column \"%s\" renamed to \"%s\"", newattname, sname)));
+ 		pfree(sname);
+ 	}
+ }
+ 
  /*
   *		renameatt		- changes the name of a attribute in a relation
   *
*************** renameatt(Oid myrelid,
*** 1611,1616 ****
--- 1668,1679 ----
  	heap_close(attrelation, RowExclusiveLock);
  
  	relation_close(targetrelation, NoLock);		/* close rel but keep lock */
+ 
+ 	/*
+ 	 * Also rename the underlying sequence
+ 	 * if this column is SERIAL or GENERATED AS IDENTITY.
+ 	 */
+ 	renameseqfor(myrelid, NULL, oldattname, newattname);
  }
  
  /*
*************** renamerel(Oid myrelid, const char *newre
*** 1632,1637 ****
--- 1695,1701 ----
  	char	   *oldrelname;
  	char		relkind;
  	bool		relhastriggers;
+ 	int		idx;
  
  	/*
  	 * Grab an exclusive lock on the target table or index, which we will NOT
*************** renamerel(Oid myrelid, const char *newre
*** 1679,1684 ****
--- 1743,1757 ----
  	/* keep the system catalog indexes current */
  	CatalogUpdateIndexes(relrelation, reltup);
  
+ 	for (idx = 0; idx < targetrelation->rd_att->natts; idx++)
+ 	{
+ 		char	*attname;
+ 		if (targetrelation->rd_att->attrs[idx]->attisdropped)
+ 			continue;
+ 		attname = NameStr(targetrelation->rd_att->attrs[idx]->attname);
+ 		renameseqfor(myrelid, newrelname, attname, attname);
+ 	}
+ 
  	heap_freetuple(reltup);
  	heap_close(relrelation, RowExclusiveLock);
  
*************** ATPrepCmd(List **wqueue, Relation rel, A
*** 1971,1976 ****
--- 2044,2052 ----
  		case AT_DisableRule:
  		case AT_AddInherit:		/* INHERIT / NO INHERIT */
  		case AT_DropInherit:
+ 		case AT_SetSeqOpts:
+ 		case AT_SetIdentity:
+ 		case AT_DropIdentity:
  			ATSimplePermissions(rel, false);
  			/* These commands never recurse */
  			/* No command-specific prep needed */
*************** ATExecCmd(AlteredTableInfo *tab, Relatio
*** 2193,2198 ****
--- 2269,2283 ----
  		case AT_DropInherit:
  			ATExecDropInherit(rel, (RangeVar *) cmd->def);
  			break;
+ 		case AT_SetSeqOpts:
+ 			ATExecAlterSeq(rel, cmd->name, (List *)cmd->def);
+ 			break;
+ 		case AT_SetIdentity:
+ 			ATExecIdentity(rel, cmd->name, true, cmd->is_generated);
+ 			break;
+ 		case AT_DropIdentity:
+ 			ATExecIdentity(rel, cmd->name, false, false);
+ 			break;
  		default:				/* oops */
  			elog(ERROR, "unrecognized alter table type: %d",
  				 (int) cmd->subtype);
*************** ATExecAddColumn(AlteredTableInfo *tab, R
*** 2952,2957 ****
--- 3037,3052 ----
  	Form_pg_type tform;
  	Expr	   *defval;
  
+ 	if (colDef->is_identity)
+ 	{
+ 		for (i = 0; i < rel->rd_att->natts; i++)
+ 			if (rel->rd_att->attrs[i]->attidentity)
+ 				ereport(ERROR,
+ 						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ 						 errmsg("multiple IDENTITY columns are not allowed")));
+ 
+ 	}
+ 
  	attrdesc = heap_open(AttributeRelationId, RowExclusiveLock);
  
  	/*
*************** ATExecAddColumn(AlteredTableInfo *tab, R
*** 3059,3064 ****
--- 3154,3161 ----
  	attribute->attisdropped = false;
  	attribute->attislocal = colDef->is_local;
  	attribute->attinhcount = colDef->inhcount;
+ 	attribute->attidentity = colDef->is_identity;
+ 	attribute->attgenerated = colDef->is_generated;
  
  	ReleaseSysCache(typeTuple);
  
*************** ATExecAddColumn(AlteredTableInfo *tab, R
*** 3096,3101 ****
--- 3193,3200 ----
  		rawEnt = (RawColumnDefault *) palloc(sizeof(RawColumnDefault));
  		rawEnt->attnum = attribute->attnum;
  		rawEnt->raw_default = copyObject(colDef->raw_default);
+ 		rawEnt->is_identity = colDef->is_identity;
+ 		rawEnt->is_generated = colDef->is_generated;
  
  		/*
  		 * This function is intended for CREATE TABLE, so it processes a
*************** ATExecColumnDefault(Relation rel, const 
*** 3353,3358 ****
--- 3452,3469 ----
  				 errmsg("cannot alter system column \"%s\"",
  						colName)));
  
+ 	if (rel->rd_att->attrs[attnum - 1]->attidentity)
+ 		ereport(ERROR,
+ 				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ 				 errmsg("cannot alter IDENTITY column \"%s\"",
+ 						colName)));
+ 
+ 	if (rel->rd_att->attrs[attnum - 1]->attgenerated)
+ 		ereport(ERROR,
+ 				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ 				 errmsg("cannot alter GENERATED ALWAYS column \"%s\"",
+ 						colName)));
+ 
  	/*
  	 * Remove any old default for the column.  We use RESTRICT here for
  	 * safety, but at present we do not expect anything to depend on the
*************** ATExecColumnDefault(Relation rel, const 
*** 3368,3373 ****
--- 3479,3486 ----
  		rawEnt = (RawColumnDefault *) palloc(sizeof(RawColumnDefault));
  		rawEnt->attnum = attnum;
  		rawEnt->raw_default = newDefault;
+ 		rawEnt->is_identity = false;
+ 		rawEnt->is_generated = false;
  
  		/*
  		 * This function is intended for CREATE TABLE, so it processes a
*************** ATExecDropColumn(Relation rel, const cha
*** 3549,3554 ****
--- 3662,3668 ----
  				 DropBehavior behavior,
  				 bool recurse, bool recursing)
  {
+ 	TupleDesc	tupleDesc;
  	HeapTuple	tuple;
  	Form_pg_attribute targetatt;
  	AttrNumber	attnum;
*************** ATExecDropColumn(Relation rel, const cha
*** 3678,3683 ****
--- 3792,3851 ----
  	}
  
  	/*
+ 	 * Check for GENERATED columns that reference this column
+ 	 */
+ 	tupleDesc = RelationGetDescr(rel);
+ 	if (attnum >= 1 &&
+ 		!tupleDesc->attrs[attnum - 1]->attidentity &&
+ 		!tupleDesc->attrs[attnum - 1]->attgenerated)
+ 	{
+ 		ParseState *pstate;
+ 		RangeTblEntry *rte;
+ 		int		gen_attnum;
+ 		int		varno;
+ 		int		sublevels_up;
+ 
+ 		pstate = make_parsestate(NULL);
+ 		rte = addRangeTableEntryForRelation(pstate,
+ 								rel,
+ 								NULL,
+ 								false,
+ 								true);
+ 		addRTEtoQuery(pstate, rte, true, true, true);
+ 		varno = RTERangeTablePosn(pstate, rte, &sublevels_up);
+ 
+ 		for (gen_attnum = 1; gen_attnum <= tupleDesc->natts; gen_attnum++)
+ 		{
+ 			if (tupleDesc->attrs[gen_attnum - 1]->attisdropped)
+ 				continue;
+ 			if (tupleDesc->attrs[gen_attnum - 1]->attgenerated &&
+ 				!tupleDesc->attrs[gen_attnum - 1]->attidentity)
+ 			{
+ 				Node	*expr;
+ 				Node	*var;
+ 				expr = build_column_default(rel, gen_attnum);
+ 				var = scanRTEForColumn(pstate,
+ 								rte,
+ 								NameStr(tupleDesc->attrs[attnum - 1]->attname),
+ 								-1);
+ 				if (contain_var_reference(expr, varno, ((Var *)var)->varattno, sublevels_up))
+ 				{
+ 					ereport(NOTICE,
+ 							(errcode(ERRCODE_WARNING),
+ 							 errmsg("GENERATED column \"%s\" of relation \"%s\" referencing column \"%s\" was dropped",
+ 								NameStr(tupleDesc->attrs[gen_attnum - 1]->attname),
+ 								RelationGetRelationName(rel),
+ 								colName)));
+ 					ATExecDropColumn(rel,
+ 								NameStr(tupleDesc->attrs[gen_attnum - 1]->attname),
+ 					                        DROP_CASCADE,
+ 					                        false, false);
+ 				}
+ 			}
+ 		}
+ 	}
+ 
+ 	/*
  	 * Perform the actual column deletion
  	 */
  	object.classId = RelationRelationId;
*************** ATExecAlterColumnType(AlteredTableInfo *
*** 4837,4842 ****
--- 5005,5012 ----
  	ScanKeyData key[3];
  	SysScanDesc scan;
  	HeapTuple	depTup;
+ 	bool		attidentity;
+ 	bool		attgenerated;
  
  	attrelation = heap_open(AttributeRelationId, RowExclusiveLock);
  
*************** ATExecAlterColumnType(AlteredTableInfo *
*** 4894,4899 ****
--- 5064,5071 ----
  	}
  	else
  		defaultexpr = NULL;
+ 	attidentity = attTup->attidentity;
+ 	attgenerated = attTup->attgenerated;
  
  	/*
  	 * Find everything that depends on the column (constraints, indexes, etc),
*************** ATExecAlterColumnType(AlteredTableInfo *
*** 5142,5148 ****
  		 */
  		RemoveAttrDefault(RelationGetRelid(rel), attnum, DROP_RESTRICT, true);
  
! 		StoreAttrDefault(rel, attnum, nodeToString(defaultexpr));
  	}
  
  	/* Cleanup */
--- 5314,5320 ----
  		 */
  		RemoveAttrDefault(RelationGetRelid(rel), attnum, DROP_RESTRICT, true);
  
! 		StoreAttrDefault(rel, attnum, nodeToString(defaultexpr), attidentity, attgenerated);
  	}
  
  	/* Cleanup */
*************** decompile_conbin(HeapTuple contup, Tuple
*** 6080,6085 ****
--- 6252,6415 ----
  }
  
  /*
+  * ALTER TABLE RESTART WITH / SET sequence_options
+  */
+ static void
+ ATExecAlterSeq(Relation rel, char *column, List *seq_opts)
+ {
+ 	Oid		tableOid;
+ 	AttrNumber	attnum;
+ 	Oid		sequenceId;
+ 
+ 	tableOid = RelationGetRelid(rel);
+ 	attnum = get_attnum(tableOid, column);
+ 
+ 	if (attnum == InvalidAttrNumber)
+ 		ereport(ERROR,
+ 				(errcode(ERRCODE_UNDEFINED_COLUMN),
+ 				 errmsg("column \"%s\" of relation \"%s\" does not exist",
+ 						column, RelationGetRelationName(rel))));
+ 
+ 	sequenceId = get_relid_att_serial_sequence(tableOid, attnum);
+ 	if (OidIsValid(sequenceId))
+ 	{
+ 		HeapTuple	seqtup;
+ 
+ 		seqtup = SearchSysCache(RELOID,
+ 						ObjectIdGetDatum(sequenceId),
+ 						0, 0, 0);
+ 		if (HeapTupleIsValid(seqtup))
+ 		{
+ 			Form_pg_class seq = (Form_pg_class) GETSTRUCT(seqtup);
+ 			HeapTuple	nsptup;
+ 			RangeVar   *rv = NULL;
+ 
+ 			nsptup = SearchSysCache(NAMESPACEOID,
+ 							ObjectIdGetDatum(seq->relnamespace),
+ 							0, 0, 0);
+ 			if (HeapTupleIsValid(nsptup))
+ 			{
+ 				Form_pg_namespace nsp = (Form_pg_namespace) GETSTRUCT(nsptup);
+ 				rv = makeRangeVar(NameStr(nsp->nspname), NameStr(seq->relname));
+ 				ReleaseSysCache(nsptup);
+ 			}
+ 
+ 			ReleaseSysCache(seqtup);
+ 
+ 			if (rv != NULL)
+ 			{
+ 				AlterSeqStmt	*newcmd;
+ 				
+ 				newcmd = makeNode(AlterSeqStmt);
+ 				newcmd->sequence = rv;
+ 				newcmd->options = seq_opts;
+ 				AlterSequence(newcmd);
+ 				pfree(newcmd);
+ 				pfree(rv);
+ 			}
+ 		}
+ 	} else
+ 		ereport(ERROR,
+ 				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ 				 errmsg("column \"%s\" of relation \"%s\" is not an IDENTITY or SERIAL column",
+ 						column, RelationGetRelationName(rel))));
+ }
+ 
+ static void
+ ATExecIdentity(Relation rel, char *column, bool is_identity, bool is_generated)
+ {
+ 	Oid		tableOid;
+ 	Relation	tableRel;
+ 	AttrNumber	idattnum;
+ 	Oid		sequenceId;
+ 	TupleDesc	tupleDesc;
+ 	Relation	attrelation;
+ 	HeapTuple	atttup;
+ 	Form_pg_attribute attform;
+ 	int		attnum;
+ 
+ 	tableOid = RelationGetRelid(rel);
+ 	tableRel = heap_open(tableOid, AccessExclusiveLock);
+ 
+ 	attrelation = heap_open(AttributeRelationId, RowExclusiveLock);
+ 
+ 	atttup = SearchSysCacheCopyAttName(tableOid, column);
+ 	if (!HeapTupleIsValid(atttup))
+ 		ereport(ERROR,
+ 				(errcode(ERRCODE_UNDEFINED_COLUMN),
+ 				 errmsg("column \"%s\" of relation \"%s\" does not exist",
+ 						column, RelationGetRelationName(rel))));
+ 
+ 	attform = (Form_pg_attribute) GETSTRUCT(atttup);
+ 
+ 	idattnum = attform->attnum;
+ 	if (idattnum <= 0)
+ 		ereport(ERROR,
+ 				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ 				 errmsg("cannot modify system column \"%s\"",
+ 						column)));
+ 
+ 	if (attform->attgenerated && !attform->attidentity)
+ 		ereport(ERROR,
+ 				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ 				 errmsg("column \"%s\" of relation \"%s\" is a GENERATED column",
+ 						column, RelationGetRelationName(rel))));
+ 
+ 	if (is_identity)
+ 	{
+ 		tupleDesc = RelationGetDescr(rel);
+ 
+ 		for (attnum = 1; attnum <= tupleDesc->natts; attnum++)
+ 		{
+ 			if (tupleDesc->attrs[attnum - 1]->attisdropped)
+ 				continue;
+ 			if (idattnum != attnum &&
+ 				tupleDesc->attrs[attnum - 1]->attidentity)
+ 				ereport(ERROR,
+ 					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ 					 errmsg("multiple IDENTITY columns are not allowed")));
+ 		}
+ 	} else
+ 		is_generated = false;
+ 
+ 	sequenceId = get_relid_att_serial_sequence(tableOid, idattnum);
+ 
+ 	if (!OidIsValid(sequenceId))
+ 		ereport(ERROR,
+ 				(errcode(ERRCODE_UNDEFINED_COLUMN),
+ 				 errmsg("column \"%s\" of relation \"%s\" does not have an associated sequence",
+ 						column, RelationGetRelationName(rel))));
+ 
+ 	if (is_identity && attform->attidentity)
+ 		ereport(ERROR,
+ 				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ 				 errmsg("column \"%s\" of relation \"%s\" is an IDENTITY column",
+ 						column, RelationGetRelationName(rel))));
+ 
+ 	if (!is_identity && !attform->attidentity)
+ 		ereport(ERROR,
+ 				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ 				 errmsg("column \"%s\" of relation \"%s\" is a non-IDENTITY serial column",
+ 						column, RelationGetRelationName(rel))));
+ 
+ 	/* Modify IDENTITY properties */
+ 	attform->attidentity = is_identity;
+ 	attform->attgenerated = is_generated;
+ 	simple_heap_update(attrelation, &atttup->t_self, atttup);
+ 
+ 	/* keep system catalog indexes current */
+ 	CatalogUpdateIndexes(attrelation, atttup);
+ 
+ 	heap_freetuple(atttup);
+ 	
+ 	heap_close(attrelation, RowExclusiveLock);
+ 
+ 	CommandCounterIncrement();
+ 
+ 	heap_close(rel, NoLock);
+ }
+ 
+ /*
   * Check columns in child table match up with columns in parent, and increment
   * their attinhcount.
   *
diff -dcrpN pgsql.orig/src/backend/commands/typecmds.c pgsql/src/backend/commands/typecmds.c
*** pgsql.orig/src/backend/commands/typecmds.c	2007-04-04 10:11:12.000000000 +0200
--- pgsql/src/backend/commands/typecmds.c	2007-04-04 12:57:20.000000000 +0200
*************** DefineDomain(CreateDomainStmt *stmt)
*** 730,736 ****
  				defaultExpr = cookDefault(pstate, constr->raw_expr,
  										  basetypeoid,
  										  basetypeMod,
! 										  domainName);
  
  				/*
  				 * Expression must be stored as a nodeToString result, but we
--- 730,737 ----
  				defaultExpr = cookDefault(pstate, constr->raw_expr,
  										  basetypeoid,
  										  basetypeMod,
! 										  domainName,
! 										  false);
  
  				/*
  				 * Expression must be stored as a nodeToString result, but we
*************** AlterDomainDefault(List *names, Node *de
*** 1391,1397 ****
  		defaultExpr = cookDefault(pstate, defaultRaw,
  								  typTup->typbasetype,
  								  typTup->typtypmod,
! 								  NameStr(typTup->typname));
  
  		/*
  		 * Expression must be stored as a nodeToString result, but we also
--- 1392,1399 ----
  		defaultExpr = cookDefault(pstate, defaultRaw,
  								  typTup->typbasetype,
  								  typTup->typtypmod,
! 								  NameStr(typTup->typname),
! 								  false);
  
  		/*
  		 * Expression must be stored as a nodeToString result, but we also
diff -dcrpN pgsql.orig/src/backend/commands/view.c pgsql/src/backend/commands/view.c
*** pgsql.orig/src/backend/commands/view.c	2007-03-13 11:39:31.000000000 +0100
--- pgsql/src/backend/commands/view.c	2007-04-04 12:57:20.000000000 +0200
*************** DefineVirtualRelation(const RangeVar *re
*** 127,132 ****
--- 127,134 ----
  			def->raw_default = NULL;
  			def->cooked_default = NULL;
  			def->constraints = NIL;
+ 			def->is_identity = false;
+ 			def->is_generated = false;
  
  			attrList = lappend(attrList, def);
  		}
diff -dcrpN pgsql.orig/src/backend/executor/execMain.c pgsql/src/backend/executor/execMain.c
*** pgsql.orig/src/backend/executor/execMain.c	2007-03-30 09:33:54.000000000 +0200
--- pgsql/src/backend/executor/execMain.c	2007-04-04 13:54:14.000000000 +0200
***************
*** 45,55 ****
--- 45,58 ----
  #include "executor/instrument.h"
  #include "executor/nodeSubplan.h"
  #include "miscadmin.h"
+ #include "nodes/makefuncs.h"
  #include "optimizer/clauses.h"
  #include "parser/parse_clause.h"
  #include "parser/parsetree.h"
+ #include "rewrite/rewriteHandler.h"
  #include "storage/smgr.h"
  #include "utils/acl.h"
+ #include "./utils/datum.h"
  #include "utils/lsyscache.h"
  #include "utils/memutils.h"
  
*************** static void ExecDelete(ItemPointer tuple
*** 87,92 ****
--- 90,98 ----
  static void ExecUpdate(TupleTableSlot *slot, ItemPointer tupleid,
  		   TupleTableSlot *planSlot,
  		   DestReceiver *dest, EState *estate);
+ static HeapTuple ExecGenerated(TupleTableSlot *slot,
+ 		   HeapTuple tuple,
+ 		   EState *estate);
  static void ExecProcessReturning(ProjectionInfo *projectReturning,
  					 TupleTableSlot *tupleSlot,
  					 TupleTableSlot *planSlot,
*************** ExecInsert(TupleTableSlot *slot,
*** 1395,1400 ****
--- 1401,1408 ----
  		}
  	}
  
+ 	tuple = ExecGenerated(slot, tuple, estate);
+ 
  	/*
  	 * Check the constraints of the tuple
  	 */
*************** ExecUpdate(TupleTableSlot *slot,
*** 1638,1643 ****
--- 1646,1656 ----
  	}
  
  	/*
+ 	 * Fill in the GENERATED columns
+ 	 */
+ 	tuple = ExecGenerated(slot, tuple, estate);
+ 
+ 	/*
  	 * Check the constraints of the tuple
  	 *
  	 * If we generate a new candidate tuple after EvalPlanQual testing, we
*************** ExecConstraints(ResultRelInfo *resultRel
*** 1831,1836 ****
--- 1844,1927 ----
  }
  
  /*
+  * ExecGenerated --- evaluate GENERATED columns
+  */
+ static HeapTuple
+ ExecGenerated(TupleTableSlot *slot, HeapTuple tuple, EState *estate)
+ {
+ 	ResultRelInfo *resultRelInfo;
+ 	Relation	resultRelationDesc;
+ 	TupleDesc	tupleDesc;
+ 	ExprContext   *econtext;
+ 	ExprState     *exprstate;
+ 	int		attnum;
+ 	Datum		*values;
+ 	bool		*isnull;
+ 	bool		*replace;
+ 
+ 	resultRelInfo = estate->es_result_relation_info;
+ 	resultRelationDesc = resultRelInfo->ri_RelationDesc;
+ 
+ 	tupleDesc = resultRelationDesc->rd_att;
+ 
+ 	values = palloc0(tupleDesc->natts * sizeof(Datum));
+ 	isnull = palloc0(tupleDesc->natts * sizeof(bool));
+ 	replace= palloc0(tupleDesc->natts * sizeof(bool));
+ 
+ 	econtext = GetPerTupleExprContext(estate);
+ 	econtext->ecxt_scantuple = slot;
+ 
+ 	for (attnum = 1; attnum <= tupleDesc->natts; attnum++)
+ 	{
+ 		Form_pg_attribute att_tup = tupleDesc->attrs[attnum - 1];
+ 
+ 		if (att_tup->attisdropped)
+ 			continue;
+ 		if (att_tup->attgenerated && !att_tup->attidentity)
+ 		{
+ 			Expr	*expr;
+ 			Datum		const_val;
+ 			bool		const_is_null;
+ 			int16		resultTypLen; 
+ 			bool		resultTypByVal;
+ 
+ 			expr = (Expr *)
+ 				build_column_default(resultRelationDesc,
+ 						attnum);
+ 			exprstate = ExecPrepareExpr(expr, estate);
+ 			const_val = ExecEvalExpr(exprstate,
+ 							econtext,
+ 							&const_is_null,
+ 							NULL);
+ 			get_typlenbyval(att_tup->atttypid,
+ 							&resultTypLen,
+ 							&resultTypByVal);
+ 			if (!const_is_null)
+ 				const_val = datumCopy(const_val,
+ 							resultTypByVal,
+ 							resultTypLen);
+ 			values[attnum - 1] = const_val;
+ 			isnull[attnum - 1] = const_is_null;
+ 			replace[attnum - 1] = true;
+ 		}
+ 	}
+ 
+ 	tuple = heap_modify_tuple(tuple, tupleDesc,
+ 						values,
+ 						isnull,
+ 						replace);
+ 
+ 	slot = ExecStoreTuple(tuple, slot, InvalidBuffer, false);
+ 
+ 	ResetPerTupleExprContext(estate);
+ 
+ 	pfree(values);
+ 	pfree(isnull);
+ 	pfree(replace);
+ 	return tuple;
+ }
+ 
+ /*
   * ExecProcessReturning --- evaluate a RETURNING list and send to dest
   *
   * projectReturning: RETURNING projection info for current result rel
diff -dcrpN pgsql.orig/src/backend/nodes/copyfuncs.c pgsql/src/backend/nodes/copyfuncs.c
*** pgsql.orig/src/backend/nodes/copyfuncs.c	2007-04-04 10:11:16.000000000 +0200
--- pgsql/src/backend/nodes/copyfuncs.c	2007-04-04 13:55:00.000000000 +0200
*************** _copyColumnDef(ColumnDef *from)
*** 1754,1759 ****
--- 1754,1761 ----
  	COPY_NODE_FIELD(raw_default);
  	COPY_STRING_FIELD(cooked_default);
  	COPY_NODE_FIELD(constraints);
+ 	COPY_SCALAR_FIELD(is_identity);
+ 	COPY_SCALAR_FIELD(is_generated);
  
  	return newnode;
  }
*************** _copyConstraint(Constraint *from)
*** 1770,1775 ****
--- 1772,1779 ----
  	COPY_NODE_FIELD(keys);
  	COPY_NODE_FIELD(options);
  	COPY_STRING_FIELD(indexspace);
+ 	COPY_SCALAR_FIELD(is_generated);
+ 	COPY_NODE_FIELD(seq_opts);
  
  	return newnode;
  }
*************** _copyQuery(Query *from)
*** 1834,1839 ****
--- 1838,1844 ----
  	COPY_NODE_FIELD(limitCount);
  	COPY_NODE_FIELD(rowMarks);
  	COPY_NODE_FIELD(setOperations);
+ 	COPY_SCALAR_FIELD(commandOverride);
  
  	return newnode;
  }
*************** _copyInsertStmt(InsertStmt *from)
*** 1847,1852 ****
--- 1852,1858 ----
  	COPY_NODE_FIELD(cols);
  	COPY_NODE_FIELD(selectStmt);
  	COPY_NODE_FIELD(returningList);
+ 	COPY_SCALAR_FIELD(commandOverride);
  
  	return newnode;
  }
*************** _copyAlterTableCmd(AlterTableCmd *from)
*** 1940,1945 ****
--- 1946,1952 ----
  	COPY_NODE_FIELD(def);
  	COPY_NODE_FIELD(transform);
  	COPY_SCALAR_FIELD(behavior);
+ 	COPY_SCALAR_FIELD(is_generated);
  
  	return newnode;
  }
diff -dcrpN pgsql.orig/src/backend/nodes/equalfuncs.c pgsql/src/backend/nodes/equalfuncs.c
*** pgsql.orig/src/backend/nodes/equalfuncs.c	2007-04-04 10:11:16.000000000 +0200
--- pgsql/src/backend/nodes/equalfuncs.c	2007-04-04 13:55:23.000000000 +0200
*************** _equalQuery(Query *a, Query *b)
*** 737,742 ****
--- 737,743 ----
  	COMPARE_NODE_FIELD(limitCount);
  	COMPARE_NODE_FIELD(rowMarks);
  	COMPARE_NODE_FIELD(setOperations);
+ 	COMPARE_SCALAR_FIELD(commandOverride);
  
  	return true;
  }
*************** _equalInsertStmt(InsertStmt *a, InsertSt
*** 748,753 ****
--- 749,755 ----
  	COMPARE_NODE_FIELD(cols);
  	COMPARE_NODE_FIELD(selectStmt);
  	COMPARE_NODE_FIELD(returningList);
+ 	COMPARE_SCALAR_FIELD(commandOverride);
  
  	return true;
  }
*************** _equalAlterTableCmd(AlterTableCmd *a, Al
*** 829,834 ****
--- 831,837 ----
  	COMPARE_NODE_FIELD(def);
  	COMPARE_NODE_FIELD(transform);
  	COMPARE_SCALAR_FIELD(behavior);
+ 	COMPARE_SCALAR_FIELD(is_generated);
  
  	return true;
  }
*************** _equalColumnDef(ColumnDef *a, ColumnDef 
*** 1765,1770 ****
--- 1768,1775 ----
  	COMPARE_NODE_FIELD(raw_default);
  	COMPARE_STRING_FIELD(cooked_default);
  	COMPARE_NODE_FIELD(constraints);
+ 	COMPARE_SCALAR_FIELD(is_identity);
+ 	COMPARE_SCALAR_FIELD(is_generated);
  
  	return true;
  }
*************** _equalConstraint(Constraint *a, Constrai
*** 1779,1784 ****
--- 1784,1791 ----
  	COMPARE_NODE_FIELD(keys);
  	COMPARE_NODE_FIELD(options);
  	COMPARE_STRING_FIELD(indexspace);
+ 	COMPARE_SCALAR_FIELD(is_generated);
+ 	COMPARE_NODE_FIELD(seq_opts);
  
  	return true;
  }
diff -dcrpN pgsql.orig/src/backend/nodes/outfuncs.c pgsql/src/backend/nodes/outfuncs.c
*** pgsql.orig/src/backend/nodes/outfuncs.c	2007-03-28 17:16:12.000000000 +0200
--- pgsql/src/backend/nodes/outfuncs.c	2007-04-04 14:02:19.000000000 +0200
*************** _outColumnDef(StringInfo str, ColumnDef 
*** 1620,1625 ****
--- 1620,1627 ----
  	WRITE_NODE_FIELD(raw_default);
  	WRITE_STRING_FIELD(cooked_default);
  	WRITE_NODE_FIELD(constraints);
+ 	WRITE_BOOL_FIELD(is_identity);
+ 	WRITE_BOOL_FIELD(is_generated);
  }
  
  static void
*************** _outQuery(StringInfo str, Query *node)
*** 1709,1714 ****
--- 1711,1717 ----
  	WRITE_NODE_FIELD(limitCount);
  	WRITE_NODE_FIELD(rowMarks);
  	WRITE_NODE_FIELD(setOperations);
+ 	WRITE_BOOL_FIELD(commandOverride);
  }
  
  static void
*************** _outConstraint(StringInfo str, Constrain
*** 1973,1984 ****
--- 1976,1993 ----
  			appendStringInfo(str, "DEFAULT");
  			WRITE_NODE_FIELD(raw_expr);
  			WRITE_STRING_FIELD(cooked_expr);
+ 			WRITE_BOOL_FIELD(is_generated);
  			break;
  
  		case CONSTR_NOTNULL:
  			appendStringInfo(str, "NOT_NULL");
  			break;
  
+ 		case CONSTR_IDENTITY:
+ 			appendStringInfo(str, "IDENTITY");
+ 			WRITE_NODE_FIELD(seq_opts);
+ 			break;
+ 
  		default:
  			appendStringInfo(str, "<unrecognized_constraint>");
  			break;
diff -dcrpN pgsql.orig/src/backend/nodes/readfuncs.c pgsql/src/backend/nodes/readfuncs.c
*** pgsql.orig/src/backend/nodes/readfuncs.c	2007-03-28 17:16:12.000000000 +0200
--- pgsql/src/backend/nodes/readfuncs.c	2007-04-04 13:56:00.000000000 +0200
*************** _readQuery(void)
*** 154,159 ****
--- 154,160 ----
  	READ_NODE_FIELD(limitCount);
  	READ_NODE_FIELD(rowMarks);
  	READ_NODE_FIELD(setOperations);
+ 	READ_BOOL_FIELD(commandOverride);
  
  	READ_DONE();
  }
diff -dcrpN pgsql.orig/src/backend/parser/analyze.c pgsql/src/backend/parser/analyze.c
*** pgsql.orig/src/backend/parser/analyze.c	2007-03-13 11:39:44.000000000 +0100
--- pgsql/src/backend/parser/analyze.c	2007-04-04 12:57:20.000000000 +0200
*************** transformInsertStmt(ParseState *pstate, 
*** 453,458 ****
--- 453,459 ----
  	ListCell   *lc;
  
  	qry->commandType = CMD_INSERT;
+ 	qry->commandOverride = stmt->commandOverride;
  	pstate->p_is_insert = true;
  
  	/*
*************** transformColumnDefinition(ParseState *ps
*** 940,945 ****
--- 941,949 ----
  	bool		saw_nullable;
  	Constraint *constraint;
  	ListCell   *clist;
+ 	bool		saw_identity;
+ 	bool		is_generated;
+ 	List	   *seq_opts;
  
  	cxt->columns = lappend(cxt->columns, column);
  
*************** transformColumnDefinition(ParseState *ps
*** 965,975 ****
  		}
  	}
  
  	/* Do necessary work on the column type declaration */
  	transformColumnType(pstate, column);
  
! 	/* Special actions for SERIAL pseudo-types */
! 	if (is_serial)
  	{
  		Oid			snamespaceid;
  		char	   *snamespace;
--- 969,1003 ----
  		}
  	}
  
+ 	/* Check for GENERATED ... AS IDENTITY constructs */
+ 	saw_identity = false; 
+ 	is_generated = false;
+ 	seq_opts = NULL;
+ 	foreach(clist, column->constraints)
+ 	{
+ 		constraint = lfirst(clist);
+ 
+ 		switch (constraint->contype) {
+ 			case CONSTR_IDENTITY:
+ 				if (saw_identity)
+ 					ereport(ERROR,
+ 						(errcode(ERRCODE_SYNTAX_ERROR),
+ 						 errmsg("multiple GENERATED ... AS IDENTITY constructs specified for column \"%s\" of table \"%s\"",
+ 						 		column->colname, cxt->relation->relname)));
+ 				saw_identity = true;
+ 				is_generated = constraint->is_generated;
+ 				seq_opts = constraint->seq_opts;
+ 				break;
+ 			default:
+ 				continue;
+ 		}
+ 	}
+ 
  	/* Do necessary work on the column type declaration */
  	transformColumnType(pstate, column);
  
! 	/* Special actions for SERIAL pseudo-types or IDENTITY columns */
! 	if (is_serial || saw_identity)
  	{
  		Oid			snamespaceid;
  		char	   *snamespace;
*************** transformColumnDefinition(ParseState *ps
*** 1011,1017 ****
  		 */
  		seqstmt = makeNode(CreateSeqStmt);
  		seqstmt->sequence = makeRangeVar(snamespace, sname);
! 		seqstmt->options = NIL;
  
  		cxt->blist = lappend(cxt->blist, seqstmt);
  
--- 1039,1045 ----
  		 */
  		seqstmt = makeNode(CreateSeqStmt);
  		seqstmt->sequence = makeRangeVar(snamespace, sname);
! 		seqstmt->options = seq_opts;
  
  		cxt->blist = lappend(cxt->blist, seqstmt);
  
*************** transformColumnDefinition(ParseState *ps
*** 1057,1062 ****
--- 1085,1091 ----
  		constraint->raw_expr = (Node *) funccallnode;
  		constraint->cooked_expr = NULL;
  		constraint->keys = NIL;
+ 		constraint->is_generated = is_generated;
  		column->constraints = lappend(column->constraints, constraint);
  
  		constraint = makeNode(Constraint);
*************** transformColumnDefinition(ParseState *ps
*** 1118,1126 ****
--- 1147,1159 ----
  							 errmsg("multiple default values specified for column \"%s\" of table \"%s\"",
  								  column->colname, cxt->relation->relname)));
  				column->raw_default = constraint->raw_expr;
+ 				is_generated = constraint->is_generated;
  				Assert(constraint->cooked_expr == NULL);
  				break;
  
+ 			case CONSTR_IDENTITY:   /* This was processed above, we only have to detect it here. */
+ 				break;
+ 
  			case CONSTR_PRIMARY:
  			case CONSTR_UNIQUE:
  				if (constraint->keys == NIL)
*************** transformColumnDefinition(ParseState *ps
*** 1145,1150 ****
--- 1178,1185 ----
  				break;
  		}
  	}
+ 	column->is_identity = saw_identity;
+ 	column->is_generated = is_generated;
  }
  
  static void
*************** transformInhRelation(ParseState *pstate,
*** 1293,1298 ****
--- 1328,1335 ----
  		def->raw_default = NULL;
  		def->cooked_default = NULL;
  		def->constraints = NIL;
+ 		def->is_identity = false;
+ 		def->is_generated = false;
  
  		/*
  		 * Add to column list
*************** transformInhRelation(ParseState *pstate,
*** 1327,1332 ****
--- 1364,1371 ----
  			 */
  
  			def->cooked_default = pstrdup(this_default);
+ 			def->is_identity = attribute->attidentity;
+ 			def->is_generated = attribute->attgenerated;
  		}
  	}
  
diff -dcrpN pgsql.orig/src/backend/parser/gram.y pgsql/src/backend/parser/gram.y
*** pgsql.orig/src/backend/parser/gram.y	2007-04-04 10:11:20.000000000 +0200
--- pgsql/src/backend/parser/gram.y	2007-04-04 12:57:20.000000000 +0200
*************** static Node *makeXmlExpr(XmlExprOp op, c
*** 286,292 ****
  
  %type <node>	fetch_direction select_limit_value select_offset_value
  
! %type <list>	OptSeqList
  %type <defelt>	OptSeqElem
  
  %type <istmt>	insert_rest
--- 286,292 ----
  
  %type <node>	fetch_direction select_limit_value select_offset_value
  
! %type <list>	OptSeqList SeqList
  %type <defelt>	OptSeqElem
  
  %type <istmt>	insert_rest
*************** static Node *makeXmlExpr(XmlExprOp op, c
*** 314,319 ****
--- 314,320 ----
  %type <range>	relation_expr
  %type <range>	relation_expr_opt_alias
  %type <target>	target_el single_set_clause set_target insert_column_item
+ %type <boolean>	OptOverride UserSystem
  
  %type <typnam>	Typename SimpleTypename ConstTypename
  				GenericType Numeric opt_float
*************** static Node *makeXmlExpr(XmlExprOp op, c
*** 341,346 ****
--- 342,349 ----
  %type <ival>	TableLikeOption
  %type <list>	ColQualList
  %type <node>	ColConstraint ColConstraintElem ConstraintAttr
+ %type <node>	AlwaysByDefault IdentityGenerated IdentitySpec
+ %type <boolean>	SetIdentityAlwaysByDefault
  %type <ival>	key_actions key_delete key_match key_update key_action
  %type <ival>	ConstraintAttributeSpec ConstraintDeferrabilitySpec
  				ConstraintTimeSpec
*************** static Node *makeXmlExpr(XmlExprOp op, c
*** 390,400 ****
  	FALSE_P FAMILY FETCH FIRST_P FLOAT_P FOR FORCE FOREIGN FORWARD
  	FREEZE FROM FULL FUNCTION
  
! 	GLOBAL GRANT GRANTED GREATEST GROUP_P
  
  	HANDLER HAVING HEADER_P HOLD HOUR_P
  
! 	IF_P ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IN_P INCLUDING INCREMENT
  	INDEX INDEXES INHERIT INHERITS INITIALLY INNER_P INOUT INPUT_P
  	INSENSITIVE INSERT INSTEAD INT_P INTEGER INTERSECT
  	INTERVAL INTO INVOKER IS ISNULL ISOLATION
--- 393,403 ----
  	FALSE_P FAMILY FETCH FIRST_P FLOAT_P FOR FORCE FOREIGN FORWARD
  	FREEZE FROM FULL FUNCTION
  
! 	GENERATED GLOBAL GRANT GRANTED GREATEST GROUP_P
  
  	HANDLER HAVING HEADER_P HOLD HOUR_P
  
! 	IDENTITY IF_P ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IN_P INCLUDING INCREMENT
  	INDEX INDEXES INHERIT INHERITS INITIALLY INNER_P INOUT INPUT_P
  	INSENSITIVE INSERT INSTEAD INT_P INTEGER INTERSECT
  	INTERVAL INTO INVOKER IS ISNULL ISOLATION
*************** static Node *makeXmlExpr(XmlExprOp op, c
*** 414,420 ****
  	NOT NOTHING NOTIFY NOTNULL NOWAIT NULL_P NULLIF NULLS_P NUMERIC
  
  	OBJECT_P OF OFF OFFSET OIDS OLD ON ONLY OPERATOR OPTION OR
! 	ORDER OUT_P OUTER_P OVERLAPS OVERLAY OWNED OWNER
  
  	PARTIAL PASSWORD PLACING POSITION
  	PRECISION PRESERVE PREPARE PREPARED PRIMARY
--- 417,423 ----
  	NOT NOTHING NOTIFY NOTNULL NOWAIT NULL_P NULLIF NULLS_P NUMERIC
  
  	OBJECT_P OF OFF OFFSET OIDS OLD ON ONLY OPERATOR OPTION OR
! 	ORDER OUT_P OUTER_P OVERLAPS OVERLAY OVERRIDING OWNED OWNER
  
  	PARTIAL PASSWORD PLACING POSITION
  	PRECISION PRESERVE PREPARE PREPARED PRIMARY
*************** alter_table_cmd:
*** 1411,1416 ****
--- 1414,1450 ----
  					n->def = (Node *) makeString($6);
  					$$ = (Node *)n;
  				}
+ 			| ALTER opt_column ColId SET SeqList
+ 				{
+ 					AlterTableCmd *n = makeNode(AlterTableCmd);
+ 					n->subtype = AT_SetSeqOpts;
+ 					n->name = $3;
+ 					n->def = (Node *) $5;
+ 					$$ = (Node *)n;
+ 				}
+ 			| ALTER opt_column ColId RESTART opt_with NumericOnly
+ 				{
+ 					AlterTableCmd *n = makeNode(AlterTableCmd);
+ 					n->subtype = AT_SetSeqOpts;
+ 					n->name = $3;
+ 					n->def = (Node *)list_make1(makeDefElem("restart", (Node *)$6));
+ 					$$ = (Node *)n;
+ 				}
+ 			| ALTER opt_column ColId SET GENERATED SetIdentityAlwaysByDefault AS IDENTITY
+ 				{
+ 					AlterTableCmd *n = makeNode(AlterTableCmd);
+ 					n->subtype = AT_SetIdentity;
+ 					n->name = $3;
+ 					n->is_generated = $6;
+ 					$$ = (Node *)n;
+ 				}
+ 			| ALTER opt_column ColId DROP IDENTITY
+ 				{
+ 					AlterTableCmd *n = makeNode(AlterTableCmd);
+ 					n->subtype = AT_DropIdentity;
+ 					n->name = $3;
+ 					$$ = (Node *)n;
+ 				}
  			/* ALTER TABLE <relation> DROP [COLUMN] <colname> [RESTRICT|CASCADE] */
  			| DROP opt_column ColId opt_drop_behavior
  				{
*************** alter_using:
*** 1651,1656 ****
--- 1685,1695 ----
  			| /* EMPTY */				{ $$ = NULL; }
  		;
  
+ SetIdentityAlwaysByDefault:
+ 			ALWAYS					{ $$ = true; }
+ 			| BY DEFAULT				{ $$ = false; }
+ 		;
+ 
  
  
  /*****************************************************************************
*************** ClosePortalStmt:
*** 1684,1698 ****
   *
   *****************************************************************************/
  
! CopyStmt:	COPY opt_binary qualified_name opt_column_list opt_oids
  			copy_from copy_file_name copy_delimiter opt_with copy_opt_list
  				{
  					CopyStmt *n = makeNode(CopyStmt);
  					n->relation = $3;
  					n->query = NULL;
  					n->attlist = $4;
! 					n->is_from = $6;
! 					n->filename = $7;
  
  					n->options = NIL;
  					/* Concatenate user-supplied flags */
--- 1723,1738 ----
   *
   *****************************************************************************/
  
! CopyStmt:	COPY opt_binary qualified_name opt_column_list opt_oids OptOverride
  			copy_from copy_file_name copy_delimiter opt_with copy_opt_list
  				{
  					CopyStmt *n = makeNode(CopyStmt);
  					n->relation = $3;
  					n->query = NULL;
  					n->attlist = $4;
! 					n->overriding = $6;
! 					n->is_from = $7;
! 					n->filename = $8;
  
  					n->options = NIL;
  					/* Concatenate user-supplied flags */
*************** CopyStmt:	COPY opt_binary qualified_name
*** 1700,1709 ****
  						n->options = lappend(n->options, $2);
  					if ($5)
  						n->options = lappend(n->options, $5);
! 					if ($8)
! 						n->options = lappend(n->options, $8);
! 					if ($10)
! 						n->options = list_concat(n->options, $10);
  					$$ = (Node *)n;
  				}
  			| COPY select_with_parens TO copy_file_name opt_with
--- 1740,1749 ----
  						n->options = lappend(n->options, $2);
  					if ($5)
  						n->options = lappend(n->options, $5);
! 					if ($9)
! 						n->options = lappend(n->options, $9);
! 					if ($11)
! 						n->options = list_concat(n->options, $11);
  					$$ = (Node *)n;
  				}
  			| COPY select_with_parens TO copy_file_name opt_with
*************** columnDef:	ColId Typename ColQualList
*** 1905,1910 ****
--- 1945,1952 ----
  					n->typename = $2;
  					n->constraints = $3;
  					n->is_local = true;
+ 					n->is_identity = false;
+ 					n->is_generated = false;
  					$$ = (Node *)n;
  				}
  		;
*************** ColConstraintElem:
*** 2046,2051 ****
--- 2088,2152 ----
  					n->initdeferred		= FALSE;
  					$$ = (Node *)n;
  				}
+ 			| GENERATED AlwaysByDefault
+ 				{
+ 					$$ = $2;
+ 				}
+ 		;
+ 
+ AlwaysByDefault:
+ 			BY DEFAULT AS IDENTITY IdentitySpec		{ $$ = $5; }
+ 			| ALWAYS AS IdentityGenerated
+ 				{
+ 					Constraint *n = (Constraint *)$3;
+ 					n->is_generated = true;
+ 					$$ = (Node *)n;
+ 				}
+ 		;
+ 
+ IdentityGenerated:
+ 			'(' a_expr ')'
+ 				{
+ 					Constraint *n = makeNode(Constraint);
+ 					n->contype = CONSTR_DEFAULT;
+ 					n->name = NULL;
+ 					n->raw_expr = $2;
+ 					n->cooked_expr = NULL;
+ 					n->keys = NULL;
+ 					n->indexspace = NULL;
+ 					$$ = (Node *)n;
+ 				}
+ 			| IDENTITY IdentitySpec
+ 				{
+ 					$$ = $2;
+ 				}
+ 		;
+ 
+ IdentitySpec:
+ 			'(' SeqList ')'
+ 				{
+ 					Constraint *n = makeNode(Constraint);
+ 					n->contype = CONSTR_IDENTITY;
+ 					n->name = NULL;
+ 					n->raw_expr = NULL;
+ 					n->cooked_expr = NULL;
+ 					n->keys = NULL;
+ 					n->indexspace = NULL;
+ 					n->seq_opts = $2;
+ 					$$ = (Node *)n;
+ 				}
+ 			| /* EMPTY */
+ 				{
+ 					Constraint *n = makeNode(Constraint);
+ 					n->contype = CONSTR_IDENTITY;
+ 					n->name = NULL;
+ 					n->raw_expr = NULL;
+ 					n->cooked_expr = NULL;
+ 					n->keys = NULL;
+ 					n->indexspace = NULL;
+ 					n->seq_opts = NULL;
+ 					$$ = (Node *)n;
+ 				}
  		;
  
  /*
*************** CreateAsElement:
*** 2358,2363 ****
--- 2459,2466 ----
  					n->raw_default = NULL;
  					n->cooked_default = NULL;
  					n->constraints = NIL;
+ 					n->is_identity = false;
+ 					n->is_generated = false;
  					$$ = (Node *)n;
  				}
  		;
*************** OptSeqList: OptSeqList OptSeqElem					{ 
*** 2396,2401 ****
--- 2499,2509 ----
  			| /*EMPTY*/								{ $$ = NIL; }
  		;
  
+ SeqList: SeqList OptSeqElem						{ $$ = lappend($1, $2); }
+ 			| OptSeqElem					{ $$ = list_make1($1); }
+ 		;
+ 
+ 
  OptSeqElem: CACHE NumericOnly
  				{
  					$$ = makeDefElem("cache", (Node *)$2);
*************** InsertStmt:
*** 5603,5619 ****
  		;
  
  insert_rest:
! 			SelectStmt
  				{
  					$$ = makeNode(InsertStmt);
  					$$->cols = NIL;
! 					$$->selectStmt = $1;
  				}
! 			| '(' insert_column_list ')' SelectStmt
  				{
  					$$ = makeNode(InsertStmt);
  					$$->cols = $2;
! 					$$->selectStmt = $4;
  				}
  			| DEFAULT VALUES
  				{
--- 5711,5729 ----
  		;
  
  insert_rest:
! 			OptOverride SelectStmt
  				{
  					$$ = makeNode(InsertStmt);
  					$$->cols = NIL;
! 					$$->commandOverride = $1;
! 					$$->selectStmt = $2;
  				}
! 			| '(' insert_column_list ')' OptOverride SelectStmt
  				{
  					$$ = makeNode(InsertStmt);
  					$$->cols = $2;
! 					$$->commandOverride = $4;
! 					$$->selectStmt = $5;
  				}
  			| DEFAULT VALUES
  				{
*************** opt_nowait:	NOWAIT							{ $$ = TRUE; }
*** 5701,5706 ****
--- 5811,5832 ----
  		;
  
  
+ OptOverride:
+ 			OVERRIDING UserSystem VALUE_P
+ 				{
+ 					$$ = $2;
+ 				}
+ 			| /* EMPTY */
+ 				{
+ 					$$ = false;
+ 				}
+ 		;
+ 
+ UserSystem:
+ 			SYSTEM_P					{ $$ = true; } 
+ 			| USER						{ $$ = false; }
+ 		;
+ 
  /*****************************************************************************
   *
   *		QUERY:
*************** unreserved_keyword:
*** 8793,8798 ****
--- 8919,8925 ----
  			| FORCE
  			| FORWARD
  			| FUNCTION
+ 			| GENERATED
  			| GLOBAL
  			| GRANTED
  			| HANDLER
*************** unreserved_keyword:
*** 8853,8858 ****
--- 8980,8986 ----
  			| OIDS
  			| OPERATOR
  			| OPTION
+ 			| OVERRIDING
  			| OWNED
  			| OWNER
  			| PARTIAL
*************** reserved_keyword:
*** 9079,9084 ****
--- 9207,9213 ----
  			| GRANT
  			| GROUP_P
  			| HAVING
+ 			| IDENTITY
  			| IN_P
  			| INITIALLY
  			| INTERSECT
diff -dcrpN pgsql.orig/src/backend/parser/keywords.c pgsql/src/backend/parser/keywords.c
*** pgsql.orig/src/backend/parser/keywords.c	2007-04-04 10:11:20.000000000 +0200
--- pgsql/src/backend/parser/keywords.c	2007-04-04 12:57:20.000000000 +0200
*************** static const ScanKeyword ScanKeywords[] 
*** 159,164 ****
--- 159,165 ----
  	{"from", FROM},
  	{"full", FULL},
  	{"function", FUNCTION},
+ 	{"generated", GENERATED},
  	{"global", GLOBAL},
  	{"grant", GRANT},
  	{"granted", GRANTED},
*************** static const ScanKeyword ScanKeywords[] 
*** 169,174 ****
--- 170,176 ----
  	{"header", HEADER_P},
  	{"hold", HOLD},
  	{"hour", HOUR_P},
+ 	{"identity", IDENTITY},
  	{"if", IF_P},
  	{"ilike", ILIKE},
  	{"immediate", IMMEDIATE},
*************** static const ScanKeyword ScanKeywords[] 
*** 264,269 ****
--- 266,272 ----
  	{"outer", OUTER_P},
  	{"overlaps", OVERLAPS},
  	{"overlay", OVERLAY},
+ 	{"overriding", OVERRIDING},
  	{"owned", OWNED},
  	{"owner", OWNER},
  	{"partial", PARTIAL},
diff -dcrpN pgsql.orig/src/backend/rewrite/rewriteHandler.c pgsql/src/backend/rewrite/rewriteHandler.c
*** pgsql.orig/src/backend/rewrite/rewriteHandler.c	2007-03-23 12:17:41.000000000 +0100
--- pgsql/src/backend/rewrite/rewriteHandler.c	2007-04-04 13:56:48.000000000 +0200
***************
*** 13,18 ****
--- 13,19 ----
   */
  #include "postgres.h"
  
+ #include "miscadmin.h"
  #include "access/heapam.h"
  #include "catalog/pg_type.h"
  #include "nodes/makefuncs.h"
***************
*** 24,29 ****
--- 25,31 ----
  #include "rewrite/rewriteDefine.h"
  #include "rewrite/rewriteHandler.h"
  #include "rewrite/rewriteManip.h"
+ #include "utils/acl.h"
  #include "utils/builtins.h"
  #include "utils/lsyscache.h"
  #include "commands/trigger.h"
*************** rewriteTargetList(Query *parsetree, Rela
*** 536,541 ****
--- 538,544 ----
  				  List **attrno_list)
  {
  	CmdType		commandType = parsetree->commandType;
+ 	bool		commandOverride = parsetree->commandOverride;
  	TargetEntry **new_tles;
  	List	   *new_tlist = NIL;
  	List	   *junk_tlist = NIL;
*************** rewriteTargetList(Query *parsetree, Rela
*** 620,634 ****
  			continue;
  
  		/*
! 		 * Handle the two cases where we need to insert a default expression:
! 		 * it's an INSERT and there's no tlist entry for the column, or the
! 		 * tlist entry is a DEFAULT placeholder node.
  		 */
! 		if ((new_tle == NULL && commandType == CMD_INSERT) ||
  			(new_tle && new_tle->expr && IsA(new_tle->expr, SetToDefault)))
  		{
  			Node	   *new_expr;
  
  			new_expr = build_column_default(target_relation, attrno);
  
  			/*
--- 623,658 ----
  			continue;
  
  		/*
! 		 * Handle the three cases where we need to insert a default expression:
! 		 * - it's an INSERT and there's no tlist entry for the column, or
! 		 * - it's an INSERT and the column is GENERATED ALWAYS
! 		 * - the tlist entry is a DEFAULT placeholder node
! 		 * Fail for UPDATE to non-default on GENERATED ALWAYS AS () columns.
! 		 * Fail for UPDATE on GENERATED ALWAYS AS IDENTITY columns
  		 */
! 		if (commandType == CMD_UPDATE && att_tup->atthasdef && att_tup->attgenerated &&
! 			new_tle && new_tle->expr)
! 		{
! 			if (att_tup->attidentity)
! 				ereport(ERROR,
! 						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
! 							 errmsg("UPDATE prohibited on GENERATED ALWAYS AS IDENTITY attributes")));
! 			else if (!IsA(new_tle->expr, SetToDefault))
! 				ereport(ERROR,
! 						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
! 							 errmsg("UPDATE to non-default value prohibited on GENERATED ALWAYS attributes")));
! 		}
! 		if (((new_tle == NULL || (att_tup->attgenerated && !commandOverride)) && commandType == CMD_INSERT) ||
  			(new_tle && new_tle->expr && IsA(new_tle->expr, SetToDefault)))
  		{
  			Node	   *new_expr;
  
+ 			/*
+ 			 * Skip all GENERATED columns that were assigned with DEFAULT.
+ 			 */
+ 			if (att_tup->attgenerated && !att_tup->attidentity)
+ 				continue;
+ 
  			new_expr = build_column_default(target_relation, attrno);
  
  			/*
diff -dcrpN pgsql.orig/src/backend/utils/adt/ruleutils.c pgsql/src/backend/utils/adt/ruleutils.c
*** pgsql.orig/src/backend/utils/adt/ruleutils.c	2007-03-28 17:18:45.000000000 +0200
--- pgsql/src/backend/utils/adt/ruleutils.c	2007-04-04 12:57:20.000000000 +0200
*************** pg_get_serial_sequence(PG_FUNCTION_ARGS)
*** 1262,1272 ****
  	Oid			tableOid;
  	char	   *column;
  	AttrNumber	attnum;
! 	Oid			sequenceId = InvalidOid;
! 	Relation	depRel;
! 	ScanKeyData key[3];
! 	SysScanDesc scan;
! 	HeapTuple	tup;
  
  	/* Get the OID of the table */
  	tablerv = makeRangeVarFromNameList(textToQualifiedNameList(tablename));
--- 1262,1268 ----
  	Oid			tableOid;
  	char	   *column;
  	AttrNumber	attnum;
! 	Oid			sequenceId;
  
  	/* Get the OID of the table */
  	tablerv = makeRangeVarFromNameList(textToQualifiedNameList(tablename));
*************** pg_get_serial_sequence(PG_FUNCTION_ARGS)
*** 1283,1328 ****
  				 errmsg("column \"%s\" of relation \"%s\" does not exist",
  						column, tablerv->relname)));
  
! 	/* Search the dependency table for the dependent sequence */
! 	depRel = heap_open(DependRelationId, AccessShareLock);
! 
! 	ScanKeyInit(&key[0],
! 				Anum_pg_depend_refclassid,
! 				BTEqualStrategyNumber, F_OIDEQ,
! 				ObjectIdGetDatum(RelationRelationId));
! 	ScanKeyInit(&key[1],
! 				Anum_pg_depend_refobjid,
! 				BTEqualStrategyNumber, F_OIDEQ,
! 				ObjectIdGetDatum(tableOid));
! 	ScanKeyInit(&key[2],
! 				Anum_pg_depend_refobjsubid,
! 				BTEqualStrategyNumber, F_INT4EQ,
! 				Int32GetDatum(attnum));
! 
! 	scan = systable_beginscan(depRel, DependReferenceIndexId, true,
! 							  SnapshotNow, 3, key);
! 
! 	while (HeapTupleIsValid(tup = systable_getnext(scan)))
! 	{
! 		Form_pg_depend deprec = (Form_pg_depend) GETSTRUCT(tup);
! 
! 		/*
! 		 * We assume any auto dependency of a sequence on a column must be
! 		 * what we are looking for.  (We need the relkind test because indexes
! 		 * can also have auto dependencies on columns.)
! 		 */
! 		if (deprec->classid == RelationRelationId &&
! 			deprec->objsubid == 0 &&
! 			deprec->deptype == DEPENDENCY_AUTO &&
! 			get_rel_relkind(deprec->objid) == RELKIND_SEQUENCE)
! 		{
! 			sequenceId = deprec->objid;
! 			break;
! 		}
! 	}
! 
! 	systable_endscan(scan);
! 	heap_close(depRel, AccessShareLock);
  
  	if (OidIsValid(sequenceId))
  	{
--- 1279,1285 ----
  				 errmsg("column \"%s\" of relation \"%s\" does not exist",
  						column, tablerv->relname)));
  
! 	sequenceId = get_relid_att_serial_sequence(tableOid, attnum);
  
  	if (OidIsValid(sequenceId))
  	{
diff -dcrpN pgsql.orig/src/backend/utils/cache/lsyscache.c pgsql/src/backend/utils/cache/lsyscache.c
*** pgsql.orig/src/backend/utils/cache/lsyscache.c	2007-04-04 10:12:37.000000000 +0200
--- pgsql/src/backend/utils/cache/lsyscache.c	2007-04-04 12:57:20.000000000 +0200
***************
*** 15,25 ****
--- 15,30 ----
   */
  #include "postgres.h"
  
+ #include "access/genam.h"
  #include "access/hash.h"
+ #include "access/heapam.h"
  #include "access/nbtree.h"
  #include "bootstrap/bootstrap.h"
+ #include "catalog/dependency.h"
+ #include "catalog/indexing.h"
  #include "catalog/pg_amop.h"
  #include "catalog/pg_amproc.h"
+ #include "catalog/pg_depend.h" 
  #include "catalog/pg_constraint.h"
  #include "catalog/pg_namespace.h"
  #include "catalog/pg_opclass.h"
***************
*** 32,37 ****
--- 37,43 ----
  #include "utils/array.h"
  #include "utils/builtins.h"
  #include "utils/datum.h"
+ #include "utils/fmgroids.h"
  #include "utils/lsyscache.h"
  #include "utils/syscache.h"
  
*************** get_relid_attribute_name(Oid relid, Attr
*** 786,791 ****
--- 792,855 ----
  }
  
  /*
+  * get_relid_attribute_sequence
+  *     Expose pg_get_serial_sequence() internally.
+  *     Assumes that attnum is valid for the table.
+  */
+ Oid
+ get_relid_att_serial_sequence(Oid relid, AttrNumber attnum)
+ {
+ 	Oid			sequenceId = InvalidOid;
+ 	Relation	depRel;
+ 	ScanKeyData key[3];
+ 	SysScanDesc scan;
+ 	HeapTuple	tup;
+ 
+ 	/* Search the dependency table for the dependent sequence */
+ 	depRel = heap_open(DependRelationId, AccessShareLock);
+ 
+ 	ScanKeyInit(&key[0],
+ 				Anum_pg_depend_refclassid,
+ 				BTEqualStrategyNumber, F_OIDEQ,
+ 				ObjectIdGetDatum(RelationRelationId));
+ 	ScanKeyInit(&key[1],
+ 				Anum_pg_depend_refobjid,
+ 				BTEqualStrategyNumber, F_OIDEQ,
+ 				ObjectIdGetDatum(relid));
+ 	ScanKeyInit(&key[2],
+ 				Anum_pg_depend_refobjsubid,
+ 				BTEqualStrategyNumber, F_INT4EQ,
+ 				Int32GetDatum(attnum));
+ 
+ 	scan = systable_beginscan(depRel, DependReferenceIndexId, true,
+ 							  SnapshotNow, 3, key);
+ 
+ 	while (HeapTupleIsValid(tup = systable_getnext(scan)))
+ 	{
+ 		Form_pg_depend deprec = (Form_pg_depend) GETSTRUCT(tup);
+ 
+ 		/*
+ 		 * We assume any auto dependency of a sequence on a column must be
+ 		 * what we are looking for.  (We need the relkind test because indexes
+ 		 * can also have auto dependencies on columns.)
+ 		 */
+ 		if (deprec->classid == RelationRelationId &&
+ 			deprec->objsubid == 0 &&
+ 			deprec->deptype == DEPENDENCY_AUTO &&
+ 			get_rel_relkind(deprec->objid) == RELKIND_SEQUENCE)
+ 		{
+ 			sequenceId = deprec->objid;
+ 			break;
+ 		}
+ 	}
+ 
+ 	systable_endscan(scan);
+ 	heap_close(depRel, AccessShareLock);
+ 
+ 	return sequenceId;
+ }
+ 
+ /*
   * get_attnum
   *
   *		Given the relation id and the attribute name,
diff -dcrpN pgsql.orig/src/backend/utils/cache/relcache.c pgsql/src/backend/utils/cache/relcache.c
*** pgsql.orig/src/backend/utils/cache/relcache.c	2007-03-30 09:33:56.000000000 +0200
--- pgsql/src/backend/utils/cache/relcache.c	2007-04-04 14:32:06.000000000 +0200
*************** RelationBuildLocalRelation(const char *r
*** 2301,2306 ****
--- 2301,2308 ----
  	for (i = 0; i < natts; i++)
  	{
  		rel->rd_att->attrs[i]->attnotnull = tupDesc->attrs[i]->attnotnull;
+ 		rel->rd_att->attrs[i]->attidentity = tupDesc->attrs[i]->attidentity;
+ 		rel->rd_att->attrs[i]->attgenerated = tupDesc->attrs[i]->attgenerated;
  		has_not_null |= tupDesc->attrs[i]->attnotnull;
  	}
  
diff -dcrpN pgsql.orig/src/bin/pg_dump/pg_dump.c pgsql/src/bin/pg_dump/pg_dump.c
*** pgsql.orig/src/bin/pg_dump/pg_dump.c	2007-04-04 10:12:40.000000000 +0200
--- pgsql/src/bin/pg_dump/pg_dump.c	2007-04-04 12:57:20.000000000 +0200
*************** dumpTableData_insert(Archive *fout, void
*** 1192,1197 ****
--- 1192,1199 ----
  				appendPQExpBuffer(q, ") ");
  				archputs(q->data, fout);
  			}
+ 			if (tbinfo->hasforceddef)
+ 				archprintf(fout, "OVERRIDING SYSTEM VALUE ");
  			archprintf(fout, "VALUES (");
  			for (field = 0; field < nfields; field++)
  			{
*************** dumpTableData(Archive *fout, TableDataIn
*** 1293,1300 ****
  		/* must use 2 steps here 'cause fmtId is nonreentrant */
  		appendPQExpBuffer(copyBuf, "COPY %s ",
  						  fmtId(tbinfo->dobj.name));
! 		appendPQExpBuffer(copyBuf, "%s %sFROM stdin;\n",
  						  fmtCopyColumnList(tbinfo),
  					  (tdinfo->oids && tbinfo->hasoids) ? "WITH OIDS " : "");
  		copyStmt = copyBuf->data;
  	}
--- 1295,1303 ----
  		/* must use 2 steps here 'cause fmtId is nonreentrant */
  		appendPQExpBuffer(copyBuf, "COPY %s ",
  						  fmtId(tbinfo->dobj.name));
! 		appendPQExpBuffer(copyBuf, "%s %s%sFROM stdin;\n",
  						  fmtCopyColumnList(tbinfo),
+ 					  tbinfo->hasforceddef ? "OVERRIDING SYSTEM VALUE " : "",
  					  (tdinfo->oids && tbinfo->hasoids) ? "WITH OIDS " : "");
  		copyStmt = copyBuf->data;
  	}
*************** getTableAttrs(TableInfo *tblinfo, int nu
*** 4282,4287 ****
--- 4285,4292 ----
  	int			i_atthasdef;
  	int			i_attisdropped;
  	int			i_attislocal;
+ 	int			i_attidentity;
+ 	int			i_attgenerated;
  	PGresult   *res;
  	int			ntups;
  	bool		hasdefaults;
*************** getTableAttrs(TableInfo *tblinfo, int nu
*** 4319,4330 ****
  
  		resetPQExpBuffer(q);
  
! 		if (g_fout->remoteVersion >= 70300)
  		{
  			/* need left join here to not fail on dropped columns ... */
  			appendPQExpBuffer(q, "SELECT a.attnum, a.attname, a.atttypmod, a.attstattarget, a.attstorage, t.typstorage, "
  				  "a.attnotnull, a.atthasdef, a.attisdropped, a.attislocal, "
! 				   "pg_catalog.format_type(t.oid,a.atttypmod) as atttypname "
  			 "from pg_catalog.pg_attribute a left join pg_catalog.pg_type t "
  							  "on a.atttypid = t.oid "
  							  "where a.attrelid = '%u'::pg_catalog.oid "
--- 4324,4350 ----
  
  		resetPQExpBuffer(q);
  
! 		if (g_fout->remoteVersion >= 80300)
  		{
  			/* need left join here to not fail on dropped columns ... */
  			appendPQExpBuffer(q, "SELECT a.attnum, a.attname, a.atttypmod, a.attstattarget, a.attstorage, t.typstorage, "
  				  "a.attnotnull, a.atthasdef, a.attisdropped, a.attislocal, "
! 				   "pg_catalog.format_type(t.oid,a.atttypmod) as atttypname, "
! 				   "a.attidentity, a.attgenerated "
! 			 "from pg_catalog.pg_attribute a left join pg_catalog.pg_type t "
! 							  "on a.atttypid = t.oid "
! 							  "where a.attrelid = '%u'::pg_catalog.oid "
! 							  "and a.attnum > 0::pg_catalog.int2 "
! 							  "order by a.attrelid, a.attnum",
! 							  tbinfo->dobj.catId.oid);
! 		}
! 		else if (g_fout->remoteVersion >= 70300)
! 		{
! 			/* need left join here to not fail on dropped columns ... */
! 			appendPQExpBuffer(q, "SELECT a.attnum, a.attname, a.atttypmod, a.attstattarget, a.attstorage, t.typstorage, "
! 				  "a.attnotnull, a.atthasdef, a.attisdropped, a.attislocal, "
! 				   "pg_catalog.format_type(t.oid,a.atttypmod) as atttypname, "
! 				   "false as attidentity, false as attgenerated "
  			 "from pg_catalog.pg_attribute a left join pg_catalog.pg_type t "
  							  "on a.atttypid = t.oid "
  							  "where a.attrelid = '%u'::pg_catalog.oid "
*************** getTableAttrs(TableInfo *tblinfo, int nu
*** 4341,4347 ****
  			 */
  			appendPQExpBuffer(q, "SELECT a.attnum, a.attname, a.atttypmod, -1 as attstattarget, a.attstorage, t.typstorage, "
  							  "a.attnotnull, a.atthasdef, false as attisdropped, false as attislocal, "
! 							  "format_type(t.oid,a.atttypmod) as atttypname "
  							  "from pg_attribute a left join pg_type t "
  							  "on a.atttypid = t.oid "
  							  "where a.attrelid = '%u'::oid "
--- 4361,4368 ----
  			 */
  			appendPQExpBuffer(q, "SELECT a.attnum, a.attname, a.atttypmod, -1 as attstattarget, a.attstorage, t.typstorage, "
  							  "a.attnotnull, a.atthasdef, false as attisdropped, false as attislocal, "
! 							  "format_type(t.oid,a.atttypmod) as atttypname, "
! 							  "false as attidentity, false as attgenerated "
  							  "from pg_attribute a left join pg_type t "
  							  "on a.atttypid = t.oid "
  							  "where a.attrelid = '%u'::oid "
*************** getTableAttrs(TableInfo *tblinfo, int nu
*** 4354,4360 ****
  			/* format_type not available before 7.1 */
  			appendPQExpBuffer(q, "SELECT attnum, attname, atttypmod, -1 as attstattarget, attstorage, attstorage as typstorage, "
  							  "attnotnull, atthasdef, false as attisdropped, false as attislocal, "
! 							  "(select typname from pg_type where oid = atttypid) as atttypname "
  							  "from pg_attribute a "
  							  "where attrelid = '%u'::oid "
  							  "and attnum > 0::int2 "
--- 4375,4382 ----
  			/* format_type not available before 7.1 */
  			appendPQExpBuffer(q, "SELECT attnum, attname, atttypmod, -1 as attstattarget, attstorage, attstorage as typstorage, "
  							  "attnotnull, atthasdef, false as attisdropped, false as attislocal, "
! 							  "(select typname from pg_type where oid = atttypid) as atttypname, "
! 							  "false as attidentity, false as attgenerated "
  							  "from pg_attribute a "
  							  "where attrelid = '%u'::oid "
  							  "and attnum > 0::int2 "
*************** getTableAttrs(TableInfo *tblinfo, int nu
*** 4378,4383 ****
--- 4400,4407 ----
  		i_atthasdef = PQfnumber(res, "atthasdef");
  		i_attisdropped = PQfnumber(res, "attisdropped");
  		i_attislocal = PQfnumber(res, "attislocal");
+ 		i_attidentity = PQfnumber(res, "attidentity");
+ 		i_attgenerated = PQfnumber(res, "attgenerated");
  
  		tbinfo->numatts = ntups;
  		tbinfo->attnames = (char **) malloc(ntups * sizeof(char *));
*************** getTableAttrs(TableInfo *tblinfo, int nu
*** 4388,4393 ****
--- 4412,4419 ----
  		tbinfo->typstorage = (char *) malloc(ntups * sizeof(char));
  		tbinfo->attisdropped = (bool *) malloc(ntups * sizeof(bool));
  		tbinfo->attislocal = (bool *) malloc(ntups * sizeof(bool));
+ 		tbinfo->attidentity = (bool *) malloc(ntups * sizeof(bool));
+ 		tbinfo->attgenerated = (bool *) malloc(ntups * sizeof(bool));
  		tbinfo->notnull = (bool *) malloc(ntups * sizeof(bool));
  		tbinfo->attrdefs = (AttrDefInfo **) malloc(ntups * sizeof(AttrDefInfo *));
  		tbinfo->inhAttrs = (bool *) malloc(ntups * sizeof(bool));
*************** getTableAttrs(TableInfo *tblinfo, int nu
*** 4411,4416 ****
--- 4437,4445 ----
  			tbinfo->typstorage[j] = *(PQgetvalue(res, j, i_typstorage));
  			tbinfo->attisdropped[j] = (PQgetvalue(res, j, i_attisdropped)[0] == 't');
  			tbinfo->attislocal[j] = (PQgetvalue(res, j, i_attislocal)[0] == 't');
+ 			tbinfo->attidentity[j] = (PQgetvalue(res, j, i_attidentity)[0] == 't');
+ 			tbinfo->attgenerated[j] = (PQgetvalue(res, j, i_attgenerated)[0] == 't');
+ 			tbinfo->hasforceddef |= tbinfo->attgenerated[j];
  			tbinfo->notnull[j] = (PQgetvalue(res, j, i_attnotnull)[0] == 't');
  			tbinfo->attrdefs[j] = NULL; /* fix below */
  			if (PQgetvalue(res, j, i_atthasdef)[0] == 't')
*************** dumpTableSchema(Archive *fout, TableInfo
*** 7973,7980 ****
  				/*
  				 * Default value --- suppress if inherited or to be printed
  				 * separately.
  				 */
! 				if (tbinfo->attrdefs[j] != NULL &&
  					!tbinfo->inhAttrDef[j] &&
  					!tbinfo->attrdefs[j]->separate)
  					appendPQExpBuffer(q, " DEFAULT %s",
--- 8002,8018 ----
  				/*
  				 * Default value --- suppress if inherited or to be printed
  				 * separately.
+ 				 * A GENERATED column cannot be built from building block
+ 				 * such as a SERIAL or IDENTITY column, only ADDed or DROPped.
+ 				 * Hence emit the GENERATED property in the schema itself.
  				 */
! 				if (tbinfo->attgenerated[j] &&
! 					!tbinfo->attidentity[j])
! 				{
! 					appendPQExpBuffer(q, " GENERATED ALWAYS AS ( %s )",
! 									tbinfo->attrdefs[j]->adef_expr);
! 				}
! 				else if (tbinfo->attrdefs[j] != NULL &&
  					!tbinfo->inhAttrDef[j] &&
  					!tbinfo->attrdefs[j]->separate)
  					appendPQExpBuffer(q, " DEFAULT %s",
*************** dumpAttrDef(Archive *fout, AttrDefInfo *
*** 8145,8156 ****
  	q = createPQExpBuffer();
  	delq = createPQExpBuffer();
  
! 	appendPQExpBuffer(q, "ALTER TABLE %s ",
  					  fmtId(tbinfo->dobj.name));
! 	appendPQExpBuffer(q, "ALTER COLUMN %s SET DEFAULT %s;\n",
  					  fmtId(tbinfo->attnames[adnum - 1]),
  					  adinfo->adef_expr);
  
  	/*
  	 * DROP must be fully qualified in case same name appears in pg_catalog
  	 */
--- 8183,8209 ----
  	q = createPQExpBuffer();
  	delq = createPQExpBuffer();
  
! 	if (tbinfo->attidentity[adnum - 1] ||
! 		!tbinfo->attgenerated[adnum - 1])
! 	{
! 		appendPQExpBuffer(q, "ALTER TABLE %s ",
  					  fmtId(tbinfo->dobj.name));
! 		appendPQExpBuffer(q, "ALTER COLUMN %s SET DEFAULT %s;\n",
  					  fmtId(tbinfo->attnames[adnum - 1]),
  					  adinfo->adef_expr);
  
+ 		if (tbinfo->attidentity[adnum - 1])
+ 		{
+ 			appendPQExpBuffer(q, "ALTER TABLE %s",
+ 						fmtId(tbinfo->dobj.name));
+ 			appendPQExpBuffer(q, " ALTER %s",
+ 						fmtId(tbinfo->attnames[adnum - 1]));
+ 			appendPQExpBuffer(q, " SET GENERATED %s AS IDENTITY;\n",
+ 						tbinfo->attgenerated[adnum - 1] ?
+ 							"ALWAYS" : "BY DEFAULT");
+ 		}
+ 	}
+ 
  	/*
  	 * DROP must be fully qualified in case same name appears in pg_catalog
  	 */
diff -dcrpN pgsql.orig/src/bin/pg_dump/pg_dump.h pgsql/src/bin/pg_dump/pg_dump.h
*** pgsql.orig/src/bin/pg_dump/pg_dump.h	2007-03-23 12:18:57.000000000 +0100
--- pgsql/src/bin/pg_dump/pg_dump.h	2007-04-04 12:57:20.000000000 +0200
*************** typedef struct _tableInfo
*** 258,263 ****
--- 258,266 ----
  	char	   *typstorage;		/* type storage scheme */
  	bool	   *attisdropped;	/* true if attr is dropped; don't dump it */
  	bool	   *attislocal;		/* true if attr has local definition */
+ 	bool	   *attidentity;	/* true if attr is GENERATED AS IDENTITY */
+ 	bool	   *attgenerated;	/* true if attr is GENERATED ALWAYS */
+ 	bool	    hasforceddef;	/* true if any of the attrs is GENERATED ALWAYS */
  
  	/*
  	 * Note: we need to store per-attribute notnull, default, and constraint
diff -dcrpN pgsql.orig/src/include/catalog/heap.h pgsql/src/include/catalog/heap.h
*** pgsql.orig/src/include/catalog/heap.h	2007-01-10 19:59:08.000000000 +0100
--- pgsql/src/include/catalog/heap.h	2007-04-04 12:57:20.000000000 +0200
*************** typedef struct RawColumnDefault
*** 21,26 ****
--- 21,28 ----
  {
  	AttrNumber	attnum;			/* attribute to attach default to */
  	Node	   *raw_default;	/* default value (untransformed parse tree) */
+ 	bool		is_identity;		/* column is GENERATED AS IDENTITY */
+ 	bool		is_generated;		/* column is GENERATED ALWAYS */
  } RawColumnDefault;
  
  typedef struct CookedConstraint
*************** typedef struct CookedConstraint
*** 29,34 ****
--- 31,37 ----
  	char	   *name;			/* name, or NULL if none */
  	AttrNumber	attnum;			/* which attr (only for DEFAULT) */
  	Node	   *expr;			/* transformed default or check expr */
+ 	bool		is_generated;		/* GENERATED ALWAYS */
  } CookedConstraint;
  
  extern Relation heap_create(const char *relname,
*************** extern List *AddRelationRawConstraints(R
*** 71,83 ****
  						  List *rawColDefaults,
  						  List *rawConstraints);
  
! extern void StoreAttrDefault(Relation rel, AttrNumber attnum, char *adbin);
  
  extern Node *cookDefault(ParseState *pstate,
  			Node *raw_default,
  			Oid atttypid,
  			int32 atttypmod,
! 			char *attname);
  
  extern int RemoveRelConstraints(Relation rel, const char *constrName,
  					 DropBehavior behavior);
--- 74,87 ----
  						  List *rawColDefaults,
  						  List *rawConstraints);
  
! extern void StoreAttrDefault(Relation rel, AttrNumber attnum, char *adbin, bool attidentity, bool attgenerated);
  
  extern Node *cookDefault(ParseState *pstate,
  			Node *raw_default,
  			Oid atttypid,
  			int32 atttypmod,
! 			char *attname,
! 			bool is_generated);
  
  extern int RemoveRelConstraints(Relation rel, const char *constrName,
  					 DropBehavior behavior);
diff -dcrpN pgsql.orig/src/include/catalog/pg_attribute.h pgsql/src/include/catalog/pg_attribute.h
*** pgsql.orig/src/include/catalog/pg_attribute.h	2007-01-26 18:53:15.000000000 +0100
--- pgsql/src/include/catalog/pg_attribute.h	2007-04-04 12:57:20.000000000 +0200
*************** CATALOG(pg_attribute,1249) BKI_BOOTSTRAP
*** 149,154 ****
--- 149,160 ----
  
  	/* Number of times inherited from direct parent relation(s) */
  	int4		attinhcount;
+ 
+ 	/* GENERATED ... AS IDENTITY or SERIAL */
+ 	bool		attidentity;
+ 
+ 	/* GENERATED ALWAYS */
+ 	bool		attgenerated;
  } FormData_pg_attribute;
  
  /*
*************** CATALOG(pg_attribute,1249) BKI_BOOTSTRAP
*** 157,163 ****
   * because of alignment padding at the end of the struct.)
   */
  #define ATTRIBUTE_TUPLE_SIZE \
! 	(offsetof(FormData_pg_attribute,attinhcount) + sizeof(int4))
  
  /* ----------------
   *		Form_pg_attribute corresponds to a pointer to a tuple with
--- 163,169 ----
   * because of alignment padding at the end of the struct.)
   */
  #define ATTRIBUTE_TUPLE_SIZE \
! 	(offsetof(FormData_pg_attribute,attgenerated) + sizeof(bool))
  
  /* ----------------
   *		Form_pg_attribute corresponds to a pointer to a tuple with
*************** typedef FormData_pg_attribute *Form_pg_a
*** 171,177 ****
   * ----------------
   */
  
! #define Natts_pg_attribute				17
  #define Anum_pg_attribute_attrelid		1
  #define Anum_pg_attribute_attname		2
  #define Anum_pg_attribute_atttypid		3
--- 177,183 ----
   * ----------------
   */
  
! #define Natts_pg_attribute				19
  #define Anum_pg_attribute_attrelid		1
  #define Anum_pg_attribute_attname		2
  #define Anum_pg_attribute_atttypid		3
*************** typedef FormData_pg_attribute *Form_pg_a
*** 189,194 ****
--- 195,202 ----
  #define Anum_pg_attribute_attisdropped	15
  #define Anum_pg_attribute_attislocal	16
  #define Anum_pg_attribute_attinhcount	17
+ #define Anum_pg_attribute_attidentity	18
+ #define Anum_pg_attribute_attgenerated	19
  
  
  
*************** typedef FormData_pg_attribute *Form_pg_a
*** 222,455 ****
   * ----------------
   */
  #define Schema_pg_type \
! { 1247, {"typname"},	   19, -1, NAMEDATALEN, 1, 0, -1, -1, false, 'p', 'i', true, false, false, true, 0 }, \
! { 1247, {"typnamespace"},  26, -1,	4,	2, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
! { 1247, {"typowner"},	   26, -1,	4,	3, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
! { 1247, {"typlen"},		   21, -1,	2,	4, 0, -1, -1, true, 'p', 's', true, false, false, true, 0 }, \
! { 1247, {"typbyval"},	   16, -1,	1,	5, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
! { 1247, {"typtype"},	   18, -1,	1,	6, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
! { 1247, {"typisdefined"},  16, -1,	1,	7, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
! { 1247, {"typdelim"},	   18, -1,	1,	8, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
! { 1247, {"typrelid"},	   26, -1,	4,	9, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
! { 1247, {"typelem"},	   26, -1,	4, 10, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
! { 1247, {"typinput"},	   24, -1,	4, 11, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
! { 1247, {"typoutput"},	   24, -1,	4, 12, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
! { 1247, {"typreceive"},    24, -1,	4, 13, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
! { 1247, {"typsend"},	   24, -1,	4, 14, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
! { 1247, {"typmodin"},	   24, -1,	4, 15, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
! { 1247, {"typmodout"},	   24, -1,	4, 16, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
! { 1247, {"typanalyze"},    24, -1,	4, 17, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
! { 1247, {"typalign"},	   18, -1,	1, 18, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
! { 1247, {"typstorage"},    18, -1,	1, 19, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
! { 1247, {"typnotnull"},    16, -1,	1, 20, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
! { 1247, {"typbasetype"},   26, -1,	4, 21, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
! { 1247, {"typtypmod"},	   23, -1,	4, 22, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
! { 1247, {"typndims"},	   23, -1,	4, 23, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
! { 1247, {"typdefaultbin"}, 25, -1, -1, 24, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
! { 1247, {"typdefault"},    25, -1, -1, 25, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0 }
  
! DATA(insert ( 1247 typname			19 -1 NAMEDATALEN	1 0 -1 -1 f p i t f f t 0));
! DATA(insert ( 1247 typnamespace		26 -1 4   2 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1247 typowner			26 -1 4   3 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1247 typlen			21 -1 2   4 0 -1 -1 t p s t f f t 0));
! DATA(insert ( 1247 typbyval			16 -1 1   5 0 -1 -1 t p c t f f t 0));
! DATA(insert ( 1247 typtype			18 -1 1   6 0 -1 -1 t p c t f f t 0));
! DATA(insert ( 1247 typisdefined		16 -1 1   7 0 -1 -1 t p c t f f t 0));
! DATA(insert ( 1247 typdelim			18 -1 1   8 0 -1 -1 t p c t f f t 0));
! DATA(insert ( 1247 typrelid			26 -1 4   9 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1247 typelem			26 -1 4  10 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1247 typinput			24 -1 4  11 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1247 typoutput		24 -1 4  12 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1247 typreceive		24 -1 4  13 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1247 typsend			24 -1 4  14 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1247 typmodin			24 -1 4  15 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1247 typmodout		24 -1 4  16 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1247 typanalyze		24 -1 4  17 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1247 typalign			18 -1 1  18 0 -1 -1 t p c t f f t 0));
! DATA(insert ( 1247 typstorage		18 -1 1  19 0 -1 -1 t p c t f f t 0));
! DATA(insert ( 1247 typnotnull		16 -1 1  20 0 -1 -1 t p c t f f t 0));
! DATA(insert ( 1247 typbasetype		26 -1 4  21 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1247 typtypmod		23 -1 4  22 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1247 typndims			23 -1 4  23 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1247 typdefaultbin	25 -1 -1 24 0 -1 -1 f x i f f f t 0));
! DATA(insert ( 1247 typdefault		25 -1 -1 25 0 -1 -1 f x i f f f t 0));
! DATA(insert ( 1247 ctid				27 0  6  -1 0 -1 -1 f p s t f f t 0));
! DATA(insert ( 1247 oid				26 0  4  -2 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1247 xmin				28 0  4  -3 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1247 cmin				29 0  4  -4 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1247 xmax				28 0  4  -5 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1247 cmax				29 0  4  -6 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1247 tableoid			26 0  4  -7 0 -1 -1 t p i t f f t 0));
  
  /* ----------------
   *		pg_proc
   * ----------------
   */
  #define Schema_pg_proc \
! { 1255, {"proname"},			19, -1, NAMEDATALEN,  1, 0, -1, -1, false, 'p', 'i', true, false, false, true, 0 }, \
! { 1255, {"pronamespace"},		26, -1, 4,	2, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
! { 1255, {"proowner"},			26, -1, 4,	3, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
! { 1255, {"prolang"},			26, -1, 4,	4, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
! { 1255, {"procost"},		   700, -1, 4,	5, 0, -1, -1, false, 'p', 'i', true, false, false, true, 0 }, \
! { 1255, {"prorows"},		   700, -1, 4,	6, 0, -1, -1, false, 'p', 'i', true, false, false, true, 0 }, \
! { 1255, {"proisagg"},			16, -1, 1,	7, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
! { 1255, {"prosecdef"},			16, -1, 1,	8, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
! { 1255, {"proisstrict"},		16, -1, 1,	9, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
! { 1255, {"proretset"},			16, -1, 1, 10, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
! { 1255, {"provolatile"},		18, -1, 1, 11, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
! { 1255, {"pronargs"},			21, -1, 2, 12, 0, -1, -1, true, 'p', 's', true, false, false, true, 0 }, \
! { 1255, {"prorettype"},			26, -1, 4, 13, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
! { 1255, {"proargtypes"},		30, -1, -1, 14, 1, -1, -1, false, 'p', 'i', true, false, false, true, 0 }, \
! { 1255, {"proallargtypes"},   1028, -1, -1, 15, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
! { 1255, {"proargmodes"},	  1002, -1, -1, 16, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
! { 1255, {"proargnames"},	  1009, -1, -1, 17, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
! { 1255, {"prosrc"},				25, -1, -1, 18, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
! { 1255, {"probin"},				17, -1, -1, 19, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
! { 1255, {"proacl"},			  1034, -1, -1, 20, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0 }
  
! DATA(insert ( 1255 proname			19 -1 NAMEDATALEN	1 0 -1 -1 f p i t f f t 0));
! DATA(insert ( 1255 pronamespace		26 -1 4   2 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1255 proowner			26 -1 4   3 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1255 prolang			26 -1 4   4 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1255 procost		   700 -1 4   5 0 -1 -1 f p i t f f t 0));
! DATA(insert ( 1255 prorows		   700 -1 4   6 0 -1 -1 f p i t f f t 0));
! DATA(insert ( 1255 proisagg			16 -1 1   7 0 -1 -1 t p c t f f t 0));
! DATA(insert ( 1255 prosecdef		16 -1 1   8 0 -1 -1 t p c t f f t 0));
! DATA(insert ( 1255 proisstrict		16 -1 1   9 0 -1 -1 t p c t f f t 0));
! DATA(insert ( 1255 proretset		16 -1 1  10 0 -1 -1 t p c t f f t 0));
! DATA(insert ( 1255 provolatile		18 -1 1  11 0 -1 -1 t p c t f f t 0));
! DATA(insert ( 1255 pronargs			21 -1 2  12 0 -1 -1 t p s t f f t 0));
! DATA(insert ( 1255 prorettype		26 -1 4  13 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1255 proargtypes		30 -1 -1 14 1 -1 -1 f p i t f f t 0));
! DATA(insert ( 1255 proallargtypes 1028 -1 -1 15 1 -1 -1 f x i f f f t 0));
! DATA(insert ( 1255 proargmodes	  1002 -1 -1 16 1 -1 -1 f x i f f f t 0));
! DATA(insert ( 1255 proargnames	  1009 -1 -1 17 1 -1 -1 f x i f f f t 0));
! DATA(insert ( 1255 prosrc			25 -1 -1 18 0 -1 -1 f x i f f f t 0));
! DATA(insert ( 1255 probin			17 -1 -1 19 0 -1 -1 f x i f f f t 0));
! DATA(insert ( 1255 proacl		  1034 -1 -1 20 1 -1 -1 f x i f f f t 0));
! DATA(insert ( 1255 ctid				27 0  6  -1 0 -1 -1 f p s t f f t 0));
! DATA(insert ( 1255 oid				26 0  4  -2 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1255 xmin				28 0  4  -3 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1255 cmin				29 0  4  -4 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1255 xmax				28 0  4  -5 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1255 cmax				29 0  4  -6 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1255 tableoid			26 0  4  -7 0 -1 -1 t p i t f f t 0));
  
  /* ----------------
   *		pg_attribute
   * ----------------
   */
  #define Schema_pg_attribute \
! { 1249, {"attrelid"},	  26, -1,	4,	1, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
! { 1249, {"attname"},	  19, -1, NAMEDATALEN,	2, 0, -1, -1, false, 'p', 'i', true, false, false, true, 0 }, \
! { 1249, {"atttypid"},	  26, -1,	4,	3, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
! { 1249, {"attstattarget"}, 23, -1,	4,	4, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
! { 1249, {"attlen"},		  21, -1,	2,	5, 0, -1, -1, true, 'p', 's', true, false, false, true, 0 }, \
! { 1249, {"attnum"},		  21, -1,	2,	6, 0, -1, -1, true, 'p', 's', true, false, false, true, 0 }, \
! { 1249, {"attndims"},	  23, -1,	4,	7, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
! { 1249, {"attcacheoff"},  23, -1,	4,	8, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
! { 1249, {"atttypmod"},	  23, -1,	4,	9, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
! { 1249, {"attbyval"},	  16, -1,	1, 10, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
! { 1249, {"attstorage"},   18, -1,	1, 11, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
! { 1249, {"attalign"},	  18, -1,	1, 12, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
! { 1249, {"attnotnull"},   16, -1,	1, 13, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
! { 1249, {"atthasdef"},	  16, -1,	1, 14, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
! { 1249, {"attisdropped"}, 16, -1,	1, 15, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
! { 1249, {"attislocal"},   16, -1,	1, 16, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
! { 1249, {"attinhcount"},  23, -1,	4, 17, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }
  
! DATA(insert ( 1249 attrelid			26 -1  4   1 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1249 attname			19 -1 NAMEDATALEN  2 0 -1 -1 f p i t f f t 0));
! DATA(insert ( 1249 atttypid			26 -1  4   3 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1249 attstattarget	23 -1  4   4 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1249 attlen			21 -1  2   5 0 -1 -1 t p s t f f t 0));
! DATA(insert ( 1249 attnum			21 -1  2   6 0 -1 -1 t p s t f f t 0));
! DATA(insert ( 1249 attndims			23 -1  4   7 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1249 attcacheoff		23 -1  4   8 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1249 atttypmod		23 -1  4   9 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1249 attbyval			16 -1  1  10 0 -1 -1 t p c t f f t 0));
! DATA(insert ( 1249 attstorage		18 -1  1  11 0 -1 -1 t p c t f f t 0));
! DATA(insert ( 1249 attalign			18 -1  1  12 0 -1 -1 t p c t f f t 0));
! DATA(insert ( 1249 attnotnull		16 -1  1  13 0 -1 -1 t p c t f f t 0));
! DATA(insert ( 1249 atthasdef		16 -1  1  14 0 -1 -1 t p c t f f t 0));
! DATA(insert ( 1249 attisdropped		16 -1  1  15 0 -1 -1 t p c t f f t 0));
! DATA(insert ( 1249 attislocal		16 -1  1  16 0 -1 -1 t p c t f f t 0));
! DATA(insert ( 1249 attinhcount		23 -1  4  17 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1249 ctid				27 0  6  -1 0 -1 -1 f p s t f f t 0));
  /* no OIDs in pg_attribute */
! DATA(insert ( 1249 xmin				28 0  4  -3 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1249 cmin				29 0  4  -4 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1249 xmax				28 0  4  -5 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1249 cmax				29 0  4  -6 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1249 tableoid			26 0  4  -7 0 -1 -1 t p i t f f t 0));
  
  /* ----------------
   *		pg_class
   * ----------------
   */
  #define Schema_pg_class \
! { 1259, {"relname"},	   19, -1, NAMEDATALEN, 1, 0, -1, -1, false, 'p', 'i', true, false, false, true, 0 }, \
! { 1259, {"relnamespace"},  26, -1,	4,	2, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
! { 1259, {"reltype"},	   26, -1,	4,	3, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
! { 1259, {"relowner"},	   26, -1,	4,	4, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
! { 1259, {"relam"},		   26, -1,	4,	5, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
! { 1259, {"relfilenode"},   26, -1,	4,	6, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
! { 1259, {"reltablespace"}, 26, -1,	4,	7, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
! { 1259, {"relpages"},	   23, -1,	4,	8, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
! { 1259, {"reltuples"},	   700, -1, 4,	9, 0, -1, -1, false, 'p', 'i', true, false, false, true, 0 }, \
! { 1259, {"reltoastrelid"}, 26, -1,	4, 10, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
! { 1259, {"reltoastidxid"}, 26, -1,	4, 11, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
! { 1259, {"relhasindex"},   16, -1,	1, 12, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
! { 1259, {"relisshared"},   16, -1,	1, 13, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
! { 1259, {"relkind"},	   18, -1,	1, 14, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
! { 1259, {"relnatts"},	   21, -1,	2, 15, 0, -1, -1, true, 'p', 's', true, false, false, true, 0 }, \
! { 1259, {"relchecks"},	   21, -1,	2, 16, 0, -1, -1, true, 'p', 's', true, false, false, true, 0 }, \
! { 1259, {"reltriggers"},   21, -1,	2, 17, 0, -1, -1, true, 'p', 's', true, false, false, true, 0 }, \
! { 1259, {"relukeys"},	   21, -1,	2, 18, 0, -1, -1, true, 'p', 's', true, false, false, true, 0 }, \
! { 1259, {"relfkeys"},	   21, -1,	2, 19, 0, -1, -1, true, 'p', 's', true, false, false, true, 0 }, \
! { 1259, {"relrefs"},	   21, -1,	2, 20, 0, -1, -1, true, 'p', 's', true, false, false, true, 0 }, \
! { 1259, {"relhasoids"},    16, -1,	1, 21, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
! { 1259, {"relhaspkey"},    16, -1,	1, 22, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
! { 1259, {"relhasrules"},   16, -1,	1, 23, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
! { 1259, {"relhassubclass"},16, -1,	1, 24, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
! { 1259, {"relfrozenxid"},  28, -1,	4, 25, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
! { 1259, {"relacl"},		 1034, -1, -1, 26, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
! { 1259, {"reloptions"},  1009, -1, -1, 27, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0 }
  
! DATA(insert ( 1259 relname			19 -1 NAMEDATALEN	1 0 -1 -1 f p i t f f t 0));
! DATA(insert ( 1259 relnamespace		26 -1 4   2 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1259 reltype			26 -1 4   3 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1259 relowner			26 -1 4   4 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1259 relam			26 -1 4   5 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1259 relfilenode		26 -1 4   6 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1259 reltablespace	26 -1 4   7 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1259 relpages			23 -1 4   8 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1259 reltuples	   700 -1 4   9 0 -1 -1 f p i t f f t 0));
! DATA(insert ( 1259 reltoastrelid	26 -1 4  10 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1259 reltoastidxid	26 -1 4  11 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1259 relhasindex		16 -1 1  12 0 -1 -1 t p c t f f t 0));
! DATA(insert ( 1259 relisshared		16 -1 1  13 0 -1 -1 t p c t f f t 0));
! DATA(insert ( 1259 relkind			18 -1 1  14 0 -1 -1 t p c t f f t 0));
! DATA(insert ( 1259 relnatts			21 -1 2  15 0 -1 -1 t p s t f f t 0));
! DATA(insert ( 1259 relchecks		21 -1 2  16 0 -1 -1 t p s t f f t 0));
! DATA(insert ( 1259 reltriggers		21 -1 2  17 0 -1 -1 t p s t f f t 0));
! DATA(insert ( 1259 relukeys			21 -1 2  18 0 -1 -1 t p s t f f t 0));
! DATA(insert ( 1259 relfkeys			21 -1 2  19 0 -1 -1 t p s t f f t 0));
! DATA(insert ( 1259 relrefs			21 -1 2  20 0 -1 -1 t p s t f f t 0));
! DATA(insert ( 1259 relhasoids		16 -1 1  21 0 -1 -1 t p c t f f t 0));
! DATA(insert ( 1259 relhaspkey		16 -1 1  22 0 -1 -1 t p c t f f t 0));
! DATA(insert ( 1259 relhasrules		16 -1 1  23 0 -1 -1 t p c t f f t 0));
! DATA(insert ( 1259 relhassubclass	16 -1 1  24 0 -1 -1 t p c t f f t 0));
! DATA(insert ( 1259 relfrozenxid		28 -1 4  25 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1259 relacl		  1034 -1 -1 26 1 -1 -1 f x i f f f t 0));
! DATA(insert ( 1259 reloptions	  1009 -1 -1 27 1 -1 -1 f x i f f f t 0));
! DATA(insert ( 1259 ctid				27 0  6  -1 0 -1 -1 f p s t f f t 0));
! DATA(insert ( 1259 oid				26 0  4  -2 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1259 xmin				28 0  4  -3 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1259 cmin				29 0  4  -4 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1259 xmax				28 0  4  -5 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1259 cmax				29 0  4  -6 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1259 tableoid			26 0  4  -7 0 -1 -1 t p i t f f t 0));
  
  /* ----------------
   *		pg_index
--- 230,468 ----
   * ----------------
   */
  #define Schema_pg_type \
! { 1247, {"typname"},	   19, -1, NAMEDATALEN, 1, 0, -1, -1, false, 'p', 'i', true, false, false, true, 0, false, false }, \
! { 1247, {"typnamespace"},  26, -1,	4,	2, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, false, false }, \
! { 1247, {"typowner"},	   26, -1,	4,	3, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, false, false }, \
! { 1247, {"typlen"},		   21, -1,	2,	4, 0, -1, -1, true, 'p', 's', true, false, false, true, 0, false, false }, \
! { 1247, {"typbyval"},	   16, -1,	1,	5, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, false, false }, \
! { 1247, {"typtype"},	   18, -1,	1,	6, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, false, false }, \
! { 1247, {"typisdefined"},  16, -1,	1,	7, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, false, false }, \
! { 1247, {"typdelim"},	   18, -1,	1,	8, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, false, false }, \
! { 1247, {"typrelid"},	   26, -1,	4,	9, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, false, false }, \
! { 1247, {"typelem"},	   26, -1,	4, 10, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, false, false }, \
! { 1247, {"typinput"},	   24, -1,	4, 11, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, false, false }, \
! { 1247, {"typoutput"},	   24, -1,	4, 12, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, false, false }, \
! { 1247, {"typreceive"},    24, -1,	4, 13, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, false, false }, \
! { 1247, {"typsend"},	   24, -1,	4, 14, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, false, false }, \
! { 1247, {"typmodin"},	   24, -1,	4, 15, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, false, false }, \
! { 1247, {"typmodout"},	   24, -1,	4, 16, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, false, false }, \
! { 1247, {"typanalyze"},    24, -1,	4, 17, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, false, false }, \
! { 1247, {"typalign"},	   18, -1,	1, 18, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, false, false }, \
! { 1247, {"typstorage"},    18, -1,	1, 19, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, false, false }, \
! { 1247, {"typnotnull"},    16, -1,	1, 20, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, false, false }, \
! { 1247, {"typbasetype"},   26, -1,	4, 21, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, false, false }, \
! { 1247, {"typtypmod"},	   23, -1,	4, 22, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, false, false }, \
! { 1247, {"typndims"},	   23, -1,	4, 23, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, false, false }, \
! { 1247, {"typdefaultbin"}, 25, -1, -1, 24, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0, false, false }, \
! { 1247, {"typdefault"},    25, -1, -1, 25, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0, false, false }
  
! DATA(insert ( 1247 typname			19 -1 NAMEDATALEN	1 0 -1 -1 f p i t f f t 0 f f));
! DATA(insert ( 1247 typnamespace		26 -1 4   2 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1247 typowner			26 -1 4   3 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1247 typlen			21 -1 2   4 0 -1 -1 t p s t f f t 0 f f));
! DATA(insert ( 1247 typbyval			16 -1 1   5 0 -1 -1 t p c t f f t 0 f f));
! DATA(insert ( 1247 typtype			18 -1 1   6 0 -1 -1 t p c t f f t 0 f f));
! DATA(insert ( 1247 typisdefined		16 -1 1   7 0 -1 -1 t p c t f f t 0 f f));
! DATA(insert ( 1247 typdelim			18 -1 1   8 0 -1 -1 t p c t f f t 0 f f));
! DATA(insert ( 1247 typrelid			26 -1 4   9 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1247 typelem			26 -1 4  10 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1247 typinput			24 -1 4  11 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1247 typoutput		24 -1 4  12 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1247 typreceive		24 -1 4  13 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1247 typsend			24 -1 4  14 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1247 typmodin			24 -1 4  15 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1247 typmodout		24 -1 4  16 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1247 typanalyze		24 -1 4  17 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1247 typalign			18 -1 1  18 0 -1 -1 t p c t f f t 0 f f));
! DATA(insert ( 1247 typstorage		18 -1 1  19 0 -1 -1 t p c t f f t 0 f f));
! DATA(insert ( 1247 typnotnull		16 -1 1  20 0 -1 -1 t p c t f f t 0 f f));
! DATA(insert ( 1247 typbasetype		26 -1 4  21 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1247 typtypmod		23 -1 4  22 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1247 typndims			23 -1 4  23 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1247 typdefaultbin	25 -1 -1 24 0 -1 -1 f x i f f f t 0 f f));
! DATA(insert ( 1247 typdefault		25 -1 -1 25 0 -1 -1 f x i f f f t 0 f f));
! DATA(insert ( 1247 ctid				27 0  6  -1 0 -1 -1 f p s t f f t 0 f f));
! DATA(insert ( 1247 oid				26 0  4  -2 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1247 xmin				28 0  4  -3 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1247 cmin				29 0  4  -4 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1247 xmax				28 0  4  -5 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1247 cmax				29 0  4  -6 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1247 tableoid			26 0  4  -7 0 -1 -1 t p i t f f t 0 f f));
  
  /* ----------------
   *		pg_proc
   * ----------------
   */
  #define Schema_pg_proc \
! { 1255, {"proname"},			19, -1, NAMEDATALEN,  1, 0, -1, -1, false, 'p', 'i', true, false, false, true, 0, false, false }, \
! { 1255, {"pronamespace"},		26, -1, 4,	2, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, false, false }, \
! { 1255, {"proowner"},			26, -1, 4,	3, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, false, false }, \
! { 1255, {"prolang"},			26, -1, 4,	4, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, false, false }, \
! { 1255, {"procost"},		   700, -1, 4,	5, 0, -1, -1, false, 'p', 'i', true, false, false, true, 0, false, false }, \
! { 1255, {"prorows"},		   700, -1, 4,	6, 0, -1, -1, false, 'p', 'i', true, false, false, true, 0, false, false }, \
! { 1255, {"proisagg"},			16, -1, 1,	7, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, false, false }, \
! { 1255, {"prosecdef"},			16, -1, 1,	8, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, false, false }, \
! { 1255, {"proisstrict"},		16, -1, 1,	9, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, false, false }, \
! { 1255, {"proretset"},			16, -1, 1, 10, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, false, false }, \
! { 1255, {"provolatile"},		18, -1, 1, 11, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, false, false }, \
! { 1255, {"pronargs"},			21, -1, 2, 12, 0, -1, -1, true, 'p', 's', true, false, false, true, 0, false, false }, \
! { 1255, {"prorettype"},			26, -1, 4, 13, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, false, false }, \
! { 1255, {"proargtypes"},		30, -1, -1, 14, 1, -1, -1, false, 'p', 'i', true, false, false, true, 0, false, false }, \
! { 1255, {"proallargtypes"},   1028, -1, -1, 15, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0, false, false }, \
! { 1255, {"proargmodes"},	  1002, -1, -1, 16, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0, false, false }, \
! { 1255, {"proargnames"},	  1009, -1, -1, 17, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0, false, false }, \
! { 1255, {"prosrc"},				25, -1, -1, 18, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0, false, false }, \
! { 1255, {"probin"},				17, -1, -1, 19, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0, false, false }, \
! { 1255, {"proacl"},			  1034, -1, -1, 20, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0, false, false }
  
! DATA(insert ( 1255 proname			19 -1 NAMEDATALEN	1 0 -1 -1 f p i t f f t 0 f f));
! DATA(insert ( 1255 pronamespace		26 -1 4   2 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1255 proowner			26 -1 4   3 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1255 prolang			26 -1 4   4 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1255 procost		   700 -1 4   5 0 -1 -1 f p i t f f t 0 f f));
! DATA(insert ( 1255 prorows		   700 -1 4   6 0 -1 -1 f p i t f f t 0 f f));
! DATA(insert ( 1255 proisagg			16 -1 1   7 0 -1 -1 t p c t f f t 0 f f));
! DATA(insert ( 1255 prosecdef		16 -1 1   8 0 -1 -1 t p c t f f t 0 f f));
! DATA(insert ( 1255 proisstrict		16 -1 1   9 0 -1 -1 t p c t f f t 0 f f));
! DATA(insert ( 1255 proretset		16 -1 1  10 0 -1 -1 t p c t f f t 0 f f));
! DATA(insert ( 1255 provolatile		18 -1 1  11 0 -1 -1 t p c t f f t 0 f f));
! DATA(insert ( 1255 pronargs			21 -1 2  12 0 -1 -1 t p s t f f t 0 f f));
! DATA(insert ( 1255 prorettype		26 -1 4  13 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1255 proargtypes		30 -1 -1 14 1 -1 -1 f p i t f f t 0 f f));
! DATA(insert ( 1255 proallargtypes 1028 -1 -1 15 1 -1 -1 f x i f f f t 0 f f));
! DATA(insert ( 1255 proargmodes	  1002 -1 -1 16 1 -1 -1 f x i f f f t 0 f f));
! DATA(insert ( 1255 proargnames	  1009 -1 -1 17 1 -1 -1 f x i f f f t 0 f f));
! DATA(insert ( 1255 prosrc			25 -1 -1 18 0 -1 -1 f x i f f f t 0 f f));
! DATA(insert ( 1255 probin			17 -1 -1 19 0 -1 -1 f x i f f f t 0 f f));
! DATA(insert ( 1255 proacl		  1034 -1 -1 20 1 -1 -1 f x i f f f t 0 f f));
! DATA(insert ( 1255 ctid				27 0  6  -1 0 -1 -1 f p s t f f t 0 f f));
! DATA(insert ( 1255 oid				26 0  4  -2 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1255 xmin				28 0  4  -3 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1255 cmin				29 0  4  -4 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1255 xmax				28 0  4  -5 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1255 cmax				29 0  4  -6 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1255 tableoid			26 0  4  -7 0 -1 -1 t p i t f f t 0 f f));
  
  /* ----------------
   *		pg_attribute
   * ----------------
   */
  #define Schema_pg_attribute \
! { 1249, {"attrelid"},	  26, -1,	4,	1, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, false, false }, \
! { 1249, {"attname"},	  19, -1, NAMEDATALEN,	2, 0, -1, -1, false, 'p', 'i', true, false, false, true, 0, false, false }, \
! { 1249, {"atttypid"},	  26, -1,	4,	3, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, false, false }, \
! { 1249, {"attstattarget"}, 23, -1,	4,	4, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, false, false }, \
! { 1249, {"attlen"},		  21, -1,	2,	5, 0, -1, -1, true, 'p', 's', true, false, false, true, 0, false, false }, \
! { 1249, {"attnum"},		  21, -1,	2,	6, 0, -1, -1, true, 'p', 's', true, false, false, true, 0, false, false }, \
! { 1249, {"attndims"},	  23, -1,	4,	7, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, false, false }, \
! { 1249, {"attcacheoff"},  23, -1,	4,	8, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, false, false }, \
! { 1249, {"atttypmod"},	  23, -1,	4,	9, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, false, false }, \
! { 1249, {"attbyval"},	  16, -1,	1, 10, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, false, false }, \
! { 1249, {"attstorage"},   18, -1,	1, 11, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, false, false }, \
! { 1249, {"attalign"},	  18, -1,	1, 12, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, false, false }, \
! { 1249, {"attnotnull"},   16, -1,	1, 13, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, false, false }, \
! { 1249, {"atthasdef"},	  16, -1,	1, 14, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, false, false }, \
! { 1249, {"attisdropped"}, 16, -1,	1, 15, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, false, false }, \
! { 1249, {"attislocal"},   16, -1,	1, 16, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, false, false }, \
! { 1249, {"attinhcount"},  23, -1,	4, 17, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, false, false }, \
! { 1249, {"attidentity"},  16, -1,	1, 18, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, false, false }, \
! { 1249, {"attgenerated"}, 16, -1,	1, 19, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, false, false }
  
! 
! DATA(insert ( 1249 attrelid			26 -1  4   1 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1249 attname			19 -1 NAMEDATALEN  2 0 -1 -1 f p i t f f t 0 f f));
! DATA(insert ( 1249 atttypid			26 -1  4   3 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1249 attstattarget	23 -1  4   4 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1249 attlen			21 -1  2   5 0 -1 -1 t p s t f f t 0 f f));
! DATA(insert ( 1249 attnum			21 -1  2   6 0 -1 -1 t p s t f f t 0 f f));
! DATA(insert ( 1249 attndims			23 -1  4   7 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1249 attcacheoff		23 -1  4   8 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1249 atttypmod		23 -1  4   9 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1249 attbyval			16 -1  1  10 0 -1 -1 t p c t f f t 0 f f));
! DATA(insert ( 1249 attstorage		18 -1  1  11 0 -1 -1 t p c t f f t 0 f f));
! DATA(insert ( 1249 attalign			18 -1  1  12 0 -1 -1 t p c t f f t 0 f f));
! DATA(insert ( 1249 attnotnull		16 -1  1  13 0 -1 -1 t p c t f f t 0 f f));
! DATA(insert ( 1249 atthasdef		16 -1  1  14 0 -1 -1 t p c t f f t 0 f f));
! DATA(insert ( 1249 attisdropped		16 -1  1  15 0 -1 -1 t p c t f f t 0 f f));
! DATA(insert ( 1249 attislocal		16 -1  1  16 0 -1 -1 t p c t f f t 0 f f));
! DATA(insert ( 1249 attinhcount		23 -1  4  17 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1249 attidentity		16 -1  1  18 0 -1 -1 t p c t f f t 0 f f));
! DATA(insert ( 1249 attgenerated		16 -1  1  19 0 -1 -1 t p c t f f t 0 f f));
! DATA(insert ( 1249 ctid				27 0  6  -1 0 -1 -1 f p s t f f t 0 f f));
  /* no OIDs in pg_attribute */
! DATA(insert ( 1249 xmin				28 0  4  -3 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1249 cmin				29 0  4  -4 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1249 xmax				28 0  4  -5 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1249 cmax				29 0  4  -6 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1249 tableoid			26 0  4  -7 0 -1 -1 t p i t f f t 0 f f));
  
  /* ----------------
   *		pg_class
   * ----------------
   */
  #define Schema_pg_class \
! { 1259, {"relname"},	   19, -1, NAMEDATALEN, 1, 0, -1, -1, false, 'p', 'i', true, false, false, true, 0, false, false }, \
! { 1259, {"relnamespace"},  26, -1,	4,	2, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, false, false }, \
! { 1259, {"reltype"},	   26, -1,	4,	3, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, false, false }, \
! { 1259, {"relowner"},	   26, -1,	4,	4, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, false, false }, \
! { 1259, {"relam"},		   26, -1,	4,	5, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, false, false }, \
! { 1259, {"relfilenode"},   26, -1,	4,	6, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, false, false }, \
! { 1259, {"reltablespace"}, 26, -1,	4,	7, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, false, false }, \
! { 1259, {"relpages"},	   23, -1,	4,	8, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, false, false }, \
! { 1259, {"reltuples"},	   700, -1, 4,	9, 0, -1, -1, false, 'p', 'i', true, false, false, true, 0, false, false }, \
! { 1259, {"reltoastrelid"}, 26, -1,	4, 10, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, false, false }, \
! { 1259, {"reltoastidxid"}, 26, -1,	4, 11, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, false, false }, \
! { 1259, {"relhasindex"},   16, -1,	1, 12, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, false, false }, \
! { 1259, {"relisshared"},   16, -1,	1, 13, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, false, false }, \
! { 1259, {"relkind"},	   18, -1,	1, 14, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, false, false }, \
! { 1259, {"relnatts"},	   21, -1,	2, 15, 0, -1, -1, true, 'p', 's', true, false, false, true, 0, false, false }, \
! { 1259, {"relchecks"},	   21, -1,	2, 16, 0, -1, -1, true, 'p', 's', true, false, false, true, 0, false, false }, \
! { 1259, {"reltriggers"},   21, -1,	2, 17, 0, -1, -1, true, 'p', 's', true, false, false, true, 0, false, false }, \
! { 1259, {"relukeys"},	   21, -1,	2, 18, 0, -1, -1, true, 'p', 's', true, false, false, true, 0, false, false }, \
! { 1259, {"relfkeys"},	   21, -1,	2, 19, 0, -1, -1, true, 'p', 's', true, false, false, true, 0, false, false }, \
! { 1259, {"relrefs"},	   21, -1,	2, 20, 0, -1, -1, true, 'p', 's', true, false, false, true, 0, false, false }, \
! { 1259, {"relhasoids"},    16, -1,	1, 21, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, false, false }, \
! { 1259, {"relhaspkey"},    16, -1,	1, 22, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, false, false }, \
! { 1259, {"relhasrules"},   16, -1,	1, 23, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, false, false }, \
! { 1259, {"relhassubclass"},16, -1,	1, 24, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, false, false }, \
! { 1259, {"relfrozenxid"},  28, -1,	4, 25, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, false, false }, \
! { 1259, {"relacl"},		 1034, -1, -1, 26, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0, false, false }, \
! { 1259, {"reloptions"},  1009, -1, -1, 27, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0, false, false }
  
! DATA(insert ( 1259 relname			19 -1 NAMEDATALEN	1 0 -1 -1 f p i t f f t 0 f f));
! DATA(insert ( 1259 relnamespace		26 -1 4   2 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1259 reltype			26 -1 4   3 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1259 relowner			26 -1 4   4 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1259 relam			26 -1 4   5 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1259 relfilenode		26 -1 4   6 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1259 reltablespace	26 -1 4   7 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1259 relpages			23 -1 4   8 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1259 reltuples	   700 -1 4   9 0 -1 -1 f p i t f f t 0 f f));
! DATA(insert ( 1259 reltoastrelid	26 -1 4  10 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1259 reltoastidxid	26 -1 4  11 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1259 relhasindex		16 -1 1  12 0 -1 -1 t p c t f f t 0 f f));
! DATA(insert ( 1259 relisshared		16 -1 1  13 0 -1 -1 t p c t f f t 0 f f));
! DATA(insert ( 1259 relkind			18 -1 1  14 0 -1 -1 t p c t f f t 0 f f));
! DATA(insert ( 1259 relnatts			21 -1 2  15 0 -1 -1 t p s t f f t 0 f f));
! DATA(insert ( 1259 relchecks		21 -1 2  16 0 -1 -1 t p s t f f t 0 f f));
! DATA(insert ( 1259 reltriggers		21 -1 2  17 0 -1 -1 t p s t f f t 0 f f));
! DATA(insert ( 1259 relukeys			21 -1 2  18 0 -1 -1 t p s t f f t 0 f f));
! DATA(insert ( 1259 relfkeys			21 -1 2  19 0 -1 -1 t p s t f f t 0 f f));
! DATA(insert ( 1259 relrefs			21 -1 2  20 0 -1 -1 t p s t f f t 0 f f));
! DATA(insert ( 1259 relhasoids		16 -1 1  21 0 -1 -1 t p c t f f t 0 f f));
! DATA(insert ( 1259 relhaspkey		16 -1 1  22 0 -1 -1 t p c t f f t 0 f f));
! DATA(insert ( 1259 relhasrules		16 -1 1  23 0 -1 -1 t p c t f f t 0 f f));
! DATA(insert ( 1259 relhassubclass	16 -1 1  24 0 -1 -1 t p c t f f t 0 f f));
! DATA(insert ( 1259 relfrozenxid		28 -1 4  25 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1259 relacl		  1034 -1 -1 26 1 -1 -1 f x i f f f t 0 f f));
! DATA(insert ( 1259 reloptions	  1009 -1 -1 27 1 -1 -1 f x i f f f t 0 f f));
! DATA(insert ( 1259 ctid				27 0  6  -1 0 -1 -1 f p s t f f t 0 f f));
! DATA(insert ( 1259 oid				26 0  4  -2 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1259 xmin				28 0  4  -3 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1259 cmin				29 0  4  -4 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1259 xmax				28 0  4  -5 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1259 cmax				29 0  4  -6 0 -1 -1 t p i t f f t 0 f f));
! DATA(insert ( 1259 tableoid			26 0  4  -7 0 -1 -1 t p i t f f t 0 f f));
  
  /* ----------------
   *		pg_index
diff -dcrpN pgsql.orig/src/include/catalog/pg_class.h pgsql/src/include/catalog/pg_class.h
*** pgsql.orig/src/include/catalog/pg_class.h	2007-01-26 18:53:15.000000000 +0100
--- pgsql/src/include/catalog/pg_class.h	2007-04-04 12:57:20.000000000 +0200
*************** typedef FormData_pg_class *Form_pg_class
*** 134,140 ****
  /* Note: "3" in the relfrozenxid column stands for FirstNormalTransactionId */
  DATA(insert OID = 1247 (  pg_type		PGNSP 71 PGUID 0 1247 0 0 0 0 0 f f r 25 0 0 0 0 0 t f f f 3   _null_ _null_ ));
  DESCR("");
! DATA(insert OID = 1249 (  pg_attribute	PGNSP 75 PGUID 0 1249 0 0 0 0 0 f f r 17 0 0 0 0 0 f f f f 3 _null_ _null_ ));
  DESCR("");
  DATA(insert OID = 1255 (  pg_proc		PGNSP 81 PGUID 0 1255 0 0 0 0 0 f f r 20 0 0 0 0 0 t f f f 3 _null_ _null_ ));
  DESCR("");
--- 134,140 ----
  /* Note: "3" in the relfrozenxid column stands for FirstNormalTransactionId */
  DATA(insert OID = 1247 (  pg_type		PGNSP 71 PGUID 0 1247 0 0 0 0 0 f f r 25 0 0 0 0 0 t f f f 3   _null_ _null_ ));
  DESCR("");
! DATA(insert OID = 1249 (  pg_attribute	PGNSP 75 PGUID 0 1249 0 0 0 0 0 f f r 19 0 0 0 0 0 f f f f 3 _null_ _null_ ));
  DESCR("");
  DATA(insert OID = 1255 (  pg_proc		PGNSP 81 PGUID 0 1255 0 0 0 0 0 f f r 20 0 0 0 0 0 t f f f 3 _null_ _null_ ));
  DESCR("");
diff -dcrpN pgsql.orig/src/include/nodes/parsenodes.h pgsql/src/include/nodes/parsenodes.h
*** pgsql.orig/src/include/nodes/parsenodes.h	2007-04-04 10:12:42.000000000 +0200
--- pgsql/src/include/nodes/parsenodes.h	2007-04-04 13:58:31.000000000 +0200
*************** typedef struct Query
*** 129,134 ****
--- 129,136 ----
  
  	Node	   *setOperations;	/* set-operation tree if this is top level of
  								 * a UNION/INTERSECT/EXCEPT query */
+ 
+ 	bool		commandOverride;	/* OVERRIDING SYSTEM VALUE */
  } Query;
  
  
*************** typedef struct ColumnDef
*** 389,394 ****
--- 391,398 ----
  	Node	   *raw_default;	/* default value (untransformed parse tree) */
  	char	   *cooked_default; /* nodeToString representation */
  	List	   *constraints;	/* other constraints on column */
+ 	bool		is_identity;	/* GENERATED AS IDENTITY */
+ 	bool		is_generated;	/* GENERATED ALWAYS */
  } ColumnDef;
  
  /*
*************** typedef struct InsertStmt
*** 673,678 ****
--- 677,683 ----
  	List	   *cols;			/* optional: names of the target columns */
  	Node	   *selectStmt;		/* the source SELECT/VALUES, or NULL */
  	List	   *returningList;	/* list of expressions to return */
+ 	bool		commandOverride;/* OVERRIDING SYSTEM VALUE */
  } InsertStmt;
  
  /* ----------------------
*************** typedef enum AlterTableType
*** 909,915 ****
  	AT_EnableReplicaRule,		/* ENABLE REPLICA RULE name */
  	AT_DisableRule,				/* DISABLE RULE name */
  	AT_AddInherit,				/* INHERIT parent */
! 	AT_DropInherit				/* NO INHERIT parent */
  } AlterTableType;
  
  typedef struct AlterTableCmd	/* one subcommand of an ALTER TABLE */
--- 914,923 ----
  	AT_EnableReplicaRule,		/* ENABLE REPLICA RULE name */
  	AT_DisableRule,				/* DISABLE RULE name */
  	AT_AddInherit,				/* INHERIT parent */
! 	AT_DropInherit,				/* NO INHERIT parent */
! 	AT_SetSeqOpts,				/* SET sequence_options for IDENTITY columns */
! 	AT_SetIdentity,				/* SET IDENTITY */
! 	AT_DropIdentity				/* DROP IDENTITY */
  } AlterTableType;
  
  typedef struct AlterTableCmd	/* one subcommand of an ALTER TABLE */
*************** typedef struct AlterTableCmd	/* one subc
*** 922,927 ****
--- 930,938 ----
  								 * index, constraint, or parent table */
  	Node	   *transform;		/* transformation expr for ALTER TYPE */
  	DropBehavior behavior;		/* RESTRICT or CASCADE for DROP cases */
+ 	bool		is_generated;	/* SET GENERATED
+ 						{ ALWAYS | BY DEFAULT }
+ 						AS IDENTITY */
  } AlterTableCmd;
  
  
*************** typedef struct CopyStmt
*** 1040,1045 ****
--- 1051,1057 ----
  	bool		is_from;		/* TO or FROM */
  	char	   *filename;		/* filename, or NULL for STDIN/STDOUT */
  	List	   *options;		/* List of DefElem nodes */
+ 	bool		overriding;	/* OVERRIDING SYSTEM VALUE */
  } CopyStmt;
  
  /* ----------------------
*************** typedef enum ConstrType			/* types of co
*** 1099,1105 ****
  	CONSTR_ATTR_DEFERRABLE,		/* attributes for previous constraint node */
  	CONSTR_ATTR_NOT_DEFERRABLE,
  	CONSTR_ATTR_DEFERRED,
! 	CONSTR_ATTR_IMMEDIATE
  } ConstrType;
  
  typedef struct Constraint
--- 1111,1118 ----
  	CONSTR_ATTR_DEFERRABLE,		/* attributes for previous constraint node */
  	CONSTR_ATTR_NOT_DEFERRABLE,
  	CONSTR_ATTR_DEFERRED,
! 	CONSTR_ATTR_IMMEDIATE,
! 	CONSTR_IDENTITY
  } ConstrType;
  
  typedef struct Constraint
*************** typedef struct Constraint
*** 1113,1118 ****
--- 1126,1133 ----
  	List	   *options;		/* options from WITH clause */
  	char	   *indexspace;		/* index tablespace for PKEY/UNIQUE
  								 * constraints; NULL for default */
+ 	bool		is_generated;	/* GENERATED ALWAYS */
+ 	List	   *seq_opts;		/* SEQUENCE options for GENERATED ... AS IDENTITY */
  } Constraint;
  
  /* ----------
diff -dcrpN pgsql.orig/src/include/utils/lsyscache.h pgsql/src/include/utils/lsyscache.h
*** pgsql.orig/src/include/utils/lsyscache.h	2007-04-04 10:12:43.000000000 +0200
--- pgsql/src/include/utils/lsyscache.h	2007-04-04 12:57:20.000000000 +0200
*************** extern Oid	get_opfamily_proc(Oid opfamil
*** 53,58 ****
--- 53,59 ----
  							  int16 procnum);
  extern char *get_attname(Oid relid, AttrNumber attnum);
  extern char *get_relid_attribute_name(Oid relid, AttrNumber attnum);
+ extern Oid	get_relid_att_serial_sequence(Oid relid, AttrNumber attnum);
  extern AttrNumber get_attnum(Oid relid, const char *attname);
  extern Oid	get_atttype(Oid relid, AttrNumber attnum);
  extern int32 get_atttypmod(Oid relid, AttrNumber attnum);
diff -dcrpN pgsql.orig/src/test/regress/expected/identity.out pgsql/src/test/regress/expected/identity.out
*** pgsql.orig/src/test/regress/expected/identity.out	1970-01-01 01:00:00.000000000 +0100
--- pgsql/src/test/regress/expected/identity.out	2007-04-04 13:50:22.000000000 +0200
***************
*** 0 ****
--- 1,702 ----
+ --
+ -- IDENTITY
+ --  2006.08.01 Zoltan Boszormenyi <zboszor@dunaweb.hu>
+ --
+ --
+ -- Test GENERATED BY DEFAULT AS IDENTITY with default sequence
+ --
+ create table id (id serial generated by default as identity primary key, name text);
+ NOTICE:  CREATE TABLE will create implicit sequence "id_id_seq" for serial column "id.id"
+ NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "id_pkey" for table "id"
+ insert into id (name) values ('a');
+ insert into id (id, name) values (default, 'a');
+ insert into id (id, name) values (default, 'a');
+ insert into id (id, name) values (default, 'a');
+ insert into id (id, name) values (0, 'a');
+ --
+ -- This must complain about UNIQUE violation
+ --
+ insert into id (id, name) values (0, 'a');
+ ERROR:  duplicate key violates unique constraint "id_pkey"
+ select * from id;
+  id | name 
+ ----+------
+   1 | a
+   2 | a
+   3 | a
+   4 | a
+   0 | a
+ (5 rows)
+ 
+ --
+ -- This must complain because SERIAL and IDENTITY has
+ -- implicit NOT NULL constraint
+ --
+ insert into id (id, name) values (null, 'a');
+ ERROR:  null value in column "id" violates not-null constraint
+ select * from id;
+  id | name 
+ ----+------
+   1 | a
+   2 | a
+   3 | a
+   4 | a
+   0 | a
+ (5 rows)
+ 
+ update id set id = default where id = 0;
+ select * from id;
+  id | name 
+ ----+------
+   1 | a
+   2 | a
+   3 | a
+   4 | a
+   5 | a
+ (5 rows)
+ 
+ drop table id;
+ --
+ -- Test GENERATED BY DEFAULT AS IDENTITY with modified sequence
+ --
+ create table id (id serial generated by default as identity(start 3) primary key, name text);
+ NOTICE:  CREATE TABLE will create implicit sequence "id_id_seq" for serial column "id.id"
+ NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "id_pkey" for table "id"
+ insert into id (id, name) values (default, 'a');
+ insert into id (id, name) values (default, 'a');
+ insert into id (id, name) values (default, 'a');
+ insert into id (id, name) values (0, 'a');
+ --
+ -- This must complain about UNIQUE violation
+ --
+ insert into id (id, name) values (0, 'a');
+ ERROR:  duplicate key violates unique constraint "id_pkey"
+ select * from id;
+  id | name 
+ ----+------
+   3 | a
+   4 | a
+   5 | a
+   0 | a
+ (4 rows)
+ 
+ drop table id;
+ --
+ -- Test GENERATED ALWAYS AS IDENTITY with default sequence
+ --
+ create table id (id serial generated always as identity primary key, name text);
+ NOTICE:  CREATE TABLE will create implicit sequence "id_id_seq" for serial column "id.id"
+ NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "id_pkey" for table "id"
+ insert into id (id, name) values (default, 'a');
+ insert into id (id, name) values (default, 'a');
+ insert into id (id, name) values (default, 'a');
+ insert into id (id, name) values (0, 'a');
+ insert into id (id, name) values (0, 'a');
+ insert into id (id, name) values (0, 'a');
+ select * from id;
+  id | name 
+ ----+------
+   1 | a
+   2 | a
+   3 | a
+   4 | a
+   5 | a
+   6 | a
+ (6 rows)
+ 
+ --
+ -- It should update 0 rows
+ --
+ update id set name = 'b' where id = 0;
+ select * from id;
+  id | name 
+ ----+------
+   1 | a
+   2 | a
+   3 | a
+   4 | a
+   5 | a
+   6 | a
+ (6 rows)
+ 
+ drop table id;
+ --
+ -- Test GENERATED ALWAYS AS IDENTITY with modified sequence
+ --
+ create table id (id serial generated always as identity(start 3) primary key, name text);
+ NOTICE:  CREATE TABLE will create implicit sequence "id_id_seq" for serial column "id.id"
+ NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "id_pkey" for table "id"
+ insert into id (id, name) values (default, 'a');
+ insert into id (id, name) values (default, 'a');
+ insert into id (id, name) values (default, 'a');
+ insert into id (id, name) values (0, 'a');
+ insert into id (id, name) values (0, 'a');
+ insert into id (id, name) values (0, 'a');
+ select * from id;
+  id | name 
+ ----+------
+   3 | a
+   4 | a
+   5 | a
+   6 | a
+   7 | a
+   8 | a
+ (6 rows)
+ 
+ --
+ -- It should update 0 rows
+ --
+ update id set name = 'b' where id = 0;
+ select * from id;
+  id | name 
+ ----+------
+   3 | a
+   4 | a
+   5 | a
+   6 | a
+   7 | a
+   8 | a
+ (6 rows)
+ 
+ drop table id;
+ --
+ -- Test GENERATED BY DEFAULT AS (expr)
+ -- It must give a syntax error but drop it anyway.
+ --
+ create table id (id integer generated by default as (1), name text);
+ ERROR:  syntax error at or near "("
+ LINE 1: ...eate table id (id integer generated by default as (1), name ...
+                                                              ^
+ drop table id;
+ ERROR:  table "id" does not exist
+ --
+ -- Test GENERATED ALWAYS AS ( expr )
+ --
+ create table id (id integer generated always as (1), name text);
+ insert into id (id, name) values (default, 'a');
+ insert into id (id, name) values (0, 'a');
+ select * from id;
+  id | name 
+ ----+------
+   1 | a
+   1 | a
+ (2 rows)
+ 
+ --
+ -- It should update 0 rows
+ --
+ update id set name = 'b' where id = 0;
+ select * from id;
+  id | name 
+ ----+------
+   1 | a
+   1 | a
+ (2 rows)
+ 
+ drop table id;
+ --
+ -- Test IDENTITY with non-integer columns
+ --
+ create table id (id decimal(10,2) generated always as identity(start 3), name text);
+ NOTICE:  CREATE TABLE will create implicit sequence "id_id_seq" for serial column "id.id"
+ insert into id (id, name) values (default, 'a');
+ insert into id (id, name) values (0, 'a');
+ select * from id;
+   id  | name 
+ ------+------
+  3.00 | a
+  4.00 | a
+ (2 rows)
+ 
+ alter table id alter id type real;
+ insert into id (id, name) values (0, 'a');
+ select * from id;
+  id | name 
+ ----+------
+   3 | a
+   4 | a
+   5 | a
+ (3 rows)
+ 
+ alter table id alter id type integer;
+ insert into id (id, name) values (0, 'a');
+ select * from id;
+  id | name 
+ ----+------
+   3 | a
+   4 | a
+   5 | a
+   6 | a
+ (4 rows)
+ 
+ --
+ -- It should update 0 rows
+ --
+ update id set name = 'b' where id = 0;
+ select * from id;
+  id | name 
+ ----+------
+   3 | a
+   4 | a
+   5 | a
+   6 | a
+ (4 rows)
+ 
+ update id set name = 'b' where id = 5;
+ select * from id;
+  id | name 
+ ----+------
+   3 | a
+   4 | a
+   6 | a
+   5 | b
+ (4 rows)
+ 
+ drop table id;
+ --
+ -- Test OVERRIDING and UPDATE on GENERATED ALWAYS columns
+ --
+ create table id (id serial generated always as identity, name text generated always as ('x'));
+ NOTICE:  CREATE TABLE will create implicit sequence "id_id_seq" for serial column "id.id"
+ insert into id (id, name) values (0, 'a');
+ insert into id (id, name) overriding user value values (0, 'a');
+ insert into id (id, name) overriding system value values (0, 'a');
+ --
+ -- It's expected to fail because of GENERATED ALWAYS AS IDENTITY.
+ --
+ update id set id = 6 where id = 0;
+ ERROR:  UPDATE prohibited on GENERATED ALWAYS AS IDENTITY attributes
+ --
+ -- It's expected to fail because of GENERATED ALWAYS AS IDENTITY.
+ --
+ update id set id = default where id = 0;
+ ERROR:  UPDATE prohibited on GENERATED ALWAYS AS IDENTITY attributes
+ --
+ -- It's expected to fail because of GENERATED ALWAYS.
+ --
+ update id set name = 'b' where id = 0;
+ ERROR:  UPDATE to non-default value prohibited on GENERATED ALWAYS attributes
+ --
+ -- It's expected to succeed
+ --
+ update id set name = default where id = 0;
+ --
+ -- Test ALTER TABLE sequence options
+ --
+ alter table id alter id restart with 10;
+ insert into id (id, name) values (0, 'a');
+ alter table id alter id set increment by 5;
+ insert into id (id, name) values (0, 'a');
+ select * from id;
+  id | name 
+ ----+------
+   1 | x
+   2 | x
+   0 | x
+  10 | x
+  15 | x
+ (5 rows)
+ 
+ --
+ -- Test ALTER TABLE RENAME
+ --
+ select pg_get_serial_sequence('id', 'id');
+  pg_get_serial_sequence 
+ ------------------------
+  public.id_id_seq
+ (1 row)
+ 
+ alter table id rename id to di;
+ NOTICE:  supporting sequence for column "di" renamed to "id_di_seq"
+ insert into id (di, name) values (0, 'a');
+ select pg_get_serial_sequence('id', 'di');
+  pg_get_serial_sequence 
+ ------------------------
+  public.id_di_seq
+ (1 row)
+ 
+ alter table id rename to di;
+ NOTICE:  supporting sequence for column "di" renamed to "di_di_seq"
+ insert into di (di, name) values (0, 'a');
+ select pg_get_serial_sequence('di', 'di');
+  pg_get_serial_sequence 
+ ------------------------
+  public.di_di_seq
+ (1 row)
+ 
+ select * from di;
+  di | name 
+ ----+------
+   1 | x
+   2 | x
+   0 | x
+  10 | x
+  15 | x
+  20 | x
+  25 | x
+ (7 rows)
+ 
+ --
+ -- Test SET/DROP DEFAULT
+ --
+ alter table di alter di drop default;
+ ERROR:  cannot alter IDENTITY column "di"
+ alter table di alter di set default 1;
+ ERROR:  cannot alter IDENTITY column "di"
+ --
+ -- Test ALTER TABLE DROP COLUMN
+ --
+ alter table di add column id integer;
+ update di set id = di;
+ alter table di drop column di;
+ select * from di;
+  name | id 
+ ------+----
+  x    |  1
+  x    |  2
+  x    |  0
+  x    | 10
+  x    | 15
+  x    | 20
+  x    | 25
+ (7 rows)
+ 
+ drop table di;
+ --
+ -- Test multiple IDENTITY columns in a single table
+ --
+ -- This must fail, no multiple IDENTITY allowed
+ create table id (
+   id1 serial generated always as identity (start 3),
+   id2 serial generated always as identity (start 5)
+ );
+ NOTICE:  CREATE TABLE will create implicit sequence "id_id1_seq" for serial column "id.id1"
+ NOTICE:  CREATE TABLE will create implicit sequence "id_id2_seq" for serial column "id.id2"
+ ERROR:  multiple IDENTITY columns are not allowed
+ -- This succeeds
+ create table id (id1 serial generated always as identity (start 3), t text not null);
+ NOTICE:  CREATE TABLE will create implicit sequence "id_id1_seq" for serial column "id.id1"
+ insert into id (t) values (null) returning id1;
+ ERROR:  null value in column "t" violates not-null constraint
+ insert into id (t) values ('a') returning id1;
+  id1 
+ -----
+    4
+ (1 row)
+ 
+ select * from id;
+  id1 | t 
+ -----+---
+    4 | a
+ (1 row)
+ 
+ -- This must fail, no multiple IDENTITY allowed
+ alter table id add id2 serial generated always as identity (start 5);
+ NOTICE:  ALTER TABLE will create implicit sequence "id_id2_seq" for serial column "id.id2"
+ ERROR:  multiple IDENTITY columns are not allowed
+ -- Downgrade id1 to normal serial
+ alter table id alter id1 drop identity;
+ --
+ -- Try to drop IDENTITY again, it fails
+ --
+ alter table id alter id1 drop identity;
+ ERROR:  column "id1" of relation "id" is a non-IDENTITY serial column
+ -- Insert new records
+ insert into id (t) values (null) returning id1;
+ ERROR:  null value in column "t" violates not-null constraint
+ insert into id (t) values ('a') returning id1;
+  id1 
+ -----
+    6
+ (1 row)
+ 
+ select * from id;
+  id1 | t 
+ -----+---
+    4 | a
+    6 | a
+ (2 rows)
+ 
+ -- Not this succeeds
+ alter table id add id2 serial generated always as identity (start 5);
+ NOTICE:  ALTER TABLE will create implicit sequence "id_id2_seq" for serial column "id.id2"
+ insert into id (t) values (null) returning id1, id2;
+ ERROR:  null value in column "t" violates not-null constraint
+ insert into id (t) values ('a') returning id1, id2;
+  id1 | id2 
+ -----+-----
+    8 |   8
+ (1 row)
+ 
+ select * from id;
+  id1 | t | id2 
+ -----+---+-----
+    4 | a |   5
+    6 | a |   6
+    8 | a |   8
+ (3 rows)
+ 
+ -- Downgrade id2 to normal serial
+ alter table id alter id2 drop identity;
+ insert into id (t) values (null) returning id1, id2;
+ ERROR:  null value in column "t" violates not-null constraint
+ insert into id (t) values ('a') returning id1, id2;
+  id1 | id2 
+ -----+-----
+   10 |  10
+ (1 row)
+ 
+ select * from id;
+  id1 | t | id2 
+ -----+---+-----
+    4 | a |   5
+    6 | a |   6
+    8 | a |   8
+   10 | a |  10
+ (4 rows)
+ 
+ -- Upgrade id1 to identity
+ alter table id alter id1 set generated always as identity;
+ -- Upgrade id2 to identity, this must fail
+ alter table id alter id2 set generated always as identity;
+ ERROR:  multiple IDENTITY columns are not allowed
+ select * from id;
+  id1 | t | id2 
+ -----+---+-----
+    4 | a |   5
+    6 | a |   6
+    8 | a |   8
+   10 | a |  10
+ (4 rows)
+ 
+ drop table id;
+ --
+ -- Test GENERATED columns
+ --
+ create table id (
+   id serial generated always as identity,
+   g integer generated always as ( id + 1 ));
+ NOTICE:  CREATE TABLE will create implicit sequence "id_id_seq" for serial column "id.id"
+ insert into id (g) values (default);
+ select * from id;
+  id | g 
+ ----+---
+   1 | 2
+ (1 row)
+ 
+ drop table id;
+ --
+ -- This should fail, GENERATED cannot be referenced by GENERATED
+ --
+ create table id (
+   id serial generated always as identity,
+   i1 integer,
+   i2 integer,
+   g1 integer generated always as ( i1 + i2 ),
+   g2 integer generated always as ( i1 + g1 ));
+ NOTICE:  CREATE TABLE will create implicit sequence "id_id_seq" for serial column "id.id"
+ ERROR:  GENERATED column "g1" of table "id" cannot be referenced by GENERATED column "g2"
+ drop table id;
+ ERROR:  table "id" does not exist
+ --
+ -- Test simple expression (col1 + col2) as GENERATED column
+ --
+ --
+ -- Test INSERT with GENERATED columns
+ --
+ create table id (
+   id serial generated always as identity,
+   i1 integer,
+   i2 integer,
+   g1 integer generated always as ( i1 + i2 ));
+ NOTICE:  CREATE TABLE will create implicit sequence "id_id_seq" for serial column "id.id"
+ --
+ -- g1 has to be 3
+ --
+ insert into id (i1, i2) values (1, 2);
+ insert into id (id, i1, i2, g1) values (default, 1, 2, default);
+ select * from id;
+  id | i1 | i2 | g1 
+ ----+----+----+----
+   1 |  1 |  2 |  3
+   2 |  1 |  2 |  3
+ (2 rows)
+ 
+ --
+ -- g1 has to be recomputed as 4
+ --
+ update id set i1 = 2 where id = 1;
+ select * from id;
+  id | i1 | i2 | g1 
+ ----+----+----+----
+   2 |  1 |  2 |  3
+   1 |  2 |  2 |  4
+ (2 rows)
+ 
+ drop table id;
+ --
+ -- Test complex expression as GENERATED column
+ --
+ create table id (
+   id serial generated always as identity,
+   i1 integer,
+   i2 integer,
+   g1 integer generated always as (
+           case when i1 is null and i2 is null then -1
+                when i1 is null                then i2
+                when i2 is null                then i1
+                                               else i1 + i2
+           end ));
+ NOTICE:  CREATE TABLE will create implicit sequence "id_id_seq" for serial column "id.id"
+ insert into id (i1, i2) values (null, null);
+ insert into id (i1, i2) values (10,   null);
+ insert into id (i1, i2) values (null, 20  );
+ insert into id (i1, i2) values (10,   20  );
+ select * from id;
+  id | i1 | i2 | g1 
+ ----+----+----+----
+   1 |    |    | -1
+   2 | 10 |    | 10
+   3 |    | 20 | 20
+   4 | 10 | 20 | 30
+ (4 rows)
+ 
+ --
+ -- Test DROP COLUMN on a column referenced by the GENERATED column
+ --
+ \d id
+                                                                   Table "public.id"
+  Column |  Type   |                                                            Modifiers                                                             
+ --------+---------+----------------------------------------------------------------------------------------------------------------------------------
+  id     | integer | not null default nextval('id_id_seq'::regclass)
+  i1     | integer | 
+  i2     | integer | 
+  g1     | integer | default CASE WHEN ((i1 IS NULL) AND (i2 IS NULL)) THEN -1 WHEN (i1 IS NULL) THEN i2 WHEN (i2 IS NULL) THEN i1 ELSE (i1 + i2) END
+ 
+ alter table id drop i2;
+ NOTICE:  GENERATED column "g1" of relation "id" referencing column "i2" was dropped
+ \d id
+                          Table "public.id"
+  Column |  Type   |                    Modifiers                    
+ --------+---------+-------------------------------------------------
+  id     | integer | not null default nextval('id_id_seq'::regclass)
+  i1     | integer | 
+ 
+ drop table id;
+ --
+ -- Test plain COPY on IDENTITY/GENERATED columns
+ -- with missing column values. These should be generated.
+ --
+ create table id (
+   id serial generated always as identity,
+   i1 integer,
+   i2 integer,
+   g1 integer generated always as (
+           case when i1 is null and i2 is null then -1
+                when i1 is null                then i2
+                when i2 is null                then i1
+                                               else i1 + i2
+           end ));
+ NOTICE:  CREATE TABLE will create implicit sequence "id_id_seq" for serial column "id.id"
+ copy id (i1, i2) from stdin;
+ select * from id;
+  id | i1 | i2 | g1 
+ ----+----+----+----
+   1 |    |    | -1
+   2 | 10 |    | 10
+   3 |    | 20 | 20
+   4 | 10 | 20 | 30
+ (4 rows)
+ 
+ drop table id;
+ --
+ -- Test COPY OVERRIDING SYSTEM VALUE on IDENTITY/GENERATED columns
+ -- with missing column values. These should be generated.
+ --
+ create table id (
+   id serial generated always as identity,
+   i1 integer,
+   i2 integer,
+   g1 integer generated always as (
+           case when i1 is null and i2 is null then -1
+                when i1 is null                then i2
+                when i2 is null                then i1
+                                               else i1 + i2
+           end ));
+ NOTICE:  CREATE TABLE will create implicit sequence "id_id_seq" for serial column "id.id"
+ copy id (i1, i2) overriding system value from stdin;
+ select * from id;
+  id | i1 | i2 | g1 
+ ----+----+----+----
+   1 |    |    | -1
+   2 | 10 |    | 10
+   3 |    | 20 | 20
+   4 | 10 | 20 | 30
+ (4 rows)
+ 
+ drop table id;
+ --
+ -- Test COPY OVERRIDING SYSTEM VALUE on IDENTITY/GENERATED columns
+ -- with explicit column values. These should accept explicit values.
+ --
+ create table id (
+   id serial generated always as identity,
+   i1 integer,
+   i2 integer,
+   g1 integer generated always as (
+           case when i1 is null and i2 is null then -1
+                when i1 is null                then i2
+                when i2 is null                then i1
+                                               else i1 + i2
+           end ));
+ NOTICE:  CREATE TABLE will create implicit sequence "id_id_seq" for serial column "id.id"
+ copy id (id, i1, i2, g1) overriding system value from stdin;
+ select * from id;
+  id | i1 | i2 | g1 
+ ----+----+----+----
+   1 |    |    | -2
+   2 | 10 |    | 37
+   3 |    | 20 | 36
+   4 | 10 | 20 | 25
+ (4 rows)
+ 
+ --
+ -- Regenerate GENERATED values
+ --
+ update id set g1 = default where id = id;
+ select * from id;
+  id | i1 | i2 | g1 
+ ----+----+----+----
+   1 |    |    | -1
+   2 | 10 |    | 10
+   3 |    | 20 | 20
+   4 | 10 | 20 | 30
+ (4 rows)
+ 
+ drop table id;
+ --
+ -- Test plain COPY on IDENTITY/GENERATED columns
+ -- with explicit column values. These should modify explicit values.
+ --
+ create table id (
+   id serial generated always as identity (start 5),
+   i1 integer,
+   i2 integer,
+   g1 integer generated always as (
+           case when i1 is null and i2 is null then -1
+                when i1 is null                then i2
+                when i2 is null                then i1
+                                               else i1 + i2
+           end ));
+ NOTICE:  CREATE TABLE will create implicit sequence "id_id_seq" for serial column "id.id"
+ copy id (id, i1, i2, g1) from stdin;
+ select * from id;
+  id | i1 | i2 | g1 
+ ----+----+----+----
+   5 |    |    | -1
+   6 | 10 |    | 10
+   7 |    | 20 | 20
+   8 | 10 | 20 | 30
+ (4 rows)
+ 
+ drop table id;   
diff -dcrpN pgsql.orig/src/test/regress/parallel_schedule pgsql/src/test/regress/parallel_schedule
*** pgsql.orig/src/test/regress/parallel_schedule	2007-04-04 10:12:44.000000000 +0200
--- pgsql/src/test/regress/parallel_schedule	2007-04-04 12:58:08.000000000 +0200
***************
*** 2,8 ****
  # The first group of parallel test
  # $PostgreSQL: pgsql/src/test/regress/parallel_schedule,v 1.42 2007/04/02 03:49:42 tgl Exp $
  # ----------
! test: boolean char name varchar text int2 int4 int8 oid float4 float8 bit numeric uuid enum
  
  # Depends on things setup during char, varchar and text
  test: strings
--- 2,8 ----
  # The first group of parallel test
  # $PostgreSQL: pgsql/src/test/regress/parallel_schedule,v 1.42 2007/04/02 03:49:42 tgl Exp $
  # ----------
! test: boolean char name varchar text int2 int4 int8 oid float4 float8 bit numeric uuid enum identity
  
  # Depends on things setup during char, varchar and text
  test: strings
diff -dcrpN pgsql.orig/src/test/regress/serial_schedule pgsql/src/test/regress/serial_schedule
*** pgsql.orig/src/test/regress/serial_schedule	2007-04-04 10:12:44.000000000 +0200
--- pgsql/src/test/regress/serial_schedule	2007-04-04 12:58:22.000000000 +0200
*************** test: bit
*** 15,20 ****
--- 15,21 ----
  test: numeric
  test: uuid
  test: enum
+ test: identity
  test: strings
  test: numerology
  test: point
diff -dcrpN pgsql.orig/src/test/regress/sql/identity.sql pgsql/src/test/regress/sql/identity.sql
*** pgsql.orig/src/test/regress/sql/identity.sql	1970-01-01 01:00:00.000000000 +0100
--- pgsql/src/test/regress/sql/identity.sql	2007-04-04 13:34:14.000000000 +0200
***************
*** 0 ****
--- 1,372 ----
+ --
+ -- IDENTITY
+ --  2006.08.01 Zoltan Boszormenyi <zboszor@dunaweb.hu>
+ --
+ 
+ --
+ -- Test GENERATED BY DEFAULT AS IDENTITY with default sequence
+ --
+ create table id (id serial generated by default as identity primary key, name text);
+ insert into id (name) values ('a');
+ insert into id (id, name) values (default, 'a');
+ insert into id (id, name) values (default, 'a');
+ insert into id (id, name) values (default, 'a');
+ insert into id (id, name) values (0, 'a');
+ --
+ -- This must complain about UNIQUE violation
+ --
+ insert into id (id, name) values (0, 'a');
+ select * from id;
+ --
+ -- This must complain because SERIAL and IDENTITY has
+ -- implicit NOT NULL constraint
+ --
+ insert into id (id, name) values (null, 'a');
+ select * from id;
+ update id set id = default where id = 0;
+ select * from id;
+ drop table id;
+ --
+ -- Test GENERATED BY DEFAULT AS IDENTITY with modified sequence
+ --
+ create table id (id serial generated by default as identity(start 3) primary key, name text);
+ insert into id (id, name) values (default, 'a');
+ insert into id (id, name) values (default, 'a');
+ insert into id (id, name) values (default, 'a');
+ insert into id (id, name) values (0, 'a');
+ --
+ -- This must complain about UNIQUE violation
+ --
+ insert into id (id, name) values (0, 'a');
+ select * from id;
+ drop table id;
+ --
+ -- Test GENERATED ALWAYS AS IDENTITY with default sequence
+ --
+ create table id (id serial generated always as identity primary key, name text);
+ insert into id (id, name) values (default, 'a');
+ insert into id (id, name) values (default, 'a');
+ insert into id (id, name) values (default, 'a');
+ insert into id (id, name) values (0, 'a');
+ insert into id (id, name) values (0, 'a');
+ insert into id (id, name) values (0, 'a');
+ select * from id;
+ --
+ -- It should update 0 rows
+ --
+ update id set name = 'b' where id = 0;
+ select * from id;
+ drop table id;
+ --
+ -- Test GENERATED ALWAYS AS IDENTITY with modified sequence
+ --
+ create table id (id serial generated always as identity(start 3) primary key, name text);
+ insert into id (id, name) values (default, 'a');
+ insert into id (id, name) values (default, 'a');
+ insert into id (id, name) values (default, 'a');
+ insert into id (id, name) values (0, 'a');
+ insert into id (id, name) values (0, 'a');
+ insert into id (id, name) values (0, 'a');
+ select * from id;
+ --
+ -- It should update 0 rows
+ --
+ update id set name = 'b' where id = 0;
+ select * from id;
+ drop table id;
+ --
+ -- Test GENERATED BY DEFAULT AS (expr)
+ -- It must give a syntax error but drop it anyway.
+ --
+ create table id (id integer generated by default as (1), name text);
+ drop table id;
+ --
+ -- Test GENERATED ALWAYS AS ( expr )
+ --
+ create table id (id integer generated always as (1), name text);
+ insert into id (id, name) values (default, 'a');
+ insert into id (id, name) values (0, 'a');
+ select * from id;
+ --
+ -- It should update 0 rows
+ --
+ update id set name = 'b' where id = 0;
+ select * from id;
+ drop table id;
+ --
+ -- Test IDENTITY with non-integer columns
+ --
+ create table id (id decimal(10,2) generated always as identity(start 3), name text);
+ insert into id (id, name) values (default, 'a');
+ insert into id (id, name) values (0, 'a');
+ select * from id;
+ alter table id alter id type real;
+ insert into id (id, name) values (0, 'a');
+ select * from id;
+ alter table id alter id type integer;
+ insert into id (id, name) values (0, 'a');
+ select * from id;
+ --
+ -- It should update 0 rows
+ --
+ update id set name = 'b' where id = 0;
+ select * from id;
+ update id set name = 'b' where id = 5;
+ select * from id;
+ drop table id;
+ --
+ -- Test OVERRIDING and UPDATE on GENERATED ALWAYS columns
+ --
+ create table id (id serial generated always as identity, name text generated always as ('x'));
+ insert into id (id, name) values (0, 'a');
+ insert into id (id, name) overriding user value values (0, 'a');
+ insert into id (id, name) overriding system value values (0, 'a');
+ --
+ -- It's expected to fail because of GENERATED ALWAYS AS IDENTITY.
+ --
+ update id set id = 6 where id = 0;
+ --
+ -- It's expected to fail because of GENERATED ALWAYS AS IDENTITY.
+ --
+ update id set id = default where id = 0;
+ --
+ -- It's expected to fail because of GENERATED ALWAYS.
+ --
+ update id set name = 'b' where id = 0;
+ --
+ -- It's expected to succeed
+ --
+ update id set name = default where id = 0;
+ --
+ -- Test ALTER TABLE sequence options
+ --
+ alter table id alter id restart with 10;
+ insert into id (id, name) values (0, 'a');
+ alter table id alter id set increment by 5;
+ insert into id (id, name) values (0, 'a');
+ select * from id;
+ --
+ -- Test ALTER TABLE RENAME
+ --
+ select pg_get_serial_sequence('id', 'id');
+ alter table id rename id to di;
+ insert into id (di, name) values (0, 'a');
+ select pg_get_serial_sequence('id', 'di');
+ alter table id rename to di;
+ insert into di (di, name) values (0, 'a');
+ select pg_get_serial_sequence('di', 'di');
+ select * from di;
+ --
+ -- Test SET/DROP DEFAULT
+ --
+ alter table di alter di drop default;
+ alter table di alter di set default 1;
+ --
+ -- Test ALTER TABLE DROP COLUMN
+ --
+ alter table di add column id integer;
+ update di set id = di;
+ alter table di drop column di;
+ select * from di;
+ drop table di;
+ --
+ -- Test multiple IDENTITY columns in a single table
+ --
+ -- This must fail, no multiple IDENTITY allowed
+ create table id (
+   id1 serial generated always as identity (start 3),
+   id2 serial generated always as identity (start 5)
+ );
+ -- This succeeds
+ create table id (id1 serial generated always as identity (start 3), t text not null);
+ insert into id (t) values (null) returning id1;
+ insert into id (t) values ('a') returning id1;
+ select * from id;
+ -- This must fail, no multiple IDENTITY allowed
+ alter table id add id2 serial generated always as identity (start 5);
+ -- Downgrade id1 to normal serial
+ alter table id alter id1 drop identity;
+ --
+ -- Try to drop IDENTITY again, it fails
+ --
+ alter table id alter id1 drop identity;
+ -- Insert new records
+ insert into id (t) values (null) returning id1;
+ insert into id (t) values ('a') returning id1;
+ select * from id;
+ -- Not this succeeds
+ alter table id add id2 serial generated always as identity (start 5);
+ insert into id (t) values (null) returning id1, id2;
+ insert into id (t) values ('a') returning id1, id2;
+ select * from id;
+ -- Downgrade id2 to normal serial
+ alter table id alter id2 drop identity;
+ insert into id (t) values (null) returning id1, id2;
+ insert into id (t) values ('a') returning id1, id2;
+ select * from id;
+ -- Upgrade id1 to identity
+ alter table id alter id1 set generated always as identity;
+ -- Upgrade id2 to identity, this must fail
+ alter table id alter id2 set generated always as identity;
+ select * from id;
+ drop table id;
+ --
+ -- Test GENERATED columns
+ --
+ create table id (
+   id serial generated always as identity,
+   g integer generated always as ( id + 1 ));
+ insert into id (g) values (default);
+ select * from id;
+ drop table id;
+ --
+ -- This should fail, GENERATED cannot be referenced by GENERATED
+ --
+ create table id (
+   id serial generated always as identity,
+   i1 integer,
+   i2 integer,
+   g1 integer generated always as ( i1 + i2 ),
+   g2 integer generated always as ( i1 + g1 ));
+ drop table id;
+ --
+ -- Test simple expression (col1 + col2) as GENERATED column
+ --
+ --
+ -- Test INSERT with GENERATED columns
+ --
+ create table id (
+   id serial generated always as identity,
+   i1 integer,
+   i2 integer,
+   g1 integer generated always as ( i1 + i2 ));
+ --
+ -- g1 has to be 3
+ --
+ insert into id (i1, i2) values (1, 2);
+ insert into id (id, i1, i2, g1) values (default, 1, 2, default);
+ select * from id;
+ --
+ -- g1 has to be recomputed as 4
+ --
+ update id set i1 = 2 where id = 1;
+ select * from id;
+ drop table id;
+ --
+ -- Test complex expression as GENERATED column
+ --
+ create table id (
+   id serial generated always as identity,
+   i1 integer,
+   i2 integer,
+   g1 integer generated always as (
+           case when i1 is null and i2 is null then -1
+                when i1 is null                then i2
+                when i2 is null                then i1
+                                               else i1 + i2
+           end ));
+ insert into id (i1, i2) values (null, null);
+ insert into id (i1, i2) values (10,   null);
+ insert into id (i1, i2) values (null, 20  );
+ insert into id (i1, i2) values (10,   20  );
+ select * from id;
+ --
+ -- Test DROP COLUMN on a column referenced by the GENERATED column
+ --
+ \d id
+ alter table id drop i2;
+ \d id
+ drop table id;
+ --
+ -- Test plain COPY on IDENTITY/GENERATED columns
+ -- with missing column values. These should be generated.
+ --
+ create table id (
+   id serial generated always as identity,
+   i1 integer,
+   i2 integer,
+   g1 integer generated always as (
+           case when i1 is null and i2 is null then -1
+                when i1 is null                then i2
+                when i2 is null                then i1
+                                               else i1 + i2
+           end ));
+ copy id (i1, i2) from stdin;
+ \N	\N
+ 10	\N
+ \N	20
+ 10	20
+ \.
+ select * from id;
+ drop table id;
+ --
+ -- Test COPY OVERRIDING SYSTEM VALUE on IDENTITY/GENERATED columns
+ -- with missing column values. These should be generated.
+ --
+ create table id (
+   id serial generated always as identity,
+   i1 integer,
+   i2 integer,
+   g1 integer generated always as (
+           case when i1 is null and i2 is null then -1
+                when i1 is null                then i2
+                when i2 is null                then i1
+                                               else i1 + i2
+           end ));
+ copy id (i1, i2) overriding system value from stdin;
+ \N	\N
+ 10	\N
+ \N	20
+ 10	20
+ \.
+ select * from id;
+ drop table id;
+ --
+ -- Test COPY OVERRIDING SYSTEM VALUE on IDENTITY/GENERATED columns
+ -- with explicit column values. These should accept explicit values.
+ --
+ create table id (
+   id serial generated always as identity,
+   i1 integer,
+   i2 integer,
+   g1 integer generated always as (
+           case when i1 is null and i2 is null then -1
+                when i1 is null                then i2
+                when i2 is null                then i1
+                                               else i1 + i2
+           end ));
+ copy id (id, i1, i2, g1) overriding system value from stdin;
+ 1	\N	\N	-2
+ 2	10	\N	37
+ 3	\N	20	36
+ 4	10	20	25
+ \.
+ select * from id;
+ --
+ -- Regenerate GENERATED values
+ --
+ update id set g1 = default where id = id;
+ select * from id;
+ drop table id;
+ --
+ -- Test plain COPY on IDENTITY/GENERATED columns
+ -- with explicit column values. These should modify explicit values.
+ --
+ create table id (
+   id serial generated always as identity (start 5),
+   i1 integer,
+   i2 integer,
+   g1 integer generated always as (
+           case when i1 is null and i2 is null then -1
+                when i1 is null                then i2
+                when i2 is null                then i1
+                                               else i1 + i2
+           end ));
+ copy id (id, i1, i2, g1) from stdin;
+ 1	\N	\N	-2
+ 2	10	\N	37
+ 3	\N	20	36
+ 4	10	20	25
+ \.
+ select * from id;
+ drop table id;   
