<!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/create_table_as.sgml,v 1.19 2003/12/13 23:59:07 neilc Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/create_table_as.sgml,v 1.20 2004/01/10 23:28:44 neilc Exp $
PostgreSQL documentation
-->
<refsynopsisdiv>
<synopsis>
-CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable>table_name</replaceable> [ (<replaceable>column_name</replaceable> [, ...] ) ]
+CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable>table_name</replaceable> [ (<replaceable>column_name</replaceable> [, ...] ) ] [ [ WITH | WITHOUT ] OIDS ]
AS <replaceable>query</replaceable>
</synopsis>
</refsynopsisdiv>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><literal>WITH OIDS</literal></term>
+ <term><literal>WITHOUT OIDS</literal></term>
+ <listitem>
+ <para>
+ This optional clause specifies whether the table created by
+ <command>CREATE TABLE AS</command> should include OIDs. If
+ neither form of this clause if specified, the value of the
+ <varname>default_with_oids</varname> configuration parameter is
+ used.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><replaceable>query</replaceable></term>
<listitem>
This command is functionally similar to <xref
linkend="sql-selectinto" endterm="sql-selectinto-title">, but it is
preferred since it is less likely to be confused with other uses of
- the <command>SELECT INTO</command> syntax.
+ the <command>SELECT INTO</> syntax. Furthermore, <command>CREATE
+ TABLE AS</command> offers a superset of the functionality offerred
+ by <command>SELECT INTO</command>.
</para>
<para>
- Prior to <productname>PostgreSQL</> 7.5, <command>CREATE TABLE
- AS</command> always included OIDs in the table it
+ Prior to <productname>PostgreSQL</productname> 7.5, <command>CREATE
+ TABLE AS</command> always included OIDs in the table it
produced. Furthermore, these OIDs were newly generated: they were
distinct from the OIDs of any of the rows in the source tables of
the <command>SELECT</command> or <command>EXECUTE</command>
statement. Therefore, if <command>CREATE TABLE AS</command> was
frequently executed, the OID counter would be rapidly
- incremented. As of <productname>PostgreSQL</> 7.5, the inclusion of
- OIDs in the table generated by <command>CREATE TABLE AS</command>
- is controlled by the <varname>default_with_oids</varname>
- configuration variable. This variable currently defaults to true,
- but will likely default to false in a future release of
- <productname>PostgreSQL</>.
+ incremented. As of <productname>PostgresSQL</productname> 7.5,
+ the <command>CREATE TABLE AS</command> command allows the user to
+ explicitely specify whether OIDs should be included. If the
+ presence of OIDs is not explicitely specified,
+ the <varname>default_with_oids</varname> configuration variable is
+ used. While this variable currently defaults to true, the default
+ value may be changed in the future. Therefore, applications that
+ require OIDs in the table created by <command>CREATE TABLE
+ AS</command> should explicitely specify <literal>WITH
+ OIDS</literal> to ensure compatibility with future versions
+ of <productname>PostgreSQL</productname>.
</para>
</refsect1>
<!--
-$PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.229 2004/01/06 17:26:22 neilc Exp $
+$PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.230 2004/01/10 23:28:43 neilc Exp $
-->
<Chapter Id="runtime">
<term><varname>default_with_oids</varname> (<type>boolean</type>)</term>
<listitem>
<para>
- This controls whether <command>CREATE TABLE</command> will
- include OIDs in newly-created tables, if neither <literal>WITH
- OIDS</literal> or <literal>WITHOUT OIDS</literal> have been
- specified. It also determines whether OIDs will be included in
- the table generated by <command>SELECT INTO</command> and
- <command>CREATE TABLE AS</command>. In
+ This controls whether <command>CREATE TABLE</command>
+ and <command>CREATE TABLE AS</command> will include OIDs in
+ newly-created tables, if neither <literal>WITH OIDS</literal>
+ or <literal>WITHOUT OIDS</literal> have been specified. It
+ also determines whether OIDs will be included in the table
+ created by <command>SELECT INTO</command>. In
<productname>PostgreSQL</productname> &version;
- <varname>default_with_oids</varname> defaults to true. This is
- also the behavior of previous versions of
- <productname>PostgreSQL</productname>. However, assuming that
- tables will contain OIDs by default is not
+ <varname>default_with_oids</varname> defaults to
+ true. This is also the behavior of previous versions
+ of <productname>PostgreSQL</productname>. However, assuming
+ that tables will contain OIDs by default is not
encouraged. Therefore, this option will default to false in a
future release of <productname>PostgreSQL</productname>.
</para>
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/sequence.c,v 1.107 2004/01/07 18:56:25 neilc Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/sequence.c,v 1.108 2004/01/10 23:28:44 neilc Exp $
*
*-------------------------------------------------------------------------
*/
stmt->relation = seq->sequence;
stmt->inhRelations = NIL;
stmt->constraints = NIL;
- stmt->hasoids = false;
+ stmt->hasoids = MUST_NOT_HAVE_OIDS;
stmt->oncommit = ONCOMMIT_NOOP;
seqoid = DefineRelation(stmt, RELKIND_SEQUENCE);
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.94 2003/11/29 19:51:47 pgsql Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.95 2004/01/10 23:28:44 neilc Exp $
*
*-------------------------------------------------------------------------
*/
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h"
+#include "utils/guc.h"
#include "utils/inval.h"
#include "utils/lsyscache.h"
#include "utils/relcache.h"
*/
descriptor = BuildDescForRelation(schema);
- descriptor->tdhasoid = (stmt->hasoids || parentHasOids);
+ if (parentHasOids)
+ descriptor->tdhasoid = true;
+ else
+ {
+ switch (stmt->hasoids)
+ {
+ case MUST_HAVE_OIDS:
+ descriptor->tdhasoid = true;
+ break;
+
+ case MUST_NOT_HAVE_OIDS:
+ descriptor->tdhasoid = false;
+ break;
+
+ case DEFAULT_OIDS:
+ descriptor->tdhasoid = default_with_oids;
+ break;
+ }
+ }
if (old_constraints != NIL)
{
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.51 2003/11/29 19:51:47 pgsql Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.52 2004/01/10 23:28:44 neilc Exp $
*
* DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the
createStmt->tableElts = coldeflist;
createStmt->inhRelations = NIL;
createStmt->constraints = NIL;
- createStmt->hasoids = false;
+ createStmt->hasoids = MUST_NOT_HAVE_OIDS;
createStmt->oncommit = ONCOMMIT_NOOP;
/*
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/view.c,v 1.79 2003/11/29 19:51:48 pgsql Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/view.c,v 1.80 2004/01/10 23:28:44 neilc Exp $
*
*-------------------------------------------------------------------------
*/
createStmt->tableElts = attrList;
createStmt->inhRelations = NIL;
createStmt->constraints = NIL;
- createStmt->hasoids = false;
+ createStmt->hasoids = MUST_NOT_HAVE_OIDS;
createStmt->oncommit = ONCOMMIT_NOOP;
/*
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.225 2004/01/07 18:56:26 neilc Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.226 2004/01/10 23:28:44 neilc Exp $
*
*-------------------------------------------------------------------------
*/
if (operation == CMD_SELECT && parseTree->into != NULL)
{
do_select_into = true;
-
- /*
- * The presence of OIDs in the result set of SELECT INTO is
- * controlled by the default_with_oids GUC parameter. The
- * behavior in versions of PostgreSQL prior to 7.5 is to
- * always include OIDs.
- */
- estate->es_force_oids = default_with_oids;
+ estate->es_force_oids = parseTree->intoHasOids;
}
/*
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.275 2004/01/06 23:55:18 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.276 2004/01/10 23:28:44 neilc Exp $
*
*-------------------------------------------------------------------------
*/
COPY_NODE_FIELD(utilityStmt);
COPY_SCALAR_FIELD(resultRelation);
COPY_NODE_FIELD(into);
+ COPY_SCALAR_FIELD(intoHasOids);
COPY_SCALAR_FIELD(hasAggs);
COPY_SCALAR_FIELD(hasSubLinks);
COPY_NODE_FIELD(rtable);
COPY_NODE_FIELD(distinctClause);
COPY_NODE_FIELD(into);
COPY_NODE_FIELD(intoColNames);
+ COPY_SCALAR_FIELD(intoHasOids);
COPY_NODE_FIELD(targetList);
COPY_NODE_FIELD(fromClause);
COPY_NODE_FIELD(whereClause);
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.213 2004/01/06 23:55:18 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.214 2004/01/10 23:28:45 neilc Exp $
*
*-------------------------------------------------------------------------
*/
COMPARE_NODE_FIELD(utilityStmt);
COMPARE_SCALAR_FIELD(resultRelation);
COMPARE_NODE_FIELD(into);
+ COMPARE_SCALAR_FIELD(intoHasOids);
COMPARE_SCALAR_FIELD(hasAggs);
COMPARE_SCALAR_FIELD(hasSubLinks);
COMPARE_NODE_FIELD(rtable);
COMPARE_NODE_FIELD(distinctClause);
COMPARE_NODE_FIELD(into);
COMPARE_NODE_FIELD(intoColNames);
+ COMPARE_SCALAR_FIELD(intoHasOids);
COMPARE_NODE_FIELD(targetList);
COMPARE_NODE_FIELD(fromClause);
COMPARE_NODE_FIELD(whereClause);
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.293 2004/01/05 20:58:58 neilc Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.294 2004/01/10 23:28:45 neilc Exp $
*
*-------------------------------------------------------------------------
*/
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h"
+#include "utils/guc.h"
#include "utils/lsyscache.h"
#include "utils/relcache.h"
#include "utils/syscache.h"
if (stmt->intoColNames)
applyColumnNames(qry->targetList, stmt->intoColNames);
+ switch (stmt->intoHasOids)
+ {
+ case MUST_HAVE_OIDS:
+ qry->intoHasOids = true;
+ break;
+
+ case MUST_NOT_HAVE_OIDS:
+ qry->intoHasOids = false;
+ break;
+
+ case DEFAULT_OIDS:
+ qry->intoHasOids = default_with_oids;
+ break;
+ }
+
/* mark column origins */
markTargetListOrigins(pstate, qry->targetList);
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.444 2004/01/10 02:21:08 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.445 2004/01/10 23:28:45 neilc Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
#include "utils/numeric.h"
#include "utils/datetime.h"
#include "utils/date.h"
-#include "utils/guc.h"
extern List *parsetree; /* final parse result is delivered here */
JoinType jtype;
DropBehavior dbehavior;
OnCommitAction oncommit;
+ ContainsOids withoids;
List *list;
FastList fastlist;
Node *node;
%type <fun_param> func_arg
%type <typnam> func_return func_type aggr_argtype
-%type <boolean> arg_class TriggerForType OptTemp OptWithOids
-%type <oncommit> OnCommitOption
+%type <boolean> arg_class TriggerForType OptTemp
+%type <oncommit> OnCommitOption
+%type <withoids> OptWithOids WithOidsAs
%type <list> for_update_clause opt_for_update_clause update_list
%type <boolean> opt_all
;
OptWithOids:
- WITH OIDS { $$ = TRUE; }
- | WITHOUT OIDS { $$ = FALSE; }
- /*
- * If the user didn't explicitely specify WITH or WITHOUT
- * OIDS, decide whether to include OIDs based on the
- * "default_with_oids" GUC var
- */
- | /*EMPTY*/ { $$ = default_with_oids; }
+ WITH OIDS { $$ = MUST_HAVE_OIDS; }
+ | WITHOUT OIDS { $$ = MUST_NOT_HAVE_OIDS; }
+ | /*EMPTY*/ { $$ = DEFAULT_OIDS; }
;
OnCommitOption: ON COMMIT DROP { $$ = ONCOMMIT_DROP; }
*/
CreateAsStmt:
- CREATE OptTemp TABLE qualified_name OptCreateAs AS SelectStmt
+ CREATE OptTemp TABLE qualified_name OptCreateAs WithOidsAs SelectStmt
{
/*
* When the SelectStmt is a set-operation tree, we must
$4->istemp = $2;
n->into = $4;
n->intoColNames = $5;
+ n->intoHasOids = $6;
$$ = $7;
}
;
+/*
+ * To avoid a shift/reduce conflict in CreateAsStmt, we need to
+ * include the 'AS' terminal in the parsing of WITH/WITHOUT
+ * OIDS. Unfortunately that means this production is effectively a
+ * duplicate of OptWithOids.
+ */
+WithOidsAs:
+ WITH OIDS AS { $$ = MUST_HAVE_OIDS; }
+ | WITHOUT OIDS AS { $$ = MUST_NOT_HAVE_OIDS; }
+ | AS { $$ = DEFAULT_OIDS; }
+ ;
+
OptCreateAs:
'(' CreateAsList ')' { $$ = $2; }
| /*EMPTY*/ { $$ = NIL; }
n->targetList = $3;
n->into = $4;
n->intoColNames = NIL;
+ n->intoHasOids = DEFAULT_OIDS;
n->fromClause = $5;
n->whereClause = $6;
n->groupClause = $7;
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.251 2004/01/06 23:55:19 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.252 2004/01/10 23:28:45 neilc Exp $
*
*-------------------------------------------------------------------------
*/
int resultRelation; /* target relation (index into rtable) */
RangeVar *into; /* target relation for SELECT INTO */
+ bool intoHasOids; /* should target relation contain OIDs? */
bool hasAggs; /* has aggregates in tlist or havingQual */
bool hasSubLinks; /* has subquery SubLink */
SETOP_EXCEPT
} SetOperation;
+typedef enum ContainsOids
+{
+ MUST_HAVE_OIDS, /* WITH OIDS explicitely specified */
+ MUST_NOT_HAVE_OIDS, /* WITHOUT OIDS explicitely specified */
+ DEFAULT_OIDS /* neither specified; use the default,
+ * which is the value of the
+ * default_with_oids GUC var
+ */
+} ContainsOids;
+
typedef struct SelectStmt
{
NodeTag type;
/*
* These fields are used only in "leaf" SelectStmts.
*
- * into and intoColNames are a kluge; they belong somewhere else...
+ * into, intoColNames and intoHasOids are a kluge; they belong
+ * somewhere else...
*/
List *distinctClause; /* NULL, list of DISTINCT ON exprs, or
* lcons(NIL,NIL) for all (SELECT
* DISTINCT) */
RangeVar *into; /* target table (for select into table) */
List *intoColNames; /* column names for into table */
+ ContainsOids intoHasOids; /* should target table have OIDs? */
List *targetList; /* the target list (of ResTarget) */
List *fromClause; /* the FROM clause */
Node *whereClause; /* WHERE qualification */
List *inhRelations; /* relations to inherit from (list of
* inhRelation) */
List *constraints; /* constraints (list of Constraint nodes) */
- bool hasoids; /* should it have OIDs? */
+ ContainsOids hasoids; /* should it have OIDs? */
OnCommitAction oncommit; /* what do we do at COMMIT? */
} CreateStmt;
DROP TABLE wi;
DROP TABLE wo;
+--
+-- WITH / WITHOUT OIDS in CREATE TABLE AS
+--
+CREATE TABLE create_table_test (
+ a int,
+ b int
+);
+COPY create_table_test FROM stdin;
+CREATE TABLE create_table_test2 WITH OIDS AS
+ SELECT a + b AS c1, a - b AS c2 FROM create_table_test;
+CREATE TABLE create_table_test3 WITHOUT OIDS AS
+ SELECT a + b AS c1, a - b AS c2 FROM create_table_test;
+SELECT count(oid) FROM create_table_test2;
+ count
+-------
+ 2
+(1 row)
+
+-- should fail
+SELECT count(oid) FROM create_table_test3;
+ERROR: column "oid" does not exist
+DROP TABLE create_table_test;
+DROP TABLE create_table_test2;
+DROP TABLE create_table_test3;
DROP TABLE wi;
DROP TABLE wo;
+
+--
+-- WITH / WITHOUT OIDS in CREATE TABLE AS
+--
+CREATE TABLE create_table_test (
+ a int,
+ b int
+);
+
+COPY create_table_test FROM stdin;
+5 10
+10 15
+\.
+
+CREATE TABLE create_table_test2 WITH OIDS AS
+ SELECT a + b AS c1, a - b AS c2 FROM create_table_test;
+
+CREATE TABLE create_table_test3 WITHOUT OIDS AS
+ SELECT a + b AS c1, a - b AS c2 FROM create_table_test;
+
+SELECT count(oid) FROM create_table_test2;
+-- should fail
+SELECT count(oid) FROM create_table_test3;
+
+DROP TABLE create_table_test;
+DROP TABLE create_table_test2;
+DROP TABLE create_table_test3;