head 1.14; access; symbols release_4_2:1.14 aix_ok:1.13 Version_2_1:1.9; locks; strict; comment @ * @; 1.14 date 94.03.18.20.50.41; author marc; state Exp; branches; next 1.13; 1.13 date 91.11.18.22.21.22; author mer; state Exp; branches; next 1.12; 1.12 date 91.08.27.14.40.17; author sp; state Exp; branches; next 1.11; 1.11 date 91.08.14.15.41.27; author sp; state Exp; branches; next 1.10; 1.10 date 91.04.08.18.14.10; author sp; state Exp; branches; next 1.9; 1.9 date 91.02.08.17.37.48; author sp; state Exp; branches; next 1.8; 1.8 date 91.01.17.19.05.03; author sp; state Exp; branches; next 1.7; 1.7 date 91.01.09.19.05.58; author sp; state Exp; branches; next 1.6; 1.6 date 90.10.16.17.17.43; author sp; state Exp; branches; next 1.5; 1.5 date 90.09.25.16.42.12; author kemnitz; state Exp; branches; next 1.4; 1.4 date 90.04.03.17.08.36; author sp; state Exp; branches; next 1.3; 1.3 date 90.03.07.17.16.54; author sp; state Exp; branches; next 1.2; 1.2 date 90.01.31.03.44.58; author sp; state Exp; branches; next 1.1; 1.1 date 90.01.11.14.42.04; author sp; state Exp; branches; next ; desc @some routines used to stroe the values of attributes in an array so that they can be easily changed without having to make copies of tuples all the time... @ 1.14 log @move $Header away from comment star @ text @ /*================================================================== * * FILE: * prs2attr.c * * IDENTIFICATION: * $Header: /usr/local/devel/postgres/src/backend/rules/prs2/RCS/prs2attr.c,v 1.13 1991/11/18 22:21:22 mer Exp marc $ * * DESCRIPTION: * *================================================================== */ #include "tmp/c.h" #include "utils/palloc.h" #include "utils/log.h" #include "access/ftup.h" /* ModifyHeapTuple() defined here... */ #include "rules/prs2.h" /*--------------------------------------------------------------------- * * attributeValuesCreate * * Given a tuple create the corresponding 'AttributeValues' array. * Note that in the beginnign all the 'value' entries are copied * form the tuple and that 'isCalculated' are all false. * */ AttributeValues attributeValuesCreate(tuple, buffer, relation) HeapTuple tuple; Buffer buffer; Relation relation; { AttributeNumber i; AttributeNumber natts; AttributeValues attrValues; long size; Boolean isNull; natts = RelationGetNumberOfAttributes(relation); size = natts * sizeof(AttributeValuesData); attrValues = (AttributeValues) palloc(size); if (attrValues == NULL) { elog(WARN,"attributeValuesCreate: palloc(%ld) failed",size); } for (i=1; i<=natts; i++) { attrValues[i-1].value = HeapTupleGetAttributeValue( tuple, buffer, i, RelationGetTupleDescriptor(relation), &isNull); attrValues[i-1].isCalculated = (Boolean) 0; attrValues[i-1].isChanged = (Boolean) 0; attrValues[i-1].isNull = isNull; } return(attrValues); } /*--------------------------------------------------------------------- * * attributeValuesFree * * Free a previously allocated 'AttributeValues' array. */ void attributeValuesFree(a, relation) AttributeValues a; Relation relation; { int i; AttributeNumber natts; TupleDescriptor tdesc; /* * free all space (if any) occupied by datums generated * by "prs2RunOnePlanAndGetValue()" * All these datums are creted via "datumCopy()" */ tdesc = RelationGetTupleDescriptor(relation); natts = RelationGetNumberOfAttributes(relation); for(i=1; i<=natts; i++) { if (a[i-1].isCalculated && a[i-1].isChanged) { if (!a[i-1].isNull) datumFree(a[i-1].value, tdesc->data[i-1]->atttypid, /* type */ tdesc->data[i-1]->attbyval, /* byVal */ (Size) tdesc->data[i-1]->attlen); /* type length */ } } pfree((Pointer)a); } /*-------------------------------------------------------------------- * * attributeValuesMakeNewTuple * * Given the old tuple and the values that the new tuple should have * create a new tuple. * * There are a couple of tricky things in here... * * Some of the attributes of the tuple (not necessarily all of them * though..) have been checked for rules, i.e. we have checked if there * is any rule that calculates a value for this attribute. * All these checked attributes have the field 'isCalculated' (of their * corresponding entry in array 'attrValues') equal to true. * On top of that, if there was an applicable rule, then the field * 'isChanged' is true (todenote that the value of this attribute * has changed because of a rule activation, therefore the value * stored in 'tuple' is now obsolete). * If no applicable rule was found then 'isChanged' is equal to false * and the value as stored in 'tuple' is the correct one. * * Finally all attributes not checked for rule activations (because * we don't need to calculate their values for the time being...) * have their 'isCalculated' field equal to false. * * Obviously enough, if at least one attribute has isChanged==true, * we must create a new tuple with the correct values in it (we * use 'ModifyHeapTuple()' for this purpose). * If no attribute has been changed we can use the olt 'tuple' * thus avoiding the copy (efficiency!). * #ifdef CHANGE_LOCKS --------------------------------------------------- XXX Currently we do NOT do that !!! XXXXXXX --------------------------------------------------- * However we must also need change the locks of the tuple! * Say, if during a retrieve operation, a rule that had a lock of * type `LockTypeRetrieveWrite' has been activated and calculated a new * value for this attribute, then we must remove this lock, so that if * later on (at a higher node in the plan, maybe a join or a topmost * result node that is used when the user's operation is an append * or delete) we want to find the value of this (laready claculated) * attribute, we do not unnecessarily reactivate the rule. * Another case where this happens is when we append a tuple. * We have to activate all rules that have `LockTypeAppendWrite' locks, * but then we can remove these locks because they are no longer * needed (a tuple is only appended once!). * The replace case is similar.... * * XXX: * Hm.. here comes the tricky question. If no attribute has been * changed (i.e. all the 'isChanged' are false) but we must change * the locks of the tuple, what shall we do?? * I think that we have the following options, but I don't know * which ones are gonna work and which not: * 1) We do not copy the tuple, and we just change its * lock so that it points to the new lock: * tuple->t_lcok.l_lock = newLock; * 2) We create a new copy of the tuple with the right locks. * I decided to do option # 2. #else * If a new tuple is created, then it will always have an empty * lock in it. #endif CHANGE_LOCKS * * * This routine returns 0 if no tuple copy has been made and * therefore the old 'tuple' can be used, or 1 if there was * a tuple copy, in which case the 'newTupleP' point to * the new tuple (note: in this case the buffer for this * new tuple is the 'InvalidBuffer') */ int attributeValuesMakeNewTuple(tuple, buffer, attrValues, locks, lockType, relation, newTupleP) HeapTuple tuple; Buffer buffer; AttributeValues attrValues; RuleLock locks; Prs2LockType lockType; Relation relation; HeapTuple *newTupleP; { AttributeNumber natts; Datum *replaceValue; char *replaceNull; char *replace; long size; int i; bool tupleHasChanged; bool locksHaveToChange; HeapTuple t; int nlocks; RuleLock newLocks; Prs2OneLock oneLock; AttributeNumber attrNo; Prs2LockType thisLockType; /* * find the number of attributes of the tuple */ natts = RelationGetNumberOfAttributes(relation); /* * Find if there was any attribute change and/or we have * to change the locks... * */ tupleHasChanged = false; for (i=0; idata[i-1]->atttypid); @ 1.5 log @Updating from revision 1.4 to revision 1.6 @ text @d8 1 a8 1 *$Header: RCS/prs2attr.c,v 1.6 90/08/13 20:29:26 sp Exp $ d59 1 d73 1 a73 1 attributeValuesFree(a) d75 1 d77 18 @ 1.4 log @New function: attributeValuesCombineNewAndOldTuple() @ text @d8 1 a8 1 *$Header: RCS/prs2attr.c,v 1.3 90/03/07 17:16:54 sp Exp $ d15 5 a19 5 #include "c.h" #include "palloc.h" #include "log.h" #include "ftup.h" /* ModifyHeapTuple() defined here... */ #include "prs2.h" d111 1 a111 1 * type `LockTypeRetrieveWrite' has been activated and calculated a new d118 1 a118 1 * We have to activate all rules that have `LockTypeAppendWrite' locks, @ 1.3 log @minor bug fixes @ text @d8 1 a8 1 *$Header: RCS/prs2attr.c,v 1.2 90/01/31 03:44:58 sp Exp $ d299 155 @ 1.2 log @Prs2Locks has been changed to RuleLocks @ text @d8 1 a8 1 *$Header: RCS/prs2attr.c,v 1.1 90/01/11 14:42:04 sp Exp Locker: sp $ d41 1 d57 1 a57 1 &(attrValues[i].isNull)); d59 1 d110 12 a121 10 * If an attribute that has been checked for rules and has some * locks on it of type 'LockTypeWrite', then somehow it must also * be marked as so, so that if at a later time (especially when the * rule manager is activated at the topmost level of a replace, * delete or appaned plan) we want to calculate the value of this * attribute we will not check again for all these rules. * One way to achieve that is for every attribute with isChecked==true * to remove all the corresponding 'LockTypeWrite' locks. * Note also that we must keep all the other locks (should they be needed * by the rule manager at the tompost level of the plan)... d145 1 a145 1 locks, relation, newTupleP) d150 1 d167 1 a167 1 Prs2LockType lockType; d249 1 a249 1 locksHaveToChange = false ; d253 2 a254 2 lockType = prs2OneLockGetLockType(oneLock); if (lockType != LockTypeRetrieveWrite || a263 1 d268 8 a281 1 prs2FreeLocks(newLocks); a292 1 prs2FreeLocks(newLocks); @ 1.1 log @Initial revision @ text @d8 1 a8 1 *$Header: RCS/prs2attr.c,v 1.2 90/01/11 00:22:44 sp Exp Locker: sp $ d145 1 a145 1 Prs2Locks locks; d159 1 a159 1 Prs2Locks newLocks; d249 2 a250 1 if (lockType != LockTypeWrite || !attrValues[attrNo-1].isCalculated){ @