@ -43,120 +43,11 @@
# define RDELIM ')'
# define DELIM ','
extern PATH * poly2path ( POLYGON * poly ) ;
extern void regress_lseg_construct ( LSEG * lseg , Point * pt1 , Point * pt2 ) ;
static void regress_lseg_construct ( LSEG * lseg , Point * pt1 , Point * pt2 ) ;
PG_MODULE_MAGIC ;
/*
* Distance from a point to a path
*/
PG_FUNCTION_INFO_V1 ( regress_dist_ptpath ) ;
Datum
regress_dist_ptpath ( PG_FUNCTION_ARGS )
{
Point * pt = PG_GETARG_POINT_P ( 0 ) ;
PATH * path = PG_GETARG_PATH_P ( 1 ) ;
float8 result = 0.0 ; /* keep compiler quiet */
float8 tmp ;
int i ;
LSEG lseg ;
switch ( path - > npts )
{
case 0 :
PG_RETURN_NULL ( ) ;
case 1 :
result = point_dt ( pt , & path - > p [ 0 ] ) ;
break ;
default :
/*
* the distance from a point to a path is the smallest distance
* from the point to any of its constituent segments .
*/
Assert ( path - > npts > 1 ) ;
for ( i = 0 ; i < path - > npts - 1 ; + + i )
{
regress_lseg_construct ( & lseg , & path - > p [ i ] , & path - > p [ i + 1 ] ) ;
tmp = DatumGetFloat8 ( DirectFunctionCall2 ( dist_ps ,
PointPGetDatum ( pt ) ,
LsegPGetDatum ( & lseg ) ) ) ;
if ( i = = 0 | | tmp < result )
result = tmp ;
}
break ;
}
PG_RETURN_FLOAT8 ( result ) ;
}
/*
* this essentially does a cartesian product of the lsegs in the
* two paths , and finds the min distance between any two lsegs
*/
PG_FUNCTION_INFO_V1 ( regress_path_dist ) ;
Datum
regress_path_dist ( PG_FUNCTION_ARGS )
{
PATH * p1 = PG_GETARG_PATH_P ( 0 ) ;
PATH * p2 = PG_GETARG_PATH_P ( 1 ) ;
bool have_min = false ;
float8 min = 0.0 ; /* initialize to keep compiler quiet */
float8 tmp ;
int i ,
j ;
LSEG seg1 ,
seg2 ;
for ( i = 0 ; i < p1 - > npts - 1 ; i + + )
{
for ( j = 0 ; j < p2 - > npts - 1 ; j + + )
{
regress_lseg_construct ( & seg1 , & p1 - > p [ i ] , & p1 - > p [ i + 1 ] ) ;
regress_lseg_construct ( & seg2 , & p2 - > p [ j ] , & p2 - > p [ j + 1 ] ) ;
tmp = DatumGetFloat8 ( DirectFunctionCall2 ( lseg_distance ,
LsegPGetDatum ( & seg1 ) ,
LsegPGetDatum ( & seg2 ) ) ) ;
if ( ! have_min | | tmp < min )
{
min = tmp ;
have_min = true ;
}
}
}
if ( ! have_min )
PG_RETURN_NULL ( ) ;
PG_RETURN_FLOAT8 ( min ) ;
}
PATH *
poly2path ( POLYGON * poly )
{
int i ;
char * output = ( char * ) palloc ( 2 * ( P_MAXDIG + 1 ) * poly - > npts + 64 ) ;
char buf [ 2 * ( P_MAXDIG ) + 20 ] ;
sprintf ( output , " (1, %*d " , P_MAXDIG , poly - > npts ) ;
for ( i = 0 ; i < poly - > npts ; i + + )
{
snprintf ( buf , sizeof ( buf ) , " ,%*g,%*g " ,
P_MAXDIG , poly - > p [ i ] . x , P_MAXDIG , poly - > p [ i ] . y ) ;
strcat ( output , buf ) ;
}
snprintf ( buf , sizeof ( buf ) , " %c " , RDELIM ) ;
strcat ( output , buf ) ;
return DatumGetPathP ( DirectFunctionCall1 ( path_in ,
CStringGetDatum ( output ) ) ) ;
}
/* return the point where two paths intersect, or NULL if no intersection. */
PG_FUNCTION_INFO_V1 ( interpt_pp ) ;
@ -201,7 +92,7 @@ interpt_pp(PG_FUNCTION_ARGS)
/* like lseg_construct, but assume space already allocated */
void
static void
regress_lseg_construct ( LSEG * lseg , Point * pt1 , Point * pt2 )
{
lseg - > p [ 0 ] . x = pt1 - > x ;
@ -291,20 +182,6 @@ pt_in_widget(PG_FUNCTION_ARGS)
PG_RETURN_BOOL ( point_dt ( point , & widget - > center ) < widget - > radius ) ;
}
PG_FUNCTION_INFO_V1 ( boxarea ) ;
Datum
boxarea ( PG_FUNCTION_ARGS )
{
BOX * box = PG_GETARG_BOX_P ( 0 ) ;
double width ,
height ;
width = Abs ( box - > high . x - box - > low . x ) ;
height = Abs ( box - > high . y - box - > low . y ) ;
PG_RETURN_FLOAT8 ( width * height ) ;
}
PG_FUNCTION_INFO_V1 ( reverse_name ) ;
Datum
@ -327,123 +204,6 @@ reverse_name(PG_FUNCTION_ARGS)
}
static TransactionId fd17b_xid = InvalidTransactionId ;
static TransactionId fd17a_xid = InvalidTransactionId ;
static int fd17b_level = 0 ;
static int fd17a_level = 0 ;
static bool fd17b_recursion = true ;
static bool fd17a_recursion = true ;
PG_FUNCTION_INFO_V1 ( funny_dup17 ) ;
Datum
funny_dup17 ( PG_FUNCTION_ARGS )
{
TriggerData * trigdata = ( TriggerData * ) fcinfo - > context ;
TransactionId * xid ;
int * level ;
bool * recursion ;
Relation rel ;
TupleDesc tupdesc ;
HeapTuple tuple ;
char * query ,
* fieldval ,
* fieldtype ;
char * when ;
uint64 inserted ;
int selected = 0 ;
int ret ;
if ( ! CALLED_AS_TRIGGER ( fcinfo ) )
elog ( ERROR , " funny_dup17: not fired by trigger manager " ) ;
tuple = trigdata - > tg_trigtuple ;
rel = trigdata - > tg_relation ;
tupdesc = rel - > rd_att ;
if ( TRIGGER_FIRED_BEFORE ( trigdata - > tg_event ) )
{
xid = & fd17b_xid ;
level = & fd17b_level ;
recursion = & fd17b_recursion ;
when = " BEFORE " ;
}
else
{
xid = & fd17a_xid ;
level = & fd17a_level ;
recursion = & fd17a_recursion ;
when = " AFTER " ;
}
if ( ! TransactionIdIsCurrentTransactionId ( * xid ) )
{
* xid = GetCurrentTransactionId ( ) ;
* level = 0 ;
* recursion = true ;
}
if ( * level = = 17 )
{
* recursion = false ;
return PointerGetDatum ( tuple ) ;
}
if ( ! ( * recursion ) )
return PointerGetDatum ( tuple ) ;
( * level ) + + ;
SPI_connect ( ) ;
fieldval = SPI_getvalue ( tuple , tupdesc , 1 ) ;
fieldtype = SPI_gettype ( tupdesc , 1 ) ;
query = ( char * ) palloc ( 100 + NAMEDATALEN * 3 +
strlen ( fieldval ) + strlen ( fieldtype ) ) ;
sprintf ( query , " insert into %s select * from %s where %s = '%s'::%s " ,
SPI_getrelname ( rel ) , SPI_getrelname ( rel ) ,
SPI_fname ( tupdesc , 1 ) ,
fieldval , fieldtype ) ;
if ( ( ret = SPI_exec ( query , 0 ) ) < 0 )
elog ( ERROR , " funny_dup17 (fired %s) on level %3d: SPI_exec (insert ...) returned %d " ,
when , * level , ret ) ;
inserted = SPI_processed ;
sprintf ( query , " select count (*) from %s where %s = '%s'::%s " ,
SPI_getrelname ( rel ) ,
SPI_fname ( tupdesc , 1 ) ,
fieldval , fieldtype ) ;
if ( ( ret = SPI_exec ( query , 0 ) ) < 0 )
elog ( ERROR , " funny_dup17 (fired %s) on level %3d: SPI_exec (select ...) returned %d " ,
when , * level , ret ) ;
if ( SPI_processed > 0 )
{
selected = DatumGetInt32 ( DirectFunctionCall1 ( int4in ,
CStringGetDatum ( SPI_getvalue (
SPI_tuptable - > vals [ 0 ] ,
SPI_tuptable - > tupdesc ,
1
) ) ) ) ;
}
elog ( DEBUG4 , " funny_dup17 (fired %s) on level %3d: " UINT64_FORMAT " /%d tuples inserted/selected " ,
when , * level , inserted , selected ) ;
SPI_finish ( ) ;
( * level ) - - ;
if ( * level = = 0 )
* xid = InvalidTransactionId ;
return PointerGetDatum ( tuple ) ;
}
# define TTDUMMY_INFINITY 999999
static SPIPlanPtr splan = NULL ;