diff --git a/contrib/fulltextindex/fti.c b/contrib/fulltextindex/fti.c index 0c4cceb3f59cc4bc97113c2270d8fafbf764fac7..6c3e2fb888eecfcfd359aec2f0ea9045e272b1f9 100644 --- a/contrib/fulltextindex/fti.c +++ b/contrib/fulltextindex/fti.c @@ -190,7 +190,7 @@ fti(PG_FUNCTION_ARGS) tupdesc = rel->rd_att; /* what the tuple looks like (?) */ /* get oid of current tuple, needed by all, so place here */ - oid = rel->rd_rel->relhasoids ? HeapTupleGetOid(rettuple) : InvalidOid; + oid = HeapTupleGetOid(rettuple); if (!OidIsValid(oid)) elog(ERROR, "Full Text Indexing: Oid of current tuple is invalid"); diff --git a/contrib/rserv/rserv.c b/contrib/rserv/rserv.c index 8672eb79cb6a2602151b8d8b891928270d9ad5f4..dc5f1268c9792cf4ba7c487e940ea5f75f098e91 100644 --- a/contrib/rserv/rserv.c +++ b/contrib/rserv/rserv.c @@ -102,10 +102,7 @@ _rserv_log_() if (keynum == ObjectIdAttributeNumber) { - snprintf(oidbuf, "%u", 64, - rel->rd_rel->relhasoids - ? HeapTupleGetOid(tuple) - : InvalidOid); + snprintf(oidbuf, "%u", sizeof(oidbuf), HeapTupleGetOid(tuple)); key = oidbuf; } else diff --git a/contrib/tablefunc/tablefunc.c b/contrib/tablefunc/tablefunc.c index 37a6e723a65862228717d1b62e3acfde5664d665..e372c4f3d677ad8defbbbb48598d85d10038634e 100644 --- a/contrib/tablefunc/tablefunc.c +++ b/contrib/tablefunc/tablefunc.c @@ -614,7 +614,7 @@ make_crosstab_tupledesc(TupleDesc spi_tupdesc, int num_catagories) * spi result input column. */ natts = num_catagories + 1; - tupdesc = CreateTemplateTupleDesc(natts, WITHOUTOID); + tupdesc = CreateTemplateTupleDesc(natts, false); /* first the rowname column */ attnum = 1; diff --git a/doc/src/sgml/page.sgml b/doc/src/sgml/page.sgml index 7551085dc94461e530d04aea88b11dbf4bfa8d7b..d7096a4bbe13c2b14582325c36de2efaddf49e5e 100644 --- a/doc/src/sgml/page.sgml +++ b/doc/src/sgml/page.sgml @@ -4,13 +4,17 @@ <abstract> <para> -A description of the database file default page format. +A description of the database file page format. </para> </abstract> <para> -This section provides an overview of the page format used by <productname>PostgreSQL</productname> -tables. User-defined access methods need not use this page format. +This section provides an overview of the page format used by +<productname>PostgreSQL</productname> tables and indexes. (Index +access methods need not use this page format. At present, all index +methods do use this basic format, but the data kept on index metapages +usually doesn't follow the item layout rules exactly.) TOAST tables +and sequences are formatted just like a regular table. </para> <para> @@ -18,15 +22,13 @@ In the following explanation, a <firstterm>byte</firstterm> is assumed to contain 8 bits. In addition, the term <firstterm>item</firstterm> -refers to data that is stored in <productname>PostgreSQL</productname> tables. +refers to an individual data value that is stored on a page. In a table, +an item is a tuple (row); in an index, an item is an index entry. </para> <para> -<xref linkend="page-table"> shows how pages in both normal - <productname>PostgreSQL</productname> tables and - <productname>PostgreSQL</productname> indexes (e.g., a B-tree index) -are structured. This structure is also used for toast tables and sequences. +<xref linkend="page-table"> shows the basic layout of a page. There are five parts to each page. </para> @@ -48,12 +50,13 @@ Item <row> <entry>PageHeaderData</entry> - <entry>20 bytes long. Contains general information about the page to allow to access it.</entry> + <entry>20 bytes long. Contains general information about the page, including +free space pointers.</entry> </row> <row> -<entry>itemPointerData</entry> -<entry>List of (offset,length) pairs pointing to the actual item.</entry> +<entry>ItemPointerData</entry> +<entry>Array of (offset,length) pairs pointing to the actual items.</entry> </row> <row> @@ -62,13 +65,14 @@ Item </row> <row> -<entry>items</entry> -<entry>The actual items themselves. Different access method have different data here.</entry> +<entry>Items</entry> +<entry>The actual items themselves.</entry> </row> <row> <entry>Special Space</entry> -<entry>Access method specific data. Different method store different data. Unused by normal tables.</entry> +<entry>Index access method specific data. Different methods store different +data. Empty in ordinary tables.</entry> </row> </tbody> @@ -78,11 +82,12 @@ Item <para> The first 20 bytes of each page consists of a page header - (PageHeaderData). It's format is detailed in <xref + (PageHeaderData). Its format is detailed in <xref linkend="pageheaderdata-table">. The first two fields deal with WAL related stuff. This is followed by three 2-byte integer fields - (<firstterm>lower</firstterm>, <firstterm>upper</firstterm>, and - <firstterm>special</firstterm>). These represent byte offsets to the start + (<structfield>pd_lower</structfield>, <structfield>pd_upper</structfield>, + and <structfield>pd_special</structfield>). These represent byte offsets to + the start of unallocated space, to the end of unallocated space, and to the start of the special space. @@ -104,7 +109,7 @@ Item <row> <entry>pd_lsn</entry> <entry>XLogRecPtr</entry> - <entry>6 bytes</entry> + <entry>8 bytes</entry> <entry>LSN: next byte after last byte of xlog</entry> </row> <row> @@ -132,38 +137,51 @@ Item <entry>Offset to start of special space.</entry> </row> <row> - <entry>pd_opaque</entry> - <entry>OpaqueData</entry> + <entry>pd_pagesize_version</entry> + <entry>uint16</entry> <entry>2 bytes</entry> - <entry>AM-generic information. Currently just stores the page size.</entry> + <entry>Page size and layout version number information.</entry> </row> </tbody> </tgroup> </table> + <para> + All the details may be found in src/include/storage/bufpage.h. + </para> + <para> Special space is a region at the end of the page that is allocated at page initialization time and contains information specific to an access method. - The last 2 bytes of the page header, <firstterm>opaque</firstterm>, - currently only stores the page size. Page size is stored in each page - because frames in the buffer pool may be subdivided into equal sized pages - on a frame by frame basis within a table (is this true? - mvo). - + The last 2 bytes of the page header, + <structfield>pd_pagesize_version</structfield>, store both the page size + and a version indicator. Beginning with + <productname>PostgreSQL</productname> 7.3 the version number is 1; prior + releases used version number 0. (The basic page layout and header format + has not changed, but the layout of heap tuple headers has.) The page size + is basically only present as a cross-check; there is no support for having + more than one page size in an installation. </para> <para> Following the page header are item identifiers - (<firstterm>ItemIdData</firstterm>). New item identifiers are allocated - from the first four bytes of unallocated space. Because an item - identifier is never moved until it is freed, its index may be used to - indicate the location of an item on a page. In fact, every pointer to an - item (<firstterm>ItemPointer</firstterm>, also know as - <firstterm>CTID</firstterm>) created by - <productname>PostgreSQL</productname> consists of a frame number and an - index of an item identifier. An item identifier contains a byte-offset to + (<type>ItemIdData</type>), each requiring four bytes. + An item identifier contains a byte-offset to the start of an item, its length in bytes, and a set of attribute bits which affect its interpretation. + New item identifiers are allocated + as needed from the beginning of the unallocated space. + The number of item identifiers present can be determined by looking at + <structfield>pd_lower</>, which is increased to allocate a new identifier. + Because an item + identifier is never moved until it is freed, its index may be used on a + long-term basis to reference an item, even when the item itself is moved + around on the page to compact free space. In fact, every pointer to an + item (<type>ItemPointer</type>, also known as + <type>CTID</type>) created by + <productname>PostgreSQL</productname> consists of a page number and the + index of an item identifier. </para> @@ -171,8 +189,8 @@ Item The items themselves are stored in space allocated backwards from the end of unallocated space. The exact structure varies depending on what the - table is to contain. Sequences and tables both use a structure named - <firstterm>HeapTupleHeaderData</firstterm>, describe below. + table is to contain. Tables and sequences both use a structure named + <type>HeapTupleHeaderData</type>, described below. </para> @@ -180,20 +198,33 @@ Item The final section is the "special section" which may contain anything the access method wishes to store. Ordinary tables do not use this at all - (indicated by setting the offset to the pagesize). + (indicated by setting <structfield>pd_special</> to equal the pagesize). </para> <para> - All tuples are structured the same way. A header of around 31 bytes - followed by an optional null bitmask and the data. The header is detailed - below in <xref linkend="heaptupleheaderdata-table">. The null bitmask is - only present if the <firstterm>HEAP_HASNULL</firstterm> bit is set in the - <firstterm>t_infomask</firstterm>. If it is present it takes up the space - between the end of the header and the beginning of the data, as indicated - by the <firstterm>t_hoff</firstterm> field. In this list of bits, a 1 bit - indicates not-null, a 0 bit is a null. + All table tuples are structured the same way. There is a fixed-size + header (occupying 23 bytes on most machines), followed by an optional null + bitmap, an optional object ID field, and the user data. The header is + detailed + in <xref linkend="heaptupleheaderdata-table">. The actual user data + (fields of the tuple) begins at the offset indicated by + <structfield>t_hoff</>, which must always be a multiple of the MAXALIGN + distance for the platform. + The null bitmap is + only present if the <firstterm>HEAP_HASNULL</firstterm> bit is set in + <structfield>t_infomask</structfield>. If it is present it begins just after + the fixed header and occupies enough bytes to have one bit per data column + (that is, <structfield>t_natts</> bits altogether). In this list of bits, a + 1 bit indicates not-null, a 0 bit is a null. When the bitmap is not + present, all columns are assumed not-null. + The object ID is only present if the <firstterm>HEAP_HASOID</firstterm> bit + is set in <structfield>t_infomask</structfield>. If present, it appears just + before the <structfield>t_hoff</> boundary. Any padding needed to make + <structfield>t_hoff</> a MAXALIGN multiple will appear between the null + bitmap and the object ID. (This in turn ensures that the object ID is + suitably aligned.) </para> @@ -211,34 +242,34 @@ Item </thead> <tbody> <row> - <entry>t_oid</entry> - <entry>Oid</entry> + <entry>t_xmin</entry> + <entry>TransactionId</entry> <entry>4 bytes</entry> - <entry>OID of this tuple</entry> + <entry>insert XID stamp</entry> </row> <row> <entry>t_cmin</entry> <entry>CommandId</entry> <entry>4 bytes</entry> - <entry>insert CID stamp</entry> + <entry>insert CID stamp (overlays with t_xmax)</entry> </row> <row> - <entry>t_cmax</entry> - <entry>CommandId</entry> + <entry>t_xmax</entry> + <entry>TransactionId</entry> <entry>4 bytes</entry> - <entry>delete CID stamp</entry> + <entry>delete XID stamp</entry> </row> <row> - <entry>t_xmin</entry> - <entry>TransactionId</entry> + <entry>t_cmax</entry> + <entry>CommandId</entry> <entry>4 bytes</entry> - <entry>insert XID stamp</entry> + <entry>delete CID stamp (overlays with t_xvac)</entry> </row> <row> - <entry>t_xmax</entry> + <entry>t_xvac</entry> <entry>TransactionId</entry> <entry>4 bytes</entry> - <entry>delete XID stamp</entry> + <entry>XID for VACUUM operation moving tuple</entry> </row> <row> <entry>t_ctid</entry> @@ -256,30 +287,28 @@ Item <entry>t_infomask</entry> <entry>uint16</entry> <entry>2 bytes</entry> - <entry>Various flags</entry> + <entry>various flags</entry> </row> <row> <entry>t_hoff</entry> <entry>uint8</entry> <entry>1 byte</entry> - <entry>length of tuple header. Also offset of data.</entry> + <entry>offset to user data</entry> </row> </tbody> </tgroup> </table> <para> - - All the details may be found in src/include/storage/bufpage.h. - + All the details may be found in src/include/access/htup.h. </para> <para> Interpreting the actual data can only be done with information obtained from other tables, mostly <firstterm>pg_attribute</firstterm>. The - particular fields are <firstterm>attlen</firstterm> and - <firstterm>attalign</firstterm>. There is no way to directly get a + particular fields are <structfield>attlen</structfield> and + <structfield>attalign</structfield>. There is no way to directly get a particular attribute, except when there are only fixed width fields and no NULLs. All this trickery is wrapped up in the functions <firstterm>heap_getattr</firstterm>, <firstterm>fastgetattr</firstterm> @@ -293,7 +322,7 @@ Item the next. Then make sure you have the right alignment. If the field is a fixed width field, then all the bytes are simply placed. If it's a variable length field (attlen == -1) then it's a bit more complicated, - using the variable length structure <firstterm>varattrib</firstterm>. + using the variable length structure <type>varattrib</type>. Depending on the flags, the data may be either inline, compressed or in another table (TOAST). diff --git a/src/backend/access/common/heaptuple.c b/src/backend/access/common/heaptuple.c index 5735da26d46da011210108b48003f882d7547cf7..884db0ad21f685677b6a991038b86cf6df9b06dc 100644 --- a/src/backend/access/common/heaptuple.c +++ b/src/backend/access/common/heaptuple.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/common/heaptuple.c,v 1.80 2002/08/25 17:20:00 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/common/heaptuple.c,v 1.81 2002/09/02 01:05:03 tgl Exp $ * * NOTES * The old interface functions have been converted to macros @@ -80,7 +80,7 @@ DataFill(char *data, bitmask = CSIGNBIT; } - *infomask &= HEAP_XACT_MASK; + *infomask &= ~(HEAP_HASNULL | HEAP_HASVARWIDTH | HEAP_HASEXTENDED); for (i = 0; i < numberOfAttributes; i++) { @@ -584,8 +584,6 @@ heap_formtuple(TupleDesc tupleDescriptor, elog(ERROR, "heap_formtuple: numberOfAttributes %d exceeds limit %d", numberOfAttributes, MaxTupleAttributeNumber); - AssertTupleDescHasOidIsValid(tupleDescriptor); - for (i = 0; i < numberOfAttributes; i++) { if (nulls[i] != ' ') @@ -600,7 +598,7 @@ heap_formtuple(TupleDesc tupleDescriptor, if (hasnull) len += BITMAPLEN(numberOfAttributes); - if (tupleDescriptor->tdhasoid == WITHOID) + if (tupleDescriptor->tdhasoid) len += sizeof(Oid); hoff = len = MAXALIGN(len); /* align user data safely */ @@ -626,6 +624,9 @@ heap_formtuple(TupleDesc tupleDescriptor, &td->t_infomask, (hasnull ? td->t_bits : NULL)); + if (tupleDescriptor->tdhasoid) + td->t_infomask |= HEAP_HASOID; + td->t_infomask |= HEAP_XMAX_INVALID; return tuple; @@ -651,7 +652,6 @@ heap_modifytuple(HeapTuple tuple, char *nulls; bool isNull; HeapTuple newTuple; - uint8 infomask; /* * sanity checks @@ -702,18 +702,10 @@ heap_modifytuple(HeapTuple tuple, nulls); /* - * copy the header except for t_len, t_natts, t_hoff, t_bits, - * t_infomask + * copy the identification info of the old tuple: t_ctid, t_self, + * and OID (if any) */ - infomask = newTuple->t_data->t_infomask; - /* - * copy t_xmin, t_cid, t_xmax, t_ctid, t_natts, t_infomask - */ - memmove((char *) newTuple->t_data, /* XXX */ - (char *) tuple->t_data, - offsetof(HeapTupleHeaderData, t_hoff)); /* XXX */ - newTuple->t_data->t_infomask = infomask; - newTuple->t_data->t_natts = numberOfAttributes; + newTuple->t_data->t_ctid = tuple->t_data->t_ctid; newTuple->t_self = tuple->t_self; newTuple->t_tableOid = tuple->t_tableOid; if (relation->rd_rel->relhasoids) @@ -776,11 +768,11 @@ heap_addheader(int natts, /* max domain index */ tuple->t_datamcxt = CurrentMemoryContext; tuple->t_data = td = (HeapTupleHeader) ((char *) tuple + HEAPTUPLESIZE); - MemSet((char *) td, 0, len); + MemSet((char *) td, 0, hoff); td->t_hoff = hoff; td->t_natts = natts; - td->t_infomask = HEAP_XMAX_INVALID; /* XXX sufficient? */ + td->t_infomask = withoid ? (HEAP_XMAX_INVALID | HEAP_HASOID) : HEAP_XMAX_INVALID; memcpy((char *) td + hoff, structure, structlen); diff --git a/src/backend/access/common/tupdesc.c b/src/backend/access/common/tupdesc.c index f90717aa12a39f627c9836e711fc5c58a7792afe..6d6cdf38ce838a32107a49495bd5b5e5edcc0037 100644 --- a/src/backend/access/common/tupdesc.c +++ b/src/backend/access/common/tupdesc.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/common/tupdesc.c,v 1.87 2002/08/30 19:23:18 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/common/tupdesc.c,v 1.88 2002/09/02 01:05:03 tgl Exp $ * * NOTES * some of the executor utility code such as "ExecTypeFromTL" should be @@ -37,7 +37,7 @@ * ---------------------------------------------------------------- */ TupleDesc -CreateTemplateTupleDesc(int natts, hasoid_t withoid) +CreateTemplateTupleDesc(int natts, bool hasoid) { uint32 size; TupleDesc desc; @@ -59,7 +59,7 @@ CreateTemplateTupleDesc(int natts, hasoid_t withoid) MemSet(desc->attrs, 0, size); desc->natts = natts; - desc->tdhasoid = withoid; + desc->tdhasoid = hasoid; return desc; } @@ -67,11 +67,12 @@ CreateTemplateTupleDesc(int natts, hasoid_t withoid) /* ---------------------------------------------------------------- * CreateTupleDesc * - * This function allocates a new TupleDesc from Form_pg_attribute array + * This function allocates a new TupleDesc pointing to a given + * Form_pg_attribute array * ---------------------------------------------------------------- */ TupleDesc -CreateTupleDesc(int natts, Form_pg_attribute *attrs) +CreateTupleDesc(int natts, bool hasoid, Form_pg_attribute *attrs) { TupleDesc desc; @@ -84,7 +85,7 @@ CreateTupleDesc(int natts, Form_pg_attribute *attrs) desc->attrs = attrs; desc->natts = natts; desc->constr = NULL; - desc->tdhasoid = UNDEFOID; + desc->tdhasoid = hasoid; return desc; } @@ -129,7 +130,6 @@ CreateTupleDescCopy(TupleDesc tupdesc) * * This function creates a new TupleDesc by copying from an existing * TupleDesc (with Constraints) - * * ---------------------------------------------------------------- */ TupleDesc @@ -477,6 +477,9 @@ TupleDescInitEntry(TupleDesc desc, * BuildDescForRelation * * Given a relation schema (list of ColumnDef nodes), build a TupleDesc. + * + * Note: the default assumption is no OIDs; caller may modify the returned + * TupleDesc if it wants OIDs. */ TupleDesc BuildDescForRelation(List *schema) @@ -497,7 +500,7 @@ BuildDescForRelation(List *schema) * allocate a new tuple descriptor */ natts = length(schema); - desc = CreateTemplateTupleDesc(natts, UNDEFOID); + desc = CreateTemplateTupleDesc(natts, false); constr->has_not_null = false; attnum = 0; @@ -667,7 +670,7 @@ TypeGetTupleDesc(Oid typeoid, List *colaliases) /* OK, get the column alias */ attname = strVal(lfirst(colaliases)); - tupdesc = CreateTemplateTupleDesc(1, WITHOUTOID); + tupdesc = CreateTemplateTupleDesc(1, false); TupleDescInitEntry(tupdesc, (AttrNumber) 1, attname, diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index 89e0fec0ed5eed215eda1f1d00efe2674b8a5bc7..9acd6b33858c468f5f9870fb39a167983af312f3 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.146 2002/08/29 00:17:02 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.147 2002/09/02 01:05:03 tgl Exp $ * * * INTERFACE ROUTINES @@ -1116,6 +1116,10 @@ heap_insert(Relation relation, HeapTuple tup, CommandId cid) if (relation->rd_rel->relhasoids) { +#ifdef NOT_USED + /* this is redundant with an Assert in HeapTupleSetOid */ + Assert(tup->t_data->t_infomask & HEAP_HASOID); +#endif /* * If the object id of this tuple has already been assigned, trust * the caller. There are a couple of ways this can happen. At @@ -1125,22 +1129,21 @@ heap_insert(Relation relation, HeapTuple tup, CommandId cid) * 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 CheckMaxObjectId(HeapTupleGetOid(tup)); } + else + { + /* check there is not space for an OID */ + Assert(!(tup->t_data->t_infomask & HEAP_HASOID)); + } tup->t_data->t_infomask &= ~(HEAP_XACT_MASK); + tup->t_data->t_infomask |= HEAP_XMAX_INVALID; HeapTupleHeaderSetXmin(tup->t_data, GetCurrentTransactionId()); HeapTupleHeaderSetCmin(tup->t_data, cid); - HeapTupleHeaderSetXmaxInvalid(tup->t_data); - /* - * Do *not* set Cmax! This would overwrite Cmin. - */ - /* HeapTupleHeaderSetCmax(tup->t_data, FirstCommandId); */ - tup->t_data->t_infomask |= HEAP_XMAX_INVALID; tup->t_tableOid = relation->rd_id; #ifdef TUPLE_TOASTER_ACTIVE @@ -1181,13 +1184,7 @@ heap_insert(Relation relation, HeapTuple tup, CommandId cid) rdata[0].len = SizeOfHeapInsert; 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_oid = HeapTupleGetOid(tup); xlhdr.t_natts = tup->t_data->t_natts; xlhdr.t_hoff = tup->t_data->t_hoff; xlhdr.mask = tup->t_data->t_infomask; @@ -1234,10 +1231,6 @@ heap_insert(Relation relation, HeapTuple tup, CommandId cid) */ CacheInvalidateHeapTuple(relation, tup); - if (!relation->rd_rel->relhasoids) - return InvalidOid; - - AssertTupleDescHasOid(relation->rd_att); return HeapTupleGetOid(tup); } @@ -1343,7 +1336,9 @@ l1: /* store transaction information of xact deleting the tuple */ tp.t_data->t_infomask &= ~(HEAP_XMAX_COMMITTED | - HEAP_XMAX_INVALID | HEAP_MARKED_FOR_UPDATE); + HEAP_XMAX_INVALID | + HEAP_MARKED_FOR_UPDATE | + HEAP_MOVED); HeapTupleHeaderSetXmax(tp.t_data, GetCurrentTransactionId()); HeapTupleHeaderSetCmax(tp.t_data, cid); /* Make sure there is no forward chain link in t_ctid */ @@ -1543,14 +1538,22 @@ l2: /* Fill in OID and transaction status data for newtup */ if (relation->rd_rel->relhasoids) { - AssertTupleDescHasOid(relation->rd_att); +#ifdef NOT_USED + /* this is redundant with an Assert in HeapTupleSetOid */ + Assert(newtup->t_data->t_infomask & HEAP_HASOID); +#endif HeapTupleSetOid(newtup, HeapTupleGetOid(&oldtup)); } + else + { + /* check there is not space for an OID */ + Assert(!(newtup->t_data->t_infomask & HEAP_HASOID)); + } + newtup->t_data->t_infomask &= ~(HEAP_XACT_MASK); newtup->t_data->t_infomask |= (HEAP_XMAX_INVALID | HEAP_UPDATED); HeapTupleHeaderSetXmin(newtup->t_data, GetCurrentTransactionId()); HeapTupleHeaderSetCmin(newtup->t_data, cid); - HeapTupleHeaderSetXmaxInvalid(newtup->t_data); /* * If the toaster needs to be activated, OR if the new tuple will not @@ -1586,7 +1589,8 @@ l2: oldtup.t_data->t_infomask &= ~(HEAP_XMAX_COMMITTED | HEAP_XMAX_INVALID | - HEAP_MARKED_FOR_UPDATE); + HEAP_MARKED_FOR_UPDATE | + HEAP_MOVED); oldtup.t_data->t_infomask |= HEAP_XMAX_UNLOGGED; HeapTupleHeaderSetXmax(oldtup.t_data, GetCurrentTransactionId()); HeapTupleHeaderSetCmax(oldtup.t_data, cid); @@ -1677,7 +1681,8 @@ l2: { oldtup.t_data->t_infomask &= ~(HEAP_XMAX_COMMITTED | HEAP_XMAX_INVALID | - HEAP_MARKED_FOR_UPDATE); + HEAP_MARKED_FOR_UPDATE | + HEAP_MOVED); HeapTupleHeaderSetXmax(oldtup.t_data, GetCurrentTransactionId()); HeapTupleHeaderSetCmax(oldtup.t_data, cid); } @@ -1852,7 +1857,9 @@ l3: ((PageHeader) BufferGetPage(*buffer))->pd_sui = ThisStartUpID; /* store transaction information of xact marking the tuple */ - tuple->t_data->t_infomask &= ~(HEAP_XMAX_COMMITTED | HEAP_XMAX_INVALID); + tuple->t_data->t_infomask &= ~(HEAP_XMAX_COMMITTED | + HEAP_XMAX_INVALID | + HEAP_MOVED); tuple->t_data->t_infomask |= HEAP_MARKED_FOR_UPDATE; HeapTupleHeaderSetXmax(tuple->t_data, GetCurrentTransactionId()); HeapTupleHeaderSetCmax(tuple->t_data, cid); @@ -2032,13 +2039,7 @@ log_heap_update(Relation reln, Buffer oldbuf, ItemPointerData from, rdata[1].len = 0; 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_oid = HeapTupleGetOid(newtup); xlhdr.hdr.t_natts = newtup->t_data->t_natts; xlhdr.hdr.t_hoff = newtup->t_data->t_hoff; xlhdr.hdr.mask = newtup->t_data->t_infomask; @@ -2197,12 +2198,10 @@ heap_xlog_delete(bool redo, XLogRecPtr lsn, XLogRecord *record) if (redo) { - /* - * On redo from WAL we cannot rely on a tqual-routine - * to have reset HEAP_MOVED. - */ - htup->t_infomask &= ~(HEAP_MOVED | HEAP_XMAX_COMMITTED | - HEAP_XMAX_INVALID | HEAP_MARKED_FOR_UPDATE); + htup->t_infomask &= ~(HEAP_XMAX_COMMITTED | + HEAP_XMAX_INVALID | + HEAP_MARKED_FOR_UPDATE | + HEAP_MOVED); HeapTupleHeaderSetXmax(htup, record->xl_xid); HeapTupleHeaderSetCmax(htup, FirstCommandId); /* Make sure there is no forward chain link in t_ctid */ @@ -2284,14 +2283,9 @@ heap_xlog_insert(bool redo, XLogRecPtr lsn, XLogRecord *record) htup->t_infomask = HEAP_XMAX_INVALID | xlhdr.mask; HeapTupleHeaderSetXmin(htup, record->xl_xid); HeapTupleHeaderSetCmin(htup, FirstCommandId); - HeapTupleHeaderSetXmaxInvalid(htup); - HeapTupleHeaderSetCmax(htup, FirstCommandId); htup->t_ctid = xlrec->target.tid; if (reln->rd_rel->relhasoids) - { - AssertTupleDescHasOid(reln->rd_att); HeapTupleHeaderSetOid(htup, xlhdr.t_oid); - } offnum = PageAddItem(page, (Item) htup, newlen, offnum, LP_USED | OverwritePageMode); @@ -2372,8 +2366,9 @@ heap_xlog_update(bool redo, XLogRecPtr lsn, XLogRecord *record, bool move) { if (move) { - htup->t_infomask &= - ~(HEAP_XMIN_COMMITTED | HEAP_XMIN_INVALID | HEAP_MOVED_IN); + htup->t_infomask &= ~(HEAP_XMIN_COMMITTED | + HEAP_XMIN_INVALID | + HEAP_MOVED_IN); htup->t_infomask |= HEAP_MOVED_OFF; HeapTupleHeaderSetXvac(htup, record->xl_xid); /* Make sure there is no forward chain link in t_ctid */ @@ -2381,12 +2376,10 @@ heap_xlog_update(bool redo, XLogRecPtr lsn, XLogRecord *record, bool move) } else { - /* - * On redo from WAL we cannot rely on a tqual-routine - * to have reset HEAP_MOVED. - */ - htup->t_infomask &= ~(HEAP_MOVED | HEAP_XMAX_COMMITTED | - HEAP_XMAX_INVALID | HEAP_MARKED_FOR_UPDATE); + htup->t_infomask &= ~(HEAP_XMAX_COMMITTED | + HEAP_XMAX_INVALID | + HEAP_MARKED_FOR_UPDATE | + HEAP_MOVED); HeapTupleHeaderSetXmax(htup, record->xl_xid); HeapTupleHeaderSetCmax(htup, FirstCommandId); /* Set forward chain link in t_ctid */ @@ -2466,10 +2459,8 @@ newsame:; 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 */ @@ -2479,7 +2470,8 @@ newsame:; (char *) xlrec + hsize, 2 * sizeof(TransactionId)); htup->t_infomask = xlhdr.mask; htup->t_infomask &= ~(HEAP_XMIN_COMMITTED | - HEAP_XMIN_INVALID | HEAP_MOVED_OFF); + HEAP_XMIN_INVALID | + HEAP_MOVED_OFF); htup->t_infomask |= HEAP_MOVED_IN; HeapTupleHeaderSetXmin(htup, xid[1]); HeapTupleHeaderSetXmax(htup, xid[0]); @@ -2490,8 +2482,6 @@ newsame:; htup->t_infomask = HEAP_XMAX_INVALID | xlhdr.mask; HeapTupleHeaderSetXmin(htup, record->xl_xid); HeapTupleHeaderSetCmin(htup, FirstCommandId); - HeapTupleHeaderSetXmaxInvalid(htup); - HeapTupleHeaderSetCmax(htup, FirstCommandId); } /* Make sure there is no forward chain link in t_ctid */ htup->t_ctid = xlrec->newtid; diff --git a/src/backend/access/heap/tuptoaster.c b/src/backend/access/heap/tuptoaster.c index 1c09af2b30840eed8df8c1dea10ed862b1cb859d..ab6eff82629bcb5fda485af32b336c54ff68527d 100644 --- a/src/backend/access/heap/tuptoaster.c +++ b/src/backend/access/heap/tuptoaster.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/heap/tuptoaster.c,v 1.34 2002/08/06 02:36:33 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/heap/tuptoaster.c,v 1.35 2002/09/02 01:05:03 tgl Exp $ * * * INTERFACE ROUTINES @@ -726,7 +726,7 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup) new_len = offsetof(HeapTupleHeaderData, t_bits); if (has_nulls) new_len += BITMAPLEN(numAttrs); - if (rel->rd_rel->relhasoids) + if (olddata->t_infomask & HEAP_HASOID) new_len += sizeof(Oid); new_len = MAXALIGN(new_len); Assert(new_len == olddata->t_hoff); diff --git a/src/backend/bootstrap/bootparse.y b/src/backend/bootstrap/bootparse.y index a50e9ac88d25e5ff3ad866f078d531c082777c59..113f11de712f719cbdfad6febfcb0b8fa804ecc2 100644 --- a/src/backend/bootstrap/bootparse.y +++ b/src/backend/bootstrap/bootparse.y @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/bootstrap/bootparse.y,v 1.51 2002/08/30 22:18:05 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/bootstrap/bootparse.y,v 1.52 2002/09/02 01:05:03 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -166,20 +166,20 @@ Boot_CreateStmt: } RPAREN { + TupleDesc tupdesc; + do_start(); + tupdesc = CreateTupleDesc(numattr, !($4), attrtypes); + if ($2) { - TupleDesc tupdesc; - if (boot_reldesc) { elog(DEBUG3, "create bootstrap: warning, open relation exists, closing first"); closerel(NULL); } - tupdesc = CreateTupleDesc(numattr, attrtypes); - tupdesc->tdhasoid = BoolToHasOid(! ($4)); boot_reldesc = heap_create(LexIDStr($5), PG_CATALOG_NAMESPACE, tupdesc, @@ -191,15 +191,12 @@ Boot_CreateStmt: else { Oid id; - TupleDesc tupdesc; - tupdesc = CreateTupleDesc(numattr,attrtypes); id = heap_create_with_catalog(LexIDStr($5), PG_CATALOG_NAMESPACE, tupdesc, RELKIND_RELATION, $3, - ! ($4), true); elog(DEBUG3, "relation created with oid %u", id); } diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c index ef9ee498dbce4e60135aa2ae8006c5c7041a5de3..28faa61b2943ad61d545a3523e3bc9d148773afe 100644 --- a/src/backend/bootstrap/bootstrap.c +++ b/src/backend/bootstrap/bootstrap.c @@ -8,7 +8,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.139 2002/08/30 22:18:05 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.140 2002/09/02 01:05:03 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -493,7 +493,6 @@ boot_openrel(char *relname) 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), @@ -677,16 +676,14 @@ InsertOneTuple(Oid objectid) elog(DEBUG3, "inserting row oid %u, %d columns", objectid, numattr); - tupDesc = CreateTupleDesc(numattr, attrtypes); - tupDesc->tdhasoid = BoolToHasOid(RelationGetForm(boot_reldesc)->relhasoids); + tupDesc = CreateTupleDesc(numattr, + RelationGetForm(boot_reldesc)->relhasoids, + attrtypes); tuple = heap_formtuple(tupDesc, values, Blanks); - 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"); @@ -878,7 +875,6 @@ gettype(char *type) 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 --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c index f7dc8e5d014123baf5cfcdce98c97266c9cdef83..ea3131b3fc7645acc683e2649b8dc51d21a9f688 100644 --- a/src/backend/catalog/aclchk.c +++ b/src/backend/catalog/aclchk.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.75 2002/08/22 00:01:41 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.76 2002/09/02 01:05:03 tgl Exp $ * * NOTES * See acl.h. @@ -565,7 +565,6 @@ ExecuteGrantStmt_Namespace(GrantStmt *stmt) 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 --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index faea56df47c51d3e0ad44ac2d6d42d6a652f6ecb..09afaf2df5c93e1f6cec88fea16ce1495712368e 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.223 2002/08/29 04:38:04 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.224 2002/09/02 01:05:03 tgl Exp $ * * * INTERFACE ROUTINES @@ -349,7 +349,7 @@ heap_storage_create(Relation rel) * -------------------------------- */ static void -CheckAttributeNames(TupleDesc tupdesc, bool relhasoids, char relkind) +CheckAttributeNames(TupleDesc tupdesc, char relkind) { int i; int j; @@ -366,7 +366,7 @@ CheckAttributeNames(TupleDesc tupdesc, bool relhasoids, char relkind) for (i = 0; i < natts; i++) { if (SystemAttributeByName(NameStr(tupdesc->attrs[i]->attname), - relhasoids) != NULL) + tupdesc->tdhasoid) != NULL) elog(ERROR, "name of column \"%s\" conflicts with an existing system column", NameStr(tupdesc->attrs[i]->attname)); } @@ -419,7 +419,6 @@ CheckAttributeNames(TupleDesc tupdesc, bool relhasoids, char relkind) static void AddNewAttributeTuples(Oid new_rel_oid, TupleDesc tupdesc, - bool relhasoids, char relkind) { Form_pg_attribute *dpp; @@ -483,7 +482,8 @@ AddNewAttributeTuples(Oid new_rel_oid, dpp = SysAtt; for (i = 0; i < -1 - FirstLowInvalidHeapAttributeNumber; i++) { - if (relhasoids || (*dpp)->attnum != ObjectIdAttributeNumber) + if (tupdesc->tdhasoid || + (*dpp)->attnum != ObjectIdAttributeNumber) { Form_pg_attribute attStruct; @@ -595,7 +595,6 @@ AddNewRelationTuple(Relation pg_class_desc, (void *) new_rel_reltup); /* force tuple to have the desired OID */ - AssertTupleDescHasOid(pg_class_desc->rd_att); HeapTupleSetOid(tup, new_rel_oid); /* @@ -671,7 +670,6 @@ heap_create_with_catalog(const char *relname, TupleDesc tupdesc, char relkind, bool shared_relation, - bool relhasoids, bool allow_system_table_mods) { Relation pg_class_desc; @@ -687,12 +685,10 @@ heap_create_with_catalog(const char *relname, elog(ERROR, "Number of columns is out of range (1 to %d)", MaxHeapAttributeNumber); - CheckAttributeNames(tupdesc, relhasoids, relkind); + CheckAttributeNames(tupdesc, relkind); if (get_relname_relid(relname, relnamespace)) elog(ERROR, "Relation '%s' already exists", relname); - - tupdesc->tdhasoid = BoolToHasOid(relhasoids); /* * Create the relcache entry (mostly dummy at this point) and the @@ -747,8 +743,7 @@ heap_create_with_catalog(const char *relname, * now add tuples to pg_attribute for the attributes in our new * relation. */ - AddNewAttributeTuples(new_rel_oid, new_rel_desc->rd_att, - relhasoids, relkind); + AddNewAttributeTuples(new_rel_oid, new_rel_desc->rd_att, relkind); /* * make a dependency link to force the relation to be deleted if @@ -987,7 +982,6 @@ RemoveAttrDefault(Oid relid, AttrNumber attnum, 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))) { @@ -1774,7 +1768,6 @@ RemoveRelConstraints(Relation rel, const char *constrName, conscan = systable_beginscan(conrel, ConstraintRelidIndex, true, SnapshotNow, 1, key); - AssertTupleDescHasOid(conrel->rd_att); /* * Scan over the result set, removing any matching entries. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index bf6608eb4030aaa223759d7caa4531fa996e3ddd..93939a978e5e67fe4c68057d61c8011ccaa9703a 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.192 2002/08/30 19:23:18 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.193 2002/09/02 01:05:04 tgl Exp $ * * * INTERFACE ROUTINES @@ -111,7 +111,7 @@ BuildFuncTupleDesc(Oid funcOid, /* * Allocate and zero a tuple descriptor for a one-column tuple. */ - funcTupDesc = CreateTemplateTupleDesc(1, UNDEFOID); + funcTupDesc = CreateTemplateTupleDesc(1, false); funcTupDesc->attrs[0] = (Form_pg_attribute) palloc(ATTRIBUTE_TUPLE_SIZE); MemSet(funcTupDesc->attrs[0], 0, ATTRIBUTE_TUPLE_SIZE); @@ -199,7 +199,7 @@ ConstructTupleDescriptor(Relation heapRelation, * allocate the new tuple descriptor */ - indexTupDesc = CreateTemplateTupleDesc(numatts, WITHOUTOID); + indexTupDesc = CreateTemplateTupleDesc(numatts, false); /* ---------------- * for each attribute we are indexing, obtain its attribute @@ -328,7 +328,6 @@ UpdateRelationRelation(Relation indexRelation) * 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); @@ -577,7 +576,7 @@ index_create(Oid heapRelationId, indexInfo->ii_KeyAttrNumbers, classObjectId); - indexTupDesc->tdhasoid = WITHOUTOID; + indexTupDesc->tdhasoid = false; /* * create the index relation's relcache entry and physical disk file. * (If we fail further down, it's the smgr's responsibility to remove @@ -609,7 +608,7 @@ index_create(Oid heapRelationId, indexRelation->rd_rel->relowner = GetUserId(); indexRelation->rd_rel->relam = accessMethodObjectId; indexRelation->rd_rel->relkind = RELKIND_INDEX; - indexRelation->rd_rel->relhasoids = false; /* WITHOUTOID! */ + indexRelation->rd_rel->relhasoids = false; /* * store index's pg_class entry diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c index f8a271f908201087bbb88c789857502b3481510b..1b4f2aef8e647f450568e5a4366452752b8d6482 100644 --- a/src/backend/catalog/namespace.c +++ b/src/backend/catalog/namespace.c @@ -13,7 +13,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.33 2002/08/30 22:18:05 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.34 2002/09/02 01:05:04 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1585,7 +1585,6 @@ RemoveTempRelations(Oid tempNamespaceId) 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 --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c index e8608925bf51844b3c4bafcb34d61ec071bd83b7..805ce61930b185ce3b3b0e317495b88ea74607a7 100644 --- a/src/backend/catalog/pg_proc.c +++ b/src/backend/catalog/pg_proc.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.91 2002/08/29 00:17:03 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.92 2002/09/02 01:05:04 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -230,7 +230,6 @@ ProcedureCreate(const char *procedureName, /* 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; @@ -239,7 +238,6 @@ ProcedureCreate(const char *procedureName, /* Need to update indexes for either the insert or update case */ CatalogUpdateIndexes(rel, tup); - AssertTupleDescHasOid(tupDesc); retval = HeapTupleGetOid(tup); /* diff --git a/src/backend/catalog/pg_type.c b/src/backend/catalog/pg_type.c index ec0704b78e60e89c1d4920419800a0e2a5805657..e3eb6abe32f00e5d4f6a5ef3caa89d434a358dd8 100644 --- a/src/backend/catalog/pg_type.c +++ b/src/backend/catalog/pg_type.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.80 2002/08/29 00:17:03 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.81 2002/09/02 01:05:04 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -267,7 +267,6 @@ TypeCreate(const char *typeName, simple_heap_update(pg_type_desc, &tup->t_self, tup); - AssertTupleDescHasOid(pg_type_desc->rd_att); typeObjectId = HeapTupleGetOid(tup); } else @@ -279,7 +278,6 @@ TypeCreate(const char *typeName, nulls); /* preassign tuple Oid, if one was given */ - AssertTupleDescHasOid(tupDesc); HeapTupleSetOid(tup, assignedTypeOid); typeObjectId = simple_heap_insert(pg_type_desc, tup); diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c index e8d2aa7e7e3ca3e8876eb10cc53bcb103e037cdf..ab0110a3f4fc098e7e1ea98dc2ddae840e269bb9 100644 --- a/src/backend/commands/cluster.c +++ b/src/backend/commands/cluster.c @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.87 2002/08/27 03:38:27 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.88 2002/09/02 01:05:04 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -199,7 +199,6 @@ make_new_heap(Oid OIDOldHeap, const char *NewName) tupdesc, OldHeap->rd_rel->relkind, OldHeap->rd_rel->relisshared, - OldHeap->rd_rel->relhasoids, allowSystemTableMods); /* diff --git a/src/backend/commands/comment.c b/src/backend/commands/comment.c index ea04fd687dc08f6a22e828ceae2842d0a8b6d182..a6925314858b212ed3f159b6d24cab818b70ca2e 100644 --- a/src/backend/commands/comment.c +++ b/src/backend/commands/comment.c @@ -7,7 +7,7 @@ * Copyright (c) 1996-2001, PostgreSQL Global Development Group * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.58 2002/08/29 00:17:03 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.59 2002/09/02 01:05:04 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -516,7 +516,6 @@ CommentRule(List *qualname, char *comment) if (HeapTupleIsValid(tuple)) { reloid = ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class; - AssertTupleDescHasOid(RewriteRelation->rd_att); ruleoid = HeapTupleGetOid(tuple); } else @@ -557,7 +556,6 @@ CommentRule(List *qualname, char *comment) 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); } @@ -769,7 +767,6 @@ CommentTrigger(List *qualname, char *comment) 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 --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index 56d40c5bf0f2db91dbfc2aa36afd45297e63346a..c8463ac8f86181a0d25c60154337ee2a7f4bf966 100644 --- a/src/backend/commands/copy.c +++ b/src/backend/commands/copy.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.169 2002/08/29 07:22:21 ishii Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.170 2002/09/02 01:05:04 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -597,10 +597,8 @@ CopyTo(Relation rel, List *attnumlist, bool binary, bool oids, /* Send OID if wanted --- note fld_count doesn't include it */ if (oids) { - Oid oid; - - AssertTupleDescHasOid(tupDesc); - oid = HeapTupleGetOid(tuple); + Oid oid = HeapTupleGetOid(tuple); + fld_size = sizeof(Oid); CopySendData(&fld_size, sizeof(int16), fp); CopySendData(&oid, sizeof(Oid), fp); @@ -611,7 +609,6 @@ CopyTo(Relation rel, List *attnumlist, bool binary, bool oids, /* 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 --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c index c511199a8b4d470dd4498da765b16ebd26361e90..ba94c54fcd99b2d42a927a0743640f9f96354db5 100644 --- a/src/backend/commands/dbcommands.c +++ b/src/backend/commands/dbcommands.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.100 2002/08/29 07:22:21 ishii Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.101 2002/09/02 01:05:04 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -335,7 +335,6 @@ createdb(const CreatedbStmt *stmt) tuple = heap_formtuple(pg_database_dsc, new_record, new_record_nulls); - AssertTupleDescHasOid(pg_database_dsc); HeapTupleSetOid(tuple, dboid); /* override heap_insert's OID * selection */ @@ -589,10 +588,7 @@ get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP, /* oid of the database */ if (dbIdP) - { - AssertTupleDescHasOid(relation->rd_att); *dbIdP = HeapTupleGetOid(tuple); - } /* sysid of the owner */ if (ownerIdP) *ownerIdP = dbform->datdba; diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c index efae790dd8ce257141a77a2bfb978146d9d91f7d..bf8b6fb27baf0eb9f2beea4955216e877859df0f 100644 --- a/src/backend/commands/explain.c +++ b/src/backend/commands/explain.c @@ -5,7 +5,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994-5, Regents of the University of California * - * $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.85 2002/08/29 00:17:03 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.86 2002/09/02 01:05:04 tgl Exp $ * */ @@ -69,7 +69,7 @@ ExplainQuery(ExplainStmt *stmt, CommandDest dest) List *l; /* need a tuple descriptor representing a single TEXT column */ - tupdesc = CreateTemplateTupleDesc(1, WITHOUTOID); + tupdesc = CreateTemplateTupleDesc(1, false); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "QUERY PLAN", TEXTOID, -1, 0, false); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 8529c15fdb5f3b5e8ca6a3636d73101d186a2ed0..8709111a860db42c7c7190d12df08defba474132 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.37 2002/08/30 19:23:19 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.38 2002/09/02 01:05:04 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -150,7 +150,8 @@ DefineRelation(CreateStmt *stmt, char relkind) * have to copy inherited constraints here.) */ descriptor = BuildDescForRelation(schema); - descriptor->tdhasoid = BoolToHasOid(stmt->hasoids || parentHasOids); + + descriptor->tdhasoid = (stmt->hasoids || parentHasOids); if (old_constraints != NIL) { @@ -212,7 +213,6 @@ DefineRelation(CreateStmt *stmt, char relkind) descriptor, relkind, false, - stmt->hasoids || parentHasOids, allowSystemTableMods); StoreCatalogInheritance(relationId, inheritOids); @@ -1733,7 +1733,6 @@ AlterTableAddColumn(Oid myrelid, ReleaseSysCache(typeTuple); - AssertTupleDescHasNoOid(attrdesc->rd_att); simple_heap_insert(attrdesc, attributeTuple); /* Update indexes on pg_attribute */ @@ -1747,7 +1746,7 @@ AlterTableAddColumn(Oid myrelid, 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 indexes current */ @@ -3430,7 +3429,7 @@ AlterTableCreateToastTable(Oid relOid, bool silent) snprintf(toast_idxname, NAMEDATALEN, "pg_toast_%u_index", relOid); /* this is pretty painful... need a tuple descriptor */ - tupdesc = CreateTemplateTupleDesc(3, WITHOUTOID); + tupdesc = CreateTemplateTupleDesc(3, false); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "chunk_id", OIDOID, @@ -3464,7 +3463,6 @@ AlterTableCreateToastTable(Oid relOid, bool silent) tupdesc, RELKIND_TOASTVALUE, shared_relation, - false, true); /* make the toast relation visible, else index creation will fail */ diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index 16da206adec2bd50c1d9eac971a4b5ae64e52998..4b765105148a3f8b47e2feaf519a26f5dc843296 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.129 2002/08/25 17:20:00 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.130 2002/09/02 01:05:04 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -301,7 +301,6 @@ CreateTrigger(CreateTrigStmt *stmt, bool forConstraint) tuple = heap_formtuple(tgrel->rd_att, values, nulls); /* force tuple to have the desired OID */ - AssertTupleDescHasOid(tgrel->rd_att); HeapTupleSetOid(tuple, trigoid); /* @@ -421,7 +420,6 @@ DropTrigger(Oid relid, const char *trigname, DropBehavior behavior) 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; @@ -683,7 +681,6 @@ RelationBuildTriggers(Relation relation) RelationGetRelationName(relation)); build = &(triggers[found]); - AssertTupleDescHasOid(tgrel->rd_att); build->tgoid = HeapTupleGetOid(htup); build->tgname = MemoryContextStrdup(CacheMemoryContext, DatumGetCString(DirectFunctionCall1(nameout, @@ -1923,7 +1920,6 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt) elog(ERROR, "Constraint '%s' is not deferrable", cname); - AssertTupleDescHasOid(tgrel->rd_att); constr_oid = HeapTupleGetOid(htup); loid = lappendi(loid, constr_oid); found = true; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index cda893fab75e007fdf010b8fe60e14fa49b217e2..3e8cc79596f4a730b399cc8b505b2d583a56db05 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -13,7 +13,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.235 2002/08/30 22:18:05 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.236 2002/09/02 01:05:04 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -396,7 +396,6 @@ getrels(const RangeVar *vacrel, const char *stmttype) { /* Make a relation list entry for this guy */ oldcontext = MemoryContextSwitchTo(vac_context); - AssertTupleDescHasOid(pgclass->rd_att); vrl = lappendi(vrl, HeapTupleGetOid(tuple)); MemoryContextSwitchTo(oldcontext); } @@ -1861,8 +1860,9 @@ repair_frag(VRelStats *vacrelstats, Relation onerel, /* NO ELOG(ERROR) TILL CHANGES ARE LOGGED */ START_CRIT_SECTION(); - tuple.t_data->t_infomask &= - ~(HEAP_XMIN_COMMITTED | HEAP_XMIN_INVALID | HEAP_MOVED_IN); + tuple.t_data->t_infomask &= ~(HEAP_XMIN_COMMITTED | + HEAP_XMIN_INVALID | + HEAP_MOVED_IN); tuple.t_data->t_infomask |= HEAP_MOVED_OFF; HeapTupleHeaderSetXvac(tuple.t_data, myXID); @@ -1901,12 +1901,16 @@ repair_frag(VRelStats *vacrelstats, Relation onerel, * Update the state of the copied tuple, and store it * on the destination page. */ - newtup.t_data->t_infomask &= - ~(HEAP_XMIN_COMMITTED | HEAP_XMIN_INVALID | HEAP_MOVED_OFF); + newtup.t_data->t_infomask &= ~(HEAP_XMIN_COMMITTED | + HEAP_XMIN_INVALID | + HEAP_MOVED_OFF); newtup.t_data->t_infomask |= HEAP_MOVED_IN; HeapTupleHeaderSetXvac(newtup.t_data, myXID); - newoff = PageAddItem(ToPage, (Item) newtup.t_data, tuple_len, - InvalidOffsetNumber, LP_USED); + newoff = PageAddItem(ToPage, + (Item) newtup.t_data, + tuple_len, + InvalidOffsetNumber, + LP_USED); if (newoff == InvalidOffsetNumber) { elog(PANIC, "moving chain: failed to add item with len = %lu to page %u", @@ -2038,11 +2042,11 @@ repair_frag(VRelStats *vacrelstats, Relation onerel, START_CRIT_SECTION(); /* - * Mark new tuple as moved_in by vacuum and store vacuum XID - * in t_cid !!! + * Mark new tuple as MOVED_IN by me. */ - newtup.t_data->t_infomask &= - ~(HEAP_XMIN_COMMITTED | HEAP_XMIN_INVALID | HEAP_MOVED_OFF); + newtup.t_data->t_infomask &= ~(HEAP_XMIN_COMMITTED | + HEAP_XMIN_INVALID | + HEAP_MOVED_OFF); newtup.t_data->t_infomask |= HEAP_MOVED_IN; HeapTupleHeaderSetXvac(newtup.t_data, myXID); @@ -2064,11 +2068,11 @@ repair_frag(VRelStats *vacrelstats, Relation onerel, newtup.t_self = newtup.t_data->t_ctid; /* - * Mark old tuple as moved_off by vacuum and store vacuum XID - * in t_cid !!! + * Mark old tuple as MOVED_OFF by me. */ - tuple.t_data->t_infomask &= - ~(HEAP_XMIN_COMMITTED | HEAP_XMIN_INVALID | HEAP_MOVED_IN); + tuple.t_data->t_infomask &= ~(HEAP_XMIN_COMMITTED | + HEAP_XMIN_INVALID | + HEAP_MOVED_IN); tuple.t_data->t_infomask |= HEAP_MOVED_OFF; HeapTupleHeaderSetXvac(tuple.t_data, myXID); diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c index 6318d79d4eb916331d02bedec1dcd23b0b83a0fc..fd4431ce5f73475c23a8dd8990c9de046a32b78d 100644 --- a/src/backend/executor/execMain.c +++ b/src/backend/executor/execMain.c @@ -27,7 +27,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.176 2002/08/29 00:17:03 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.177 2002/09/02 01:05:05 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -712,22 +712,25 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate) aclcheck_error(aclresult, get_namespace_name(namespaceId)); - /* - * new "INTO" table is created WITH OIDS - */ - tupType->tdhasoid = WITHOID; /* * 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, - true, allowSystemTableMods); FreeTupleDesc(tupdesc); diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c index 30f5b0e378f3406ab985c605180ede27d0c009e5..12b2089fd7363d85d416f761bed752d65ae36e34 100644 --- a/src/backend/executor/execQual.c +++ b/src/backend/executor/execQual.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.106 2002/08/31 22:10:43 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.107 2002/09/02 01:05:05 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -997,7 +997,7 @@ ExecMakeTableFunctionResult(Expr *funcexpr, /* * Scalar type, so make a single-column descriptor */ - tupdesc = CreateTemplateTupleDesc(1, WITHOUTOID); + tupdesc = CreateTemplateTupleDesc(1, false); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "column", @@ -2006,10 +2006,7 @@ ExecTargetList(List *targetlist, * 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 --git a/src/backend/executor/execTuples.c b/src/backend/executor/execTuples.c index afadcd3137b028ef74fb2ea4090b3c8ab6d083d6..e07fd8719abeb21330f2a4a52b6b403df37e1a57 100644 --- a/src/backend/executor/execTuples.c +++ b/src/backend/executor/execTuples.c @@ -15,7 +15,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/execTuples.c,v 1.57 2002/08/29 00:17:03 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/execTuples.c,v 1.58 2002/09/02 01:05:05 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -541,7 +541,6 @@ ExecInitNullTupleSlot(EState *estate, TupleDesc tupType) ExecSetSlotDescriptor(slot, tupType, false); - NullTupleDesc.tdhasoid = WITHOUTOID; nullTuple = heap_formtuple(&NullTupleDesc, values, nulls); return ExecStoreTuple(nullTuple, slot, InvalidBuffer, true); @@ -559,7 +558,7 @@ ExecInitNullTupleSlot(EState *estate, TupleDesc tupType) * ---------------------------------------------------------------- */ TupleDesc -ExecTypeFromTL(List *targetList, hasoid_t withoid) +ExecTypeFromTL(List *targetList, bool hasoid) { List *tlitem; TupleDesc typeInfo; @@ -578,7 +577,7 @@ ExecTypeFromTL(List *targetList, hasoid_t withoid) /* * allocate a new typeInfo */ - typeInfo = CreateTemplateTupleDesc(len, withoid); + typeInfo = CreateTemplateTupleDesc(len, hasoid); /* * scan list, generate type info for each entry diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c index 24f232469b0ac281ca05986ecb86a1d4a59f3518..3e8cf203b11f8441a311f22fb1f8897641ca1113 100644 --- a/src/backend/executor/execUtils.c +++ b/src/backend/executor/execUtils.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.88 2002/08/06 02:36:34 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.89 2002/09/02 01:05:05 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -291,22 +291,36 @@ void ExecAssignResultTypeFromTL(Plan *node, CommonState *commonstate) { ResultRelInfo *ri; - Relation rel; - hasoid_t withoid; + bool hasoid = false; TupleDesc tupDesc; + /* + * This is pretty grotty: 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. We assume that estate->es_result_relation_info + * is already set up to describe the target relation. 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 + * plan to do so. + * + * It would be better to have InitPlan adjust the topmost plan node's + * output descriptor after plan tree initialization. However, that + * doesn't quite work because in an UPDATE that spans an inheritance + * tree, some of the target relations may have OIDs and some not. + * We 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 ... + */ ri = node->state->es_result_relation_info; if (ri != NULL) - rel = ri->ri_RelationDesc; - else - rel = node->state->es_into_relation_descriptor; + { + Relation rel = ri->ri_RelationDesc; - if (rel != NULL) - withoid = BoolToHasOid(rel->rd_rel->relhasoids); - else - withoid = WITHOUTOID; + if (rel != NULL) + hasoid = rel->rd_rel->relhasoids; + } - tupDesc = ExecTypeFromTL(node->targetlist, withoid); + tupDesc = ExecTypeFromTL(node->targetlist, hasoid); ExecAssignResultType(commonstate, tupDesc, true); } diff --git a/src/backend/executor/nodeAppend.c b/src/backend/executor/nodeAppend.c index 724f0c8ce8950afc4bb4a8613cfed3158dc0e30f..8bc7136cb442b08991c84a89ede66e989ce970e8 100644 --- a/src/backend/executor/nodeAppend.c +++ b/src/backend/executor/nodeAppend.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/nodeAppend.c,v 1.45 2002/06/20 20:29:28 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/nodeAppend.c,v 1.46 2002/09/02 01:05:05 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -217,7 +217,9 @@ ExecInitAppend(Append *node, EState *estate, Plan *parent) /* * call ExecInitNode on each of the plans to be executed and save the - * results into the array "initialized" + * results into the array "initialized". Note we *must* set + * estate->es_result_relation_info correctly while we initialize each + * sub-plan; ExecAssignResultTypeFromTL depends on that! */ for (i = appendstate->as_firstplan; i <= appendstate->as_lastplan; i++) { diff --git a/src/backend/executor/nodeFunctionscan.c b/src/backend/executor/nodeFunctionscan.c index 89b5a544e5a42855e5b98a3b322a0881df27f831..8a9ac848e7bd45ba85924a3b469040c920c9abd4 100644 --- a/src/backend/executor/nodeFunctionscan.c +++ b/src/backend/executor/nodeFunctionscan.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/nodeFunctionscan.c,v 1.10 2002/08/31 19:09:27 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/nodeFunctionscan.c,v 1.11 2002/09/02 01:05:05 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -209,7 +209,7 @@ ExecInitFunctionScan(FunctionScan *node, EState *estate, Plan *parent) */ char *attname = strVal(lfirst(rte->eref->colnames)); - tupdesc = CreateTemplateTupleDesc(1, WITHOUTOID); + tupdesc = CreateTemplateTupleDesc(1, false); TupleDescInitEntry(tupdesc, (AttrNumber) 1, attname, @@ -223,10 +223,7 @@ ExecInitFunctionScan(FunctionScan *node, EState *estate, Plan *parent) /* * Must be a pseudo type, i.e. record */ - List *coldeflist = rte->coldeflist; - - tupdesc = BuildDescForRelation(coldeflist); - tupdesc->tdhasoid = WITHOUTOID; + tupdesc = BuildDescForRelation(rte->coldeflist); } else elog(ERROR, "Unknown kind of return type specified for function"); diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c index 8535d875328ff0ff02ce4c27bce0092efc32b54c..f0cc3fe17ae500e2a9f882fe526adf96565b2c45 100644 --- a/src/backend/executor/spi.c +++ b/src/backend/executor/spi.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/spi.c,v 1.72 2002/07/20 05:16:58 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/spi.c,v 1.73 2002/09/02 01:05:05 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -392,7 +392,6 @@ SPI_modifytuple(Relation rel, HeapTuple tuple, int natts, int *attnum, MemoryContext oldcxt = NULL; HeapTuple mtuple; int numberOfAttributes; - uint8 infomask; Datum *v; char *n; bool isnull; @@ -434,14 +433,13 @@ SPI_modifytuple(Relation rel, HeapTuple tuple, int natts, int *attnum, if (i == natts) /* no errors in *attnum */ { mtuple = heap_formtuple(rel->rd_att, v, n); - infomask = mtuple->t_data->t_infomask; /* - * copy t_xmin, t_cid, t_xmax, t_ctid, t_natts, t_infomask + * copy the identification info of the old tuple: t_ctid, t_self, + * and OID (if any) */ - memmove((char *)mtuple->t_data, (char *)tuple->t_data, - offsetof(HeapTupleHeaderData, t_hoff)); - mtuple->t_data->t_infomask = infomask; - mtuple->t_data->t_natts = numberOfAttributes; + 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_rel->relhasoids) HeapTupleSetOid(mtuple, HeapTupleGetOid(tuple)); } diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c index c5aacab95b1686a1e9134952fa2b5952735a265c..3dd3b4e2625d8d33c79cde07ba710594dd9699d4 100644 --- a/src/backend/postmaster/pgstat.c +++ b/src/backend/postmaster/pgstat.c @@ -16,7 +16,7 @@ * * Copyright (c) 2001, PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/backend/postmaster/pgstat.c,v 1.24 2002/08/29 07:22:23 ishii Exp $ + * $Header: /cvsroot/pgsql/src/backend/postmaster/pgstat.c,v 1.25 2002/09/02 01:05:05 tgl Exp $ * ---------- */ #include "postgres.h" @@ -620,7 +620,6 @@ pgstat_vacuum_tabstat(void) dbidlist = (Oid *) repalloc((char *) dbidlist, sizeof(Oid) * dbidalloc); } - AssertTupleDescHasOid(dbrel->rd_att); dbidlist[dbidused++] = HeapTupleGetOid(dbtup); } heap_endscan(dbscan); diff --git a/src/backend/storage/page/bufpage.c b/src/backend/storage/page/bufpage.c index ca8186ccdace1030a045eb62396c9f053543c7d0..a44e405d0fde921fb9d1f730eb34fa3c34760268 100644 --- a/src/backend/storage/page/bufpage.c +++ b/src/backend/storage/page/bufpage.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/storage/page/bufpage.c,v 1.47 2002/08/06 19:41:23 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/storage/page/bufpage.c,v 1.48 2002/09/02 01:05:05 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -45,7 +45,7 @@ PageInit(Page page, Size pageSize, Size specialSize) p->pd_lower = SizeOfPageHeaderData; p->pd_upper = pageSize - specialSize; p->pd_special = pageSize - specialSize; - PageSetPageSize(page, pageSize); + PageSetPageSizeAndVersion(page, pageSize, PG_PAGE_LAYOUT_VERSION); } diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c index b1ccceebcb9aa53b380b4ab7cd3af1fee276e3c0..a5dda27f640bd1704e4d3c29fdb5ec2d16895222 100644 --- a/src/backend/utils/adt/lockfuncs.c +++ b/src/backend/utils/adt/lockfuncs.c @@ -6,7 +6,7 @@ * Copyright (c) 2002, PostgreSQL Global Development Group * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/lockfuncs.c,v 1.5 2002/08/31 17:14:28 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/lockfuncs.c,v 1.6 2002/09/02 01:05:06 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -50,7 +50,7 @@ pg_lock_status(PG_FUNCTION_ARGS) /* build tupdesc for result tuples */ /* this had better match pg_locks view in initdb.sh */ - tupdesc = CreateTemplateTupleDesc(6, WITHOUTOID); + tupdesc = CreateTemplateTupleDesc(6, false); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "relation", OIDOID, -1, 0, false); TupleDescInitEntry(tupdesc, (AttrNumber) 2, "database", diff --git a/src/backend/utils/adt/regproc.c b/src/backend/utils/adt/regproc.c index c99685d675f3051d93237bf77d636cd715b3cd10..c39d176ece8e6c1c85969716be731f3c995fa1ec 100644 --- a/src/backend/utils/adt/regproc.c +++ b/src/backend/utils/adt/regproc.c @@ -13,7 +13,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/regproc.c,v 1.73 2002/08/22 00:01:43 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/regproc.c,v 1.74 2002/09/02 01:05:06 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -110,7 +110,6 @@ regprocin(PG_FUNCTION_ARGS) while (HeapTupleIsValid(tuple = systable_getnext(sysscan))) { - AssertTupleDescHasOid(hdesc->rd_att); result = (RegProcedure) HeapTupleGetOid(tuple); if (++matches > 1) break; @@ -425,7 +424,6 @@ regoperin(PG_FUNCTION_ARGS) while (HeapTupleIsValid(tuple = systable_getnext(sysscan))) { - AssertTupleDescHasOid(hdesc->rd_att); result = HeapTupleGetOid(tuple); if (++matches > 1) break; @@ -756,10 +754,7 @@ regclassin(PG_FUNCTION_ARGS) SnapshotNow, 1, skey); if (HeapTupleIsValid(tuple = systable_getnext(sysscan))) - { - AssertTupleDescHasOid(hdesc->rd_att); result = HeapTupleGetOid(tuple); - } else elog(ERROR, "No class with name %s", class_name_or_oid); @@ -912,10 +907,7 @@ regtypein(PG_FUNCTION_ARGS) SnapshotNow, 1, skey); if (HeapTupleIsValid(tuple = systable_getnext(sysscan))) - { - AssertTupleDescHasOid(hdesc->rd_att); result = HeapTupleGetOid(tuple); - } else elog(ERROR, "No type with name %s", typ_name_or_oid); diff --git a/src/backend/utils/adt/sets.c b/src/backend/utils/adt/sets.c index 2c0beb25e0d133df52b1941f06c840c0acb2fb20..321b9c6855e0b4577594ff5869e99a991dd5386d 100644 --- a/src/backend/utils/adt/sets.c +++ b/src/backend/utils/adt/sets.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/sets.c,v 1.52 2002/08/27 03:56:35 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/sets.c,v 1.53 2002/09/02 01:05:06 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -116,7 +116,6 @@ SetDefine(char *querystr, Oid elemType) simple_heap_update(procrel, &newtup->t_self, newtup); - AssertTupleDescHasOid(procrel->rd_att); setoid = HeapTupleGetOid(newtup); CatalogUpdateIndexes(procrel, newtup); diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c index 21f1e01dabb9829aadbaa94afa3af2464c410c3f..5703bf16530bb07e6f7f87d78ac74683fad82abb 100644 --- a/src/backend/utils/cache/catcache.c +++ b/src/backend/utils/cache/catcache.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.97 2002/07/20 05:16:58 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.98 2002/09/02 01:05:06 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -907,7 +907,6 @@ CatalogCacheInitializeCache(CatCache *cache) * 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 @@ -1687,10 +1686,7 @@ build_dummy_tuple(CatCache *cache, int nkeys, ScanKey skeys) ntp = heap_formtuple(tupDesc, values, nulls); if (tupOid != InvalidOid) - { - AssertTupleDescHasOid(tupDesc); HeapTupleSetOid(ntp, tupOid); - } pfree(values); pfree(nulls); diff --git a/src/backend/utils/cache/inval.c b/src/backend/utils/cache/inval.c index c292926238171082c7481e6400a047b3bba228c1..d64f5bf0b57be73dd0aef00b8b30a881d5926234 100644 --- a/src/backend/utils/cache/inval.c +++ b/src/backend/utils/cache/inval.c @@ -74,7 +74,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/cache/inval.c,v 1.53 2002/07/20 05:16:58 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/cache/inval.c,v 1.54 2002/09/02 01:05:06 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -525,10 +525,7 @@ PrepareForTupleInvalidation(Relation relation, HeapTuple tuple, tupleRelId = RelationGetRelid(relation); if (tupleRelId == RelOid_pg_class) - { - AssertTupleDescHasOid(relation->rd_att); relationId = HeapTupleGetOid(tuple); - } else if (tupleRelId == RelOid_pg_attribute) relationId = ((Form_pg_attribute) GETSTRUCT(tuple))->attrelid; else diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index 1b5717029aa65f4424d769f700d284a7680f9c0d..036d11022bb633b22295d828e0d8efd8cc984a0f 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.172 2002/08/11 21:17:35 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.173 2002/09/02 01:05:06 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -434,7 +434,8 @@ AllocateRelationDesc(Relation relation, Form_pg_class relp) relation->rd_rel = relationForm; /* and allocate attribute tuple form storage */ - relation->rd_att = CreateTemplateTupleDesc(relationForm->relnatts, BoolToHasOid(relationForm->relhasoids)); + relation->rd_att = CreateTemplateTupleDesc(relationForm->relnatts, + relationForm->relhasoids); MemoryContextSwitchTo(oldcxt); @@ -460,6 +461,8 @@ RelationBuildTupleDesc(RelationBuildDescInfo buildinfo, AttrDefault *attrdef = NULL; int ndef = 0; + relation->rd_att->tdhasoid = RelationGetForm(relation)->relhasoids; + constr = (TupleConstr *) MemoryContextAlloc(CacheMemoryContext, sizeof(TupleConstr)); constr->has_not_null = false; @@ -695,7 +698,6 @@ RelationBuildRuleLock(Relation relation) rule = (RewriteRule *) MemoryContextAlloc(rulescxt, sizeof(RewriteRule)); - AssertTupleDescHasOid(rewrite_tupdesc); rule->ruleId = HeapTupleGetOid(rewrite_tuple); rule->event = rewrite_form->ev_type - '0'; @@ -871,7 +873,6 @@ RelationBuildDesc(RelationBuildDescInfo buildinfo, * 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 @@ -1405,7 +1406,8 @@ formrdesc(const char *relationName, * 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, BoolToHasOid(relation->rd_rel->relhasoids)); + relation->rd_att = CreateTemplateTupleDesc(natts, + relation->rd_rel->relhasoids); /* * initialize tuple desc info @@ -2101,7 +2103,7 @@ RelationBuildLocalRelation(const char *relname, rel->rd_rel->relnamespace = relnamespace; rel->rd_rel->relkind = RELKIND_UNCATALOGED; - rel->rd_rel->relhasoids = (rel->rd_att->tdhasoid == WITHOID); + rel->rd_rel->relhasoids = rel->rd_att->tdhasoid; rel->rd_rel->relnatts = natts; rel->rd_rel->reltype = InvalidOid; @@ -2304,7 +2306,7 @@ RelationCacheInitializePhase2(void) */ Assert(relation->rd_rel != NULL); memcpy((char *) relation->rd_rel, (char *) relp, CLASS_TUPLE_SIZE); - relation->rd_att->tdhasoid = BoolToHasOid(relp->relhasoids); + relation->rd_att->tdhasoid = relp->relhasoids; ReleaseSysCache(htup); } @@ -2766,7 +2768,8 @@ load_relcache_init_file(void) rel->rd_rel = relform; /* initialize attribute tuple forms */ - rel->rd_att = CreateTemplateTupleDesc(relform->relnatts, BoolToHasOid(relform->relhasoids)); + rel->rd_att = CreateTemplateTupleDesc(relform->relnatts, + relform->relhasoids); /* next read all the attribute tuple form data entries */ for (i = 0; i < relform->relnatts; i++) diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c index 82f4f632e58a4e23c56fb18c5f526c2e4d287a34..5e4100384a275d30289c244a67cf9cdfba7172a0 100644 --- a/src/backend/utils/init/postinit.c +++ b/src/backend/utils/init/postinit.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.112 2002/08/30 22:18:06 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.113 2002/09/02 01:05:06 tgl Exp $ * * *------------------------------------------------------------------------- @@ -98,7 +98,6 @@ ReverifyMyDatabase(const char *name) pgdbscan = heap_beginscan(pgdbrel, SnapshotNow, 1, &key); tup = heap_getnext(pgdbscan, ForwardScanDirection); - AssertTupleDescHasOid(pgdbrel->rd_att); if (!HeapTupleIsValid(tup) || HeapTupleGetOid(tup) != MyDatabaseId) { diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index e07421a87cfa97b844c4b80b6b1ae228bc033ae7..0c24034b5f24fd4fa0508d449db556fea9d8b8cd 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -5,7 +5,7 @@ * command, configuration file, and command line options. * See src/backend/utils/misc/README for more information. * - * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.90 2002/09/01 23:26:06 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.91 2002/09/02 01:05:06 tgl Exp $ * * Copyright 2000 by PostgreSQL Global Development Group * Written by Peter Eisentraut <peter_e@gmx.net>. @@ -2288,7 +2288,7 @@ ShowGUCConfigOption(const char *name) value = GetConfigOptionByName(name, &varname); /* need a tuple descriptor representing a single TEXT column */ - tupdesc = CreateTemplateTupleDesc(1, WITHOUTOID); + tupdesc = CreateTemplateTupleDesc(1, false); TupleDescInitEntry(tupdesc, (AttrNumber) 1, (char *) varname, TEXTOID, -1, 0, false); @@ -2314,7 +2314,7 @@ ShowAllGUCConfig(void) char *values[2]; /* need a tuple descriptor representing two TEXT columns */ - tupdesc = CreateTemplateTupleDesc(2, WITHOUTOID); + tupdesc = CreateTemplateTupleDesc(2, false); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name", TEXTOID, -1, 0, false); TupleDescInitEntry(tupdesc, (AttrNumber) 2, "setting", @@ -2445,7 +2445,7 @@ show_all_settings(PG_FUNCTION_ARGS) oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); /* need a tuple descriptor representing two TEXT columns */ - tupdesc = CreateTemplateTupleDesc(2, WITHOUTOID); + tupdesc = CreateTemplateTupleDesc(2, false); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name", TEXTOID, -1, 0, false); TupleDescInitEntry(tupdesc, (AttrNumber) 2, "setting", diff --git a/src/backend/utils/time/tqual.c b/src/backend/utils/time/tqual.c index bd7693ca37cef3dc6deaedef4fc7906193fbba55..0cc88167dac69ec8b4db42fdad82385856dbe9cd 100644 --- a/src/backend/utils/time/tqual.c +++ b/src/backend/utils/time/tqual.c @@ -16,7 +16,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/time/tqual.c,v 1.58 2002/07/30 16:08:33 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/time/tqual.c,v 1.59 2002/09/02 01:05:06 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -83,7 +83,6 @@ HeapTupleSatisfiesItself(HeapTupleHeader tuple) return false; } tuple->t_infomask |= HEAP_XMIN_COMMITTED; - tuple->t_infomask &= ~HEAP_MOVED; } } else if (tuple->t_infomask & HEAP_MOVED_IN) @@ -93,10 +92,7 @@ HeapTupleSatisfiesItself(HeapTupleHeader tuple) if (TransactionIdIsInProgress(HeapTupleHeaderGetXvac(tuple))) return false; if (TransactionIdDidCommit(HeapTupleHeaderGetXvac(tuple))) - { tuple->t_infomask |= HEAP_XMIN_COMMITTED; - tuple->t_infomask &= ~HEAP_MOVED; - } else { tuple->t_infomask |= HEAP_XMIN_INVALID; @@ -223,7 +219,6 @@ HeapTupleSatisfiesNow(HeapTupleHeader tuple) return false; } tuple->t_infomask |= HEAP_XMIN_COMMITTED; - tuple->t_infomask &= ~HEAP_MOVED; } } else if (tuple->t_infomask & HEAP_MOVED_IN) @@ -233,10 +228,7 @@ HeapTupleSatisfiesNow(HeapTupleHeader tuple) if (TransactionIdIsInProgress(HeapTupleHeaderGetXvac(tuple))) return false; if (TransactionIdDidCommit(HeapTupleHeaderGetXvac(tuple))) - { tuple->t_infomask |= HEAP_XMIN_COMMITTED; - tuple->t_infomask &= ~HEAP_MOVED; - } else { tuple->t_infomask |= HEAP_XMIN_INVALID; @@ -344,7 +336,6 @@ HeapTupleSatisfiesToast(HeapTupleHeader tuple) return false; } tuple->t_infomask |= HEAP_XMIN_COMMITTED; - tuple->t_infomask &= ~HEAP_MOVED; } } else if (tuple->t_infomask & HEAP_MOVED_IN) @@ -354,10 +345,7 @@ HeapTupleSatisfiesToast(HeapTupleHeader tuple) if (TransactionIdIsInProgress(HeapTupleHeaderGetXvac(tuple))) return false; if (TransactionIdDidCommit(HeapTupleHeaderGetXvac(tuple))) - { tuple->t_infomask |= HEAP_XMIN_COMMITTED; - tuple->t_infomask &= ~HEAP_MOVED; - } else { tuple->t_infomask |= HEAP_XMIN_INVALID; @@ -401,7 +389,6 @@ HeapTupleSatisfiesUpdate(HeapTuple htuple, CommandId curcid) return HeapTupleInvisible; } tuple->t_infomask |= HEAP_XMIN_COMMITTED; - tuple->t_infomask &= ~HEAP_MOVED; } } else if (tuple->t_infomask & HEAP_MOVED_IN) @@ -411,10 +398,7 @@ HeapTupleSatisfiesUpdate(HeapTuple htuple, CommandId curcid) if (TransactionIdIsInProgress(HeapTupleHeaderGetXvac(tuple))) return HeapTupleInvisible; if (TransactionIdDidCommit(HeapTupleHeaderGetXvac(tuple))) - { tuple->t_infomask |= HEAP_XMIN_COMMITTED; - tuple->t_infomask &= ~HEAP_MOVED; - } else { tuple->t_infomask |= HEAP_XMIN_INVALID; @@ -536,7 +520,6 @@ HeapTupleSatisfiesDirty(HeapTupleHeader tuple) return false; } tuple->t_infomask |= HEAP_XMIN_COMMITTED; - tuple->t_infomask &= ~HEAP_MOVED; } } else if (tuple->t_infomask & HEAP_MOVED_IN) @@ -546,10 +529,7 @@ HeapTupleSatisfiesDirty(HeapTupleHeader tuple) if (TransactionIdIsInProgress(HeapTupleHeaderGetXvac(tuple))) return false; if (TransactionIdDidCommit(HeapTupleHeaderGetXvac(tuple))) - { tuple->t_infomask |= HEAP_XMIN_COMMITTED; - tuple->t_infomask &= ~HEAP_MOVED; - } else { tuple->t_infomask |= HEAP_XMIN_INVALID; @@ -671,7 +651,6 @@ HeapTupleSatisfiesSnapshot(HeapTupleHeader tuple, Snapshot snapshot) return false; } tuple->t_infomask |= HEAP_XMIN_COMMITTED; - tuple->t_infomask &= ~HEAP_MOVED; } } else if (tuple->t_infomask & HEAP_MOVED_IN) @@ -681,10 +660,7 @@ HeapTupleSatisfiesSnapshot(HeapTupleHeader tuple, Snapshot snapshot) if (TransactionIdIsInProgress(HeapTupleHeaderGetXvac(tuple))) return false; if (TransactionIdDidCommit(HeapTupleHeaderGetXvac(tuple))) - { tuple->t_infomask |= HEAP_XMIN_COMMITTED; - tuple->t_infomask &= ~HEAP_MOVED; - } else { tuple->t_infomask |= HEAP_XMIN_INVALID; @@ -833,7 +809,6 @@ HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId OldestXmin) return HEAPTUPLE_DEAD; } tuple->t_infomask |= HEAP_XMIN_COMMITTED; - tuple->t_infomask &= ~HEAP_MOVED; } else if (tuple->t_infomask & HEAP_MOVED_IN) { @@ -842,10 +817,7 @@ HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId OldestXmin) if (TransactionIdIsInProgress(HeapTupleHeaderGetXvac(tuple))) return HEAPTUPLE_INSERT_IN_PROGRESS; if (TransactionIdDidCommit(HeapTupleHeaderGetXvac(tuple))) - { tuple->t_infomask |= HEAP_XMIN_COMMITTED; - tuple->t_infomask &= ~HEAP_MOVED; - } else { tuple->t_infomask |= HEAP_XMIN_INVALID; diff --git a/src/include/access/htup.h b/src/include/access/htup.h index f1d9748f5c526950e5eb106bf544e12a90649010..3bede1bfa3af99f7fc156f8dec3f94aa4bcbd666 100644 --- a/src/include/access/htup.h +++ b/src/include/access/htup.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: htup.h,v 1.58 2002/08/25 17:20:01 tgl Exp $ + * $Id: htup.h,v 1.59 2002/09/02 01:05:06 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -46,33 +46,69 @@ */ #define MaxHeapAttributeNumber 1600 /* 8 * 200 */ -/* +/*---------- * On-disk heap tuple header. Currently this is also used as the header * format for tuples formed in memory, although in principle they could - * be different. + * be different. To avoid wasting space, the fields should be layed out + * in such a way to avoid structure padding. + * + * The overall structure of a heap tuple looks like: + * fixed fields (HeapTupleHeaderData struct) + * nulls bitmap (if HEAP_HASNULL is set in t_infomask) + * alignment padding (as needed to make user data MAXALIGN'd) + * object ID (if HEAP_HASOID is set in t_infomask) + * user data fields + * + * We store five "virtual" fields Xmin, Cmin, Xmax, Cmax, and Xvac + * in just three physical fields. Xmin is always really stored, but + * Cmin and Xmax share a field, as do Cmax and Xvac. This works because + * we know that there are only a limited number of states that a tuple can + * be in, and that Cmin and Cmax are only interesting for the lifetime of + * the inserting and deleting transactions respectively. We have the + * following possible states of a tuple: + * + * XMIN CMIN XMAX CMAX XVAC + * + * NEW (never deleted, not moved by vacuum): + * valid valid invalid invalid invalid * - * To avoid wasting space, the attributes should be layed out in such a - * way to reduce structure padding. Note that t_hoff is the offset to - * the start of the user data, and so must be a multiple of MAXALIGN. - * Also note that we omit the nulls bitmap if t_infomask shows that there - * are no nulls in the tuple. + * DELETED BY CREATING XACT: + * valid valid = XMIN valid invalid + * + * DELETED BY OTHER XACT: + * valid unneeded valid valid invalid + * + * MOVED BY VACUUM FULL: + * valid unneeded maybe-valid unneeded valid + * + * This assumes that VACUUM FULL never tries to move a tuple whose Cmin or + * Cmax is still interesting (ie, insert-in-progress or delete-in-progress). + * + * This table shows that if we use an infomask bit to handle the case + * XMAX=XMIN specially, we never need to store Cmin and Xmax at the same + * time. Nor do we need to store Cmax and Xvac at the same time. + * + * Following the fixed header fields, the nulls bitmap is stored (beginning + * at t_bits). The bitmap is *not* stored if t_infomask shows that there + * are no nulls in the tuple. If an OID field is present (as indicated by + * t_infomask), then it is stored just before the user data, which begins at + * the offset shown by t_hoff. Note that t_hoff must be a multiple of + * MAXALIGN. + *---------- */ -/* -** We store five "virtual" fields Xmin, Cmin, Xmax, Cmax, and Xvac -** in three physical fields t_xmin, t_cid, t_xmax: -** CommandId Cmin; insert CID stamp -** CommandId Cmax; delete CommandId stamp -** TransactionId Xmin; insert XID stamp -** TransactionId Xmax; delete XID stamp -** TransactionId Xvac; used by VACCUUM -** -** This assumes, that a CommandId can be stored in a TransactionId. -*/ typedef struct HeapTupleHeaderData { - TransactionId t_xmin; /* Xmin -- 4 bytes each */ - TransactionId t_cid; /* Cmin, Cmax, Xvac */ - TransactionId t_xmax; /* Xmax, Cmax */ + TransactionId t_xmin; /* inserting xact ID */ + + union { + CommandId t_cmin; /* inserting command ID */ + TransactionId t_xmax; /* deleting xact ID */ + } t_field2; + + union { + CommandId t_cmax; /* deleting command ID */ + TransactionId t_xvac; /* VACUUM FULL xact ID */ + } t_field3; ItemPointerData t_ctid; /* current TID of this or newer tuple */ @@ -101,11 +137,12 @@ typedef HeapTupleHeaderData *HeapTupleHeader; #define HEAP_HASCOMPRESSED 0x0008 /* has compressed stored * attribute(s) */ #define HEAP_HASEXTENDED 0x000C /* the two above combined */ - -#define HEAP_XMIN_IS_XMAX 0x0040 /* created and deleted in the */ - /* same transaction */ -#define HEAP_XMAX_UNLOGGED 0x0080 /* to lock tuple for update */ - /* without logging */ +#define HEAP_HASOID 0x0010 /* has an object-id field */ +/* bit 0x0020 is presently unused */ +#define HEAP_XMAX_IS_XMIN 0x0040 /* created and deleted in the + * same transaction */ +#define HEAP_XMAX_UNLOGGED 0x0080 /* to lock tuple for update + * without logging */ #define HEAP_XMIN_COMMITTED 0x0100 /* t_xmin committed */ #define HEAP_XMIN_INVALID 0x0200 /* t_xmin invalid/aborted */ #define HEAP_XMAX_COMMITTED 0x0400 /* t_xmax committed */ @@ -113,143 +150,111 @@ typedef HeapTupleHeaderData *HeapTupleHeader; #define HEAP_MARKED_FOR_UPDATE 0x1000 /* marked for UPDATE */ #define HEAP_UPDATED 0x2000 /* this is UPDATEd version of row */ #define HEAP_MOVED_OFF 0x4000 /* moved to another place by - * vacuum */ + * VACUUM FULL */ #define HEAP_MOVED_IN 0x8000 /* moved from another place by - * vacuum */ + * VACUUM FULL */ #define HEAP_MOVED (HEAP_MOVED_OFF | HEAP_MOVED_IN) -#define HEAP_XACT_MASK 0xFFF0 /* visibility-related bits */ - -/* paranoid checking */ - -#ifdef DEBUG_TUPLE_ACCESS - -#define HeapTupleHeaderExpectedLen(tup, withoid) \ - MAXALIGN(offsetof(HeapTupleHeaderData, t_bits) + \ - (((tup)->t_infomask & HEAP_HASNULL) \ - ? BITMAPLEN((tup)->t_natts) : 0) + \ - ((withoid) ? sizeof(Oid) : 0) \ - ) - -#define AssertHeapTupleHeaderHoffIsValid(tup, withoid) \ - AssertMacro((tup)->t_hoff == HeapTupleHeaderExpectedLen(tup, withoid)) - -#else - -#define AssertHeapTupleHeaderHoffIsValid(tup, withoid) ((void)true) - -#endif /* DEBUG_TUPLE_ACCESS */ - +#define HEAP_XACT_MASK 0xFFC0 /* visibility-related bits */ -/* HeapTupleHeader accessor macros */ -#define HeapTupleHeaderGetOid(tup) \ -( \ - AssertHeapTupleHeaderHoffIsValid(tup, true), \ - *((Oid *)((char *)(tup) + (tup)->t_hoff - sizeof(Oid))) \ -) - -#define HeapTupleHeaderSetOid(tup, oid) \ -( \ - AssertHeapTupleHeaderHoffIsValid(tup, true), \ - *((Oid *)((char *)(tup) + (tup)->t_hoff - sizeof(Oid))) = (oid) \ -) - +/* + * HeapTupleHeader accessor macros + * + * Note: beware of multiple evaluations of "tup" argument. But the Set + * macros evaluate their other argument only once. + */ #define HeapTupleHeaderGetXmin(tup) \ ( \ (tup)->t_xmin \ ) -#define HeapTupleHeaderGetXmax(tup) \ -( \ - ((tup)->t_infomask & HEAP_XMIN_IS_XMAX) ? \ - (tup)->t_xmin \ - : \ - (tup)->t_xmax \ -) - -/* no AssertMacro, because this is read as a system-defined attribute */ -#define HeapTupleHeaderGetCmin(tup) \ +#define HeapTupleHeaderSetXmin(tup, xid) \ ( \ - ((tup)->t_infomask & HEAP_MOVED) ? \ - FirstCommandId \ - : \ - ( \ - ((tup)->t_infomask & (HEAP_XMIN_IS_XMAX | HEAP_XMAX_INVALID)) ? \ - (CommandId) (tup)->t_cid \ - : \ - FirstCommandId \ - ) \ + TransactionIdStore((xid), &(tup)->t_xmin) \ ) -#define HeapTupleHeaderGetCmax(tup) \ +#define HeapTupleHeaderGetXmax(tup) \ ( \ - ((tup)->t_infomask & HEAP_MOVED) ? \ - FirstCommandId \ + ((tup)->t_infomask & HEAP_XMAX_IS_XMIN) ? \ + (tup)->t_xmin \ : \ - ( \ - ((tup)->t_infomask & (HEAP_XMIN_IS_XMAX | HEAP_XMAX_INVALID)) ? \ - (CommandId) (tup)->t_xmax \ - : \ - (CommandId) (tup)->t_cid \ - ) \ -) - -#define HeapTupleHeaderGetXvac(tup) \ -( \ - AssertMacro((tup)->t_infomask & HEAP_MOVED), \ - (tup)->t_cid \ -) - - -#define HeapTupleHeaderSetXmin(tup, xid) \ -( \ - TransactionIdStore((xid), &(tup)->t_xmin) \ + (tup)->t_field2.t_xmax \ ) -#define HeapTupleHeaderSetXminInvalid(tup) \ -do { \ - (tup)->t_infomask &= ~HEAP_XMIN_IS_XMAX; \ - StoreInvalidTransactionId(&(tup)->t_xmin); \ -} while (0) - #define HeapTupleHeaderSetXmax(tup, xid) \ do { \ - if (TransactionIdEquals((tup)->t_xmin, (xid))) \ - (tup)->t_infomask |= HEAP_XMIN_IS_XMAX; \ + TransactionId _newxid = (xid); \ + if (TransactionIdEquals((tup)->t_xmin, _newxid)) \ + (tup)->t_infomask |= HEAP_XMAX_IS_XMIN; \ else \ { \ - (tup)->t_infomask &= ~HEAP_XMIN_IS_XMAX; \ - TransactionIdStore((xid), &(tup)->t_xmax); \ + (tup)->t_infomask &= ~HEAP_XMAX_IS_XMIN; \ + TransactionIdStore(_newxid, &(tup)->t_field2.t_xmax); \ } \ } while (0) -#define HeapTupleHeaderSetXmaxInvalid(tup) \ -do { \ - (tup)->t_infomask &= ~HEAP_XMIN_IS_XMAX; \ - StoreInvalidTransactionId(&(tup)->t_xmax); \ -} while (0) +/* + * Note: GetCmin will produce wrong answers after SetXmax has been executed + * by a transaction other than the inserting one. We could check + * HEAP_XMAX_INVALID and return FirstCommandId if it's clear, but since that + * bit will be set again if the deleting transaction aborts, there'd be no + * real gain in safety from the extra test. So, just rely on the caller not + * to trust the value unless it's meaningful. + */ +#define HeapTupleHeaderGetCmin(tup) \ +( \ + (tup)->t_field2.t_cmin \ +) #define HeapTupleHeaderSetCmin(tup, cid) \ do { \ - Assert(!((tup)->t_infomask & HEAP_MOVED)); \ - TransactionIdStore((TransactionId) (cid), &(tup)->t_cid); \ + Assert((tup)->t_infomask & HEAP_XMAX_INVALID); \ + (tup)->t_field2.t_cmin = (cid); \ } while (0) +/* + * As with GetCmin, we can't completely ensure that GetCmax can detect whether + * a valid command ID is available, and there's little point in a partial test. + */ +#define HeapTupleHeaderGetCmax(tup) \ +( \ + (tup)->t_field3.t_cmax \ +) + #define HeapTupleHeaderSetCmax(tup, cid) \ do { \ Assert(!((tup)->t_infomask & HEAP_MOVED)); \ - if ((tup)->t_infomask & HEAP_XMIN_IS_XMAX) \ - TransactionIdStore((TransactionId) (cid), &(tup)->t_xmax); \ - else \ - TransactionIdStore((TransactionId) (cid), &(tup)->t_cid); \ + (tup)->t_field3.t_cmax = (cid); \ } while (0) +#define HeapTupleHeaderGetXvac(tup) \ +( \ + ((tup)->t_infomask & HEAP_MOVED) ? \ + (tup)->t_field3.t_xvac \ + : \ + InvalidTransactionId \ +) + #define HeapTupleHeaderSetXvac(tup, xid) \ do { \ Assert((tup)->t_infomask & HEAP_MOVED); \ - TransactionIdStore((xid), &(tup)->t_cid); \ + TransactionIdStore((xid), &(tup)->t_field3.t_xvac); \ +} while (0) + +#define HeapTupleHeaderGetOid(tup) \ +( \ + ((tup)->t_infomask & HEAP_HASOID) ? \ + *((Oid *) ((char *)(tup) + (tup)->t_hoff - sizeof(Oid))) \ + : \ + InvalidOid \ +) + +#define HeapTupleHeaderSetOid(tup, oid) \ +do { \ + Assert((tup)->t_infomask & HEAP_HASOID); \ + *((Oid *) ((char *)(tup) + (tup)->t_hoff - sizeof(Oid))) = (oid); \ } while (0) @@ -400,12 +405,10 @@ typedef HeapTupleData *HeapTuple; #define HEAPTUPLESIZE MAXALIGN(sizeof(HeapTupleData)) -/* ---------------- - * support macros - * ---------------- +/* + * GETSTRUCT - given a HeapTuple pointer, return address of the user data */ -#define GETSTRUCT(TUP) (((char *)((HeapTuple)(TUP))->t_data) + \ - ((HeapTuple)(TUP))->t_data->t_hoff) +#define GETSTRUCT(TUP) ((char *) ((TUP)->t_data) + (TUP)->t_data->t_hoff) /* @@ -421,24 +424,24 @@ typedef HeapTupleData *HeapTuple; #define HeapTupleIsValid(tuple) PointerIsValid(tuple) #define HeapTupleNoNulls(tuple) \ - (!(((HeapTuple) (tuple))->t_data->t_infomask & HEAP_HASNULL)) + (!((tuple)->t_data->t_infomask & HEAP_HASNULL)) #define HeapTupleAllFixed(tuple) \ - (!(((HeapTuple) (tuple))->t_data->t_infomask & HEAP_HASVARWIDTH)) + (!((tuple)->t_data->t_infomask & HEAP_HASVARWIDTH)) #define HeapTupleHasExternal(tuple) \ - ((((HeapTuple)(tuple))->t_data->t_infomask & HEAP_HASEXTERNAL) != 0) + (((tuple)->t_data->t_infomask & HEAP_HASEXTERNAL) != 0) #define HeapTupleHasCompressed(tuple) \ - ((((HeapTuple)(tuple))->t_data->t_infomask & HEAP_HASCOMPRESSED) != 0) + (((tuple)->t_data->t_infomask & HEAP_HASCOMPRESSED) != 0) #define HeapTupleHasExtended(tuple) \ - ((((HeapTuple)(tuple))->t_data->t_infomask & HEAP_HASEXTENDED) != 0) + (((tuple)->t_data->t_infomask & HEAP_HASEXTENDED) != 0) #define HeapTupleGetOid(tuple) \ - HeapTupleHeaderGetOid(((HeapTuple)(tuple))->t_data) + HeapTupleHeaderGetOid((tuple)->t_data) #define HeapTupleSetOid(tuple, oid) \ - HeapTupleHeaderSetOid(((HeapTuple)(tuple))->t_data, (oid)) + HeapTupleHeaderSetOid((tuple)->t_data, (oid)) #endif /* HTUP_H */ diff --git a/src/include/access/tupdesc.h b/src/include/access/tupdesc.h index c8c9839985e454f3e47d19acf2dcf8ed9ed56835..09512a322e179d0c517e5e98771cd0482c4e1848 100644 --- a/src/include/access/tupdesc.h +++ b/src/include/access/tupdesc.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: tupdesc.h,v 1.37 2002/07/20 05:16:59 momjian Exp $ + * $Id: tupdesc.h,v 1.38 2002/09/02 01:05:06 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -41,14 +41,9 @@ typedef struct tupleConstr 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. + * pg_attribute, pg_attrdef, pg_constraint) for the structure of a tuple. */ typedef struct tupleDesc { @@ -56,29 +51,14 @@ typedef struct tupleDesc 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 */ + bool tdhasoid; /* Tuple has oid attribute in its header */ } *TupleDesc; -#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) +extern TupleDesc CreateTemplateTupleDesc(int natts, bool hasoid); -#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); +extern TupleDesc CreateTupleDesc(int natts, bool hasoid, + Form_pg_attribute *attrs); extern TupleDesc CreateTupleDescCopy(TupleDesc tupdesc); diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index f561dee66b1c58db453be10da83cd8c9e5d03943..652009104fe30c71c40507e1d7198012d3362914 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -37,7 +37,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: catversion.h,v 1.156 2002/08/31 17:14:28 tgl Exp $ + * $Id: catversion.h,v 1.157 2002/09/02 01:05:06 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 200208311 +#define CATALOG_VERSION_NO 200209011 #endif diff --git a/src/include/catalog/heap.h b/src/include/catalog/heap.h index f45c61515adb6dac3a1987967d3f7ba5a6ae33b3..b1f5dc8600c5645187ad3117ad2fa3428ffedd96 100644 --- a/src/include/catalog/heap.h +++ b/src/include/catalog/heap.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: heap.h,v 1.55 2002/08/02 18:15:09 tgl Exp $ + * $Id: heap.h,v 1.56 2002/09/02 01:05:06 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -41,7 +41,6 @@ extern Oid heap_create_with_catalog(const char *relname, TupleDesc tupdesc, char relkind, bool shared_relation, - bool relhasoids, bool allow_system_table_mods); extern void heap_drop_with_catalog(Oid rid); diff --git a/src/include/executor/executor.h b/src/include/executor/executor.h index 3fbf63567acc0c09f4a93268c6f5ecb65090add4..f2fa81857cdbd0a34ecb5f8c1fe36a37ca5622db 100644 --- a/src/include/executor/executor.h +++ b/src/include/executor/executor.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: executor.h,v 1.76 2002/08/30 23:59:46 tgl Exp $ + * $Id: executor.h,v 1.77 2002/09/02 01:05:06 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -122,7 +122,7 @@ extern void ExecInitScanTupleSlot(EState *estate, extern TupleTableSlot *ExecInitExtraTupleSlot(EState *estate); extern TupleTableSlot *ExecInitNullTupleSlot(EState *estate, TupleDesc tupType); -extern TupleDesc ExecTypeFromTL(List *targetList, hasoid_t withoid); +extern TupleDesc ExecTypeFromTL(List *targetList, bool hasoid); extern void SetChangedParamList(Plan *node, List *newchg); typedef struct TupOutputState diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index a64be7fcf2ae8489dabbbc1f5efee6f6cf9927f9..670c80a4030624d61245598864a77657d75489a7 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -8,7 +8,7 @@ * or in pg_config.h afterwards. Of course, if you edit pg_config.h, then your * changes will be overwritten the next time you run configure. * - * $Id: pg_config.h.in,v 1.29 2002/08/29 08:03:22 ishii Exp $ + * $Id: pg_config.h.in,v 1.30 2002/09/02 01:05:06 tgl Exp $ */ #ifndef PG_CONFIG_H @@ -298,12 +298,6 @@ /* #define ACLDEBUG */ /* #define RTDEBUG */ /* #define GISTDEBUG */ -/* - * DEBUG_TUPLE_ACCESS enables paranoid assertions during - * elimination of oids from the fixed sized part of HeapTupleHeader. - * This is expected to be undef'd after v7.3 release at the latest. - */ -#define DEBUG_TUPLE_ACCESS /* * defining unsafe floats will make float4 and float8 ops faster diff --git a/src/include/storage/bufpage.h b/src/include/storage/bufpage.h index a9fc0f7a2a243fdc7eb6f5dd1b3ffa848b6c5371..7a6080a1bcd0071ba39cddfa1cd0f7717b581a21 100644 --- a/src/include/storage/bufpage.h +++ b/src/include/storage/bufpage.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: bufpage.h,v 1.51 2002/08/06 19:37:10 tgl Exp $ + * $Id: bufpage.h,v 1.52 2002/09/02 01:05:06 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -97,12 +97,20 @@ typedef uint16 LocationIndex; * pd_lower - offset to start of free space. * pd_upper - offset to end of free space. * pd_special - offset to start of special space. - * pd_pagesize - size in bytes. - * Minimum possible page size is perhaps 64B to fit - * page header, opaque space and a minimal tuple; - * of course, in reality you want it much bigger. - * On the high end, we can only support pages up - * to 32KB because lp_off/lp_len are 15 bits. + * pd_pagesize_version - size in bytes and page layout version number. + * + * The page version number and page size are packed together into a single + * uint16 field. This is for historical reasons: before PostgreSQL 7.3, + * there was no concept of a page version number, and doing it this way + * lets us pretend that pre-7.3 databases have page version number zero. + * We constrain page sizes to be multiples of 256, leaving the low eight + * bytes available for a version number. + * + * Minimum possible page size is perhaps 64B to fit page header, opaque space + * and a minimal tuple; of course, in reality you want it much bigger, so + * the constraint on pagesize mod 256 is not an important restriction. + * On the high end, we can only support pages up to 32KB because lp_off/lp_len + * are 15 bits. */ typedef struct PageHeaderData { @@ -116,12 +124,18 @@ typedef struct PageHeaderData LocationIndex pd_lower; /* offset to start of free space */ LocationIndex pd_upper; /* offset to end of free space */ LocationIndex pd_special; /* offset to start of special space */ - uint16 pd_pagesize; + uint16 pd_pagesize_version; ItemIdData pd_linp[1]; /* beginning of line pointer array */ } PageHeaderData; typedef PageHeaderData *PageHeader; +/* + * Page layout version number 0 is for pre-7.3 Postgres releases. The + * current version number is 1, denoting a new HeapTupleHeader layout. + */ +#define PG_PAGE_LAYOUT_VERSION 1 + /* ---------------------------------------------------------------- * page support macros @@ -178,7 +192,7 @@ typedef PageHeaderData *PageHeader; ((char *) (&((PageHeader) (page))->pd_linp[0])) /* ---------------- - * macros to access opaque space + * macros to access page size info * ---------------- */ @@ -203,14 +217,32 @@ typedef PageHeaderData *PageHeader; * however, it can be called on a page for which there is no buffer. */ #define PageGetPageSize(page) \ - ((Size) ((PageHeader) (page))->pd_pagesize) + ((Size) (((PageHeader) (page))->pd_pagesize_version & (uint16) 0xFF00)) /* - * PageSetPageSize - * Sets the page size of a page. + * PageGetPageLayoutVersion + * Returns the page layout version of a page. + * + * this can only be called on a formatted page (unlike + * BufferGetPageSize, which can be called on an unformatted page). + * however, it can be called on a page for which there is no buffer. */ -#define PageSetPageSize(page, size) \ - (((PageHeader) (page))->pd_pagesize = (size)) +#define PageGetPageLayoutVersion(page) \ + (((PageHeader) (page))->pd_pagesize_version & 0x00FF) + +/* + * PageSetPageSizeAndVersion + * Sets the page size and page layout version number of a page. + * + * We could support setting these two values separately, but there's + * no real need for it at the moment. + */ +#define PageSetPageSizeAndVersion(page, size, version) \ +( \ + AssertMacro(((size) & 0xFF00) == (size)), \ + AssertMacro(((version) & 0x00FF) == (version)), \ + ((PageHeader) (page))->pd_pagesize_version = (size) | (version) \ +) /* ---------------- * page special data macros