PostGIS 3.7.0dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches
lwgeom_triggers.c
Go to the documentation of this file.
1/**********************************************************************
2 *
3 * PostGIS - Spatial Types for PostgreSQL
4 * http://postgis.net
5 *
6 * PostGIS is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * PostGIS is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with PostGIS. If not, see <http://www.gnu.org/licenses/>.
18 *
19 **********************************************************************
20 *
21 * Copyright (C) 2004 Refractions Research Inc.
22 *
23 **********************************************************************/
24
25
26#include "postgres.h"
27#include "executor/spi.h" /* this is what you need to work with SPI */
28#include "commands/trigger.h" /* ... and triggers */
29
30#include "../postgis_config.h"
31#include "lwgeom_pg.h"
32#include "utils/rel.h"
33
34Datum cache_bbox(PG_FUNCTION_ARGS);
35
46Datum cache_bbox(PG_FUNCTION_ARGS)
47{
48 TriggerData *trigdata = (TriggerData *) fcinfo->context;
49 Trigger *trigger;
50 TupleDesc tupdesc;
51 HeapTuple rettuple;
52 bool isnull;
53 Datum in, out;
54 int attno, ret;
55
56 /* make sure it's called as a trigger at all */
57 if (!CALLED_AS_TRIGGER(fcinfo))
58 elog(ERROR, "cache_bbox: not called by trigger manager");
59
60 /*
61 * make sure it's called with at least one argument
62 * (the geometry fields)
63 */
64 if ( trigdata->tg_trigger->tgnargs != 1 )
65 elog(ERROR, "trigger 'cache_bbox' must be called with one argument");
66
67 trigger = trigdata->tg_trigger;
68
69 /* tuple to return to executor */
70 if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
71 rettuple = trigdata->tg_newtuple;
72 else
73 rettuple = trigdata->tg_trigtuple;
74
75 /* Do nothing when fired by delete, after or for statement */
76 if (TRIGGER_FIRED_BY_DELETE(trigdata->tg_event))
77 {
78 elog(NOTICE, "Useless cache_box trigger fired by DELETE");
79 return PointerGetDatum(rettuple);
80 }
81 if (TRIGGER_FIRED_AFTER(trigdata->tg_event))
82 {
83 elog(NOTICE, "Useless cache_box trigger fired AFTER");
84 return PointerGetDatum(rettuple);
85 }
86 if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event))
87 {
88 elog(NOTICE, "Useless cache_box trigger fired for STATEMENT");
89 return PointerGetDatum(rettuple);
90 }
91
92 tupdesc = trigdata->tg_relation->rd_att;
93
94 /* Connect to SPI manager */
95 if ((ret = SPI_connect()) < 0)
96 elog(ERROR, "cache_bbox: SPI_connect returned %d", ret);
97
98 /* Find number of requested argument */
99 attno = SPI_fnumber(tupdesc, trigger->tgargs[0]);
100 if ( attno == SPI_ERROR_NOATTRIBUTE )
101 elog(ERROR, "trigger %s can't find attribute %s",
102 trigger->tgname, trigger->tgargs[0]);
103
104 /* Find number of requested argument */
105 if ( strcmp(SPI_gettype(tupdesc, attno), "geometry") )
106 elog(ERROR, "trigger %s requested to apply to a non-geometry field (%s)", trigger->tgname, trigger->tgargs[0]);
107
108 /* Get input lwgeom */
109 in = SPI_getbinval(rettuple, tupdesc, attno, &isnull);
110
111 if ( ! isnull )
112 {
113 out = DirectFunctionCall1(LWGEOM_addBBOX, in);
114 rettuple = SPI_modifytuple(trigdata->tg_relation, rettuple,
115 1, &attno, &out, NULL);
116 }
117
118 /* Disconnect from SPI */
119 SPI_finish();
120
121 return PointerGetDatum(rettuple);
122}
Datum LWGEOM_addBBOX(PG_FUNCTION_ARGS)
Datum cache_bbox(PG_FUNCTION_ARGS)
PG_FUNCTION_INFO_V1(cache_bbox)