diff -ruN ../base/src/backend/access/common/heaptuple.c src/backend/access/common/heaptuple.c --- ../base/src/backend/access/common/heaptuple.c 2002-07-17 19:44:12.000000000 +0200 +++ src/backend/access/common/heaptuple.c 2002-07-17 22:25:38.000000000 +0200 @@ -581,6 +581,8 @@ elog(ERROR, "heap_formtuple: numberOfAttributes %d exceeds limit %d", numberOfAttributes, MaxTupleAttributeNumber); + AssertTupleDescHasOidIsValid(tupleDescriptor); + for (i = 0; i < numberOfAttributes; i++) { if (nulls[i] != ' ') diff -ruN ../base/src/backend/access/common/tupdesc.c src/backend/access/common/tupdesc.c --- ../base/src/backend/access/common/tupdesc.c 2002-07-17 19:44:12.000000000 +0200 +++ src/backend/access/common/tupdesc.c 2002-07-17 22:25:38.000000000 +0200 @@ -36,7 +36,7 @@ * ---------------------------------------------------------------- */ TupleDesc -CreateTemplateTupleDesc(int natts) +CreateTemplateTupleDesc(int natts, hasoid_t withoid) { uint32 size; TupleDesc desc; @@ -58,6 +58,7 @@ MemSet(desc->attrs, 0, size); desc->natts = natts; + desc->tdhasoid = withoid; return desc; } @@ -82,6 +83,7 @@ desc->attrs = attrs; desc->natts = natts; desc->constr = NULL; + desc->tdhasoid = UNDEFOID; return desc; } @@ -116,6 +118,7 @@ desc->attrs[i]->atthasdef = false; } desc->constr = NULL; + desc->tdhasoid = tupdesc->tdhasoid; return desc; } @@ -182,6 +185,7 @@ else desc->constr = NULL; + desc->tdhasoid = tupdesc->tdhasoid; return desc; } @@ -235,6 +239,8 @@ if (tupdesc1->natts != tupdesc2->natts) return false; + if (tupdesc1->tdhasoid != tupdesc2->tdhasoid) + return false; for (i = 0; i < tupdesc1->natts; i++) { Form_pg_attribute attr1 = tupdesc1->attrs[i]; @@ -479,7 +485,7 @@ * allocate a new tuple descriptor */ natts = length(schema); - desc = CreateTemplateTupleDesc(natts); + desc = CreateTemplateTupleDesc(natts, UNDEFOID); constr->has_not_null = false; attnum = 0; @@ -646,7 +652,7 @@ /* OK, get the column alias */ attname = strVal(lfirst(colaliases)); - tupdesc = CreateTemplateTupleDesc(1); + tupdesc = CreateTemplateTupleDesc(1, WITHOUTOID); TupleDescInitEntry(tupdesc, (AttrNumber) 1, attname, diff -ruN ../base/src/backend/access/heap/heapam.c src/backend/access/heap/heapam.c --- ../base/src/backend/access/heap/heapam.c 2002-07-17 19:44:12.000000000 +0200 +++ src/backend/access/heap/heapam.c 2002-07-17 22:25:38.000000000 +0200 @@ -1116,6 +1116,7 @@ * to support a persistent object store (objects need to contain * pointers to one another). */ + AssertTupleDescHasOid(relation->rd_att); if (!OidIsValid(HeapTupleGetOid(tup))) HeapTupleSetOid(tup, newoid()); else @@ -1167,7 +1168,10 @@ rdata[0].next = &(rdata[1]); if (relation->rd_rel->relhasoids) + { + AssertTupleDescHasOid(relation->rd_att); xlhdr.t_oid = HeapTupleGetOid(tup); + } else xlhdr.t_oid = InvalidOid; xlhdr.t_natts = tup->t_data->t_natts; @@ -1213,6 +1217,7 @@ if (!relation->rd_rel->relhasoids) return InvalidOid; + AssertTupleDescHasOid(relation->rd_att); return HeapTupleGetOid(tup); } @@ -1507,7 +1512,10 @@ /* Fill in OID and transaction status data for newtup */ if (relation->rd_rel->relhasoids) + { + AssertTupleDescHasOid(relation->rd_att); HeapTupleSetOid(newtup, HeapTupleGetOid(&oldtup)); + } newtup->t_data->t_infomask &= ~(HEAP_XACT_MASK); newtup->t_data->t_infomask |= (HEAP_XMAX_INVALID | HEAP_UPDATED); HeapTupleHeaderSetXmin(newtup->t_data, GetCurrentTransactionId()); @@ -1981,7 +1989,10 @@ rdata[1].next = &(rdata[2]); if (reln->rd_rel->relhasoids) + { + AssertTupleDescHasOid(reln->rd_att); xlhdr.hdr.t_oid = HeapTupleGetOid(newtup); + } else xlhdr.hdr.t_oid = InvalidOid; xlhdr.hdr.t_natts = newtup->t_data->t_natts; @@ -2218,7 +2229,10 @@ HeapTupleHeaderSetXmaxInvalid(htup); HeapTupleHeaderSetCmax(htup, FirstCommandId); if (reln->rd_rel->relhasoids) + { + AssertTupleDescHasOid(reln->rd_att); HeapTupleHeaderSetOid(htup, xlhdr.t_oid); + } offnum = PageAddItem(page, (Item) htup, newlen, offnum, LP_USED | OverwritePageMode); @@ -2385,7 +2399,10 @@ htup->t_natts = xlhdr.t_natts; htup->t_hoff = xlhdr.t_hoff; if (reln->rd_rel->relhasoids) + { + AssertTupleDescHasOid(reln->rd_att); HeapTupleHeaderSetOid(htup, xlhdr.t_oid); + } if (move) { TransactionId xid[2]; /* xmax, xmin */ diff -ruN ../base/src/backend/bootstrap/bootparse.y src/backend/bootstrap/bootparse.y --- ../base/src/backend/bootstrap/bootparse.y 2002-07-17 08:18:25.000000000 +0200 +++ src/backend/bootstrap/bootparse.y 2002-07-17 22:25:38.000000000 +0200 @@ -179,13 +179,13 @@ } tupdesc = CreateTupleDesc(numattr, attrtypes); + tupdesc->tdhasoid = BoolToHasOid(! ($4)); boot_reldesc = heap_create(LexIDStr($5), PG_CATALOG_NAMESPACE, tupdesc, $3, true, true); - boot_reldesc->rd_rel->relhasoids = ! ($4); elog(DEBUG3, "bootstrap relation created"); } else diff -ruN ../base/src/backend/bootstrap/bootstrap.c src/backend/bootstrap/bootstrap.c --- ../base/src/backend/bootstrap/bootstrap.c 2002-07-17 19:44:12.000000000 +0200 +++ src/backend/bootstrap/bootstrap.c 2002-07-17 22:25:38.000000000 +0200 @@ -495,6 +495,7 @@ app = Typ; while ((tup = heap_getnext(scan, ForwardScanDirection)) != NULL) { + AssertTupleDescHasOid(rel->rd_att); (*app)->am_oid = HeapTupleGetOid(tup); memcpy((char *) &(*app)->am_typ, (char *) GETSTRUCT(tup), @@ -675,13 +676,15 @@ elog(DEBUG3, "inserting row oid %u, %d columns", objectid, numattr); tupDesc = CreateTupleDesc(numattr, attrtypes); + tupDesc->tdhasoid = BoolToHasOid(RelationGetForm(boot_reldesc)->relhasoids); tuple = heap_formtuple(tupDesc, values, Blanks); - pfree(tupDesc); /* just free's tupDesc, not the attrtypes */ if (objectid != (Oid) 0) { + AssertTupleDescHasOid(tupDesc); HeapTupleSetOid(tuple, objectid); } + pfree(tupDesc); /* just free's tupDesc, not the attrtypes */ simple_heap_insert(boot_reldesc, tuple); heap_freetuple(tuple); elog(DEBUG3, "row inserted"); @@ -873,6 +876,7 @@ app = Typ; while ((tup = heap_getnext(scan, ForwardScanDirection)) != NULL) { + AssertTupleDescHasOid(rel->rd_att); (*app)->am_oid = HeapTupleGetOid(tup); memmove((char *) &(*app++)->am_typ, (char *) GETSTRUCT(tup), diff -ruN ../base/src/backend/catalog/aclchk.c src/backend/catalog/aclchk.c --- ../base/src/backend/catalog/aclchk.c 2002-07-17 19:44:12.000000000 +0200 +++ src/backend/catalog/aclchk.c 2002-07-17 22:25:39.000000000 +0200 @@ -591,6 +591,7 @@ elog(ERROR, "namespace \"%s\" not found", nspname); pg_namespace_tuple = (Form_pg_namespace) GETSTRUCT(tuple); + AssertTupleDescHasOid(relation->rd_att); if (!pg_namespace_ownercheck(HeapTupleGetOid(tuple), GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, nspname); diff -ruN ../base/src/backend/catalog/heap.c src/backend/catalog/heap.c --- ../base/src/backend/catalog/heap.c 2002-07-17 19:48:43.000000000 +0200 +++ src/backend/catalog/heap.c 2002-07-17 22:32:02.000000000 +0200 @@ -65,7 +65,7 @@ static void AddNewRelationTuple(Relation pg_class_desc, Relation new_rel_desc, Oid new_rel_oid, Oid new_type_oid, - char relkind, bool relhasoids); + char relkind); static void AddNewRelationType(const char *typeName, Oid typeNamespace, Oid new_rel_oid, @@ -527,8 +527,7 @@ Relation new_rel_desc, Oid new_rel_oid, Oid new_type_oid, - char relkind, - bool relhasoids) + char relkind) { Form_pg_class new_rel_reltup; HeapTuple tup; @@ -579,7 +578,6 @@ new_rel_reltup->relowner = GetUserId(); new_rel_reltup->reltype = new_type_oid; new_rel_reltup->relkind = relkind; - new_rel_reltup->relhasoids = relhasoids; /* ---------------- * now form a tuple to add to pg_class @@ -591,6 +589,7 @@ (void *) new_rel_reltup); /* force tuple to have the desired OID */ + AssertTupleDescHasOid(pg_class_desc->rd_att); HeapTupleSetOid(tup, new_rel_oid); /* @@ -691,6 +690,8 @@ if (get_relname_relid(relname, relnamespace)) elog(ERROR, "Relation '%s' already exists", relname); + tupdesc->tdhasoid = BoolToHasOid(relhasoids); + /* * Tell heap_create not to create a physical file; we'll do that below * after all our catalog updates are done. (This isn't really @@ -723,8 +724,7 @@ new_rel_desc, new_rel_oid, new_type_oid, - relkind, - relhasoids); + relkind); /* * since defining a relation also defines a complex type, we add a new @@ -900,6 +900,7 @@ scan = systable_beginscan(attrdef_rel, AttrDefaultIndex, true, SnapshotNow, 2, scankeys); + AssertTupleDescHasOid(attrdef_rel->rd_att); /* There should be at most one matching tuple, but we loop anyway */ while (HeapTupleIsValid(tuple = systable_getnext(scan))) { @@ -1691,6 +1692,7 @@ conscan = systable_beginscan(conrel, ConstraintRelidIndex, true, SnapshotNow, 1, key); + AssertTupleDescHasOid(conrel->rd_att); /* * Scan over the result set, removing any matching entries. */ diff -ruN ../base/src/backend/catalog/index.c src/backend/catalog/index.c --- ../base/src/backend/catalog/index.c 2002-07-17 19:44:12.000000000 +0200 +++ src/backend/catalog/index.c 2002-07-17 22:25:39.000000000 +0200 @@ -111,7 +111,7 @@ /* * Allocate and zero a tuple descriptor for a one-column tuple. */ - funcTupDesc = CreateTemplateTupleDesc(1); + funcTupDesc = CreateTemplateTupleDesc(1, UNDEFOID); funcTupDesc->attrs[0] = (Form_pg_attribute) palloc(ATTRIBUTE_TUPLE_SIZE); MemSet(funcTupDesc->attrs[0], 0, ATTRIBUTE_TUPLE_SIZE); @@ -199,7 +199,7 @@ * allocate the new tuple descriptor */ - indexTupDesc = CreateTemplateTupleDesc(numatts); + indexTupDesc = CreateTemplateTupleDesc(numatts, WITHOUTOID); /* ---------------- * for each attribute we are indexing, obtain its attribute @@ -327,6 +327,7 @@ * the new tuple must have the oid already chosen for the index. * sure would be embarrassing to do this sort of thing in polite company. */ + AssertTupleDescHasOid(pg_class->rd_att); HeapTupleSetOid(tuple, RelationGetRelid(indexRelation)); simple_heap_insert(pg_class, tuple); @@ -599,6 +600,7 @@ indexInfo->ii_KeyAttrNumbers, classObjectId); + indexTupDesc->tdhasoid = WITHOUTOID; /* * create the index relation (but don't create storage yet) */ @@ -626,7 +628,7 @@ indexRelation->rd_rel->relowner = GetUserId(); indexRelation->rd_rel->relam = accessMethodObjectId; indexRelation->rd_rel->relkind = RELKIND_INDEX; - indexRelation->rd_rel->relhasoids = false; + indexRelation->rd_rel->relhasoids = false; /* WITHOUTOID! */ /* * store index's pg_class entry diff -ruN ../base/src/backend/catalog/namespace.c src/backend/catalog/namespace.c --- ../base/src/backend/catalog/namespace.c 2002-07-17 19:52:25.000000000 +0200 +++ src/backend/catalog/namespace.c 2002-07-17 22:36:46.000000000 +0200 @@ -1572,6 +1572,7 @@ case RELKIND_RELATION: case RELKIND_SEQUENCE: case RELKIND_VIEW: + AssertTupleDescHasOid(pgclass->rd_att); object.classId = RelOid_pg_class; object.objectId = HeapTupleGetOid(tuple); object.objectSubId = 0; diff -ruN ../base/src/backend/catalog/pg_proc.c src/backend/catalog/pg_proc.c --- ../base/src/backend/catalog/pg_proc.c 2002-07-17 19:54:31.000000000 +0200 +++ src/backend/catalog/pg_proc.c 2002-07-17 22:25:39.000000000 +0200 @@ -240,6 +240,7 @@ /* start out with empty permissions */ nulls[Anum_pg_proc_proacl-1] = 'n'; + AssertTupleDescHasOid(tupDesc); tup = heap_formtuple(tupDesc, values, nulls); simple_heap_insert(rel, tup); is_update = false; @@ -255,6 +256,7 @@ CatalogCloseIndices(Num_pg_proc_indices, idescs); } + AssertTupleDescHasOid(tupDesc); retval = HeapTupleGetOid(tup); /* diff -ruN ../base/src/backend/catalog/pg_type.c src/backend/catalog/pg_type.c --- ../base/src/backend/catalog/pg_type.c 2002-07-17 19:44:12.000000000 +0200 +++ src/backend/catalog/pg_type.c 2002-07-17 22:25:39.000000000 +0200 @@ -275,6 +275,7 @@ simple_heap_update(pg_type_desc, &tup->t_self, tup); + AssertTupleDescHasOid(pg_type_desc->rd_att); typeObjectId = HeapTupleGetOid(tup); } else @@ -286,6 +287,7 @@ nulls); /* preassign tuple Oid, if one was given */ + AssertTupleDescHasOid(tupDesc); HeapTupleSetOid(tup, assignedTypeOid); typeObjectId = simple_heap_insert(pg_type_desc, tup); diff -ruN ../base/src/backend/commands/comment.c src/backend/commands/comment.c --- ../base/src/backend/commands/comment.c 2002-07-17 19:55:48.000000000 +0200 +++ src/backend/commands/comment.c 2002-07-17 22:25:39.000000000 +0200 @@ -435,6 +435,7 @@ if (!HeapTupleIsValid(dbtuple)) elog(ERROR, "database \"%s\" does not exist", database); + AssertTupleDescHasOid(pg_database->rd_att); oid = HeapTupleGetOid(dbtuple); /* Allow if the user matches the database dba or is a superuser */ @@ -481,6 +482,7 @@ elog(ERROR, "CommentSchema: Schema \"%s\" could not be found", namespace); + /* no TupleDesc here to Assert(...->tdhasoid); */ oid = HeapTupleGetOid(tp); /* Check object security */ @@ -552,6 +554,7 @@ if (HeapTupleIsValid(tuple)) { reloid = ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class; + AssertTupleDescHasOid(RewriteRelation->rd_att); ruleoid = HeapTupleGetOid(tuple); } else @@ -592,6 +595,7 @@ if (!HeapTupleIsValid(tuple)) elog(ERROR, "rule \"%s\" does not exist", rulename); Assert(reloid == ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class); + AssertTupleDescHasOid(relation->rd_att); ruleoid = HeapTupleGetOid(tuple); ReleaseSysCache(tuple); } @@ -805,6 +809,7 @@ elog(ERROR, "trigger \"%s\" for relation \"%s\" does not exist", trigname, RelationGetRelationName(relation)); + AssertTupleDescHasOid(pg_trigger->rd_att); oid = HeapTupleGetOid(triggertuple); systable_endscan(scan); diff -ruN ../base/src/backend/commands/copy.c src/backend/commands/copy.c --- ../base/src/backend/commands/copy.c 2002-07-17 19:44:12.000000000 +0200 +++ src/backend/commands/copy.c 2002-07-17 22:25:39.000000000 +0200 @@ -577,6 +577,7 @@ { Oid oid; + AssertTupleDescHasOid(tupDesc); oid = HeapTupleGetOid(tuple); fld_size = sizeof(Oid); CopySendData(&fld_size, sizeof(int16), fp); @@ -588,6 +589,7 @@ /* Text format has no per-tuple header, but send OID if wanted */ if (oids) { + AssertTupleDescHasOid(tupDesc); string = DatumGetCString(DirectFunctionCall1(oidout, ObjectIdGetDatum(HeapTupleGetOid(tuple)))); CopySendString(string, fp); diff -ruN ../base/src/backend/commands/dbcommands.c src/backend/commands/dbcommands.c --- ../base/src/backend/commands/dbcommands.c 2002-07-17 19:44:12.000000000 +0200 +++ src/backend/commands/dbcommands.c 2002-07-17 22:25:39.000000000 +0200 @@ -341,6 +341,7 @@ tuple = heap_formtuple(pg_database_dsc, new_record, new_record_nulls); + AssertTupleDescHasOid(pg_database_dsc); HeapTupleSetOid(tuple, dboid); /* override heap_insert's OID * selection */ @@ -617,6 +618,7 @@ /* oid of the database */ if (dbIdP) { + AssertTupleDescHasOid(relation->rd_att); *dbIdP = HeapTupleGetOid(tuple); } /* sysid of the owner */ diff -ruN ../base/src/backend/commands/explain.c src/backend/commands/explain.c --- ../base/src/backend/commands/explain.c 2002-06-21 02:12:15.000000000 +0200 +++ src/backend/commands/explain.c 2002-07-17 22:25:39.000000000 +0200 @@ -855,7 +855,7 @@ tstate = (TextOutputState *) palloc(sizeof(TextOutputState)); /* need a tuple descriptor representing a single TEXT column */ - tupdesc = CreateTemplateTupleDesc(1); + tupdesc = CreateTemplateTupleDesc(1, WITHOUTOID); TupleDescInitEntry(tupdesc, (AttrNumber) 1, title, TEXTOID, -1, 0, false); diff -ruN ../base/src/backend/commands/tablecmds.c src/backend/commands/tablecmds.c --- ../base/src/backend/commands/tablecmds.c 2002-07-17 19:44:12.000000000 +0200 +++ src/backend/commands/tablecmds.c 2002-07-17 22:25:39.000000000 +0200 @@ -149,6 +149,7 @@ * have to copy inherited constraints here.) */ descriptor = BuildDescForRelation(schema); + descriptor->tdhasoid = BoolToHasOid(stmt->hasoids || parentHasOids); if (old_constraints != NIL) { @@ -1682,6 +1683,7 @@ ReleaseSysCache(typeTuple); + AssertTupleDescHasNoOid(attrdesc->rd_att); simple_heap_insert(attrdesc, attributeTuple); /* Update indexes on pg_attribute */ @@ -1702,6 +1704,7 @@ newreltup = heap_copytuple(reltup); ((Form_pg_class) GETSTRUCT(newreltup))->relnatts = maxatts; + AssertTupleDescHasOid(pgclass->rd_att); simple_heap_update(pgclass, &newreltup->t_self, newreltup); /* keep catalog indices current */ @@ -3299,7 +3302,7 @@ sprintf(toast_idxname, "pg_toast_%u_index", relOid); /* this is pretty painful... need a tuple descriptor */ - tupdesc = CreateTemplateTupleDesc(3); + tupdesc = CreateTemplateTupleDesc(3, WITHOUTOID); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "chunk_id", OIDOID, diff -ruN ../base/src/backend/commands/trigger.c src/backend/commands/trigger.c --- ../base/src/backend/commands/trigger.c 2002-07-17 19:58:36.000000000 +0200 +++ src/backend/commands/trigger.c 2002-07-17 22:50:18.000000000 +0200 @@ -400,6 +400,7 @@ if (!pg_class_ownercheck(relid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, get_rel_name(relid)); + AssertTupleDescHasOid(tgrel->rd_att); object.classId = RelationGetRelid(tgrel); object.objectId = HeapTupleGetOid(tup); object.objectSubId = 0; @@ -671,6 +672,7 @@ RelationGetRelationName(relation)); build = &(triggers[found]); + AssertTupleDescHasOid(tgrel->rd_att); build->tgoid = HeapTupleGetOid(htup); build->tgname = MemoryContextStrdup(CacheMemoryContext, DatumGetCString(DirectFunctionCall1(nameout, @@ -1932,6 +1934,7 @@ elog(ERROR, "Constraint '%s' is not deferrable", cname); + AssertTupleDescHasOid(tgrel->rd_att); constr_oid = HeapTupleGetOid(htup); loid = lappendi(loid, constr_oid); found = true; diff -ruN ../base/src/backend/commands/vacuum.c src/backend/commands/vacuum.c --- ../base/src/backend/commands/vacuum.c 2002-07-17 19:44:12.000000000 +0200 +++ src/backend/commands/vacuum.c 2002-07-17 22:25:39.000000000 +0200 @@ -392,6 +392,7 @@ { /* Make a relation list entry for this guy */ oldcontext = MemoryContextSwitchTo(vac_context); + AssertTupleDescHasOid(pgclass->rd_att); vrl = lappendi(vrl, HeapTupleGetOid(tuple)); MemoryContextSwitchTo(oldcontext); } diff -ruN ../base/src/backend/executor/execJunk.c src/backend/executor/execJunk.c --- ../base/src/backend/executor/execJunk.c 2002-06-21 02:12:15.000000000 +0200 +++ src/backend/executor/execJunk.c 2002-07-17 22:25:39.000000000 +0200 @@ -170,7 +170,7 @@ * Now calculate the tuple type for the cleaned tuple (we were already * given the type for the original targetlist). */ - cleanTupType = ExecTypeFromTL(cleanTargetList); + cleanTupType = ExecTypeFromTL(cleanTargetList, tupType->tdhasoid); len = ExecTargetListLength(targetList); cleanLength = ExecTargetListLength(cleanTargetList); @@ -383,8 +383,8 @@ * information for the new "clean" tuple. * * Note: we use memory on the stack to optimize things when we are - * dealing with a small number of tuples. for large tuples we just use - * palloc. + * dealing with a small number of attributes. for large tuples we + * just use palloc. */ if (cleanLength > 64) { diff -ruN ../base/src/backend/executor/execMain.c src/backend/executor/execMain.c --- ../base/src/backend/executor/execMain.c 2002-07-17 08:18:26.000000000 +0200 +++ src/backend/executor/execMain.c 2002-07-17 22:25:39.000000000 +0200 @@ -717,6 +717,10 @@ } /* + * new "INTO" table is created WITH OIDS + */ + tupType->tdhasoid = WITHOID; + /* * have to copy tupType to get rid of constraints */ tupdesc = CreateTupleDescCopy(tupType); diff -ruN ../base/src/backend/executor/execQual.c src/backend/executor/execQual.c --- ../base/src/backend/executor/execQual.c 2002-07-09 14:00:55.000000000 +0200 +++ src/backend/executor/execQual.c 2002-07-17 22:25:40.000000000 +0200 @@ -1770,7 +1770,10 @@ * natts = 0 to deal with it. */ if (targettype == NULL) + { targettype = &NullTupleDesc; + targettype->tdhasoid = WITHOUTOID; + } /* * allocate an array of char's to hold the "null" information only if diff -ruN ../base/src/backend/executor/execTuples.c src/backend/executor/execTuples.c --- ../base/src/backend/executor/execTuples.c 2002-06-21 02:12:16.000000000 +0200 +++ src/backend/executor/execTuples.c 2002-07-17 22:25:40.000000000 +0200 @@ -540,6 +540,7 @@ ExecSetSlotDescriptor(slot, tupType, false); + NullTupleDesc.tdhasoid = WITHOUTOID; nullTuple = heap_formtuple(&NullTupleDesc, values, nulls); return ExecStoreTuple(nullTuple, slot, InvalidBuffer, true); @@ -557,7 +558,7 @@ * ---------------------------------------------------------------- */ TupleDesc -ExecTypeFromTL(List *targetList) +ExecTypeFromTL(List *targetList, hasoid_t withoid) { List *tlitem; TupleDesc typeInfo; @@ -576,7 +577,7 @@ /* * allocate a new typeInfo */ - typeInfo = CreateTemplateTupleDesc(len); + typeInfo = CreateTemplateTupleDesc(len, withoid); /* * scan list, generate type info for each entry diff -ruN ../base/src/backend/executor/execUtils.c src/backend/executor/execUtils.c --- ../base/src/backend/executor/execUtils.c 2002-06-27 13:58:04.000000000 +0200 +++ src/backend/executor/execUtils.c 2002-07-17 22:25:40.000000000 +0200 @@ -290,9 +290,23 @@ void ExecAssignResultTypeFromTL(Plan *node, CommonState *commonstate) { + ResultRelInfo *ri; + Relation rel; + hasoid_t withoid; TupleDesc tupDesc; - tupDesc = ExecTypeFromTL(node->targetlist); + ri = node->state->es_result_relation_info; + if (ri != NULL) + rel = ri->ri_RelationDesc; + else + rel = node->state->es_into_relation_descriptor; + + if (rel != NULL) + withoid = BoolToHasOid(rel->rd_rel->relhasoids); + else + withoid = WITHOUTOID; + + tupDesc = ExecTypeFromTL(node->targetlist, withoid); ExecAssignResultType(commonstate, tupDesc, true); } diff -ruN ../base/src/backend/executor/nodeFunctionscan.c src/backend/executor/nodeFunctionscan.c --- ../base/src/backend/executor/nodeFunctionscan.c 2002-06-21 02:12:16.000000000 +0200 +++ src/backend/executor/nodeFunctionscan.c 2002-07-17 22:25:40.000000000 +0200 @@ -234,7 +234,7 @@ */ char *attname = strVal(lfirst(rte->eref->colnames)); - tupdesc = CreateTemplateTupleDesc(1); + tupdesc = CreateTemplateTupleDesc(1, WITHOUTOID); TupleDescInitEntry(tupdesc, (AttrNumber) 1, attname, diff -ruN ../base/src/backend/postmaster/pgstat.c src/backend/postmaster/pgstat.c --- ../base/src/backend/postmaster/pgstat.c 2002-07-17 19:44:12.000000000 +0200 +++ src/backend/postmaster/pgstat.c 2002-07-17 22:25:40.000000000 +0200 @@ -628,6 +628,7 @@ dbidlist = (Oid *) repalloc((char *) dbidlist, sizeof(Oid) * dbidalloc); } + AssertTupleDescHasOid(dbrel->rd_att); dbidlist[dbidused++] = HeapTupleGetOid(dbtup); } heap_endscan(dbscan); diff -ruN ../base/src/backend/utils/adt/regproc.c src/backend/utils/adt/regproc.c --- ../base/src/backend/utils/adt/regproc.c 2002-07-17 19:44:12.000000000 +0200 +++ src/backend/utils/adt/regproc.c 2002-07-17 22:25:40.000000000 +0200 @@ -110,6 +110,7 @@ while (HeapTupleIsValid(tuple = systable_getnext(sysscan))) { + AssertTupleDescHasOid(hdesc->rd_att); result = (RegProcedure) HeapTupleGetOid(tuple); if (++matches > 1) break; @@ -414,6 +415,7 @@ while (HeapTupleIsValid(tuple = systable_getnext(sysscan))) { + AssertTupleDescHasOid(hdesc->rd_att); result = HeapTupleGetOid(tuple); if (++matches > 1) break; @@ -732,6 +734,7 @@ if (HeapTupleIsValid(tuple = systable_getnext(sysscan))) { + AssertTupleDescHasOid(hdesc->rd_att); result = HeapTupleGetOid(tuple); } else @@ -887,6 +890,7 @@ if (HeapTupleIsValid(tuple = systable_getnext(sysscan))) { + AssertTupleDescHasOid(hdesc->rd_att); result = HeapTupleGetOid(tuple); } else diff -ruN ../base/src/backend/utils/adt/sets.c src/backend/utils/adt/sets.c --- ../base/src/backend/utils/adt/sets.c 2002-07-17 19:44:12.000000000 +0200 +++ src/backend/utils/adt/sets.c 2002-07-17 22:25:40.000000000 +0200 @@ -120,6 +120,7 @@ simple_heap_update(procrel, &newtup->t_self, newtup); + AssertTupleDescHasOid(procrel->rd_att); setoid = HeapTupleGetOid(newtup); if (RelationGetForm(procrel)->relhasindex) diff -ruN ../base/src/backend/utils/cache/catcache.c src/backend/utils/cache/catcache.c --- ../base/src/backend/utils/cache/catcache.c 2002-07-17 19:44:12.000000000 +0200 +++ src/backend/utils/cache/catcache.c 2002-07-17 22:25:40.000000000 +0200 @@ -907,6 +907,7 @@ * copy the relcache's tuple descriptor to permanent cache storage */ tupdesc = CreateTupleDescCopyConstr(RelationGetDescr(relation)); + AssertTupleDescHasOidIsValid(tupdesc); /* * get the relation's OID and relisshared flag, too @@ -1685,7 +1686,11 @@ } ntp = heap_formtuple(tupDesc, values, nulls); - HeapTupleSetOid(ntp, tupOid); + if (tupOid != InvalidOid) + { + AssertTupleDescHasOid(tupDesc); + HeapTupleSetOid(ntp, tupOid); + } pfree(values); pfree(nulls); diff -ruN ../base/src/backend/utils/cache/inval.c src/backend/utils/cache/inval.c --- ../base/src/backend/utils/cache/inval.c 2002-07-17 19:44:12.000000000 +0200 +++ src/backend/utils/cache/inval.c 2002-07-17 22:25:40.000000000 +0200 @@ -526,6 +526,7 @@ if (tupleRelId == RelOid_pg_class) { + AssertTupleDescHasOid(relation->rd_att); relationId = HeapTupleGetOid(tuple); } else if (tupleRelId == RelOid_pg_attribute) diff -ruN ../base/src/backend/utils/cache/relcache.c src/backend/utils/cache/relcache.c --- ../base/src/backend/utils/cache/relcache.c 2002-07-17 19:44:12.000000000 +0200 +++ src/backend/utils/cache/relcache.c 2002-07-17 22:25:40.000000000 +0200 @@ -440,7 +440,7 @@ relation->rd_rel = relationForm; /* and allocate attribute tuple form storage */ - relation->rd_att = CreateTemplateTupleDesc(relationForm->relnatts); + relation->rd_att = CreateTemplateTupleDesc(relationForm->relnatts, BoolToHasOid(relationForm->relhasoids)); MemoryContextSwitchTo(oldcxt); @@ -701,6 +701,7 @@ rule = (RewriteRule *) MemoryContextAlloc(rulescxt, sizeof(RewriteRule)); + AssertTupleDescHasOid(rewrite_tupdesc); rule->ruleId = HeapTupleGetOid(rewrite_tuple); rule->event = rewrite_form->ev_type - '0'; @@ -872,6 +873,7 @@ * initialize the tuple descriptor (relation->rd_att). */ RelationBuildTupleDesc(buildinfo, relation); + RelationGetDescr(relation)->tdhasoid = BoolToHasOid(RelationGetForm(relation)->relhasoids); /* * Fetch rules and triggers that affect this relation @@ -1395,7 +1397,7 @@ * right because it will never be replaced. The input values must be * correctly defined by macros in src/include/catalog/ headers. */ - relation->rd_att = CreateTemplateTupleDesc(natts); + relation->rd_att = CreateTemplateTupleDesc(natts, BoolToHasOid(relation->rd_rel->relhasoids)); /* * initialize tuple desc info @@ -2067,7 +2069,7 @@ rel->rd_rel->relnamespace = relnamespace; rel->rd_rel->relkind = RELKIND_UNCATALOGED; - rel->rd_rel->relhasoids = true; + rel->rd_rel->relhasoids = (rel->rd_att->tdhasoid == WITHOID); rel->rd_rel->relnatts = natts; rel->rd_rel->reltype = InvalidOid; @@ -2313,6 +2315,7 @@ */ Assert(relation->rd_rel != NULL); memcpy((char *) relation->rd_rel, (char *) relp, CLASS_TUPLE_SIZE); + relation->rd_att->tdhasoid = BoolToHasOid(relp->relhasoids); ReleaseSysCache(htup); } @@ -2774,7 +2777,7 @@ rel->rd_rel = relform; /* initialize attribute tuple forms */ - rel->rd_att = CreateTemplateTupleDesc(relform->relnatts); + rel->rd_att = CreateTemplateTupleDesc(relform->relnatts, BoolToHasOid(relform->relhasoids)); /* next read all the attribute tuple form data entries */ for (i = 0; i < relform->relnatts; i++) diff -ruN ../base/src/backend/utils/init/postinit.c src/backend/utils/init/postinit.c --- ../base/src/backend/utils/init/postinit.c 2002-07-17 19:44:12.000000000 +0200 +++ src/backend/utils/init/postinit.c 2002-07-17 22:25:40.000000000 +0200 @@ -98,6 +98,7 @@ pgdbscan = heap_beginscan(pgdbrel, SnapshotNow, 1, &key); tup = heap_getnext(pgdbscan, ForwardScanDirection); + AssertTupleDescHasOid(pgdbrel->rd_att); if (!HeapTupleIsValid(tup) || HeapTupleGetOid(tup) != MyDatabaseId) { diff -ruN ../base/src/include/access/tupdesc.h src/include/access/tupdesc.h --- ../base/src/include/access/tupdesc.h 2002-07-17 08:18:29.000000000 +0200 +++ src/include/access/tupdesc.h 2002-07-17 22:25:40.000000000 +0200 @@ -41,6 +41,11 @@ bool has_not_null; } TupleConstr; +typedef char hasoid_t; +#define WITHOID 'C' +#define WITHOUTOID 'S' +#define UNDEFOID '?' +#define BoolToHasOid(b) ((b) ? WITHOID : WITHOUTOID) /* * This structure contains all information (i.e. from Classes * pg_attribute, pg_attrdef, pg_constraint) for a tuple. @@ -51,9 +56,27 @@ Form_pg_attribute *attrs; /* attrs[N] is a pointer to the description of Attribute Number N+1. */ TupleConstr *constr; + hasoid_t tdhasoid; /* Tuple has an oid attribute in its header */ } *TupleDesc; -extern TupleDesc CreateTemplateTupleDesc(int natts); +#ifdef DEBUG_TUPLE_ACCESS + +#define AssertTupleDescHasOidIsValid(td) \ + Assert(((td)->tdhasoid == WITHOID) || ((td)->tdhasoid == WITHOUTOID)) +#define AssertTupleDescHasOid(td) \ + Assert((td)->tdhasoid == WITHOID) +#define AssertTupleDescHasNoOid(td) \ + Assert((td)->tdhasoid == WITHOUTOID) + +#else + +#define AssertTupleDescHasOidIsValid(td) +#define AssertTupleDescHasOid(td) +#define AssertTupleDescHasNoOid(td) + +#endif + +extern TupleDesc CreateTemplateTupleDesc(int natts, hasoid_t withoid); extern TupleDesc CreateTupleDesc(int natts, Form_pg_attribute *attrs); diff -ruN ../base/src/include/executor/executor.h src/include/executor/executor.h --- ../base/src/include/executor/executor.h 2002-06-27 13:58:05.000000000 +0200 +++ src/include/executor/executor.h 2002-07-17 22:25:40.000000000 +0200 @@ -118,7 +118,7 @@ extern TupleTableSlot *ExecInitExtraTupleSlot(EState *estate); extern TupleTableSlot *ExecInitNullTupleSlot(EState *estate, TupleDesc tupType); -extern TupleDesc ExecTypeFromTL(List *targetList); +extern TupleDesc ExecTypeFromTL(List *targetList, hasoid_t withoid); extern void SetChangedParamList(Plan *node, List *newchg); /*