4343#define RDELIM ')'
4444#define DELIM ','
4545
46- extern PATH * poly2path (POLYGON * poly );
47- extern void regress_lseg_construct (LSEG * lseg , Point * pt1 , Point * pt2 );
46+ static void regress_lseg_construct (LSEG * lseg , Point * pt1 , Point * pt2 );
4847
4948PG_MODULE_MAGIC ;
5049
5150
52- /*
53- * Distance from a point to a path
54- */
55- PG_FUNCTION_INFO_V1 (regress_dist_ptpath );
56-
57- Datum
58- regress_dist_ptpath (PG_FUNCTION_ARGS )
59- {
60- Point * pt = PG_GETARG_POINT_P (0 );
61- PATH * path = PG_GETARG_PATH_P (1 );
62- float8 result = 0.0 ; /* keep compiler quiet */
63- float8 tmp ;
64- int i ;
65- LSEG lseg ;
66-
67- switch (path -> npts )
68- {
69- case 0 :
70- PG_RETURN_NULL ();
71- case 1 :
72- result = point_dt (pt , & path -> p [0 ]);
73- break ;
74- default :
75-
76- /*
77- * the distance from a point to a path is the smallest distance
78- * from the point to any of its constituent segments.
79- */
80- Assert (path -> npts > 1 );
81- for (i = 0 ; i < path -> npts - 1 ; ++ i )
82- {
83- regress_lseg_construct (& lseg , & path -> p [i ], & path -> p [i + 1 ]);
84- tmp = DatumGetFloat8 (DirectFunctionCall2 (dist_ps ,
85- PointPGetDatum (pt ),
86- LsegPGetDatum (& lseg )));
87- if (i == 0 || tmp < result )
88- result = tmp ;
89- }
90- break ;
91- }
92- PG_RETURN_FLOAT8 (result );
93- }
94-
95- /*
96- * this essentially does a cartesian product of the lsegs in the
97- * two paths, and finds the min distance between any two lsegs
98- */
99- PG_FUNCTION_INFO_V1 (regress_path_dist );
100-
101- Datum
102- regress_path_dist (PG_FUNCTION_ARGS )
103- {
104- PATH * p1 = PG_GETARG_PATH_P (0 );
105- PATH * p2 = PG_GETARG_PATH_P (1 );
106- bool have_min = false;
107- float8 min = 0.0 ; /* initialize to keep compiler quiet */
108- float8 tmp ;
109- int i ,
110- j ;
111- LSEG seg1 ,
112- seg2 ;
113-
114- for (i = 0 ; i < p1 -> npts - 1 ; i ++ )
115- {
116- for (j = 0 ; j < p2 -> npts - 1 ; j ++ )
117- {
118- regress_lseg_construct (& seg1 , & p1 -> p [i ], & p1 -> p [i + 1 ]);
119- regress_lseg_construct (& seg2 , & p2 -> p [j ], & p2 -> p [j + 1 ]);
120-
121- tmp = DatumGetFloat8 (DirectFunctionCall2 (lseg_distance ,
122- LsegPGetDatum (& seg1 ),
123- LsegPGetDatum (& seg2 )));
124- if (!have_min || tmp < min )
125- {
126- min = tmp ;
127- have_min = true;
128- }
129- }
130- }
131-
132- if (!have_min )
133- PG_RETURN_NULL ();
134-
135- PG_RETURN_FLOAT8 (min );
136- }
137-
138- PATH *
139- poly2path (POLYGON * poly )
140- {
141- int i ;
142- char * output = (char * ) palloc (2 * (P_MAXDIG + 1 ) * poly -> npts + 64 );
143- char buf [2 * (P_MAXDIG ) + 20 ];
144-
145- sprintf (output , "(1, %*d" , P_MAXDIG , poly -> npts );
146-
147- for (i = 0 ; i < poly -> npts ; i ++ )
148- {
149- snprintf (buf , sizeof (buf ), ",%*g,%*g" ,
150- P_MAXDIG , poly -> p [i ].x , P_MAXDIG , poly -> p [i ].y );
151- strcat (output , buf );
152- }
153-
154- snprintf (buf , sizeof (buf ), "%c" , RDELIM );
155- strcat (output , buf );
156- return DatumGetPathP (DirectFunctionCall1 (path_in ,
157- CStringGetDatum (output )));
158- }
159-
16051/* return the point where two paths intersect, or NULL if no intersection. */
16152PG_FUNCTION_INFO_V1 (interpt_pp );
16253
@@ -201,7 +92,7 @@ interpt_pp(PG_FUNCTION_ARGS)
20192
20293
20394/* like lseg_construct, but assume space already allocated */
204- void
95+ static void
20596regress_lseg_construct (LSEG * lseg , Point * pt1 , Point * pt2 )
20697{
20798 lseg -> p [0 ].x = pt1 -> x ;
@@ -291,20 +182,6 @@ pt_in_widget(PG_FUNCTION_ARGS)
291182 PG_RETURN_BOOL (point_dt (point , & widget -> center ) < widget -> radius );
292183}
293184
294- PG_FUNCTION_INFO_V1 (boxarea );
295-
296- Datum
297- boxarea (PG_FUNCTION_ARGS )
298- {
299- BOX * box = PG_GETARG_BOX_P (0 );
300- double width ,
301- height ;
302-
303- width = Abs (box -> high .x - box -> low .x );
304- height = Abs (box -> high .y - box -> low .y );
305- PG_RETURN_FLOAT8 (width * height );
306- }
307-
308185PG_FUNCTION_INFO_V1 (reverse_name );
309186
310187Datum
@@ -327,123 +204,6 @@ reverse_name(PG_FUNCTION_ARGS)
327204}
328205
329206
330- static TransactionId fd17b_xid = InvalidTransactionId ;
331- static TransactionId fd17a_xid = InvalidTransactionId ;
332- static int fd17b_level = 0 ;
333- static int fd17a_level = 0 ;
334- static bool fd17b_recursion = true;
335- static bool fd17a_recursion = true;
336-
337- PG_FUNCTION_INFO_V1 (funny_dup17 );
338-
339- Datum
340- funny_dup17 (PG_FUNCTION_ARGS )
341- {
342- TriggerData * trigdata = (TriggerData * ) fcinfo -> context ;
343- TransactionId * xid ;
344- int * level ;
345- bool * recursion ;
346- Relation rel ;
347- TupleDesc tupdesc ;
348- HeapTuple tuple ;
349- char * query ,
350- * fieldval ,
351- * fieldtype ;
352- char * when ;
353- uint64 inserted ;
354- int selected = 0 ;
355- int ret ;
356-
357- if (!CALLED_AS_TRIGGER (fcinfo ))
358- elog (ERROR , "funny_dup17: not fired by trigger manager" );
359-
360- tuple = trigdata -> tg_trigtuple ;
361- rel = trigdata -> tg_relation ;
362- tupdesc = rel -> rd_att ;
363- if (TRIGGER_FIRED_BEFORE (trigdata -> tg_event ))
364- {
365- xid = & fd17b_xid ;
366- level = & fd17b_level ;
367- recursion = & fd17b_recursion ;
368- when = "BEFORE" ;
369- }
370- else
371- {
372- xid = & fd17a_xid ;
373- level = & fd17a_level ;
374- recursion = & fd17a_recursion ;
375- when = "AFTER " ;
376- }
377-
378- if (!TransactionIdIsCurrentTransactionId (* xid ))
379- {
380- * xid = GetCurrentTransactionId ();
381- * level = 0 ;
382- * recursion = true;
383- }
384-
385- if (* level == 17 )
386- {
387- * recursion = false;
388- return PointerGetDatum (tuple );
389- }
390-
391- if (!(* recursion ))
392- return PointerGetDatum (tuple );
393-
394- (* level )++ ;
395-
396- SPI_connect ();
397-
398- fieldval = SPI_getvalue (tuple , tupdesc , 1 );
399- fieldtype = SPI_gettype (tupdesc , 1 );
400-
401- query = (char * ) palloc (100 + NAMEDATALEN * 3 +
402- strlen (fieldval ) + strlen (fieldtype ));
403-
404- sprintf (query , "insert into %s select * from %s where %s = '%s'::%s" ,
405- SPI_getrelname (rel ), SPI_getrelname (rel ),
406- SPI_fname (tupdesc , 1 ),
407- fieldval , fieldtype );
408-
409- if ((ret = SPI_exec (query , 0 )) < 0 )
410- elog (ERROR , "funny_dup17 (fired %s) on level %3d: SPI_exec (insert ...) returned %d" ,
411- when , * level , ret );
412-
413- inserted = SPI_processed ;
414-
415- sprintf (query , "select count (*) from %s where %s = '%s'::%s" ,
416- SPI_getrelname (rel ),
417- SPI_fname (tupdesc , 1 ),
418- fieldval , fieldtype );
419-
420- if ((ret = SPI_exec (query , 0 )) < 0 )
421- elog (ERROR , "funny_dup17 (fired %s) on level %3d: SPI_exec (select ...) returned %d" ,
422- when , * level , ret );
423-
424- if (SPI_processed > 0 )
425- {
426- selected = DatumGetInt32 (DirectFunctionCall1 (int4in ,
427- CStringGetDatum (SPI_getvalue (
428- SPI_tuptable -> vals [0 ],
429- SPI_tuptable -> tupdesc ,
430- 1
431- ))));
432- }
433-
434- elog (DEBUG4 , "funny_dup17 (fired %s) on level %3d: " UINT64_FORMAT "/%d tuples inserted/selected" ,
435- when , * level , inserted , selected );
436-
437- SPI_finish ();
438-
439- (* level )-- ;
440-
441- if (* level == 0 )
442- * xid = InvalidTransactionId ;
443-
444- return PointerGetDatum (tuple );
445- }
446-
447207#define TTDUMMY_INFINITY 999999
448208
449209static SPIPlanPtr splan = NULL ;
0 commit comments