1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-03 20:02:46 +03:00

Remove WITH OIDS support, change oid catalog column visibility.

Previously tables declared WITH OIDS, including a significant fraction
of the catalog tables, stored the oid column not as a normal column,
but as part of the tuple header.

This special column was not shown by default, which was somewhat odd,
as it's often (consider e.g. pg_class.oid) one of the more important
parts of a row.  Neither pg_dump nor COPY included the contents of the
oid column by default.

The fact that the oid column was not an ordinary column necessitated a
significant amount of special case code to support oid columns. That
already was painful for the existing, but upcoming work aiming to make
table storage pluggable, would have required expanding and duplicating
that "specialness" significantly.

WITH OIDS has been deprecated since 2005 (commit ff02d0a05280e0).
Remove it.

Removing includes:
- CREATE TABLE and ALTER TABLE syntax for declaring the table to be
  WITH OIDS has been removed (WITH (oids[ = true]) will error out)
- pg_dump does not support dumping tables declared WITH OIDS and will
  issue a warning when dumping one (and ignore the oid column).
- restoring an pg_dump archive with pg_restore will warn when
  restoring a table with oid contents (and ignore the oid column)
- COPY will refuse to load binary dump that includes oids.
- pg_upgrade will error out when encountering tables declared WITH
  OIDS, they have to be altered to remove the oid column first.
- Functionality to access the oid of the last inserted row (like
  plpgsql's RESULT_OID, spi's SPI_lastoid, ...) has been removed.

The syntax for declaring a table WITHOUT OIDS (or WITH (oids = false)
for CREATE TABLE) is still supported. While that requires a bit of
support code, it seems unnecessary to break applications / dumps that
do not use oids, and are explicit about not using them.

The biggest user of WITH OID columns was postgres' catalog. This
commit changes all 'magic' oid columns to be columns that are normally
declared and stored. To reduce unnecessary query breakage all the
newly added columns are still named 'oid', even if a table's column
naming scheme would indicate 'reloid' or such.  This obviously
requires adapting a lot code, mostly replacing oid access via
HeapTupleGetOid() with access to the underlying Form_pg_*->oid column.

The bootstrap process now assigns oids for all oid columns in
genbki.pl that do not have an explicit value (starting at the largest
oid previously used), only oids assigned later by oids will be above
FirstBootstrapObjectId. As the oid column now is a normal column the
special bootstrap syntax for oids has been removed.

Oids are not automatically assigned during insertion anymore, all
backend code explicitly assigns oids with GetNewOidWithIndex(). For
the rare case that insertions into the catalog via SQL are called for
the new pg_nextoid() function can be used (which only works on catalog
tables).

The fact that oid columns on system tables are now normal columns
means that they will be included in the set of columns expanded
by * (i.e. SELECT * FROM pg_class will now include the table's oid,
previously it did not). It'd not technically be hard to hide oid
column by default, but that'd mean confusing behavior would either
have to be carried forward forever, or it'd cause breakage down the
line.

While it's not unlikely that further adjustments are needed, the
scope/invasiveness of the patch makes it worthwhile to get merge this
now. It's painful to maintain externally, too complicated to commit
after the code code freeze, and a dependency of a number of other
patches.

Catversion bump, for obvious reasons.

Author: Andres Freund, with contributions by John Naylor
Discussion: https://postgr.es/m/20180930034810.ywp2c7awz7opzcfr@alap3.anarazel.de
This commit is contained in:
Andres Freund
2018-11-20 15:36:57 -08:00
parent 0999ac4792
commit 578b229718
343 changed files with 2292 additions and 4291 deletions

View File

@ -2520,7 +2520,6 @@ ExecInitWholeRowVar(ExprEvalStep *scratch, Var *variable, ExprState *state)
{
scratch->d.wholerow.junkFilter =
ExecInitJunkFilter(subplan->plan->targetlist,
ExecGetResultType(subplan)->tdhasoid,
ExecInitExtraTupleSlot(parent->state, NULL,
&TTSOpsVirtual));
}

View File

@ -53,12 +53,11 @@
* Initialize the Junk filter.
*
* The source targetlist is passed in. The output tuple descriptor is
* built from the non-junk tlist entries, plus the passed specification
* of whether to include room for an OID or not.
* built from the non-junk tlist entries.
* An optional resultSlot can be passed as well.
*/
JunkFilter *
ExecInitJunkFilter(List *targetList, bool hasoid, TupleTableSlot *slot)
ExecInitJunkFilter(List *targetList, TupleTableSlot *slot)
{
JunkFilter *junkfilter;
TupleDesc cleanTupType;
@ -70,7 +69,7 @@ ExecInitJunkFilter(List *targetList, bool hasoid, TupleTableSlot *slot)
/*
* Compute the tuple descriptor for the cleaned tuple.
*/
cleanTupType = ExecCleanTypeFromTL(targetList, hasoid);
cleanTupType = ExecCleanTypeFromTL(targetList);
/*
* Use the given slot, or make a new slot if we weren't given one.

View File

@ -344,7 +344,6 @@ standard_ExecutorRun(QueryDesc *queryDesc,
* startup tuple receiver, if we will be emitting tuples
*/
estate->es_processed = 0;
estate->es_lastoid = InvalidOid;
sendTuples = (operation == CMD_SELECT ||
queryDesc->plannedstmt->hasReturning);
@ -1056,7 +1055,6 @@ InitPlan(QueryDesc *queryDesc, int eflags)
slot = ExecInitExtraTupleSlot(estate, NULL, &TTSOpsVirtual);
j = ExecInitJunkFilter(planstate->plan->targetlist,
tupType->tdhasoid,
slot);
estate->es_junkFilter = j;
@ -1477,68 +1475,6 @@ ExecCleanUpTriggerState(EState *estate)
}
}
/*
* ExecContextForcesOids
*
* This is pretty grotty: when doing INSERT, UPDATE, or CREATE TABLE AS,
* we need to ensure that result tuples have space for an OID iff they are
* going to be stored into a relation that has OIDs. In other contexts
* we are free to choose whether to leave space for OIDs in result tuples
* (we generally don't want to, but we do if a physical-tlist optimization
* is possible). This routine checks the plan context and returns true if the
* choice is forced, false if the choice is not forced. In the true case,
* *hasoids is set to the required value.
*
* One reason this is ugly is that all plan nodes in the plan tree will emit
* tuples with space for an OID, though we really only need the topmost node
* to do so. However, node types like Sort don't project new tuples but just
* return their inputs, and in those cases the requirement propagates down
* to the input node. Eventually we might make this code smart enough to
* recognize how far down the requirement really goes, but for now we just
* make all plan nodes do the same thing if the top level forces the choice.
*
* We assume that if we are generating tuples for INSERT or UPDATE,
* estate->es_result_relation_info is already set up to describe the target
* relation. Note that in an UPDATE that spans an inheritance tree, some of
* the target relations may have OIDs and some not. We have to make the
* decisions on a per-relation basis as we initialize each of the subplans of
* the ModifyTable node, so ModifyTable has to set es_result_relation_info
* while initializing each subplan.
*
* CREATE TABLE AS is even uglier, because we don't have the target relation's
* descriptor available when this code runs; we have to look aside at the
* flags passed to ExecutorStart().
*/
bool
ExecContextForcesOids(PlanState *planstate, bool *hasoids)
{
ResultRelInfo *ri = planstate->state->es_result_relation_info;
if (ri != NULL)
{
Relation rel = ri->ri_RelationDesc;
if (rel != NULL)
{
*hasoids = rel->rd_rel->relhasoids;
return true;
}
}
if (planstate->state->es_top_eflags & EXEC_FLAG_WITH_OIDS)
{
*hasoids = true;
return true;
}
if (planstate->state->es_top_eflags & EXEC_FLAG_WITHOUT_OIDS)
{
*hasoids = false;
return true;
}
return false;
}
/* ----------------------------------------------------------------
* ExecPostprocessPlan
*

View File

@ -786,7 +786,7 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, EState *estate,
* partition that's tupdesc-equal to the partitioned table;
* partitions of different tupdescs must generate their own.
*/
tupDesc = ExecTypeFromTL(onconflset, partrelDesc->tdhasoid);
tupDesc = ExecTypeFromTL(onconflset);
ExecSetSlotDescriptor(mtstate->mt_conflproj, tupDesc);
leaf_part_rri->ri_onConflict->oc_ProjInfo =
ExecBuildProjectionInfo(onconflset, econtext,

View File

@ -260,7 +260,7 @@ ExecMakeTableFunctionResult(SetExprState *setexpr,
rsinfo.setResult = tupstore;
if (!returnsTuple)
{
tupdesc = CreateTemplateTupleDesc(1, false);
tupdesc = CreateTemplateTupleDesc(1);
TupleDescInitEntry(tupdesc,
(AttrNumber) 1,
"column",
@ -746,7 +746,7 @@ init_sexpr(Oid foid, Oid input_collation, Expr *node,
else if (functypclass == TYPEFUNC_SCALAR)
{
/* Base data type, i.e. scalar */
tupdesc = CreateTemplateTupleDesc(1, false);
tupdesc = CreateTemplateTupleDesc(1);
TupleDescInitEntry(tupdesc,
(AttrNumber) 1,
NULL,

View File

@ -70,7 +70,7 @@
static TupleDesc ExecTypeFromTLInternal(List *targetList,
bool hasoid, bool skipjunk);
bool skipjunk);
static pg_attribute_always_inline void
slot_deform_heap_tuple(TupleTableSlot *slot, HeapTuple tuple, uint32 *offp,
int natts);
@ -1602,20 +1602,9 @@ ExecFetchSlotHeapTupleDatum(TupleTableSlot *slot)
void
ExecInitResultTypeTL(PlanState *planstate)
{
bool hasoid;
TupleDesc tupDesc;
TupleDesc tupDesc = ExecTypeFromTL(planstate->plan->targetlist);
if (ExecContextForcesOids(planstate, &hasoid))
{
/* context forces OID choice; hasoid is now set correctly */
}
else
{
/* given free choice, don't leave space for OIDs in result tuples */
hasoid = false;
}
tupDesc = ExecTypeFromTL(planstate->plan->targetlist, hasoid);
tupDesc = ExecTypeFromTL(planstate->plan->targetlist);
planstate->ps_ResultTupleDesc = tupDesc;
}
@ -1796,9 +1785,9 @@ slot_getsomeattrs_int(TupleTableSlot *slot, int attnum)
* ----------------------------------------------------------------
*/
TupleDesc
ExecTypeFromTL(List *targetList, bool hasoid)
ExecTypeFromTL(List *targetList)
{
return ExecTypeFromTLInternal(targetList, hasoid, false);
return ExecTypeFromTLInternal(targetList, false);
}
/* ----------------------------------------------------------------
@ -1808,13 +1797,13 @@ ExecTypeFromTL(List *targetList, bool hasoid)
* ----------------------------------------------------------------
*/
TupleDesc
ExecCleanTypeFromTL(List *targetList, bool hasoid)
ExecCleanTypeFromTL(List *targetList)
{
return ExecTypeFromTLInternal(targetList, hasoid, true);
return ExecTypeFromTLInternal(targetList, true);
}
static TupleDesc
ExecTypeFromTLInternal(List *targetList, bool hasoid, bool skipjunk)
ExecTypeFromTLInternal(List *targetList, bool skipjunk)
{
TupleDesc typeInfo;
ListCell *l;
@ -1825,7 +1814,7 @@ ExecTypeFromTLInternal(List *targetList, bool hasoid, bool skipjunk)
len = ExecCleanTargetListLength(targetList);
else
len = ExecTargetListLength(targetList);
typeInfo = CreateTemplateTupleDesc(len, hasoid);
typeInfo = CreateTemplateTupleDesc(len);
foreach(l, targetList)
{
@ -1861,7 +1850,7 @@ ExecTypeFromExprList(List *exprList)
ListCell *lc;
int cur_resno = 1;
typeInfo = CreateTemplateTupleDesc(list_length(exprList), false);
typeInfo = CreateTemplateTupleDesc(list_length(exprList));
foreach(lc, exprList)
{

View File

@ -144,7 +144,6 @@ CreateExecutorState(void)
estate->es_tupleTable = NIL;
estate->es_processed = 0;
estate->es_lastoid = InvalidOid;
estate->es_top_eflags = 0;
estate->es_instrument = 0;
@ -545,7 +544,6 @@ tlist_matches_tupdesc(PlanState *ps, List *tlist, Index varno, TupleDesc tupdesc
{
int numattrs = tupdesc->natts;
int attrno;
bool hasoid;
ListCell *tlist_item = list_head(tlist);
/* Check the tlist attributes */
@ -590,14 +588,6 @@ tlist_matches_tupdesc(PlanState *ps, List *tlist, Index varno, TupleDesc tupdesc
if (tlist_item)
return false; /* tlist too long */
/*
* If the plan context requires a particular hasoid setting, then that has
* to match, too.
*/
if (ExecContextForcesOids(ps, &hasoid) &&
hasoid != tupdesc->tdhasoid)
return false;
return true;
}

View File

@ -1717,7 +1717,7 @@ check_sql_fn_retval(Oid func_id, Oid rettype, List *queryTreeList,
/* Set up junk filter if needed */
if (junkFilter)
*junkFilter = ExecInitJunkFilter(tlist, false,
*junkFilter = ExecInitJunkFilter(tlist,
MakeSingleTupleTableSlot(NULL, &TTSOpsMinimalTuple));
}
else if (fn_typtype == TYPTYPE_COMPOSITE || rettype == RECORDOID)
@ -1775,7 +1775,7 @@ check_sql_fn_retval(Oid func_id, Oid rettype, List *queryTreeList,
TupleTableSlot *slot =
MakeSingleTupleTableSlot(NULL, &TTSOpsMinimalTuple);
*junkFilter = ExecInitJunkFilter(tlist, false, slot);
*junkFilter = ExecInitJunkFilter(tlist, slot);
}
return false; /* NOT returning whole tuple */
}
@ -1796,7 +1796,7 @@ check_sql_fn_retval(Oid func_id, Oid rettype, List *queryTreeList,
TupleTableSlot *slot;
slot = MakeSingleTupleTableSlot(NULL, &TTSOpsMinimalTuple);
*junkFilter = ExecInitJunkFilter(tlist, false, slot);
*junkFilter = ExecInitJunkFilter(tlist, slot);
}
return true;
}

View File

@ -1396,7 +1396,7 @@ find_hash_columns(AggState *aggstate)
Max(varNumber + 1, perhash->largestGrpColIdx);
}
hashDesc = ExecTypeFromTL(hashTlist, false);
hashDesc = ExecTypeFromTL(hashTlist);
execTuplesHashPrepare(perhash->numCols,
perhash->aggnode->grpOperators,
@ -3062,7 +3062,7 @@ build_pertrans_for_aggref(AggStatePerTrans pertrans,
*/
if (numSortCols > 0 || aggref->aggfilter)
{
pertrans->sortdesc = ExecTypeFromTL(aggref->args, false);
pertrans->sortdesc = ExecTypeFromTL(aggref->args);
pertrans->sortslot =
ExecInitExtraTupleSlot(estate, pertrans->sortdesc,
&TTSOpsMinimalTuple);

View File

@ -72,7 +72,7 @@ ExecInitCustomScan(CustomScan *cscan, EState *estate, int eflags)
{
TupleDesc scan_tupdesc;
scan_tupdesc = ExecTypeFromTL(cscan->custom_scan_tlist, false);
scan_tupdesc = ExecTypeFromTL(cscan->custom_scan_tlist);
ExecInitScanTupleSlot(estate, &css->ss, scan_tupdesc, &TTSOpsVirtual);
/* Node's targetlist will contain Vars with varno = INDEX_VAR */
tlistvarno = INDEX_VAR;

View File

@ -179,7 +179,7 @@ ExecInitForeignScan(ForeignScan *node, EState *estate, int eflags)
{
TupleDesc scan_tupdesc;
scan_tupdesc = ExecTypeFromTL(node->fdw_scan_tlist, false);
scan_tupdesc = ExecTypeFromTL(node->fdw_scan_tlist);
ExecInitScanTupleSlot(estate, &scanstate->ss, scan_tupdesc,
&TTSOpsHeapTuple);
/* Node's targetlist will contain Vars with varno = INDEX_VAR */

View File

@ -383,7 +383,7 @@ ExecInitFunctionScan(FunctionScan *node, EState *estate, int eflags)
else if (functypclass == TYPEFUNC_SCALAR)
{
/* Base data type, i.e. scalar */
tupdesc = CreateTemplateTupleDesc(1, false);
tupdesc = CreateTemplateTupleDesc(1);
TupleDescInitEntry(tupdesc,
(AttrNumber) 1,
NULL, /* don't care about the name here */
@ -454,7 +454,7 @@ ExecInitFunctionScan(FunctionScan *node, EState *estate, int eflags)
if (node->funcordinality)
natts++;
scan_tupdesc = CreateTemplateTupleDesc(natts, false);
scan_tupdesc = CreateTemplateTupleDesc(natts);
for (i = 0; i < nfuncs; i++)
{

View File

@ -526,7 +526,7 @@ ExecInitIndexOnlyScan(IndexOnlyScan *node, EState *estate, int eflags)
* types of the original datums. (It's the AM's responsibility to return
* suitable data anyway.)
*/
tupDesc = ExecTypeFromTL(node->indextlist, false);
tupDesc = ExecTypeFromTL(node->indextlist);
ExecInitScanTupleSlot(estate, &indexstate->ss, tupDesc, &TTSOpsHeapTuple);
/*

View File

@ -39,6 +39,7 @@
#include "access/htup_details.h"
#include "access/xact.h"
#include "catalog/catalog.h"
#include "commands/trigger.h"
#include "executor/execPartition.h"
#include "executor/executor.h"
@ -262,7 +263,6 @@ ExecInsert(ModifyTableState *mtstate,
HeapTuple tuple;
ResultRelInfo *resultRelInfo;
Relation resultRelationDesc;
Oid newId;
List *recheckIndexes = NIL;
TupleTableSlot *result = NULL;
TransitionCaptureState *ar_insert_trig_tcs;
@ -281,21 +281,6 @@ ExecInsert(ModifyTableState *mtstate,
resultRelInfo = estate->es_result_relation_info;
resultRelationDesc = resultRelInfo->ri_RelationDesc;
/*
* If the result relation has OIDs, force the tuple's OID to zero so that
* heap_insert will assign a fresh OID. Usually the OID already will be
* zero at this point, but there are corner cases where the plan tree can
* return a tuple extracted literally from some table with the same
* rowtype.
*
* XXX if we ever wanted to allow users to assign their own OIDs to new
* rows, this'd be the place to do it. For the moment, we make a point of
* doing this before calling triggers, so that a user-supplied trigger
* could hack the OID if desired.
*/
if (resultRelationDesc->rd_rel->relhasoids)
HeapTupleSetOid(tuple, InvalidOid);
/*
* BEFORE ROW INSERT Triggers.
*
@ -328,8 +313,6 @@ ExecInsert(ModifyTableState *mtstate,
/* trigger might have changed tuple */
tuple = ExecFetchSlotHeapTuple(slot, true, NULL);
newId = InvalidOid;
}
else if (resultRelInfo->ri_FdwRoutine)
{
@ -352,8 +335,6 @@ ExecInsert(ModifyTableState *mtstate,
* tableoid column, so initialize t_tableOid before evaluating them.
*/
tuple->t_tableOid = RelationGetRelid(resultRelationDesc);
newId = InvalidOid;
}
else
{
@ -473,10 +454,10 @@ ExecInsert(ModifyTableState *mtstate,
HeapTupleHeaderSetSpeculativeToken(tuple->t_data, specToken);
/* insert the tuple, with the speculative token */
newId = heap_insert(resultRelationDesc, tuple,
estate->es_output_cid,
HEAP_INSERT_SPECULATIVE,
NULL);
heap_insert(resultRelationDesc, tuple,
estate->es_output_cid,
HEAP_INSERT_SPECULATIVE,
NULL);
/* insert index entries for tuple */
recheckIndexes = ExecInsertIndexTuples(slot, &(tuple->t_self),
@ -519,9 +500,9 @@ ExecInsert(ModifyTableState *mtstate,
* Note: heap_insert returns the tid (location) of the new tuple
* in the t_self field.
*/
newId = heap_insert(resultRelationDesc, tuple,
estate->es_output_cid,
0, NULL);
heap_insert(resultRelationDesc, tuple,
estate->es_output_cid,
0, NULL);
/* insert index entries for tuple */
if (resultRelInfo->ri_NumIndices > 0)
@ -534,7 +515,6 @@ ExecInsert(ModifyTableState *mtstate,
if (canSetTag)
{
(estate->es_processed)++;
estate->es_lastoid = newId;
setLastTid(&(tuple->t_self));
}
@ -2401,8 +2381,7 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
* the tupdesc in the parent's state: it can be reused by partitions
* with an identical descriptor to the parent.
*/
tupDesc = ExecTypeFromTL((List *) node->onConflictSet,
relationDesc->tdhasoid);
tupDesc = ExecTypeFromTL((List *) node->onConflictSet);
mtstate->mt_conflproj =
ExecInitExtraTupleSlot(mtstate->ps.state,
mtstate->mt_partition_tuple_routing ?
@ -2516,7 +2495,6 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
subplan->targetlist);
j = ExecInitJunkFilter(subplan->targetlist,
resultRelInfo->ri_RelationDesc->rd_att->tdhasoid,
ExecInitExtraTupleSlot(estate, NULL,
&TTSOpsHeapTuple));

View File

@ -967,7 +967,7 @@ ExecInitSubPlan(SubPlan *subplan, PlanState *parent)
* (hack alert!). The righthand expressions will be evaluated in our
* own innerecontext.
*/
tupDescLeft = ExecTypeFromTL(lefttlist, false);
tupDescLeft = ExecTypeFromTL(lefttlist);
slot = ExecInitExtraTupleSlot(estate, tupDescLeft, &TTSOpsVirtual);
sstate->projLeft = ExecBuildProjectionInfo(lefttlist,
NULL,
@ -975,7 +975,7 @@ ExecInitSubPlan(SubPlan *subplan, PlanState *parent)
parent,
NULL);
sstate->descRight = tupDescRight = ExecTypeFromTL(righttlist, false);
sstate->descRight = tupDescRight = ExecTypeFromTL(righttlist);
slot = ExecInitExtraTupleSlot(estate, tupDescRight, &TTSOpsVirtual);
sstate->projRight = ExecBuildProjectionInfo(righttlist,
sstate->innerecontext,

View File

@ -43,7 +43,6 @@
* when entering/exiting a SPI nesting level.
*/
uint64 SPI_processed = 0;
Oid SPI_lastoid = InvalidOid;
SPITupleTable *SPI_tuptable = NULL;
int SPI_result = 0;
@ -128,7 +127,6 @@ SPI_connect_ext(int options)
_SPI_current = &(_SPI_stack[_SPI_connected]);
_SPI_current->processed = 0;
_SPI_current->lastoid = InvalidOid;
_SPI_current->tuptable = NULL;
_SPI_current->execSubid = InvalidSubTransactionId;
slist_init(&_SPI_current->tuptables);
@ -139,7 +137,6 @@ SPI_connect_ext(int options)
_SPI_current->atomic = (options & SPI_OPT_NONATOMIC ? false : true);
_SPI_current->internal_xact = false;
_SPI_current->outer_processed = SPI_processed;
_SPI_current->outer_lastoid = SPI_lastoid;
_SPI_current->outer_tuptable = SPI_tuptable;
_SPI_current->outer_result = SPI_result;
@ -169,7 +166,6 @@ SPI_connect_ext(int options)
* depend on state of an outer caller.
*/
SPI_processed = 0;
SPI_lastoid = InvalidOid;
SPI_tuptable = NULL;
SPI_result = 0;
@ -199,7 +195,6 @@ SPI_finish(void)
* pointing at a just-deleted tuptable
*/
SPI_processed = _SPI_current->outer_processed;
SPI_lastoid = _SPI_current->outer_lastoid;
SPI_tuptable = _SPI_current->outer_tuptable;
SPI_result = _SPI_current->outer_result;
@ -296,7 +291,6 @@ SPICleanup(void)
_SPI_connected = -1;
/* Reset API global variables, too */
SPI_processed = 0;
SPI_lastoid = InvalidOid;
SPI_tuptable = NULL;
SPI_result = 0;
}
@ -363,7 +357,6 @@ AtEOSubXact_SPI(bool isCommit, SubTransactionId mySubid)
* be already gone.
*/
SPI_processed = connection->outer_processed;
SPI_lastoid = connection->outer_lastoid;
SPI_tuptable = connection->outer_tuptable;
SPI_result = connection->outer_result;
@ -878,8 +871,6 @@ SPI_modifytuple(Relation rel, HeapTuple tuple, int natts, int *attnum,
mtuple->t_data->t_ctid = tuple->t_data->t_ctid;
mtuple->t_self = tuple->t_self;
mtuple->t_tableOid = tuple->t_tableOid;
if (rel->rd_att->tdhasoid)
HeapTupleSetOid(mtuple, HeapTupleGetOid(tuple));
}
else
{
@ -910,7 +901,7 @@ SPI_fnumber(TupleDesc tupdesc, const char *fname)
return res + 1;
}
sysatt = SystemAttributeByName(fname, true /* "oid" will be accepted */ );
sysatt = SystemAttributeByName(fname);
if (sysatt != NULL)
return sysatt->attnum;
@ -935,7 +926,7 @@ SPI_fname(TupleDesc tupdesc, int fnumber)
if (fnumber > 0)
att = TupleDescAttr(tupdesc, fnumber - 1);
else
att = SystemAttributeDefinition(fnumber, true);
att = SystemAttributeDefinition(fnumber);
return pstrdup(NameStr(att->attname));
}
@ -965,7 +956,7 @@ SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber)
if (fnumber > 0)
typoid = TupleDescAttr(tupdesc, fnumber - 1)->atttypid;
else
typoid = (SystemAttributeDefinition(fnumber, true))->atttypid;
typoid = (SystemAttributeDefinition(fnumber))->atttypid;
getTypeOutputInfo(typoid, &foutoid, &typisvarlena);
@ -1007,7 +998,7 @@ SPI_gettype(TupleDesc tupdesc, int fnumber)
if (fnumber > 0)
typoid = TupleDescAttr(tupdesc, fnumber - 1)->atttypid;
else
typoid = (SystemAttributeDefinition(fnumber, true))->atttypid;
typoid = (SystemAttributeDefinition(fnumber))->atttypid;
typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typoid));
@ -1043,7 +1034,7 @@ SPI_gettypeid(TupleDesc tupdesc, int fnumber)
if (fnumber > 0)
return TupleDescAttr(tupdesc, fnumber - 1)->atttypid;
else
return (SystemAttributeDefinition(fnumber, true))->atttypid;
return (SystemAttributeDefinition(fnumber))->atttypid;
}
char *
@ -2051,7 +2042,6 @@ _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI,
{
int my_res = 0;
uint64 my_processed = 0;
Oid my_lastoid = InvalidOid;
SPITupleTable *my_tuptable = NULL;
int res = 0;
bool pushed_active_snap = false;
@ -2183,7 +2173,6 @@ _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI,
DestReceiver *dest;
_SPI_current->processed = 0;
_SPI_current->lastoid = InvalidOid;
_SPI_current->tuptable = NULL;
if (stmt->utilityStmt)
@ -2324,7 +2313,6 @@ _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI,
if (canSetTag)
{
my_processed = _SPI_current->processed;
my_lastoid = _SPI_current->lastoid;
SPI_freetuptable(my_tuptable);
my_tuptable = _SPI_current->tuptable;
my_res = res;
@ -2372,7 +2360,6 @@ fail:
/* Save results for caller */
SPI_processed = my_processed;
SPI_lastoid = my_lastoid;
SPI_tuptable = my_tuptable;
/* tuptable now is caller's responsibility, not SPI's */
@ -2484,7 +2471,6 @@ _SPI_pquery(QueryDesc *queryDesc, bool fire_triggers, uint64 tcount)
ExecutorRun(queryDesc, ForwardScanDirection, tcount, true);
_SPI_current->processed = queryDesc->estate->es_processed;
_SPI_current->lastoid = queryDesc->estate->es_lastoid;
if ((res == SPI_OK_SELECT || queryDesc->plannedstmt->hasReturning) &&
queryDesc->dest->mydest == DestSPI)