~ubuntu-branches/ubuntu/trusty/postgis/trusty-security

« back to all changes in this revision

Viewing changes to postgis/lwgeom_triggers.c

  • Committer: Bazaar Package Importer
  • Author(s): Francesco Paolo Lovergine
  • Date: 2009-12-11 13:10:34 UTC
  • mfrom: (1.1.9 upstream) (5.2.1 experimental)
  • Revision ID: james.westby@ubuntu.com-20091211131034-wmsz69wxvt95pe5r
Tags: 1.4.0-2
* Upload to unstable.
* Better parameterized debian/rules against postgis $(VERSION).
* Added dblatex and libcunit1-dev among build-deps.
* Added postgis_comments.sql to contrib/ SQL templates.
* Dropping 8.3 support, no more supported for squeeze.
  (closes: #559587)
* Do not stop on error in postrm if the target dir does not exist.
  (closes: #560409)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "postgres.h"
 
2
#include "executor/spi.h"       /* this is what you need to work with SPI */
 
3
#include "commands/trigger.h"   /* ... and triggers */
 
4
#include "lwgeom_pg.h"
 
5
 
 
6
Datum cache_bbox(PG_FUNCTION_ARGS);
 
7
 
 
8
/** @file
 
9
 *      The intended use for this trigger function is making
 
10
 *      a geometry field cache it's bbox. Use like this:
 
11
 *
 
12
 *      CREATE TRIGGER <name> BEFORE INSERT OR UPDATE
 
13
 *              ON <table> FOR EACH ROW EXECUTE PROCEDURE
 
14
 *              cache_bbox(<field>);
 
15
 *
 
16
 */
 
17
PG_FUNCTION_INFO_V1(cache_bbox);
 
18
Datum cache_bbox(PG_FUNCTION_ARGS)
 
19
{
 
20
        TriggerData *trigdata = (TriggerData *) fcinfo->context;
 
21
        Trigger *trigger;
 
22
        TupleDesc   tupdesc;
 
23
        HeapTuple   rettuple;
 
24
        bool        isnull;
 
25
        Datum in, out;
 
26
        int attno, ret;
 
27
 
 
28
        /* make sure it's called as a trigger at all */
 
29
        if (!CALLED_AS_TRIGGER(fcinfo))
 
30
                elog(ERROR, "cache_bbox: not called by trigger manager");
 
31
 
 
32
        /*
 
33
         * make sure it's called with at least one argument
 
34
         * (the geometry fields)
 
35
         */
 
36
        if ( trigdata->tg_trigger->tgnargs != 1 )
 
37
                elog(ERROR, "trigger 'cache_bbox' must be called with one argument");
 
38
 
 
39
        trigger = trigdata->tg_trigger;
 
40
 
 
41
        /* tuple to return to executor */
 
42
        if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
 
43
                rettuple = trigdata->tg_newtuple;
 
44
        else
 
45
                rettuple = trigdata->tg_trigtuple;
 
46
 
 
47
        /* Do nothing when fired by delete, after or for statement */
 
48
        if (TRIGGER_FIRED_BY_DELETE(trigdata->tg_event))
 
49
        {
 
50
                elog(NOTICE, "Useless cache_box trigger fired by DELETE");
 
51
                return PointerGetDatum(rettuple);
 
52
        }
 
53
        if (TRIGGER_FIRED_AFTER(trigdata->tg_event))
 
54
        {
 
55
                elog(NOTICE, "Useless cache_box trigger fired AFTER");
 
56
                return PointerGetDatum(rettuple);
 
57
        }
 
58
        if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event))
 
59
        {
 
60
                elog(NOTICE, "Useless cache_box trigger fired for STATEMENT");
 
61
                return PointerGetDatum(rettuple);
 
62
        }
 
63
 
 
64
        tupdesc = trigdata->tg_relation->rd_att;
 
65
 
 
66
        /* Connect to SPI manager */
 
67
        if ((ret = SPI_connect()) < 0)
 
68
                elog(ERROR, "cache_bbox: SPI_connect returned %d", ret);
 
69
 
 
70
        /* Find number of requested argument */
 
71
        attno = SPI_fnumber(tupdesc, trigger->tgargs[0]);
 
72
        if ( attno == SPI_ERROR_NOATTRIBUTE )
 
73
                elog(ERROR, "trigger %s can't find attribute %s",
 
74
                     trigger->tgname, trigger->tgargs[0]);
 
75
 
 
76
        /* Find number of requested argument */
 
77
        if ( strcmp(SPI_gettype(tupdesc, attno), "geometry") )
 
78
                elog(ERROR, "trigger %s requested to apply to a non-geometry field (%s)", trigger->tgname, trigger->tgargs[0]);
 
79
 
 
80
        /* Get input lwgeom */
 
81
        in = SPI_getbinval(rettuple, tupdesc, attno, &isnull);
 
82
 
 
83
        if ( ! isnull )
 
84
        {
 
85
                out = PointerGetDatum(DirectFunctionCall1(LWGEOM_addBBOX, in));
 
86
 
 
87
                rettuple = SPI_modifytuple(trigdata->tg_relation, rettuple,
 
88
                                           1, &attno, &out, NULL);
 
89
        }
 
90
 
 
91
        /* Disconnect from SPI */
 
92
        SPI_finish();
 
93
 
 
94
        return PointerGetDatum(rettuple);
 
95
}