-CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE table_name [ (column_name [, ...] ) ]
+CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE table_name [ (column_name [, ...] ) ] [ [ WITH | WITHOUT ] OIDS ]
AS query
+
+ WITH OIDS
+ WITHOUT OIDS
+
+ This optional clause specifies whether the table created by
+ CREATE TABLE AS should include OIDs. If
+ neither form of this clause if specified, the value of the
+ default_with_oids configuration parameter is
+ used.
+
+
+
+
query
This command is functionally similar to
linkend="sql-selectinto" endterm="sql-selectinto-title">, but it is
preferred since it is less likely to be confused with other uses of
- the SELECT INTO syntax.
+ the SELECT INTO> syntax. Furthermore, CREATE
+ TABLE AS offers a superset of the functionality offerred
+ by SELECT INTO.
- Prior to
PostgreSQL> 7.5, CREATE TABLE
- AS always included OIDs in the table it
+ Prior to
PostgreSQLproductname> 7.5, CREATE
+ TABLE AS 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 SELECT or EXECUTE
statement. Therefore, if CREATE TABLE AS was
frequently executed, the OID counter would be rapidly
- incremented. As of
PostgreSQL> 7.5, the inclusion of
- OIDs in the table generated by CREATE TABLE AS
- is controlled by the default_with_oids
- configuration variable. This variable currently defaults to true,
- but will likely default to false in a future release of
+ incremented. As of
PostgresSQL 7.5,
+ the CREATE TABLE AS command allows the user to
+ explicitely specify whether OIDs should be included. If the
+ presence of OIDs is not explicitely specified,
+ the default_with_oids 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 CREATE TABLE
+ AS should explicitely specify WITH
+ OIDS to ensure compatibility with future versions
default_with_oids (boolean)
- This controls whether CREATE TABLE will
- include OIDs in newly-created tables, if neither WITH
- OIDS or WITHOUT OIDS have been
- specified. It also determines whether OIDs will be included in
- the table generated by SELECT INTO and
- CREATE TABLE AS. In
+ This controls whether CREATE TABLE
+ and CREATE TABLE AS will include OIDs in
+ newly-created tables, if neither WITH OIDS
+ or WITHOUT OIDS have been specified. It
+ also determines whether OIDs will be included in the table
+ created by SELECT INTO. In
- default_with_oids defaults to true. This is
- also the behavior of previous versions of
-
PostgreSQL. However, assuming that
- tables will contain OIDs by default is not
+ default_with_oids defaults to
+ true. This is also the behavior of previous versions
+ of
PostgreSQL. However, assuming
+ that tables will contain OIDs by default is not
encouraged. Therefore, this option will default to false in a
future release of
PostgreSQL.
*
*
* 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 func_arg
%type func_return func_type aggr_argtype
-%type arg_class TriggerForType OptTemp OptWithOids
-%type OnCommitOption
+%type arg_class TriggerForType OptTemp
+%type OnCommitOption
+%type OptWithOids WithOidsAs
%type for_update_clause opt_for_update_clause update_list
%type 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;