Commit 98dcf085 authored by Neil Conway's avatar Neil Conway

Implement "WITH / WITHOID OIDS" clause for CREATE TABLE AS. This is

intended to allow application authors to insulate themselves from
changes to the default value of 'default_with_oids' in future releases
of PostgreSQL.

This patch also fixes a bug in the earlier implementation of the
'default_with_oids' GUC variable: code in gram.y should not examine
the value of GUC variables directly due to synchronization issues.
parent cf4c925d
<!-- <!--
$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 PostgreSQL documentation
--> -->
...@@ -20,7 +20,7 @@ PostgreSQL documentation ...@@ -20,7 +20,7 @@ PostgreSQL documentation
<refsynopsisdiv> <refsynopsisdiv>
<synopsis> <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> AS <replaceable>query</replaceable>
</synopsis> </synopsis>
</refsynopsisdiv> </refsynopsisdiv>
...@@ -98,6 +98,20 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable>table_name ...@@ -98,6 +98,20 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable>table_name
</listitem> </listitem>
</varlistentry> </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> <varlistentry>
<term><replaceable>query</replaceable></term> <term><replaceable>query</replaceable></term>
<listitem> <listitem>
...@@ -121,23 +135,30 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable>table_name ...@@ -121,23 +135,30 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable>table_name
This command is functionally similar to <xref This command is functionally similar to <xref
linkend="sql-selectinto" endterm="sql-selectinto-title">, but it is linkend="sql-selectinto" endterm="sql-selectinto-title">, but it is
preferred since it is less likely to be confused with other uses of 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>
<para> <para>
Prior to <productname>PostgreSQL</> 7.5, <command>CREATE TABLE Prior to <productname>PostgreSQL</productname> 7.5, <command>CREATE
AS</command> always included OIDs in the table it TABLE AS</command> always included OIDs in the table it
produced. Furthermore, these OIDs were newly generated: they were produced. Furthermore, these OIDs were newly generated: they were
distinct from the OIDs of any of the rows in the source tables of distinct from the OIDs of any of the rows in the source tables of
the <command>SELECT</command> or <command>EXECUTE</command> the <command>SELECT</command> or <command>EXECUTE</command>
statement. Therefore, if <command>CREATE TABLE AS</command> was statement. Therefore, if <command>CREATE TABLE AS</command> was
frequently executed, the OID counter would be rapidly frequently executed, the OID counter would be rapidly
incremented. As of <productname>PostgreSQL</> 7.5, the inclusion of incremented. As of <productname>PostgresSQL</productname> 7.5,
OIDs in the table generated by <command>CREATE TABLE AS</command> the <command>CREATE TABLE AS</command> command allows the user to
is controlled by the <varname>default_with_oids</varname> explicitely specify whether OIDs should be included. If the
configuration variable. This variable currently defaults to true, presence of OIDs is not explicitely specified,
but will likely default to false in a future release of the <varname>default_with_oids</varname> configuration variable is
<productname>PostgreSQL</>. 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> </para>
</refsect1> </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"> <Chapter Id="runtime">
...@@ -2437,17 +2437,17 @@ dynamic_library_path = '/usr/local/lib/postgresql:/home/my_project/lib:$libdir' ...@@ -2437,17 +2437,17 @@ dynamic_library_path = '/usr/local/lib/postgresql:/home/my_project/lib:$libdir'
<term><varname>default_with_oids</varname> (<type>boolean</type>)</term> <term><varname>default_with_oids</varname> (<type>boolean</type>)</term>
<listitem> <listitem>
<para> <para>
This controls whether <command>CREATE TABLE</command> will This controls whether <command>CREATE TABLE</command>
include OIDs in newly-created tables, if neither <literal>WITH and <command>CREATE TABLE AS</command> will include OIDs in
OIDS</literal> or <literal>WITHOUT OIDS</literal> have been newly-created tables, if neither <literal>WITH OIDS</literal>
specified. It also determines whether OIDs will be included in or <literal>WITHOUT OIDS</literal> have been specified. It
the table generated by <command>SELECT INTO</command> and also determines whether OIDs will be included in the table
<command>CREATE TABLE AS</command>. In created by <command>SELECT INTO</command>. In
<productname>PostgreSQL</productname> &version; <productname>PostgreSQL</productname> &version;
<varname>default_with_oids</varname> defaults to true. This is <varname>default_with_oids</varname> defaults to
also the behavior of previous versions of true. This is also the behavior of previous versions
<productname>PostgreSQL</productname>. However, assuming that of <productname>PostgreSQL</productname>. However, assuming
tables will contain OIDs by default is not that tables will contain OIDs by default is not
encouraged. Therefore, this option will default to false in a encouraged. Therefore, this option will default to false in a
future release of <productname>PostgreSQL</productname>. future release of <productname>PostgreSQL</productname>.
</para> </para>
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -178,7 +178,7 @@ DefineSequence(CreateSeqStmt *seq) ...@@ -178,7 +178,7 @@ DefineSequence(CreateSeqStmt *seq)
stmt->relation = seq->sequence; stmt->relation = seq->sequence;
stmt->inhRelations = NIL; stmt->inhRelations = NIL;
stmt->constraints = NIL; stmt->constraints = NIL;
stmt->hasoids = false; stmt->hasoids = MUST_NOT_HAVE_OIDS;
stmt->oncommit = ONCOMMIT_NOOP; stmt->oncommit = ONCOMMIT_NOOP;
seqoid = DefineRelation(stmt, RELKIND_SEQUENCE); seqoid = DefineRelation(stmt, RELKIND_SEQUENCE);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -47,6 +47,7 @@ ...@@ -47,6 +47,7 @@
#include "utils/acl.h" #include "utils/acl.h"
#include "utils/builtins.h" #include "utils/builtins.h"
#include "utils/fmgroids.h" #include "utils/fmgroids.h"
#include "utils/guc.h"
#include "utils/inval.h" #include "utils/inval.h"
#include "utils/lsyscache.h" #include "utils/lsyscache.h"
#include "utils/relcache.h" #include "utils/relcache.h"
...@@ -185,7 +186,25 @@ DefineRelation(CreateStmt *stmt, char relkind) ...@@ -185,7 +186,25 @@ DefineRelation(CreateStmt *stmt, char relkind)
*/ */
descriptor = BuildDescForRelation(schema); 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) if (old_constraints != NIL)
{ {
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the * The "DefineFoo" routines take the parse tree and pick out the
...@@ -1066,7 +1066,7 @@ DefineCompositeType(const RangeVar *typevar, List *coldeflist) ...@@ -1066,7 +1066,7 @@ DefineCompositeType(const RangeVar *typevar, List *coldeflist)
createStmt->tableElts = coldeflist; createStmt->tableElts = coldeflist;
createStmt->inhRelations = NIL; createStmt->inhRelations = NIL;
createStmt->constraints = NIL; createStmt->constraints = NIL;
createStmt->hasoids = false; createStmt->hasoids = MUST_NOT_HAVE_OIDS;
createStmt->oncommit = ONCOMMIT_NOOP; createStmt->oncommit = ONCOMMIT_NOOP;
/* /*
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -141,7 +141,7 @@ DefineVirtualRelation(const RangeVar *relation, List *tlist, bool replace) ...@@ -141,7 +141,7 @@ DefineVirtualRelation(const RangeVar *relation, List *tlist, bool replace)
createStmt->tableElts = attrList; createStmt->tableElts = attrList;
createStmt->inhRelations = NIL; createStmt->inhRelations = NIL;
createStmt->constraints = NIL; createStmt->constraints = NIL;
createStmt->hasoids = false; createStmt->hasoids = MUST_NOT_HAVE_OIDS;
createStmt->oncommit = ONCOMMIT_NOOP; createStmt->oncommit = ONCOMMIT_NOOP;
/* /*
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
* *
* *
* IDENTIFICATION * 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 $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -593,14 +593,7 @@ InitPlan(QueryDesc *queryDesc, bool explainOnly) ...@@ -593,14 +593,7 @@ InitPlan(QueryDesc *queryDesc, bool explainOnly)
if (operation == CMD_SELECT && parseTree->into != NULL) if (operation == CMD_SELECT && parseTree->into != NULL)
{ {
do_select_into = true; do_select_into = true;
estate->es_force_oids = parseTree->intoHasOids;
/*
* 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;
} }
/* /*
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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 $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -1549,6 +1549,7 @@ _copyQuery(Query *from) ...@@ -1549,6 +1549,7 @@ _copyQuery(Query *from)
COPY_NODE_FIELD(utilityStmt); COPY_NODE_FIELD(utilityStmt);
COPY_SCALAR_FIELD(resultRelation); COPY_SCALAR_FIELD(resultRelation);
COPY_NODE_FIELD(into); COPY_NODE_FIELD(into);
COPY_SCALAR_FIELD(intoHasOids);
COPY_SCALAR_FIELD(hasAggs); COPY_SCALAR_FIELD(hasAggs);
COPY_SCALAR_FIELD(hasSubLinks); COPY_SCALAR_FIELD(hasSubLinks);
COPY_NODE_FIELD(rtable); COPY_NODE_FIELD(rtable);
...@@ -1623,6 +1624,7 @@ _copySelectStmt(SelectStmt *from) ...@@ -1623,6 +1624,7 @@ _copySelectStmt(SelectStmt *from)
COPY_NODE_FIELD(distinctClause); COPY_NODE_FIELD(distinctClause);
COPY_NODE_FIELD(into); COPY_NODE_FIELD(into);
COPY_NODE_FIELD(intoColNames); COPY_NODE_FIELD(intoColNames);
COPY_SCALAR_FIELD(intoHasOids);
COPY_NODE_FIELD(targetList); COPY_NODE_FIELD(targetList);
COPY_NODE_FIELD(fromClause); COPY_NODE_FIELD(fromClause);
COPY_NODE_FIELD(whereClause); COPY_NODE_FIELD(whereClause);
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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 $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -604,6 +604,7 @@ _equalQuery(Query *a, Query *b) ...@@ -604,6 +604,7 @@ _equalQuery(Query *a, Query *b)
COMPARE_NODE_FIELD(utilityStmt); COMPARE_NODE_FIELD(utilityStmt);
COMPARE_SCALAR_FIELD(resultRelation); COMPARE_SCALAR_FIELD(resultRelation);
COMPARE_NODE_FIELD(into); COMPARE_NODE_FIELD(into);
COMPARE_SCALAR_FIELD(intoHasOids);
COMPARE_SCALAR_FIELD(hasAggs); COMPARE_SCALAR_FIELD(hasAggs);
COMPARE_SCALAR_FIELD(hasSubLinks); COMPARE_SCALAR_FIELD(hasSubLinks);
COMPARE_NODE_FIELD(rtable); COMPARE_NODE_FIELD(rtable);
...@@ -667,6 +668,7 @@ _equalSelectStmt(SelectStmt *a, SelectStmt *b) ...@@ -667,6 +668,7 @@ _equalSelectStmt(SelectStmt *a, SelectStmt *b)
COMPARE_NODE_FIELD(distinctClause); COMPARE_NODE_FIELD(distinctClause);
COMPARE_NODE_FIELD(into); COMPARE_NODE_FIELD(into);
COMPARE_NODE_FIELD(intoColNames); COMPARE_NODE_FIELD(intoColNames);
COMPARE_SCALAR_FIELD(intoHasOids);
COMPARE_NODE_FIELD(targetList); COMPARE_NODE_FIELD(targetList);
COMPARE_NODE_FIELD(fromClause); COMPARE_NODE_FIELD(fromClause);
COMPARE_NODE_FIELD(whereClause); COMPARE_NODE_FIELD(whereClause);
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#include "utils/acl.h" #include "utils/acl.h"
#include "utils/builtins.h" #include "utils/builtins.h"
#include "utils/fmgroids.h" #include "utils/fmgroids.h"
#include "utils/guc.h"
#include "utils/lsyscache.h" #include "utils/lsyscache.h"
#include "utils/relcache.h" #include "utils/relcache.h"
#include "utils/syscache.h" #include "utils/syscache.h"
...@@ -1974,6 +1975,21 @@ transformSelectStmt(ParseState *pstate, SelectStmt *stmt) ...@@ -1974,6 +1975,21 @@ transformSelectStmt(ParseState *pstate, SelectStmt *stmt)
if (stmt->intoColNames) if (stmt->intoColNames)
applyColumnNames(qry->targetList, 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 */ /* mark column origins */
markTargetListOrigins(pstate, qry->targetList); markTargetListOrigins(pstate, qry->targetList);
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * 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 * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
...@@ -63,7 +63,6 @@ ...@@ -63,7 +63,6 @@
#include "utils/numeric.h" #include "utils/numeric.h"
#include "utils/datetime.h" #include "utils/datetime.h"
#include "utils/date.h" #include "utils/date.h"
#include "utils/guc.h"
extern List *parsetree; /* final parse result is delivered here */ extern List *parsetree; /* final parse result is delivered here */
...@@ -109,6 +108,7 @@ static void doNegateFloat(Value *v); ...@@ -109,6 +108,7 @@ static void doNegateFloat(Value *v);
JoinType jtype; JoinType jtype;
DropBehavior dbehavior; DropBehavior dbehavior;
OnCommitAction oncommit; OnCommitAction oncommit;
ContainsOids withoids;
List *list; List *list;
FastList fastlist; FastList fastlist;
Node *node; Node *node;
...@@ -235,8 +235,9 @@ static void doNegateFloat(Value *v); ...@@ -235,8 +235,9 @@ static void doNegateFloat(Value *v);
%type <fun_param> func_arg %type <fun_param> func_arg
%type <typnam> func_return func_type aggr_argtype %type <typnam> func_return func_type aggr_argtype
%type <boolean> arg_class TriggerForType OptTemp OptWithOids %type <boolean> arg_class TriggerForType OptTemp
%type <oncommit> OnCommitOption %type <oncommit> OnCommitOption
%type <withoids> OptWithOids WithOidsAs
%type <list> for_update_clause opt_for_update_clause update_list %type <list> for_update_clause opt_for_update_clause update_list
%type <boolean> opt_all %type <boolean> opt_all
...@@ -1824,14 +1825,9 @@ OptInherit: INHERITS '(' qualified_name_list ')' { $$ = $3; } ...@@ -1824,14 +1825,9 @@ OptInherit: INHERITS '(' qualified_name_list ')' { $$ = $3; }
; ;
OptWithOids: OptWithOids:
WITH OIDS { $$ = TRUE; } WITH OIDS { $$ = MUST_HAVE_OIDS; }
| WITHOUT OIDS { $$ = FALSE; } | WITHOUT OIDS { $$ = MUST_NOT_HAVE_OIDS; }
/* | /*EMPTY*/ { $$ = DEFAULT_OIDS; }
* 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; }
; ;
OnCommitOption: ON COMMIT DROP { $$ = ONCOMMIT_DROP; } OnCommitOption: ON COMMIT DROP { $$ = ONCOMMIT_DROP; }
...@@ -1847,7 +1843,7 @@ OnCommitOption: ON COMMIT DROP { $$ = ONCOMMIT_DROP; } ...@@ -1847,7 +1843,7 @@ OnCommitOption: ON COMMIT DROP { $$ = ONCOMMIT_DROP; }
*/ */
CreateAsStmt: 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 * When the SelectStmt is a set-operation tree, we must
...@@ -1864,10 +1860,23 @@ CreateAsStmt: ...@@ -1864,10 +1860,23 @@ CreateAsStmt:
$4->istemp = $2; $4->istemp = $2;
n->into = $4; n->into = $4;
n->intoColNames = $5; n->intoColNames = $5;
n->intoHasOids = $6;
$$ = $7; $$ = $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: OptCreateAs:
'(' CreateAsList ')' { $$ = $2; } '(' CreateAsList ')' { $$ = $2; }
| /*EMPTY*/ { $$ = NIL; } | /*EMPTY*/ { $$ = NIL; }
...@@ -4531,6 +4540,7 @@ simple_select: ...@@ -4531,6 +4540,7 @@ simple_select:
n->targetList = $3; n->targetList = $3;
n->into = $4; n->into = $4;
n->intoColNames = NIL; n->intoColNames = NIL;
n->intoHasOids = DEFAULT_OIDS;
n->fromClause = $5; n->fromClause = $5;
n->whereClause = $6; n->whereClause = $6;
n->groupClause = $7; n->groupClause = $7;
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -55,6 +55,7 @@ typedef struct Query ...@@ -55,6 +55,7 @@ typedef struct Query
int resultRelation; /* target relation (index into rtable) */ int resultRelation; /* target relation (index into rtable) */
RangeVar *into; /* target relation for SELECT INTO */ RangeVar *into; /* target relation for SELECT INTO */
bool intoHasOids; /* should target relation contain OIDs? */
bool hasAggs; /* has aggregates in tlist or havingQual */ bool hasAggs; /* has aggregates in tlist or havingQual */
bool hasSubLinks; /* has subquery SubLink */ bool hasSubLinks; /* has subquery SubLink */
...@@ -595,6 +596,16 @@ typedef enum SetOperation ...@@ -595,6 +596,16 @@ typedef enum SetOperation
SETOP_EXCEPT SETOP_EXCEPT
} SetOperation; } 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 typedef struct SelectStmt
{ {
NodeTag type; NodeTag type;
...@@ -602,13 +613,15 @@ typedef struct SelectStmt ...@@ -602,13 +613,15 @@ typedef struct SelectStmt
/* /*
* These fields are used only in "leaf" SelectStmts. * 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 List *distinctClause; /* NULL, list of DISTINCT ON exprs, or
* lcons(NIL,NIL) for all (SELECT * lcons(NIL,NIL) for all (SELECT
* DISTINCT) */ * DISTINCT) */
RangeVar *into; /* target table (for select into table) */ RangeVar *into; /* target table (for select into table) */
List *intoColNames; /* column names for into table */ List *intoColNames; /* column names for into table */
ContainsOids intoHasOids; /* should target table have OIDs? */
List *targetList; /* the target list (of ResTarget) */ List *targetList; /* the target list (of ResTarget) */
List *fromClause; /* the FROM clause */ List *fromClause; /* the FROM clause */
Node *whereClause; /* WHERE qualification */ Node *whereClause; /* WHERE qualification */
...@@ -895,7 +908,7 @@ typedef struct CreateStmt ...@@ -895,7 +908,7 @@ typedef struct CreateStmt
List *inhRelations; /* relations to inherit from (list of List *inhRelations; /* relations to inherit from (list of
* inhRelation) */ * inhRelation) */
List *constraints; /* constraints (list of Constraint nodes) */ 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? */ OnCommitAction oncommit; /* what do we do at COMMIT? */
} CreateStmt; } CreateStmt;
......
...@@ -36,3 +36,27 @@ SELECT min(relpages) < max(relpages), min(reltuples) - max(reltuples) ...@@ -36,3 +36,27 @@ SELECT min(relpages) < max(relpages), min(reltuples) - max(reltuples)
DROP TABLE wi; DROP TABLE wi;
DROP TABLE wo; 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;
...@@ -33,3 +33,30 @@ SELECT min(relpages) < max(relpages), min(reltuples) - max(reltuples) ...@@ -33,3 +33,30 @@ SELECT min(relpages) < max(relpages), min(reltuples) - max(reltuples)
DROP TABLE wi; DROP TABLE wi;
DROP TABLE wo; 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;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment