Header And Logo

PostgreSQL
| The world's most advanced open source database.

Defines | Functions | Variables

lo.c File Reference

#include "postgres.h"
#include "commands/trigger.h"
#include "executor/spi.h"
#include "libpq/be-fsstubs.h"
#include "utils/rel.h"
Include dependency graph for lo.c:

Go to the source code of this file.

Defines

#define atooid(x)   ((Oid) strtoul((x), NULL, 10))

Functions

Datum lo_manage (PG_FUNCTION_ARGS)
 PG_FUNCTION_INFO_V1 (lo_manage)

Variables

 PG_MODULE_MAGIC

Define Documentation

#define atooid (   x  )     ((Oid) strtoul((x), NULL, 10))

Function Documentation

Datum lo_manage ( PG_FUNCTION_ARGS   ) 

Definition at line 31 of file lo.c.

References atooid, CALLED_AS_TRIGGER, DirectFunctionCall1, elog, ERROR, lo_unlink(), NULL, ObjectIdGetDatum, pfree(), PointerGetDatum, RelationData::rd_att, SPI_fnumber(), SPI_getvalue(), TriggerData::tg_event, TriggerData::tg_newtuple, TriggerData::tg_relation, TriggerData::tg_trigger, TriggerData::tg_trigtuple, Trigger::tgargs, TRIGGER_FIRED_BY_DELETE, and TRIGGER_FIRED_BY_UPDATE.

{
    TriggerData *trigdata = (TriggerData *) fcinfo->context;
    int         attnum;         /* attribute number to monitor  */
    char      **args;           /* Args containing attr name    */
    TupleDesc   tupdesc;        /* Tuple Descriptor             */
    HeapTuple   rettuple;       /* Tuple to be returned         */
    bool        isdelete;       /* are we deleting?             */
    HeapTuple   newtuple;       /* The new value for tuple      */
    HeapTuple   trigtuple;      /* The original value of tuple  */

    if (!CALLED_AS_TRIGGER(fcinfo))     /* internal error */
        elog(ERROR, "not fired by trigger manager");

    /*
     * Fetch some values from trigdata
     */
    newtuple = trigdata->tg_newtuple;
    trigtuple = trigdata->tg_trigtuple;
    tupdesc = trigdata->tg_relation->rd_att;
    args = trigdata->tg_trigger->tgargs;

    /* tuple to return to Executor */
    if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
        rettuple = newtuple;
    else
        rettuple = trigtuple;

    /* Are we deleting the row? */
    isdelete = TRIGGER_FIRED_BY_DELETE(trigdata->tg_event);

    /* Get the column we're interested in */
    attnum = SPI_fnumber(tupdesc, args[0]);

    if (attnum <= 0)
        elog(ERROR, "column \"%s\" does not exist", args[0]);

    /*
     * Handle updates
     *
     * Here, if the value of the monitored attribute changes, then the large
     * object associated with the original value is unlinked.
     */
    if (newtuple != NULL)
    {
        char       *orig = SPI_getvalue(trigtuple, tupdesc, attnum);
        char       *newv = SPI_getvalue(newtuple, tupdesc, attnum);

        if (orig != NULL && (newv == NULL || strcmp(orig, newv) != 0))
            DirectFunctionCall1(lo_unlink,
                                ObjectIdGetDatum(atooid(orig)));

        if (newv)
            pfree(newv);
        if (orig)
            pfree(orig);
    }

    /*
     * Handle deleting of rows
     *
     * Here, we unlink the large object associated with the managed attribute
     */
    if (isdelete)
    {
        char       *orig = SPI_getvalue(trigtuple, tupdesc, attnum);

        if (orig != NULL)
        {
            DirectFunctionCall1(lo_unlink,
                                ObjectIdGetDatum(atooid(orig)));

            pfree(orig);
        }
    }

    return PointerGetDatum(rettuple);
}

PG_FUNCTION_INFO_V1 ( lo_manage   ) 

Variable Documentation

Definition at line 16 of file lo.c.