mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-03-13 19:57:53 +08:00
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.
This commit is contained in:
parent
742403bdad
commit
790d5bc992
@ -26,7 +26,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.198 2003/01/12 18:19:37 petere Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.199 2003/01/23 05:10:37 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -450,6 +450,7 @@ InitPlan(QueryDesc *queryDesc)
|
||||
PlanState *planstate;
|
||||
List *rangeTable;
|
||||
Relation intoRelationDesc;
|
||||
bool do_select_into;
|
||||
TupleDesc tupType;
|
||||
|
||||
/*
|
||||
@ -529,6 +530,26 @@ InitPlan(QueryDesc *queryDesc)
|
||||
estate->es_result_relation_info = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Detect whether we're doing SELECT INTO. If so, set the force_oids
|
||||
* flag appropriately so that the plan tree will be initialized with
|
||||
* the correct tuple descriptors.
|
||||
*/
|
||||
do_select_into = false;
|
||||
|
||||
if (operation == CMD_SELECT &&
|
||||
!parseTree->isPortal &&
|
||||
parseTree->into != NULL)
|
||||
{
|
||||
do_select_into = true;
|
||||
/*
|
||||
* For now, always create OIDs in SELECT INTO; this is for backwards
|
||||
* compatibility with pre-7.3 behavior. Eventually we might want
|
||||
* to allow the user to choose.
|
||||
*/
|
||||
estate->es_force_oids = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Have to lock relations selected for update
|
||||
*/
|
||||
@ -687,79 +708,64 @@ InitPlan(QueryDesc *queryDesc)
|
||||
}
|
||||
|
||||
/*
|
||||
* initialize the "into" relation
|
||||
* If doing SELECT INTO, initialize the "into" relation. We must wait
|
||||
* till now so we have the "clean" result tuple type to create the
|
||||
* new table from.
|
||||
*/
|
||||
intoRelationDesc = (Relation) NULL;
|
||||
|
||||
if (operation == CMD_SELECT)
|
||||
if (do_select_into)
|
||||
{
|
||||
if (!parseTree->isPortal)
|
||||
{
|
||||
/*
|
||||
* a select into table --- need to create the "into" table
|
||||
*/
|
||||
if (parseTree->into != NULL)
|
||||
{
|
||||
char *intoName;
|
||||
Oid namespaceId;
|
||||
AclResult aclresult;
|
||||
Oid intoRelationId;
|
||||
TupleDesc tupdesc;
|
||||
char *intoName;
|
||||
Oid namespaceId;
|
||||
AclResult aclresult;
|
||||
Oid intoRelationId;
|
||||
TupleDesc tupdesc;
|
||||
|
||||
/*
|
||||
* find namespace to create in, check permissions
|
||||
*/
|
||||
intoName = parseTree->into->relname;
|
||||
namespaceId = RangeVarGetCreationNamespace(parseTree->into);
|
||||
/*
|
||||
* find namespace to create in, check permissions
|
||||
*/
|
||||
intoName = parseTree->into->relname;
|
||||
namespaceId = RangeVarGetCreationNamespace(parseTree->into);
|
||||
|
||||
aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(),
|
||||
ACL_CREATE);
|
||||
if (aclresult != ACLCHECK_OK)
|
||||
aclcheck_error(aclresult,
|
||||
get_namespace_name(namespaceId));
|
||||
aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(),
|
||||
ACL_CREATE);
|
||||
if (aclresult != ACLCHECK_OK)
|
||||
aclcheck_error(aclresult, get_namespace_name(namespaceId));
|
||||
|
||||
/*
|
||||
* have to copy tupType to get rid of constraints
|
||||
*/
|
||||
tupdesc = CreateTupleDescCopy(tupType);
|
||||
/*
|
||||
* have to copy tupType to get rid of constraints
|
||||
*/
|
||||
tupdesc = CreateTupleDescCopy(tupType);
|
||||
|
||||
/*
|
||||
* Formerly we forced the output table to have OIDs, but
|
||||
* as of 7.3 it will not have OIDs, because it's too late
|
||||
* here to change the tupdescs of the already-initialized
|
||||
* plan tree. (Perhaps we could recurse and change them
|
||||
* all, but it's not really worth the trouble IMHO...)
|
||||
*/
|
||||
intoRelationId = heap_create_with_catalog(intoName,
|
||||
namespaceId,
|
||||
tupdesc,
|
||||
RELKIND_RELATION,
|
||||
false,
|
||||
ONCOMMIT_NOOP,
|
||||
allowSystemTableMods);
|
||||
|
||||
intoRelationId =
|
||||
heap_create_with_catalog(intoName,
|
||||
namespaceId,
|
||||
tupdesc,
|
||||
RELKIND_RELATION,
|
||||
false,
|
||||
ONCOMMIT_NOOP,
|
||||
allowSystemTableMods);
|
||||
FreeTupleDesc(tupdesc);
|
||||
|
||||
FreeTupleDesc(tupdesc);
|
||||
/*
|
||||
* Advance command counter so that the newly-created
|
||||
* relation's catalog tuples will be visible to heap_open.
|
||||
*/
|
||||
CommandCounterIncrement();
|
||||
|
||||
/*
|
||||
* Advance command counter so that the newly-created
|
||||
* relation's catalog tuples will be visible to heap_open.
|
||||
*/
|
||||
CommandCounterIncrement();
|
||||
/*
|
||||
* If necessary, create a TOAST table for the into
|
||||
* relation. Note that AlterTableCreateToastTable ends
|
||||
* with CommandCounterIncrement(), so that the TOAST table
|
||||
* will be visible for insertion.
|
||||
*/
|
||||
AlterTableCreateToastTable(intoRelationId, true);
|
||||
|
||||
/*
|
||||
* If necessary, create a TOAST table for the into
|
||||
* relation. Note that AlterTableCreateToastTable ends
|
||||
* with CommandCounterIncrement(), so that the TOAST table
|
||||
* will be visible for insertion.
|
||||
*/
|
||||
AlterTableCreateToastTable(intoRelationId, true);
|
||||
|
||||
intoRelationDesc = heap_open(intoRelationId,
|
||||
AccessExclusiveLock);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* And open the constructed table for writing.
|
||||
*/
|
||||
intoRelationDesc = heap_open(intoRelationId, AccessExclusiveLock);
|
||||
}
|
||||
|
||||
estate->es_into_relation_descriptor = intoRelationDesc;
|
||||
@ -1964,6 +1970,7 @@ EvalPlanQualStart(evalPlanQual *epq, EState *estate, evalPlanQual *priorepq)
|
||||
palloc0(estate->es_topPlan->nParamExec * sizeof(ParamExecData));
|
||||
epqstate->es_rowMark = estate->es_rowMark;
|
||||
epqstate->es_instrument = estate->es_instrument;
|
||||
epqstate->es_force_oids = estate->es_force_oids;
|
||||
epqstate->es_topPlan = estate->es_topPlan;
|
||||
/*
|
||||
* Each epqstate must have its own es_evTupleNull state, but
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.95 2003/01/12 04:03:34 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.96 2003/01/23 05:10:39 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -199,6 +199,7 @@ CreateExecutorState(void)
|
||||
estate->es_rowMark = NIL;
|
||||
|
||||
estate->es_instrument = false;
|
||||
estate->es_force_oids = false;
|
||||
|
||||
estate->es_exprcontexts = NIL;
|
||||
|
||||
@ -424,7 +425,6 @@ ExecAssignResultTypeFromOuterPlan(PlanState *planstate)
|
||||
void
|
||||
ExecAssignResultTypeFromTL(PlanState *planstate)
|
||||
{
|
||||
ResultRelInfo *ri;
|
||||
bool hasoid = false;
|
||||
TupleDesc tupDesc;
|
||||
|
||||
@ -444,14 +444,24 @@ ExecAssignResultTypeFromTL(PlanState *planstate)
|
||||
* have to make the decision on a per-relation basis as we initialize
|
||||
* each of the child plans of the topmost Append plan. So, this is
|
||||
* ugly but it works, for now ...
|
||||
*
|
||||
* SELECT INTO is also pretty grotty, because we don't yet have the
|
||||
* INTO relation's descriptor at this point; we have to look aside
|
||||
* at a flag set by InitPlan().
|
||||
*/
|
||||
ri = planstate->state->es_result_relation_info;
|
||||
if (ri != NULL)
|
||||
if (planstate->state->es_force_oids)
|
||||
hasoid = true;
|
||||
else
|
||||
{
|
||||
Relation rel = ri->ri_RelationDesc;
|
||||
ResultRelInfo *ri = planstate->state->es_result_relation_info;
|
||||
|
||||
if (rel != NULL)
|
||||
hasoid = rel->rd_rel->relhasoids;
|
||||
if (ri != NULL)
|
||||
{
|
||||
Relation rel = ri->ri_RelationDesc;
|
||||
|
||||
if (rel != NULL)
|
||||
hasoid = rel->rd_rel->relhasoids;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: execnodes.h,v 1.91 2003/01/12 04:03:34 tgl Exp $
|
||||
* $Id: execnodes.h,v 1.92 2003/01/23 05:10:41 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -311,6 +311,8 @@ typedef struct EState
|
||||
List *es_rowMark; /* not good place, but there is no other */
|
||||
|
||||
bool es_instrument; /* true requests runtime instrumentation */
|
||||
bool es_force_oids; /* true forces result tuples to have (space
|
||||
* for) OIDs --- used for SELECT INTO */
|
||||
|
||||
List *es_exprcontexts; /* List of ExprContexts within EState */
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user