head 1.19; access; symbols release_4_2:1.19 marc_alpha:1.15 aix_ok:1.15 Version_2_1:1.4; locks; strict; comment @ * @; 1.19 date 94.02.07.11.28.47; author aoki; state Exp; branches; next 1.18; 1.18 date 94.01.29.12.55.33; author aoki; state Exp; branches; next 1.17; 1.17 date 93.11.27.23.19.43; author marcel; state Exp; branches; next 1.16; 1.16 date 93.11.03.08.24.31; author aoki; state Exp; branches; next 1.15; 1.15 date 93.08.10.01.46.51; author marc; state Exp; branches; next 1.14; 1.14 date 92.04.03.01.01.45; author mer; state Exp; branches; next 1.13; 1.13 date 91.11.18.16.49.03; author hong; state Exp; branches; next 1.12; 1.12 date 91.11.08.15.40.04; author kemnitz; state Exp; branches; next 1.11; 1.11 date 91.08.11.18.48.55; author mao; state Exp; branches; next 1.10; 1.10 date 91.05.23.18.12.30; author kemnitz; state Exp; branches; next 1.9; 1.9 date 91.05.22.14.01.40; author kemnitz; state Exp; branches; next 1.8; 1.8 date 91.05.13.21.00.59; author kemnitz; state Exp; branches; next 1.7; 1.7 date 91.05.13.17.02.02; author kemnitz; state Exp; branches; next 1.6; 1.6 date 91.05.01.02.48.49; author cimarron; state Exp; branches; next 1.5; 1.5 date 91.04.28.09.17.22; author cimarron; state Exp; branches; next 1.4; 1.4 date 91.03.03.00.31.21; author mao; state Exp; branches; next 1.3; 1.3 date 91.02.28.20.55.06; author mao; state Exp; branches; next 1.2; 1.2 date 91.02.24.08.58.47; author mao; state Exp; branches; next 1.1; 1.1 date 91.01.29.15.18.47; author cimarron; state Exp; branches; next ; desc @reorganization of access method code 1/28/91 -cim @ 1.19 log @proto fixes @ text @/* ---------------------------------------------------------------- * FILE * indextuple.c * * DESCRIPTION * This file contains index tuple accessor and mutator * routines, as well as a few various tuple utilities. * * INTERFACE ROUTINES * index_formtuple * index_getsysattr * index_getattr * * NOTES * All the stupid ``GeneralResultXXX'' routines should be * eliminated and replaced with something simple and clean. * * old routines formituple, FormIndexTuple, AMgetattr have been * turned into macros in itup.h. IsValid predicates have been * macroized too. -cim 4/30/91 * * IDENTIFICATION * $Header: /faerie/aoki/postgres/src/backend/access/common/RCS/indextuple.c,v 1.18 1994/01/29 12:55:33 aoki Exp $ * ---------------------------------------------------------------- */ #include #include "tmp/c.h" #include "access/ibit.h" #include "access/itup.h" #include "access/heapam.h" #include "access/tupdesc.h" #include "access/attval.h" #include "access/tupmacs.h" #include "storage/form.h" #include "storage/itemptr.h" #include "rules/prs2locks.h" #include "utils/log.h" #include "utils/palloc.h" RcsId("$Header: /faerie/aoki/postgres/src/backend/access/common/RCS/indextuple.c,v 1.18 1994/01/29 12:55:33 aoki Exp $"); /* ---------------------------------------------------------------- * index_ tuple interface routines * ---------------------------------------------------------------- */ /* ---------------- * index_formtuple * ---------------- */ IndexTuple index_formtuple(numberOfAttributes, tupleDescriptor, value, null) AttributeNumber numberOfAttributes; TupleDescriptor tupleDescriptor; Datum value[]; char null[]; { register char *tp; /* tuple pointer */ IndexTuple tuple; /* return tuple */ Size size, hoff; int i, infomask = 0; bool hasnull = false; char tupmask = 0; if (numberOfAttributes > MaxIndexAttributeNumber) elog(WARN, "index_formtuple: numberOfAttributes of %d > %d", numberOfAttributes, MaxIndexAttributeNumber); for (i = 0; i < numberOfAttributes && !hasnull; i++) { if (null[i] != ' ') hasnull = true; } if (hasnull) infomask |= INDEX_NULL_MASK; hoff = IndexInfoFindDataOffset(infomask); size = hoff + ComputeDataSize(numberOfAttributes, tupleDescriptor, value, null); size = LONGALIGN(size); tp = (char *) palloc(size); tuple = (IndexTuple) tp; bzero(tp, (int)size); DataFill((Pointer) tp + hoff, numberOfAttributes, tupleDescriptor, value, null, &tupmask, (hasnull ? tp + sizeof *tuple : NULL)); /* * We do this because DataFill wants to initialize a "tupmask" which * is used for HeapTuples, but we want an indextuple infomask. The only * "relevent" info is the "has variable attributes" field, which is in * mask position 0x02. We have already set the null mask above. */ if (tupmask & 0x02) infomask |= INDEX_VAR_MASK; /* * Here we make sure that we can actually hold the size. We also want * to make sure that size is not aligned oddly. This actually is a * rather odd way to make sure the size is not too large overall. */ if (size & 0xE000) { elog(WARN, "index_formtuple: data takes %d bytes: too big", size); } infomask |= size; /* ---------------- * initialize metadata * ---------------- */ tuple->t_info = infomask; return (tuple); } /* ---------------- * fastgetiattr * * This is a newer version of fastgetiattr which attempts to be * faster by caching attribute offsets in the attribute descriptor. * * an alternate way to speed things up would be to cache offsets * with the tuple, but that seems more difficult unless you take * the storage hit of actually putting those offsets into the * tuple you send to disk. Yuck. * * This scheme will be slightly slower than that, but should * preform well for queries which hit large #'s of tuples. After * you cache the offsets once, examining all the other tuples using * the same attribute descriptor will go much quicker. -cim 5/4/91 * ---------------- */ char * fastgetiattr(tup, attnum, att, isnull) IndexTuple tup; unsigned attnum; struct attribute *att[]; bool *isnull; { register char *tp; /* ptr to att in tuple */ register char *bp; /* ptr to att in tuple */ int slow; /* do we have to walk nulls? */ register int data_off; /* tuple data offset */ /* ---------------- * sanity checks * ---------------- */ Assert(PointerIsValid(isnull)); Assert(attnum > 0); /* ---------------- * Three cases: * * 1: No nulls and no variable length attributes. * 2: Has a null or a varlena AFTER att. * 3: Has nulls or varlenas BEFORE att. * ---------------- */ *isnull = false; data_off = IndexTupleHasMinHeader(tup) ? sizeof *tup : IndexInfoFindDataOffset(tup->t_info); if (IndexTupleNoNulls(tup)) { /* first attribute is always at position zero */ if (attnum == 1) { return(fetchatt(att, (Pointer) tup + data_off)); } attnum--; if (att[attnum]->attcacheoff > 0) { return(fetchatt(att + attnum, (Pointer) tup + data_off + att[attnum]->attcacheoff)); } tp = (Pointer) tup + data_off; slow = 0; } else /* there's a null somewhere in the tuple */ { bp = (char *) tup + sizeof(*tup); /* "knows" t_bits are here! */ slow = 0; /* ---------------- * check to see if desired att is null * ---------------- */ attnum--; { if (att_isnull(attnum, bp)) { *isnull = true; return NULL; } } /* ---------------- * Now check to see if any preceeding bits are null... * ---------------- */ { register int i = 0; /* current offset in bp */ register int mask; /* bit in byte we're looking at */ register char n; /* current byte in bp */ register int byte, finalbit; byte = attnum >> 3; finalbit = attnum & 0x07; for (; i <= byte; i++) { n = bp[i]; if (i < byte) { /* check for nulls in any "earlier" bytes */ if ((~n) != 0) { slow++; break; } } else { /* check for nulls "before" final bit of last byte*/ mask = (finalbit << 1) - 1; if ((~n) & mask) slow++; } } } tp = (Pointer) tup + data_off; } /* now check for any non-fixed length attrs before our attribute */ if (!slow) { if (att[attnum]->attcacheoff > 0) { return(fetchatt(att + attnum, tp + att[attnum]->attcacheoff)); } else if (!IndexTupleAllFixed(tup)) { register int j = 0; for (j = 0; j < attnum && !slow; j++) if (att[j]->attlen < 1) slow = 1; } } /* * if slow is zero, and we got here, we know that we have a tuple with * no nulls. We also know that we have to initialize the remainder of * the attribute cached offset values. */ if (!slow) { register int j = 1; register long off; /* * need to set cache for some atts */ att[0]->attcacheoff = 0; while (att[j]->attcacheoff > 0) j++; off = att[j-1]->attcacheoff + att[j-1]->attlen; for (; j < attnum + 1; j++) { /* * Fix me when going to a machine with more than a four-byte * word! */ switch(att[j]->attlen) { case -1: off = INTALIGN(off); break; case sizeof(char): break; case sizeof(short): off = SHORTALIGN(off); break; case sizeof(int32): off = INTALIGN(off); break; default: if (att[j]->attlen > sizeof(int32)) off = LONGALIGN(off); else elog(WARN, "fastgetiattr: attribute %d has len %d", j, att[j]->attlen); break; } att[j]->attcacheoff = off; off += att[j]->attlen; } return(fetchatt(att + attnum, tp + att[attnum]->attcacheoff)); } else { register bool usecache = true; register int off = 0; register int savelen; register int i; /* * Now we know that we have to walk the tuple CAREFULLY. */ for (i = 0; i < attnum; i++) { if (!IndexTupleNoNulls(tup)) { if (att_isnull(i, bp)) { usecache = false; continue; } } if (usecache && att[i]->attcacheoff > 0) { off = att[i]->attcacheoff; if (att[i]->attlen == -1) { usecache = false; } else continue; } if (usecache) att[i]->attcacheoff = off; switch(att[i]->attlen) { case sizeof(char): off++; break; case sizeof(short): off = SHORTALIGN(off + sizeof(short)); break; case -1: usecache = false; off = INTALIGN(off); off += VARSIZE(tp + off); break; default: if (att[i]->attlen > sizeof(int32)) off = LONGALIGN(off + att[i]->attlen); else elog(WARN, "fastgetiattr2: attribute %d has len %d", i, att[i]->attlen); break; } } return(fetchatt(att + attnum, tp + off)); } } /* ---------------- * index_getsysattr * ---------------- */ AttributeValue index_getsysattr(tuple, attributeNumber) IndexTuple tuple; int attributeNumber; { static Datum datum; switch (attributeNumber) { case IndxRuleLockAttributeNumber: elog(NOTICE, "index_getsysattr: Rule locks are always NULL"); return PointerGetDatum((Pointer) NULL); break; case IndxBaseTupleIdAttributeNumber: bcopy((char *) &tuple->t_tid, (char *) &datum, sizeof datum); return datum; break; default: elog(WARN, "IndexTupleGetAttributeValue: undefined attnum %d", attributeNumber); } return((AttributeValue) NULL); } /* ---------------- * index_getattr * ---------------- */ AttributeValue IndexTupleGetAttributeValue(tuple, attNum, tupleDescriptor, isNullOutP) IndexTuple tuple; AttributeNumber attNum; TupleDescriptor tupleDescriptor; Boolean *isNullOutP; { /* ---------------- * handle normal attributes * ---------------- */ if (attNum > 0) return (AttributeValue) fastgetiattr(tuple, attNum, tupleDescriptor, isNullOutP); /* ---------------- * otherwise handle system attributes * ---------------- */ *isNullOutP = '\0'; return index_getsysattr(tuple, attNum); } Pointer index_getattr(tuple, attNum, tupDesc, isNullOutP) IndexTuple tuple; AttributeNumber attNum; TupleDescriptor tupDesc; Boolean *isNullOutP; { Datum datum; datum = IndexTupleGetAttributeValue(tuple, attNum, tupDesc, isNullOutP); return DatumGetPointer(datum); } /* ---------------------------------------------------------------- * misc index result stuff (XXX OBSOLETE ME!) * ---------------------------------------------------------------- */ GeneralInsertIndexResult ItemPointerFormGeneralInsertIndexResult(pointer, lock) ItemPointer pointer; RuleLock lock; { GeneralInsertIndexResult result; Assert(ItemPointerIsValid(pointer)); /* XXX Assert(RuleLockIsValid(lock)); locks don't work yet */ result = (GeneralInsertIndexResult) palloc(sizeof *result); result->pointerData = *pointer; result->lock = lock; return (result); } InsertIndexResult ItemPointerFormInsertIndexResult(pointer, lock, offset) ItemPointer pointer; RuleLock lock; double offset; { InsertIndexResult result; Assert(ItemPointerIsValid(pointer)); /* XXX Assert(RuleLockIsValid(lock)); locks don't work yet */ /* Assert(InsertOffsetIsValid(offset)); */ result = (InsertIndexResult) palloc(sizeof *result); result->pointerData = *pointer; result->lock = lock; result->offset = offset; return (result); } GeneralRetrieveIndexResult ItemPointerFormGeneralRetrieveIndexResult(heapItemPointer) ItemPointer heapItemPointer; { GeneralRetrieveIndexResult result; Assert(ItemPointerIsValid(heapItemPointer)); result = (GeneralRetrieveIndexResult) palloc(sizeof *result); result->heapItemData = *heapItemPointer; return (result); } RetrieveIndexResult ItemPointerFormRetrieveIndexResult(indexItemPointer, heapItemPointer) ItemPointer indexItemPointer; ItemPointer heapItemPointer; { RetrieveIndexResult result; Assert(ItemPointerIsValid(indexItemPointer)); Assert(ItemPointerIsValid(heapItemPointer)); result = (RetrieveIndexResult) palloc(sizeof *result); result->indexItemData = *indexItemPointer; result->heapItemData = *heapItemPointer; return (result); } /* * Takes an infomask as argument (primarily because this needs to be usable * at index_formtuple time so enough space is allocated). * * Change me if adding an attribute to IndexTuples!!!!!!!!!!! */ Size IndexInfoFindDataOffset(t_info) unsigned short t_info; { if (!(t_info & (INDEX_NULL_MASK | INDEX_RULE_MASK))) return((Size) sizeof(IndexTupleData)); else { Size size = sizeof(IndexTupleData); if (t_info & INDEX_NULL_MASK) { size += sizeof(IndexAttributeBitMapData); } if (t_info & INDEX_RULE_MASK) { size = INTALIGN(size) + sizeof(IndexTupleRuleLock) + sizeof(char); } return(INTALIGN(size)); } } /* * Copies source into target. If *target == NULL, we palloc space; otherwise * we assume we have space that is already palloc'ed. */ void CopyIndexTuple(source, target) IndexTuple source, *target; { Size size, hoff; IndexTuple ret; size = IndexTupleSize(source); if (*target == NULL) { *target = (IndexTuple) palloc(size); } ret = *target; bcopy(source, ret, size); } /* for debugging purpose only. will only be called in dbx. */ int indexTupleHeaderSize() { return(sizeof(IndexTupleData)); } @ 1.18 log @header stuff @ text @d23 1 a23 1 * $Header: /faerie/aoki/postgres/src/backend/access/common/RCS/indextuple.c,v 1.17 1993/11/27 23:19:43 marcel Exp aoki $ d32 1 d44 1 a44 1 RcsId("$Header: /faerie/aoki/postgres/src/backend/access/common/RCS/indextuple.c,v 1.17 1993/11/27 23:19:43 marcel Exp aoki $"); @ 1.17 log @fixed minor bug in CopyIndexTuple @ text @d23 1 a23 1 * $Header: /usr/local/devel/marcel/postgres/src/backend/access/common/RCS/indextuple.c,v 1.16 1993/11/03 08:24:31 aoki Exp marcel $ d26 3 d43 1 a43 1 RcsId("$Header: /usr/local/devel/marcel/postgres/src/backend/access/common/RCS/indextuple.c,v 1.16 1993/11/03 08:24:31 aoki Exp marcel $"); @ 1.16 log @fix broken prs2 protos remove rules/rlock.h, access/xcxt.h, access/newam.h (dead headers with residual dependencies) @ text @d23 1 a23 1 * $Header: /faerie/aoki/postgres/src/backend/access/common/RCS/indextuple.c,v 1.15 1993/08/10 01:46:51 marc Exp aoki $ d40 1 a40 1 RcsId("$Header: /faerie/aoki/postgres/src/backend/access/common/RCS/indextuple.c,v 1.15 1993/08/10 01:46:51 marc Exp aoki $"); d570 1 a570 1 *target = ret = (IndexTuple) palloc(size); d573 1 @ 1.15 log @alpha port @ text @d23 1 a23 1 * $Header: /usr/local/devel/postgres.alpha.merge/src/backend/access/common/RCS/indextuple.c,v 1.14 1992/04/03 01:01:45 mer Exp marc $ d35 1 a35 1 #include "rules/rlock.h" d40 1 a40 1 RcsId("$Header: /usr/local/devel/postgres.alpha.merge/src/backend/access/common/RCS/indextuple.c,v 1.14 1992/04/03 01:01:45 mer Exp marc $"); @ 1.14 log @no long write varlena size to disk twice so don't need to add sizeof(long) @ text @d23 1 a23 1 * $Header: /u/mer/pg/src/access/common/RCS/indextuple.c,v 1.13 1991/11/18 16:49:03 hong Exp mer $ d40 1 a40 1 RcsId("$Header: /u/mer/pg/src/access/common/RCS/indextuple.c,v 1.13 1991/11/18 16:49:03 hong Exp mer $"); d291 19 a309 3 case sizeof(char) : break; case sizeof(short): off = SHORTALIGN(off); break; default : off = LONGALIGN(off); break; d361 1 a361 1 off = LONGALIGN(off); d365 6 a370 1 off = LONGALIGN(off + att[i]->attlen); d547 1 a547 1 size = LONGALIGN(size) + sizeof(IndexTupleRuleLock) + sizeof(char); d549 1 a549 1 return(LONGALIGN(size)); @ 1.13 log @added a function to get tuple header sizes so it can be called in dbx @ text @d23 1 a23 1 * $Header: RCS/indextuple.c,v 1.12 91/11/08 15:40:04 kemnitz Exp Locker: hong $ d40 1 a40 1 RcsId("$Header: RCS/indextuple.c,v 1.12 91/11/08 15:40:04 kemnitz Exp Locker: hong $"); d345 2 a346 2 off = LONGALIGN(off) + sizeof(long); off += PSIZE(tp + off); @ 1.12 log @fixed prototypes @ text @d23 1 a23 1 * $Header: RCS/indextuple.c,v 1.11 91/08/11 18:48:55 mao Exp Locker: kemnitz $ d40 1 a40 1 RcsId("$Header: RCS/indextuple.c,v 1.11 91/08/11 18:48:55 mao Exp Locker: kemnitz $"); d553 9 @ 1.11 log @took out sanity check that did an elog -- shd have been an Assert, but code will dump core immediately afterwards, anyway. @ text @d23 1 a23 1 * $Header: /users/mao/postgres/src/access/common/RCS/indextuple.c,v 1.10 1991/05/23 18:12:30 kemnitz Exp mao $ d40 1 a40 1 RcsId("$Header: /users/mao/postgres/src/access/common/RCS/indextuple.c,v 1.10 1991/05/23 18:12:30 kemnitz Exp mao $"); d393 1 a393 1 int attNum; @ 1.10 log @got rid of has return(e); and return; @ text @d23 1 a23 1 * $Header: RCS/indextuple.c,v 1.9 91/05/22 14:01:40 kemnitz Exp Locker: kemnitz $ d40 1 a40 1 RcsId("$Header: RCS/indextuple.c,v 1.9 91/05/22 14:01:40 kemnitz Exp Locker: kemnitz $"); a396 7 /* ---------------- * sanity check * ---------------- */ if (tuple == NULL) elog(WARN, "IndexTupleGetAttributeValue: called with NULL tuple"); @ 1.9 log @changed indextuple header somewhat. @ text @d23 1 a23 1 * $Header: RCS/indextuple.c,v 1.8 91/05/13 21:00:59 kemnitz Exp Locker: kemnitz $ d40 1 a40 1 RcsId("$Header: RCS/indextuple.c,v 1.8 91/05/13 21:00:59 kemnitz Exp Locker: kemnitz $"); d383 1 @ 1.8 log @fastgetiattr now uses attribute caching @ text @d23 1 a23 1 * $Header: RCS/indextuple.c,v 1.7 91/05/13 17:02:02 kemnitz Exp Locker: kemnitz $ d40 1 a40 1 RcsId("$Header: RCS/indextuple.c,v 1.7 91/05/13 17:02:02 kemnitz Exp Locker: kemnitz $"); d60 5 a64 3 Size size; size = sizeof *tuple; d69 11 a79 1 size += ComputeDataSize(numberOfAttributes, tupleDescriptor, value, null); d81 1 a81 1 d86 1 a86 1 DataFill((Pointer) &tp[sizeof *tuple], d91 25 a115 3 &tuple->t_infomask, &tuple->bits.bits[0]); d120 1 a120 4 tuple->t_size = size; tuple->t_locktype = MEM_INDX_RULE_LOCK; tuple->t_lock.l_lock = NULL; d127 1 a127 1 * This is a newer version of fastgetattr which attempts to be d152 1 d163 7 a169 7 * Three cases: * * 1: No nulls and no variable length attributes. * 2: Has a null or a varlena AFTER att. * 3: Has nulls or varlenas BEFORE att. * ---------------- */ d172 2 d181 1 a181 1 return(fetchatt(att, (Pointer) tup + sizeof(*tup))); d187 2 a188 2 return(fetchatt(att + attnum, (Pointer) tup + sizeof(*tup) + att[attnum]->attcacheoff)); d191 1 a191 1 tp = (Pointer) tup + sizeof(*tup); d197 1 a197 1 bp = (char *) tup->bits.bits; d241 1 d408 1 a408 2 return (AttributeValue) d505 54 @ 1.7 log @indextuples now have t_infomask, which is populated by DataFill. @ text @d23 1 a23 1 * $Header: RCS/indextuple.c,v 1.6 91/05/01 02:48:49 cimarron Exp Locker: kemnitz $ d31 1 d40 1 a40 1 RcsId("$Header: RCS/indextuple.c,v 1.6 91/05/01 02:48:49 cimarron Exp Locker: kemnitz $"); d95 13 d110 7 a116 6 AttributeValue fastgetiattr(tuple, attributeNumber, tupleDescriptor, isNullOutP) IndexTuple tuple; int attributeNumber; TupleDescriptor tupleDescriptor; Boolean *isNullOutP; d118 3 a120 8 int bitmask; bits8 bitMap; Attribute *ap; /* attribute pointer */ char *tp; /* tuple pointer */ int finalbit; int bitrange; AttributeValue value; AttributeNumber attributeOffset; a121 3 /* XXX quick hack to clear garbage in filler */ bzero(&value, sizeof(AttributeValue)); d123 1 a123 1 * check for null attributes d126 4 a129 10 attributeOffset = attributeNumber - 1; finalbit = 1 << attributeOffset; bitMap = tuple->bits.bits[0]; if (! (bitMap & finalbit)) { if (PointerIsValid(isNullOutP)) *isNullOutP = (Boolean)1; value = PointerGetDatum(NULL); return (value); } d131 7 a137 8 * now walk the tuple descriptor until we get to the attribute * we want. we advance tp the length of each attribute we advance * so tp points to our attribute when we're done. * ---------------- */ *isNullOutP = (Boolean)0; ap = &tupleDescriptor->data[0]; tp = (char *)tuple + sizeof *tuple; d139 21 a159 16 bitrange = finalbit >> 1; for (bitmask = 1; bitmask <= bitrange; bitmask <<= 1) { if (bitMap & bitmask) if ((*ap)->attlen < 0) { tp = (char *) LONGALIGN(tp) + sizeof (long); tp += PSIZE(tp); } else if ((*ap)->attlen >= 3) { tp = (char *) LONGALIGN(tp); tp += (*ap)->attlen; } else if ((*ap)->attlen == 2) tp = (char *) SHORTALIGN(tp + 2); else if (!(*ap)->attlen) elog(WARN, "amgetattr: 0 attlen"); else tp++; ap++; d161 8 d170 37 a206 7 /* ---------------- * handle variable length attributes * ---------------- */ if ((*ap)->attlen < 0) { value = PointerGetDatum((char *)LONGALIGN(tp + sizeof (long))); return (value); d209 30 a238 4 if (!(*ap)->attbyval) { /* ---------------- * by value attributes * ---------------- d240 26 a265 17 if ((*ap)->attlen >= 3) { value = PointerGetDatum((char *)LONGALIGN(tp)); } else if ((*ap)->attlen == 2) { value = PointerGetDatum((char *)SHORTALIGN(tp)); } else { value = PointerGetDatum(tp); } } else { /* ---------------- * by reference attributes * * We can't assume that ptr alignment is correct or that casting * will work right; we used bcopy() to write the datum, so we * use bcopy() to read it. * ---------------- */ bcopy(tp, (char *) &value, sizeof value); d267 6 d274 14 a287 2 return (value); } d289 9 d299 23 d374 1 @ 1.6 log @round II of converting simple functions to macros + code cleaning in general @ text @d23 1 a23 1 * $Header: RCS/indextuple.c,v 1.5 91/04/28 09:17:22 cimarron Exp Locker: cimarron $ d39 1 a39 1 RcsId("$Header: RCS/indextuple.c,v 1.5 91/04/28 09:17:22 cimarron Exp Locker: cimarron $"); d78 1 @ 1.5 log @Converted IsValid code into macros and added an improved NodeIsType scheme @ text @a13 4 * OLD INTERFACE FUNCTIONS * formituple, FormIndexTuple * AMgetattr * d18 4 d23 1 a23 1 * $Header: RCS/indextuple.c,v 1.4 91/03/03 00:31:21 mao Exp Locker: cimarron $ d39 1 a39 1 RcsId("$Header: RCS/indextuple.c,v 1.4 91/03/03 00:31:21 mao Exp Locker: cimarron $"); a41 193 * index tuple predicates * ---------------------------------------------------------------- */ /* * IndexTupleIsValid(tuple) is now a macro in itup.h -cim 4/27/91 */ ItemPointer IndexTupleGetRuleLockItemPointer(tuple) IndexTuple tuple; { Assert(IndexTupleIsValid(tuple)); return (&tuple->t_lock.l_ltid); } RuleLock IndexTupleGetRuleLock(tuple) IndexTuple tuple; { Assert(IndexTupleIsValid(tuple)); return (tuple->t_lock.l_lock); } /* * IndexAttributeBitMapIsValid(bits) is now a macro in ibit.h -cim 4/27/91 */ IndexAttributeBitMap IndexTupleGetIndexAttributeBitMap(tuple) IndexTuple tuple; { Assert(IndexTupleIsValid(tuple)); return (&tuple->bits); } Form IndexTupleGetForm(tuple) IndexTuple tuple; { Assert(IndexTupleIsValid(tuple)); return ((Form) &tuple[1]); } /* ---------------------------------------------------------------- * misc index result stuff (XXX OBSOLETE ME!) * ---------------------------------------------------------------- */ /* * GeneralInsertIndexResultIsValid(result) * InsertIndexResultIsValid(result) * GeneralRetrieveIndexResultIsValid(result) * RetrieveIndexResultIsValid(result) * * .. are all macros in itup.h -cim 4/27/91 */ ItemPointer GeneralInsertIndexResultGetItemPointer(result) GeneralInsertIndexResult result; { Assert(GeneralInsertIndexResultIsValid(result)); return (&result->pointerData); } RuleLock GeneralInsertIndexResultGetRuleLock(result) GeneralInsertIndexResult result; { Assert(GeneralInsertIndexResultIsValid(result)); return (result->lock); } GeneralInsertIndexResult ItemPointerFormGeneralInsertIndexResult(pointer, lock) ItemPointer pointer; RuleLock lock; { GeneralInsertIndexResult result; Assert(ItemPointerIsValid(pointer)); /* XXX Assert(RuleLockIsValid(lock)); locks don't work yet */ result = (GeneralInsertIndexResult) palloc(sizeof *result); result->pointerData = *pointer; result->lock = lock; return (result); } ItemPointer InsertIndexResultGetItemPointer(result) InsertIndexResult result; { Assert(InsertIndexResultIsValid(result)); return (&result->pointerData); } RuleLock InsertIndexResultGetRuleLock(result) InsertIndexResult result; { Assert(InsertIndexResultIsValid(result)); return (result->lock); } double InsertIndexResultGetInsertOffset(result) InsertIndexResult result; { Assert(InsertIndexResultIsValid(result)); return (result->offset); } InsertIndexResult ItemPointerFormInsertIndexResult(pointer, lock, offset) ItemPointer pointer; RuleLock lock; double offset; { InsertIndexResult result; Assert(ItemPointerIsValid(pointer)); /* XXX Assert(RuleLockIsValid(lock)); locks don't work yet */ /* Assert(InsertOffsetIsValid(offset)); */ result = (InsertIndexResult) palloc(sizeof *result); result->pointerData = *pointer; result->lock = lock; result->offset = offset; return (result); } ItemPointer GeneralRetrieveIndexResultGetHeapItemPointer(result) GeneralRetrieveIndexResult result; { Assert(GeneralRetrieveIndexResultIsValid(result)); return (&result->heapItemData); } GeneralRetrieveIndexResult ItemPointerFormGeneralRetrieveIndexResult(heapItemPointer) ItemPointer heapItemPointer; { GeneralRetrieveIndexResult result; Assert(ItemPointerIsValid(heapItemPointer)); result = (GeneralRetrieveIndexResult) palloc(sizeof *result); result->heapItemData = *heapItemPointer; return (result); } ItemPointer RetrieveIndexResultGetIndexItemPointer(result) RetrieveIndexResult result; { Assert(RetrieveIndexResultIsValid(result)); return (&result->indexItemData); } ItemPointer RetrieveIndexResultGetHeapItemPointer(result) RetrieveIndexResult result; { Assert(RetrieveIndexResultIsValid(result)); return (&result->heapItemData); } RetrieveIndexResult ItemPointerFormRetrieveIndexResult(indexItemPointer, heapItemPointer) ItemPointer indexItemPointer; ItemPointer heapItemPointer; { RetrieveIndexResult result; Assert(ItemPointerIsValid(indexItemPointer)); Assert(ItemPointerIsValid(heapItemPointer)); result = (RetrieveIndexResult) palloc(sizeof *result); result->indexItemData = *indexItemPointer; result->heapItemData = *heapItemPointer; return (result); } /* ---------------------------------------------------------------- d63 1 a63 1 elog(WARN, "FormIndexTuple: numberOfAttributes of %d > %d", d271 1 a271 1 * old interface routines d274 5 a278 6 IndexTuple FormIndexTuple(numberOfAttributes, tupleDescriptor, value, null) AttributeNumber numberOfAttributes; TupleDescriptor tupleDescriptor; Datum value[]; char null[]; d280 10 a289 2 return index_formtuple(numberOfAttributes, tupleDescriptor, value, null); d292 5 a296 6 IndexTuple formituple(numberOfAttributes, tupleDescriptor, value, null) AttributeNumber numberOfAttributes; TupleDescriptor tupleDescriptor; Datum value[]; char null[]; d298 12 a309 2 return index_formtuple(numberOfAttributes, tupleDescriptor, value, null); d312 3 a314 6 Pointer AMgetattr(tuple, attNum, tupleDescriptor, isNullOutP) IndexTuple tuple; AttributeNumber attNum; TupleDescriptor tupleDescriptor; Boolean *isNullOutP; d316 25 a340 1 return index_getattr(tuple, attNum, tupleDescriptor, isNullOutP); @ 1.4 log @get arbitrary-length index keys working @ text @d23 1 a23 1 * $Header: RCS/indextuple.c,v 1.3 91/02/28 20:55:06 mao Exp $ d39 1 a39 1 RcsId("$Header: RCS/indextuple.c,v 1.3 91/02/28 20:55:06 mao Exp $"); a44 7 bool IndexTupleIsValid(tuple) IndexTuple tuple; { return (bool) PointerIsValid(tuple); } d46 5 a66 7 bool IndexAttributeBitMapIsValid(bits) IndexAttributeBitMap bits; { return (bool) PointerIsValid(bits); } d68 4 a92 7 bool GeneralInsertIndexResultIsValid(result) GeneralInsertIndexResult result; { return (bool) PointerIsValid(result); } d94 8 a101 23 bool InsertIndexResultIsValid(result) InsertIndexResult result; { return (bool) PointerIsValid(result); } bool GeneralRetrieveIndexResultIsValid(result) GeneralRetrieveIndexResult result; { return (bool) PointerIsValid(result); } bool RetrieveIndexResultIsValid(result) RetrieveIndexResult result; { return (bool) PointerIsValid(result); } @ 1.3 log @typecast calls to palloc @ text @d23 1 a23 1 * $Header: RCS/indextuple.c,v 1.2 91/02/24 08:58:47 mao Exp Locker: mao $ d39 1 a39 1 RcsId("$Header: RCS/indextuple.c,v 1.2 91/02/24 08:58:47 mao Exp Locker: mao $"); d287 1 @ 1.2 log @index tuples now store their sizes in the tuple data -- turned out to be necessary for extensibility of the indexed access methods @ text @d23 1 a23 1 * $Header: RCS/indextuple.c,v 1.1 91/01/29 15:18:47 cimarron Exp Locker: mao $ d39 1 a39 1 RcsId("$Header: RCS/indextuple.c,v 1.1 91/01/29 15:18:47 cimarron Exp Locker: mao $"); d288 1 a288 1 tp = palloc(size); @ 1.1 log @Initial revision @ text @d23 1 a23 1 * $Header$ d39 1 a39 1 RcsId("$Header$"); d300 1 a300 1 * initialize rule lock information d303 1 @