~ubuntu-branches/ubuntu/hardy/postgresql-8.4/hardy-backports

« back to all changes in this revision

Viewing changes to src/backend/commands/trigger.c

  • Committer: Package Import Robot
  • Author(s): Ubuntu Archive Auto-Backport
  • Date: 2011-10-27 06:13:09 UTC
  • mfrom: (5.3.14 sid)
  • Revision ID: package-import@ubuntu.com-20111027061309-zc27cjc6hu8yp0z0
Tags: 8.4.9-1~hardy1
Automated backport upload; no source changes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1921
1921
                                                          false, NULL, NULL);
1922
1922
}
1923
1923
 
1924
 
HeapTuple
 
1924
TupleTableSlot *
1925
1925
ExecBRUpdateTriggers(EState *estate, ResultRelInfo *relinfo,
1926
 
                                         ItemPointer tupleid, HeapTuple newtuple)
 
1926
                                         ItemPointer tupleid, TupleTableSlot *slot)
1927
1927
{
1928
1928
        TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
1929
1929
        int                     ntrigs = trigdesc->n_before_row[TRIGGER_EVENT_UPDATE];
1930
1930
        int                *tgindx = trigdesc->tg_before_row[TRIGGER_EVENT_UPDATE];
 
1931
        HeapTuple       slottuple = ExecMaterializeSlot(slot);
 
1932
        HeapTuple       newtuple = slottuple;
1931
1933
        TriggerData LocTriggerData;
1932
1934
        HeapTuple       trigtuple;
1933
1935
        HeapTuple       oldtuple;
1934
 
        HeapTuple       intuple = newtuple;
1935
1936
        TupleTableSlot *newSlot;
1936
1937
        int                     i;
1937
1938
 
1940
1941
                return NULL;
1941
1942
 
1942
1943
        /*
1943
 
         * In READ COMMITTED isolation level it's possible that newtuple was
1944
 
         * changed due to concurrent update.
 
1944
         * In READ COMMITTED isolation level it's possible that target tuple was
 
1945
         * changed due to concurrent update.  In that case we have a raw subplan
 
1946
         * output tuple in newSlot, and need to run it through the junk filter to
 
1947
         * produce an insertable tuple.
 
1948
         *
 
1949
         * Caution: more than likely, the passed-in slot is the same as the
 
1950
         * junkfilter's output slot, so we are clobbering the original value of
 
1951
         * slottuple by doing the filtering.  This is OK since neither we nor our
 
1952
         * caller have any more interest in the prior contents of that slot.
1945
1953
         */
1946
1954
        if (newSlot != NULL)
1947
 
                intuple = newtuple = ExecRemoveJunk(estate->es_junkFilter, newSlot);
 
1955
        {
 
1956
                slot = ExecFilterJunk(estate->es_junkFilter, newSlot);
 
1957
                slottuple = ExecMaterializeSlot(slot);
 
1958
                newtuple = slottuple;
 
1959
        }
1948
1960
 
1949
1961
        LocTriggerData.type = T_TriggerData;
1950
1962
        LocTriggerData.tg_event = TRIGGER_EVENT_UPDATE |
1977
1989
                                                                           relinfo->ri_TrigFunctions,
1978
1990
                                                                           relinfo->ri_TrigInstrument,
1979
1991
                                                                           GetPerTupleMemoryContext(estate));
1980
 
                if (oldtuple != newtuple && oldtuple != intuple)
 
1992
                if (oldtuple != newtuple && oldtuple != slottuple)
1981
1993
                        heap_freetuple(oldtuple);
1982
1994
                if (newtuple == NULL)
1983
 
                        break;
 
1995
                {
 
1996
                        heap_freetuple(trigtuple);
 
1997
                        return NULL;            /* "do nothing" */
 
1998
                }
1984
1999
        }
1985
2000
        heap_freetuple(trigtuple);
1986
 
        return newtuple;
 
2001
 
 
2002
        if (newtuple != slottuple)
 
2003
        {
 
2004
                /*
 
2005
                 * Return the modified tuple using the es_trig_tuple_slot.  We assume
 
2006
                 * the tuple was allocated in per-tuple memory context, and therefore
 
2007
                 * will go away by itself. The tuple table slot should not try to
 
2008
                 * clear it.
 
2009
                 */
 
2010
                TupleTableSlot *newslot = estate->es_trig_tuple_slot;
 
2011
                TupleDesc       tupdesc = RelationGetDescr(relinfo->ri_RelationDesc);
 
2012
 
 
2013
                if (newslot->tts_tupleDescriptor != tupdesc)
 
2014
                        ExecSetSlotDescriptor(newslot, tupdesc);
 
2015
                ExecStoreTuple(newtuple, newslot, InvalidBuffer, false);
 
2016
                slot = newslot;
 
2017
        }
 
2018
        return slot;
1987
2019
}
1988
2020
 
1989
2021
void