Skip to content

Commit 790d5bc

Browse files
committed
Change CREATE TABLE AS / SELECT INTO to create the new table with OIDs,
for backwards compatibility with pre-7.3 behavior. Per discussion on pgsql-general and pgsql-hackers.
1 parent 742403b commit 790d5bc

File tree

3 files changed

+89
-70
lines changed

3 files changed

+89
-70
lines changed

src/backend/executor/execMain.c

Lines changed: 69 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
*
2727
*
2828
* IDENTIFICATION
29-
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.198 2003/01/12 18:19:37 petere Exp $
29+
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.199 2003/01/23 05:10:37 tgl Exp $
3030
*
3131
*-------------------------------------------------------------------------
3232
*/
@@ -450,6 +450,7 @@ InitPlan(QueryDesc *queryDesc)
450450
PlanState *planstate;
451451
List *rangeTable;
452452
Relation intoRelationDesc;
453+
bool do_select_into;
453454
TupleDesc tupType;
454455

455456
/*
@@ -529,6 +530,26 @@ InitPlan(QueryDesc *queryDesc)
529530
estate->es_result_relation_info = NULL;
530531
}
531532

533+
/*
534+
* Detect whether we're doing SELECT INTO. If so, set the force_oids
535+
* flag appropriately so that the plan tree will be initialized with
536+
* the correct tuple descriptors.
537+
*/
538+
do_select_into = false;
539+
540+
if (operation == CMD_SELECT &&
541+
!parseTree->isPortal &&
542+
parseTree->into != NULL)
543+
{
544+
do_select_into = true;
545+
/*
546+
* For now, always create OIDs in SELECT INTO; this is for backwards
547+
* compatibility with pre-7.3 behavior. Eventually we might want
548+
* to allow the user to choose.
549+
*/
550+
estate->es_force_oids = true;
551+
}
552+
532553
/*
533554
* Have to lock relations selected for update
534555
*/
@@ -687,79 +708,64 @@ InitPlan(QueryDesc *queryDesc)
687708
}
688709

689710
/*
690-
* initialize the "into" relation
711+
* If doing SELECT INTO, initialize the "into" relation. We must wait
712+
* till now so we have the "clean" result tuple type to create the
713+
* new table from.
691714
*/
692715
intoRelationDesc = (Relation) NULL;
693716

694-
if (operation == CMD_SELECT)
717+
if (do_select_into)
695718
{
696-
if (!parseTree->isPortal)
697-
{
698-
/*
699-
* a select into table --- need to create the "into" table
700-
*/
701-
if (parseTree->into != NULL)
702-
{
703-
char *intoName;
704-
Oid namespaceId;
705-
AclResult aclresult;
706-
Oid intoRelationId;
707-
TupleDesc tupdesc;
719+
char *intoName;
720+
Oid namespaceId;
721+
AclResult aclresult;
722+
Oid intoRelationId;
723+
TupleDesc tupdesc;
708724

709-
/*
710-
* find namespace to create in, check permissions
711-
*/
712-
intoName = parseTree->into->relname;
713-
namespaceId = RangeVarGetCreationNamespace(parseTree->into);
725+
/*
726+
* find namespace to create in, check permissions
727+
*/
728+
intoName = parseTree->into->relname;
729+
namespaceId = RangeVarGetCreationNamespace(parseTree->into);
714730

715-
aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(),
716-
ACL_CREATE);
717-
if (aclresult != ACLCHECK_OK)
718-
aclcheck_error(aclresult,
719-
get_namespace_name(namespaceId));
731+
aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(),
732+
ACL_CREATE);
733+
if (aclresult != ACLCHECK_OK)
734+
aclcheck_error(aclresult, get_namespace_name(namespaceId));
720735

721-
/*
722-
* have to copy tupType to get rid of constraints
723-
*/
724-
tupdesc = CreateTupleDescCopy(tupType);
725-
726-
/*
727-
* Formerly we forced the output table to have OIDs, but
728-
* as of 7.3 it will not have OIDs, because it's too late
729-
* here to change the tupdescs of the already-initialized
730-
* plan tree. (Perhaps we could recurse and change them
731-
* all, but it's not really worth the trouble IMHO...)
732-
*/
736+
/*
737+
* have to copy tupType to get rid of constraints
738+
*/
739+
tupdesc = CreateTupleDescCopy(tupType);
733740

734-
intoRelationId =
735-
heap_create_with_catalog(intoName,
736-
namespaceId,
737-
tupdesc,
738-
RELKIND_RELATION,
739-
false,
740-
ONCOMMIT_NOOP,
741-
allowSystemTableMods);
741+
intoRelationId = heap_create_with_catalog(intoName,
742+
namespaceId,
743+
tupdesc,
744+
RELKIND_RELATION,
745+
false,
746+
ONCOMMIT_NOOP,
747+
allowSystemTableMods);
742748

743-
FreeTupleDesc(tupdesc);
749+
FreeTupleDesc(tupdesc);
744750

745-
/*
746-
* Advance command counter so that the newly-created
747-
* relation's catalog tuples will be visible to heap_open.
748-
*/
749-
CommandCounterIncrement();
751+
/*
752+
* Advance command counter so that the newly-created
753+
* relation's catalog tuples will be visible to heap_open.
754+
*/
755+
CommandCounterIncrement();
750756

751-
/*
752-
* If necessary, create a TOAST table for the into
753-
* relation. Note that AlterTableCreateToastTable ends
754-
* with CommandCounterIncrement(), so that the TOAST table
755-
* will be visible for insertion.
756-
*/
757-
AlterTableCreateToastTable(intoRelationId, true);
757+
/*
758+
* If necessary, create a TOAST table for the into
759+
* relation. Note that AlterTableCreateToastTable ends
760+
* with CommandCounterIncrement(), so that the TOAST table
761+
* will be visible for insertion.
762+
*/
763+
AlterTableCreateToastTable(intoRelationId, true);
758764

759-
intoRelationDesc = heap_open(intoRelationId,
760-
AccessExclusiveLock);
761-
}
762-
}
765+
/*
766+
* And open the constructed table for writing.
767+
*/
768+
intoRelationDesc = heap_open(intoRelationId, AccessExclusiveLock);
763769
}
764770

765771
estate->es_into_relation_descriptor = intoRelationDesc;
@@ -1964,6 +1970,7 @@ EvalPlanQualStart(evalPlanQual *epq, EState *estate, evalPlanQual *priorepq)
19641970
palloc0(estate->es_topPlan->nParamExec * sizeof(ParamExecData));
19651971
epqstate->es_rowMark = estate->es_rowMark;
19661972
epqstate->es_instrument = estate->es_instrument;
1973+
epqstate->es_force_oids = estate->es_force_oids;
19671974
epqstate->es_topPlan = estate->es_topPlan;
19681975
/*
19691976
* Each epqstate must have its own es_evTupleNull state, but

src/backend/executor/execUtils.c

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.95 2003/01/12 04:03:34 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.96 2003/01/23 05:10:39 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -199,6 +199,7 @@ CreateExecutorState(void)
199199
estate->es_rowMark = NIL;
200200

201201
estate->es_instrument = false;
202+
estate->es_force_oids = false;
202203

203204
estate->es_exprcontexts = NIL;
204205

@@ -424,7 +425,6 @@ ExecAssignResultTypeFromOuterPlan(PlanState *planstate)
424425
void
425426
ExecAssignResultTypeFromTL(PlanState *planstate)
426427
{
427-
ResultRelInfo *ri;
428428
bool hasoid = false;
429429
TupleDesc tupDesc;
430430

@@ -444,14 +444,24 @@ ExecAssignResultTypeFromTL(PlanState *planstate)
444444
* have to make the decision on a per-relation basis as we initialize
445445
* each of the child plans of the topmost Append plan. So, this is
446446
* ugly but it works, for now ...
447+
*
448+
* SELECT INTO is also pretty grotty, because we don't yet have the
449+
* INTO relation's descriptor at this point; we have to look aside
450+
* at a flag set by InitPlan().
447451
*/
448-
ri = planstate->state->es_result_relation_info;
449-
if (ri != NULL)
452+
if (planstate->state->es_force_oids)
453+
hasoid = true;
454+
else
450455
{
451-
Relation rel = ri->ri_RelationDesc;
456+
ResultRelInfo *ri = planstate->state->es_result_relation_info;
452457

453-
if (rel != NULL)
454-
hasoid = rel->rd_rel->relhasoids;
458+
if (ri != NULL)
459+
{
460+
Relation rel = ri->ri_RelationDesc;
461+
462+
if (rel != NULL)
463+
hasoid = rel->rd_rel->relhasoids;
464+
}
455465
}
456466

457467
/*

src/include/nodes/execnodes.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $Id: execnodes.h,v 1.91 2003/01/12 04:03:34 tgl Exp $
10+
* $Id: execnodes.h,v 1.92 2003/01/23 05:10:41 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -311,6 +311,8 @@ typedef struct EState
311311
List *es_rowMark; /* not good place, but there is no other */
312312

313313
bool es_instrument; /* true requests runtime instrumentation */
314+
bool es_force_oids; /* true forces result tuples to have (space
315+
* for) OIDs --- used for SELECT INTO */
314316

315317
List *es_exprcontexts; /* List of ExprContexts within EState */
316318

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy