PostGIS  2.1.10dev-r@@SVN_REVISION@@
lwgeom_triggers.c
Go to the documentation of this file.
1 /**********************************************************************
2  *
3  * PostGIS - Spatial Types for PostgreSQL
4  * http://postgis.net
5  *
6  * Copyright (C) 2004 Refractions Research Inc.
7  *
8  * This is free software; you can redistribute and/or modify it under
9  * the terms of the GNU General Public Licence. See the COPYING file.
10  *
11  **********************************************************************/
12 
13 #include "postgres.h"
14 #include "executor/spi.h" /* this is what you need to work with SPI */
15 #include "commands/trigger.h" /* ... and triggers */
16 
17 #include "../postgis_config.h"
18 #include "lwgeom_pg.h"
19 #include "utils/rel.h"
20 
21 Datum cache_bbox(PG_FUNCTION_ARGS);
22 
33 Datum cache_bbox(PG_FUNCTION_ARGS)
34 {
35  TriggerData *trigdata = (TriggerData *) fcinfo->context;
36  Trigger *trigger;
37  TupleDesc tupdesc;
38  HeapTuple rettuple;
39  bool isnull;
40  Datum in, out;
41  int attno, ret;
42 
43  /* make sure it's called as a trigger at all */
44  if (!CALLED_AS_TRIGGER(fcinfo))
45  elog(ERROR, "cache_bbox: not called by trigger manager");
46 
47  /*
48  * make sure it's called with at least one argument
49  * (the geometry fields)
50  */
51  if ( trigdata->tg_trigger->tgnargs != 1 )
52  elog(ERROR, "trigger 'cache_bbox' must be called with one argument");
53 
54  trigger = trigdata->tg_trigger;
55 
56  /* tuple to return to executor */
57  if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
58  rettuple = trigdata->tg_newtuple;
59  else
60  rettuple = trigdata->tg_trigtuple;
61 
62  /* Do nothing when fired by delete, after or for statement */
63  if (TRIGGER_FIRED_BY_DELETE(trigdata->tg_event))
64  {
65  elog(NOTICE, "Useless cache_box trigger fired by DELETE");
66  return PointerGetDatum(rettuple);
67  }
68  if (TRIGGER_FIRED_AFTER(trigdata->tg_event))
69  {
70  elog(NOTICE, "Useless cache_box trigger fired AFTER");
71  return PointerGetDatum(rettuple);
72  }
73  if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event))
74  {
75  elog(NOTICE, "Useless cache_box trigger fired for STATEMENT");
76  return PointerGetDatum(rettuple);
77  }
78 
79  tupdesc = trigdata->tg_relation->rd_att;
80 
81  /* Connect to SPI manager */
82  if ((ret = SPI_connect()) < 0)
83  elog(ERROR, "cache_bbox: SPI_connect returned %d", ret);
84 
85  /* Find number of requested argument */
86  attno = SPI_fnumber(tupdesc, trigger->tgargs[0]);
87  if ( attno == SPI_ERROR_NOATTRIBUTE )
88  elog(ERROR, "trigger %s can't find attribute %s",
89  trigger->tgname, trigger->tgargs[0]);
90 
91  /* Find number of requested argument */
92  if ( strcmp(SPI_gettype(tupdesc, attno), "geometry") )
93  elog(ERROR, "trigger %s requested to apply to a non-geometry field (%s)", trigger->tgname, trigger->tgargs[0]);
94 
95  /* Get input lwgeom */
96  in = SPI_getbinval(rettuple, tupdesc, attno, &isnull);
97 
98  if ( ! isnull )
99  {
100  out = PointerGetDatum(DirectFunctionCall1(LWGEOM_addBBOX, in));
101 
102  rettuple = SPI_modifytuple(trigdata->tg_relation, rettuple,
103  1, &attno, &out, NULL);
104  }
105 
106  /* Disconnect from SPI */
107  SPI_finish();
108 
109  return PointerGetDatum(rettuple);
110 }
PG_FUNCTION_INFO_V1(cache_bbox)
Datum LWGEOM_addBBOX(PG_FUNCTION_ARGS)
Definition: lwgeom_inout.c:408
Datum cache_bbox(PG_FUNCTION_ARGS)
if(!(yy_init))
Definition: lwin_wkt_lex.c:860