diff -dcrpN pgsql.orig/doc/src/sgml/ref/alter_sequence.sgml pgsql/doc/src/sgml/ref/alter_sequence.sgml
*** pgsql.orig/doc/src/sgml/ref/alter_sequence.sgml	2007-10-25 20:54:03.000000000 +0200
--- pgsql/doc/src/sgml/ref/alter_sequence.sgml	2008-04-21 19:37:40.000000000 +0200
*************** PostgreSQL documentation
*** 26,32 ****
    <synopsis>
  ALTER SEQUENCE <replaceable class="parameter">name</replaceable> [ INCREMENT [ BY ] <replaceable class="parameter">increment</replaceable> ]
      [ MINVALUE <replaceable class="parameter">minvalue</replaceable> | NO MINVALUE ] [ MAXVALUE <replaceable class="parameter">maxvalue</replaceable> | NO MAXVALUE ]
!     [ RESTART [ WITH ] <replaceable class="parameter">start</replaceable> ] [ CACHE <replaceable class="parameter">cache</replaceable> ] [ [ NO ] CYCLE ]
      [ OWNED BY { <replaceable class="parameter">table</replaceable>.<replaceable class="parameter">column</replaceable> | NONE } ]
  ALTER SEQUENCE <replaceable class="parameter">name</replaceable> RENAME TO <replaceable class="parameter">new_name</replaceable>
  ALTER SEQUENCE <replaceable class="parameter">name</replaceable> SET SCHEMA <replaceable class="parameter">new_schema</replaceable>
--- 26,32 ----
    <synopsis>
  ALTER SEQUENCE <replaceable class="parameter">name</replaceable> [ INCREMENT [ BY ] <replaceable class="parameter">increment</replaceable> ]
      [ MINVALUE <replaceable class="parameter">minvalue</replaceable> | NO MINVALUE ] [ MAXVALUE <replaceable class="parameter">maxvalue</replaceable> | NO MAXVALUE ]
!     [ RESTART [[ WITH ] <replaceable class="parameter">start</replaceable> ]] [ CACHE <replaceable class="parameter">cache</replaceable> ] [ [ NO ] CYCLE ]
      [ OWNED BY { <replaceable class="parameter">table</replaceable>.<replaceable class="parameter">column</replaceable> | NONE } ]
  ALTER SEQUENCE <replaceable class="parameter">name</replaceable> RENAME TO <replaceable class="parameter">new_name</replaceable>
  ALTER SEQUENCE <replaceable class="parameter">name</replaceable> SET SCHEMA <replaceable class="parameter">new_schema</replaceable>
*************** ALTER SEQUENCE <replaceable class="param
*** 112,123 ****
        <term><replaceable class="parameter">start</replaceable></term>
        <listitem>
         <para>
!         The optional clause <literal>RESTART WITH <replaceable
!         class="parameter">start</replaceable></literal> changes the
          current value of the sequence.  This is equivalent to calling the
          <function>setval</> function with <literal>is_called</literal> =
          <literal>false</>: the specified value will be returned by the
!         <emphasis>next</> call of <function>nextval</>.
         </para>
        </listitem>
       </varlistentry>
--- 112,125 ----
        <term><replaceable class="parameter">start</replaceable></term>
        <listitem>
         <para>
!         The optional clause <literal>RESTART [WITH <replaceable
!         class="parameter">start</replaceable>]</literal> changes the
          current value of the sequence.  This is equivalent to calling the
          <function>setval</> function with <literal>is_called</literal> =
          <literal>false</>: the specified value will be returned by the
!         <emphasis>next</> call of <function>nextval</>. Omitting the
!         <replaceable class="parameter">start</replaceable> value is equivalent
!         to supplying the value used at <literal>CREATE SEQUENCE</literal>.
         </para>
        </listitem>
       </varlistentry>
diff -dcrpN pgsql.orig/doc/src/sgml/ref/truncate.sgml pgsql/doc/src/sgml/ref/truncate.sgml
*** pgsql.orig/doc/src/sgml/ref/truncate.sgml	2008-03-30 13:29:44.000000000 +0200
--- pgsql/doc/src/sgml/ref/truncate.sgml	2008-04-21 22:33:39.000000000 +0200
*************** PostgreSQL documentation
*** 20,26 ****
  
   <refsynopsisdiv>
  <synopsis>
! TRUNCATE [ TABLE ] <replaceable class="PARAMETER">name</replaceable> [, ...] [ CASCADE | RESTRICT ]
  </synopsis>
   </refsynopsisdiv>
  
--- 20,26 ----
  
   <refsynopsisdiv>
  <synopsis>
! TRUNCATE [ TABLE ] <replaceable class="PARAMETER">name</replaceable> [, ...] [ { CONTINUE | RESTART } IDENTITY ] [ CASCADE | RESTRICT ]
  </synopsis>
   </refsynopsisdiv>
  
*************** TRUNCATE [ TABLE ] <replaceable class="P
*** 51,56 ****
--- 51,67 ----
     </varlistentry>
  
     <varlistentry>
+     <term><literal>RESTART IDENTITY</literal></term>
+     <listitem>
+      <para>
+       Automatically restart sequences owned by columns of
+       the truncated table. <literal>CONTINUE IDENTITY</literal>
+       doesn't modify owned sequences and it is also the default.
+      </para>
+     </listitem>
+    </varlistentry>
+ 
+    <varlistentry>
      <term><literal>CASCADE</literal></term>
      <listitem>
       <para>
diff -dcrpN pgsql.orig/src/backend/commands/sequence.c pgsql/src/backend/commands/sequence.c
*** pgsql.orig/src/backend/commands/sequence.c	2008-01-01 20:45:49.000000000 +0100
--- pgsql/src/backend/commands/sequence.c	2008-04-21 18:50:19.000000000 +0200
*************** static Relation open_share_lock(SeqTable
*** 88,94 ****
  static void init_sequence(Oid relid, SeqTable *p_elm, Relation *p_rel);
  static Form_pg_sequence read_info(SeqTable elm, Relation rel, Buffer *buf);
  static void init_params(List *options, bool isInit,
! 			Form_pg_sequence new, List **owned_by);
  static void do_setval(Oid relid, int64 next, bool iscalled);
  static void process_owned_by(Relation seqrel, List *owned_by);
  
--- 88,94 ----
  static void init_sequence(Oid relid, SeqTable *p_elm, Relation *p_rel);
  static Form_pg_sequence read_info(SeqTable elm, Relation rel, Buffer *buf);
  static void init_params(List *options, bool isInit,
! 			Form_pg_sequence new, Form_pg_sequence old, List **owned_by);
  static void do_setval(Oid relid, int64 next, bool iscalled);
  static void process_owned_by(Relation seqrel, List *owned_by);
  
*************** DefineSequence(CreateSeqStmt *seq)
*** 116,122 ****
  	NameData	name;
  
  	/* Check and set all option values */
! 	init_params(seq->options, true, &new, &owned_by);
  
  	/*
  	 * Create relation (and fill *null & *value)
--- 116,122 ----
  	NameData	name;
  
  	/* Check and set all option values */
! 	init_params(seq->options, true, &new, NULL, &owned_by);
  
  	/*
  	 * Create relation (and fill *null & *value)
*************** DefineSequence(CreateSeqStmt *seq)
*** 143,148 ****
--- 143,153 ----
  				namestrcpy(&name, seq->sequence->relname);
  				value[i - 1] = NameGetDatum(&name);
  				break;
+ 			case SEQ_COL_STARTVAL:
+ 				coldef->typename = makeTypeNameFromOid(INT8OID, -1);
+ 				coldef->colname = "start_value";
+ 				value[i - 1] = Int64GetDatumFast(new.start_value);
+ 				break;
  			case SEQ_COL_LASTVAL:
  				coldef->typename = makeTypeNameFromOid(INT8OID, -1);
  				coldef->colname = "last_value";
*************** AlterSequence(AlterSeqStmt *stmt)
*** 336,342 ****
  	memcpy(&new, seq, sizeof(FormData_pg_sequence));
  
  	/* Check and set new values */
! 	init_params(stmt->options, false, &new, &owned_by);
  
  	/* Clear local cache so that we don't think we have cached numbers */
  	/* Note that we do not change the currval() state */
--- 341,347 ----
  	memcpy(&new, seq, sizeof(FormData_pg_sequence));
  
  	/* Check and set new values */
! 	init_params(stmt->options, false, &new, seq, &owned_by);
  
  	/* Clear local cache so that we don't think we have cached numbers */
  	/* Note that we do not change the currval() state */
*************** read_info(SeqTable elm, Relation rel, Bu
*** 967,973 ****
   */
  static void
  init_params(List *options, bool isInit,
! 			Form_pg_sequence new, List **owned_by)
  {
  	DefElem    *last_value = NULL;
  	DefElem    *increment_by = NULL;
--- 972,978 ----
   */
  static void
  init_params(List *options, bool isInit,
! 			Form_pg_sequence new, Form_pg_sequence old, List **owned_by)
  {
  	DefElem    *last_value = NULL;
  	DefElem    *increment_by = NULL;
*************** init_params(List *options, bool isInit,
*** 995,1003 ****
  		/*
  		 * start is for a new sequence restart is for alter
  		 */
! 		else if (strcmp(defel->defname, "start") == 0 ||
! 				 strcmp(defel->defname, "restart") == 0)
  		{
  			if (last_value)
  				ereport(ERROR,
  						(errcode(ERRCODE_SYNTAX_ERROR),
--- 1000,1023 ----
  		/*
  		 * start is for a new sequence restart is for alter
  		 */
! 		else if (strcmp(defel->defname, "start") == 0)
  		{
+ 			if (!isInit)
+ 				ereport(ERROR,
+ 						(errcode(ERRCODE_SYNTAX_ERROR),
+ 						 errmsg("use ALTER SEQUENCE ... RESTART ...")));
+ 			if (last_value)
+ 				ereport(ERROR,
+ 						(errcode(ERRCODE_SYNTAX_ERROR),
+ 						 errmsg("conflicting or redundant options")));
+ 			last_value = defel;
+ 		}
+ 		else if (strcmp(defel->defname, "restart") == 0)
+ 		{
+ 			if (isInit)
+ 				ereport(ERROR,
+ 						(errcode(ERRCODE_SYNTAX_ERROR),
+ 						 errmsg("use CREATE SEQUENCE ... START ...")));
  			if (last_value)
  				ereport(ERROR,
  						(errcode(ERRCODE_SYNTAX_ERROR),
*************** init_params(List *options, bool isInit,
*** 1109,1124 ****
  	/* START WITH */
  	if (last_value != NULL)
  	{
! 		new->last_value = defGetInt64(last_value);
  		new->is_called = false;
  		new->log_cnt = 1;
  	}
  	else if (isInit)
  	{
  		if (new->increment_by > 0)
! 			new->last_value = new->min_value;	/* ascending seq */
  		else
! 			new->last_value = new->max_value;	/* descending seq */
  		new->is_called = false;
  		new->log_cnt = 1;
  	}
--- 1129,1149 ----
  	/* START WITH */
  	if (last_value != NULL)
  	{
! 		if (last_value->arg != NULL)
! 			new->last_value = defGetInt64(last_value);
! 		else
! 			new->last_value = old->start_value;
! 		if (isInit)
! 			new->start_value = new->last_value;
  		new->is_called = false;
  		new->log_cnt = 1;
  	}
  	else if (isInit)
  	{
  		if (new->increment_by > 0)
! 			new->start_value = new->last_value = new->min_value;	/* ascending seq */
  		else
! 			new->start_value = new->last_value = new->max_value;	/* descending seq */
  		new->is_called = false;
  		new->log_cnt = 1;
  	}
diff -dcrpN pgsql.orig/src/backend/commands/tablecmds.c pgsql/src/backend/commands/tablecmds.c
*** pgsql.orig/src/backend/commands/tablecmds.c	2008-03-31 09:32:26.000000000 +0200
--- pgsql/src/backend/commands/tablecmds.c	2008-04-21 22:11:31.000000000 +0200
*************** ExecuteTruncate(TruncateStmt *stmt)
*** 566,572 ****
  	 * soon as we open it, to avoid a faux pas such as holding lock for a long
  	 * time on a rel we have no permissions for.
  	 */
! 	if (stmt->behavior == DROP_CASCADE)
  	{
  		for (;;)
  		{
--- 566,572 ----
  	 * soon as we open it, to avoid a faux pas such as holding lock for a long
  	 * time on a rel we have no permissions for.
  	 */
! 	if (stmt->drop_behavior == DROP_CASCADE)
  	{
  		for (;;)
  		{
*************** ExecuteTruncate(TruncateStmt *stmt)
*** 600,606 ****
  #ifdef USE_ASSERT_CHECKING
  	heap_truncate_check_FKs(rels, false);
  #else
! 	if (stmt->behavior == DROP_RESTRICT)
  		heap_truncate_check_FKs(rels, false);
  #endif
  
--- 600,606 ----
  #ifdef USE_ASSERT_CHECKING
  	heap_truncate_check_FKs(rels, false);
  #else
! 	if (stmt->drop_behavior == DROP_RESTRICT)
  		heap_truncate_check_FKs(rels, false);
  #endif
  
*************** ExecuteTruncate(TruncateStmt *stmt)
*** 700,705 ****
--- 700,731 ----
  	{
  		Relation	rel = (Relation) lfirst(cell);
  
+ 		if (stmt->identity_behavior == IDENTITY_RESTART)
+ 		{
+ 			Oid			heap_relid;
+ 			Oid			seq_relid;
+ 			Oid			namesp_id;
+ 			int			i;
+ 			char		   *snamespace;
+ 			char		   *sname;
+ 			AlterSeqStmt	   *altseqstmt = makeNode(AlterSeqStmt);
+ 
+ 			heap_relid = RelationGetRelid(rel);
+ 			for (i = 0; i < rel->rd_att->natts; i++)
+ 			{
+ 				seq_relid = get_relid_att_serial_sequence(heap_relid, i + 1);
+ 				if (OidIsValid(seq_relid))
+ 				{
+ 					namesp_id = get_rel_namespace(heap_relid);
+ 					snamespace = get_namespace_name(namesp_id);
+ 					sname = get_rel_name(seq_relid);
+ 					altseqstmt->sequence = makeRangeVar(snamespace, sname);
+ 					altseqstmt->options = list_make1(makeDefElem("restart", NULL));
+ 					AlterSequence(altseqstmt);
+ 				}
+ 			}
+ 		}
+ 
  		heap_close(rel, NoLock);
  	}
  }
diff -dcrpN pgsql.orig/src/backend/nodes/copyfuncs.c pgsql/src/backend/nodes/copyfuncs.c
*** pgsql.orig/src/backend/nodes/copyfuncs.c	2008-04-18 20:49:11.000000000 +0200
--- pgsql/src/backend/nodes/copyfuncs.c	2008-04-21 21:36:03.000000000 +0200
*************** _copyTruncateStmt(TruncateStmt *from)
*** 2158,2164 ****
  	TruncateStmt *newnode = makeNode(TruncateStmt);
  
  	COPY_NODE_FIELD(relations);
! 	COPY_SCALAR_FIELD(behavior);
  
  	return newnode;
  }
--- 2158,2165 ----
  	TruncateStmt *newnode = makeNode(TruncateStmt);
  
  	COPY_NODE_FIELD(relations);
! 	COPY_SCALAR_FIELD(identity_behavior);
! 	COPY_SCALAR_FIELD(drop_behavior);
  
  	return newnode;
  }
diff -dcrpN pgsql.orig/src/backend/nodes/equalfuncs.c pgsql/src/backend/nodes/equalfuncs.c
*** pgsql.orig/src/backend/nodes/equalfuncs.c	2008-04-18 20:49:12.000000000 +0200
--- pgsql/src/backend/nodes/equalfuncs.c	2008-04-21 21:36:32.000000000 +0200
*************** static bool
*** 1010,1016 ****
  _equalTruncateStmt(TruncateStmt *a, TruncateStmt *b)
  {
  	COMPARE_NODE_FIELD(relations);
! 	COMPARE_SCALAR_FIELD(behavior);
  
  	return true;
  }
--- 1010,1017 ----
  _equalTruncateStmt(TruncateStmt *a, TruncateStmt *b)
  {
  	COMPARE_NODE_FIELD(relations);
! 	COMPARE_SCALAR_FIELD(identity_behavior);
! 	COMPARE_SCALAR_FIELD(drop_behavior);
  
  	return true;
  }
diff -dcrpN pgsql.orig/src/backend/parser/gram.y pgsql/src/backend/parser/gram.y
*** pgsql.orig/src/backend/parser/gram.y	2008-04-18 20:49:12.000000000 +0200
--- pgsql/src/backend/parser/gram.y	2008-04-21 20:08:09.000000000 +0200
*************** static Node *makeXmlExpr(XmlExprOp op, c
*** 124,129 ****
--- 124,130 ----
  	bool				boolean;
  	JoinType			jtype;
  	DropBehavior		dbehavior;
+ 	IdentityBehavior	ibehavior;
  	OnCommitAction		oncommit;
  	List				*list;
  	Node				*node;
*************** static Node *makeXmlExpr(XmlExprOp op, c
*** 186,191 ****
--- 187,193 ----
  %type <list>	alter_table_cmds alter_rel_cmds
  
  %type <dbehavior>	opt_drop_behavior
+ %type <ibehavior>	opt_identity_behavior
  
  %type <list>	createdb_opt_list alterdb_opt_list copy_opt_list
  				transaction_mode_list
*************** static Node *makeXmlExpr(XmlExprOp op, c
*** 378,384 ****
  	CHARACTER CHARACTERISTICS CHECK CHECKPOINT CLASS CLOSE
  	CLUSTER COALESCE COLLATE COLUMN COMMENT COMMIT
  	COMMITTED CONCURRENTLY CONFIGURATION CONNECTION CONSTRAINT CONSTRAINTS
! 	CONTENT_P CONVERSION_P COPY COST CREATE CREATEDB
  	CREATEROLE CREATEUSER CROSS CSV CURRENT_P CURRENT_DATE CURRENT_ROLE
  	CURRENT_TIME CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE
  
--- 380,386 ----
  	CHARACTER CHARACTERISTICS CHECK CHECKPOINT CLASS CLOSE
  	CLUSTER COALESCE COLLATE COLUMN COMMENT COMMIT
  	COMMITTED CONCURRENTLY CONFIGURATION CONNECTION CONSTRAINT CONSTRAINTS
! 	CONTENT_P CONTINUE_P CONVERSION_P COPY COST CREATE CREATEDB
  	CREATEROLE CREATEUSER CROSS CSV CURRENT_P CURRENT_DATE CURRENT_ROLE
  	CURRENT_TIME CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE
  
*************** static Node *makeXmlExpr(XmlExprOp op, c
*** 396,402 ****
  
  	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
--- 398,404 ----
  
  	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
*************** opt_drop_behavior:
*** 1697,1702 ****
--- 1699,1710 ----
  			| /* EMPTY */				{ $$ = DROP_RESTRICT; /* default */ }
  		;
  
+ opt_identity_behavior:
+ 			CONTINUE_P IDENTITY				{ $$ = IDENTITY_CONTINUE; }
+ 			| RESTART IDENTITY				{ $$ = IDENTITY_RESTART; }
+ 			| /* EMPTY */				{ $$ = IDENTITY_CONTINUE; /* default */ }
+ 		;
+ 
  alter_using:
  			USING a_expr				{ $$ = $2; }
  			| /* EMPTY */				{ $$ = NULL; }
*************** OptSeqElem: CACHE NumericOnly
*** 2486,2491 ****
--- 2494,2503 ----
  				{
  					$$ = makeDefElem("start", (Node *)$3);
  				}
+ 			| RESTART
+ 				{
+ 					$$ = makeDefElem("restart", NULL);
+ 				}
  			| RESTART opt_with NumericOnly
  				{
  					$$ = makeDefElem("restart", (Node *)$3);
*************** attrs:		'.' attr_name
*** 3361,3371 ****
   *****************************************************************************/
  
  TruncateStmt:
! 			TRUNCATE opt_table qualified_name_list opt_drop_behavior
  				{
  					TruncateStmt *n = makeNode(TruncateStmt);
  					n->relations = $3;
! 					n->behavior = $4;
  					$$ = (Node *)n;
  				}
  		;
--- 3373,3384 ----
   *****************************************************************************/
  
  TruncateStmt:
! 			TRUNCATE opt_table qualified_name_list opt_identity_behavior opt_drop_behavior
  				{
  					TruncateStmt *n = makeNode(TruncateStmt);
  					n->relations = $3;
! 					n->identity_behavior = $4;
! 					n->drop_behavior = $5;
  					$$ = (Node *)n;
  				}
  		;
*************** unreserved_keyword:
*** 9056,9061 ****
--- 9069,9075 ----
  			| CONNECTION
  			| CONSTRAINTS
  			| CONTENT_P
+ 			| CONTINUE_P
  			| CONVERSION_P
  			| COPY
  			| COST
*************** reserved_keyword:
*** 9390,9395 ****
--- 9404,9410 ----
  			| 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	2008-03-30 13:29:47.000000000 +0200
--- pgsql/src/backend/parser/keywords.c	2008-04-21 20:06:31.000000000 +0200
*************** static const ScanKeyword ScanKeywords[] 
*** 101,106 ****
--- 101,107 ----
  	{"constraint", CONSTRAINT, RESERVED_KEYWORD},
  	{"constraints", CONSTRAINTS, UNRESERVED_KEYWORD},
  	{"content", CONTENT_P, UNRESERVED_KEYWORD},
+ 	{"continue", CONTINUE_P, UNRESERVED_KEYWORD},
  	{"conversion", CONVERSION_P, UNRESERVED_KEYWORD},
  	{"copy", COPY, UNRESERVED_KEYWORD},
  	{"cost", COST, UNRESERVED_KEYWORD},
*************** static const ScanKeyword ScanKeywords[] 
*** 181,186 ****
--- 182,188 ----
  	{"header", HEADER_P, UNRESERVED_KEYWORD},
  	{"hold", HOLD, UNRESERVED_KEYWORD},
  	{"hour", HOUR_P, UNRESERVED_KEYWORD},
+ 	{"identity", IDENTITY, RESERVED_KEYWORD},
  	{"if", IF_P, UNRESERVED_KEYWORD},
  	{"ilike", ILIKE, TYPE_FUNC_NAME_KEYWORD},
  	{"immediate", IMMEDIATE, UNRESERVED_KEYWORD},
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	2008-03-30 13:29:48.000000000 +0200
--- pgsql/src/backend/utils/adt/ruleutils.c	2008-04-21 21:58:51.000000000 +0200
*************** pg_get_serial_sequence(PG_FUNCTION_ARGS)
*** 1298,1308 ****
  	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));
--- 1298,1304 ----
  	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)
*** 1318,1363 ****
  				 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))
  	{
--- 1314,1320 ----
  				 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	2008-04-14 09:26:14.000000000 +0200
--- pgsql/src/backend/utils/cache/lsyscache.c	2008-04-21 22:03:49.000000000 +0200
***************
*** 15,26 ****
--- 15,31 ----
   */
  #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_constraint.h"
+ #include "catalog/pg_depend.h"
  #include "catalog/pg_namespace.h"
  #include "catalog/pg_opclass.h"
  #include "catalog/pg_operator.h"
***************
*** 32,39 ****
--- 37,46 ----
  #include "utils/array.h"
  #include "utils/builtins.h"
  #include "utils/datum.h"
+ #include "utils/fmgroids.h"
  #include "utils/lsyscache.h"
  #include "utils/syscache.h"
+ #include "utils/tqual.h"
  
  
  /*				---------- AMOP CACHES ----------						 */
*************** get_relid_attribute_name(Oid relid, Attr
*** 785,790 ****
--- 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/bin/pg_dump/pg_dump.c pgsql/src/bin/pg_dump/pg_dump.c
*** pgsql.orig/src/bin/pg_dump/pg_dump.c	2008-04-18 20:49:16.000000000 +0200
--- pgsql/src/bin/pg_dump/pg_dump.c	2008-04-21 18:50:19.000000000 +0200
*************** static void
*** 9424,9430 ****
  dumpSequence(Archive *fout, TableInfo *tbinfo)
  {
  	PGresult   *res;
! 	char	   *last,
  			   *incby,
  			   *maxv = NULL,
  			   *minv = NULL,
--- 9424,9431 ----
  dumpSequence(Archive *fout, TableInfo *tbinfo)
  {
  	PGresult   *res;
! 	char	   *startv,
! 			   *last,
  			   *incby,
  			   *maxv = NULL,
  			   *minv = NULL,
*************** dumpSequence(Archive *fout, TableInfo *t
*** 9442,9449 ****
  	snprintf(bufm, sizeof(bufm), INT64_FORMAT, SEQ_MINVALUE);
  	snprintf(bufx, sizeof(bufx), INT64_FORMAT, SEQ_MAXVALUE);
  
! 	appendPQExpBuffer(query,
! 					  "SELECT sequence_name, last_value, increment_by, "
  				   "CASE WHEN increment_by > 0 AND max_value = %s THEN NULL "
  				   "     WHEN increment_by < 0 AND max_value = -1 THEN NULL "
  					  "     ELSE max_value "
--- 9443,9469 ----
  	snprintf(bufm, sizeof(bufm), INT64_FORMAT, SEQ_MINVALUE);
  	snprintf(bufx, sizeof(bufx), INT64_FORMAT, SEQ_MAXVALUE);
  
! 	if (g_fout->remoteVersion >= 80400)
! 		appendPQExpBuffer(query,
! 					  "SELECT sequence_name, start_value, last_value, increment_by, "
! 				   "CASE WHEN increment_by > 0 AND max_value = %s THEN NULL "
! 				   "     WHEN increment_by < 0 AND max_value = -1 THEN NULL "
! 					  "     ELSE max_value "
! 					  "END AS max_value, "
! 					"CASE WHEN increment_by > 0 AND min_value = 1 THEN NULL "
! 				   "     WHEN increment_by < 0 AND min_value = %s THEN NULL "
! 					  "     ELSE min_value "
! 					  "END AS min_value, "
! 					  "cache_value, is_cycled, is_called from %s",
! 					  bufx, bufm,
! 					  fmtId(tbinfo->dobj.name));
! 	else
! 		appendPQExpBuffer(query,
! 					  "SELECT sequence_name, "
! 				   "CASE WHEN increment_by > 0 THEN min_value "
! 				   	"WHEN increment_by < 0 THEN max_value "
! 				   	"END as start_value, "
! 				   	"last_value, increment_by, "
  				   "CASE WHEN increment_by > 0 AND max_value = %s THEN NULL "
  				   "     WHEN increment_by < 0 AND max_value = -1 THEN NULL "
  					  "     ELSE max_value "
*************** dumpSequence(Archive *fout, TableInfo *t
*** 9476,9490 ****
  	}
  #endif
  
! 	last = PQgetvalue(res, 0, 1);
! 	incby = PQgetvalue(res, 0, 2);
! 	if (!PQgetisnull(res, 0, 3))
! 		maxv = PQgetvalue(res, 0, 3);
  	if (!PQgetisnull(res, 0, 4))
! 		minv = PQgetvalue(res, 0, 4);
! 	cache = PQgetvalue(res, 0, 5);
! 	cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0);
! 	called = (strcmp(PQgetvalue(res, 0, 7), "t") == 0);
  
  	/*
  	 * The logic we use for restoring sequences is as follows:
--- 9496,9511 ----
  	}
  #endif
  
! 	startv = PQgetvalue(res, 0, 1);
! 	last = PQgetvalue(res, 0, 2);
! 	incby = PQgetvalue(res, 0, 3);
  	if (!PQgetisnull(res, 0, 4))
! 		maxv = PQgetvalue(res, 0, 4);
! 	if (!PQgetisnull(res, 0, 5))
! 		minv = PQgetvalue(res, 0, 5);
! 	cache = PQgetvalue(res, 0, 6);
! 	cycled = (strcmp(PQgetvalue(res, 0, 7), "t") == 0);
! 	called = (strcmp(PQgetvalue(res, 0, 8), "t") == 0);
  
  	/*
  	 * The logic we use for restoring sequences is as follows:
*************** dumpSequence(Archive *fout, TableInfo *t
*** 9514,9521 ****
  						  "CREATE SEQUENCE %s\n",
  						  fmtId(tbinfo->dobj.name));
  
! 		if (!called)
! 			appendPQExpBuffer(query, "    START WITH %s\n", last);
  
  		appendPQExpBuffer(query, "    INCREMENT BY %s\n", incby);
  
--- 9535,9541 ----
  						  "CREATE SEQUENCE %s\n",
  						  fmtId(tbinfo->dobj.name));
  
! 		appendPQExpBuffer(query, "    START WITH %s\n", startv);
  
  		appendPQExpBuffer(query, "    INCREMENT BY %s\n", incby);
  
diff -dcrpN pgsql.orig/src/include/commands/sequence.h pgsql/src/include/commands/sequence.h
*** pgsql.orig/src/include/commands/sequence.h	2008-03-30 13:29:50.000000000 +0200
--- pgsql/src/include/commands/sequence.h	2008-04-21 18:50:19.000000000 +0200
*************** typedef struct FormData_pg_sequence
*** 29,34 ****
--- 29,35 ----
  {
  	NameData	sequence_name;
  #ifndef INT64_IS_BUSTED
+ 	int64		start_value;
  	int64		last_value;
  	int64		increment_by;
  	int64		max_value;
*************** typedef struct FormData_pg_sequence
*** 36,53 ****
  	int64		cache_value;
  	int64		log_cnt;
  #else
! 	int32		last_value;
  	int32		pad1;
! 	int32		increment_by;
  	int32		pad2;
! 	int32		max_value;
  	int32		pad3;
! 	int32		min_value;
  	int32		pad4;
! 	int32		cache_value;
  	int32		pad5;
! 	int32		log_cnt;
  	int32		pad6;
  #endif
  	bool		is_cycled;
  	bool		is_called;
--- 37,56 ----
  	int64		cache_value;
  	int64		log_cnt;
  #else
! 	int32		start_value;
  	int32		pad1;
! 	int32		last_value;
  	int32		pad2;
! 	int32		increment_by;
  	int32		pad3;
! 	int32		max_value;
  	int32		pad4;
! 	int32		min_value;
  	int32		pad5;
! 	int32		cache_value;
  	int32		pad6;
+ 	int32		log_cnt;
+ 	int32		pad7;
  #endif
  	bool		is_cycled;
  	bool		is_called;
*************** typedef FormData_pg_sequence *Form_pg_se
*** 60,73 ****
   */
  
  #define SEQ_COL_NAME			1
! #define SEQ_COL_LASTVAL			2
! #define SEQ_COL_INCBY			3
! #define SEQ_COL_MAXVALUE		4
! #define SEQ_COL_MINVALUE		5
! #define SEQ_COL_CACHE			6
! #define SEQ_COL_LOG				7
! #define SEQ_COL_CYCLE			8
! #define SEQ_COL_CALLED			9
  
  #define SEQ_COL_FIRSTCOL		SEQ_COL_NAME
  #define SEQ_COL_LASTCOL			SEQ_COL_CALLED
--- 63,77 ----
   */
  
  #define SEQ_COL_NAME			1
! #define SEQ_COL_STARTVAL		2
! #define SEQ_COL_LASTVAL			3
! #define SEQ_COL_INCBY			4
! #define SEQ_COL_MAXVALUE		5
! #define SEQ_COL_MINVALUE		6
! #define SEQ_COL_CACHE			7
! #define SEQ_COL_LOG			8
! #define SEQ_COL_CYCLE			9
! #define SEQ_COL_CALLED			10
  
  #define SEQ_COL_FIRSTCOL		SEQ_COL_NAME
  #define SEQ_COL_LASTCOL			SEQ_COL_CALLED
diff -dcrpN pgsql.orig/src/include/nodes/parsenodes.h pgsql/src/include/nodes/parsenodes.h
*** pgsql.orig/src/include/nodes/parsenodes.h	2008-04-18 20:49:17.000000000 +0200
--- pgsql/src/include/nodes/parsenodes.h	2008-04-21 20:10:44.000000000 +0200
*************** typedef struct CreateSchemaStmt
*** 868,873 ****
--- 868,879 ----
  	List	   *schemaElts;		/* schema components (list of parsenodes) */
  } CreateSchemaStmt;
  
+ typedef enum IdentityBehavior
+ {
+ 	IDENTITY_CONTINUE,		/* TRUNCATE doesn't modify SEQUENCEs behind SERIALs */
+ 	IDENTITY_RESTART		/* TRUNCATE restarts SEQUENCEs behind SERIALs */
+ } IdentityBehavior;
+ 
  typedef enum DropBehavior
  {
  	DROP_RESTRICT,				/* drop fails if any dependent objects */
*************** typedef struct DropPropertyStmt
*** 1457,1465 ****
   */
  typedef struct TruncateStmt
  {
! 	NodeTag		type;
! 	List	   *relations;		/* relations (RangeVars) to be truncated */
! 	DropBehavior behavior;		/* RESTRICT or CASCADE behavior */
  } TruncateStmt;
  
  /* ----------------------
--- 1463,1472 ----
   */
  typedef struct TruncateStmt
  {
! 	NodeTag			type;
! 	List		   *relations;		/* relations (RangeVars) to be truncated */
! 	IdentityBehavior	identity_behavior;
! 	DropBehavior		drop_behavior;		/* RESTRICT or CASCADE behavior */
  } TruncateStmt;
  
  /* ----------------------
diff -dcrpN pgsql.orig/src/include/utils/lsyscache.h pgsql/src/include/utils/lsyscache.h
*** pgsql.orig/src/include/utils/lsyscache.h	2008-04-14 09:26:17.000000000 +0200
--- pgsql/src/include/utils/lsyscache.h	2008-04-21 21:59:42.000000000 +0200
*************** extern Oid get_opfamily_proc(Oid opfamil
*** 52,57 ****
--- 52,58 ----
  				  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/sequence.out pgsql/src/test/regress/expected/sequence.out
*** pgsql.orig/src/test/regress/expected/sequence.out	2006-08-21 02:57:26.000000000 +0200
--- pgsql/src/test/regress/expected/sequence.out	2008-04-21 18:50:19.000000000 +0200
*************** DROP SEQUENCE sequence_test;
*** 99,107 ****
  CREATE SEQUENCE foo_seq;
  ALTER TABLE foo_seq RENAME TO foo_seq_new;
  SELECT * FROM foo_seq_new;
!  sequence_name | last_value | increment_by |      max_value      | min_value | cache_value | log_cnt | is_cycled | is_called 
! ---------------+------------+--------------+---------------------+-----------+-------------+---------+-----------+-----------
!  foo_seq       |          1 |            1 | 9223372036854775807 |         1 |           1 |       1 | f         | f
  (1 row)
  
  DROP SEQUENCE foo_seq_new;
--- 99,107 ----
  CREATE SEQUENCE foo_seq;
  ALTER TABLE foo_seq RENAME TO foo_seq_new;
  SELECT * FROM foo_seq_new;
!  sequence_name | start_value | last_value | increment_by |      max_value      | min_value | cache_value | log_cnt | is_cycled | is_called 
! ---------------+-------------+------------+--------------+---------------------+-----------+-------------+---------+-----------+-----------
!  foo_seq       |           1 |          1 |            1 | 9223372036854775807 |         1 |           1 |       1 | f         | f
  (1 row)
  
  DROP SEQUENCE foo_seq_new;
*************** SELECT nextval('sequence_test2');
*** 175,180 ****
--- 175,212 ----
         5
  (1 row)
  
+ ALTER SEQUENCE sequence_test2 RESTART
+ 	 INCREMENT BY 4 MAXVALUE 36 MINVALUE 5 CYCLE;
+ SELECT nextval('sequence_test2');
+  nextval 
+ ---------
+       32
+ (1 row)
+ 
+ SELECT nextval('sequence_test2');
+  nextval 
+ ---------
+       36
+ (1 row)
+ 
+ SELECT nextval('sequence_test2');
+  nextval 
+ ---------
+        5
+ (1 row)
+ 
+ SELECT nextval('sequence_test2');
+  nextval 
+ ---------
+        9
+ (1 row)
+ 
+ SELECT nextval('sequence_test2');
+  nextval 
+ ---------
+       13
+ (1 row)
+ 
  -- Test comments
  COMMENT ON SEQUENCE asdf IS 'won''t work';
  ERROR:  relation "asdf" does not exist
diff -dcrpN pgsql.orig/src/test/regress/expected/truncate.out pgsql/src/test/regress/expected/truncate.out
*** pgsql.orig/src/test/regress/expected/truncate.out	2008-03-30 13:29:52.000000000 +0200
--- pgsql/src/test/regress/expected/truncate.out	2008-04-21 22:21:31.000000000 +0200
*************** SELECT * FROM trunc_trigger_log;
*** 223,225 ****
--- 223,272 ----
  DROP TABLE trunc_trigger_test;
  DROP TABLE trunc_trigger_log;
  DROP FUNCTION trunctrigger();
+ -- test TRUNCATE ... RESTART IDENTITY
+ CREATE SEQUENCE truncate_a_id1 START WITH 33;
+ CREATE TABLE truncate_a (id serial, id1 integer default nextval('truncate_a_id1'));
+ NOTICE:  CREATE TABLE will create implicit sequence "truncate_a_id_seq" for serial column "truncate_a.id"
+ ALTER SEQUENCE truncate_a_id1 OWNED BY truncate_a.id1;
+ INSERT INTO truncate_a DEFAULT VALUES;
+ INSERT INTO truncate_a DEFAULT VALUES;
+ INSERT INTO truncate_a DEFAULT VALUES;
+ INSERT INTO truncate_a DEFAULT VALUES;
+ SELECT * FROM truncate_a;
+  id | id1 
+ ----+-----
+   1 |  33
+   2 |  34
+   3 |  35
+   4 |  36
+ (4 rows)
+ 
+ TRUNCATE truncate_a;
+ INSERT INTO truncate_a DEFAULT VALUES;
+ INSERT INTO truncate_a DEFAULT VALUES;
+ INSERT INTO truncate_a DEFAULT VALUES;
+ INSERT INTO truncate_a DEFAULT VALUES;
+ SELECT * FROM truncate_a;
+  id | id1 
+ ----+-----
+   5 |  37
+   6 |  38
+   7 |  39
+   8 |  40
+ (4 rows)
+ 
+ TRUNCATE truncate_a RESTART IDENTITY;
+ INSERT INTO truncate_a DEFAULT VALUES;
+ INSERT INTO truncate_a DEFAULT VALUES;
+ INSERT INTO truncate_a DEFAULT VALUES;
+ INSERT INTO truncate_a DEFAULT VALUES;
+ SELECT * FROM truncate_a;
+  id | id1 
+ ----+-----
+   1 |  33
+   2 |  34
+   3 |  35
+   4 |  36
+ (4 rows)
+ 
+ DROP TABLE truncate_a;
diff -dcrpN pgsql.orig/src/test/regress/sql/sequence.sql pgsql/src/test/regress/sql/sequence.sql
*** pgsql.orig/src/test/regress/sql/sequence.sql	2005-10-03 01:50:16.000000000 +0200
--- pgsql/src/test/regress/sql/sequence.sql	2008-04-21 18:50:19.000000000 +0200
*************** SELECT nextval('sequence_test2');
*** 74,79 ****
--- 74,88 ----
  SELECT nextval('sequence_test2');
  SELECT nextval('sequence_test2');
  
+ ALTER SEQUENCE sequence_test2 RESTART
+ 	 INCREMENT BY 4 MAXVALUE 36 MINVALUE 5 CYCLE;
+ 
+ SELECT nextval('sequence_test2');
+ SELECT nextval('sequence_test2');
+ SELECT nextval('sequence_test2');
+ SELECT nextval('sequence_test2');
+ SELECT nextval('sequence_test2');
+ 
  -- Test comments
  COMMENT ON SEQUENCE asdf IS 'won''t work';
  COMMENT ON SEQUENCE sequence_test2 IS 'will work';
diff -dcrpN pgsql.orig/src/test/regress/sql/truncate.sql pgsql/src/test/regress/sql/truncate.sql
*** pgsql.orig/src/test/regress/sql/truncate.sql	2008-03-30 13:29:52.000000000 +0200
--- pgsql/src/test/regress/sql/truncate.sql	2008-04-21 22:20:27.000000000 +0200
*************** DROP TABLE trunc_trigger_test;
*** 130,132 ****
--- 130,164 ----
  DROP TABLE trunc_trigger_log;
  
  DROP FUNCTION trunctrigger();
+ 
+ -- test TRUNCATE ... RESTART IDENTITY
+ CREATE SEQUENCE truncate_a_id1 START WITH 33;
+ CREATE TABLE truncate_a (id serial, id1 integer default nextval('truncate_a_id1'));
+ ALTER SEQUENCE truncate_a_id1 OWNED BY truncate_a.id1;
+ 
+ INSERT INTO truncate_a DEFAULT VALUES;
+ INSERT INTO truncate_a DEFAULT VALUES;
+ INSERT INTO truncate_a DEFAULT VALUES;
+ INSERT INTO truncate_a DEFAULT VALUES;
+ 
+ SELECT * FROM truncate_a;
+ 
+ TRUNCATE truncate_a;
+ 
+ INSERT INTO truncate_a DEFAULT VALUES;
+ INSERT INTO truncate_a DEFAULT VALUES;
+ INSERT INTO truncate_a DEFAULT VALUES;
+ INSERT INTO truncate_a DEFAULT VALUES;
+ 
+ SELECT * FROM truncate_a;
+ 
+ TRUNCATE truncate_a RESTART IDENTITY;
+ 
+ INSERT INTO truncate_a DEFAULT VALUES;
+ INSERT INTO truncate_a DEFAULT VALUES;
+ INSERT INTO truncate_a DEFAULT VALUES;
+ INSERT INTO truncate_a DEFAULT VALUES;
+ 
+ SELECT * FROM truncate_a;
+ 
+ DROP TABLE truncate_a;
