LCOV - code coverage report
Current view: top level - src/include/utils - geo_decls.h (source / functions) Hit Total Coverage
Test: PostgreSQL 19devel Lines: 42 42 100.0 %
Date: 2025-12-13 07:18:15 Functions: 21 21 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  * geo_decls.h - Declarations for various 2D constructs.
       4             :  *
       5             :  *
       6             :  * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
       7             :  * Portions Copyright (c) 1994, Regents of the University of California
       8             :  *
       9             :  * src/include/utils/geo_decls.h
      10             :  *
      11             :  *    XXX These routines were not written by a numerical analyst.
      12             :  *
      13             :  *    XXX I have made some attempt to flesh out the operators
      14             :  *      and data types. There are still some more to do. - tgl 97/04/19
      15             :  *
      16             :  *-------------------------------------------------------------------------
      17             :  */
      18             : #ifndef GEO_DECLS_H
      19             : #define GEO_DECLS_H
      20             : 
      21             : #include <math.h>
      22             : 
      23             : #include "fmgr.h"
      24             : 
      25             : /*--------------------------------------------------------------------
      26             :  * Useful floating point utilities and constants.
      27             :  *--------------------------------------------------------------------
      28             :  *
      29             :  * "Fuzzy" floating-point comparisons: values within EPSILON of each other
      30             :  * are considered equal.  Beware of normal reasoning about the behavior of
      31             :  * these comparisons, since for example FPeq does not behave transitively.
      32             :  *
      33             :  * Note that these functions are not NaN-aware and will give FALSE for
      34             :  * any case involving NaN inputs.
      35             :  *
      36             :  * Also note that these will give sane answers for infinite inputs,
      37             :  * where it's important to avoid computing Inf minus Inf; we do so
      38             :  * by eliminating equality cases before subtracting.
      39             :  */
      40             : 
      41             : #define EPSILON                 1.0E-06
      42             : 
      43             : #ifdef EPSILON
      44             : #define FPzero(A)               (fabs(A) <= EPSILON)
      45             : 
      46             : static inline bool
      47    18273306 : FPeq(double A, double B)
      48             : {
      49    18273306 :     return A == B || fabs(A - B) <= EPSILON;
      50             : }
      51             : 
      52             : static inline bool
      53         384 : FPne(double A, double B)
      54             : {
      55         384 :     return A != B && fabs(A - B) > EPSILON;
      56             : }
      57             : 
      58             : static inline bool
      59     2862878 : FPlt(double A, double B)
      60             : {
      61     2862878 :     return A + EPSILON < B;
      62             : }
      63             : 
      64             : static inline bool
      65     3182184 : FPle(double A, double B)
      66             : {
      67     3182184 :     return A <= B + EPSILON;
      68             : }
      69             : 
      70             : static inline bool
      71    31562126 : FPgt(double A, double B)
      72             : {
      73    31562126 :     return A > B + EPSILON;
      74             : }
      75             : 
      76             : static inline bool
      77     1116512 : FPge(double A, double B)
      78             : {
      79     1116512 :     return A + EPSILON >= B;
      80             : }
      81             : #else
      82             : #define FPzero(A)               ((A) == 0)
      83             : #define FPeq(A,B)               ((A) == (B))
      84             : #define FPne(A,B)               ((A) != (B))
      85             : #define FPlt(A,B)               ((A) < (B))
      86             : #define FPle(A,B)               ((A) <= (B))
      87             : #define FPgt(A,B)               ((A) > (B))
      88             : #define FPge(A,B)               ((A) >= (B))
      89             : #endif
      90             : 
      91             : 
      92             : /*---------------------------------------------------------------------
      93             :  * Point - (x,y)
      94             :  *-------------------------------------------------------------------*/
      95             : typedef struct
      96             : {
      97             :     float8      x,
      98             :                 y;
      99             : } Point;
     100             : 
     101             : 
     102             : /*---------------------------------------------------------------------
     103             :  * LSEG - A straight line, specified by endpoints.
     104             :  *-------------------------------------------------------------------*/
     105             : typedef struct
     106             : {
     107             :     Point       p[2];
     108             : } LSEG;
     109             : 
     110             : 
     111             : /*---------------------------------------------------------------------
     112             :  * PATH - Specified by vertex points.
     113             :  *-------------------------------------------------------------------*/
     114             : typedef struct
     115             : {
     116             :     int32       vl_len_;        /* varlena header (do not touch directly!) */
     117             :     int32       npts;
     118             :     int32       closed;         /* is this a closed polygon? */
     119             :     int32       dummy;          /* padding to make it double align */
     120             :     Point       p[FLEXIBLE_ARRAY_MEMBER];
     121             : } PATH;
     122             : 
     123             : 
     124             : /*---------------------------------------------------------------------
     125             :  * LINE - Specified by its general equation (Ax+By+C=0).
     126             :  *-------------------------------------------------------------------*/
     127             : typedef struct
     128             : {
     129             :     float8      A,
     130             :                 B,
     131             :                 C;
     132             : } LINE;
     133             : 
     134             : 
     135             : /*---------------------------------------------------------------------
     136             :  * BOX  - Specified by two corner points, which are
     137             :  *       sorted to save calculation time later.
     138             :  *-------------------------------------------------------------------*/
     139             : typedef struct
     140             : {
     141             :     Point       high,
     142             :                 low;            /* corner POINTs */
     143             : } BOX;
     144             : 
     145             : /*---------------------------------------------------------------------
     146             :  * POLYGON - Specified by an array of doubles defining the points,
     147             :  *      keeping the number of points and the bounding box for
     148             :  *      speed purposes.
     149             :  *-------------------------------------------------------------------*/
     150             : typedef struct
     151             : {
     152             :     int32       vl_len_;        /* varlena header (do not touch directly!) */
     153             :     int32       npts;
     154             :     BOX         boundbox;
     155             :     Point       p[FLEXIBLE_ARRAY_MEMBER];
     156             : } POLYGON;
     157             : 
     158             : /*---------------------------------------------------------------------
     159             :  * CIRCLE - Specified by a center point and radius.
     160             :  *-------------------------------------------------------------------*/
     161             : typedef struct
     162             : {
     163             :     Point       center;
     164             :     float8      radius;
     165             : } CIRCLE;
     166             : 
     167             : /*
     168             :  * fmgr interface functions
     169             :  *
     170             :  * Path and Polygon are toastable varlena types, the others are just
     171             :  * fixed-size pass-by-reference types.
     172             :  */
     173             : 
     174             : static inline Point *
     175   100280236 : DatumGetPointP(Datum X)
     176             : {
     177   100280236 :     return (Point *) DatumGetPointer(X);
     178             : }
     179             : static inline Datum
     180    80658662 : PointPGetDatum(const Point *X)
     181             : {
     182    80658662 :     return PointerGetDatum(X);
     183             : }
     184             : #define PG_GETARG_POINT_P(n) DatumGetPointP(PG_GETARG_DATUM(n))
     185             : #define PG_RETURN_POINT_P(x) return PointPGetDatum(x)
     186             : 
     187             : static inline LSEG *
     188       83002 : DatumGetLsegP(Datum X)
     189             : {
     190       83002 :     return (LSEG *) DatumGetPointer(X);
     191             : }
     192             : static inline Datum
     193       61570 : LsegPGetDatum(const LSEG *X)
     194             : {
     195       61570 :     return PointerGetDatum(X);
     196             : }
     197             : #define PG_GETARG_LSEG_P(n) DatumGetLsegP(PG_GETARG_DATUM(n))
     198             : #define PG_RETURN_LSEG_P(x) return LsegPGetDatum(x)
     199             : 
     200             : static inline PATH *
     201     2847034 : DatumGetPathP(Datum X)
     202             : {
     203     2847034 :     return (PATH *) PG_DETOAST_DATUM(X);
     204             : }
     205             : static inline PATH *
     206        1866 : DatumGetPathPCopy(Datum X)
     207             : {
     208        1866 :     return (PATH *) PG_DETOAST_DATUM_COPY(X);
     209             : }
     210             : static inline Datum
     211       32866 : PathPGetDatum(const PATH *X)
     212             : {
     213       32866 :     return PointerGetDatum(X);
     214             : }
     215             : #define PG_GETARG_PATH_P(n)      DatumGetPathP(PG_GETARG_DATUM(n))
     216             : #define PG_GETARG_PATH_P_COPY(n) DatumGetPathPCopy(PG_GETARG_DATUM(n))
     217             : #define PG_RETURN_PATH_P(x)      return PathPGetDatum(x)
     218             : 
     219             : static inline LINE *
     220       19408 : DatumGetLineP(Datum X)
     221             : {
     222       19408 :     return (LINE *) DatumGetPointer(X);
     223             : }
     224             : static inline Datum
     225         618 : LinePGetDatum(const LINE *X)
     226             : {
     227         618 :     return PointerGetDatum(X);
     228             : }
     229             : #define PG_GETARG_LINE_P(n) DatumGetLineP(PG_GETARG_DATUM(n))
     230             : #define PG_RETURN_LINE_P(x) return LinePGetDatum(x)
     231             : 
     232             : static inline BOX *
     233    97193474 : DatumGetBoxP(Datum X)
     234             : {
     235    97193474 :     return (BOX *) DatumGetPointer(X);
     236             : }
     237             : static inline Datum
     238     2594454 : BoxPGetDatum(const BOX *X)
     239             : {
     240     2594454 :     return PointerGetDatum(X);
     241             : }
     242             : #define PG_GETARG_BOX_P(n) DatumGetBoxP(PG_GETARG_DATUM(n))
     243             : #define PG_RETURN_BOX_P(x) return BoxPGetDatum(x)
     244             : 
     245             : static inline POLYGON *
     246      875666 : DatumGetPolygonP(Datum X)
     247             : {
     248      875666 :     return (POLYGON *) PG_DETOAST_DATUM(X);
     249             : }
     250             : static inline POLYGON *
     251             : DatumGetPolygonPCopy(Datum X)
     252             : {
     253             :     return (POLYGON *) PG_DETOAST_DATUM_COPY(X);
     254             : }
     255             : static inline Datum
     256       79224 : PolygonPGetDatum(const POLYGON *X)
     257             : {
     258       79224 :     return PointerGetDatum(X);
     259             : }
     260             : #define PG_GETARG_POLYGON_P(n)      DatumGetPolygonP(PG_GETARG_DATUM(n))
     261             : #define PG_GETARG_POLYGON_P_COPY(n) DatumGetPolygonPCopy(PG_GETARG_DATUM(n))
     262             : #define PG_RETURN_POLYGON_P(x)      return PolygonPGetDatum(x)
     263             : 
     264             : static inline CIRCLE *
     265      343130 : DatumGetCircleP(Datum X)
     266             : {
     267      343130 :     return (CIRCLE *) DatumGetPointer(X);
     268             : }
     269             : static inline Datum
     270      200786 : CirclePGetDatum(const CIRCLE *X)
     271             : {
     272      200786 :     return PointerGetDatum(X);
     273             : }
     274             : #define PG_GETARG_CIRCLE_P(n) DatumGetCircleP(PG_GETARG_DATUM(n))
     275             : #define PG_RETURN_CIRCLE_P(x) return CirclePGetDatum(x)
     276             : 
     277             : #endif                          /* GEO_DECLS_H */

Generated by: LCOV version 1.16