head 1.17; access; symbols release_4_2:1.17 aix_ok:1.16 Version_2_1:1.2; locks; strict; comment @ * @; 1.17 date 94.02.07.11.29.46; author aoki; state Exp; branches; next 1.16; 1.16 date 93.01.16.03.14.59; author aoki; state Exp; branches; next 1.15; 1.15 date 93.01.05.02.31.00; author aoki; state Exp; branches; next 1.14; 1.14 date 92.12.22.01.57.39; author aoki; state Exp; branches; next 1.13; 1.13 date 92.08.21.16.26.56; author mao; state Exp; branches; next 1.12; 1.12 date 91.11.08.15.39.50; author kemnitz; state Exp; branches; next 1.11; 1.11 date 91.06.03.21.40.20; author kemnitz; state Exp; branches; next 1.10; 1.10 date 91.06.03.15.43.33; author kemnitz; state Exp; branches; next 1.9; 1.9 date 91.06.03.15.33.29; author kemnitz; state Exp; branches; next 1.8; 1.8 date 91.06.03.03.56.16; author kemnitz; state Exp; branches; next 1.7; 1.7 date 91.06.03.03.00.47; author kemnitz; state Exp; branches; next 1.6; 1.6 date 91.05.01.02.48.47; author cimarron; state Exp; branches; next 1.5; 1.5 date 91.04.20.06.17.35; author kemnitz; state Exp; branches; next 1.4; 1.4 date 91.04.20.03.47.09; author kemnitz; state Exp; branches; next 1.3; 1.3 date 91.04.19.05.35.49; author kemnitz; state Exp; branches; next 1.2; 1.2 date 91.02.06.18.01.48; author cimarron; state Exp; branches; next 1.1; 1.1 date 91.01.29.15.18.44; author cimarron; state Exp; branches; next ; desc @reorganization of access method code 1/28/91 -cim @ 1.17 log @casting to shut up gcc @ text @/* ---------------------------------------------------------------- * FILE * heapvalid.c * * DESCRIPTION * heap tuple qualification validity checking code * * INTERFACE ROUTINES * heap_satisifies * heap_keytest * TupleUpdatedByCurXactAndCmd * * OLD INTERFACE ROUTINES (turned into macros in valid.h -cim 4/30/91) * amvalidtup * ItemIdHasValidHeapTupleForQualification * keytest_tupdesc * keytest * * NOTES * * IDENTIFICATION * $Header: /import/faerie/faerie/aoki/postgres/src/backend/access/common/RCS/heapvalid.c,v 1.16 1993/01/16 03:14:59 aoki Exp aoki $ * ---------------------------------------------------------------- */ #include "tmp/c.h" #include "access/htup.h" #include "access/skey.h" #include "access/tqual.h" #include "access/valid.h" #include "access/xact.h" #include "storage/buf.h" #include "storage/bufmgr.h" #include "storage/bufpage.h" #include "storage/itemid.h" #include "storage/page.h" #include "fmgr.h" #include "utils/log.h" #include "utils/rel.h" RcsId("$Header: /import/faerie/faerie/aoki/postgres/src/backend/access/common/RCS/heapvalid.c,v 1.16 1993/01/16 03:14:59 aoki Exp aoki $"); /* ---------------- * heap_keytest * * Test a heap tuple with respect to a scan key. * ---------------- */ bool heap_keytest(t, tupdesc, nkeys, keys) HeapTuple t; TupleDescriptor tupdesc; int nkeys; struct skey keys[]; { Boolean isnull; DATUM atp; int test; for (; nkeys--; keys++) { atp = heap_getattr(t, InvalidBuffer, keys->sk_attnum, tupdesc, &isnull); if (isnull) /* XXX eventually should check if SK_ISNULL */ return false; if (keys->sk_flags & SK_COMMUTE) test = (long) FMGR_PTR2(keys->func, keys->sk_opr, keys->sk_data, atp); else test = (long) FMGR_PTR2(keys->func, keys->sk_opr, atp, keys->sk_data); if (!test == !(keys->sk_flags & SK_NEGATE)) return false; } return true; } /* ---------------- * heap_tuple_satisfies * * Returns a valid HeapTuple if it satisfies the timequal and keytest. * Returns NULL otherwise. Used to be heap_satisifies (sic) which * returned a boolean. It now returns a tuple so that we can avoid doing two * PageGetItem's per tuple. * * Complete check of validity including LP_CTUP and keytest. * This should perhaps be combined with valid somehow in the * future. (Also, additional rule tests/time range tests.) * * on 8/21/92 mao says: i rearranged the tests here to do keytest before * SatisfiesTimeQual. profiling indicated that even for vacuumed relations, * time qual checking was more expensive than key testing. time qual is * least likely to fail, too. we should really add the time qual test to * the restriction and optimize it in the normal way. this has interactions * with joey's expensive function work. * ---------------- */ HeapTuple heap_tuple_satisfies(itemId, relation, disk_page, qual, nKeys, key) ItemId itemId; Relation relation; PageHeader disk_page; TimeQual qual; ScanKeySize nKeys; ScanKey key; { HeapTuple tuple; bool res; if (! ItemIdIsUsed(itemId) || ItemIdIsLock(itemId)) return NULL; tuple = (HeapTuple) PageGetItem((Page) disk_page, itemId); if (key != NULL) res = keytest(tuple, relation, nKeys, (struct skey *) key); else res = TRUE; if (res && (relation->rd_rel->relkind == 'u' || HeapTupleSatisfiesTimeQual(tuple,qual))) return tuple; return (HeapTuple) NULL; } /* ---------------- * TupleUpdatedByCurXactAndCmd * ---------------- */ bool TupleUpdatedByCurXactAndCmd(t) HeapTuple t; { if (TransactionIdEquals((TransactionId) t->t_xmax, GetCurrentTransactionId()) && t->t_cmax == (CID) GetCurrentCommandId()) return true; return false; } @ 1.16 log @removed references to utils/fmgr.h and parser/parse.h @ text @d22 1 a22 1 * $Header: /home2/aoki/postgres/src/backend/access/common/RCS/heapvalid.c,v 1.15 1993/01/05 02:31:00 aoki Exp aoki $ d43 1 a43 1 RcsId("$Header: /home2/aoki/postgres/src/backend/access/common/RCS/heapvalid.c,v 1.15 1993/01/05 02:31:00 aoki Exp aoki $"); d71 2 a72 2 test = (int) FMGR_PTR2(keys->func, keys->sk_opr, keys->sk_data, atp); d74 1 a74 1 test = (int) FMGR_PTR2(keys->func, keys->sk_opr, @ 1.15 log @changed direct function-ptr jumps to use FMGR_PTR2 macro so we can find them later.. @ text @d22 1 a22 1 * $Header: /home2/aoki/postgres/src/backend/access/common/RCS/heapvalid.c,v 1.14 1992/12/22 01:57:39 aoki Exp aoki $ d39 1 a39 1 #include "utils/fmgr.h" d43 1 a43 1 RcsId("$Header: /home2/aoki/postgres/src/backend/access/common/RCS/heapvalid.c,v 1.14 1992/12/22 01:57:39 aoki Exp aoki $"); @ 1.14 log @checkin for untrusted functions @ text @d22 1 a22 1 * $Header: /usr/local/dev/postgres/mastertree/newconf/RCS/heapvalid.c,v 1.13 1992/08/21 16:26:56 mao Exp $ d43 1 a43 1 RcsId("$Header: /usr/local/dev/postgres/mastertree/newconf/RCS/heapvalid.c,v 1.13 1992/08/21 16:26:56 mao Exp $"); d71 2 a72 3 test = (keys->func != (ScanKeyFunc) NULL) ? (int) (*(keys->func)) (keys->sk_data, atp) : (int) fmgr(keys->sk_opr, keys->sk_data, atp); d74 2 a75 3 test = (keys->func != (ScanKeyFunc) NULL) ? (int) (*(keys->func)) (atp, keys->sk_data) : (int) fmgr(keys->sk_opr, atp, keys->sk_data); @ 1.13 log @reorganize test in heap_tuple_satisfies for efficiency @ text @d22 1 a22 1 * $Header: /usr/local/dev/postgres/mastertree/newconf/RCS/heapvalid.c,v 1.12 1991/11/08 15:39:50 kemnitz Exp $ d43 1 a43 1 RcsId("$Header: /usr/local/dev/postgres/mastertree/newconf/RCS/heapvalid.c,v 1.12 1991/11/08 15:39:50 kemnitz Exp $"); d71 3 a73 1 test = (int) (*(keys->func)) (keys->sk_data, atp); d75 3 a77 1 test = (int) (*(keys->func)) (atp, keys->sk_data); @ 1.12 log @fixed prototypes. ,. @ text @d22 1 a22 1 * $Header: RCS/heapvalid.c,v 1.11 91/06/03 21:40:20 kemnitz Exp $ d43 1 a43 1 RcsId("$Header: RCS/heapvalid.c,v 1.11 91/06/03 21:40:20 kemnitz Exp $"); d93 7 d113 1 d115 1 a115 2 if (! ItemIdIsUsed(itemId) || ItemIdIsContinuation(itemId) || ItemIdIsLock(itemId)) d120 8 a127 8 if (relation->rd_rel->relkind == 'u' || HeapTupleSatisfiesTimeQual(tuple,qual)) { if (key == NULL) return tuple; else if (keytest(tuple, relation, nKeys, (struct skey *) key)) return tuple; } @ 1.11 log @sped up heap_satisfies somewhat. @ text @d22 1 a22 1 * $Header: RCS/heapvalid.c,v 1.10 91/06/03 15:43:33 kemnitz Exp Locker: kemnitz $ d43 1 a43 1 RcsId("$Header: RCS/heapvalid.c,v 1.10 91/06/03 15:43:33 kemnitz Exp Locker: kemnitz $"); d103 1 a103 1 struct skey *key; d111 1 a111 1 tuple = (HeapTuple) PageGetItem(disk_page, itemId); d118 1 a118 1 else if (keytest(tuple, relation, nKeys, key)) d133 2 a134 1 if (TransactionIdEquals(t->t_xmax, GetCurrentTransactionId()) && @ 1.10 log @fixed compile error @ text @d22 1 a22 1 * $Header: RCS/heapvalid.c,v 1.9 91/06/03 15:33:29 kemnitz Exp Locker: kemnitz $ d36 1 d43 1 a43 1 RcsId("$Header: RCS/heapvalid.c,v 1.9 91/06/03 15:33:29 kemnitz Exp Locker: kemnitz $"); d86 2 a87 2 * Returns NULL otherwise. Used to be heap_satisifies which returned a * boolean. It now returns a tuple so that we can avoid doing two d97 1 a97 1 heap_tuple_satisfies(itemId, relation, buffer, qual, nKeys, key) d100 1 a100 1 Buffer buffer; d109 1 a109 1 return false; d111 1 a111 2 tuple = (HeapTuple) PageGetItem(BufferGetBlock(buffer), itemId); @ 1.9 log @heap_satisfies now is heap_tuple_satisfies (which returns a tuple) @ text @d22 1 a22 1 * $Header: RCS/heapvalid.c,v 1.8 91/06/03 03:56:16 kemnitz Exp Locker: kemnitz $ d42 1 a42 1 RcsId("$Header: RCS/heapvalid.c,v 1.8 91/06/03 03:56:16 kemnitz Exp Locker: kemnitz $"); d122 1 a122 1 return NULL; @ 1.8 log @got rid of call to keytest if key is null @ text @d22 1 a22 1 * $Header: src/access/common/RCS/heapvalid.c,v 1.7 91/06/03 03:00:47 kemnitz Exp Locker: kemnitz $ d42 1 a42 1 RcsId("$Header: src/access/common/RCS/heapvalid.c,v 1.7 91/06/03 03:00:47 kemnitz Exp Locker: kemnitz $"); d82 1 a82 1 * heap_satisifies d84 5 d94 3 a96 2 bool heap_satisfies(itemId, relation, buffer, qual, nKeys, key) d115 6 a120 4 if (key == NULL) return true; else return (bool) keytest(tuple, relation, nKeys, key); d122 1 a122 1 return false; @ 1.7 log @interface to heap_satisfies now passes relation. @ text @d22 1 a22 1 * $Header: RCS/heapvalid.c,v 1.6 91/05/01 02:48:47 cimarron Exp $ d42 1 a42 1 RcsId("$Header: RCS/heapvalid.c,v 1.6 91/05/01 02:48:47 cimarron Exp $"); d92 1 a92 1 Relation relation; d107 6 a112 3 if (relation->rd_rel->relkind == 'u') return (bool) keytest(tuple, relation, nKeys, key); d114 1 a114 5 if (! (keytest(tuple, relation, nKeys, key) && HeapTupleSatisfiesTimeQual(tuple, qual))) return false; return true; @ 1.6 log @round II of converting simple functions to macros + code cleaning in general @ text @d22 1 a22 1 * $Header: RCS/heapvalid.c,v 1.5 91/04/20 06:17:35 kemnitz Exp Locker: cimarron $ d42 1 a42 1 RcsId("$Header: RCS/heapvalid.c,v 1.5 91/04/20 06:17:35 kemnitz Exp Locker: cimarron $"); d90 1 a90 1 heap_satisifies(itemId, buffer, qual, nKeys, key) d92 1 a98 1 Relation relation = BufferGetRelation(buffer); d111 2 a112 2 if (! HeapTupleSatisfiesTimeQual(tuple, qual) || ! keytest(tuple, relation, nKeys, key)) @ 1.5 log @got rid of Assert @ text @d13 1 a13 1 * OLD INTERFACE ROUTINES d22 1 a22 1 * $Header: RCS/heapvalid.c,v 1.4 91/04/20 03:47:09 kemnitz Exp Locker: kemnitz $ d42 1 a42 1 RcsId("$Header: RCS/heapvalid.c,v 1.4 91/04/20 03:47:09 kemnitz Exp Locker: kemnitz $"); d45 1 a45 1 * heap_satisifies d47 1 a47 3 * Complete check of validity including LP_CTUP and keytest. * This should perhaps be combined with valid somehow in the * future. (Also, additional rule tests/time range tests.) a50 35 heap_satisifies(itemId, buffer, qual, nKeys, key) ItemId itemId; Buffer buffer; TimeQual qual; ScanKeySize nKeys; struct skey *key; { HeapTuple tuple; Relation relation = BufferGetRelation(buffer); if (! ItemIdIsUsed(itemId) || ItemIdIsContinuation(itemId) || ItemIdIsLock(itemId)) return false; tuple = (HeapTuple) PageGetItem(BufferGetBlock(buffer), itemId); if (relation->rd_rel->relkind == 'u') return (bool) keytest(tuple, relation, nKeys, key); if (! HeapTupleSatisfiesTimeQual(tuple, qual) || ! keytest(tuple, relation, nKeys, key)) return false; return true; } /* -------------------------------- * heap_keytest * -------------------------------- */ bool d55 1 a55 1 struct skey keys[]; a80 1 d82 5 a86 1 * TupleUpdatedByCurXactAndCmd d90 1 a90 21 TupleUpdatedByCurXactAndCmd(t) HeapTuple t; { if (TransactionIdEquals(t->t_xmax, GetCurrentTransactionId()) && t->t_cmax == (CID) GetCurrentCommandId()) return true; return false; } /* ---------------------------------------------------------------- * old interface routines * ---------------------------------------------------------------- */ /* ---------------- * amvalidtup * ItemIdHasValidHeapTupleForQualification * ---------------- */ bool ItemIdHasValidHeapTupleForQualification(itemId, buffer, qual, nKeys, key) d95 1 a95 1 ScanKey key; d97 2 a98 3 return heap_satisifies(itemId, buffer, qual, nKeys, key); } d100 16 a115 9 int amvalidtup(b, lp, nkeys, key) Buffer b; ItemId lp; int32 nkeys; struct skey key[]; { return (int) heap_satisifies(lp, b, NowTimeQual, nkeys, key); d119 1 a119 2 * keytest_tupdesc * keytest d122 3 a124 6 int keytest_tupdesc(t, tupdesc, nkeys, keys) HeapTuple t; TupleDescriptor tupdesc; int nkeys; ScanKey keys[]; d126 3 a128 3 return (int) heap_keytest(t, tupdesc, nkeys, keys); } d130 1 a130 9 int keytest(t, rdesc, nkeys, keys) HeapTuple t; Relation rdesc; int nkeys; struct skey keys[]; { return (int) heap_keytest(t, &rdesc->rd_att, nkeys, keys); @ 1.4 log @fixed bug in initializing scankey @ text @d22 1 a22 1 * $Header: RCS/heapvalid.c,v 1.3 91/04/19 05:35:49 kemnitz Exp Locker: kemnitz $ d42 1 a42 1 RcsId("$Header: RCS/heapvalid.c,v 1.3 91/04/19 05:35:49 kemnitz Exp Locker: kemnitz $"); a105 2 Assert(PointerIsValid(keys->func)); @ 1.3 log @uses the function cached in the scankey (instead of fmgr) @ text @d22 1 a22 1 * $Header: RCS/heapvalid.c,v 1.2 91/02/06 18:01:48 cimarron Exp Locker: kemnitz $ d42 1 a42 1 RcsId("$Header: RCS/heapvalid.c,v 1.2 91/02/06 18:01:48 cimarron Exp Locker: kemnitz $"); d58 1 a58 1 struct skey key; d105 2 @ 1.2 log @removed DATUM amgetattr(); reference @ text @d22 1 a22 1 * $Header: RCS/heapvalid.c,v 1.1 91/01/29 15:18:44 cimarron Exp Locker: cimarron $ d42 1 a42 1 RcsId("$Header: RCS/heapvalid.c,v 1.1 91/01/29 15:18:44 cimarron Exp Locker: cimarron $"); d58 1 a58 1 ScanKey key; d92 1 a92 1 struct skey keys[]; a96 1 char *fmgr(); d107 1 a107 1 test = (int) fmgr(keys->sk_opr, keys->sk_data, atp); d109 1 a109 1 test = (int) fmgr(keys->sk_opr, atp, keys->sk_data); d176 1 a176 1 struct skey keys[]; @ 1.1 log @Initial revision @ text @d22 1 a22 1 * $Header$ d42 1 a42 1 RcsId("$Header$"); a96 1 DATUM amgetattr(); @